10 #include "slang/ast/TimingControl.h"
11 #include "llvm/ADT/ScopeExit.h"
13 using namespace circt;
14 using namespace ImportVerilog;
17 using slang::ast::EdgeKind;
20 return moore::Edge::AnyChange;
21 case EdgeKind::PosEdge:
22 return moore::Edge::PosEdge;
23 case EdgeKind::NegEdge:
24 return moore::Edge::NegEdge;
25 case EdgeKind::BothEdges:
26 return moore::Edge::BothEdges;
28 llvm_unreachable(
"all edge kinds handled");
35 struct EventControlVisitor {
41 LogicalResult visit(
const slang::ast::SignalEventControl &ctrl) {
47 if (ctrl.iffCondition) {
49 condition = context.
convertToBool(condition, Domain::TwoValued);
53 builder.create<moore::DetectEventOp>(loc, edge, expr, condition);
58 LogicalResult visit(
const slang::ast::EventListControl &ctrl) {
59 for (
const auto *event : ctrl.events) {
62 if (failed(event->visit(visitor)))
70 LogicalResult visit(T &&ctrl) {
71 return mlir::emitError(loc)
77 struct DelayControlVisitor {
84 LogicalResult visit(T &&ctrl) {
85 return mlir::emitError(loc)
98 const slang::ast::TimingControl &ctrl,
99 moore::WaitEventOp &implicitWaitOp) {
100 auto &builder = context.
builder;
103 using slang::ast::TimingControlKind;
113 case TimingControlKind::RepeatedEvent:
114 return mlir::emitError(loc) <<
"unsupported repeated event control";
121 case TimingControlKind::ImplicitEvent:
122 implicitWaitOp = builder.create<moore::WaitEventOp>(loc);
126 case TimingControlKind::SignalEvent:
127 case TimingControlKind::EventList: {
128 auto waitOp = builder.create<moore::WaitEventOp>(loc);
129 OpBuilder::InsertionGuard guard(builder);
130 builder.setInsertionPointToStart(&waitOp.getBody().emplaceBlock());
131 EventControlVisitor visitor{context, loc, builder};
132 return ctrl.visit(visitor);
136 case TimingControlKind::Delay:
137 case TimingControlKind::Delay3:
138 case TimingControlKind::OneStepDelay:
139 case TimingControlKind::CycleDelay: {
140 DelayControlVisitor visitor{context, loc, builder};
141 return ctrl.visit(visitor);
145 return mlir::emitError(loc,
"unsupported timing control: ")
152 const slang::ast::Statement &stmt) {
156 moore::WaitEventOp implicitWaitOp;
165 if (failed(
handleRoot(*
this, ctrl, implicitWaitOp)))
173 llvm::SmallSetVector<Value, 8> readValues;
178 if (implicitWaitOp) {
180 readValues.insert(readOp.getInput());
181 if (previousCallback)
182 previousCallback(readOp);
191 if (implicitWaitOp) {
192 OpBuilder::InsertionGuard guard(
builder);
193 builder.setInsertionPointToStart(&implicitWaitOp.getBody().emplaceBlock());
194 for (
auto readValue : readValues) {
196 builder.create<moore::ReadOp>(implicitWaitOp.getLoc(), readValue);
197 builder.create<moore::DetectEventOp>(
198 implicitWaitOp.getLoc(), moore::Edge::AnyChange, value, Value{});
const char * toString(Flow flow)
static moore::Edge convertEdgeKind(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.
LogicalResult convertTimingControl(const slang::ast::TimingControl &ctrl, const slang::ast::Statement &stmt)
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.