circt/test/Conversion/SimToSV/dpi.mlir

113 lines
4.8 KiB
MLIR

// RUN: circt-opt --lower-sim-to-sv %s | FileCheck %s
// RUN: circt-opt --lower-sim-to-sv --lower-seq-to-sv -export-verilog %s | FileCheck %s --check-prefix=VERILOG
sim.func.dpi @dpi(out arg0: i1, in %arg1: i1, out arg2: i1)
// CHECK: sv.func private @dpi(out arg0 : i1, in %arg1 : i1, out arg2 : i1)
// CHECK-NEXT: sv.macro.decl @__CIRCT_DPI_IMPORT_DPI
// CHECK-NEXT: emit.fragment @dpi_dpi_import_fragument {
// CHECK-NEXT: sv.ifdef @__CIRCT_DPI_IMPORT_DPI {
// CHECK-NEXT: } else {
// CHECK-NEXT: sv.func.dpi.import @dpi
// CHECK-NEXT: sv.macro.def @__CIRCT_DPI_IMPORT_DPI ""
// CHECK-NEXT: }
// CHECK-NEXT: }
// VERILOG: import "DPI-C" context function void dpi(
// VERILOG-NEXT: output bit arg0,
// VERILOG-NEXT: input bit arg1,
// VERILOG-NEXT: output bit arg2
// VERILOG-NEXT: );
// CHECK-LABEL: hw.module @dpi_call
// CHECK-SAME: {emit.fragments = [@dpi_dpi_import_fragument]}
hw.module @dpi_call(in %clock : !seq.clock, in %enable : i1, in %in: i1,
out o1: i1, out o2: i1, out o3: i1, out o4: i1, out o5: i1, out o6: i1, out o7: i1, out o8: i1) {
%0, %1 = sim.func.dpi.call @dpi(%in) clock %clock enable %enable: (i1) -> (i1, i1)
// CHECK: %[[CLK:.+]] = seq.from_clock %clock
// CHECK-NEXT: sv.always posedge %[[CLK]] {
// CHECK-NEXT: sv.if %enable {
// CHECK-NEXT: %[[RESULT:.+]]:2 = sv.func.call.procedural @dpi(%in) : (i1) -> (i1, i1)
// CHECK-NEXT: sv.passign %{{.+}}, %[[RESULT]]#0 : i1
// CHECK-NEXT: sv.passign %{{.+}}, %[[RESULT]]#1 : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// VERILOG: always @(posedge clock) begin
// VERILOG-NEXT: if (enable) begin
// VERILOG-NEXT: dpi([[TMP_RESULT_0:.+]], in, [[TMP_RESULT_1:.+]]);
// VERILOG-NEXT: [[RESULT_0:_.+]] <= [[TMP_RESULT_0]];
// VERILOG-NEXT: [[RESULT_1:_.+]] <= [[TMP_RESULT_1]];
// VERILOG-NEXT: end
// VERILOG-NEXT: end
%2, %3 = sim.func.dpi.call @dpi(%in) clock %clock : (i1) -> (i1, i1)
// CHECK: %[[CLK:.+]] = seq.from_clock %clock
// CHECK-NEXT: sv.always posedge %[[CLK]] {
// CHECK-NEXT: %[[RESULT:.+]]:2 = sv.func.call.procedural @dpi(%in) : (i1) -> (i1, i1)
// CHECK-NEXT: sv.passign %{{.+}}, %[[RESULT]]#0 : i1
// CHECK-NEXT: sv.passign %{{.+}}, %[[RESULT]]#1 : i1
// CHECK-NEXT: }
// VERILOG: always @(posedge clock) begin
// VERILOG-NEXT: dpi([[TMP_RESULT_0:.+]], in, [[TMP_RESULT_1:.+]]);
// VERILOG-NEXT: [[RESULT_2:_.+]] <= [[TMP_RESULT_0]];
// VERILOG-NEXT: [[RESULT_3:_.+]] <= [[TMP_RESULT_1]];
// VERILOG-NEXT: end
%4, %5 = sim.func.dpi.call @dpi(%in) enable %enable : (i1) -> (i1, i1)
// CHECK: sv.alwayscomb {
// CHECK-NEXT: sv.if %enable {
// CHECK-NEXT: %[[RESULT:.+]]:2 = sv.func.call.procedural @dpi(%in) : (i1) -> (i1, i1)
// CHECK-NEXT: sv.bpassign %{{.+}}, %[[RESULT]]#0 : i1
// CHECK-NEXT: sv.bpassign %{{.+}}, %[[RESULT]]#1 : i1
// CHECK-NEXT: } else {
// CHECK-NEXT: %[[X:.+]] = sv.constantX
// CHECK-NEXT: sv.bpassign %{{.+}}, %[[X]] : i1
// CHECK-NEXT: %[[X:.+]] = sv.constantX
// CHECK-NEXT: sv.bpassign %{{.+}}, %[[X]] : i1
// CHECK-NEXT: }
// CHECK-NEXT: }
// VERILOG: always_comb begin
// VERILOG-NEXT: if (enable) begin
// VERILOG-NEXT: dpi([[RESULT_4:.+]], in, [[RESULT_5:.+]]);
// VERILOG-NEXT: end
// VERILOG-NEXT: else begin
// VERILOG-NEXT: [[RESULT_4]] = 1'bx;
// VERILOG-NEXT: [[RESULT_5]] = 1'bx;
// VERILOG-NEXT: end
// VERILOG-NEXT: end
%6, %7 = sim.func.dpi.call @dpi(%in) : (i1) -> (i1, i1)
// CHECK: sv.alwayscomb {
// CHECK-NEXT: %[[RESULT:.+]]:2 = sv.func.call.procedural @dpi(%in) : (i1) -> (i1, i1)
// CHECK-NEXT: sv.bpassign %{{.+}}, %[[RESULT]]#0 : i1
// CHECK-NEXT: sv.bpassign %{{.+}}, %[[RESULT]]#1 : i1
// CHECK-NEXT: }
// VERILOG: always_comb begin
// VERILOG-NEXT: dpi([[RESULT_6:.+]], in, [[RESULT_7:.+]]);
// VERILOG-NEXT: end
// VERILOG: assign o1 = [[RESULT_0]];
// VERILOG-NEXT: assign o2 = [[RESULT_1]];
// VERILOG-NEXT: assign o3 = [[RESULT_2]];
// VERILOG-NEXT: assign o4 = [[RESULT_3]];
// VERILOG-NEXT: assign o5 = [[RESULT_4]];
// VERILOG-NEXT: assign o6 = [[RESULT_5]];
// VERILOG-NEXT: assign o7 = [[RESULT_6]];
// VERILOG-NEXT: assign o8 = [[RESULT_7]];
hw.output %0, %1, %2, %3, %4, %5, %6, %7: i1, i1, i1, i1, i1, i1, i1, i1
}
sim.func.dpi private @increment_counter(in %in_0 : i64, out out_0 : i32)
sim.func.dpi private @create_counter(out out_0 : i64)
// CHECK-LABEL: hw.module @Issue7191
// Check lowering successes.
hw.module @Issue7191(out result : i32) {
// CHECK: call.procedural @create_counter
// CHECK: call.procedural @increment_counter
%0 = sim.func.dpi.call @create_counter() : () -> i64
%1 = sim.func.dpi.call @increment_counter(%0) : (i64) -> i32
hw.output %1 : i32
}