【问题标题】:Tick Counter Verilog刻度计数器 Verilog
【发布时间】:2012-09-06 07:23:15
【问题描述】:

我想知道如何为滴答计数器编写一个verilog 程序。 当快速输入为低电平时,输出滴答为高电平,每 150 ms 一个周期(每 7500000 个周期) 时钟周期为 20ns。 如果快速输入为高电平,tick 应每隔一个时钟周期变为高电平一个周期。

我在想我应该计算 clk 周期,并在满足周期数时使用该计数来输出最高的滴答声,但我似乎无法让它工作。

这是我的代码:

module tick_counter(
  input  clk,
  input  reset,
  input  fast,
  output reg tick
);

reg count;

always @(posedge clk) begin
  count <= count + 1;
  if((fast == 1)&&(count == 2)) begin
    tick <= 1;
  end
  else if(fast == 0)&&(count == 7500000)) begin
    tick <= 1;
  end
end
endmodule

【问题讨论】:

    标签: counter verilog


    【解决方案1】:

    您的计数器只有 1 位宽,您没有包括重置,您也没有在需要时将计数器归零。 ==2 只是 == 7500000 的相移。试试:

    module tick_counter(
      input  clk,
      input  reset,
      input  fast,
      output reg tick
    );
    
    reg [22:0] count;
    
    always @(posedge clk or negedge reset) begin
      if (~reset) begin
        count <= 'd0;
        tick  <=   0;
      end
      else begin
        if((fast == 1)&&(count == 2)) begin
          tick  <= 1;
          count <= 'd0;
        end
        else if(fast == 0)&&(count == 7500000)) begin
          tick  <= 1;
          count <= 'd0;
        end
        else begin
          tick  <= 0;
          count <= count + 1;
        end
      end
    end
    endmodule
    

    或者像下面这样的东西可能会合成更小:

    reg  [22:0] count;
    
    wire [22:0] comp = (fast) ? 23'd2: 23'd7500000 ;
    wire        done = count >= comp               ;
    
    always @(posedge clk or negedge reset) begin
      if (~reset) begin
        count <= 'd0;
        tick  <=   0;
      end
      else begin
        if(done) begin
          tick  <= 1;
          count <= 'd0;
        end
        else begin
          tick  <= 0;
          count <= count + 1;
        end
      end
    end
    

    【讨论】:

    • 您可能需要if((fast == 1)&amp;&amp;(count &gt;= 2)) begin,因为如果fast 在 3 到 749999 之间的某个位置变为 1,并且在 750001 之前一直保持为 1,则不会触发任何条件。
    • 否则你可以存储一个reg previous_fast,并在fast != previous_fast 时将count 设置为零。这可能会合成更小,并且不会在我上述评论的重置条件下触发tick;取决于您的要求。
    • @DaxFohl,你是对的。我添加了另一个带有共享比较器的示例,并使用 >= 这也有助于防止故障。
    【解决方案2】:

    更少的门 - 没有比较器 - 只需使用递减计数器:

    module tick_counter(  
      input  wire clk,  
      input  wire resetn,  
      input  wire fast,  
      output reg  tick);  
    
      reg  [22:0] count;  
    
      wire [22:0] load = (fast) ? 23'd2: 23'd7500000;  
      wire        done = !count;  
    
      always @(posedge clk or negedge resetn) begin  
        if (!resetn) begin  
          count <= 23'd0;  
          tick  <= 1'b0;  
        end else begin  
          tick  <= 1'b0;  
          count <= count - 23'd1;  
          if(done) begin  
            tick  <= 1'b1;  
            count <= load;  
          end  
        end  
      end  
    endmodule//tick_counter  
    

    否则,如果您更喜欢向上计数器,请反转文字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2018-04-21
      相关资源
      最近更新 更多