才开始学Verilog的时候不知道分频是怎么计算的,经过一段时间的学习后,总结如下,如有错误,请大家指正~
例如:系统频率为50M,要控制LED,系统频率太高,直接使用系统频率,人眼将无法看到灯的亮灭;因此要进行分频。那么分频数怎么求呢?
因为人眼所能看到灯光的闪烁最大频率是30-50Hz,所以低于30-50Hz的频率人眼才能看到。
系统·频率(FPGA晶振)50M意味着什么呢?对应的周期为1/50M=0.02us,每隔0.01us翻转一次,换言之为10ns翻转一次。
若我们设置频率为1Hz(小于30-50Hz,人眼可见灯光的闪烁),那么需要多少分频才行呢?计算公式如下:(系统频率÷所需频率-2)÷2=分频数(divcnt)
((50×106Hz÷1Hz)-2)÷2=24999999;
进行25,000,000分频,采用计数器的方式。当计数值达到25,000,000时令divclk翻转。(1/50*106)*25000000=1/2s,意思就是每0.5s翻转一次,周期为1s。对应过来的频率是1/T=1Hz,人眼可见。
1
2
3
4
5
6
7
8
9always@(posedge clk or negedge Rst_n) begin if(!Rst_n) div_cnt=0; else if(div_cnt==50000000)//2s/20ns÷2,将ns换算成s后计算 begin divclk=~divclk;div_cnt=0;end else div_cnt=div_cnt+1'b1; end
div_cnt是1,分频就为1*2+2,即四分频,如下图所示;
为什么要加2是不是很疑惑?我的理解如下:
因为这里的1指隔1个周期
现附上灯1s翻转一次的完整代码,供大家理解本片博客分频数的计算,可以试着修改div_cnt来体会分频。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23`timescale 1ns / 1ps module LED_1( input clk, input Rst_n, output reg led ); reg [31:0]div_cnt; reg divclk; always@(posedge clk or negedge Rst_n) begin if(!Rst_n) begin div_cnt=0;led<=0;divclk<=0;end else if(div_cnt==50000000)//2s/20ns÷2,将ns换算成s后计算 begin divclk<=~divclk;div_cnt<=0;end else div_cnt<=div_cnt+1'b1; end always@(posedge divclk) begin led=~led; end endmodule
Testbench如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18module LED_1_tst(); reg clk; reg Rst_n; wire led; LED_1 uut(.clk(clk), .Rst_n(Rst_n), .led(led)); initial begin clk=0; Rst_n=0; #100 Rst_n=1; //#1000 $finish; end always #10 clk=~clk; endmodule
我会在下一篇博客里,介绍如何用利用分频和计数器实现LED1s翻转一次,以及LED1ms亮,0.8ms灭。
最后
以上就是无奈雪糕最近收集整理的关于Verilog中分频数的计算的全部内容,更多相关Verilog中分频数内容请搜索靠谱客的其他文章。
发表评论 取消回复