I am trying to implement clock gating logic manually using a latch and an AND gate as shown in the figure.
The latch has an enable (en
) and a done signal which are both asserted only for one clock cycle. When the en
is asserted, the output of the latch (latch_en
) needs to be a one until reset(done
) is asserted. When the done
signal is asserted the output of the latch needs to be a zero until en
is asserted again. The latch is transparent on the negative half of the clock (clk
).
Images below show the waveforms for the behavior of the latch from RTL simulation and post synthesis gate level netlist simulation. I am using Synopsys DC for performing synthesis. I am using Modelsim for simulation. Additionally, for synthesis, we are using TSMC 28 nm technology.
The RTL simulation before synthesis works as expected.
Issue description
The gate level netlist simulation after synthesis does not work as expected. The latch_en
is high only for the negative half of the clk
during which the latch is transparent. It does not continue to hold the signal value.
The following is my SystemVerilog RTL for the clock gating unit:
module latch_clkgating (
input logic clk,
input logic en,
input logic done,
output logic gated_clk);
logic latch_en;
always_latch begin
if(~clk) begin
if(done)
latch_en <= 0;
else if (en)
latch_en <= 1;
end
end
assign gated_clk = clk & latch_en;
endmodule
What can be done to get the expected behavior of the latch post synthesis?
Below are the supporting images
This is the RTL simulation
This is the gate level netlist simulation
This is the basic idea I want to implement
-
\$\begingroup\$ Gating a clock is usually a BAD IDEA. The RIGHT way to handle them usually involves letting the device's clock fabric run continuously, and route clock enables to the downstream logic to tell them which clock edges to use and to ignore. If you want to do something different, then you have to get right down into the weeds of setup and hold times, which, at a quick glance at your timing diagrams, the RTL is making ASSUMPTIONS about them that the synthesis isn't. Those 'coincident' edges where latch_en drops early are not coincident. When does the sensitivity list trigger the process? \$\endgroup\$Neil_UK– Neil_UK2025年08月07日 06:19:46 +00:00Commented Aug 7 at 6:19
-
\$\begingroup\$ @Neil_UK, for an FPGA, you're absolute right: gating clocks is nearly always a disastrous one-way ticket to instability and timing problems. However, the OP's using an ASIC ("for synthesis, we are using TSMC 28 nm technology") and clock gating is common in ASICs for all the good reasons. But they'd use a better primitive to do it than a home-made DFF-fall-edge-AND circuit \$\endgroup\$TonyM– TonyM2025年08月07日 10:57:54 +00:00Commented Aug 7 at 10:57
-
\$\begingroup\$ @rachana, What should I do when someone answers my question? \$\endgroup\$toolic– toolic2025年08月09日 10:26:49 +00:00Commented Aug 9 at 10:26
1 Answer 1
Synthesis tools require specific Verilog coding patterns in order to infer common logic gates. The way you coded the latch might not match one of the recognized patterns of your synthesis tool. Furthermore, not all synthesis tools are guaranteed to support all the same Verilog code patterns.
You should read the documentation that comes with your synthesis tool. Perhaps there are guidelines for writing Verilog code for latches and clock gates.
You should also read the synthesis report log files that your tool generated. Look for error or warning messages and also look for what type of logic was inferred. If you do not see that a latch was inferred, that may be the reason the post-synthesis simulation results do not match the RTL simulation results.
Also take a look at the Verilog gate netlist code and look for a latch there.
Perhaps if you simplify the latch code, the synthesis tool will recognize it as such. For example, create an internal enable
signal for the input to the latch from your en
and done
inputs:
module latch_clkgating (
input logic clk,
input logic en,
input logic done,
output logic gated_clk);
logic enable; // Enable input to the latch
logic latch_en; // Latch output
always_ff @(posedge clk) begin
if (en) begin
enable <= 1;
end else if (done) begin
enable <= 0;
end
end
always_latch begin
if (~clk) begin
latch_en <= enable;
end
end
assign gated_clk = clk & latch_en;
endmodule
I recommend you reset all your logic as well using a separate reset input to the module.
Another important consideration when using latches is to be careful with your synthesis timing constraints. Refer to the documentation.
Explore related questions
See similar questions with these tags.