Drive events get reordered
Closed this issue · 2 comments
fabianschuiki commented
It seems that drive events are being reordered in an arbitrary fashion at times. Seen this in a larger code example, but for example not in the following code (which works fine):
proc @foo () (i32$ %out) {
%entry:
drv %out 0
drv %out 1
drv %out 2
drv %out 3
wait %end for 1ns
%end:
halt
}
Output in the VCD file is 3
for %out
.
fabianschuiki commented
The following example does not work however:
proc @n274 (i32$ %0, i32$ %1, i32$ %2, i32$ %3, i32$ %4, i32$ %5) (i1$ %6, i1$ %7, i1$ %8) {
%9:
br label %body
%body:
%11 = prb %3
%12 = prb %0
%13 = cmp eq i32 %11 %12
drv %6 %13
%15 = prb %4
%16 = prb %1
%17 = cmp eq i32 %15 %16
drv %7 %17
%19 = prb %5
%20 = prb %2
%21 = cmp eq i32 %19 %20
drv %8 %21
br label %check
%check:
wait %body, %0, %1, %2, %3, %4, %5
}
proc @n275 (i1$ %0, i1$ %1, i1$ %2, i1$ %3, i1$ %4, i1$ %5) (i1$ %6, i1$ %7, i1$ %8, i1$ %9) {
%10:
br label %body
%body:
drv %6 1
%13 = prb %6
%14 = prb %0
%15 = and i1 %13 %14
drv %7 %15
%17 = prb %7
%18 = prb %1
%19 = and i1 %17 %18
drv %8 %19
%21 = prb %8
%22 = prb %2
%23 = and i1 %21 %22
drv %9 %23
br label %check
%check:
wait %body, %0, %1, %2, %6, %7, %8
}
proc @n276 (i32$ %0, i32$ %1, i32$ %2, i1$ %3, i1$ %4, i1$ %5) (i32$ %6) {
%7:
br label %body
%body:
drv %6 0
%10 = prb %3
br %10 label %if_true %if_false
%check:
wait %body, %0, %1, %2, %3, %4, %5
%if_true:
%13 = prb %0
drv %6 %13
br label %if_exit
%if_false:
br label %if_exit
%if_exit:
%17 = prb %4
br %17 label %if_true0 %if_false0
%if_true0:
%19 = prb %1
drv %6 %19
br label %if_exit0
%if_false0:
br label %if_exit0
%if_exit0:
%23 = prb %5
br %23 label %if_true1 %if_false1
%if_true1:
%25 = prb %2
drv %6 %25
br label %if_exit1
%if_false1:
br label %if_exit1
%if_exit1:
br label %check
}
proc @n277 (i1$ %0, i1$ %1, i1$ %2, i32$ %3, i32$ %4, i32$ %5, i32$ %6, i1$ %7, i1$ %8, i1$ %9, i1$ %10, i1$ %11, i1$ %12, i32$ %13, i1$ %14) (i32$ %15, i32$ %16, i32$ %17, i32$ %18, i1$ %19) {
%20:
br label %init
%init:
%22 = prb %0
%23 = prb %1
wait %check, %0, %1
%check:
%25 = prb %0
%26 = cmp eq i1 %22 0
%27 = cmp neq i1 %25 0
%posedge = and i1 %26 %27
%28 = prb %1
%29 = cmp eq i1 %28 0
%30 = cmp neq i1 %23 0
%negedge = and i1 %29 %30
%event_or = or i1 %posedge %negedge
br %event_or label %event %init
%event:
%32 = prb %1
%33 = not i1 %32
br %33 label %if_true %if_false
%if_true:
drv %16 0
drv %17 0
drv %18 0
drv %19 0
br label %if_exit
%if_false:
%40 = prb %2
br %40 label %if_true0 %if_false0
%if_exit:
br label %20
%if_true0:
%43 = prb %10
br %43 label %if_true1 %if_false1
%if_false0:
br label %if_exit0
%if_exit0:
br label %if_exit
%if_true1:
%47 = prb %7
br %47 label %if_true2 %if_false2
%if_false1:
br label %if_exit1
%if_exit1:
%50 = prb %11
br %50 label %if_true3 %if_false3
%if_true2:
drv %16 0
br label %if_exit2
%if_false2:
%54 = prb %16
%55 = add i32 %54 1
drv %16 %55
br label %if_exit2
%if_exit2:
br label %if_exit1
%if_true3:
%59 = prb %8
br %59 label %if_true4 %if_false4
%if_false3:
br label %if_exit3
%if_exit3:
%62 = prb %12
br %62 label %if_true5 %if_false5
%if_true4:
drv %17 0
br label %if_exit4
%if_false4:
%66 = prb %17
%67 = add i32 %66 1
drv %17 %67
br label %if_exit4
%if_exit4:
br label %if_exit3
%if_true5:
%71 = prb %9
br %71 label %if_true6 %if_false6
%if_false5:
br label %if_exit5
%if_exit5:
%74 = prb %15
%75 = prb %13
%76 = add i32 %74 %75
drv %15 %76
%78 = prb %14
drv %19 %78
br label %if_exit0
%if_true6:
drv %18 0
br label %if_exit6
%if_false6:
%83 = prb %18
%84 = add i32 %83 1
drv %18 %84
br label %if_exit6
%if_exit6:
br label %if_exit5
}
entity @addr_gen (i1$ %clk_i, i1$ %rst_ni, i1$ %enable_i) (i32$ %addr_o, i1$ %done_o) {
%pointer = sig i32 1024
%bound_0 = sig i32 3
%bound_1 = sig i32 3
%bound_2 = sig i32 1
%index_0 = sig i32
%index_1 = sig i32
%index_2 = sig i32
%stride_0 = sig i32 4
%stride_1 = sig i32 16
%stride_2 = sig i32 256
%max_0 = sig i1
%max_1 = sig i1
%max_2 = sig i1
%enable_0 = sig i1
%enable_1 = sig i1
%enable_2 = sig i1
%active_stride = sig i32
%done_d = sig i1
%done_q = sig i1
%0 = prb %pointer
drv %addr_o %0
%2 = prb %done_d
drv %done_o %2
inst @n274 (%bound_0, %bound_1, %bound_2, %index_0, %index_1, %index_2) (%max_0, %max_1, %max_2)
inst @n275 (%max_0, %max_1, %max_2, %enable_0, %enable_1, %enable_2) (%enable_0, %enable_1, %enable_2, %done_d)
inst @n276 (%stride_0, %stride_1, %stride_2, %enable_0, %enable_1, %enable_2) (%active_stride)
inst @n277 (%clk_i, %rst_ni, %enable_i, %pointer, %index_0, %index_1, %index_2, %max_0, %max_1, %max_2, %enable_0, %enable_1, %enable_2, %active_stride, %done_d) (%pointer, %index_0, %index_1, %index_2, %done_q)
}
proc @n234 () (i1$ %0, i1$ %1) {
%2:
wait %4 for 1ns
%4:
drv %1 0
wait %7 for 1ns
%7:
drv %1 1
wait %10 for 1ns
%10:
%loop_count = var i32
store i32 100 %loop_count
br label %loop_body
%loop_body:
%13 = load i32 %loop_count
%14 = cmp neq i32 %13 0
br %14 label %loop_continue %loop_exit
%loop_exit:
wait %17 for 1ns
%loop_continue:
drv %0 1
wait %20 for 500ps
%20:
drv %0 0
wait %23 for 500ps
%23:
%24 = load i32 %loop_count
%25 = sub i32 %24 1
store i32 %25 %loop_count
br label %loop_body
%17:
halt
}
entity @testbench () () {
%clk_i = sig i1
%rst_ni = sig i1 1
%enable_i = sig i1 1
%addr_o = sig i32
%done_o = sig i1
%dut = inst @addr_gen (%clk_i, %rst_ni, %enable_i) (%addr_o, %done_o)
inst @n234 () (%clk_i, %rst_ni)
}
Output in the VCD file is always 0
for active_stride
, except when enable_2 = 1
, then it is 0x100
as expected. It seems that the events issue during @n276
get reordered such that the initial drive to 0
may overtake the other events.
fabianschuiki commented
This repository is now deprecated in favor of the implementation within LLHD. Tracking continues there.