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?
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.
start <= 1'b1
is a nonblocking assignment and can only be executed inside an always block.
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
.