Open
Description
Consider:
hw.module @Test(in %x : i8, in %clock: i1) {
// All of these are equivalent to `var logic x` .
// logic-type variable, assign to x.
%logicvar = sv.logic : !hw.inout<i8>
sv.assign %logicvar, %x : i8
// Same but use keyword "reg" (reg x; = var logic x;)
%regvar = sv.reg : !hw.inout<i8>
sv.assign %regvar, %x : i8
// sv.reg supports initialization operand, demonstrate.
%regwithinit = sv.reg init %x : !hw.inout<i8>
}
Which we emit as:
// Generated by CIRCT 1.57.1g20231016_fa69518
module Test( // logic-test.mlir:1:1
input [7:0] x, // logic-test.mlir:1:20
input clock // logic-test.mlir:1:32
);
logic [7:0] logicvar = x; // logic-test.mlir:5:15
reg [7:0] regvar; // logic-test.mlir:9:13
assign regvar = x; // logic-test.mlir:10:3
reg [7:0] regwithinit = x; // logic-test.mlir:13:18
endmodule
These are all variables of type logic
but we problematically inline the assignment to the variable (one-time initialization) instead of emitting as a continuous assignment. We probably shouldn't have two ops for this, but regardless this is not equivalent.
To see this in action, take a look at this EDA playground example (slightly modified from above):
https://edaplayground.com/x/UfjT
Which produces the following output (truncated):
x 1 x 1
x 0 x 0
x 1 x 1
x 0 x 0
x 1 x 1
$stop at time 1000 Scope: Go File: testbench.sv Line: 12
Done