Open EclecticGriffin opened 4 days ago
This is a great writeup; thank you!
I just wanted to stake out one "philosophical" argument about this:
Is the
undef
value used during convergence equivalent to'x
?
Assuming that 'x
means Verilog's 'x
, my opinion is that the Calyx project should not attempt to adopt any Verilog semantics around undefinedness. Verilog's treatment of 'x
is super complicated, probably for good reasons, and we should not create any constraints of the form "the Calyx semantics should easily map onto Verilog's semantics." Of course, Verilog-as-a-target may introduce certain constraints on what is practical! But to whatever extent we can, we should design the undefinedness semantics we want, and only later figure out how to realize those semantics when generating code.
And, to jot down initial gut reactions without thinking about them too hard:
@control
? -> "Default to 0," in the sense that, after the convergence loop has finished, any @control
ports that are still undef
become 0
instead as a post-processing pass.I reserve the right to be entirely wrong about all three of these!
Once again time to discuss undefinedness and its semantic implications. This is sort of a grab bag issue for a couple of things that have come up during some of the recent Cider 2 work. There is motivating code for a lot of this, so the issue might be a little long, but to summarize the top-level questions go something like this:
undef
value used during convergence equivalent to'x
? If not, what are the semantics of the latter?@control
annotations fit into our semantic model? It would not be correct to replaceundef
with 0 in all cases which returns us to question 1.Example 1 - Missing Ref Cells
Here's a silly piece of example code I wrote while testing ref cells.
In the current version of Cider 2 this program will immediately error since
my_add
usesresult.out
in a continuous assignment andresult
, being a ref cell, is only defined during the later invoke and not otherwise. Should this be a hard error? Should the value read fromresult.out
be undef?This raises the additional question: Should ref cells be allowed in continuous assignments?
Example 2 - Writing undef to registers
the
tests/correctness/pipelined-mac.futil
program was tripping an undefined write error:This program invokes a mac written in calyx which has the following signature
and has a the following group
This group is the first thing executed by the control of the mac, so it always runs.
The main component invokes mac three times.
The first two are well-behaved, but this last one isn't since it never supplies a value to data_valid which causes the write to main.mac.data_valid_reg to be undefined, triggering the error. In this case, it is pretty clear that the component was assuming data_valid was zero when not driven Changing the last invoke to:
resolves the problem and generates the expected results for the test
Example 3 - TCAM
The
lpm.futil
correctness test for TCAM looks like:Note that the invokes are only supplying one of
write_en
andsearch_en
. The TCAM definition contains the following two groups:which are unconditionally executed first thing in the program
Subsequently creating the same error condition as in example 2. And as with that example these registers are used to direct the control flow of the component.