|
基于至簡設計法的數字時鐘設計 明德揚科技教育有限公司 官 網:www.mdy-edu.com 淘 寶:mdy-edu.taobao.com QQ 群:97925396
數字時鐘是常見的畢業設計題目。我們做畢業設計時,一般使用數碼管來顯示數字。小時、分鐘和秒鐘各兩位數字,所以需要用到6位的數碼管。 如果平時不動手,要做這個畢業設計,很多人都會覺得挺難的。收集到的代碼,其風格也是五花八門,第一感覺是貌似能看懂,但就是不知道怎么設計出來的。 其實如果有正確的設計思路和方法,其實現起來是非常簡單的。下面我們就核心的數字模塊為例,講解如何使用至簡設計法來實現。
數字模塊的功能,是產生6個信號,分別表示時十位、時個位、分十位、分個位、秒十位和秒個位的值。例如上述信號值依次為2、1、4、3、5、9時,則表示時間為21點43分59秒。 仔細觀察6個信號,每個單獨來看,其數字都是遞增的,增加到一定數后就清零。以秒個位為例,開始時值為0,然后是1、2、3依次增加,直到變成9后,然后變成0,再次循環。其他信號都是相同的規律。這些依次遞增的信號,就是計數器。 我們認識到這些信號是計數器,那就好辦了,明德揚最擅長就是計數器的設計。計數器設計只需要考慮兩點,什么時候加1和要數多少個,明確這兩個問題后,剩下的就是套用明德揚計數器模板了。 以秒個位這個計數器為例,這個計數器加1的條件是什么呢?到了1秒就加1。那我們怎么知道1秒鐘時間到了呢? FPGA是通過數時鐘周期數來確定時間的。例如下圖,假設時鐘頻率是50MHz,即時鐘周期是20ns,cnt是每個時鐘加1,則當cnt==99時,就說明數了100個時鐘周期,也就是時間是100*20=2000ns了。
同樣的道理,1秒鐘時間,我們就是數1s/20ns= 50_000_000個時鐘周期。我們也認識到這個cnt也是計數器,其加1條件是“1”,要數50_000_000個數。我們套用明德揚計數器模塊,即有下面代碼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 0; end else if(add_cnt)begin if(end_cnt) cnt <= 0; else cnt <= cnt + 1; end end
assign add_cnt = 1 ; assign end_cnt = add_cnt && cnt== 50_000_000-1;
|
代碼中,always語句除了名字后,完全套用模板,不用更改。加1條件體現在第13行,要數多少個體現在第14行。
確定了cnt后,那么秒個位的加1條件就非常明確了,就是cnt數到50_000_000個,也就是end_cnt有效的時候。所以秒個位的加1條件是end_cnt。 秒個位要數多少個數字呢?由0到9,因此有10個。
綜上所述,我們得到秒個位的代碼如下表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin miao_g <= 0; end else if(add_miao_g)begin if(end_miao_g) miao_g <= 0; else miao_g <= miao_g + 1; end end
assign add_miao_g = end_cnt; assign end_miao_g = add_miao_g && miao_g == 10-1;
|
用類似于秒個位的思考方法,我們可以得到秒十位、分個位、分十位、時個位和時十位的代碼,完整的代碼如下表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 0; end else if(add_cnt)begin if(end_cnt) cnt <= 0; else cnt <= cnt + 1; end end
assign add_cnt = 1 ; assign end_cnt = add_cnt && cnt== 50_000_000-1;
always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin miao_g <= 0; end else if(add_miao_g)begin if(end_miao_g)begin miao_g <= 0; end else begin miao_g <= miao_g + 1; end end end
assign add_miao_g = end_cnt; assign end_miao_g = add_miao_g && miao_g == 10-1;
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin miao_s <= 0; end else if(add_miao_s)begin if(end_miao_s)begin miao_s <= 0; end else begin miao_s <= miao_s + 1; end end end
assign add_miao_s = end_miao_g; assign end_miao_s = add_miao_s && miao_s == 6-1;
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin fen_g <= 0; end else if(add_fen_g)begin if(end_fen_g)begin fen_g <= 0; end else begin fen_g <= fen_g + 1; end end end
assign add_fen_g = end_miao_s; assign end_fen_g = add_fen_g && fen_g == 10-1;
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin fen_s <= 0; end else if(add_fen_s)begin if(end_fen_s)begin fen_s <= 0; end else begin fen_s <= fen_s + 1; end end end
assign add_fen_s = end_fen_g; assign end_fen_s = add_fen_s && fen_s == 6-1;
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin shi_g <= 0; end else if(add_shi_g)begin if(end_shi_g)begin shi_g <= 0; end else begin shi_g <= shi_g + 1; end end end
assign add_shi_g = end_fen_s; assign end_shi_g = add_shi_g && shi_g ==x-1;
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin shi_s <= 0; end else if(add_shi_s)begin if(end_shi_s)begin shi_s <= 0; end else begin shi_s <= shi_s + 1; end end end
assign add_shi_s = end_shi_g; assign end_shi_s = add_shi_s && shi_s == 3-1;
always@(*)begin if(shi_s==2) x =4; else x =10; end
|
細心的讀者可以發現,上面每段計數器格式都非常相似。沒錯,這就是明德揚設計的技巧。我們設計的這套模板,基本上可以應用于任何場合,任何時候讀者只考慮兩個因素就夠了,不會出現丟三落四的情況,而且每次只需要考慮一個因素,保證能做出最優的設計。 如果你還未發現這代碼優秀的地方,建議你百度下數字時鐘的代碼,好好比一比,特別是好好想想我們的設計思路,明德揚是有方法有步驟、可以做到一次性設計對,而他們的則是想到哪寫到哪,每次設計都不同的想法。每次設計都是不同的思想,水平怎么能提高!
明德揚整個培訓周期,都是訓練類似于這種固定、專業的思維方法,無論你遇到多復雜多前衛的項目,都能用這種思維方式來設計。
對了,上面代碼中,我們沒有補充信號定義這些。其實我們認為這些信號定義純屬體力勞動,是根本就不需要學習的,所以我們就沒列出來。讀者有興趣可必補充。另外加上數碼管譯碼 電路,那么一個完整的數字時鐘代碼就出來了。
|