Verilog 24位计数器状态机

Verilog 24位计数器状态机,verilog,fpga,Verilog,Fpga,我试图在verilog中创建一个计数器,它可以计算出已经有多少个时钟周期,在1000万个时钟周期之后,它将重置并重新启动 我创建了一个24位加法器模块以及另一个包含24个D触发器的模块,用于存储加法器输出的循环计数 然后我想要一个状态机,它处于计数状态,直到一千万个周期过去,然后它进入重置状态 这听起来对吗?问题是我不确定如何实现状态机 有人能给我指一个能帮我解决这个问题的网站/书吗 谢谢,你不需要状态机。您在计数器中已经有状态。您所需要做的就是检测您想要包装的值,并在该点将0加载到计数器中 在

我试图在verilog中创建一个计数器,它可以计算出已经有多少个时钟周期,在1000万个时钟周期之后,它将重置并重新启动

我创建了一个24位加法器模块以及另一个包含24个D触发器的模块,用于存储加法器输出的循环计数

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

这听起来对吗?问题是我不确定如何实现状态机

有人能给我指一个能帮我解决这个问题的网站/书吗


谢谢,你不需要状态机。您在计数器中已经有状态。您所需要做的就是检测您想要包装的值,并在该点将0加载到计数器中

在伪代码中:

if count == 10000000 then
  nextCount = 0;
else
  nextCount = count + 1;
……或者

nextCount  = count + 1;
if count == 10000000 then
  resetCount = 1;

正如Paul S已经提到的,如果您希望计数器在溢出后继续计数,则不需要状态机。您可以这样做(未经测试,可能包含拼写错误):

模块溢出\u计数器(
中华电力有限公司,
重置,
使可能
ctr_out
);
//端口定义
输入时钟、复位、启用;
输出[23:0]电流输出;
//寄存器定义
注册[23:0]注册中心;
//任务
分配ctr\u out=reg\u ctr;
//计数器行为-异步主动高复位

初始注册中心状态机并不太复杂。使用localparam(带宽度,不要忘记宽度,此处未显示,因为它只有一位)为您的状态定义标签。然后创建两个reg变量(
state\u reg
state\u next
)。
\u reg
变量是您的实际寄存器。
\u next
变量是一个“wire reg”(可分配给组合块内部的导线)。要记住的两件事是做
X_next=X_reg
在组合always块(然后是组合逻辑的其余部分)和
X_reg中,我看不出在您的示例中状态实现了什么。没有什么取决于它。如果该代码放在FPGA中,合成器将优化与状态相关的代码。
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
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