如何在Verilog HDL中制作这样的时钟计数器?

时间:2018-06-08 07:57:00

标签: verilog fpga hdl

我想制作一个可以在特定信号的位置开始计数的计数器。一旦计数到256,停止计数,将计数器设置为0并输出一些东西。

我编写了以下代码,但显然它会导致“多个驱动程序”错误。

但我想不出另一种方式。有人可以提供一个想法吗?

always@(posedge a_specific_signal)
begin
    counter_switch <= 1;
end

always@(posedge clk)
begin
if (counter_switch  == 1)
    counter <= counter + 1;
if (counter == 256)  
    begin   
        counter <= 0;  
        counter_switch <= 0; 
        something <= 1; 
    end
end

3 个答案:

答案 0 :(得分:1)

您无法在两个不同的counter_switch语句中更改always的值。您需要在同一always块中执行此操作。

我做这样的事情:(没有测试代码可能包含错误)

input clock, reset;

reg counter_switch, ready;
reg [7:0] counter;

always@(posedge clock) begin
    if (reset) begin
        counter_switch <= 0;
    end else begin 
        if (a_specific_signal) begin 
            counter_switch <= 1;
        end else if (ready) begin
            counter_switch <= 0;
        end 
    end 
end

always@(posedge clock) begin
    if (reset) begin 
        ready <= 0;
        counter <= 0;
    end else begin
        if (counter_switch) begin 
            if (counter == 255) begin   
                counter <= 0;  
                ready <= 1; 
            end else begin 
                counter <= counter + 1;
            end
        end else begin 
            ready <= 0;
        end
    end
end

答案 1 :(得分:0)

这是您的计数器,0 to 256计数。

module counter (clk, reset, op);
  input logic clk, reset;
  output logic [16:0] op;

  logic [16:0] current_cnt, next_cnt;

  assign next_cnt = (current_cnt[16]) ? 17'd0 : (current_cnt + 17'd1);
  assign op = current_cnt;

  always @ (posedge clk, negedge reset)
  begin
    if (~reset)
      current_cnt <= 17'd0;
    else 
      current_cnt <= next_cnt;
  end
endmodule

因此,无论何时达到256,那么你的第17位current_cnt将为1,这意味着你的next_cnt应为0.在所有其他情况下,你的下一次计数应为+1。

答案 2 :(得分:0)

“多个驱动程序”错误是由于尝试修改来自不同进程/始终块的信号而引起的。你不应该这样做。

我习惯使用完全同步的系统,因此我应该问您“ a_specific_signal”是什么样的,以及与您的主时钟的关系是什么。

因此,我的方法是:1.将“ a_specific_signal”同步到当前时钟; 2.检测其正沿; 3.将其用作驱动我的计数器的标志

reg a_spec_signal_reg0 = 1'b0, a_spec_signal_reg1 = 1'b0, a_spec_signal_reg2 = 1'b0;

always @(posedge clk) begin --synchronizer with 3 FFs
  a_spec_signal_reg0 <= a_specific_signal;
  a_spec_signal_reg1 <= a_spec_signal_reg0;
  a_spec_signal_reg2 <= a_spec_signal_reg1;
end

wire a_spec_signal_posedge;
assign a_spec_signal_posedge = a_spec_signal_reg1 & ~(a_spec_signal_reg2);

reg counter_switch = 1'b0;

always @(posedge clk) begin
  something <= 1'b0;
  if (a_spec_signal_posedge)
      counter_switch <= 1'b1;
  if (counter_switch) begin
      counter <= counter + 1;
      if (counter == 255) begin   
          counter <= 0;  
          counter_switch <= 0;
          something <= 1'b1;
      end
  end
end

一些注意事项:我假设您想对256个事件进行计数,所以这意味着使用0到255(8位)之间的计数器。另外,something信号在其默认状态下也设置为0,因此当条件“ counter == 255”到来时,它仅在一个时钟周期内输出一个滴答,这通常是使用的。