-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIRRTL] FRT: treats different encodings of register resets differently #7678
Comments
One of the reasons why I want to drill in to this issue, is because its hard for the FullResetTransform to determine if a register already has a reset or not (when determining if it should add one), and one valid option is for it to always add a reset unconditionally. We can then let regular optimizations handle the Invalid value. So:
After FullResetTransform:
and then, through regular evaluation:
|
That's not valid because if the reset signal is the same as the one used by the register to specify a different (i.e. non-zero) reset value, it will straight up override the user-specified reset. And I think it's actually worse than that. Because sync reset is just a mux, the reset used for FSRT could be further up the chain of muxes feeding the input to the register. I wouldn't call those muxes "reset", but if it's the same signal, then FSRT has now inserted a coverage hole. Consider the following: FIRRTL version 4.0.0
circuit Foo: %[[
{
"class": "circt.FullResetAnnotation",
"target": "~Foo|Foo>extra_reset",
"resetType": "sync"
}
]]
public module Foo:
input c : Clock
input in0 : UInt<8>
input in1 : UInt<8>
input reset : UInt<1>
input extra_reset : UInt<1>
output o : UInt<8>
reg reg : UInt<8>, c
connect reg, mux(reset, in0, mux(extra_reset, in1, reg))
connect o, reg This gives: // Generated by CIRCT firtool-1.87.0
module Foo(
input c,
input [7:0] in0,
in1,
input reset,
extra_reset,
output [7:0] o
);
reg [7:0] reg_0;
always @(posedge c) begin
if (extra_reset)
reg_0 <= 8'h0;
else if (reset)
reg_0 <= in0;
else if (extra_reset)
reg_0 <= in1;
end // always @(posedge)
assign o = reg_0;
endmodule The mux branch assigning |
Yeah, I sorta chalk this one up to "you get what you asked for" :) And I am not sure if this proves anything interesting, but you can get the same problems with async reset as well: FIRRTL version 4.0.0
circuit Foo: %[[
{
"class": "sifive.enterprise.firrtl.FullAsyncResetAnnotation",
"target": "~Foo|Foo>extra_reset"
}
]]
public module Foo:
input c : Clock
input in0 : UInt<8>
input in1 : UInt<8>
input reset : UInt<1>
output o : UInt<8>
node extra_reset = asAsyncReset(reset)
reg reg : UInt<8>, c
connect reg, mux(reset, in0, in1)
connect o, reg module Foo(
input c,
input [7:0] in0,
in1,
input reset,
output [7:0] o
);
reg [7:0] reg_0;
always @(posedge c or posedge reset) begin
if (reset)
reg_0 <= 8'h0;
else
reg_0 <= reset ? in0 : in1;
end // always @(posedge, posedge)
`ifdef ENABLE_INITIAL_REG_
`ifdef FIRRTL_BEFORE_INITIAL
`FIRRTL_BEFORE_INITIAL
`endif // FIRRTL_BEFORE_INITIAL
initial begin
if (reset)
reg_0 = 8'h0;
end // initial
`ifdef FIRRTL_AFTER_INITIAL
`FIRRTL_AFTER_INITIAL
`endif // FIRRTL_AFTER_INITIAL
`endif // ENABLE_INITIAL_REG_
assign o = reg_0;
endmodule |
Both registers have a reset, although the first uses the
regreset
representation, and the latter uses a regularreg
driven by a mux.gives:
The second register ends up with a needless double-reset added by FRT, when it already had a reset.
The text was updated successfully, but these errors were encountered: