9
\$\begingroup\$

We have two types of procedural blocks in verilog: initial and always block. The statements inside these blocks are executed sequentially. Does that affect the timing of these signals? For example, in the code below:

initial begin
  a = 1'b0;
  b = 1'b1;
end

Will the assignment of b will take place a small time after the assignment of a? If not what will be the difference between this and the concurrent blocks in verilog, i.e.,assign statements?

assign a = 1'b0;
assign b = 1'b1;
\$\endgroup\$
1
  • 2
    \$\begingroup\$ imagine assign statements as "connect these two wires together". For eg: assign a = b is connect wire a to wire/reg b. or assign a = 0 is connect a to GND. This is what the tools are doing. an assign is the equivilent of a wire-join (or you could even call it an alias, if you will). \$\endgroup\$
    – stanri
    Commented Aug 1, 2014 at 11:46

3 Answers 3

6
\$\begingroup\$

Does that affect the timing of these signals?

Not really.

Yes a&b are evaluated sequentially but in the same simulator timestep, not seqential in terms of electronic design.

initial begin
  a = 1'b0;
  b = 1'b1;
end

a and b are essentially evaluated in parallel. but your simulator can not do that, the only time that this needs careful consideration is if you rely on previous results.

The following are just examples and would imply latches in some case and should not be used in RTL like this.

always @(posedge clk) begin
  a = y;
  b = a; //this is b=y
end

is not the same as:

always @(posedge clk) begin
  b = a;     //This is old y
  a = y;
end

For clocked systems (implying flip-flops) we use non-blocking (<=) the following 2 examples are the same:

always @(posedge clk) begin
  a <= y;
  b <= a; //this is old y
end

always @(posedge clk) begin
  b <= a;     //This is old y
  a <= y;
end
\$\endgroup\$
5
  • \$\begingroup\$ What do you mean by simulator time-step? \$\endgroup\$
    – sarthak
    Commented Aug 2, 2014 at 13:47
  • \$\begingroup\$ @user3671483 We are simulating electronics which has many circuits in parallel, we do not have the ability to calculate all of the values in one cpu cycle of the simulator so we use multiple cpu cycles to calculate the electronics values in time steps. These will be the accuracy of which you can model time in your simulation. Delta cycles are used to resolve combinatorial loops. \$\endgroup\$ Commented Aug 2, 2014 at 17:33
  • \$\begingroup\$ How does the simulator determines the time-step? \$\endgroup\$
    – sarthak
    Commented Aug 3, 2014 at 4:07
  • \$\begingroup\$ @user3671483 Timescale directives `timescale 1ns/1ps has 1 picosecond precision. \$\endgroup\$ Commented Aug 3, 2014 at 7:43
  • \$\begingroup\$ Using blocking assignments in clocked always blocks in RTL is ok provided you do not read the results from a different always block. \$\endgroup\$ Commented Mar 30, 2017 at 13:19
7
\$\begingroup\$
initial begin
  a = 1'b0;
  b = 1'b1;
end

The initial block is a mechanism for describing how you want your signals to behave initially. When synthesised, the tools use these values as the initial vales for each register. The registers are not assigned these values sequentially, they have these values from the start.

In the case of simulation, the CPU processes the instructions given, one after the other

assign a = b;

As I mentioned in my comment, assigns are a synthesizable construct that essentially mean "connect this wire to this reg/wire". In reality, that assignment is going to end up optimised by the tools.

With all asynchronous assignments, the timing implications are going to depend on how long the wire is between 'a' and 'b'. If a mux is used, or any other processing performed (say, assign a = b + c), that will also have an inherent propagation delay. How long are these in reality? Probably much shorter than a clock cycle. However you must be careful when going mad with assign statements. For example, this may get you into trouble with your timing constraints.

assign OutputQLLParity = QLLDout[23:21]^
                        QLLDout[20:18]^
                        ...
                        QLLDout[5:3]^
                        QLLDout[2:0];

Heading on to always blocks.

always @(posedge clk) begin
  a <= y;
  b <= a;
end

Notice the clk in the sensitivity list. This means that this process is going to only be executed (for lack of a better word) on the positive edge of a clock.

Say, for example, that y changes after the clock rising edge. Even though y has changed, a is only going to be updated on the next rising edge.

A is not updated directly on the rising edge, it's updated a tiny bit after that (this is called delta time). So b will only change on the clock cycle after that, a clock cycle after a.

Here, a handy timing diagram for you:

          _____      _____      _____      _____
clk  ____/     \____/     \____/     \____/     \____
             ________________________________________
y    _______/       
                     ________________________________
a    _______________/       
                                _____________________
b    __________________________/       

So what does this look like in hardware?

They're not technically d-types in actuality, but it gives a good idea. A clocked register is used that propagates the input to the output on the rising clock edge.

schematic

simulate this circuit – Schematic created using CircuitLab

Last note:

See the difference in assignments. = is a blocking assignment, <= is non-blocking.

It is possible to mix and match these in some cases, but if you're starting out with this, and just generally for your own sanity in the beginning, a good rule of thumb is = is for assigns, initial blocks and processes without sensitivity lists*. <= for processes with sensitivity lists.

* bit hazy about this. I don't use combinatorial processes in verilog very often.

\$\endgroup\$
9
  • \$\begingroup\$ Just a brief nitpick: "initial" blocks may be synthesizable if you're targeting an FPGA. \$\endgroup\$
    – Jules
    Commented Aug 1, 2014 at 14:49
  • \$\begingroup\$ @Jules Good point. Clarified that part :) \$\endgroup\$
    – stanri
    Commented Aug 1, 2014 at 16:12
  • \$\begingroup\$ Bigger nit-pick: = is blocking assignment. <= is nonblocking assignment. \$\endgroup\$
    – The Photon
    Commented Aug 1, 2014 at 16:33
  • \$\begingroup\$ @ThePhoton Hah. You're correct. I've never really understood how the blocking/non blocking terminology can be applied to hw. Understand in terms of simulating initial blocks, but it doesn't make sense with assigns and processes. But then I am a VHDL girl through and through. Will reword that part. \$\endgroup\$
    – stanri
    Commented Aug 1, 2014 at 16:40
  • \$\begingroup\$ @StaceyAnne, The answer by @pre-randomize explains the difference, as far as it's ever made a difference to me. It's more about what happens if you have several statements in a block and some of the rhs's depend on some of the lhs's. In an assign statement, I've never seen <= used; I don't think it's even allowed. \$\endgroup\$
    – The Photon
    Commented Aug 1, 2014 at 16:40
0
\$\begingroup\$

The example which you have taken is of blocking statements.
Yes, initial & always blocks are sequential whereas assign statements are concurrent.
In the initial & always block a=1'b0 will be assigned before b=1'b1 is assigned. Whereas in the case of assign statements, a & b will be assigned concurrently.

In the case of non-blocking statements "<=", if the value assigned to a depends on b then a will be assigned first, then b. But since a value depends on b, the value of a is modified after that. This is called discrete event simulation

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.