0
\$\begingroup\$

I am getting totally confused because contradictory things are given.

https://class.ece.uw.edu/371/peckol/doc/Always@.pdf

In this pdf, it is said that whether the 'always block' will be executed sequentially or parallelly will depend on the assignment used. If nonblocking->parallely else sequentially. But many answers like this

Are Verilog if blocks executed sequentially or concurrently? Says it is always executed sequentially. So I have two doubts

  1. Is the 'always' block executed sequentially or parallelly?
  2. If sequentially, how do nonblocking statements execute?
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Verilog describes hardware - it's not being "executed in parallel." You are either laying down transistors (or configuring gate arrays) to do all the things all the time. Sequentially just means that it will have a flip-flop at the end of a chain of circuits. \$\endgroup\$ Dec 19, 2019 at 22:40
  • \$\begingroup\$ I think post you linked is referring to how the code parser evaluates your logic, instead of what is being generated in hardware. The always@ block can describe logic sequentially (key word is describe) while synthesizing something that is totally parallel. If it realizes a circuit with flip-flops, then you have sequential logic. \$\endgroup\$ Dec 19, 2019 at 22:48
  • 3
    \$\begingroup\$ @AaronD.Marasco Actually the "always @" blocks will get executed in a simulator; sometimes they'll get executed in ways that can't be replicated by a synthesized circuit, in which case (we hope!) the simulation fails. I don't have an example to hand for you, but synthesizable Verilog is a subset of simulatable Verilog. \$\endgroup\$
    – TimWescott
    Dec 19, 2019 at 22:52
  • \$\begingroup\$ Race condition between two always blocks driving the same signal is one example. That's fine in simulation, but the synthesizer will complain bitterly. \$\endgroup\$ Dec 20, 2019 at 8:14

3 Answers 3

1
\$\begingroup\$

Nonblocking assignments simply defer the actual update of the value until all of the statements in the current always block are evaluated. It has the appearance that all of the statements run "concurrently" or "in parallel", but if this was actually the case, it creates an ambiguity: what happens when you assign the same reg two different values in the same always block? If things are truly concurrent, this is a race condition and the new value will be unpredictable. However, the language semantics dictate something else: that the statements must be evaluated sequentially. If you assign the same reg from multiple places in the same always block, the last one takes precedence. Hence, you can consider that the statements are "evaluated" sequentially, but the regs are all updated with new values concurrently.

The synthesizer will convert the HDL code into logic that implements the equivalent functionality. In hardware, things will naturally be evaluated in parallel if there are no data dependencies, but the ordering of the statements would determine the precedence - which value is selected to be loaded into the next register or logic gate.

\$\endgroup\$
5
  • \$\begingroup\$ Suppose in an always block x<=2; and after that we have x<=3; so after the execution of Always block , x will have value 3 right? \$\endgroup\$ Dec 20, 2019 at 9:11
  • \$\begingroup\$ Yep, that's correct. \$\endgroup\$ Dec 20, 2019 at 16:55
  • \$\begingroup\$ If you have something like c <= x and afterwards c <= {c, &c} will the last statement be equivalent to c <= {x, &x} or not? \$\endgroup\$
    – Rhi
    Jul 19, 2021 at 8:43
  • \$\begingroup\$ No, because the value of c will not actually change until the end of the block, so at the end of the block you would see c update to a new value based on the old value of c and having no relation to x. \$\endgroup\$ Jul 19, 2021 at 9:19
  • \$\begingroup\$ @alex.forencich ok thanks, I have posted a question concerning this here electronics.stackexchange.com/questions/576042/… \$\endgroup\$
    – Rhi
    Jul 19, 2021 at 9:37
2
\$\begingroup\$

You have to separate the software execution semantics in simulation from the hardware semantics in synthesis. Verilog/SystmeVerilog gets used for both. And sometimes the terminology gets reused in different ways, especially the word sequential.

Each always block represents a concurrent process or behavior based on the procedural code you write associated with the block. Certainly styles of code (but not all) can be synthesized into hardware, and that hardware is typically divided into two categories of logic: sequential and combinatorial.

Sequential logic stores state information over time where as combinatorial logic is totally dependent on the immediate inputs to the block. In software, sequential code simply means the is a defined order of execution between statements.

always @(*) begin
      a = b + c;
      d = a + e;
   end

The code above represents combinatorial logic, but the code between the begin/end executes sequentially. If you change the code to

always @(posedge clk) begin
      a = b + c;
      d = a + e;
end

now you still have sequentially executing statements, but the code now represents a mixture of sequential and combinational logic (only d is sequential). But if you replace the blocking to non-blocking assignments

  always @(posedge clk) begin
          a <= b + c;
          d <= a + e;
  end

You still have two assignment statements executing in sequence, but since the update to a is deferred, you now have two sequential logic elements in parallel. Its the same has if you had written the last example in separate always blocks.

  always @(posedge clk) begin
          a <= b + c;
  end
  always @(posedge clk) begin
          d <= a + e;
  end
\$\endgroup\$
0
\$\begingroup\$

Your course is being a bit loose on the details.

Something that makes VHDL and Verilog somewhat tricky is that they were originally designed as languages for describing hardware for simulation. They were then later re-used as languages to describe hardware for synthesis.

To understand HDL simulation there are first a couple of basic concepts we must understand.

The first is simulation time, Simulation time is not tied to real-time, it essentially advances when all code paths are waiting for something (either a time delay or a

The second is the concept of time deltas, a time delta represents an infinitesimally small step of simulation time.


Back to always blocks, the contents of an always block in simulation are executed sequentially. A "blocking" assignment takes effect immediately.

A non-blocking assignment reads it's input immediately, but it's result does not take effect until the end of the current time-delta. So, from the programmers perspective, the results of all non-blocking assignments on a given time-delta take effect at the same time.

This is vitally important, because it allows us to describe systems involving multiple "always" blocks in a deterministic manner. The clock triggers all the always blocks to run, the blocks make their calculations, and only once all the blocks have run and we get to the end of the time delta do the results take effect. We can effectively define the state of the system after the clock edge.

As a general rule blocking assignments in clock-triggered always blocks should not be read from anywhere outside the always block in which they are set. Doing so tends to lead quickly to non-deterministic code.

In always blocks that are triggered by all their input signals it tends to matter less, since those blocks will be re-run until all their inputs settle.

Unless you know precisely what you are doing you should avoid getting fancy with always block sensitivity lists, they may work in simulation but they are likely to not work correctly in synthesis.


Synthesis is a different ball-game from simulation, there are many things you can do in Verilog that will work find in simulation but will either cause errors or misbehavior when synthesizing . Essentially the synthesis tool is looking for patterns, clocked always blocks become logic with flip-flops at the output, assignment statements and combinatorial always blocks just become combinatorial logic. If you throw non-standard stuff at it you are likely to get misbehaviour or synthesis failures.

Having said that there is a lot you can do in synthesis too. As long as you keep it within one always block so the order is defined, the compiler will happilly unroll your loops, inline your functions and tasks, and turn your temporary variables into signals, so that the synthesised logic produces the same result as the simulation.

\$\endgroup\$
1
  • \$\begingroup\$ Verilog/VHDL languages were both designed with synthesis in mind; that was VHDL's initial charter. It's just that it took longer for synthesis tools to appear on the market that could handle it. \$\endgroup\$
    – dave_59
    Dec 20, 2019 at 6:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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