计数器设计
计数器需要考虑两个问题:
1、何时开始计数?(复位信号结束时,随着上升沿到来立刻计数)
2、何时清零?
计数器清零也分两种情况:
1)、计数满时清零;
2)、计数到我们需要的值时清零。
这里利用计数器实现的功能是:每隔1s led灯闪烁一次(即每隔0.5s输出信号led_out电平翻转一次)。而0.5s的延时就是靠计数实现的,在系统时钟控制下,计数到一个特定值M(这里M等于25’d24999999),输出信号电平翻转。
下面是Verilog代码。
module count
#( parameter M = 25'd24999999) //此形式例化时可更改参数
(
input sys_clk,
input rst_n,
output reg led_out
);
reg [24:0] cnt;
always@(posedge sys_clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt<=25'd0;
else if(cnt==M)
cnt<=25'd0;
else
cnt<=cnt+25'd1;
end
always@(posedge sys_clk or negedge rst_n)begin
if(rst_n==1'b0)
led_out<=1'd0;
else if(cnt==M)
led_out<=~led_out;
else
led_out<=led_out;
end
endmodule
这是仿真文件。
`timescale 1ns/1ns
module counter_tb();
reg sys_clk;
reg rst_n;
wire led_out;
initial begin
sys_clk=1'd1;
forever #10 sys_clk=~sys_clk;
end
initial begin
rst_n<=1'd0;
#20
rst_n<=1'd1;
end
count
#( .M( 25'd24) //计数值改为24,便于仿真观察
)
counter_inst
(
.sys_clk(sys_clk),
.rst_n(rst_n),
.led_out(led_out)
);
endmodule