calyx
calyx copied to clipboard
Nested `if` conditions that share combinational groups
This issue is a summary of this slack thread.
Suppose I made the following combinational group:
comb group check {
lt_1.left = reg_1.out;
lt_1.right = reg_2.out;
lt_2.left = reg_3.out;
lt_2.right = reg_4.out;
and.left = lt_1.out
and.right = lt_2.out
}
Then, could I do something like this in my control?
if lt_1.out with check {
if and.out with check {...}
}
More concretely, here's a small program that tries to do this:
import "primitives/core.futil";
import "primitives/memories/comb.futil";
component main(@go go: 1) -> (@done done: 1) {
cells {
@external mem = comb_mem_d1(32, 1, 1);
lt_1 = std_lt(32);
lt_2 = std_lt(32);
conj = std_and(1);
}
wires {
comb group check {
lt_1.left = 32'd10;
lt_1.right = 32'd11;
lt_2.left = 32'd15;
lt_2.right = 32'd16;
conj.left = lt_1.out;
conj.right = lt_2.out;
}
group write {
mem.addr0 = 1'd0;
mem.write_en = 1'd1;
mem.write_data = 32'd500;
write[done] = mem.done;
}
}
control {
if lt_1.out with check {
if conj.out with check {write;}
}
}
}
If we ran this, we'd be met with the error
Assignments from 'check' are actived here
from Calyx's well-formed pass.
This might be expected since, as per the docs, our code is maybe in violation of well-formedness:
Well-formedness: The combinational group is considered to be running during the entire execution of the control program and therefore should not have conflicting assignments with either true_c or false_c.
Perhaps this suggests that tweaking our control to say
if lt_1.out with check {
if conj.out {write;}
}
(deleting with check from the inner if) should make our program work since well-formedness says the combinational group is running through the entire execution of the control program. However, if we ran this modified program, we'd see the error
If statement has no comb group and its condition port conj.out is unstable
Is there a good way to do this kind of construction in Calyx?