如何使用一个时钟脉冲使能启动计数器

时间:2016-04-26 17:13:09

标签: verilog counter

所以我试图实现一个采用一个时钟周期启用的计数器并从那里开始计数。一旦计数器完成计数,它就会发送一个时钟周期。在计数器完成计数之前,永远不会再次发送启用,并且值输入是连续的。

我在考虑使用一个reg变量,当enable = 1时,变量变为高,一旦计数器完成计数,变量变为低。我担心这可能意味着我不想要的锁存器...有更好的方法吗?

当前代码:

module Timer(
input [3:0] value,
input start_timer,
input clk,
input rst,
output reg expired
);

//counter var
reg [3:0] count;

//hold variable
reg hold;

//setting hold
always @*
begin
    if (start_timer == 1'b1)
         hold <= 1'b1;
end


//counter
if (hold == 1'b1)
begin
always @ (posedge(clk))
begin
    if(count == value - 1)
    begin
        expired <= 1'b1;
        count <= 4'b0;
        hold <= 1'b0;
    end
    else
        count <= count + 1'b1;
end
end

endmodule

1 个答案:

答案 0 :(得分:0)

嗯,你似乎走在了正确的轨道上,但你说你的当前设计意味着锁定是正确的。您可以通过将hold设置为自己的触发器来解决这个问题,并且只计算完所设置的时间,并在计数完成后将其清除。请注意,这会影响系统的时间,因此您必须确保所有操作都在正确的周期内完成。很难从您的描述中说明您是希望在“expired”周期或“value + 1”周期设置value。为了向您展示您需要对代码执行哪些操作以使其编译并具有适当的时序,我将假设一些事情:

  1. value保持一个常数,并且在计算时不会改变
  2. expired将在value设置后的start_timer时间脉冲
  3. value不会是4'h0(虽然这很容易处理,因为根据假设1不需要计算)
  4. 所以,你的模块看起来像这样:

    module Timer(
                 input [3:0] value,
                 input start_timer,
                 input clk,
                 input rst,
                 output expired
                );
    
    //counter var
    reg [3:0] count;
    
    //hold variable
    reg hold;
    
    // Note you cannot assign hold from multiple blocks, so the other one has been removed
    
    // In order to meet the timing from assumption 2, we need to combinationally determine expired (be sure we only set it while we are counting; thus the dependence on hold)
    assign expired = (count == value - 4'd1) && (hold == 1'b1);
    
    //counter
    // Note, you cannot have logic outside of a procedural block!
    always @(posedge clk) begin
      if ((hold == 1'b0) && (start_timer == 1'b1)) begin
        hold <= 1'b1; // Hold is part of the register, making it its own flipflop
        count <= 4'd0;
      end
      else if (hold == 1'b1) begin
        if (count == value - 4'd1) begin
            hold <= 1'b0; // Clear hold, we are done counting
            // No need to clear count, it will be cleared at the start of the timer
        end
        else begin
          count <= count + 4'd1;
        end
      end
    end
    
    endmodule