2011-10-28 42 views
4

我正在尝试在verilog中创建一个计数器,计算出有多少个时钟周期,并且在一千万个时钟周期后它将重置并重新开始。24位计数器状态机

我创建了一个二十四位加法器模块以及另一个包含二十四个D触发器的模块,用于存储加法器输出的周期数。

然后我想要一个处于计数状态的状态机,直到一千万个周期过去,然后它进入重置状态。

这听起来是正确的?问题是我不知道如何实现状态机。

任何人都可以指向我的网站/书籍,可以帮助我吗?

谢谢

回答

3

你不需要状态机。你已经在柜台上了。所有你需要做的是在这一点上

在伪代码检测你想和负载0包装的价值到您的计数器:

if count == 10000000 then 
    nextCount = 0; 
else 
    nextCount = count + 1; 

......或者......

nextCount = count + 1; 
if count == 10000000 then 
    resetCount = 1; 
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

2

状态机不是太棘手。使用localparam(宽度不要忘记宽度,这里没有显示,因为它只是一个位)来为你的状态定义标签。然后创建两个reg变量(state_reg,state_next)。变量_reg是您的实际注册表。变量_next是一个“导线注册”(一个可以分配到组合总是块内的导线)。需要记住的两件事是在连续always块中的组合逻辑总块(然后是组合逻辑的其余部分)和X_reg <= X_next;中执行X_next = X_reg;。你可以喜欢特殊情况,但如果你坚持这些简单的规则,那么事情应该是正常的。我尝试不使用实例化来实现像加法器这样的非常简单的事情,因为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。

+0

我看不出你的例子中状态是怎样完成的。没有什么依赖于它。如果该代码放置在FPGA中,合成器将优化与状态相关的代码。 – Darhuuk

+0

我回答了原来的问题。 –