因为本人也是刚学习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<=32'b0; end always@(posedge clk or negedge rst_n) begin if(!rst_n) jishu_1ms<=16'b0; else if(jishu_1ms jishu_1ms<=16'b0; end assign en_1s=(jishu_1s==cnt_1s)? 1'b1 : 1'b0; assign en_1ms=(jishu_1ms==cnt_1ms)? 1'b1 : 1'b0; endmodule //1s //1ms //按键控制部分 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的值就稳定了 end always @(posedge clk or negedge rst_n) begin if (!rst_n) reg1_low <= 1'b1; else reg1_low <= reg_low; end assign key1_low = reg1_low & ( ~reg_low); //当寄存器 reg_low 由 1 变为 0 时,key_low 的值变为高,维持一个时钟周期 reg reg2_low; reg reg3_low; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin reg2_low <= 1'b1; end else if(cnt_key2 == 20'hfffff) begin reg2_low <= key2; end end always @(posedge clk or negedge rst_n) begin if (!rst_n) reg3_low <= 1'b1; else reg3_low <= reg2_low; end assign key2_low = reg3_low & ( ~reg2_low); endmodule //时、分、秒 module shijian(clk,rst_n,en_1s,key1_low,key2_low,shi,fen,miao); input clk; input rst_n; input en_1s; input key1_low; input key2_low; output[5:0] shi; output[5:0] fen; output[5:0] miao; reg [5:0] shi; reg [5:0] fen; reg [5:0] miao; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin shi<=6'b0; fen<=6'b0; miao<=6'b0; end else if(en_1s) begin miao=miao+1'b1; if(miao==60) begin miao=0; fen=fen+1'b1; if(fen==60) begin fen=0; shi=shi+1'b1; if(shi==24) shi=0; end end end else if(key1_low) begin fen=fen+1'b1; if(fen==60) begin fen=0; shi=shi+1'b1; if(shi==24) shi=0; end 搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新资格考试认证FPGA--数字时钟(verilog) 全文阅读和word下载服务。
相关推荐: