在Verilog中递增计数器变量:组合或顺序 [英] Incrementing a counter variable in verilog: combinational or sequential
问题描述
我正在为数据路径电路实现FSM控制器.控制器在内部增加一个计数器.当我在下面模拟程序时,计数器从未更新.
I am implementing an FSM controller for a datapath circuit. The controller increments a counter internally. When I simulated the program below, the counter was never updated.
reg[3:0] counter;
//incrementing counter in combinational block
counter = counter + 4'b1;
但是,如 Verilog最佳做法中所述,在创建额外的变量counter_next时-递增变量并仅在顺序块中递增计数器,计数器就会递增.
However, on creating an extra variable, counter_next, as described in Verilog Best Practice - Incrementing a variable and incrementing the counter only in the sequential block, the counter gets incremented.
reg[3:0] counter, counter_next;
//sequential block
always @(posedge clk)
counter <= counter_next;
//combinational block
counter_next = counter + 4'b1;
为什么在前一种情况下计数器不增加?我有什么想念吗?
Why doesn't the counter get incremented in the previous case? Anything I'm missing?
推荐答案
好.我假设您在第一个示例中遗漏了一些代码,因为它甚至不应该编译.但是,我想我还是可以为您澄清这个问题.
Ok. I'm assuming that you left some code out of your first example since that shouldn't even compile. However, I think I can elucidate the issue for you anyway.
在一个看起来像这样的块中:
In a block that looks like this:
always @(*) begin // or always @(counter)
counter = counter + 4'b1;
end
有两个问题.
1)计数器从未初始化.在仿真开始时,所有"reg"类型变量均为X,因此将X加1就是X.
1) counter is never initialized. All 'reg' type variables are X at the start of simulation time so adding 1 to X is X.
2)这就是组合循环.该块对'counter'的变化很敏感,因此即使假设'counter'初始化为0,仿真器也将永远循环更新'counter',并且仿真时间将永远不会延长.即
2) This is what is considered a combinational loop. The block is sensitive to changes in 'counter' so even assuming that 'counter' was initialized to 0 the simulator would loop forever updating 'counter' and simulation time will never advance. i.e.
always block executes -> counter = 1
counter has changed
always block executes -> counter = 2
counter has changed
and so on...
如果要在其中放置$ display语句,则可能会看到此循环.否则,只会出现模拟器已挂起且不会写入任何波形的情况.
If you were to put a $display statement in there you could see this loop occurring. Otherwise it'll just appear that the simulator is hung and no waves will be written.
第二个示例起作用的原因是您有一个触发器破坏了组合循环.在每个时钟沿,"counter"都将更新为"counter_next"的当前值.然后,组合块执行一次(并且仅执行一次)以计算新版本的"counter_next".
The reason the 2nd example works is that you have a flip-flop breaking the combinational loop. At each clock edge 'counter' gets updated with the current value of 'counter_next'. Then the combinational block executes once (and only once) to calculate the new version of 'counter_next'.
通过复位子句或初始语句,您仍然缺少对计数器"的初始化,以确保完整性.
You're still lacking an initialization of 'counter' through a reset clause or initial statement so for completeness.
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;
end
这篇关于在Verilog中递增计数器变量:组合或顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!