FPGA的学习:计数器的实现
Posted 石小舟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA的学习:计数器的实现相关的知识,希望对你有一定的参考价值。
实现一个led灯前0.5s点亮,后0.5s熄灭这样的状态。
首先画出系统框图和结构图。
计算1s的时间需要多少个时间间隔?
f=50MHz=5*10^4KHz=5*10^7Hz
t=1/f=1/5*10^7=2*10^-8=20ns
间隔的最大值M=1s/20ns=5*10^7
M-1=5*10^7-1
用代码实现:
module counter
#(
parameter CNT_MAX = 25'd24_999_999
)
(
input wire sys_clk , //系统时钟50Mhz
input wire sys_rst_n , //全局复位
output reg led_out //输出控制led灯
);
reg [24:0] cnt; //经计算得需要25位宽的寄存器才够500ms
reg cnt_flag;
//cnt:计数器计数,当计数到CNT_MAX的值时清零
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_flag:计数到最大值产生的标志信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_flag <= 1'b0;
else if(cnt == CNT_MAX - 1'b1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
//led_out:输出控制一个LED灯,每当计数满标志信号有效时取反
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
led_out <= 1'b0;
else if(cnt_flag == 1'b1)
led_out <= ~led_out;
else
led_out <= led_out;
endmodule
编写完成后,编写仿真文件来仿真
`timescale 1ns/1ns
module tb_counter();
wire led_out ;
reg sys_clk ;
reg sys_rst_n ;
//初始化系统时钟、全局复位
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50Mhz
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 ), //input sys_clk
.sys_rst_n (sys_rst_n ), //input sys_rst_n
.led_out (led_out ) //output led_out
);
endmodule
以上是关于FPGA的学习:计数器的实现的主要内容,如果未能解决你的问题,请参考以下文章