设计定义
LED在计数器的控制下,每500ms后状态翻转一次。
对系统时钟进行计数,系统时钟50MHz,周期 1/50MHz = 0.02us = 20ns,
计数次数:500ms / 20ns = 25_000_000,次数达到后计数器清零并驱动LED翻转。
设计输入
在设计定义中可知,有两个要实现的功能:
1、计数器逻辑计数进程
always @(posedge Clk50M or negedge Rst_n)//时序逻辑,敏感信号为时钟沿,复位信号的下降沿
if(Rst_n == 1'b0) //复位,计数器清零
cnt <=30'd0;
else if(cnt == 30'd24_999_999) // 计数满500ms,清零计数器
cnt <= 30'd0;
else
cnt <= cnt + 1'b1;//否则,每来一个时钟上升沿,cnt自加1(Clk50M与时钟连接)
2、LED输出控制进程
always @(posedge Clk50M or negedge Rst_n) //always建立时序逻辑,非阻塞赋值
if(Rst_n == 1'b0)
led <= 1'b1; //复位输出高电平,而低电平有效
else if(cnt == 30'd24_999_999)//计数25_000_000共500ms,500ms亮,500ms灭
led <= ~led;
else
led <= led; //当没有计数完成,保持原状态。时序电路可以没有输入,用自身状态作为组合逻辑输入
疑惑:在实际功能实现时,不知道有几个进程,也就是不知道使用几个always块实现整体功能,也就是说对整体的架构设计不知道,无从下手。我想多复现案例,多敲代码,多总结,就能慢慢体会到架构设计吧!
仿真
使用ModelSim进行仿真,分前仿真、后仿真。
前仿真验证电路设计的正确性,在设计阶段就发现电路设计中的不足;
后仿真加入了布局布线,验证电路的时序行为和时序完整性,进而优化电路。
前仿真
计时500ms,LED翻转
后仿真
后仿真中LED并不是严格500ms翻转一次,因为从高电平->低电平,低电平->高电平,两者的所需时间不一样导致,布局布线导致信号到达的时间不一样。
实际电路分析
抽象出电路模型:
寄存器:计数器对应寄存器,有时钟输入信号Clk50M、输入信号D,输出信号Q;
比较器:计数器输出与预设值24_999_999比较,比较结果驱动LED和控制计数器清零;
2选1多路选择器:比较器结果作为选择端,两个输入端分别代表计时器加1的值、计数器清零;
LED驱动:
电路分析:
每时钟上升沿来临,计数器输出端Q自加1,作为选择器的输入端DATAA;
计数器cnt的输出A[29:0]与预设值24_999_999在比较器中进行比较,比较的结果驱动LED和控制计数器进行清零操作:
比较结果相等,驱动LED,同时选择MUX21的DATAB端,作为OUT0,计数器进行清零操作。
比较结果不等,选择MUX21的DATAA端,输入到计数器D,实现加1操作。