10#include "slang/ast/TimingControl.h"
11#include "llvm/ADT/ScopeExit.h"
14using namespace ImportVerilog;
17 using slang::ast::EdgeKind;
19 case EdgeKind::NegEdge:
20 return ltl::ClockEdge::Neg;
21 case EdgeKind::PosEdge:
22 return ltl::ClockEdge::Pos;
27 case EdgeKind::BothEdges:
28 return ltl::ClockEdge::Both;
30 llvm_unreachable(
"all edge kinds handled");
34 using slang::ast::EdgeKind;
37 return moore::Edge::AnyChange;
38 case EdgeKind::PosEdge:
39 return moore::Edge::PosEdge;
40 case EdgeKind::NegEdge:
41 return moore::Edge::NegEdge;
42 case EdgeKind::BothEdges:
43 return moore::Edge::BothEdges;
45 llvm_unreachable(
"all edge kinds handled");
52struct EventControlVisitor {
58 LogicalResult visit(
const slang::ast::SignalEventControl &ctrl) {
64 if (ctrl.iffCondition) {
66 condition = context.
convertToBool(condition, Domain::TwoValued);
70 builder.create<moore::DetectEventOp>(loc, edge, expr, condition);
75 LogicalResult visit(
const slang::ast::EventListControl &ctrl) {
76 for (
const auto *event : ctrl.events) {
79 if (failed(event->visit(visitor)))
87 LogicalResult visit(T &&ctrl) {
88 return mlir::emitError(loc)
89 <<
"unsupported event control: " << slang::ast::toString(ctrl.kind);
94struct DelayControlVisitor {
100 template <
typename T>
101 LogicalResult visit(T &&ctrl) {
102 return mlir::emitError(loc)
103 <<
"unsupported delay control: " << slang::ast::toString(ctrl.kind);
107struct LTLClockControlVisitor {
113 Value visit(
const slang::ast::SignalEventControl &ctrl) {
119 if (ctrl.iffCondition) {
121 condition = context.
convertToBool(condition, Domain::TwoValued);
128 return builder.create<ltl::ClockOp>(loc, seqOrPro, edge, expr);
131 template <
typename T>
132 Value visit(T &&ctrl) {
133 mlir::emitError(loc,
"unsupported LTL clock control: ")
134 << slang::ast::toString(ctrl.kind);
147 const slang::ast::TimingControl &ctrl,
148 moore::WaitEventOp &implicitWaitOp) {
149 auto &builder = context.
builder;
152 using slang::ast::TimingControlKind;
162 case TimingControlKind::RepeatedEvent:
163 return mlir::emitError(loc) <<
"unsupported repeated event control";
170 case TimingControlKind::ImplicitEvent:
171 implicitWaitOp = builder.create<moore::WaitEventOp>(loc);
175 case TimingControlKind::SignalEvent:
176 case TimingControlKind::EventList: {
177 auto waitOp = builder.create<moore::WaitEventOp>(loc);
178 OpBuilder::InsertionGuard guard(builder);
179 builder.setInsertionPointToStart(&waitOp.getBody().emplaceBlock());
180 EventControlVisitor visitor{context, loc, builder};
181 return ctrl.visit(visitor);
185 case TimingControlKind::Delay:
186 case TimingControlKind::Delay3:
187 case TimingControlKind::OneStepDelay:
188 case TimingControlKind::CycleDelay: {
189 DelayControlVisitor visitor{context, loc, builder};
190 return ctrl.visit(visitor);
194 return mlir::emitError(loc,
"unsupported timing control: ")
195 << slang::ast::toString(ctrl.kind);
200Context::convertTimingControl(
const slang::ast::TimingControl &ctrl,
201 const slang::ast::Statement &stmt) {
205 moore::WaitEventOp implicitWaitOp;
214 if (failed(
handleRoot(*
this, ctrl, implicitWaitOp)))
222 llvm::SmallSetVector<Value, 8> readValues;
227 if (implicitWaitOp) {
229 readValues.insert(readOp.getInput());
230 if (previousCallback)
231 previousCallback(readOp);
240 if (implicitWaitOp) {
241 OpBuilder::InsertionGuard guard(
builder);
242 builder.setInsertionPointToStart(&implicitWaitOp.getBody().emplaceBlock());
243 for (
auto readValue : readValues) {
245 builder.create<moore::ReadOp>(implicitWaitOp.getLoc(), readValue);
246 builder.create<moore::DetectEventOp>(
247 implicitWaitOp.getLoc(), moore::Edge::AnyChange, value, Value{});
200Context::convertTimingControl(
const slang::ast::TimingControl &ctrl, {
…}
255 const Value &seqOrPro) {
258 LTLClockControlVisitor visitor{*
this, loc,
builder, seqOrPro};
259 return ctrl.visit(visitor);
static moore::Edge convertEdgeKind(const slang::ast::EdgeKind edge)
static ltl::ClockEdge convertEdgeKindLTL(const slang::ast::EdgeKind edge)
static LogicalResult handleRoot(Context &context, const slang::ast::TimingControl &ctrl, moore::WaitEventOp &implicitWaitOp)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
A helper class to facilitate the conversion from a Slang AST to MLIR operations.
Value convertToI1(Value value)
Helper function to convert a value to a MLIR I1 value.
Value convertLTLTimingControl(const slang::ast::TimingControl &ctrl, const Value &seqOrPro)
OpBuilder builder
The builder used to create IR operations.
std::function< void(moore::ReadOp)> rvalueReadCallback
A listener called for every variable or net being read.
Value convertToBool(Value value)
Helper function to convert a value to its "truthy" boolean value.
Value convertRvalueExpression(const slang::ast::Expression &expr, Type requiredType={})
LogicalResult convertStatement(const slang::ast::Statement &stmt)
Location convertLocation(slang::SourceLocation loc)
Convert a slang SourceLocation into an MLIR Location.