4

I am new to verilog and am finding the execution of verilog tricky. How does the execution occurs in a verilog program. Say I have 2 modules and a testbench-

module module1(clock,A,B,C);
    input A,B,clock;
    output C;
    assign c=A+B;
endmodule

module module2(clock,A,B,C);
    input A,B,clock;
    output C;

    assign C=A-B;

endmodule

module testbench;
    reg A,B,clock;
    wire C;
    module1 m1(clock,A,B,C);
    module2 m2(clock,A,B,C);
    initial
        clock=1'b0;
    always
        #4 clock=~clock;
endmodule

I understand all initial blocks start at time 0.But are these initial blocks then executed sequentially i.e. if a initial block has more than one lines, will all of them executed sequentially or concurrently. Also, how does module execution take place?Will module1 start first as it appears before module2 in testbench and finish completely and then module2 start or both run concurrently. What happens when clock changes after 4sec, will the module running stop in between if clock changes or will it complete its previous execution and then start again with new clock?

2 Answers 2

3

In verilog, instantiation of a module means adding physical hardware to your board.

Modules are nothing but small hardware blocks that work concurrently. Every module can have some procedural blocks, continuous assignment statements or both.

Every procedural block executes concurrently, similar applies to continuous assignment statements.

I refer as this:

Procedural  blocks: initial, always etc. blocks.
Continuous assignment: assign, force etc.

So, no matter in what sequence you instantiate modules, all are going to work in parallel.

Here comes the concept of timestamp. Each timestamp contains active, inactive and NBA regions. Refer to figure here:

Verilog Procedural Blocks

For each timestamp, all the instances are checked in every region. If any execution is to be done in let's say module1 then it is done, in parallel, other module let's say module2 is also checked. If there is some dependency between the modules, then they are executed again.

Here, in your example, c is a single wire, and output of both modules, this generates a race around condition between modules, which is of course not good.

Think from hardware perspective. Two or more different hardware blocks can have same inputs but can not have same outputs. So, the output wires must be different.

module testbench; 
  reg A,B,clock; 
  wire C1,C2; // different wires

  module1 m1(clock,A,B,C1); 
  module2 m2(clock,A,B,C2); 
  initial clock=1'b0; 
  always #4 clock=~clock; 
endmodule

Also, here the modules have continuous assignment, so there is no effect of clock. No the modules are running in between the clocks also. It's just that there are no events scheduled in those timestamps.

As we know now, all procedural blocks are executed in parallel. But the contents inside procedural block is executed sequentially. To make the contents in concurrent, fork..join construct is used. For example:


initial
  begin
    a<=0;
    #5;
    b<=1;  // b is assigned at 5ns
  end

initial
  fork
    a<=0;
    #5;
    b<=1; // b is assigned at 0ns
  join

Refer to Verilog Procedural Blocks, Concurrent and Sequential Statements sites for further information.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks..I have a further question...do continuous assignment statements within a single module run concurrently or sequentially?I mean if in a module I have more than one assignment statements how will they execute?
Yes. For example: assign b = x|y ; assign c = x&y; will both occur concurrently. Note that the LHS is different. One will synthesize to and (producing c as output) and other to or (producing b as output) gate. Both working in parallel.
1

Another way to think about this from a simulation point of view

All of the initial, always, and continuous assign statements in your design execute concurrently starting at time 0. It doesn't matter whether they are in different modules or not - they are all equally concurrent. The elaboration step flattens out all of your module instances. All that is left are hierarchical names for things that were inside those modules.

Now, unless you are running the simulation on massively parallel CPUs (essentially running on the real synthesized hardware does), there is no way to actually run all of these processes concurrently, A software simulator has to choose one process to go first. You just can't rely on which one it chooses.

That is what the Verilog algorithm does. It puts everything scheduled to run at time 0 into an event queue (active queue), and starts executing each process one at time. It executes each process until it finishes, or it has to block waiting for some delay or a signal to change. It the process has to block, it gets suspended and put onto another queue. Then the next process in the current queue starts executing, and these steps keep repeating until the current queue is empty.

Then the scheduling algorithm picks another queue to become the active queue, and advances time if that queue is scheduled with some delay.

Comments

Your Answer

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