我正在尝试在verilog中创建一个计数器,该计数器计算已经有多少个时钟周期,一千万个时钟周期后它将重置并重新启动。
我创建了一个二十四位加法器模块以及另一个包含二十四个D触发器的模块,用于存储从加法器输出的周期数。
然后我希望有一个处于计数状态的状态机,直到超过一千万个周期,然后它进入复位状态。
这听起来不错吗?问题是我不知道如何实现状态机。
有人能指出我可以帮助我的网站/书吗?
感谢
答案 0 :(得分:4)
正如Paul S已经提到的,如果你希望你的计数器在溢出后继续计数,就不需要状态机。你可以这样做(未经测试,可能包含拼写错误):
module overflow_counter (
clk,
reset,
enable,
ctr_out
);
// Port definitions
input clk, reset, enable;
output [23:0] ctr_out;
// Register definitions
reg [23:0] reg_ctr;
// Assignments
assign ctr_out = reg_ctr;
// Counter behaviour - Asynchronous active-high reset
initial reg_ctr <= 0;
always @ (posedge clk or posedge reset)
begin
if (reset) reg_ctr <= 0;
else if (enable)
begin
if (reg_ctr == 10000000) reg_ctr <= 0;
else reg_ctr <= reg_ctr + 1;
end
end
endmodule
当然,通常你会使用参数,因此每次你想要一个溢出的计数器时你不必制作一个自定义模块。我会把它留给你;)。
[编辑] 以下是一些可以帮助您了解FSM的文档。我刚搜索谷歌的“verilog状态机”:
我还没看过第一篇论文,所以我不能对此发表评论。第二个显示了各种风格的编码FSM,其中3个总是阻止样式,我强烈推荐,因为它更容易调试(状态转换和FSM输出整齐地分开)。链接似乎已关闭,因此这里是the cached Google result。
答案 1 :(得分:3)
您不需要状态机。你已经在柜台有州。您需要做的就是检测要包装的值并在此时将0加载到计数器
在伪代码中:
if count == 10000000 then
nextCount = 0;
else
nextCount = count + 1;
...或...
nextCount = count + 1;
if count == 10000000 then
resetCount = 1;
答案 2 :(得分:2)
状态机并不太棘手。使用localparam(宽度,不要忘记宽度,这里没有显示,因为它只是一位)来定义状态的标签。然后创建两个注册变量(state_reg
,state_next
)。 _reg
变量是您的实际注册。 _next
变量是“wire reg”(可以分配到组合内部的线路始终阻止)。要记住的两件事是在组合中始终X_next = X_reg;
阻塞(然后是组合逻辑的其余部分)和X_reg <= X_next;
在顺序始终阻塞中。你可以对特殊情况有所了解,但如果你坚持这些简单的规则,那么事情就应该有效。我尽量不使用实例化来处理非常简单的事情,因为Verilog对加法器有很大的支持。
由于我使用FPGA,我将初始值分配给寄存器,而不使用复位信号。我不确定,但对于ASIC设计我认为是相反的。
localparam STATE_RESET = 1'b0, STATE_COUNT = 1'b1;
reg [23:0] cntr_reg = 24'd0, cntr_next;
reg state_reg = STATE_COUNT, state_next;
always @* begin
cntr_next = cntr_reg; // statement not required since we handle all cases
if (cntr_reg == 24'd10_000_000)
cntr_next = 24'd0;
else
cntr_next = cntr_reg + 24'd1;
state_next = state_reg; // statement required since we don't handle all cases
case (state_reg)
STATE_COUNT: if (cntr_reg == 24'd10_000_000) state_next = STATE_RESET;
endcase
end
always @(posedge clk) begin
cntr_reg <= cntr_next;
state_reg <= state_next;
end
我发现this book非常有帮助。本书还有VHDL版本,因此您可以并排使用Rosetta Stone来学习VHDL。