在参加VHDL课程后,我才开始学习Verilog。我无法理解执行行为陈述的顺序。这是有问题的代码。
//This files 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
这是输出
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
我不明白为什么我没有在每个正时钟边沿重置为零。 myMain是否记得它在执行中的位置并且每次调用时钟时都会从那里继续?如果是这样,它在哪里停止? 这一切将如何合成?
另外两个小问题:
我试着写 开始< = 1'b01; 代替 assign start = 1'b01; 在第二个模块但它不会工作。为什么不呢?
第二个是输出中奇怪的间距是什么?
感谢您的时间。
答案 0 :(得分:4)
always @(posedge clk)
不会在每个时钟边沿自动执行。 always块只能在它到达当前执行结束时才重新启动(你不能同时让两个线程执行一个块)。在8个时钟之后,您的始终阻止不会达到end
,因为它会卡在您的(重复循环)循环中。只有在8个posedge时钟后才能完成循环,点击始终块的结尾,然后在下一个posedge重新启动。
start <= 1'b1
是一个非阻塞分配,只能在always块内执行。
$ display可能保留足够的空间来打印32位十进制的最大值。如果您不想要所有额外的空格,请尝试%0d
而不是%d
。