Skip to content

Commit c47d240

Browse files
[Moore] Add WaitDelayOp, support delay control in ImportVerilog (#8884)
Add a `moore.wait_delay` operation to the Moore dialect. This op simply suspends execution for an amount of time determined by its operand. This lowers directly to `llhd.wait delay %0, ^bb0`. Make use of this new op in ImportVerilog by adding support for basic `#10ns` delay control statements.
1 parent 847e461 commit c47d240

File tree

6 files changed

+89
-1
lines changed

6 files changed

+89
-1
lines changed

include/circt/Dialect/Moore/MooreOps.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,19 @@ def DetectEventOp : MooreOp<"detect_event", [
481481
}];
482482
}
483483

484+
def WaitDelayOp : MooreOp<"wait_delay"> {
485+
let summary = "Suspend execution for a given amount of time";
486+
let description = [{
487+
The `moore.wait_delay` op suspends execution of the current process for the
488+
amount of time specified by its operand. Corresponds to the `#` delay
489+
control in SystemVerilog.
490+
491+
See IEEE 1800-2017 § 9.4.1 "Delay control".
492+
}];
493+
let arguments = (ins TimeType:$delay);
494+
let assemblyFormat = [{ $delay attr-dict }];
495+
}
496+
484497
//===----------------------------------------------------------------------===//
485498
// Constants
486499
//===----------------------------------------------------------------------===//

lib/Conversion/ImportVerilog/TimingControls.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ struct DelayControlVisitor {
9696
Location loc;
9797
OpBuilder &builder;
9898

99+
// Handle delays.
100+
LogicalResult visit(const slang::ast::DelayControl &ctrl) {
101+
auto delay = context.convertRvalueExpression(
102+
ctrl.expr, moore::TimeType::get(builder.getContext()));
103+
if (!delay)
104+
return failure();
105+
moore::WaitDelayOp::create(builder, loc, delay);
106+
return success();
107+
}
108+
99109
// Emit an error for all other timing controls.
100110
template <typename T>
101111
LogicalResult visit(T &&ctrl) {

lib/Conversion/MooreToCore/MooreToCore.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,23 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
508508
}
509509
};
510510

511+
struct WaitDelayOpConversion : public OpConversionPattern<WaitDelayOp> {
512+
using OpConversionPattern::OpConversionPattern;
513+
514+
LogicalResult
515+
matchAndRewrite(WaitDelayOp op, OpAdaptor adaptor,
516+
ConversionPatternRewriter &rewriter) const override {
517+
auto *resumeBlock =
518+
rewriter.splitBlock(op->getBlock(), ++Block::iterator(op));
519+
rewriter.setInsertionPoint(op);
520+
rewriter.replaceOpWithNewOp<llhd::WaitOp>(op, ValueRange{},
521+
adaptor.getDelay(), ValueRange{},
522+
ValueRange{}, resumeBlock);
523+
rewriter.setInsertionPointToStart(resumeBlock);
524+
return success();
525+
}
526+
};
527+
511528
//===----------------------------------------------------------------------===//
512529
// Declaration Conversion
513530
//===----------------------------------------------------------------------===//
@@ -1850,7 +1867,11 @@ static void populateOpConversion(RewritePatternSet &patterns,
18501867
CaseXZEqOpConversion<CaseXZEqOp, false>,
18511868

18521869
// Patterns of structural operations.
1853-
SVModuleOpConversion, InstanceOpConversion, ProcedureOpConversion, WaitEventOpConversion,
1870+
SVModuleOpConversion,
1871+
InstanceOpConversion,
1872+
ProcedureOpConversion,
1873+
WaitEventOpConversion,
1874+
WaitDelayOpConversion,
18541875

18551876
// Patterns of shifting operations.
18561877
ShrOpConversion, ShlOpConversion, AShrOpConversion,

test/Conversion/ImportVerilog/basic.sv

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,6 +2081,19 @@ task automatic ImplicitEventControl(ref int x, ref int y);
20812081
@* dummyD(x + y);
20822082
endtask
20832083

2084+
// CHECK-LABEL: func.func private @DelayControl(
2085+
// CHECK-SAME: [[X:%[^:]+]]: !moore.time
2086+
task automatic DelayControl(time x);
2087+
// CHECK: [[TMP:%.+]] = moore.constant_time 1234000 fs
2088+
// CHECK: moore.wait_delay [[TMP]]
2089+
// CHECK: call @dummyA()
2090+
#1.234ns dummyA();
2091+
2092+
// CHECK: moore.wait_delay [[X]]
2093+
// CHECK: call @dummyA()
2094+
#x dummyA();
2095+
endtask
2096+
20842097
// CHECK-LABEL: func.func private @SignalEventControl(
20852098
// CHECK-SAME: [[X:%[^:]+]]: !moore.ref<i32>
20862099
// CHECK-SAME: [[Y:%[^:]+]]: !moore.ref<i32>

test/Conversion/MooreToCore/basic.mlir

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,31 @@ moore.module @EmptyWaitEvent(out out : !moore.l32) {
10011001
moore.output %1 : !moore.l32
10021002
}
10031003

1004+
1005+
// CHECK-LABEL: hw.module @WaitDelay
1006+
moore.module @WaitDelay(in %d: !moore.time) {
1007+
// CHECK: llhd.process {
1008+
// CHECK: [[TMP:%.+]] = llhd.constant_time <1000000fs, 0d, 0e>
1009+
// CHECK: func.call @dummyA()
1010+
// CHECK: llhd.wait delay [[TMP]], ^[[RESUME1:.+]]
1011+
// CHECK: ^[[RESUME1]]:
1012+
// CHECK: func.call @dummyB()
1013+
// CHECK: llhd.wait delay %d, ^[[RESUME2:.+]]
1014+
// CHECK: ^[[RESUME2]]:
1015+
// CHECK: func.call @dummyC()
1016+
// CHECK: llhd.halt
1017+
// CHECK: }
1018+
moore.procedure initial {
1019+
%0 = moore.constant_time 1000000 fs
1020+
func.call @dummyA() : () -> ()
1021+
moore.wait_delay %0
1022+
func.call @dummyB() : () -> ()
1023+
moore.wait_delay %d
1024+
func.call @dummyC() : () -> ()
1025+
moore.return
1026+
}
1027+
}
1028+
10041029
// Just check that block without predecessors are handled without crashing
10051030
// CHECK-LABEL: @NoPredecessorBlockErasure
10061031
moore.module @NoPredecessorBlockErasure(in %clk_i : !moore.l1, in %raddr_i : !moore.array<2 x l5>, out rdata_o : !moore.array<2 x l32>, in %waddr_i : !moore.array<1 x l5>, in %wdata_i : !moore.array<1 x l32>, in %we_i : !moore.l1) {

test/Dialect/Moore/basic.mlir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,12 @@ func.func @WaitEvent(%arg0: !moore.i1, %arg1: !moore.i1) {
366366
return
367367
}
368368

369+
// CHECK-LABEL: func.func @WaitDelay
370+
func.func @WaitDelay(%arg0: !moore.time) {
371+
// CHECK: moore.wait_delay %arg0
372+
moore.wait_delay %arg0
373+
return
374+
}
369375

370376
// CHECK-LABEL: func.func @FormatStrings
371377
// CHECK-SAME: %arg0: !moore.format_string

0 commit comments

Comments
 (0)