一、计数器概念
计数是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路,计数器在数字系统中主要是对脉冲的个数进行计数,以实现测量、计数和控制的功能, 同时兼有分频功能。
计数器在数字系统中应用广泛,如电子计算机的控制器中对指令地址进行计数,以便顺序取出下一条指令,在运算器中作乘法、除法运算时记下加法、减法次数,又如在数字仪器中
对脉冲的计数等等。
二、计数器计时计算
计数器计时主要与时钟频率有比较大的关系
要实现1s的计数,用50Mhz的晶振来实现,其计算过程如下所示
f=50Mhz=510四次方KHZ=5010七次方HZ
即在单位时间内进行了5010七次方的周期变化(单位时间为1s)
每次变化的时间T=1/f =1/(510七次方)s=210负八次方s=20ns
即每记一次数就计数20ns
M=1s/20ns=510的七次方 所以计5*10七次方才能计1s,但是计数是从0开始,所以计的个数为M-1个
三、parameter与localparam的区别
首先两者都可以对参数进行赋值,但是不同的是parameter能够将参数传递,即参数实例化,其定义如下
对参数进行实例化如下
而localparam只能在此程序中使用,不能够实例化应用
四、计数器
方式一:
程序
module counter
#(
parameter CNT_MAX = 24_999_999
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg out
);
reg [24:0] cnt;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
cnt <= 25’d0;
else if (cnt == CNT_MAX)
cnt <=25’d0;
else
cnt <= cnt+25’d1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
out <= 1’b0;
else if (cnt == CNT_MAX)
out <= ~out;
else
out <= out;
endmodule
方式二
module counter
#(
parameter CNT_MAX = 24_999_999
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg out
);
reg [24:0] cnt;
reg cnt_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
cnt <= 25’d0;
else if (cnt == CNT_MAX)
cnt <=25’d0;
else
cnt <= cnt+25’d1;
/采用标志位来进行******/
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
out <= 1’b0;
else if (cnt_flag == 1’b1)
out <= ~out;
else
out <= out;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
cnt_flag <= 1’b0;
else if (cnt == (CNT_MAX - 25’d1))
cnt_flag <= 1’b1;
else
cnt_flag <= 1’b0;
endmodule
测试程序
`timescale 1ns/1ns
module tb_counter();
reg sys_clk;
reg sys_rst_n;
wire out;
initial
begin
sys_clk = 1’b0;
sys_rst_n <= 1’b0;
#20
sys_rst_n <= 1’b1;
end
initial
begin
$timeformat(-9,0,“ns”,6);
m
o
n
i
t
o
r
(
"
@
t
i
m
e
monitor("@time %t:out=%b",
monitor("@timetime,out);
end
always #10 sys_clk = ~sys_clk;
counter
#(
.CNT_MAX (25’d24)
)
counter_inst
(
.sys_clk (sys_clk) ,
.sys_rst_n (sys_rst_n) ,
.out (out )
);
endmodule