How to avoid unwanted clock gating?

R

Ralf Hildebrandt

Guest
Hello!

I want to design some flipflops, where some of them have different
async. set/reset inputs and I want to avoid unwanted clock gatings. For
VHDL I have a quite clean solution for my problem, but not for Verilog.

Let's start with the initial problem - in VHDL:

process(reset,set,clk)
begin
if (reset='1') then
sig1<='0';
sig2<='0';
elsif (set='1') then
sig1<='1';
elsif rising_edge(clk) then
...
end if;
end process;

As can be seen, sig2 is not assigned under the "if (set='1')" condition.
Therefore if set is '1' then sig2 has to stay unchanged. Therefore
synthesis will do clock gating for sig2. Anyway - this behavior is not
what I want. For VHDL the correct solution is:

process(reset,set,clk)
begin
if rising_edge(clk) then
...
end if;
if (reset='1') then
sig1<='0';
sig2<='0';
end if;
if (set='1') then
sig1<='1';
end if;
end process;

Then sig1 becomes a flipflop with set and reset and sig2 becomes a
flipflop with only reset. Perfect.
(This solution has been discussed in comp.lang.vhdl some years ago.)


But what is the solution in Verilog? The following code is not correct:

always @(posedge reset or posedge set or posedge clk)
begin
// if /*posedge clk*/ begin
...
// end //if
if (reset=1'b1) begin
sig1<=1'b0;
sig2<=1'b0;
end //if
if (set=1'b1) begin
sig1<=1'b1;
end //if
end //always

First: this is not the desired behavior, because in case of a posedge
set event, the synchronous part (posedge clk) will be executed for sig2.
Second: this code is not accepted by Synopsys synthesis.


The straightforward solution is to split the always statement into 2
always statements: one for sig1 and one for sig2. This is somewhat ugly
especially if the always statement is a big state machine. Do you know a
different, more handy solution?


Ralf
 
Ralf Hildebrandt wrote:
Hello!

I want to design some flipflops, where some of them have different
async. set/reset inputs and I want to avoid unwanted clock gatings. For
VHDL I have a quite clean solution for my problem, but not for Verilog.

Let's start with the initial problem - in VHDL:

process(reset,set,clk)
begin
if (reset='1') then
sig1<='0';
sig2<='0';
elsif (set='1') then
sig1<='1';
elsif rising_edge(clk) then
...
end if;
end process;

As can be seen, sig2 is not assigned under the "if (set='1')" condition.
Therefore if set is '1' then sig2 has to stay unchanged. Therefore
synthesis will do clock gating for sig2. Anyway - this behavior is not
what I want. For VHDL the correct solution is:

process(reset,set,clk)
begin
if rising_edge(clk) then
...
end if;
if (reset='1') then
sig1<='0';
sig2<='0';
end if;
if (set='1') then
sig1<='1';
end if;
end process;

Then sig1 becomes a flipflop with set and reset and sig2 becomes a
flipflop with only reset. Perfect.
(This solution has been discussed in comp.lang.vhdl some years ago.)


But what is the solution in Verilog? The following code is not correct:

always @(posedge reset or posedge set or posedge clk)
begin
// if /*posedge clk*/ begin
...
// end //if
if (reset=1'b1) begin
sig1<=1'b0;
sig2<=1'b0;
end //if
if (set=1'b1) begin
sig1<=1'b1;
end //if
end //always

First: this is not the desired behavior, because in case of a posedge
set event, the synchronous part (posedge clk) will be executed for sig2.
Second: this code is not accepted by Synopsys synthesis.


The straightforward solution is to split the always statement into 2
always statements: one for sig1 and one for sig2. This is somewhat ugly
especially if the always statement is a big state machine. Do you know a
different, more handy solution?


Ralf
The issue of properly describing a flip-flop with asynchronous set and
asynchronous reset has been discussed many times here. Basically in
Verilog you can't describe it correctly in one process, even forgetting
about mixing flip-flop types in the same process. If you look at a
behavioral model for this sort of flop (like sig1 in your code) you
generally find two processes, one for the asynchronous set and clear
and another for the posedge clock part. You can often get a synthesizer
to infer this type of flop with the single-process description like:

always @ (posedge clock or posedge reset or posedge set)
if (reset) sig1 <= 0;
else if (set) sig1 <= 1;
else // posedge clock
sig1 <= D;

The problem is that this does not model the case where both set and
reset are asserted and then one or the other de-asserted, since only
the positive edge of each signal triggers the process. So while you
might actually get the synthesizer to create what you wanted, you can
run into simulation/synthesis mismatch if you ever assert both
asynchronous controls.

My first choice in Verilog would be to remove sig1 from the process
leaving the standard template for flops with a single asynchronous
control. Furthermore I would probably instantiate the correct flop
primitive rather than trying to incorrectly describe it in Verilog.
Then you'd need to generate the equations for the D input for sig1
rather than its Q output, but you'd have a design without mismatch
between behavioral simulation and synthesis.

Or you could always revert to VHDL if you can get the synthesizer
to understand the code as you wrote it. Are you trying to avoid
a multi-language design?

--
Gabor
 
Hi GaborSzakacs!


The issue of properly describing a flip-flop with asynchronous set and
asynchronous reset has been discussed many times here. Basically in
Verilog you can't describe it correctly in one process, even forgetting
about mixing flip-flop types in the same process. If you look at a
behavioral model for this sort of flop (like sig1 in your code) you
generally find two processes, one for the asynchronous set and clear
and another for the posedge clock part. You can often get a synthesizer
to infer this type of flop with the single-process description like:

always @ (posedge clock or posedge reset or posedge set)
if (reset) sig1 <= 0;
else if (set) sig1 <= 1;
else // posedge clock
sig1 <= D;
Ok. I have verified this again and found, that it depends on the
synthesis tool and maybe on the tool version as well as on the target
library.

Some years ago I noticed, that this type of description result in a
clock-gating because of the set-signal. Now I see that my actual
synthesis tool generates some logic if set is active and a flipflop is
not written in the set-branch of the if-tree. This is not exactly what I
want to have as synthesis result, but much better than clock gating.


The problem is that this does not model the case where both set and
reset are asserted and then one or the other de-asserted, since only
the positive edge of each signal triggers the process. So while you
might actually get the synthesizer to create what you wanted, you can
run into simulation/synthesis mismatch if you ever assert both
asynchronous controls.
Good point.

It seems to be that the synthesis tool is aware of the priority of the
reset- and set- input. I strongly guess that this comes from the
description of the target library data base. I can see this, if I change
the order or the reset- and the set-clause. If I chose the "wrong"
order, then the synthesis tool infers additional logic that makes sure
that one signal has higher priority than the other.

Surprisingly the synthesis result is different between the VHDL and
Verilog models - even if they are written in the style as you have
recommended. But always the difference is only some additional code for
blocking reset while set is active or vice versa.


My first choice in Verilog would be to remove sig1 from the process
leaving the standard template for flops with a single asynchronous
control.
I guess the cleanest solution is splitting the always block into parts
where all flipflops with both set and reset are in the one block and
flipflops with only reset are in the other. But this doubles the amount
of code.


Furthermore I would probably instantiate the correct flop
primitive rather than trying to incorrectly describe it in Verilog.
This is the safest way, but impossible if a high-level model is needed
where the target library is unknown. (The code has to be portable.)


Or you could always revert to VHDL if you can get the synthesizer
to understand the code as you wrote it. Are you trying to avoid
a multi-language design?
I am forced to only one language. It is about an IP core we have in VHDL
and that has to be translated to Verilog, because costumers require it.


Tanks for your recommendations and hints!
Ralf
 

Welcome to EDABoard.com

Sponsor

Back
Top