记号计数器Verilog

Tick Counter Verilog

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

我想我应该对clk周期进行计数,并在满足周期数时使用该计数将tick输出为高,但是我似乎无法使其正常工作。

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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

或者类似以下内容的东西可能更小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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

否则,如果您喜欢递增计数器,则将文字求反。