分享

基于Verilog简单数字时钟(2)

 独孤琅嬛 2014-04-07
然后就是顶层模块clock;
同理,因为Quartus II不支持中文,所以写程序时为了方便懂哥自己清晰思路,所以用自己看得懂的英文进行了描述,大家完全可以忽略.中文为懂哥整理这次笔记时补充.
//数码管为低选通的共阳数码管,按键为低电平有效


module clock(clk,seg,latch,key_in);//key_in为按键输入,需要去抖动
     input clk;
     input[3:0] key_in;
     output [7:0]seg;
     output [5:0]latch;
     reg[23:0]timed;//存放时间数据
     reg clk1;//1hz分频
     reg [31:0]count;// count for 1s(1hz)
     reg [23:0]temp;//临时寄存时间数据
     reg [3:0]d1,d2,d3;
     wire [3:0]key_out;//去抖动后输出


     disp t(.clk(clk),.dat(timed),.seg(seg),.latch(latch));//调用数码管显示模块

     assign key_out=(d1|d2|d3);//elimilate dithering

     always@(posedge clk) //按键去抖动三次取样的结果判断是否为低,因为抖动毛刺一般在微秒级
     begin
         d1<=key_in;
         d2<=d1;
         d3<=d2;
     end

     always@(posedge clk)//50Mhz~1hz
     begin
         if(count==32'd25000000)
         begin
             clk1<=~clk1;
             count<=0;
         end
         else count<=count+1'b1;
     end

         always@(key_out)//懂哥承认也许这样处理按键的方法比较丑陋,可是顾虑到reg赋值以及同一变量不能在多个block中赋值于是采用了两段的臃肿办法如果有高手能指点一下更好的办法就^_^
         begin
                   temp=timed;//保存按键时时间数据
             if(key_out[0]==0)//清零
             temp=0;
                   else if(key_out[1]==0)//秒调整
                             temp[23:16]=temp[23:16]+1'b1;
                   else if(key_out[2]==0)//分调整
                             temp[15:8]=temp[15:8]+1'b1;
                   else if(key_out[3]==0)//时调整
                             temp[7:0]=temp[7:0]+1'b1;
         end
     always@(posedge clk1)//时钟显示处理
     begin
                   timed=temp;//同一always块里面使用阻塞和非阻塞,这里也许很有问题并且书上讲明了要尽量避免,可是暂时没有想出更好的办法来输出正确的结果
         begin
                         timed[3:0]<=timed[3:0]+1'b1;//秒个位
           if(timed[3:0]==4'h9)
           begin
                                   timed[7:4]<=timed[7:4]+1'b1;//秒十位
                 timed[3:0]<=0;
                 if(timed[7:4]==4'h5)
                 begin
                                             timed[11:8]<=timed[11:8]+1'b1;//分个位
                   timed[7:4]<=0;
                   if(timed[11:8]==4'h9)
                   begin
                                                       timed[15:12]<=timed[15:12]+1'b1;//分十位
                       timed[11:8]<=0;
                       if(timed[15:12]==4'h5)
                       begin
                                                               timed[19:16]<=timed[19:16]+1'b1;//时个位
                                                               timed[15:12]<=0;
                         if(timed[19:16]==4'h9)
                         begin
                                                                         timed[23:20]<=timed[23:20]+1'b1;//时十位
                             timed[19:16]<=0;
                         end
                                                               if(timed[23:16]==8'h23)//24小时到清零
                                                               begin
                                                                         timed[23:16]<=0;
                                                               end
                       end
                     end
                 end
               end
           end
     end

endmodule

程序在板子上跑得比较正确
放上跑在板子上的图
(1:嘿嘿,那个数字是懂哥故意调的…2:清零键效果图.3:调节时间以后时钟走的样子)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多