计数器是FPGA设计中最常用的一种时序逻辑,根据计数器的计数值我们可以精确计算出FPGA内部各种信号之间的时间关系,每个信号何时拉高、何时拉低、拉低需要多久、拉高需要多久,都可以比较精准的控制具体需要计数的时间。计数器一般是从0开始计数,计数到我们需要的值或者计数满溢出后清零,并可以进行不断的循环,3位数的十进制计数器可最大计数到999,4位数的最大可以计数到9999;3位数的二进制计数器最大可以计数到111(7),4位数的最大可以计数到1111(15),等等。
counter10.v
`timescale 1ns/1ns
module counter10(clk,rst_n,cnt,cout);
input clk;//input clock
input rst_n;//reset ,lowVoltage effect
output[3:0]cnt;//output counter
output cout;//overflow
reg[3:0] cnt_temp;
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_temp<=4'b0;
end
else if(cnt_temp==4'd9)begin
cnt_temp<=4'b0000;
end
else begin
cnt_temp<=cnt_temp+1'b1;
end
end
assign cout=(cnt_temp==4'd9);//ou cycle times
assign cnt = cnt_temp;//ou real time couter
endmodule
tb_counter10.v
`timescale 1ns/1ns
//parameter CYCLE = 10
module tb_counter();
parameter CYCLE = 10;
reg clk,rst_n;
//reg [3:0]cnt_temp;
//wire [3:0]cnt_temp;
wire cout;
wire [3:0] cnt;
counter10 U0(
.clk(clk),
.rst_n(rst_n),
.cout(cout),
.cnt(cnt));
initial begin
rst_n=1;
rst_n = 0;
#(20*CYCLE);
rst_n=1;
end
//generate clk
initial begin
clk = 0;
forever begin
#(CYCLE/2);
clk = 1;
#(CYCLE/2);
clk = 0;
end
end
initial begin
#(200*CYCLE);
$display("sim end!!!");
$finish;
end
endmodule
wave:

cout信号输出周期位,cnt实时的计数器(0~9)。
Schematic: