The compiler can initialize wires in a non-deterministic order when passing in to ref cells. We suspect this has to do with HashMap iterators somewhere in the verilog backend.
An MRE to reproduce looks like this:
import "primitives/core.futil";
component comp_with_ref() -> () {
cells {
ref my_ref_reg = std_reg(8);
}
wires {
group some_group {
some_group[done] = 1'b0 ? 1'b1; //this allows us to have an "empty" group without the compiler getting mad. Not important to reproduce AFAIK.
}
}
control {
some_group;
}
}
component main() -> () {
cells {
my_actual_reg = std_reg(8);
my_ref_comp = comp_with_ref();
}
wires {
}
control {
seq {
par {
seq {
invoke my_ref_comp[my_ref_reg=my_actual_reg]()();
}
}
}
}
}
And can be compared with /target/debug/calyx <path to above file> -b verilog --disable-verify -o tmp.v && ./target/debug/calyx <path to above file> -b verilog --disable-verify -o tmp2.v && diff tmp.v tmp2.v && rm tmp.v tmp2.v
@sampsyo suggested that these lines may the culprit. Which also suggests this wire_decls function may be to blame.
Tried to write down all of the relevant information here, but in case I missed anything here is the original Slack thread.
The compiler can initialize wires in a non-deterministic order when passing in to
ref
cells. We suspect this has to do withHashMap
iterators somewhere in the verilog backend.An MRE to reproduce looks like this:
And can be compared with
/target/debug/calyx <path to above file> -b verilog --disable-verify -o tmp.v && ./target/debug/calyx <path to above file> -b verilog --disable-verify -o tmp2.v && diff tmp.v tmp2.v && rm tmp.v tmp2.v
@sampsyo suggested that these lines may the culprit. Which also suggests this
wire_decls
function may be to blame.Tried to write down all of the relevant information here, but in case I missed anything here is the original Slack thread.