设计定义
LED作为输入输出指示,每500ms状态翻转一次。系统时钟为50MHz,对应周期为20ns,需要对系统时钟进行计数。
500ms=500_000_000ns,计数次数为N=500_000_000/20=25_000_000次
计数器定义位宽:25_000_000转换为二进制至少需要25位的计数器才能完整表示
代码编写
module counter(clk50M,rst_n,led);
input clk50M;//系统时钟50M
input rst_n; //全局复位,低电平复位
output reg led;//led输出
reg [24:0]cnt;
//计数器进程
always@(posedge clk50M or negedge rst_n)//在每个系统时钟等上升沿或者在复位信号置位时触发
if(rst_n == 1'b0)//if(!rst_n)如果复位
cnt <= 25'd0;
else if (cnt == 25'd24_999_999)//计数满
cnt <= 25'd0;
else
cnt <= cnt + 1'b1;//0-24_999_999累加
//led输出控制进程
always@(posedge clk50M or negedge rst_n)
if(rst_n == 1'b0)
led <= 1'b1;
else if(cnt == 25'd24_999_999)
led <= ~led;
endmodule
功能仿真
‘仿真结果初始复位需要时间大概为4ns
仿真过程中由于进行500ms的仿真仿真时间太长,可以先把计数器的时间改小后再进行仿真。
在向FPGA中下载程序后,可以保存.cdf文件,双击.cdf文件可以直接打开之前编译好的文件直接运行。
电路分析
计数器每500ms清零一次,逻辑综合出的电路图如下图。
cnt触发器的输入为计数数据,锁存器在一个时钟周期内为一个数,然后在Q端口输出,输出后进入比较器和预设值进行比较,若与预设值相等,则输出低电平然后改变LED灯的状态。
将cnt触发器的值取出后送入累加器进行累加,每次累加的数值为1,然后经过一个二选一多路器,当判断输出的结果等于预装载值的时候,二选一多路器输出DATAB的值,也就是初值0,当不等于预装载值的时候,输出DATAA的值,也就是目前累加器累加完之后的结果。这样,就完成了实现了对应电路的设计。