EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
转——从零开始学FPGA——by ihalin——实现让LED灯每50ms翻转一次
4 r6 f* W4 G- ]/ l6 j3 n' _: C" B
' b: u) O3 G' Z9 E. p3 R" y这是我前面做的实验 实验一和实验二 计划每天一个. L7 t3 ?5 o. k) n8 r6 W9 X G
下面是第三个实验计数器实验3 S- C7 |% f2 c. \3 F
实现让LED灯每50ms翻转一次
$ ^! E' m) `! Q9 p! ~7 O2 T) q2 ~
原理是连接50MHZ的晶振 50MHZ=50_000_000HZ 时间是 1/50_000_000秒=20ns
; \6 \- o1 E+ c& D$ `* f所以计数的次数CNT=50_000_000/20=25_000_000次因为计数是从0开始计数的所以只需要计数到24_999_999即可
& c+ g+ V8 d2 w& f/ x开始时序逻辑电路了
+ m$ x( ] T% j) {$ h) G. C% L0 rposedge 等待CLK上升沿8 ?! ]# Z$ Y1 S7 s0 u% M( ^
negedge 等待RST下降沿5 [. F2 m" A, c$ d% z% Y. T
always之间是并行的,它是一直在检测触发条件,always内部是顺序执行的。2 P( @, C b O2 _
下面是代码 1. module counter(Clk50M,Rst_n,led); 2. input Clk50M;//系统时钟,50M=20ns 3. input Rst_n;//全局复位,低电平复位 4. output reg led;//led输出 5. reg [24:0]cnt;//500ms=500_000_000ns/20ns = 25000 000 6. //计数器的进程 7. always@(posedge Clk50M or negedge Rst_n)//在系统时钟是上升沿时候或者是复位的下降沿 8. if(Rst_n == 1'b0)//如果发生了复位则计数器清零 9. cnt <= 25'd0; 10. else if(cnt == 25'd24_999_999)//如果计数到了24 999 999时候则计数器清零 11. cnt <= 25'd0; 12. else 13. cnt <= cnt +1'b1;//否则计数器自加1 14. 15. //led的进程 16. always@(posedge Clk50M or negedge Rst_n)//在系统时钟是上升沿时候或者是复位的下降沿 17. if(Rst_n == 1'b0) 18. led <= 1'b0; 19. else if(cnt == 25'd24_999_999) 20. led <= ~led; 21. else 22. led <= led; 23. 24. 25. endmodule 26. 然后是testbench
& v! e% x8 g1 N, f6 a使用宏定义方便代码修改 1. `timescale 1ns/1ns//仿真时间步进和精度 2. `define clock_period 20 3. module counter_tb; 4. reg clk; 5. reg rst_n; 6. 7. wire led; 8. 9. 10. counter ct0( 11. .Clk50M(clk), 12. .Rst_n(rst_n), 13. .led(led) 14. ); 15. 16. initial clk =1; 17. always #(`clock_period/2) clk =~clk; 18. 19. initial begin 20. rst_n = 1'b0; 21. #(`clock_period*200); 22. rst_n = 1'b1; 23. #2000000000; 24. $stop; 25. 26. 27. end 28. 29. 30. endmodule 31. 然后是RTL的仿真实验
% `$ i/ O; D/ p: Q( \) P* P- k
* \% ]1 q* w, ?+ o# t. c, a9 j1 f Y
符合设计
[( a% @5 u7 |& R然后是门级仿真& w3 D* h8 L- A' s6 }/ z
* V6 m2 w5 U G0 o3 c* m8 }
然后是下载到板子上! E7 L& p! |" Q+ m9 Q: N: o
0 ] l9 M# s e, w: q& w8 s+ W- q
一闪一闪的时间估计对的上。 9 T9 q' |5 }2 f, b6 o$ L1 D
|