我正在为数据路径电路实现一个FSM控制器。控制器在内部递增计数器。当我模拟下面的程序时,计数器从未更新过。
reg[3:0] counter;
//incrementing counter in combinational block
counter = counter + 4'b1;但是,在创建一个额外的变量counter_next (如Verilog Best Practice - Incrementing a variable中所述)并仅在顺序块中递增计数器时,计数器将递增。
reg[3:0] counter, counter_next;
//sequential block
always @(posedge clk)
counter <= counter_next;
//combinational block
counter_next = counter + 4'b1;为什么在前一种情况下计数器不会递增?我遗漏了什么吗?
发布于 2012-12-30 05:12:25
好的。我假设您在第一个示例中遗漏了一些代码,因为这些代码甚至不应该编译。无论如何,我想我可以为你澄清这个问题。
在如下所示的块中:
always @(*) begin // or always @(counter)
counter = counter + 4'b1;
end有两个问题。
1)计数器从不初始化。所有'reg‘类型的变量在模拟开始时都是X,所以X加1就是X。
2)这被认为是一个组合循环。该模块对“计数器”的变化很敏感,因此即使假设“计数器”被初始化为0,模拟器也会一直循环更新“计数器”,模拟时间永远不会提前。即
always block executes -> counter = 1
counter has changed
always block executes -> counter = 2
counter has changed
and so on...如果你在里面放一条$display语句,你可以看到这个循环发生了。否则,模拟器将被挂起,并且不会写入任何wave。
第二个例子起作用的原因是你有一个触发器打破了组合循环。在每个时钟沿,'counter‘被更新为'counter_next’的当前值。然后,组合块执行一次(并且只执行一次),以计算新版本的“counter_next”。
您仍然缺少通过reset子句或initial语句初始化'counter‘,以确保完整性。
reg [3:0] counter;
reg [3:0] counter_next;
always @(*) begin
counter_next = counter + 1;
end
always @(posedge clk or negedge rst_l) begin
if (!rst_l)
counter <= 4'b0;
else
counter <= counter_next;
endhttps://stackoverflow.com/questions/14083475
复制相似问题