案例-1位閃爍燈設(shè)計(jì)
本文為明德?lián)P原創(chuàng)及錄用文章,轉(zhuǎn)載請(qǐng)注明出處!? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
?本文的文檔編號(hào):000800000013
本文檔沒(méi)有對(duì)應(yīng)的視頻
1、本文是講解了如何使用至簡(jiǎn)設(shè)計(jì)法來(lái)時(shí)序1位LED燈間隔1秒,亮N秒(其中N=1 .2. …. 9)的功能
個(gè)人總結(jié)及感悟:
對(duì)于學(xué)習(xí)本案例,首先要理解案例的頂層框架,再是理解框架下面的邏輯,最后才是理解代碼。這一點(diǎn)對(duì)于自己動(dòng)手寫(xiě)代碼也很有幫助,畢竟寫(xiě)代碼就是為了實(shí)現(xiàn)框架。再來(lái)說(shuō)說(shuō)本案例中的代碼吧,本案例給出的代碼對(duì)于剛接觸FPGA的人也許會(huì)有“這代碼寫(xiě)的太麻煩了吧!”“明明可以寫(xiě)成49_999_999的為啥要寫(xiě)成50_000_000-1呢?”之類的想法,這也是我剛接觸明德?lián)P的代碼時(shí)的想法。
后來(lái)接觸多了,自己也開(kāi)始用明得揚(yáng)的代碼規(guī)范寫(xiě)了一些代碼,才慢慢覺(jué)得明德?lián)P的代碼規(guī)范挺好用的,寫(xiě)出來(lái)的代碼也通俗易懂。而且這些代碼也很方便移植與修改,對(duì)于實(shí)現(xiàn)某些相似的功能時(shí)也不用自己再重新寫(xiě)代碼,可以直接拿過(guò)來(lái)再修改一下就行了。
總的來(lái)說(shuō),要想學(xué)好FPGA需要從三個(gè)方面著手:1、框架;2、規(guī)范;3、動(dòng)手做。這三個(gè)方面做好了,那以后自己做工程就成功一半了。
?
設(shè)計(jì)目標(biāo):
使用一個(gè)LED燈,實(shí)現(xiàn)閃爍燈的功能。工作時(shí)鐘50M,也就是時(shí)鐘周期為20ns。輸出低電平時(shí),燈亮;輸出高電平時(shí),燈滅。
?
功能要求:
隔1秒,亮N秒。N的變化是1,2,3,……,9秒。然后再次循環(huán)。
?波形示意圖:

頂層信號(hào)設(shè)計(jì):
工程共需要三個(gè)信號(hào),時(shí)鐘clk,復(fù)位rst_n和輸出信號(hào)led。其中clk、rst_n是輸入信號(hào),led是輸出信號(hào),并且三個(gè)信號(hào)都是1比特的。
?
工程實(shí)現(xiàn)思路:
??從功能要求及波形圖可知,需要一個(gè)計(jì)數(shù)器計(jì)數(shù)第N次,需要一個(gè)計(jì)數(shù)器計(jì)數(shù)第N次需要持續(xù)的時(shí)間。本工程設(shè)計(jì)兩個(gè)計(jì)數(shù)器cnt0,cnt1。cnt0用于計(jì)數(shù)第N次需要持續(xù)的時(shí)間,cnt1計(jì)數(shù)第N次。第1次時(shí),持續(xù)2秒;第2次時(shí),持續(xù)3秒;第N次時(shí),持續(xù)N+1秒。直至第9次結(jié)束,又從第1次開(kāi)始循環(huán)。輸出信號(hào)led同時(shí)滿足cnt0計(jì)數(shù)器的計(jì)數(shù)開(kāi)始信號(hào)add_cnt0的出現(xiàn)與cnt0計(jì)數(shù)到50_000_000-1這兩個(gè)條件時(shí)變?yōu)榈碗娖剑辉趀nd_cnt0信號(hào)出現(xiàn)時(shí)變?yōu)楦唠娖?,意味著在第N次計(jì)數(shù)中第1秒內(nèi)燈滅,其余時(shí)間燈亮。
代碼實(shí)現(xiàn):
計(jì)數(shù)器cnt0
always@(posedgeclkor negedgerst_n)begin
if(rst_n)begin
?? cnt0<=0;
end
else if(add_cnt0)begin
?? if(end_cnt0)
?????? cnt0<=0;
?? else
?????? cnt0<=cnt0+1;
end
end
assign add_cnt0 = 1;
assign end_cnt0 = add_cnt0&&cnt0==x-1;
因?yàn)閏nt0需要不停的計(jì)數(shù),永不停止,故計(jì)數(shù)開(kāi)始信號(hào)add_cnt0一直為1。引入了變量x,x為要計(jì)數(shù)的個(gè)數(shù)。比較計(jì)數(shù)器cnt1的不同,從而賦予變量x不同的值。
cnt1計(jì)數(shù)器
always@(posedgeclkor negedgerst_n)begin
if(rst_n)begin
?? cnt1<=0;
end
elseif(add_cnt1)begin
?? if(end_cnt1)
?????? cnt1<=0;
?? else
?????? cnt1<=cnt1+1;
end
end
assignadd_cnt1 = end_cnt0;
assignend_cnt1 = add_cnt1&&cnt1==9-1;
當(dāng)計(jì)數(shù)器cnt0計(jì)數(shù)結(jié)束時(shí)的下一個(gè)時(shí)鐘節(jié)拍里,使得cnt1計(jì)數(shù)加1。
led輸出信號(hào)
always@(posedgeclkor negedgerst_n)begin
if(rst_n)begin
led<= 1;
end
elseif(add_cnt0 && cnt0 ==50_000_000-1)begin
?? led <= 0;
elseif(end_cnt0)begin
?? led <= 1;
end
end
led信號(hào)在第N次計(jì)數(shù)時(shí),計(jì)數(shù)1秒后燈亮。
?
信號(hào)定義:
always里面的信號(hào)需要定義為reg型;assign的信號(hào)需要定義為wire型。另外需要重點(diǎn)注意每個(gè)信號(hào)的位寬。
?
注意事項(xiàng):
具體編寫(xiě)代碼過(guò)程中,需要注意以下三點(diǎn)。
1、要注意計(jì)數(shù)器的計(jì)數(shù)結(jié)束條件,例如工作時(shí)鐘是50M,計(jì)數(shù)1秒鐘,那么計(jì)數(shù)范圍就是0~49_999_999,千萬(wàn)要注意不能超出。
2、代碼一定要規(guī)范,不然過(guò)段時(shí)間可能連自己都看不懂。
3、要注意各個(gè)信號(hào)的位寬。