FPGARelated.com
Forums

Delays in verilog

Started by Gerr August 11, 2005
Hi,

I'm a bit confused by the do's and dont's of delay's (#) in verilog,
like the following snippet :

always @(posedge clk)
	load_r <= #1 load;

I'm trying to learn some tricks by reading other peoples code
(opencores.org, mostly), and a lot of projects are using delays like
this. All the books tell you not to use delays in verilog, though,
because it's not synthesizable.

So what's the use of those delays in code that's ment to be synthesized
?

Thanks,

In this case, 'not synthesisable' means the same thing as ignored - the
value of the delay will be set to (nominally) zero for synthesis.

The delay is needed for some simulation purpose, possibly because the
block that is being fed by your signal load_r has some hold time
requirement with respect to the clock.  This is likely to be the case
if the downstream block is a simulation model of something that
actually requires hold time in real life.

Some people like to put the delay in as you've shown so that when
they look at wavfeforms in their simulation they clearly see the clock
transition, a delay, then the register changes.

The delay is ignored by synthesis tools.

Delays are also useful for modeling input/output delays in testbenches
to mimic what happens in I/O buffers.

I hope this helps.

John Providenza

On 10 Aug 2005 23:36:00 -0700, "Gerr" 
<gertvierman@hotmail.com> wrote:

>I'm a bit confused by the do's and dont's of delay's (#) in verilog, >like the following snippet : > >always @(posedge clk) > load_r <= #1 load;
In the jargon, this is intra-assignment delay on a nonblocking assignment. It works very nicely to model the clock-to-output delay of a flip-flop. Synthesis tools will happily ignore it. It can make your simulation waveforms look much prettier. Lots of people like to do it. Please, whatever you do, DON'T do it. I know that I'll get into trouble with some Verilog experts by saying that, but it's just a crazy thing to do. Here's why.... Consider the following rather useful synthesis idiom: always @(posedge clk) begin out_reg <= 2'd0; // Default value if (condition_1) out_reg <= 2'd1; if (condition_2) out_reg <= 2'd2; end Especially if there are complicated nested conditions, this can be a very neat way of describing default conditions - there's no need to check that you have written the right "else" clauses to mop up all the default possibilities. However, let's now suppose that you added delays to the assignments - but you missed one: out_reg <= #1 2'd0; if (condition_1) out_reg <= #1 2'd1; if (condition_2) out_reg <= 2'd2; // oops, forgot the delay Now imagine that we execute the code, and condition_1 is false but condition_2 is true. The first assignment schedules an update on out_reg one time unit into the future. The second assignment is not executed at all, because its "if" conditional is false. The third assignment schedules an update in the immediate future. "<= #T" delay in Verilog is a transport delay, so both updates remain active. So the assignment that we wanted to happen, out_reg <= 2'd2 , will take place immediately but, one time unit later, it will be superseded by the default assignment. The design is broken in a way that's very hard to diagnose, and what's worse, simulation and synthesis will disagree (synthesis will give the answer that you wanted, because it ignores the delays). The only way to get this right is to ensure that all assignments have exactly the same delay. This is completely absurd, and impossible to maintain across a large always block - especially if it calls tasks. DON'T DO IT. No delays, please. If you really want to delay the output, then make your clocked assignments to an internal variable, and copy that on to the output port using a continuous assign with a delay. In that way the delay is centralised in one place and is not subject to the kind of error I described. Note that VHDL does not suffer this problem, because assignment delays are (by default) inertial and so the intuitive "most recent assignment wins" rule works as you'd expect, even if the delays are different. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL, Verilog, SystemC, Perl, Tcl/Tk, Verification, Project Services Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, BH24 1AW, UK Tel: +44 (0)1425 471223 mail:jonathan.bromley@doulos.com Fax: +44 (0)1425 471573 Web: http://www.doulos.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
The only purpose of these delays (at least in most OpenCores designs)
is to allow a better view of the signals in the waveform viewer. If
the signals of a clocked process change at the same time of the clock
it could be confusing.

Regards

Javier 


On 10 Aug 2005 23:36:00 -0700, "Gerr" <gertvierman@hotmail.com> wrote:

> >Hi, > >I'm a bit confused by the do's and dont's of delay's (#) in verilog, >like the following snippet : > >always @(posedge clk) > load_r <= #1 load; > >I'm trying to learn some tricks by reading other peoples code >(opencores.org, mostly), and a lot of projects are using delays like >this. All the books tell you not to use delays in verilog, though, >because it's not synthesizable. > >So what's the use of those delays in code that's ment to be synthesized >? > >Thanks,
my understanding of verilog is that the code below is umbigous,
so it is a bad practice anyway, with or without delays.
The reason of the ambiguity is that assignements are
analyzed in parallel, so if condition 2 is true, you
don't know if the synthezaizer implemented 
  out_reg <= 2'd0; 
or
  out_reg <= 2'd2;



On Fri, 12 Aug 2005, Jonathan Bromley wrote:

> Consider the following rather useful synthesis idiom: > > always @(posedge clk) begin > out_reg <= 2'd0; // Default value > if (condition_1) > out_reg <= 2'd1; > if (condition_2) > out_reg <= 2'd2; > end > > Especially if there are complicated nested conditions, > this can be a very neat way of describing default > conditions - there's no need to check that you have > written the right "else" clauses to mop up all the > default possibilities. However, let's now suppose > that you added delays to the assignments - but you > missed one: > > out_reg <= #1 2'd0; > if (condition_1) > out_reg <= #1 2'd1; > if (condition_2) > out_reg <= 2'd2; // oops, forgot the delay > > Now imagine that we execute the code, and condition_1 > is false but condition_2 is true. The first assignment > schedules an update on out_reg one time unit into the future. > The second assignment is not executed at all, because > its "if" conditional is false. The third assignment > schedules an update in the immediate future. > > "<= #T" delay in Verilog is a transport delay, so both > updates remain active. So the assignment that we > wanted to happen, > > out_reg <= 2'd2 , > > will take place immediately but, one time unit later, it > will be superseded by the default assignment. The design > is broken in a way that's very hard to diagnose, and > what's worse, simulation and synthesis will disagree > (synthesis will give the answer that you wanted, because > it ignores the delays). > > The only way to get this right is to ensure that all > assignments have exactly the same delay. This is > completely absurd, and impossible to maintain across > a large always block - especially if it calls tasks. > DON'T DO IT. No delays, please. > > If you really want to delay the output, then make your > clocked assignments to an internal variable, and copy > that on to the output port using a continuous assign > with a delay. In that way the delay is centralised in > one place and is not subject to the kind of error I > described. > > Note that VHDL does not suffer this problem, because > assignment delays are (by default) inertial and so > the intuitive "most recent assignment wins" rule > works as you'd expect, even if the delays are different. >
-- Tullio Grassi ====================================== Univ. of Maryland-Dept. of Physics | College Park, MD 20742 - US | Tel +1 301 405 5970 | Fax +1 301 699 9195 | ======================================
On Mon, 15 Aug 2005 03:21:49 +0200, Tullio Grassi
<tgrassi@mail.cern.ch> wrote:

>my understanding of verilog is that the code below is umbigous,
>> always @(posedge clk) begin >> out_reg <= 2'd0; // Default value >> if (condition_1) >> out_reg <= 2'd1; >> if (condition_2) >> out_reg <= 2'd2; >> end
>so it is a bad practice anyway, with or without delays. >The reason of the ambiguity is that assignements are >analyzed in parallel, so if condition 2 is true, you >don't know if the synthezaizer implemented > out_reg <= 2'd0; >or > out_reg <= 2'd2;
This is completely untrue. Signal updates scheduled by nonblocking assignments *for a given moment of time* are performed in the same order in which the assignments were executed. I stand by my statement that this is "a useful synthesis idiom" provided you don't make the mistake of adding delays to the assignments. -- Jonathan Bromley
I would agree... I do this quite often in VHDL using the same idea..
statements are executed is sequence within a process... processes are
executed in parallel.
this is a good way to generate strobes which have one on condition and
multiple off conditions.  I just have a section of "defaults" after the
clock.  Quite nice in state machines to keep states uncluttered... and it
means states only care about the tasks each state knows about (or cares
about).

Simon

"Jonathan Bromley" <jonathan@oxfordbromley.u-net.com> wrote in message
news:430ca95b.2463367@news.freeserve.com...
> On Mon, 15 Aug 2005 03:21:49 +0200, Tullio Grassi > <tgrassi@mail.cern.ch> wrote: > > >my understanding of verilog is that the code below is umbigous, > > >> always @(posedge clk) begin > >> out_reg <= 2'd0; // Default value > >> if (condition_1) > >> out_reg <= 2'd1; > >> if (condition_2) > >> out_reg <= 2'd2; > >> end > > >so it is a bad practice anyway, with or without delays. > >The reason of the ambiguity is that assignements are > >analyzed in parallel, so if condition 2 is true, you > >don't know if the synthezaizer implemented > > out_reg <= 2'd0; > >or > > out_reg <= 2'd2; > > This is completely untrue. > > Signal updates scheduled by nonblocking assignments > *for a given moment of time* are performed in the > same order in which the assignments were executed. > > I stand by my statement that this is "a useful > synthesis idiom" provided you don't make the mistake > of adding delays to the assignments. > > -- > Jonathan Bromley