EPFL-LAP / dynamatic

DHLS (Dynamic High-Level Synthesis) compiler based on MLIR
Other
64 stars 19 forks source link

[Backend] Simulation hang in a circuit without loop #118

Closed Jiahui17 closed 2 months ago

Jiahui17 commented 3 months ago

Benchmark:

simple_example.c

Script:

set-dynamatic-path ./dynamatic;     set-src ./dynamatic/integration-test/simple_example/simple_example.c;     set-clock-period 4;     compile;     write-hdl --hdl vhdl;     simulate;     synthesize;     exit

Issue:

void simple_example(inout_int_t a[N]) {
  int x = 0;
  for (unsigned i = 0; i < N; ++i)
    x++;
  a[0] = x;
}

The loop in this program is optimized away:

module {
  handshake.func @simple_example(%arg0: memref<100xi32>, %arg1: !handshake.control<>, ...) -> !handshake.control<> attributes {argNames = ["a", "start"], resNames = ["end"]} {
    %0:4 = fork [4] %arg1 {handshake.bb = 0 : ui32, handshake.name = "fork0"} : <>
    %done = mem_controller[%arg0 : memref<100xi32>] (%2, %addressResult, %dataResult) {bufProps = #handshake<bufProps{"0": [0,0], [0,0], 0.000000e+00, 0.000000e+00, 0.000000e+00, "1": [0,0], [0,0], 0.000000e+00, 0.000000e+00, 0.000000e+00, "2": [0,0], [0,0], 0.000000e+00, 0.000000e+00, 0.000000e+00, "3": [0,0], [0,0], 0.000000e+00, 0.000000e+00, 0.000000e+00}>, connectedBlocks = [0 : i32], handshake.name = "mem_controller0"} : (!handshake.channel<i32>, !handshake.channel<i32>, !handshake.channel<i32>) -> !handshake.control<>
    %1 = constant %0#2 {handshake.bb = 0 : ui32, handshake.name = "constant3", value = 1 : i2} : <i2>
    %2 = extsi %1 {handshake.bb = 0 : ui32, handshake.name = "extsi0"} : <i2> to <i32>
    %3 = constant %0#1 {handshake.bb = 0 : ui32, handshake.name = "constant4", value = false} : <i1>
    %4 = extsi %3 {handshake.bb = 0 : ui32, handshake.name = "extsi1"} : <i1> to <i32>
    %5 = constant %0#0 {handshake.bb = 0 : ui32, handshake.name = "constant5", value = 100 : i8} : <i8>
    %6 = extsi %5 {handshake.bb = 0 : ui32, handshake.name = "extsi2"} : <i8> to <i32>
    %addressResult, %dataResult = mc_store[%4] %6 {handshake.bb = 0 : ui32, handshake.name = "mc_store0"} : <i32>, <i32>
    end {bufProps = #handshake<bufProps{"1": [0,0], [0,0], 0.000000e+00, 0.000000e+00, 0.000000e+00}>, handshake.bb = 0 : ui32, handshake.name = "end0"} %0#3, %done : <>, <>
  }
}

And the simulation does not terminate.

lucas-rami commented 2 months ago

This is most likely due to the removal of the ReturnOp operation (daff034), which was basically forcing a TEHB on the result's path. If the circuit is non-cyclic there may be no buffers inserted on the path and our current (bad) testbench generation logic is unable to handle that. I'm reworking the latter as part of the circuit/memory interface redesign which I hope to merge today, it should fix the issue as a side-effect.