在Verilog中递增计数器变量:组合或顺序 [英] Incrementing a counter variable in verilog: combinational or sequential

查看:220
本文介绍了在Verilog中递增计数器变量:组合或顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为数据路径电路实现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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆