firrtl-spec
firrtl-spec copied to clipboard
Consider/Add "Strict Connect" Operation
Now that partial connect is removed and connect has width truncation/extension behavior, we should consider adding a new connect operation that has stricter semantics. I.e., a connect operation which mandates: (1) known widths, (2) type equivalence, and (3) width equivalence.
We've been using this inside CIRCT for almost a year and it's proved incredibly useful.
I'm using made-up syntax here (<==
). The following example shows what is legal and illegal:
wire a: Uint<1>
wire b: Uint<2>
wire c: UInt
a <== a ; this is legal
b <== b ; this is legal
c <== c ; this is illegal
a <== b ; this is illegal
a <== c ; this is illegal
b <== a ; this is illegal
b <== c ; this is illegal
It continues to be true that type equivalence holds, e.g.,:
wire d: Uint<3>
wire e: SInt<3>
d <== e ; this is illegal
d <= e ; this is still illegal
The main benefit of this is that it is a connect that is amenable to folding (replacing a connect operation with its operand) without any creation of a new pad/tail operation. This also may help provide strict connect semantics to Chisel.
Note: the strict connect op cannot be used to exclusively replace connect in situations where uninformed widths are present.
Why is a <== b
and b <== a
considered illegal? According to your proposal, the newly introduced operation mandates
- known widths
- type equivalence
Point 1. is clearly fulfilled (the widths are 1 for a
and 2 for b
) and according to Section "Type Equivalence" signed/unsigned are to be treated as equal as follows:
An unsigned integer type is always equivalent to another unsigned integer type regardless of bit width, and is not equivalent to any other type. Similarly, a signed integer type is always equivalent to another signed integer type regardless of bit width, and is not equivalent to any other type.
So I would say that, despite the obvious intention of yours, point 2. is also fulfilled and, hence, a <== b
and b <== a
in your example above should be legal.
Ideas:
- Re-formulate the above criteria to be (1) equal widths (implying known widths) and (2) type equivalence
- If the operator is adapted, the examples should be extended as follows
to have an example with known and matching width so that the reader sees how strict it really is.wire a: UInt<2> wire b: SInt<2> a <== b ; this is illegal
- Re-think whether the current notion of type equivalence captures the correct concept. In my opinion, it should by
UInt<a> == UInt<b>
$\Leftrightarrow$a == b
to begin with.
Updated the above. This was missing an additional restriction on equivalent widths.
Fair point about Uint<2> <== SInt<2>
being illegal. That was implicitly always the case (as that violates type equivalence), but I can add an example to make it explicit.