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
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