Verilog execution order
I am just starting to learn Verilog on my own after taking the VHDL course. I am having trouble understanding the execution order of the behavioral statements. Here is the code in question.
//This files is an experiment into the order in which verilog executes it 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 conclusion
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 don't reset to zero on every positive edge of the clock. Does myMain mean where it is in execution and continue from there every time time is called? If so, where does it stop? And how will all this be synthesized?
Two other minor questions:
I tried to write start <= 1'b01; instead assign start = 1'b01; in the second module, but that won't work. Why not?
the second is what's with the weird spacing in the output?
Thank you for your time.
source to share
always @(posedge clk)
is not performed automatically on every edge of the clock. Always a block can only be restarted after it reaches the end of the current execution (you cannot have two threads executing a block at the same time). Your block never reaches
until 8 o'clock because it gets stuck in a loop (re-loops). Only after the 8 o'clock can finish the cycle, remove the end of the always block, and then restart it in the next position.
start <= 1'b1
is a non-blocking assignment and can only be executed inside an always block.
The $ display probably reserves enough space to print the maximum 32-bit decimal place. If you don't want all the extra spaces, try
source to share