FPGA--数字时钟(verilog)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
因为本人也是刚学习fpga的菜鸟,所以这个程序漏洞很多,仅供参考。。。。。。。。。
//分频子模块
module fenpin (clk,rst_n,en_1s,en_1ms); //产生1s,1ms的分频
input clk;
input rst_n;
output en_1s;
output en_1ms;
reg[31:0] jishu_1s;
reg[15:0] jishu_1ms;
parameter cnt_1s =49999999;
parameter cnt_1ms =49999;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
jishu_1s<=32'b0;
else if(jishu_1s jishu_1s<=jishu_1s+1'b1; else jishu_1s<=32'b0; end always@(posedge clk or negedge rst_n) begin if(!rst_n) jishu_1ms<=16'b0; else if(jishu_1ms jishu_1ms<=jishu_1ms+1'b1; else jishu_1ms<=16'b0; end assign en_1s=(jishu_1s==cnt_1s)? 1'b1 : 1'b0; //1s assign en_1ms=(jishu_1ms==cnt_1ms)? 1'b1 : 1'b0; //1ms endmodule //按键控制部分 module anjian(clk,rst_n,key1,key2,key1_low,key2_low); input clk; input rst_n; input key1; // 分加 input key2; // 分减 output key1_low; //按键按下消抖后的标志位 output key2_low; reg reg0_key; //key1消抖 reg reg1_key; reg reg2_key; //key2消抖 reg reg3_key; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin reg0_key <= 1'b1; reg1_key <= 1'b1; end else begin reg0_key <= key1; reg1_key <= reg0_key; //根据非阻塞赋值的原理,reg1_key 存储的值是reg0_key 上一个时钟的值 end end //脉冲边沿检测法,当寄存器key1 由1 变为0 时,key1_an 的值变为高,维持一个时钟周期 wire key1_an; assign key1_an = reg1_key & ( ~reg0_key); always @(posedge clk or negedge rst_n) begin if(!rst_n) begin reg2_key <= 1'b1; reg3_key <= 1'b1; end else begin reg2_key <= key2; reg3_key <= reg2_key; end end //脉冲边沿检测法,当寄存器key2 由1 变为0 时,key2_an 的值变为高,维持一个时钟周期 wire key2_an; assign key2_an = reg3_key & ( ~reg2_key); reg[19:0] cnt_key1; //计数寄存器 always @ (posedge clk or negedge rst_n) begin if (!rst_n) cnt_key1 <= 20'd0; //异步复位 else if(key1_an) cnt_key1 <=20'd0; //led1_an=1,按键确认按下,cnt_key1从0开始计数else cnt_key1 <= cnt_key1 + 1'b1; end reg[19:0] cnt_key2; //计数寄存器 always @ (posedge clk or negedge rst_n) begin if (!rst_n) cnt_key2 <= 20'd0; else if(key2_an) cnt_key2 <=20'd0; else cnt_key2 <= cnt_key2 + 1'b1; end //以下为消抖程序 reg reg_low; reg reg1_low; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin reg_low <= 1'b1; end else if(cnt_key1 == 20'hfffff) //时钟50mhz的话大约计时是20ms begin reg_low <= key1; //led_an=1,按键确认按下,cnt_key从0开始计数,这时候还有消抖动,计数20ms后抖动滤除了此时再锁存一下key1的值 end //这时key1的值就稳定了