4

I'm just starting to learn Verilog on my own after taking a course on VHDL. I'm having a trouble understanding the order in which behavioral statements are executed. Here is the code in question.

// This file is an experiment into the order in which verilog executes it's statements

module MainCircuit(clk, start);

    parameter cycles = 8;
    input clk;
    input start;
    //input [15:0] data;

    integer i;

    always @(posedge clk)
    begin
        if(start)
        begin
            i=0;
            
            repeat(cycles)
            begin
                @(posedge clk) $display("%d\ti = %d", $time, i);
                i = i + 1;
            end
        end
    end

endmodule

module tester;

    reg clk;
    wire start;

    assign start = 1'b1;
    initial clk = 1'b0;

    MainCircuit myMain(clk, start);
    initial repeat(40)
    begin
        #5 clk = 1'b1;
        #5 clk = 1'b0;
    end

endmodule

and here is the output:

                  15    i =           0
                  25    i =           1
                  35    i =           2
                  45    i =           3
                  55    i =           4
                  65    i =           5
                  75    i =           6
                  85    i =           7
                 105    i =           0
                 115    i =           1
                 125    i =           2
                 135    i =           3
                 145    i =           4
                 155    i =           5
                 165    i =           6
                 175    i =           7
                 195    i =           0
                 205    i =           1
                 215    i =           2
                 225    i =           3
                 235    i =           4
                 245    i =           5
                 255    i =           6
                 265    i =           7
                 285    i =           0
                 295    i =           1
                 305    i =           2
                 315    i =           3
                 325    i =           4
                 335    i =           5
                 345    i =           6
                 355    i =           7
                 375    i =           0
                 385    i =           1
                 395    i =           2

I don't understand why i isn't being reset to zero at each positive clock edge. Does myMain remember where it is in execution and continue from there each time clock is called? If so, where is it stopping? And how would all this be synthesized?

Two other minor questions:

I tried to write

start <= 1'b01;

instead of

assign start = 1'b01;

in the second module, but it wouldn't work. Why not?

The second question is: what's with the weird spacing in the output?

toolic
  • 57,801
  • 17
  • 75
  • 117
Chris Morin
  • 51
  • 1
  • 5

1 Answers1

4
  1. always @(posedge clk) doesn't automatically execute at every clock edge. An always block can only restart once it has reached the end of it's current execution (you can't simultaneously have two threads executing a block). Your always block doesn't reach end until after 8 clocks because it is stuck in your (repeat cycles) loop. Only after 8 posedge clocks can it finish the loop, hit the end of the always block, and then restart on the next posedge.

  2. start <= 1'b1 is a nonblocking assignment and can only be executed inside an always block.

  3. The $display is probably reserving enough space to print the max value of a 32bit decimal. If you don't want all the extra spaces try %0d instead of %d.

Tim
  • 35,413
  • 11
  • 95
  • 121
  • Thanks, its my first time posting here and I was worried that the verilog section wouldn't be very active. 1) So does the execution hang at`@(posedge clk) $display("%d\ti = %d", $time, i);`? Also, how is this synthesized to logic? 2) Which way is the standard way of hard-wiring the input to a circuit? I thought that both assign and always were blocks of procedural code but I see hard-wiring as more of a gate-level thing. – Chris Morin Apr 01 '12 at 04:04
  • @ChrisMorin Its probably less active than most sections but most questions look like they get at least one or two answers. Yes, the execution does pause on the display line. @(posedge clk) just means "wait here until the positive edge of the clock, then run the next statement". I'm not sure exactly how to answer 'how is this synthesized'... I guess it would just create a counter that runs up to 8 bits and then repeats, similar to your output. As for how to hard wire an input, there's nothing wrong with an assign statement to set a port on the DUT to a constant value. – Tim Apr 01 '12 at 06:35