计数器结构
时钟频率为50MHz
需要计数到M-1,波形图
如果计数到M/2-1,波形图
两种区别在于计数器的位宽,计数到M/2-1需要用到的位宽比M-1少一位,更可以节约资源。
`timescale 1ns/1ns
module tb_counter();
reg sys_clk,
reg sys_rst_n,
wire led_out;
initial
begin
sys_clk = 1'b1;
sys_rst_n <=1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t:led_out=%b",$time,led_out);
end
counter
#(
.CNT_MAX(25‘d24)
)
counter_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n ),
.led_out (led_out )
);
endmodule
module counter
#(
parameter CNT_MAX = 25'd24_999_999
)
(
input wire sys_clk ,
input wire sys_rst_n ,
output reg led_out
);
//parameter CNT_MAX = 25'd24_999_999; //参数定义,技术最大值
reg [24:0] cnt;
//输入信号定义
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) //复位信号有效时
cnt <= 25'b0;
else if (cnt == CNT_MAX)
cnt <= 25'b0;
else
cnt <= cnt + 1'b1; //这里是cnt是25位二进制 每次加二进制1 ---1'b1
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) //复位信号有效时
led_out <= 1'b0;
else if(cnt == CNT_MAX)
led_out <= ~led_out;
else
led_out <= led_out;
endmodule
这里是十进制加1 1位十进制 每次加十进制的1-----1'd1
计数到最大值24,电平翻转
加入计数单位cnt_flag后,counter的代码为
module counter
#(
parameter CNT_MAX = 25'd24_999_999
)
(
input wire sys_clk ,
input wire sys_rst_n ,
output reg led_out
);
//parameter CNT_MAX = 25'd24_999_999; //参数定义,技术最大值
reg [24:0] cnt;
reg cnt_flag;
//输入信号定义
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) //复位信号有效时
cnt <= 25'b0;
else if (cnt == CNT_MAX)
cnt <= 25'b0;
else
cnt <= cnt + 1'b1;
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;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) //复位信号有效时
led_out <= 1'b0;
else if(cnt == CNT_MAX)
led_out <= ~led_out;
else
led_out <= led_out;
endmodule