第(dì)二(èr)階(jiē)段(duàn) 項目实踐
第(dì)一(yī)章(zhāng) FPGA設計(jì)思(sī)想(xiǎng)
本(běn)文(wén)檔編号(hào):001500000080
需要(yào)看(kàn)对(duì)應(yìng)的(de)視頻,請點(diǎn)擊視頻編号(hào):001500000089
1、本(běn)节(jié)是(shì)講解(jiě)詳细(xì)講解(jiě)了(le)如(rú)何正(zhèng)确的(de)看(kàn)懂 信(xìn)号(hào)波(bō)形
1.1 看(kàn)波(bō)形图(tú)的(de)方(fāng)法
本(běn)書(shū)的(de)D觸發(fà)器一(yī)章(zhāng)、怎麼(me)看(kàn)FPGA波(bō)形一(yī)节(jié)中(zhōng),講述下(xià)如(rú)何看(kàn)信(xìn)号(hào)的(de)波(bō)形,读(dú)者(zhě)只(zhī)需要(yào)記(jì)住一(yī)个(gè)規則:时(shí)鐘(zhōng)上(shàng)升(shēng)沿看(kàn)信(xìn)号(hào),看(kàn)到(dào)的(de)是(shì)信(xìn)号(hào)變(biàn)化(huà)前(qián)的(de)值。有(yǒu)興趣的(de)读(dú)者(zhě),可(kě)以(yǐ)返回(huí)再细(xì)看(kàn)那(nà)一(yī)章(zhāng)內(nèi)容。
图(tú) 111
例如(rú)图(tú)111,在(zài)第(dì)4个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿看(kàn)信(xìn)号(hào)a,則是(shì)看(kàn)到(dào)a的(de)值为(wèi)1(變(biàn)化(huà)前(qián));看(kàn)信(xìn)号(hào)c,看(kàn)到(dào)c的(de)值为(wèi)0(變(biàn)化(huà)前(qián));在(zài)第(dì)5个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿看(kàn)信(xìn)号(hào)b,看(kàn)到(dào)b的(de)值为(wèi)1,看(kàn)信(xìn)号(hào)c,看(kàn)到(dào)c的(de)值为(wèi)1。
图(tú) 112
例如(rú)图(tú)112,在(zài)第(dì)5个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿看(kàn)信(xìn)号(hào)dout,其值为(wèi)1;看(kàn)信(xìn)号(hào)cnt,其值为(wèi)1,而(ér)不(bù)是(shì)2。
以(yǐ)上(shàng)就(jiù)是(shì)看(kàn)波(bō)形的(de)方(fāng)法,該方(fāng)法的(de)由(yóu)来(lái),可(kě)以(yǐ)參考本(běn)書(shū)的(de)D觸發(fà)器一(yī)章(zhāng)、怎麼(me)看(kàn)FPGA波(bō)形一(yī)节(jié)的(de)內(nèi)容。當然,使用(yòng)該方(fāng)法是(shì)有(yǒu)前(qián)提(tí)的(de):所(suǒ)有(yǒu)信(xìn)号(hào)都是(shì)同(tóng)步信(xìn)号(hào);波(bō)形是(shì)理想(xiǎng)的(de)波(bō)形。
1.2 至(zhì)簡設計(jì)法的(de)四(sì)種(zhǒng)設計(jì)類(lèi)型
学習FPGA,最(zuì)關(guān)鍵的(de)是(shì)学什麼(me)?
笔(bǐ)者(zhě)發(fà)現(xiàn),有(yǒu)部(bù)分(fēn)读(dú)者(zhě)将学習的(de)重(zhòng)點(diǎn)放(fàng)在(zài)接口(kǒu)知識、算法原理等理論知識层面(miàn)。例如(rú),学習串口(kǒu)的(de)时(shí)候,把学習重(zhòng)點(diǎn)放(fàng)在(zài):什麼(me)是(shì)串口(kǒu)、串口(kǒu)有(yǒu)什麼(me)优勢、什麼(me)时(shí)候用(yòng)到(dào)串口(kǒu)等理論。至(zhì)于(yú)串口(kǒu)代(dài)碼,也(yě)是(shì)借(jiè)鉴和(hé)模仿,原代(dài)碼是(shì)什麼(me)結構,自(zì)己設計(jì)的(de)代(dài)碼也(yě)要(yào)有(yǒu)这(zhè)種(zhǒng)結構,原代(dài)碼有(yǒu)什麼(me)信(xìn)号(hào),自(zì)己也(yě)要(yào)有(yǒu)这(zhè)些信(xìn)号(hào)等。如(rú)果(guǒ)該串口(kǒu)功能(néng)稍加改動(dòng),則陷入(rù)完全(quán)无從下(xià)手(shǒu)的(de)狀态。
每个(gè)工程师(shī)都有(yǒu)自(zì)己的(de)代(dài)碼风格,甚至(zhì)有(yǒu)些工程师(shī)今天(tiān)的(de)风格和(hé)昨天(tiān)的(de)风格都会(huì)不(bù)一(yī)樣(yàng)。网(wǎng)絡上(shàng)的(de)代(dài)碼自(zì)然也(yě)是(shì)良莠不(bù)齊,一(yī)味靠模仿,能(néng)成(chéng)长为(wèi)高(gāo)手(shǒu),那(nà)就(jiù)奇怪了(le)。
明(míng)德揚認为(wèi),学習FPGA應(yìng)該是(shì)为(wèi)了(le)提(tí)高(gāo)自(zì)己的(de)設計(jì)開(kāi)發(fà)能(néng)力。学習串口(kǒu),不(bù)是(shì)为(wèi)了(le)懂得这(zhè)个(gè)串口(kǒu),而(ér)是(shì)通(tòng)过(guò)这(zhè)个(gè)串口(kǒu)例子,学習其設計(jì)思(sī)路(lù)和(hé)方(fāng)法,以(yǐ)便應(yìng)用(yòng)到(dào)其他(tā)接口(kǒu)上(shàng)。
明(míng)德揚認为(wèi),設計(jì)思(sī)路(lù)和(hé)方(fāng)法,不(bù)應(yìng)过(guò)多(duō)过(guò)雜,而(ér)是(shì)形成(chéng)自(zì)己的(de)一(yī)套(tào)模式。今天(tiān)学少(shǎo)林(lín)铁(tiě)头(tóu)功,明(míng)天(tiān)学武當太极(jí),後(hòu)天(tiān)学華山(shān)劍法,先(xiān)不(bù)说(shuō)精力問(wèn)題(tí),能(néng)达(dá)到(dào)精通(tòng)狀态吗?
明(míng)德揚研發(fà)了(le)一(yī)套(tào)通(tòng)用(yòng)的(de)設計(jì)方(fāng)法:至(zhì)簡設計(jì)法。
至(zhì)簡設計(jì)法從宏观上(shàng),适應(yìng)所(suǒ)有(yǒu)的(de)功能(néng)設計(jì)需求。例如(rú),无論是(shì)什麼(me)功能(néng),我(wǒ)们(men)都先(xiān)将其轉(zhuǎn)化(huà)成(chéng)需求波(bō)形。然後(hòu)在(zài)此(cǐ)基礎上(shàng)設計(jì)模块(kuài)架構;在(zài)模块(kuài)架構基礎上(shàng)設計(jì)信(xìn)号(hào)。这(zhè)步驟都是(shì)通(tòng)用(yòng)的(de)、是(shì)固化(huà)的(de)。
至(zhì)簡設計(jì)法在(zài)微观上(shàng),制定(dìng)了(le)实用(yòng)的(de)規範。詳细(xì)到(dào)什麼(me)时(shí)候添加信(xìn)号(hào);怎麼(me)添加信(xìn)号(hào);添加信(xìn)号(hào)名字(zì)是(shì)什麼(me)等,我(wǒ)们(men)都做了(le)詳细(xì)的(de)規定(dìng)。
大部(bù)分(fēn)的(de)FPGA設計(jì),明(míng)德揚将其歸類(lèi)下(xià)面(miàn)講述的(de)4種(zhǒng)類(lèi)型。无論多(duō)複雜的(de)功能(néng),都是(shì)这(zhè)4種(zhǒng)類(lèi)型的(de)變(biàn)種(zhǒng)。下(xià)面(miàn)通(tòng)过(guò)4个(gè)典型案(àn)例的(de)設計(jì),来(lái)講述至(zhì)簡設計(jì)法。
1.2.1 至(zhì)簡設計(jì)法設計(jì)類(lèi)型1
案(àn)例1:當收(shōu)到(dào)en=1後(hòu),dout産生(shēng)一(yī)个(gè)宽(kuān)度(dù)为(wèi)10个(gè)时(shí)鐘(zhōng)周期(qī)的(de)高(gāo)電(diàn)平脈沖。图(tú)113是(shì)功能(néng)波(bō)形图(tú)。
图(tú) 113
根(gēn)據(jù)看(kàn)波(bō)形規則,在(zài)第(dì)3个(gè)时(shí)鐘(zhōng)上(shàng)沿的(de)时(shí)候,看(kàn)到(dào)en==1,根(gēn)據(jù)功能(néng)要(yào)求,上(shàng)升(shēng)沿之後(hòu)dout就(jiù)会(huì)變(biàn)为(wèi)1。10个(gè)时(shí)鐘(zhōng)周期(qī)後(hòu),即第(dì)13个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿时(shí),dout将變(biàn)为(wèi)0。
推理1:從功能(néng)要(yào)求中(zhōng),看(kàn)到(dào)數字(zì)10,我(wǒ)们(men)就(jiù)知道(dào)要(yào)計(jì)數,要(yào)使用(yòng)計(jì)數器。
推理2:10个(gè)是(shì)指dout==1的(de)次(cì)數为(wèi)10个(gè)时(shí)鐘(zhōng)周期(qī),所(suǒ)以(yǐ)該計(jì)數器數的(de)是(shì)dout==1的(de)次(cì)數,因(yīn)此(cǐ)看(kàn)到(dào)dout==1时(shí),計(jì)數器就(jiù)会(huì)加1。
此(cǐ)外(wài),明(míng)德揚還(huán)制定(dìng)了(le)計(jì)數器要(yào)遵守的(de)原則。
原則1:初值一(yī)定(dìng)为(wèi)0。複位後(hòu),計(jì)數器一(yī)定(dìng)要(yào)为(wèi)0。
原則2:數到(dào)最(zuì)後(hòu)一(yī)个(gè)时(shí),要(yào)及(jí)时(shí)清(qīng)0。
根(gēn)據(jù)上(shàng)面(miàn)2个(gè)推理和(hé)原則,補充計(jì)數器信(xìn)号(hào)cnt,更(gèng)新後(hòu)的(de)波(bō)形如(rú)图(tú)114。

图(tú) 114
從功能(néng)要(yào)求和(hé)波(bō)形图(tú),我(wǒ)们(men)确認,計(jì)數器cnt是(shì)对(duì)dout==1進(jìn)行計(jì)數,并且一(yī)共(gòng)數10个(gè)。为(wèi)此(cǐ),在(zài)GVIM編輯器中(zhōng)輸 入(rù)“Jsq”并回(huí)車,将出(chū)現(xiàn)图(tú)115的(de)代(dài)碼。
图(tú) 115
在(zài)第(dì)13行,輸入(rù)dout==1,在(zài)第(dì)14行代(dài)碼中(zhōng),輸入(rù)10-1,这(zhè)樣(yàng)就(jiù)完成(chéng)了(le)計(jì)數器設計(jì),如(rú)图(tú) 116。
图(tú) 116
add_cnt表(biǎo)示:計(jì)數器cnt加1条(tiáo)件(jiàn)。
end_cnt表(biǎo)示:計(jì)數器數到(dào)最(zuì)後(hòu)一(yī)个(gè),也(yě)稱之为(wèi)結束(shù)条(tiáo)件(jiàn)。
图(tú)116第(dì)1~第(dì)11代(dài)碼功能(néng):时(shí)鐘(zhōng)上(shàng)升(shēng)沿时(shí),如(rú)果(guǒ)計(jì)數器加1条(tiáo)件(jiàn)有(yǒu)效,并且是(shì)數到(dào)最(zuì)後(hòu)一(yī)个(gè),則計(jì)數器清(qīng)零(líng);如(rú)果(guǒ)計(jì)數器加1条(tiáo)件(jiàn)有(yǒu)效,但不(bù)是(shì)最(zuì)後(hòu)一(yī)个(gè),則計(jì)數器就(jiù)加1;其他(tā)时(shí)候,計(jì)數器就(jiù)保持(chí)不(bù)變(biàn)。
那(nà)麼(me)加1条(tiáo)件(jiàn),即add_cnt是(shì)什麼(me)呢?在(zài)第(dì)13行進(jìn)行了(le)定(dìng)義。該行代(dài)碼表(biǎo)示,dout==1就(jiù)是(shì)計(jì)數器的(de)加1条(tiáo)件(jiàn)。
那(nà)麼(me)結束(shù)条(tiáo)件(jiàn),即end_cnt是(shì)什麼(me)呢?在(zài)第(dì)14行進(jìn)行了(le)定(dìng)義。該行代(dài)碼表(biǎo)示,數到(dào)10个(gè)就(jiù)結束(shù)。其中(zhōng)我(wǒ)们(men)關(guān)注的(de)是(shì)那(nà)个(gè)數字(zì)10,而(ér)-1是(shì)固定(dìng)的(de)格式。
add_cnt && cnt==10-1,含義是(shì)表(biǎo)示“數到(dào)第(dì)10个(gè)的(de)时(shí)候”,add_cnt && cnt==x-1表(biǎo)示“數到(dào)第(dì) x个(gè)的(de)时(shí)候”。記(jì)住这(zhè)个(gè)規則。end_cnt==1也(yě)表(biǎo)示數完了(le)。
設計(jì)好(hǎo)計(jì)數器cnt後(hòu),我(wǒ)们(men)就(jiù)可(kě)以(yǐ)設計(jì)輸出(chū)信(xìn)号(hào)dout了(le)。仔细(xì)分(fēn)析dout,該信(xìn)号(hào)有(yǒu)两(liǎng)个(gè)變(biàn)化(huà)點(diǎn):變(biàn)1和(hé)變(biàn)0。我(wǒ)们(men)分(fēn) 析原因(yīn),dout變(biàn)1是(shì)由(yóu)于(yú)收(shōu)到(dào)en==1;dout變(biàn)0,則是(shì)數到(dào)了(le)10个(gè)或(huò)者(zhě)是(shì)數完了(le)。所(suǒ)以(yǐ)綜上(shàng)所(suǒ)述,dout的(de)代(dài)碼是(shì):
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0 ; end else if(en==1) begin dout <= 1 ; end else if(end_cnt) begin dout <= 0 ; end end |
至(zhì)此(cǐ),我(wǒ)们(men)完成(chéng)了(le)主(zhǔ)體(tǐ)程序的(de)設計(jì),接下(xià)来(lái)補充module的(de)其他(tā)部(bù)分(fēn)。
将module的(de)名稱定(dìng)義为(wèi)my_ex1。并且我(wǒ)们(men)已經(jīng)知道(dào)該模块(kuài)有(yǒu)4个(gè)信(xìn)号(hào):clk、rst_n、en和(hé)dout。为(wèi)此(cǐ),代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 |
module my_ex1( clk , rst_n , en , dout ); |
其中(zhōng)clk、rst_n和(hé)en是(shì)輸入(rù)信(xìn)号(hào),dout是(shì)輸出(chū)信(xìn)号(hào),并且4个(gè)信(xìn)号(hào)都是(shì)1比特(tè)的(de),根(gēn)據(jù)这(zhè)些信(xìn)息,我(wǒ)们(men)補充輸入(rù)輸出(chū)端口(kǒu)定(dìng)義。代(dài)碼如(rú)下(xià):
|
1 2 3 4 |
input clk ; input rst_n ; input en ; output dout ; |
接下(xià)来(lái)定(dìng)義信(xìn)号(hào)類(lèi)型。
cnt是(shì)用(yòng)always産生(shēng)的(de)信(xìn)号(hào),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。cnt計(jì)數的(de)最(zuì)大值为(wèi)9,需要(yào)用(yòng)4根(gēn)線(xiàn)表(biǎo)示,即位宽(kuān)是(shì)4位。add_cnt和(hé)end_cnt都是(shì)用(yòng)assign方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)wire。并且其值是(shì)0或(huò)者(zhě)1,1个(gè)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 |
reg [ 3:0] cnt ; wire add_cnt ; wire end_cnt ; |
dout是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg dout ; |
至(zhì)此(cǐ),整个(gè)代(dài)碼的(de)設計(jì)工作已經(jīng)完成(chéng)。整體(tǐ)代(dài)碼如(rú)下(xià):
|
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 |
module my_ex1( clk , rst_n , en , dout ); input clk ; input rst_n ; input en ; output dout ;
reg [ 3:0] cnt ; wire add_cnt ; wire end_cnt ; reg dout ;
always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 0; end else if(add_cnt) begin if(end_cnt) &nbs p; cnt <= 0; else &nbs p; cnt <= cnt + 1; end end
assign add_cnt = (dout==1); assign end_cnt = add_cnt && cnt==10 -1 ;
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(en==1) begin dout <= 1; end else if(add_cnt && cnt==10-1)begin dout <= 0; end end
endmodule |
1.2.2 至(zhì)簡設計(jì)法設計(jì)類(lèi)型2
例2. 當收(shōu)到(dào)en=1後(hòu),dout間(jiān)隔3个(gè)时(shí)鐘(zhōng)後(hòu),産生(shēng)宽(kuān)度(dù)为(wèi)2个(gè)时(shí)鐘(zhōng)周期(qī)的(de)高(gāo)電(diàn)平脈沖。
图(tú) 117
如(rú)上(shàng)面(miàn)波(bō)形图(tú)所(suǒ)示,在(zài)第(dì)3个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿看(kàn)到(dào)en==1,間(jiān)隔 3个(gè)时(shí)鐘(zhōng)後(hòu),dout變(biàn)1,再过(guò)2个(gè)时(shí)鐘(zhōng)後(hòu),dout變(biàn)0。
根(gēn)據(jù)案(àn)例1的(de)經(jīng)验(yàn),出(chū)現(xiàn)大于(yú)1的(de)數字(zì)时(shí),就(jiù)需要(yào)計(jì)數。我(wǒ)们(men)这(zhè)里(lǐ)有(yǒu)數字(zì)2和(hé)3,建議的(de)計(jì)數方(fāng)式如(rú)下(xià)。
图(tú) 118
當然,其他(tā)計(jì)數方(fāng)式最(zuì)終(zhōng)也(yě)能(néng)实現(xiàn)功能(néng)。但明(míng)德揚的(de)總(zǒng)結是(shì)上(shàng)面(miàn)方(fāng)式最(zuì)好(hǎo),实現(xiàn)的(de)代(dài)碼将是(shì)最(zuì)簡的(de),其他(tā)方(fāng)式則稍微複雜。
接下(xià)来(lái)判斷計(jì)數器的(de)加1条(tiáo)件(jiàn)。與(yǔ)案(àn)例1不(bù)同(tóng)的(de)是(shì),計(jì)數器加1區(qū)域如(rú)下(xià)图(tú)陰影部(bù)分(fēn),但图(tú)中(zhōng)沒(méi)有(yǒu)任何信(xìn)号(hào)来(lái)指示此(cǐ)區(qū)域 。
图(tú) 119
为(wèi)此(cǐ),添加一(yī)个(gè)名字(zì)为(wèi)“flag_add”的(de)信(xìn)号(hào),刚好(hǎo)覆蓋了(le)陰影部(bù)分(fēn),如(rú)下(xià)图(tú)。
图(tú) 120
補充該信(xìn)号(hào)後(hòu),計(jì)數器的(de)加1条(tiáo)件(jiàn)就(jiù)變(biàn)为(wèi)flag_add==1,并且是(shì)數5个(gè)。代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
always @(posedge clk or negedge rst_n) begin if (rst_n==0) begin cnt <= 0; end else if(add_cnt) begin if(end_cnt) &nbs p; cnt <= 0; else &nbs p; cnt <= cnt+1 ; end end assign add_cnt = flag_add==1; assign end_cnt = add_cnt && cnt == 5-1 ; |
|
|
|
flag_add有(yǒu)2个(gè)變(biàn)化(huà)點(diǎn),變(biàn)1和(hé)變(biàn)0。變(biàn)1的(de)条(tiáo)件(jiàn)是(shì)收(shōu)到(dào)en==1,變(biàn)0的(de)条(tiáo)件(jiàn)是(shì)計(jì)數器數完了(le),因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_add <= 0; end else if(en==1) begin flag_add <= 1; end else if(end_cnt) begin flag_add <= 0; end end |
dout也(yě)有(yǒu)2个(gè)變(biàn)化(huà)點(diǎn):變(biàn)1和(hé)變(biàn)0。變(biàn)1的(de)条(tiáo)件(jiàn)是(shì)“3个(gè)間(jiān)隔之後(hòu)”,也(yě)就(jiù)是(shì)“數到(dào)3个(gè)的(de)时(shí)候”;變(biàn)0的(de)条(tiáo)件(jiàn)是(shì)數完了(le)。代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(add_cnt && cnt==3-1)begin dout <= 1; end else if(end_cnt) begin dout <= 0; end end |
至(zhì)此(cǐ),我(wǒ)们(men)完成(chéng)了(le)主(zhǔ)體(tǐ)程序的(de)設計(jì),接下(xià)来(lái)是(shì)補充module的(de)其他(tā)部(bù)分(fēn)。
将module的(de)名稱定(dìng)義为(wèi)my_ex2。并且我(wǒ)们(men)已經(jīng)知道(dào)該模块(kuài)有(yǒu)4个(gè)信(xìn)号(hào):clk、rst_n、en和(hé)dout。为(wèi)此(cǐ),代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 |
module my_ex2( clk , rst_n , en , dout ); |
其中(zhōng)clk、rst_n和(hé)en是(shì)輸入(rù)信(xìn)号(hào),dout是(shì)輸出(chū)信(xìn)号(hào),并且4个(gè)信(xìn)号(hào)都是(shì)1比特(tè)的(de),根(gēn)據(jù)这(zhè)些信(xìn)息,我(wǒ)们(men)補充輸入(rù)輸出(chū)端口(kǒu)定(dìng)義。代(dài)碼如(rú)下(xià):
|
1 2 3 4 |
input clk ; input rst_n ; input en ; output dout ; |
接下(xià)来(lái)定(dìng)義信(xìn)号(hào)類(lèi)型。
cnt是(shì)用(yòng)always産生(shēng)的(de)信(xìn)号(hào),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。cnt計(jì)數的(de)最(zuì)大值为(wèi)4,需要(yào)用(yòng)3根(gēn)線(xiàn)表(biǎo)示,即位宽(kuān)是(shì)3位。add_cnt和(hé)end_cnt都是(shì)用(yòng)assign方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)wire。并且其值是(shì)0或(huò)者(zhě)1,1个(gè)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 |
reg [ 2:0] cnt ; wire add_cnt ; wire end_cnt ; |
dout是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg dout ; |
flag_add是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg flag_add ; |
至(zhì)此(cǐ),整个(gè)代(dài)碼的(de)設計(jì)工作已經(jīng)完成(chéng)。整體(tǐ)代(dài)碼如(rú)下(xià):
|
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 |
module my_ex2( clk , rst_n , en , dout );
input clk ; input rst_n ; input en ; output dout ;
reg [ 2:0] cnt ; wire add_cnt ; wire end_cnt ; reg flag_add ; reg dout ;
always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 0; end else if(add_cnt) begin if(end_cnt) &nbs p; cnt <= 0; else &nbs p; cnt <= cnt + 1; end end
assign add_cnt = flag_add==1; assign end_cnt = add_cnt && cnt==5-1 ;
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_add <= 0; end else if(en==1) begin flag_add <= 1; end else if(end_cnt) begin flag_add <= 0; end end
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(add_cnt && cnt==3-1)begin dout <= 1; end else if(end_cnt) begin dout <= 0; end end
endmodule |
經(jīng)过(guò)这(zhè)个(gè)案(àn)例,我(wǒ)们(men)做一(yī)下(xià)總(zǒng)結:在(zài)設計(jì)計(jì)數器的(de)时(shí)候,如(rú)果(guǒ)計(jì)數區(qū)域沒(méi)有(yǒu)信(xìn)号(hào)来(lái)表(biǎo)示时(shí),可(kě)補充一(yī)个(gè)信(xìn)号(hào)flag_add。
1.2.3 至(zhì)簡設計(jì)法設計(jì)類(lèi)型3
案(àn)例3. 當收(shōu)到(dào)en1=1时(shí),dout産生(shēng)3个(gè)时(shí)鐘(zhōng)周期(qī)的(de)高(gāo)電(diàn)平脈沖;當收(shōu)到(dào)en2==1时(shí),dout産生(shēng)2个(gè)周期(qī)的(de)高(gāo)電(diàn)平脈沖 。下(xià)面(miàn)波(bō)形图(tú)描述了(le)該功能(néng)。
图(tú) 121
图(tú)中(zhōng),第(dì)3个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿收(shōu)到(dào)en1==1,所(suǒ)以(yǐ)dout變(biàn)1并且持(chí)續3个(gè)时(shí)鐘(zhōng)周期(qī);在(zài)第(dì)9个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿看(kàn)到(dào)en2==1,所(suǒ)以(yǐ) dout變(biàn)1并且持(chí)續2个(gè)时(shí)鐘(zhōng)周期(qī)。注意(yì),en1==1和(hé)en2==1的(de)出(chū)現(xiàn)是(shì)沒(méi)有(yǒu)順序的(de)。
有(yǒu)读(dú)者(zhě)可(kě)能(néng)会(huì)問(wèn),如(rú)果(guǒ)en1==1和(hé)en2==1同(tóng)时(shí)出(chū)現(xiàn),或(huò)者(zhě)说(shuō)在(zài)dout==1期(qī)間(jiān),出(chū)現(xiàn)了(le)en1==1或(huò)者(zhě)en2==1,該怎麼(me)辦(bàn)?請不(bù)要(yào)考慮这(zhè)種(zhǒng)情(qíng)況,本(běn)案(àn)例假設永遠(yuǎn)不(bù)会(huì)出(chū)現(xiàn)該情(qíng)況。明(míng)德揚在(zài)模块(kuài)劃(huà)分(fēn)規範时(shí),会(huì)要(yào)求各(gè)个(gè)模块(kuài)之間(jiān)配合清(qīng)楚,这(zhè)有(yǒu)助于(yú)簡化(huà)我(wǒ)们(men)的(de)設計(jì),精簡系(xì)統。
看(kàn)到(dào)大于(yú)1的(de)數字(zì),就(jiù)知道(dào)要(yào)計(jì)數。推薦的(de)計(jì)數方(fāng)式如(rú)下(xià):
图(tú) 122
首先(xiān),不(bù)要(yào)用(yòng)2个(gè)計(jì)數器分(fēn)别計(jì)两(liǎng)種(zhǒng)情(qíng)況。这(zhè)是(shì)因(yīn)为(wèi)这(zhè)2个(gè)計(jì)數器都是(shì)不(bù)同(tóng)时(shí)計(jì)數的(de),是(shì)可(kě)以(yǐ)合并的(de)。同(tóng)时(shí),我(wǒ)们(men)可(kě)以(yǐ)知道(dào),这(zhè)两(liǎng)種(zhǒng)情(qíng)況都是(shì)計(jì)算dout==1的(de)次(cì)數。
在(zài)确認計(jì)數器數多(duō)少(shǎo)个(gè)时(shí),我(wǒ)们(men)遇到(dào)了(le)問(wèn)題(tí)。因(yīn)为(wèi)这(zhè)个(gè)計(jì)數器有(yǒu)时(shí)候數到(dào)3个(gè)就(jiù)清(qīng)零(líng)(en1==1觸發(fà)的(de)波(bō)形),有(yǒu)时(shí)候數到(dào)2个(gè)就(jiù)清(qīng)零(líng)(en2==1觸發(fà) 的(de)波(bō)形)。此(cǐ)时(shí),我(wǒ)们(men)建議你用(yòng)變(biàn)量(liàng)x代(dài)替,即數到(dào)x个(gè)。注意(yì),verilog是(shì)沒(méi)有(yǒu)變(biàn)量(liàng)的(de)概念的(de),这(zhè)个(gè)變(biàn)量(liàng),是(shì)明(míng)德揚提(tí)出(chū)的(de)一(yī)个(gè)設計(jì)概念,x本(běn)質(zhì)上(shàng)還(huán)是(shì)一(yī)个(gè)信(xìn)号(hào)。
引入(rù)變(biàn)量(liàng)有(yǒu)什麼(me)用(yòng)呢?設計(jì)計(jì)數器时(shí)就(jiù)方(fāng)便了(le),該計(jì)數器加1条(tiáo)件(jiàn)是(shì)dout==1,數x个(gè)就(jiù)結束(shù),因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
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) &nbs p; cnt <= 0; else &nbs p; cnt <= cnt + 1; end end
assign add_cnt = dout==1; assign end_cnt = add_cnt && cnt==x-1 ; |
甚至(zhì)我(wǒ)们(men)還(huán)可(kě)以(yǐ)写出(chū)dout的(de)代(dài)碼,dout變(biàn)1的(de)条(tiáo)件(jiàn)是(shì):en1==1或(huò)者(zhě)en2==1;變(biàn)0的(de)条(tiáo)件(jiàn)是(shì):計(jì)數器數完了(le)。所(suǒ)以(yǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(en1==1 || en2==1)begin dout <= 1; end else if(end_cnt) begin dout <= 0; end end |
我(wǒ)们(men)再設計(jì)一(yī)下(xià)變(biàn)量(liàng)x,我(wǒ)们(men)知道(dào)計(jì)數器en1==1觸發(fà)的(de)时(shí)候數3个(gè)就(jiù)清(qīng)零(líng),en2==1觸發(fà)的(de)时(shí)候數到(dào)2个(gè)就(jiù)清(qīng)零(líng),为(wèi)此(cǐ)增加一(yī)个(gè)信(xìn)号(hào)flag_sel来(lái)區(qū)分(fēn)这(zhè)两(liǎng)種(zhǒng)情(qíng)況,flag_sel==0表(biǎo)示是(shì)en1==1觸發(fà)的(de),flag_sel==1表(biǎo)示是(shì)en2==1觸發(fà)的(de),波(bō)形如(rú)下(xià):
图(tú) 123
flag_sel變(biàn)0的(de)条(tiáo)件(jiàn)是(shì)遇到(dào)en1==1,flag_sel變(biàn)1的(de)条(tiáo)件(jiàn)是(shì)遇到(dào)en2==1,为(wèi)此(cǐ)flag_sel的(de)代(dài)碼如(rú)下(xià)。
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_sel <= 0; end else if(en1==1) begin flag_sel <= 0; end else if(en2==1) begin flag_sel <= 1; end end |
有(yǒu)了(le)flag_sel,我(wǒ)们(men)就(jiù)好(hǎo)區(qū)分(fēn)x的(de)值了(le)。 flag_sel为(wèi)0时(shí),x为(wèi)3(數3个(gè)清(qīng)零(líng));flag_sel为(wèi)1时(shí),x为(wèi)2(數2个(gè)清(qīng)零(líng)),此(cǐ)时(shí)要(yào)用(yòng)組合邏輯設計(jì)x,不(bù)然会(huì)出(chū)錯的(de)。代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 |
always @(*)begin if(flag_sel==0) x = 3; else x = 2; end |
至(zhì)此(cǐ),本(běn)工程的(de)主(zhǔ)體(tǐ)程序已經(jīng)設計(jì)完畢,本(běn)題(tí),我(wǒ)们(men)使用(yòng)了(le)變(biàn)量(liàng)x,这(zhè)是(shì)明(míng)德揚的(de)至(zhì)簡設計(jì)方(fāng)法中(zhōng)的(de)變(biàn)量(liàng)法。
主(zhǔ)體(tǐ)程序完成(chéng)後(hòu),我(wǒ)们(men)補充模块(kuài)的(de)其他(tā)部(bù)分(fēn)。
将module的(de)名稱定(dìng)義为(wèi)my_ex3。并且我(wǒ)们(men)已經(jīng)知道(dào)該模块(kuài)有(yǒu)5个(gè)信(xìn)号(hào):clk、rst_n、en1、en2和(hé)dout。为(wèi)此(cǐ) ,代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 7 |
module my_ex3( clk , rst_n , en1 , en2 , dout ); |
其中(zhōng)clk、rst_n、en1和(hé)en2是(shì)輸入(rù)信(xìn)号(hào),dout是(shì)輸出(chū)信(xìn)号(hào),并且5个(gè)信(xìn)号(hào)都是(shì)1比特(tè)的(de),根(gēn)據(jù)这(zhè)些信(xìn)息,我(wǒ)们(men)補充輸入(rù)輸出(chū)端口(kǒu)定(dìng)義。代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 |
input clk ; input rst_n ; input en1 ; input en2 ; output dout ; |
接下(xià)来(lái)定(dìng)義信(xìn)号(hào)類(lèi)型。
cnt是(shì)用(yòng)always産生(shēng)的(de)信(xìn)号(hào),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。cnt計(jì)數的(de)最(zuì)大值为(wèi)2,需要(yào)用(yòng)2根(gēn)線(xiàn)表(biǎo)示,即位宽(kuān)是(shì)2位。add_cnt和(hé)end_cnt都是(shì)用(yòng)assign方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)wire。并且其值是(shì)0或(huò)者(zhě)1,1个(gè)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 |
reg [ 1:0] cnt ; wire add_cnt ; wire end_cnt ; |
dout是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg dout ; |
flag_sel是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg flag_sel ; |
x是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg,并且其值最(zuì)大为(wèi)3,用(yòng)2根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg [ 1:0] x ; |
至(zhì)此(cǐ),整个(gè)代(dài)碼的(de)設計(jì)工作已經(jīng)完成(chéng)。整體(tǐ)代(dài)碼如(rú)下(xià):
|
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 |
module my_ex3( clk , rst_n , en1 , en2 , dout );
input clk ; input rst_n ; input en1 ; input en2 ; output dout ;
reg [ 1:0] cnt ; wire add_cnt ; wire end_cnt ; reg dout ; reg flag_sel ; reg [ 1:0] x ;
always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 0; end else if(add_cnt) begin if(end_cnt) &nbs p; cnt <= 0; else &nbs p; cnt <= cnt + 1; end end
assign add_cnt = dout==1; assign end_cnt = add_cnt && cnt==x-1 ;
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(en1==1 || en2==1)begin dout <= 1; end else if(end_cnt) begin dout <= 0; end end
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_sel <= 0; end else if(en2==1) begin flag_sel <= 1; end else if(en1==1) begin flag_sel <= 0; end end
always @(*)begin if(flag_sel==0) x = 3; else x = 2; end
endmodule |
總(zǒng)結:設計(jì)时(shí),我(wǒ)们(men)不(bù)要(yào)受具體(tǐ)數字(zì)的(de)影響,而(ér)是(shì)仔细(xì)識别信(xìn)号(hào)的(de)一(yī)致(zhì)性(xìng)動(dòng)作,然後(hòu)利用(yòng)變(biàn)量(liàng)法来(lái)設計(jì)。这(zhè)樣(yàng)就(jiù)能(néng)設計(jì)出(chū)精妙的(de)代(dài)碼。
1.2.4 至(zhì)簡設計(jì)法設計(jì)類(lèi)型4
案(àn)例4. 當收(shōu)到(dào)en=1时(shí),dout間(jiān)隔1个(gè)时(shí)鐘(zhōng)後(hòu),産生(shēng)2个(gè)时(shí)鐘(zhōng)周期(qī)的(de)高(gāo)電(diàn)平脈沖,并且重(zhòng)複3次(cì)。
图(tú) 124
上(shàng)面(miàn)波(bō)形图(tú)顯示了(le)描述的(de)功能(néng)。第(dì)3个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿收(shōu)到(dào)en==1,所(suǒ)以(yǐ)dout間(jiān)隔1个(gè)时(shí)鐘(zhōng)後(hòu)變(biàn)1并且持(chí)續2个(gè)时(shí)鐘(zhōng)周期(qī),这(zhè)个(gè)動(dòng)作重(zhòng)複3次(cì),結束(shù)。
看(kàn)到(dào)大于(yú)1的(de)數字(zì),就(jiù)知道(dào)要(yào)計(jì)數。下(xià)面(miàn)的(de)計(jì)數方(fāng)式非(fēi)常普遍(biàn):
图(tú) 125
即用(yòng)一(yī)个(gè)計(jì)數器,從头(tóu)數到(dào)尾。这(zhè)个(gè)計(jì)數器的(de)設計(jì)很簡單,但産生(shēng)dout信(xìn)号(hào)就(jiù)不(bù)容易了(le)。
明(míng)德揚推薦的(de)計(jì)數方(fāng)式如(rú)下(xià):
图(tú) 126
利用(yòng)2个(gè)計(jì)數器。cnt0就(jiù)如(rú)案(àn)例2一(yī)樣(yàng),數的(de)是(shì)間(jiān)隔和(hé)高(gāo)電(diàn)平时(shí)鐘(zhōng);而(ér)計(jì)數器cnt1數的(de)是(shì)重(zhòng)複次(cì)數。
如(rú)案(àn)例2相同(tóng),需要(yào)添加信(xìn)号(hào)flag_add来(lái)指示cnt0的(de)加1區(qū)域,波(bō)形如(rú)下(xià)图(tú)。
图(tú) 127
所(suǒ)以(yǐ)cnt0的(de)加1条(tiáo)件(jiàn)是(shì)flag_add==1,計(jì)數3个(gè)就(jiù)清(qīng)零(líng)。
仔细(xì)观察cnt1可(kě)以(yǐ)看(kàn)到(dào),每次(cì)cnt0數完後(hòu),cnt1就(jiù)会(huì)加1。所(suǒ)以(yǐ)cnt1的(de)加1条(tiáo)件(jiàn)是(shì)end_cnt0,計(jì)數3个(gè)就(jiù)清(qīng)零(líng)。從而(ér)我(wǒ)们(men)可(kě)以(yǐ)設計(jì)出(chū)cnt0和(hé)cnt1的(de)代(dài)碼,輸入(rù)Jsq2,即可(kě)調出(chū)模板。
|
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 |
always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt0 <= 0; end else if(add_cnt0) begin if(end_cnt0) &nbs p; cnt0 <= 0; else &nbs p; cnt0 <= cnt0 + 1; end end
assign add_cnt0 = flag_add==1; assign end_cnt0 = add_cnt0 && cnt0==3-1 ;
always @(posedge clk or negedge rst_n)begin if(!rst_n) begin cnt1 <= 0; end else if(add_cnt1) begin if(end_cnt1) &nbs p; cnt1 <= 0; else &nbs p; cnt1 <= cnt1 + 1; end end
assign add_cnt1 = end_cnt0; assign end_cnt1 = add_cnt1 && cnt1==3-1 ; |
flag_add有(yǒu)两(liǎng)个(gè)變(biàn)化(huà)點(diǎn):變(biàn)1和(hé)變(biàn)0。變(biàn)1是(shì)因(yīn)为(wèi)en==1,變(biàn)0是(shì)因(yīn)为(wèi)重(zhòng)複次(cì)數都完了(le),也(yě)就(jiù)是(shì)end_cnt1。所(suǒ)以(yǐ)flag_add代(dài)碼如(rú)下(xià)。
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_add <= 0; end else if(en==1) begin flag_add <= 0; end else if(end_cnt1) begin flag_add <= 1; end end |
dout有(yǒu)两(liǎng)个(gè)變(biàn)化(huà)點(diǎn):變(biàn)1和(hé)變(biàn)0。在(zài)cnt0數到(dào)1时(shí)(一(yī)个(gè)間(jiān)隔)时(shí)變(biàn)1,在(zài)cnt0數完时(shí)變(biàn)0,所(suǒ)以(yǐ)dout的(de)代(dài)碼如(rú)下(xià)。
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(add_cnt0 && cnt0==1-1)begin dout <= 1; end else if(end_cnt0) begin dout <= 0; end end |
至(zhì)此(cǐ),本(běn)工程的(de)主(zhǔ)體(tǐ)程序已經(jīng)設計(jì)完畢,之後(hòu)需要(yào)读(dú)者(zhě)補充信(xìn)号(hào)定(dìng)義、輸入(rù)輸出(chū)定(dìng)義了(le)。
将module的(de)名稱定(dìng)義为(wèi)my_ex3。并且我(wǒ)们(men)已經(jīng)知道(dào)該模块(kuài)有(yǒu)5个(gè)信(xìn)号(hào):clk、rst_n、en和(hé)dout。为(wèi)此(cǐ),代(dài)碼如(rú)下(xià):
|
1 2 3 4 5 6 |
module my_ex4( clk , rst_ n , en , dout ); |
其中(zhōng)clk、rst_n、en是(shì)輸入(rù)信(xìn)号(hào),dout是(shì)輸出(chū)信(xìn)号(hào),并且4个(gè)信(xìn)号(hào)都是(shì)1比特(tè)的(de),根(gēn)據(jù)这(zhè)些信(xìn)息,我(wǒ)们(men)補充輸入(rù)輸出(chū)端口(kǒu)定(dìng)義。代(dài)碼如(rú)下(xià):
|
1 2 3 4 |
input clk ; input rst_n ; input en ; output dout ; |
接下(xià)来(lái)定(dìng)義信(xìn)号(hào)類(lèi)型。
cnt0是(shì)用(yòng)always産生(shēng)的(de)信(xìn)号(hào),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。cnt0計(jì)數的(de)最(zuì)大值为(wèi)2,需要(yào)用(yòng)2根(gēn)線(xiàn)表(biǎo)示,即位宽(kuān)是(shì) 2位。add_cnt0和(hé)end_cnt0都是(shì)用(yòng)assign方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)wire。并且其值是(shì) 0或(huò)者(zhě)1,1个(gè)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 |
reg [ 1:0] cnt0 ; wire add_cnt0 ; wire end_cnt0 ; |
cnt1是(shì)用(yòng)always産生(shēng)的(de)信(xìn)号(hào),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。cnt1計(jì)數的(de) 最(zuì)大值为(wèi)2,需要(yào)用(yòng)2根(gēn)線(xiàn)表(biǎo)示,即位宽(kuān)是(shì)2位。 add_cnt1和(hé)end_cnt1都是(shì)用(yòng)assign方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)wire。并且其值是(shì)0或(huò)者(zhě)1,1个(gè)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 2 3 |
reg [ 1:0] cnt1 ; wire add_cnt1 ; wire end_cnt1 ; |
dout是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg dout ; |
flag_add是(shì)用(yòng)always方(fāng)式設計(jì)的(de),因(yīn)此(cǐ)類(lèi)型为(wèi)reg。并且其值是(shì)0或(huò)者(zhě)1,1根(gēn)線(xiàn)表(biǎo)示即可(kě)。因(yīn)此(cǐ)代(dài)碼如(rú)下(xià):
|
1 |
reg flag_add ; |
至(zhì)此(cǐ),整个(gè)代(dài)碼的(de)設計(jì)工作已經(jīng)完成(chéng)。整體(tǐ)代(dài)碼如(rú)下(xià):
|
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 8 |
module my_ex4( clk , rst_n , en , dout );
input clk ; input rst_n ; input en ; output dout ;
reg [ 1:0] cnt0 ; wire add_cnt0 ; wire end_cnt0 ;
reg [ 1:0] cnt1 ; wire add_cnt1 ; wire end_cnt1 ; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt0 <= 0; end else if(add_cnt0) begin if(end_cnt0) &nbs p; cnt0 <= 0; else &nbs p; cnt0 <= cnt0 + 1; end end
assign add_cnt0 = flag_add==1; assign end_cnt0 = add_cnt0 && cnt0==3-1 ;
always @(posedge clk or negedge rst_n)begin if(!rst_n) begin cnt1 <= 0; end else if(add_cnt1) begin if(end_cnt1) &nbs p; cnt1 <= 0; else &nbs p; cnt1 <= cnt1 + 1; end end
assign add_cnt1 = end_cnt0; assign end_cnt1 = add_cnt1 && cnt1==3-1 ;
reg flag_add ;
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_add <= 0; end else if(en==1) begin flag_add <= 1; end else if(end_cnt1) begin flag_add <= 0; end end
reg dout ;
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(add_cnt0 && cnt0==1-1)begin dout <= 1; end else if(end_cnt0) begin dout <= 0; end end
endmodule |
本(běn)題(tí)中(zhōng),我(wǒ)们(men)設計(jì)了(le)2个(gè)計(jì)數器 ,從而(ér)使得dout的(de)設計(jì)非(fēi)常簡單。計(jì)數器的(de)組合使用(yòng),对(duì)設計(jì)的(de)複雜度(dù)有(yǒu)非(fēi)常大的(de)影響。合理和(hé)正(zhèng)确使用(yòng),将能(néng)設計(jì)出(chū)賞心(xīn)悅目的(de)代(dài)碼。
1.3 至(zhì)簡設計(jì)法高(gāo)效設計(jì)
上(shàng)一(yī)节(jié)我(wǒ)们(men)描述了(le)四(sì)種(zhǒng)情(qíng)況下(xià)的(de)設計(jì)方(fāng)法。在(zài)闡述案(àn)例过(guò)程中(zhōng),我(wǒ)们(men)画(huà)出(chū)了(le)大量(liàng)的(de)波(bō)形图(tú)。有(yǒu)读(dú)者(zhě)可(kě)能(néng)会(huì)問(wèn),在(zài)工作中(zhōng),我(wǒ)们(men)是(shì)不(bù)是(shì)也(yě)需要(yào)先(xiān)大量(liàng)地(dì)画(huà)波(bō)形图(tú),再来(lái)写代(dài)碼呢?
不(bù)是(shì)的(de)!工作中(zhōng),我(wǒ)们(men)要(yào)設計(jì)的(de)系(xì)統更(gèng)加的(de)複雜,一(yī)个(gè)模块(kuài)的(de)信(xìn)号(hào)也(yě)非(fēi)常地(dì)多(duō),如(rú)果(guǒ)我(wǒ)们(men)每个(gè)模块(kuài)都要(yào)画(huà)波(bō)形图(tú),这(zhè)不(bù)是(shì)明(míng)德揚提(tí)倡的(de)至(zhì)簡設計(jì)。何況,功能(néng)一(yī)複雜,画(huà)出(chū)来(lái)的(de)波(bō)形信(xìn)号(hào)也(yě)是(shì)相當地(dì)多(duō),也(yě)容易迷糊當中(zhōng)。
在(zài)上(shàng)一(yī)节(jié)中(zhōng),我(wǒ)们(men)画(huà)波(bō)形图(tú)的(de)目的(de),是(shì)为(wèi)了(le)讓读(dú)者(zhě)更(gèng)清(qīng)晰地(dì)理解(jiě)功能(néng)、計(jì)數器和(hé)信(xìn)号(hào)的(de)關(guān)系(xì)。如(rú)果(guǒ)我(wǒ)们(men)牢記(jì)明(míng)德揚的(de)規則。或(huò)者(zhě)熟練掌握後(hòu),波(bō)形存在(zài)心(xīn)中(zhōng)即可(kě)。我(wǒ)们(men)的(de)設計(jì)将非(fēi)常簡單。
FPGA其实不(bù)是(shì)波(bō)形設計(jì),而(ér)是(shì)功能(néng)設計(jì),講究的(de)是(shì)邏輯,講究的(de)是(shì)因(yīn)果(guǒ)關(guān)系(xì)。功能(néng)設計(jì)就(jiù)是(shì)根(gēn)據(jù)功能(néng)需求,編写我(wǒ)们(men)的(de)設計(jì)代(dài)碼。我(wǒ)们(men)以(yǐ)上(shàng)一(yī)节(jié)中(zhōng)的(de)案(àn)例4为(wèi)例,说(shuō)明(míng)什麼(me)叫功能(néng)設計(jì)。
案(àn)例4的(de)功能(néng)要(yào)求是(shì):當收(shōu)到(dào)en=1时(shí),dout間(jiān)隔1个(gè)时(shí)鐘(zhōng)後(hòu),産生(shēng)2个(gè)时(shí)鐘(zhōng)周期(qī)的(de)高(gāo)電(diàn)平脈沖,并且重(zhòng)複3次(cì)。
由(yóu)題(tí)意(yì)可(kě)知,要(yào)对(duì)“間(jiān)隔” 和(hé)“高(gāo)電(diàn)平”个(gè)數進(jìn)行計(jì)數,但沒(méi)有(yǒu)信(xìn)号(hào)表(biǎo)示“高(gāo)隔”,为(wèi)此(cǐ)想(xiǎng)出(chū)補充一(yī)个(gè)信(xìn)号(hào) flag_add,用(yòng)来(lái)表(biǎo)示計(jì)數區(qū)域。間(jiān)隔时(shí)間(jiān)+高(gāo)電(diàn)平时(shí)間(jiān),得到(dào)計(jì)數器數3个(gè)。
图(tú) 128
我(wǒ)们(men)看(kàn)到(dào)重(zhòng)複3次(cì)这(zhè)一(yī)句(jù)話(huà),这(zhè)就(jiù)说(shuō)明(míng)還(huán)有(yǒu)一(yī)个(gè)計(jì)數器計(jì)數重(zhòng)複的(de)次(cì)數。自(zì)然地(dì)想(xiǎng)到(dào),每完成(chéng)一(yī)次(cì)就(jiù)加1,一(yī)共(gòng)加3次(cì)。得到(dào)代(dài)碼如(rú)下(xià)。
图(tú) 129
在(zài)設計(jì)計(jì)數器0的(de)时(shí)候,新增了(le)信(xìn)号(hào)flag_add。那(nà)進(jìn)一(yī)步思(sī)考,什麼(me)时(shí)候要(yào)産生(shēng)動(dòng)作,那(nà)就(jiù)讓flag_add为(wèi)1。自(zì)然, 從題(tí)意(yì)可(kě)知,en==1是(shì)開(kāi)始,重(zhòng)複次(cì)數完了(le),那(nà)就(jiù)結束(shù),不(bù)用(yòng)再産生(shēng)信(xìn)号(hào)。所(suǒ)以(yǐ)flag_add代(dài)碼。
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin flag_add <= 0; end else if(en==1) begin flag_add <= 0; end else if(end_cnt1) begin flag_add <= 1; end end |
最(zuì)後(hòu)我(wǒ)们(men)再来(lái)設計(jì)dout,由(yóu)題(tí)意(yì)可(kě)知,每次(cì)均是(shì)間(jiān)隔1个(gè)之後(hòu)dout變(biàn)1,2个(gè)时(shí)鐘(zhōng)之後(hòu)變(biàn)0。那(nà)用(yòng)什麼(me)来(lái)數这(zhè)个(gè)1和(hé)2呢?cnt0。綜合起来(lái),就(jiù)是(shì)说(shuō)cnt0數到(dào)1个(gè)後(hòu),dout變(biàn)1,數完後(hòu)變(biàn)0。
|
1 2 3 4 5 6 7 8 9 10 11 |
always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin dout <= 0; end else if(add_cnt0 && cnt0==1-1)begin dout <= 1; end else if(end_cnt0) begin dout <= 0; end end |
總(zǒng)結:從功能(néng)的(de)文(wén)字(zì)描述中(zhōng)出(chū)發(fà),根(gēn)據(jù)功能(néng)要(yào)求来(lái)設計(jì)代(dài)碼。在(zài)設計(jì)时(shí),一(yī)定(dìng)要(yào)理解(jiě)清(qīng)楚信(xìn)号(hào)的(de)因(yīn)果(guǒ)關(guān)系(xì),例如(rú)为(wèi)什麼(me)變(biàn)0,为(wèi)什麼(me)變(biàn)1,從功能(néng)说(shuō)明(míng)中(zhōng)找(zhǎo)答(dá)案(àn)。經(jīng)常訓練这(zhè)種(zhǒng)思(sī)考和(hé)設計(jì)方(fāng)式,幾(jǐ)分(fēn)鐘(zhōng)就(jiù)能(néng)設計(jì)出(chū)精妙的(de)代(dài)碼,而(ér)且因(yīn)果(guǒ)關(guān)系(xì)、邏輯關(guān)系(xì)清(qīng)楚,幾(jǐ)乎不(bù)存在(zài)出(chū)錯的(de)可(kě)能(néng),從而(ér)写出(chū)所(suǒ)想(xiǎng)即所(suǒ)得的(de)代(dài)碼。








