日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

74ls390设计任意进制计数器_异步FIFO:设计原理及Verliog源码

發(fā)布時(shí)間:2023/11/27 生活经验 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 74ls390设计任意进制计数器_异步FIFO:设计原理及Verliog源码 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.? 異步FIFO的概念
異步FIFO為讀取與寫入采用不同的時(shí)鐘,使用異步FIFO用于在不同的時(shí)鐘域傳輸數(shù)據(jù),主要用于跨時(shí)鐘域傳輸多bit數(shù)據(jù)。

2.? 異步FIFO的設(shè)計(jì)難點(diǎn)
同步異步信號(hào),避免亞穩(wěn)態(tài)數(shù)據(jù)的危害
設(shè)計(jì)合適的FIFO指針,判斷FIFO滿或者空狀態(tài)。3.? 同步FIFO的指針
同步FIFO有一個(gè)計(jì)數(shù)器用于計(jì)數(shù)存儲(chǔ)的數(shù)目和讀取的數(shù)目。當(dāng)FIFO只有寫操作沒(méi)有讀操作計(jì)數(shù)值增加,當(dāng)FIFO只有讀操作沒(méi)有寫操作的時(shí)候計(jì)數(shù)值減小,當(dāng)沒(méi)有讀寫操作或者同時(shí)在進(jìn)行讀寫操作的時(shí)候計(jì)數(shù)值保持不變。當(dāng)計(jì)數(shù)器的計(jì)數(shù)值達(dá)到FIFO的總長(zhǎng)度的時(shí)候FIFO滿,當(dāng)計(jì)數(shù)值為0的時(shí)候那么FIFO空。
但是在異步FIFO設(shè)計(jì)中無(wú)法使用一個(gè)計(jì)數(shù)器來(lái)統(tǒng)計(jì)FIFO的數(shù)據(jù)的個(gè)數(shù),因?yàn)閮蓚€(gè)異步的時(shí)鐘需要去控制同一個(gè)計(jì)數(shù)器。因此在設(shè)計(jì)異步FIFO時(shí)候需要比較FIFO的讀寫指針位置。4.? 異步FIFO的指針
異步FIFO的寫指針總是指向下一個(gè)要被寫入的地址,當(dāng)復(fù)位或者清空時(shí)候讀寫指針都指向FIFO緩沖區(qū)的0地址。同樣的讀指針總是指向當(dāng)前FIFO中要被讀出的數(shù)據(jù)所在的地址,當(dāng)清空或者復(fù)位是指針指向0,當(dāng)發(fā)生一次讀操作時(shí)讀指針?biāo)傅牡刂返臄?shù)據(jù)被取出,然后指針地址增加。
FIFO空的標(biāo)志發(fā)生時(shí)是當(dāng)讀的指針和寫的指針相等時(shí)。當(dāng)讀寫指針復(fù)位到0的時(shí)候如清空FIFO等操作的時(shí)候,或者是當(dāng)讀的指針趕上了寫指針。
FIFO滿的標(biāo)志也是當(dāng)讀指針和寫指針相等的時(shí)候。當(dāng)寫指針已經(jīng)環(huán)繞一周,然后追上讀指針的時(shí)候。因此就存在一個(gè)問(wèn)題當(dāng)讀寫指針相等的時(shí)候如何判斷是讀空還是寫滿。
為了區(qū)分是讀空還是寫滿,一種設(shè)計(jì)的方式是給讀寫指針添加一個(gè)額外的位。當(dāng)寫指針增加了以后超過(guò)了FIFO的存儲(chǔ)空間的最后的地址,這時(shí)候指針自加就會(huì)使得額外添加的最高位翻轉(zhuǎn)。同樣的讀指針也會(huì)進(jìn)行相同的操作。因此當(dāng)兩個(gè)最高位是不同的時(shí)候就可以判斷是寫指針已經(jīng)環(huán)繞追上了讀指針,那么FIFO是處于寫滿狀態(tài),如果最高位是相同的那么是讀指針追趕上了寫指針,FIFO處于讀空狀態(tài)。


圖1 添加MSB用于區(qū)分寫滿與讀空5.? 讀寫指針計(jì)數(shù)器設(shè)計(jì)
對(duì)于一個(gè)二進(jìn)制計(jì)數(shù)器,當(dāng)他的計(jì)數(shù)值從一個(gè)時(shí)鐘域同步到另外一個(gè)時(shí)鐘域的時(shí)候是危險(xiǎn)的,因?yàn)榭赡艽嬖趎-bits數(shù)據(jù)同時(shí)變化的情況,如7計(jì)數(shù)到8對(duì)應(yīng)的二進(jìn)制是0111計(jì)數(shù)到1000,那么對(duì)應(yīng)的所有的位均發(fā)生變化。
一種通用的解決FIFO計(jì)數(shù)器的問(wèn)題的方法是使用格雷碼進(jìn)行計(jì)數(shù),格雷碼對(duì)于相鄰的兩個(gè)計(jì)數(shù)值只允許一個(gè)位發(fā)生變化。因此就解決了欲在同一個(gè)時(shí)鐘邊沿同步多個(gè)bits的問(wèn)題。6.? 格雷碼計(jì)數(shù)器問(wèn)題引入
考慮4位和3位的格雷碼計(jì)數(shù)器如圖 2。通過(guò)對(duì)二進(jìn)制碼的分析可以得出對(duì)于4位格雷碼上半部分與下半部分是最高位反向其余位關(guān)于中點(diǎn)鏡像。為了將4位的格雷碼轉(zhuǎn)化為3位的格雷碼,同時(shí)使得最高位為附加位,用于區(qū)分寫滿與讀空。我們希望4位格雷碼的低3位重復(fù)第一部分的低3位,而不是關(guān)于中點(diǎn)的鏡像。如果直接將下半部分的低3位格雷碼編碼改為上半部分的低3位一樣的編碼那么就不是真格雷碼應(yīng)為從7到8以及15到0時(shí)候會(huì)出現(xiàn)兩bits發(fā)生變化。而真格雷碼應(yīng)該是在相鄰的兩個(gè)計(jì)數(shù)之間只有一個(gè)位發(fā)生變化。
圖2 四位格雷碼7.? 格雷碼計(jì)數(shù)器設(shè)計(jì)
格雷碼計(jì)數(shù)器是不存在奇數(shù)長(zhǎng)度的,因此設(shè)計(jì)出來(lái)的額FIFO的深度就是? 。 二進(jìn)制計(jì)數(shù)器咋每次自加都會(huì)檢測(cè)是否為滿或者空狀態(tài),從而保證不會(huì)出現(xiàn)溢出或者下溢。
在圖 3所示的格雷碼計(jì)數(shù)器中二進(jìn)制計(jì)數(shù)器的低(n-1)位可以直接作為FIFO存儲(chǔ)單元的地址指針,將二進(jìn)制數(shù)轉(zhuǎn)化為格雷碼傳輸給另外一個(gè)時(shí)鐘域。
圖 3格雷碼計(jì)數(shù)器8.? 格雷碼轉(zhuǎn)二進(jìn)制與二進(jìn)制轉(zhuǎn)格雷碼
二進(jìn)制B[n:0]轉(zhuǎn)化為格雷碼G[n:0]
G[n] = B[n]?????????????????????? //保留最高位作為格雷碼的最高位

G[n-1:0] = B[n-1:0]^B[n:1]? //次高位格雷碼為二進(jìn)制碼的高位與次高位相異或其余類似

格雷碼G[n:0]轉(zhuǎn)化為二進(jìn)制B[n:0]
B[n] = G[n]??????????????????????? //保留最高位作為二進(jìn)制碼的最高位

B[n-1:0] = G[n-1:0]^B[n:1]? //次高位格雷碼為二進(jìn)制碼的高位與次高位相異或其余類似

9.? FIFO實(shí)現(xiàn)
將地址指針轉(zhuǎn)化為格雷碼以后對(duì)于相鄰的兩個(gè)地址只有一個(gè)位數(shù)據(jù)發(fā)生變化,因此可以使用觸發(fā)器來(lái)同步異步時(shí)鐘的數(shù)據(jù)。? 圖4 FIFO結(jié)構(gòu)框圖10.滿和空信號(hào)的生成

讀空信號(hào)是在讀時(shí)鐘域生成的,從而保證能夠?qū)崟r(shí)的沒(méi)有延遲的確定讀空。當(dāng)讀空發(fā)生時(shí)是讀指針追趕上寫指針,兩個(gè)指針值相同(包括擴(kuò)展的最高位)。此時(shí)其格雷碼也是相同的,因此設(shè)計(jì)相對(duì)簡(jiǎn)單。
在FIFO設(shè)計(jì)中寫滿信號(hào)是在寫時(shí)鐘域生成的,從而保證能夠?qū)崟r(shí)的沒(méi)有延遲的確定寫滿。當(dāng)寫指針追趕上讀指針的時(shí)候發(fā)生,此時(shí)兩個(gè)指針的二進(jìn)制計(jì)數(shù)器的低(n-1)位相同最高位不同。但是由于擴(kuò)展了格雷碼,而對(duì)于n位格雷碼其(n-1)位是關(guān)于中間值鏡像對(duì)稱的。

圖 5 有擴(kuò)展位的格雷碼編碼
考慮圖 5對(duì)于3位的格雷碼地址添加一個(gè)附加位用于區(qū)分寫滿與讀空成為4位的格雷碼編碼。當(dāng)FIFO空時(shí)即讀指針趕上寫指針,此時(shí)兩個(gè)格雷碼完全相同(包括擴(kuò)展位)。當(dāng)FIFO寫滿時(shí)候需要考慮如下3個(gè)條件
1.? 寫指針的格雷碼與同步到寫時(shí)鐘域的讀指針格雷碼的最高位不同
2.? 寫指針的格雷碼與同步到寫時(shí)鐘域的讀指針格雷碼的次高位不相等
3.? 寫指針的格雷碼與同步到寫時(shí)鐘域的讀指針格雷碼的其余位都相等11.不同的時(shí)鐘速率同步的深入思考
當(dāng)異步FIFO來(lái)同步兩個(gè)不同的時(shí)鐘域的時(shí)候,顯然兩個(gè)時(shí)鐘的速度是不一樣的,考慮當(dāng)一個(gè)快的時(shí)鐘域的信號(hào)同步到慢的時(shí)鐘域的時(shí)候可能會(huì)存在計(jì)數(shù)值跳躍,因?yàn)樵诼臅r(shí)鐘域的一個(gè)周期快的時(shí)鐘域的計(jì)數(shù)值可能已經(jīng)增加了多次了,因此就會(huì)導(dǎo)致如下的兩個(gè)問(wèn)題:
1. ?在同步格雷碼的時(shí)候如果格雷碼的值增加了2個(gè)然而只采樣了一次就會(huì)出現(xiàn)多個(gè)位的數(shù)據(jù)發(fā)生變化,這種情況下會(huì)導(dǎo)致多bit數(shù)據(jù)同步問(wèn)題嗎?
?? 答案是否定的。在同步多bit數(shù)據(jù)的時(shí)候當(dāng)多個(gè)數(shù)據(jù)位在同步上升沿變化時(shí)會(huì)出現(xiàn)問(wèn)題。但是對(duì)于快的時(shí)鐘域的寫指針的格雷碼在一個(gè)時(shí)鐘周期只改變一位,因此在慢的時(shí)鐘域周圍最多只會(huì)有一個(gè)位發(fā)生變化。
2. ?在慢的時(shí)鐘域一個(gè)周期里面快的時(shí)鐘域的計(jì)數(shù)器可能已經(jīng)增加了幾個(gè)計(jì)數(shù)值了,那么會(huì)存在快的時(shí)鐘域的已經(jīng)從滿狀態(tài)增加到(滿+1)的狀態(tài),而沒(méi)能檢測(cè)出滿嗎?
?? 答案是否定的,應(yīng)為滿狀態(tài)是在寫時(shí)鐘域產(chǎn)生的,如果寫的時(shí)鐘比讀取的時(shí)鐘快,當(dāng)寫指針趕上從讀時(shí)鐘域同步過(guò)來(lái)的讀指針后,滿狀態(tài)會(huì)馬上置位,因此就不會(huì)出現(xiàn)溢出。
滿與空狀態(tài)能夠準(zhǔn)確的被置位,但是標(biāo)志位清除有一定的延遲。
當(dāng)我們?cè)趯憰r(shí)鐘域產(chǎn)生FIFO滿的狀態(tài),當(dāng)寫指針追趕上讀指針的時(shí)候馬上產(chǎn)生滿標(biāo)志,此時(shí)當(dāng)讀指針增長(zhǎng)了以后FIFO就不再滿了,但是寫時(shí)鐘域不能馬上檢測(cè)到讀指針已經(jīng)增加了,需要經(jīng)過(guò)兩個(gè)時(shí)鐘周期,使得讀指針的數(shù)據(jù)同步到寫時(shí)鐘域以后才能夠清空滿狀態(tài)。這樣能夠保證FIFO不會(huì)溢出,相同的讀FIFO也存在這樣的問(wèn)題。

Verilog源碼:

/*異步fifo 參考文獻(xiàn)? Simulation and SynthesisTechniques for Asynchronous FIFO Design*/

module async_fifo(

?????? rst_n???????? ,

?????? fifo_wr_clk?? ,

?????? fifo_wr_en,

?????? r_fifo_full?? ,

?????? fifo_wr_data,

?????? fifo_rd_clk?? ,

?????? fifo_rd_en,

?????? fifo_rd_data,

?????? r_fifo_empty?

//???? fifo_wr_err,

//???? fifo_rd_err

??? );

?????? input rst_n????????? ;

?????? inputfifo_wr_en? ;

?????? input? [15:0]fifo_wr_data;

?????? inputfifo_rd_en? ;

?????? inputfifo_rd_clk;

?????? inputfifo_wr_clk;

?????? output regr_fifo_full?? ;

?????? output[15:0]fifo_rd_data;

?????? output regr_fifo_empty? ;

//???? output regfifo_wr_err;

//???? output regfifo_rd_err;

?????? reg[9:0]?rdaddress; //RAM地址為9位地址 擴(kuò)展一位用于同步

?????? reg[9:0]?wraddress;

?????? wire?? [9:0]? gray_rdaddress;

?????? wire?? [9:0]? gray_wraddress;

?????? /*同步寄存器*/

?????? reg[9:0] sync_w2r_r1,sync_w2r_r2;

?????? reg[9:0] sync_r2w_r1,sync_r2w_r2;

?????? wirefifo_empty;

?????? wirefifo_full;

?????? /*二進(jìn)制轉(zhuǎn)化為格雷碼計(jì)數(shù)器*/

?????? assigngray_rdaddress = (rdaddress >>1) ^ rdaddress;//(({1'b0,rdaddress[9:1]}) ^rdaddress);

?????? /*二進(jìn)制轉(zhuǎn)化為格雷碼計(jì)數(shù)器*/

?????? assigngray_wraddress = (({1'b0,wraddress[9:1]}) ^ wraddress);

?????? assignfifo_empty = (gray_rdaddress == sync_w2r_r2);

?????? assignfifo_full = (gray_wraddress == {~sync_r2w_r2[9:8],sync_r2w_r2[7:0]});

//????

//???? assignfifo_wr_err = (w_fifo_full && fifo_wr_en);

//???? assignfifo_rd_err = (fifo_empty && fifo_rd_en);

?????? ram? ram(

?????????? .data????? (fifo_wr_data???? ),

?????????? .rdaddress(rdaddress[8:0]),

?????????? .rdclock?? (fifo_rd_clk? ),

?????????? .wraddress(wraddress[8:0]),

?????????? .wrclock?? (fifo_wr_clk? ),

?????????? .wren????? (fifo_wr_en?? ),

?????????? .q???????? (fifo_rd_data)

?????????? );?

?????? /*在讀時(shí)鐘域同步FIFO空 sync_w2r_r2 為同步的寫指針地址延遲兩拍 非實(shí)際 寫指針值 但是確保不會(huì)發(fā)生未寫入數(shù)據(jù)就讀取*/

?????? always@(posedgefifo_rd_clk or negedge rst_n)

?????? if(!rst_n)

?????????? r_fifo_empty<= 1'b1;

?????? else

?????????? r_fifo_empty<= fifo_empty;

?????????? /*在寫時(shí)鐘域判斷FIFO滿 sync_r2w_r2 實(shí)際延遲兩個(gè)節(jié)拍可能存在非滿判斷為滿 但不會(huì)導(dǎo)致覆蓋*/

?????? always@(posedgefifo_wr_clk or negedge rst_n)

?????? if(!rst_n)

?????????? r_fifo_full<= 1'b1;

?????? else ?????????????????????????????

?????????? r_fifo_full<= fifo_full;//格雷碼判斷追及問(wèn)題???????

?????? /*讀數(shù)據(jù)地址生成*/

?????? always@(posedgefifo_rd_clk or negedge rst_n)

?????? if(!rst_n)

?????????? rdaddress<= 10'b0;

?????? elseif(fifo_rd_en && ~fifo_empty)begin

?????????? rdaddress<= rdaddress + 1'b1;

?????? end

?????? /*寫數(shù)據(jù)地址生成*/

?????? always@(posedgefifo_wr_clk or negedge rst_n)

?????? if(!rst_n)

?????????? wraddress<= 10'b0;

?????? elseif(fifo_wr_en && ~r_fifo_full)begin

?????????? wraddress<= wraddress + 1'b1;

?????? end

?????? /*同步讀地址到寫時(shí)鐘域*/

?????? always@(posedgefifo_wr_clk or negedge rst_n)

?????? if(!rst_n)begin

?????????? sync_r2w_r1<= 10'd0;

?????????? sync_r2w_r2<= 10'd0;

?????? end elsebegin

?????????? sync_r2w_r1<= gray_rdaddress;

?????????? sync_r2w_r2<= sync_r2w_r1;????

?????? end

?????? /*同步寫地址到讀時(shí)鐘域, 同步以后 存在延遲兩個(gè)節(jié)拍*/

?????? always@(posedgefifo_rd_clk or negedge rst_n)

?????? if(!rst_n)begin

?????????? sync_w2r_r1<= 10'd0;

?????????? sync_w2r_r2<= 10'd0;

?????? end elsebegin

?????????? sync_w2r_r1<= gray_wraddress ;

??? ?????? sync_w2r_r2 <= sync_w2r_r1;????

?????? end

endmodule


轉(zhuǎn)載自:

https://blog.csdn.net/u014070258/article/details/90052281

侵刪。

總結(jié)

以上是生活随笔為你收集整理的74ls390设计任意进制计数器_异步FIFO:设计原理及Verliog源码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。