-
Notifications
You must be signed in to change notification settings - Fork 39
Description
Having a replaceable cell for latches would be very helpful for designs with complex latch-D conditions to avoid accidental synthesis inference of non-unate paths.
In system verilog there is no way to express which part of an always_latch block is supposed to be the enable signal of a latch (from here on out: G), and which part is supposed to constitute the data path towards the data input (from here on out: D). In most situations intent is clear, i.e. a clock should drive G and all other logic should be folded into the computation of D.
However, in more complex cases like a register file with multiple ports (e.g. CV32E40Ps latch register file) and muxing between ports, there is no clear language-based way to express this, and a synthesis tool might infer non-unate paths by folding the clock-signal into the computation of D, rather than using it to drive G.
My suggestion would be to implement two simple single- (or multi-) bit latch tech cells, tc_latch and tc_latch_rst, which allow to uniquely describe which part of a latch assignment expression is used to drive G and which part is used to drive D to avoid non-unate paths. Whether high- and low- transparent versions are required is to be determined.
For brevity, I would suggest the following starting point for tc_latch_rst:
module tc_latch_rst (
logic clk_i,
logic rst_ni,
logic data_i,
logic data_o
);
always_latch begin
if (~rst_ni) begin
data_o <= '0;
end else if (clk_i) begin
data_o <= data_i;
end
end
endmodule