assignment from multiple always blocks

R

Remco Poelstra

Guest
Hi all,

I've a problem with describing a special counter.
The counter is incremented by a clock but needs to be reset by an
external trigger (and by a reset signal).
I want to implement it as follows:
----------------
module shift_inhibit( clk,fsclk,reset,out );
input clk;
input fsclk;
input reset;
output out;
reg [4:0] counter;
wire out;

assign out = (counter<=23);

always @(fsclk)
begin
if(reset) //reset is active low
counter = 5'b11111;
end

always @(negedge reset)
begin
counter = 5'b11000;
end

always @(negedge clk)
begin
if(reset)
counter = counter + 1;
end
endmodule
---------------------------
The simulator thinks this is OK, but the synthesizer complains about the
assignment from multiple always blocks. How can I solve that?

Thanks in advance.

Kind regards,

Remco Poelstra
 
What you described will (without constsraints on the inputs) cause race conditions
(read up on metastability) in hardware. This, as the synthesizer informs
you, isn't allowed. The easiest way to solve your problem is to recode the
behavior into a single always block. The more complex way is to have each
always block drive a unique wire and add another always block the resolves
(synchronizes the updates to) the multiple wires into a single reg.


---Matthew Hicks


Hi all,

I've a problem with describing a special counter.
The counter is incremented by a clock but needs to be reset by an
external trigger (and by a reset signal).
I want to implement it as follows:
----------------
module shift_inhibit( clk,fsclk,reset,out );
input clk;
input fsclk;
input reset;
output out;
reg [4:0] counter;
wire out;
assign out = (counter<=23);

always @(fsclk)
begin
if(reset) //reset is active low
counter = 5'b11111;
end
always @(negedge reset)
begin
counter = 5'b11000;
end
always @(negedge clk)
begin
if(reset)
counter = counter + 1;
end
endmodule
---------------------------
The simulator thinks this is OK, but the synthesizer complains about
the
assignment from multiple always blocks. How can I solve that?
Thanks in advance.

Kind regards,

Remco Poelstra
 
You should write a single always block like this. Multiple assignments
are not synthesizable.

always @(negedge clk or negedge reset)
begin
if(!reset)
counter <= 5'b11000;
else if(fsclk)
counter <= 5'b11111;
else
counter <= counter + 1;
end
 
On May 15, 12:29 am, Haris <hari...@gmail.com> wrote:
You should write a single always block like this. Multiple assignments
are not synthesizable.

always @(negedge clk or negedge reset)
  begin
   if(!reset)
     counter <= 5'b11000;
   else if(fsclk)
     counter <= 5'b11111;
   else
     counter <= counter + 1;
  end
This is not quite the same logic as the original design. In this new
version,
fsclk is synchronous to clk, in the original design it was an async
signal.

John Providenza
 
On May 15, 10:18 pm, john <jprovide...@yahoo.com> wrote:
On May 15, 12:29 am, Haris <hari...@gmail.com> wrote:

You should write a single always block like this. Multiple assignments
are not synthesizable.

always @(negedge clk or negedge reset)
begin
if(!reset)
counter <= 5'b11000;
else if(fsclk)
counter <= 5'b11111;
else
counter <= counter + 1;
end

This is not quite the same logic as the original design. In this new
version,
fsclk is synchronous to clk, in the original design it was an
signal.

John Providenza

You can consider to use a double-synchronizer to make the async signal
synchronous, named fsclk_syn. Then use it in the always block. So the
code looks like:
reg fsclk_syn1,fsclk_syn0;
always @(negedge clk or negedge reset)
begin
if(!reset)
{fsclk_syn1,fsclk_syn0}<=2'b00;
else
{fsclk_syn1,fsclk_syn0}<{fsclk_syn0,fsclk};
end

always @(negedge clk or negedge reset)
begin
if(!reset)
counter <= 5'b11000;
else if(fsclk_syn1)
counter <= 5'b11111;
else
counter <= counter + 1;
end
 
vidar schreef:
On May 15, 10:18 pm, john <jprovide...@yahoo.com> wrote:
On May 15, 12:29 am, Haris <hari...@gmail.com> wrote:

You should write a single always block like this. Multiple assignments
are not synthesizable.
always @(negedge clk or negedge reset)
begin
if(!reset)
counter <= 5'b11000;
else if(fsclk)
counter <= 5'b11111;
else
counter <= counter + 1;
end
This is not quite the same logic as the original design. In this new
version,
fsclk is synchronous to clk, in the original design it was an
signal.

John Providenza


You can consider to use a double-synchronizer to make the async signal
synchronous, named fsclk_syn. Then use it in the always block. So the
code looks like:
reg fsclk_syn1,fsclk_syn0;
always @(negedge clk or negedge reset)
begin
if(!reset)
{fsclk_syn1,fsclk_syn0}<=2'b00;
else
{fsclk_syn1,fsclk_syn0}<{fsclk_syn0,fsclk};
end
My fsclk is indeed asynchronous. So I probably need something like this.
I just don't understand what is written here, probably because I'm a bit
new to verilog. Is there some sort of tutorial that handles these kind
of constructs?

Regards,

Remco Poelstra
 
On May 18, 12:30 am, Remco Poelstra <remco.poelstra+albas...@duran-
audio.com> wrote:
vidar schreef:



On May 15, 10:18 pm, john <jprovide...@yahoo.com> wrote:
On May 15, 12:29 am, Haris <hari...@gmail.com> wrote:

You should write a single always block like this. Multiple assignments
are not synthesizable.
always @(negedge clk or negedge reset)
  begin
   if(!reset)
     counter <= 5'b11000;
   else if(fsclk)
     counter <= 5'b11111;
   else
     counter <= counter + 1;
  end
This is not quite the same logic as the original design.  In this new
version,
fsclk is synchronous to clk, in the original design it was an
signal.

John Providenza

You can consider to use a double-synchronizer to make the async signal
synchronous, named fsclk_syn. Then use it in the always block. So the
code looks like:
reg fsclk_syn1,fsclk_syn0;
 always @(negedge clk or negedge reset)
   begin
     if(!reset)
       {fsclk_syn1,fsclk_syn0}<=2'b00;
     else
       {fsclk_syn1,fsclk_syn0}<{fsclk_syn0,fsclk};
   end

My fsclk is indeed asynchronous. So I probably need something like this.
I just don't understand what is written here, probably because I'm a bit
new to verilog. Is there some sort of tutorial that handles these kind
of constructs?

Regards,

Remco Poelstra
Remco -

a) it might be useful if you told us the expected clock frequency and
the
pulse widths of your async signals.

b) the construct:
always @(negedge clk or negedge reset)
if(!reset)
is a very standard way of implying an async clear flip-flop. This
should be
covered in any standard Verilog book or tutorial. There are several
very good
tutorials on the web, just browse around. You can also look at some
samples
from OpenCores.org to get ideas on coding examples. Another source of
coding
ideas is to look at the Xilinx synthesis guide - they show the Verilog
idioms
used to create various hardware structures.

John Providenza
 

Welcome to EDABoard.com

Sponsor

Back
Top