如何使用Verilog设置计数器以秒计数

时间:2019-06-07 07:46:17

标签: verilog

我正在尝试使用Verilog制作第二个计数器和毫秒计数器。问题是,每当我运行模拟时,第二个计数器(clk_1sec)和毫秒计数器(clk_1msec)的值都固定为0。

“我的模拟”显示正确的结果,直到代码的第19行,但是模拟没有显示clk_1secclk_1msec的正确结果(这两个计数器的值固定为0)

module clk_gen(clk_5k, reset, loopcount, clk_1sec, clk_1msec);

input clk_5k, reset;
output [14:0] loopcount;
output clk_1sec, clk_1msec;
reg [14:0] loopcount;
reg clk_1sec, clk_1msec;

always @(posedge clk_5k or negedge reset)

begin

  if (~reset)
    begin
      clk_1sec <= 0; clk_1msec <= 0; loopcount <= 0;
    end

  else
    loopcount <= loopcount + 2'b10;
    begin
      if (loopcount += 13'b1001110001000)
        clk_1sec = ~clk_1sec;

      else if (loopcount += 3'b101)
        clk_1msec = ~clk_1msec;
      end
    end
  end
end
endmodule 

预期结果是,当clk_1sec的值为loopcount(十进制)时,loopcount + 5000应该更改其值,而当{{ 1}}是clk_1msec(十进制)。

2 个答案:

答案 0 :(得分:1)

您的代码中存在一些误解:

  • 您始终在时钟内部使用阻塞分配。您应该只使用非阻塞分配。
  • 您正在使用13位常量与15位寄存器(循环计数)一起操作。您应该使用15位常量。
  • 最重要的是,您正在使用一种不正确的方法来判断loopcount的值是否为5的倍数(以毫秒为单位)。不是二的幂的倍数很难在硬件中实现。您应该使用两个时钟信号的幂(对于这些应用程序,常见的时钟是32.768 kHz),或者应该使用一个计数器对周期进行计数以获取毫秒,而使用一个计数器对毫秒进行计数以获取一秒钟。

假设时钟为32.768 kHz,则模块将如下所示:

module clk_gen (
  input wire clk32768,
  input wire reset,
  output reg [15:0] loopcount,
  output wire clk_1sec,
  output wire clk_1msec
  );

  assign clk_1sec  = loopcount[15];  // 1 exact second (32768 counts)
  assign clk_1msec = loopcount[5];   // not quite 1ms, but 0.97ms

  always @(posedge clk32768 or negedge reset) begin
    if (~reset)
      loopcount <= 16'd0;
    else
      loopcount <= loopcount + 16'd1;
  end
endmodule

如果您需要坚持使用5KHz时钟和/或需要精确的毫秒级测量(在时钟振荡器的限制范围内),则可以这样做:

module clk_gen (
  input wire clk_5k,
  input wire reset,
  output reg clk_1sec,
  output reg clk_1msec
  );

  reg [2:0] counter_cycles;  // counts from 0 to 4 cycles => 1ms
  reg [9:0] counter_msecs;   // counts from 0 to 999 msecons => 1s

  always @(posedge clk_5k or negedge reset) begin
    if (~reset) begin
      clk_1sec <= 1'b0;
      clk_1msec <= 1'b0;
      counter_cycles <= 3'd0;
      counter_msecs <= 10'd0;
    end
    else begin
      if (counter_cycles == 3'd4) begin
        counter_cycles <= 3'd0;
        clk_1msec <= ~clk_1msec;
        if (counter_msecs == 10'd999) begin
          counter_msecs <= 10'd0;
          clk_1sec <= ~clk_1sec;
        end
        else begin
          counter_msecs <= counter_msecs + 10'd1;
        end
      end
      else begin
        counter_cycles <= counter_cycles + 3'd1;
      end
    end
  end
endmodule

您可以在以下位置编辑/模拟此版本 https://www.edaplayground.com/x/3CjH

答案 1 :(得分:0)

问题是LIB与第一个begin/end的嵌套不正确。您的缩进与编译器看到的不匹配。而且我确定您的意思是else而不是==