異步FIFO的實現(xiàn)方式(共14頁)_第1頁
異步FIFO的實現(xiàn)方式(共14頁)_第2頁
異步FIFO的實現(xiàn)方式(共14頁)_第3頁
異步FIFO的實現(xiàn)方式(共14頁)_第4頁
異步FIFO的實現(xiàn)方式(共14頁)_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、精選優(yōu)質(zhì)文檔-傾情為你奉上異步FIFO的實現(xiàn)方式實驗?zāi)康谋敬螌嶒灲榻B一種異步FIFO的實現(xiàn)方式。使用FIFO存儲器可以在兩個不同時鐘系統(tǒng)之間快速而方便的傳輸數(shù)據(jù)。另外,在網(wǎng)絡(luò)接口,圖像處理等方面異步FIFO存儲器也得到了廣泛的應(yīng)用。因此,異步FIFO存儲器具有較大的研究和應(yīng)用價值。異步FIFO的介紹和整體結(jié)構(gòu)異步FIFO(First In First Out)存儲器是指向FIFO緩沖器中寫入數(shù)據(jù)的時鐘域和從FIFO緩沖器中讀取數(shù)據(jù)的時鐘域是不同的,這兩個時鐘之間沒有必然的因果關(guān)系。異步FIFO是一種先進(jìn)先出的電路,使用在異步時鐘域數(shù)據(jù)接口的部分,用來存儲、緩沖在兩個異步時鐘之間的數(shù)據(jù)傳輸。在異

2、步電路中,由于時鐘之間周期和相位完全獨立,所以數(shù)據(jù)的丟失概率不為零。如何設(shè)計一個高可靠性、高速的異步FIFO存儲器便成為一個難點。異步FIFO的一般結(jié)構(gòu)如圖1所示,都是由一個讀時鐘域電路、一個寫時鐘域電路和一個雙端口的RAM來構(gòu)成的。異步FIFO與同步FIFO所做的工作是相同的,都是在寫信號有效時寫數(shù)據(jù)到RAM中,在讀信號有效時把數(shù)據(jù)從RAM中讀出,所以對于中間部分的RAM設(shè)計是比較簡單的。另外,讀電路和寫電路單獨實現(xiàn)起來也是比較容易的,只需要按照同步FIFO的工作情況,如果沒有寫滿或讀空的狀態(tài)時每寫一個數(shù)據(jù)就把寫地址加1,每讀一個數(shù)據(jù)就把讀地址減1。設(shè)計難點在于兩個時鐘域的交疊部分:滿、空狀

3、態(tài)的產(chǎn)生,這也是設(shè)計的重點。圖1 異步FIFO結(jié)構(gòu)針對這個問題,先從對亞穩(wěn)態(tài)的處理開始介紹亞穩(wěn)態(tài)的處理一個觸發(fā)器進(jìn)入亞穩(wěn)態(tài)時,既無法預(yù)測該單元的輸出電平,也無法預(yù)測何時輸出才能穩(wěn)定在某個正確的電平上。在這個穩(wěn)定期間,觸發(fā)器輸出一些中間級電平,或者可能處于振蕩狀態(tài)、并且這種無用的輸出電平可以沿信號通道上的各個觸發(fā)器級聯(lián)式傳播下去。亞穩(wěn)態(tài)發(fā)生的原因是由于在同步系統(tǒng)中,如果觸發(fā)器的建立時間或保持時間不滿足,就可能產(chǎn)生亞穩(wěn)態(tài),此時觸發(fā)器輸出端Q在亞穩(wěn)態(tài)是指觸發(fā)器無法在某個規(guī)定時間段內(nèi)達(dá)到一個可確認(rèn)的狀態(tài),邏輯誤判有可能通過電路的特殊設(shè)計減輕危害(如本設(shè)計中將使用的Gray碼計數(shù)器),而亞穩(wěn)態(tài)的傳播則擴(kuò)

4、大了故障面,難以處理。在數(shù)字集成電路中寄存器要滿足建立時間和保持時間。建立時間是在時鐘翻轉(zhuǎn)之前數(shù)據(jù)輸入必須有效的時間,保持時間是在時鐘沿之后數(shù)據(jù)輸出必須仍然有效的時間。當(dāng)一個信號被寄存器鎖存時,如果信號和時鐘之間不滿足這個要求,Q的值是不確定的,并且在未知的時刻會固定到高電平或低電平。此時寄存器進(jìn)入了亞穩(wěn)態(tài)(Metastability)。解決這一問題的最簡單方法是使用同步器,使得在另一個時鐘域采樣時信號足夠穩(wěn)定。同步器的設(shè)計本身就是一個比較麻煩的問題,本次設(shè)計中也不深入討論一些細(xì)節(jié)性的問題,直接采用兩級采樣的同步器,避免了使用一級同步器仍可能出現(xiàn)亞穩(wěn)態(tài)的情況。每個這樣的同步器都具有一個等于時鐘

5、周期的等待時間。這種同步器可以把一些亞穩(wěn)態(tài)的值同步為確定值,但并不一定是正確值,同時有一些亞穩(wěn)態(tài)也還是無法穩(wěn)定成確切值的,這種情況稱為同步出錯。由于同步出錯的隨機(jī)性,很難對它們進(jìn)行跟蹤。如果想進(jìn)一步降低亞穩(wěn)態(tài)出現(xiàn)的概率、可以再増加同步器的級數(shù),但是太多的同步器會使系統(tǒng)的性能下降,所以系統(tǒng)中不會用太多的同步器,一般使用兩個同步器已經(jīng)足夠。空滿狀態(tài)的判斷之所以在前面介紹了亞穩(wěn)態(tài)的問題,是因為這是判斷滿狀態(tài)或空狀態(tài)無法回避的一個問題。因為讀電路在讀控制時維持一個地址指針,寫電路在寫控制時維持一個地址指針,簡單來說,這兩個地址指針直接一比較,就能得到空滿的判斷結(jié)果,但是實際操作起來非常麻煩。例如對于滿

6、狀態(tài)來說,這是寫入電路所關(guān)心的狀態(tài),因為滿狀態(tài)下不能繼續(xù)寫入數(shù)據(jù),但是空狀態(tài)對于寫電路沒有影響。如果寫入電路要判斷當(dāng)前FIFO是否為滿,就需要把寫電路自身維持的寫指針和讀電路維持的讀指針做比較,這個讀指針就需要送入寫電路中,此時就發(fā)生了穿過時鐘域的問題,也就是說,讀指針要從讀時鐘域同步到寫時鐘域,然后參與判斷,此時就需要前面介紹的同步器。同樣,對于空狀態(tài)來說,這是讀出電路所關(guān)心的狀態(tài),也是由讀電路來維持的,因為空狀態(tài)下再讀數(shù)就會得到錯誤的數(shù)據(jù),但是滿狀態(tài)下讀數(shù)是沒有影響的。如果讀電路要判斷當(dāng)前FIFO是否為空,就需要把寫時鐘域中的寫指針取到讀時鐘域來,和讀時鐘域的讀指針進(jìn)行比較得出是否是空狀態(tài)

7、,同樣跨越了時鐘域。在跨時鐘域系統(tǒng)中希望出現(xiàn)錯誤的概率越低越好,此時格雷碼無疑是最好的一個選擇。格雷碼屬于可靠性編碼,是一種誤差最小化的編碼,它大大減少了由一個狀態(tài)到下一個狀態(tài)時電路混淆。由這種編碼相鄰的兩個碼組之間只有一位不同,和其他編碼同時改變2位和多位的情況相比更為可靠。表1所示是格雷碼與二進(jìn)制碼的對應(yīng)關(guān)系。 表1 格雷碼與二進(jìn)制碼轉(zhuǎn)換真值表由前面的介紹可知通過同步器之后信號穩(wěn)定的值可能是1也可能是0,可能與輸入的值相同也可能與輸入的值不同。如果對于二進(jìn)制碼,這顯然是災(zāi)難性的。例如從十進(jìn)制的7變到8,二進(jìn)制碼是從0111變?yōu)?000,把0111送入同步器之后,由于4位都要變化,所以4位都

8、可能會出現(xiàn)亞穩(wěn)態(tài),從而在同步器的輸出端就會出現(xiàn)各種可能性,這樣即使數(shù)據(jù)穩(wěn)定下來,對整個電路的作用也很小。而如果采用格雷碼,是從0100變?yōu)?100,只是最高位發(fā)生了改變,也就只有這一位可能會出現(xiàn)亞穩(wěn)態(tài)的情況。這樣經(jīng)過同步器處理之后,輸出端可能得到的值只有兩種0100或1100,其中1100是正確的數(shù)值,如果得到這個輸出自然是最好,但即使是0100的輸出,也只是和原來的值相同,可以認(rèn)為沒有變化,這也不會對電路造成負(fù)面的影響。相比二進(jìn)制代碼那種變化后什么值都有可能的情況,格雷碼顯然是一種更易于接受的編碼方式。格雷碼雖然在跨時鐘域方面效果比較好,但在本身計數(shù)方面是不足的,也就是說還需要把格雷碼轉(zhuǎn)換成

9、二進(jìn)制碼來計數(shù),4位的格雷碼轉(zhuǎn)二進(jìn)制碼的代碼部分如下:bin0=gray3gray2 gray1 gray0;bin1=gray3gray2 gray1;bin2=gray3gray2;bin2=gray3;也可以用for循環(huán)完成:module gray2(bin,gray);parameter size=4;output size-1:0 bin;input size-1:0 gray;reg size-1:0 bin;integer i;always (gray) for(i=0;i,size;i=i=i+1);bini=(gray>>1);endmodule計數(shù)之后還要變回格

10、雷碼,轉(zhuǎn)換的方法與上述方式類似。這樣使用格雷碼作為指針就可以降低亞穩(wěn)態(tài)帶來的影響。接下來要解決的是空滿判斷的問題,常用的判斷方法是附加位比較法。附加位比較法是給每個指針增加一個附加位,對于二進(jìn)制指針而言,將存儲空間的最后一個存儲單元寫入數(shù)據(jù)后,地址將變?yōu)榱?,即地址指針低n-1位清零并向最高位(MSB)也就是附加位進(jìn)位。讀指針也是如此工作。如果兩個指針的最高位(MSBs)不同而其余位相同,就說明寫指針比讀指針多循環(huán)了一次,標(biāo)志FIFO存儲器處于滿狀態(tài)。如果包括最高位在內(nèi)的兩個指針完全相同,則說明寫指針和讀指針經(jīng)歷了相同次數(shù)的循環(huán),也就是說FIFO存儲器處于空狀態(tài)。這樣讀指針和寫指針就變成了一個n

11、位指針,其中低n-1位是用來存放FIFO存儲器的地址,可以用來對2n-1個存儲單元尋址,而最高位則用來辨別當(dāng)兩個指針的地址相等時是滿狀態(tài)還是空狀態(tài)。對二進(jìn)制指針來說,用這種方式來區(qū)分滿狀態(tài)與空狀態(tài)是可行的。但是,格雷碼指針卻不能直接使用這種方式,原因有兩個。舉個4位格雷碼的例子,格雷碼計數(shù)器的低3位用于存放存儲地址,第四位是附加位,這個FIFO存儲器的存儲容量為8。正確的操作應(yīng)當(dāng)是,當(dāng)寫(或讀)完一個循環(huán)時,地址應(yīng)該重新開始計數(shù),附加位應(yīng)該翻轉(zhuǎn)。然而格雷碼指針卻并非如此,地址由7到8格雷碼由0-100到1-100),指針的附加位改變,但是地址位(低n-1位)卻沒有重新開始計數(shù),這是由于格雷碼是

12、一種鏡像碼造成的。第二個原因是這種格雷碼不能直接產(chǎn)生滿狀態(tài)標(biāo)志。如果兩個格雷碼指針都是Gray-7,這時的FIFO存儲器為空狀態(tài),在進(jìn)行一次寫操作后寫指針將加1,格雷碼第4位將變?yōu)?而低3位不變,這時的讀指針和寫指針的最高位將不同而低位相同。如果這樣的話,F(xiàn)IFO存儲器滿標(biāo)志將置位,這顯然是錯誤的,因而需要對這個4位的格雷碼進(jìn)行修改。想要的結(jié)果是:一個n位的(即包括附加位)格雷碼計數(shù)器用在異步時鐘域間傳遞數(shù)據(jù),但是又希望它的低n-1位計數(shù)器也是格雷碼類型的。這樣低n-1位就能單獨形成一個循環(huán),而不是一種反射碼。所以,此時需要的是一個既能產(chǎn)生n位的格雷碼序列又能產(chǎn)生n-1位的格雷碼序列的計數(shù)器。

13、分別實現(xiàn)一個n位的格雷碼計數(shù)器和一個n-1位的格雷碼計數(shù)器自是非常簡單:用一個計數(shù)器來實現(xiàn)一個n位的格雷碼計數(shù)器,并將這個計數(shù)器的次高位進(jìn)行修改而低位保持不變以實現(xiàn)一個n-1位的格雷碼計數(shù)器,這也不是一件很難的事情。這種既能產(chǎn)生n位格雷碼又能產(chǎn)生n-1位格雷碼的計數(shù)器被稱為"兩重格雷碼計數(shù)器。下面以3位和4位格雷碼來說明空滿狀態(tài)的判斷標(biāo)準(zhǔn)。3位格雷碼表示的就是地址空間,可以有8個存儲空間。由于寫入和讀出并不是按照從000開始的,而是可以以任意一個位置開始,比如存放數(shù)據(jù)可以按照十進(jìn)制地址5、6、7、0、1、2、3、4的地址順序來存放,讀出數(shù)據(jù)也同理,這樣為了表示循環(huán),就增加了1位變?yōu)?

14、位格雷碼。首先說明空狀態(tài)的判斷標(biāo)準(zhǔn),空狀態(tài)表示讀指針和寫指針重合,此時無論是看3位格雷碼還是4位格雷碼都應(yīng)該是完全相同,比如寫指針指向1010,讀指針也必然指向1010,這樣判斷空狀態(tài)就只需要判斷兩個指針是否相同,相同時即為空,不同時即為不空。然后解釋滿狀態(tài)的判斷標(biāo)準(zhǔn)。滿狀態(tài)判斷比較復(fù)雜。假設(shè)一次寫入數(shù)據(jù)是從十進(jìn)制地址6開始,連續(xù)寫入8個數(shù)據(jù)。到14,這時存滿8個數(shù)據(jù),應(yīng)產(chǎn)生滿狀態(tài)輸出,這兩個地址形式如下:十進(jìn)制地址6二進(jìn)制地址0110格雷碼地址0101十進(jìn)制地址14二進(jìn)制地址1110格雷碼地址1001如果是二進(jìn)制地址,判斷的方法已經(jīng)介紹過了。而格雷碼地址的前兩位是不同的,但后面的兩位是相同的

15、。如果擴(kuò)展成更多位的格雷碼,滿狀態(tài)下依然是這種情況,即前兩位不同,后面位均相同。這樣判斷滿狀態(tài)首先要保證除去前兩位之后的剩余部分是相同的。然后對于本例來說,需要保證前兩部分是01和10,如果地址是以01開頭,則滿時一定是10;如果以10開頭,滿時一定是01。判斷的方法可以有很多種,這里采用先取前兩位的異或值,保證相等,此時只可能是0,1的組合,然后再判斷首位不同,這樣就只能是01和10這兩種情況。經(jīng)過這三個條件的判斷,就能就保證此時為寫滿狀態(tài)。再觀察地址以00和11開頭的情況,給出地址如下十進(jìn)制地址2二進(jìn)制地址0010格雷碼地址0011十進(jìn)制地址10二進(jìn)制地址1010格雷碼地址1111剛才提出

16、的的三個條件依然保證寫滿狀態(tài)的正常輸出,所以寫滿狀態(tài)就以這三個條件作判斷標(biāo)準(zhǔn)。下面開始具體設(shè)計:頂層模塊的端口和功能針對異步FIFO的基本結(jié)構(gòu)和功能,以及保留一些必要的狀態(tài)信號和控制信號,現(xiàn)確定頂層模塊的端口與功能見表2:端口名稱功能說明rclk輸入信號,1位,讀時鐘wlck輸入信號,1位,寫時鐘rinc輸入信號,1位,讀使能信號,高電平時生效,表示寫入數(shù)據(jù)winc輸入信號,1位,寫使能信號,高電平時生效,表示讀出數(shù)據(jù)rrst_n輸入信號,1位,低電平時讀指針清零wrst_n輸入信號,1位,低電平時寫指針清零Rdata輸出信號,8位,從RAM中讀出數(shù)據(jù)Wdata輸入信號,8位,待寫入RAM數(shù)據(jù)

17、Wfull輸出信號,1位,高電平時表示FIFO已存滿數(shù)據(jù),已滿Rempty輸出信號,1位,高電平時表示FIFO中數(shù)據(jù)已全部讀出,已空表2 頂層模塊的端口與功能子模塊設(shè)計本設(shè)計的異步FIFO劃分為5個子模塊:讀指針控制模塊、寫指針控制模塊、存儲RAW模塊、讀指針同步到寫時鐘域模塊,寫指針同步到讀時鐘域模塊。依次介紹如下:兩個同步模塊這兩個同步模塊同前文介紹的一樣,是兩個寄存器連接的一起。寫指針同步到讀時鐘域模塊代碼如下module syne_w2r(rwptr2,wptr,rclk,rrst_n);parameter ADDRSIZE=4;output ADDRSIZE:0 rwptr2; /同

18、步后的寫指針input ADDRSIZE:0 wptr; /同步前的寫指針input rclk,rrst_n;reg ADDRSIZE:0 rwptr2,rwptr1; /兩個中間寄存器always (posedge rclk or negedge rrst_n)if(!rrst_n) rwptr2,rwptr1<=0; /復(fù)位else rwptr2,rwptr1<=rwptr1,wptr; /寄存器串聯(lián) Endmodule讀指針同步到寫時鐘域模塊代碼如下:module sync_r2w(wrptr2,rptr,wclk,wrst_n);parameter ADDRSIZE=4;

19、output ADDRSIZE:0 wrptr2;input ADDRSIZE:0 rptr;input wclk, wrst_n;reg ADDRSIZE:0 wrptr2, wrptrl;always (posedge wclk or negedge wrst_n)if (!wrst_n) wrptr2, wrptrl<=0;else wrptr2,wrptrl<= wrptrl,rptr; endmodule功能比較簡單,故不做仿真驗證存儲模塊module fifomem(rdata, wdata, waddr,raddr, wclken, wclk,rclken,rclk)

20、;parameter DATASIZE=8; / 數(shù)據(jù)寬度parameter ADDRSIZE=4; / 地址寬度output DATASIZE-1:0 rdata; input DATASIZE-1:0 wdata;input wclken, wclk,rclken,rclk; /讀寫控制和時鐘input ADDRSIZE-1:0 raddr, waddr; /輸入讀寫地址reg DATASIZE-1:0 rdata; reg DATASIZE-1:0 MEM 0:(1<<ADDRSIZE)-1; /存儲體always (posedge rclk) /讀時鐘讀出數(shù)據(jù)if (rcl

21、ken) rdata = MEMraddr; always (posedge wclk)if (wclken) MEMwaddr <= wdata; /寫時鐘寫入數(shù)據(jù)endmodule此模塊構(gòu)造了一個存儲器,按讀寫始終安排輸入和輸出。編寫測試模塊如下:module tbmem;parameter DATASIZE=8; parameter ADDRSIZE=4; wire DATASIZE-1:0 rdata;reg DATASIZE-1:0 wdata;reg wclken, wclk,rclken,rclk;reg ADDRSIZE-1:0 raddr, waddr;integer

22、seed1;initialbegin wclk=0;rclk=0;seed1=20; /初始化 waddr=0;raddr=0;endalways #9 wclk=wclk; /生成寫時鐘always #11 rclk=rclk; /生成讀時鐘always (posedge wclk)wdata<=$random(seed1)/256; /產(chǎn)生隨機(jī)寫入數(shù)據(jù)initialbegin wclken=1;rclken=0; repeat (10) (posedge wclk); /寫入10個數(shù)據(jù) wclken=0;rclken=1; repeat (6) (posedge rclk); /讀出

23、6個數(shù)據(jù) wclken=1;rclken=1; #99 $stop;end always (posedge wclk)if(wclken=1) waddr=waddr+1; /寫地址生成always (posedge rclk)if(rclken=1) raddr=raddr+1; /讀地址生成fifomem fifomem(rdata, wdata, waddr,raddr, wclken, wclk,rclken,rclk);endmodule仿真波形如圖2所示圖2 存儲仿真波形第一行為讀出數(shù)據(jù),第二行為寫入數(shù)據(jù),圖中第一行和第二行數(shù)據(jù)是完全對應(yīng)的。讀地址控制模塊FIFO存儲器空狀態(tài)是在讀

24、時鐘域中生成的,這樣就可以確保一旦FIFO存儲器達(dá)到空狀態(tài)時就能被檢測到。也就是說,在讀時鐘域里讀指針可以在讀時鐘周期內(nèi)與同步而來的寫指針(包括附加的最高位MSB)進(jìn)行比較。當(dāng)讀指針與同步的寫指針rwptr2相等時,F(xiàn)IFO存儲器為空狀態(tài),此時FIFO存儲器停止讀取數(shù)據(jù),否則會導(dǎo)致向下溢出(underflow)。比較讀指針和同步的寫指針以生成空標(biāo)志的比較器很容易實現(xiàn)。FIFO存儲器的指針總是預(yù)先指向下一個內(nèi)存位置,每進(jìn)行一次讀寫操作,相應(yīng)的指針就增加一次。如果讀指針與同步的寫指針rwptr2的附加位(這兩個指針的最高位MSBs)是相等的,則這兩個指針經(jīng)歷了相同的循環(huán)次數(shù),假如這時兩個指針的低位

25、(共n-1位)也相等,F(xiàn)IFO存儲器就為空狀態(tài)。在這個模塊中包含了除讀同步模塊之外的所有讀時鐘域的邏輯電路。讀指針是"兩重格雷碼計數(shù)器”。位指針rptr被同步到寫時鐘域中,n-1位指針用于產(chǎn)生地址。當(dāng)讀指針rptr的下一個狀態(tài)rgnext等于同步的寫指針rwptr2時,空狀態(tài)標(biāo)志將在下一個讀時鐘的上升沿被置位。這個模塊已經(jīng)是一個讀時鐘域的同步時序電路,這有利于進(jìn)行靜態(tài)時序分析。模塊包含讀指針電路和空標(biāo)志邏輯電路,代碼如下:module rptr_empty(rempty,raddr,rptr,rwptr2,rinc,rclk,rrst_n);parameter ADDRSIZE=4;

26、output rempty;output ADDRSIZE-1:0 raddr;output ADDRSIZE:0 rptr;input ADDRSIZE:0 rwptr2;input rinc, rclk,rrst_n;reg ADDRSIZE:0 rptr,rbin,rgnext,rbnext;reg rempty,raddrmsb; always (posedge rclk or negedge rrst_n)if(!rrst_n) begin rptr <=0; raddrmsb<=0; endelse begin rptr <=rgnext; raddrmsb &l

27、t;=rgnextADDRSIZErgnextADDRSIZE-1; endalways (rptr or rinc)begin:Gray_inc integer i; for(i=0;i<=ADDRSIZE;i=i+1) rbini=(rptr>>i); /格雷碼轉(zhuǎn)換為二進(jìn)制碼 if(!rempty) rbnext=rbin+rinc; /增加FIFO計數(shù) else rbnext=rbin; rgnext = (rbnext>>1)rbnext; /二進(jìn)制轉(zhuǎn)化為格雷碼end always (posedge rclk or negedge rrst_n)if(!r

28、rst_n) rempty<=1'b1; /復(fù)位時輸出空else rempty<=(rgnext=rwptr2); /否則判斷是否滿足條件 assign raddr = raddrmsb,rptrADDRSIZE-2:0; /讀地址指針endmodule讀地址控制模塊主要的部分按代碼順序有復(fù)位部分,完成復(fù)位功能計數(shù)部分,完成格雷碼轉(zhuǎn)二進(jìn)制計數(shù)再轉(zhuǎn)換成格雷碼;空狀態(tài)判斷部分,復(fù)位時輸出空,讀指針和同步后的寫指針相同時出示空狀態(tài);最后是一個讀地址的拼接輸出。為此模塊編寫測試模塊,代碼如下:module tbrptr;parameter ADDRSIZE=4;wire rempt

29、y;wire ADDRSIZE-1:0 raddr;wire ADDRSIZE:0 rptr;reg ADDRSIZE:0 rwptr2;reg rinc, rclk,rrst_n;initialbegin rclk=0;rrst_n=1;rinc=0; rwptr2=14; #3 rrst_n=0; #4 rrst_n=1; #6 rinc=1; endalways #11 rclk=rclk;initialbegin repeat (5) (posedge rclk); (posedge rempty); #20 $stop;end rptr_empty rptr_empty(rempty

30、,raddr,rptr,rwptr2,rinc,rclk,rrst_n);endmodule仿真波形如圖3所示圖3 讀地址控制模塊波形中第一行是空狀態(tài),一開始復(fù)位一次,計數(shù)到0110時與預(yù)置的寫指針相同,空狀態(tài)重新變?yōu)楦唠娖?。此模塊可正常完成地址計數(shù)和空狀態(tài)的生成,功能驗證結(jié)果正確。寫指針控制模塊與讀指針控制模塊代碼基本相同。此模塊僅在滿狀態(tài)判斷部分不相同。代碼如下:module wptr_full(wfull,waddr,wptr,wrptr2,winc,wclk,wrst_n);parameter ADDRSIZE = 4; output wfull;output ADDRSIZE-1:0

31、 waddr;output ADDRSIZE:0 wptr;input ADDRSIZE:0 wrptr2;input winc, wclk, wrst_n;reg ADDRSIZE:0 wptr, wbin, wgnext, wbnext;reg wfull, waddrmsb;wire w_2ndmsb,wr_2ndmsb; /添加的判斷信號always (posedge wclk or negedge wrst_n)if (!wrst_n) begin wptr <= 0; waddrmsb <= 0; endelse begin wptr <=wgnext; wadd

32、rmsb <=wgnextADDRSIZEwgnextADDRSIZE-1; endalways (wptr or winc) begin: Gray_inc integer i; for(i=0; i<=ADDRSIZE; i=i+1) wbini= (wptr>>i); /格雷碼轉(zhuǎn)二進(jìn)制 if (!wfull) wbnext = wbin+winc; /FIFO計數(shù) else wbnext = wbin; wgnext=(wbnext>>1) wbnext; /二進(jìn)制轉(zhuǎn)格雷碼endassign w_2ndmsb = wgnextADDRSIZE wgne

33、xtADDRSIZE-1; /寫指針前兩位異或assign wr_2ndmsb = wrptr2ADDRSIZE wrptr2ADDRSIZE-1; /同步后的讀指針前兩位異或always (posedge wclk or negedge wrst_n)if (!wrst_n) wfull<=0;else wfull <= (wgnextADDRSIZE !=wrptr2ADDRSIZE)&&(w_2ndmsb= wr_2ndmsb) && (wgnextADDRSIZE-2:0= wrptr2ADDRSIZE-2:0); /三個判斷條件均滿足則滿a

34、ssign waddr= waddrmsb,wptrADDRSIZE-2:0; endmodule由于功能基本相似,此模塊不再列出仿真整體仿真結(jié)果將五個子模塊合成一個頂層模塊,代碼如下:module fifo_asyn1(rdata,wfull,rempty,wdata,winc,wclk,wrst_n,rinc,rclk,rrst_n);parameter DSIZE = 8; /數(shù)據(jù)存儲寬度parameter ASIZE = 4; /存儲地址寬度output 7:0 rdata;output wfull;output rempty;input 7:0 wdata;input winc,wc

35、lk,wrst_n;input rinc,rclk,rrst_n;wire 3:0 waddr,raddr;wire 4:0 wptr,rptr,wrptr2,rwptr2;sync_r2w sync_r2w(.wrptr2(wrptr2),.rptr(rptr),.wclk(wclk),.wrst_n(wrst_n);syne_w2r syne_w2r(.rwptr2(rwptr2),.wptr(wptr),.rclk(rclk),.rrst_n(rrst_n);fifomem #(DSIZE,ASIZE) fifomem(.rdata(rdata),.wdata(wdata),.waddr(waddr),.raddr(raddr), .wclken(winc),.wclk(wclk),.rclken(rinc),.rclk(rclk); rptr_empty #(ASIZE) rptr_empty(.rempty(rempty),.raddr(raddr),.rptr(rptr),.rwptr2(rwptr2),

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論