跨時鐘域信號傳輸(二)——數據信號篇

PS:轉載請標明出處 http://www.cnblogs.com/IClearner/;本文如有錯誤,歡迎留言更正。

因爲學習了其他方面的知識,耽擱了更新。今天我們就聊聊跨時鐘域中的數據信號傳輸的問題。主要內容預覽:

   ·使用握手信號進行跨時鐘域的數據傳輸

  ·FIFO的介紹

  ·在進行FIFO的RTL設計前的問題

  ·FIFO的RTL設計(與仿真測試)

  ·跨時鐘域中的數據信號傳輸總結

 

一、使用握手信號進行跨時鐘域的數據傳輸

  下面敘述的意義相同:前級時鐘=發送時鐘; 後級時鐘=採樣時鐘=接收時鐘

 

  使用握手信號傳輸數據不是我們的重點,重點是FIFO的設計。在使用握手信號進行數據傳輸之前,我們說說爲什麼雙D觸發器鏈不應該用於數據的傳輸。

  一般情況下,我們要傳輸的數據都是多位的,也就是以數據總線的形式傳播的。如果我們使用簡單的多組D觸發器鏈進行同步數據的話,由於每一種D觸發器鏈第一級觸發器都有可能出現亞穩態,穩定下來之後的電平可能出錯;由於有多組D觸發器鏈,就有可能發送多個電平出錯,因而導致數據出錯,如下圖所示:

       

可以看到,原來前面的時鐘域發送的0111數據變成1000的時候,捕獲時鐘的時鐘採樣本來要纔到0111的,由於保持時間不足,導致了b[2]、b[1]出現亞穩態,而且b[2]穩定後的電平是錯誤的電平,由此就傳輸了錯誤的數據。因此直接使用觸發器鏈進行同步數據是不建議的。

  於是乎,我們就看看使用握手信號是怎麼進行傳輸數據的。

  ·數據變化速率比採樣時鐘域低

  當數據的速率比採樣時鐘域慢時,也就是說,數據速率相對於採樣時鐘域(接收數據的時鐘域)來說是慢時鐘,可以使用控制信號進行同步,在採樣到慢時鐘域的控制信號後,接收採樣數據,時序圖如下所示:

                

 

這裏只給出了時序圖,電路可以按照時序圖進行設計。需要注意的是,這個額外的控制信號(wr_en_s)是由前面的邏輯產生的。這與下面的電路不一樣:

在下面的這個電路中,控制信號是由上升沿檢測電路產生的,而且是接收時鐘驅動的上升沿檢測電路(也就是說這個控制信號是由後級的邏輯產生的),電路如下所示:

                 

 

下面我們來分析一下這個電路吧,時序圖如下所示:

                 

 

  從時序圖中可以看到,可以用上升沿檢測電路,檢測發送時鐘的上升沿,然後這個沿相當於使能信號。上面中,檢測到了第二個發送時鐘的上升沿,之後就有了使能信號,採樣的數據也是第二時鐘發送的數據DB,因此對應起來是沒有問題。這裏由於沒有檢測到EN1第一個上升沿,所以沒有采樣到DA也是正常的,這是因爲前面的波形沒有畫出的緣故。

  ·當數據的速率(或者說發送時鐘的頻率)略高於接收時鐘端

  由於發送時鐘比接收時鐘快,於是對於接收時鐘,發送時鐘就相當於窄脈衝信號,這樣我們就有思路了。我們還是上面一樣,採用上升沿檢測信號當做使能信號;但是問題來了,發送時鐘是快的,可能會錯過上升沿。於是乎,我們就把窄脈衝捕獲電路和上升沿檢測電路結合起來。先是窄脈衝捕捉電路,把時鐘的沿捕捉到,然後進行邊沿檢測,檢測得到的結果作爲使能信號,電路圖如下所示:

               

 

具體就不分析了,需要強調的是,這個是發送時鐘也不能太快。

  ·數據變化速率比採樣時鐘快很多

  當數據的速率比採樣的時鐘的速率快很多時,對應到時鐘的關係就是——發送時鐘和比接收時鐘快很多時,這個時候採樣時鐘就採樣不到數據,或者說會採漏部分數據,因此這時候就不能用握手信號了。也許有人說我可以增加使能信號,把數據拉長啊,等後面的採樣時鐘採樣到使能信號、接收到數據之後,我再改變時鐘。這種方法的實質就是硬生生地把數據變化率蓋滿,也就是把發送時鐘域的時鐘改慢,跟前面的數據變化速率比採樣時鐘域低的實質是一樣的。因此當數據變化率比採樣時鐘快很多時,就要採樣下面介紹的FIFO了。

 

二、FIFO的介紹

  終於寫到FIFO了,FIFO 是first in first out的縮寫,也就是“先進先出”;從字面理解,就是說,數據先進來的,就先出去。前面說了當快時鐘域傳輸數據到慢時鐘域時,就推薦用FIFO了。FIFO無論是快到慢,還是慢到快,都可以使用它進行數據的緩衝,可謂是“快慢皆宜”啊。

  FIFO的工作流程如下:

  FIFO在寫時鐘狀態信號的控制下,根據寫使能信號往FIFO裏面寫數據,當寫到一定程度後,FIFO存不下新數據的了(或者要以犧牲丟棄舊數據爲貸款),這時候就不能往FIFO裏面寫數據了;在讀時鐘狀態信號的控制下,根據讀使能信號從FIFO裏面讀出數據,當讀到一定程度後,FIFO裏面沒有數據了,就不能繼續讀了,不然就會讀出錯誤的數據。根據讀寫時鐘是否一致(同步),FIFO的種類又可以分成同步FIFO和異步FIFO。FIFO能夠讀寫數據,肯定需要數據的存儲單元,這裏存儲數據的單元往往是雙口RAM

  FIFO的寫過程:在復位的時候,FIFO(雙口RAM)裏面的數據被清零(也就是不存在數據)。復位之後,只能進行操作,因爲什麼都沒有,讀數據會讀出錯誤的值。這個時候,當外部給FIFO寫使能信號了,在時鐘的驅動下,數據就會被寫入FIFO裏面的RAM存儲單元(存儲單元的地址寫指針寄存器的內容確定,寫指針寄存器中的內容稱爲寫地址,復位的時候爲0),寫完數據之後(或者在允許寫數據之後),這個寫指針寄存器就會自動加一,指向下一個存儲單元。當寫到一定程度的時候(寫指針寄存器到達一定的數值),舊數據還沒有被讀出的時候,再寫入新數據就會把舊數據給覆蓋,這個時候稱爲寫滿,需要產生寫滿的狀態信號(full,簡稱滿)。在寫滿的時候,需要禁止繼續寫數據。

  FIFO的讀過程:在復位的時候,FIFO裏面沒有數據,因此這個時候是禁止讀數據的。當裏面有數據之後,外部讀信號到來後,在時鐘信號到來的時候,FIFO就會根據讀地址(由讀指針寄存器的內容確定,讀指針寄存器裏面的內容稱爲讀地址,復位的時候爲0)讀出相應的數據,讀出數據之後(或者說允許RAM讀之後),讀指針寄存器自動加一。指向下一個存儲單元。當讀到一定的程度的時候,也就是FIFO裏面沒有數據了,這個時候稱爲讀空,需要產生讀空的狀態信號(empty,簡稱)。在讀空的時候,需要禁止繼續讀數據。

  根據前面的描述,我們就可以知道,在復位的時候,FIFO空有效、滿無效,禁止讀數據,只能往裏面寫數據。當把FIFO裏面的內容都寫滿的時候,FIFO滿有效,空無效,這時候只能讀數據,而不能繼續往裏面寫數據。

 

三、在進行FIFO的RTL設計前的問題

  根據FIFO的介紹內容,我們試着來推導一下FIFO大致由哪些部分構成。

  首先,FIFO需要存儲數據,因此就需要存儲器;由於需要讀,也需要寫,於是乎就需要一個DPRAM(double  port  RAM,雙端口RAM)。

  然後,RAM需要讀/寫地址,它才知道在哪裏讀/寫數據,因此需要讀/寫地址產生模塊,也就是需要讀/寫地址寄存器。什麼時候進行寫,什麼時候進行讀,因此需要讀/寫控制邏輯空滿狀態的信號產生邏輯

  最後,空滿信號的產生需要通過對讀地址和寫地址的比較,由於讀寫地址在不同的時鐘域,因此需要同步電路進行同步。

  通過上面的簡單介紹,我們就得到了FIFO的大致框圖如下(主要是告訴大家爲什麼會有這麼一個框圖):

            

 

現在來看看這些信號是什麼意思吧:

w:寫時鐘域一方的信號;r:讀時鐘域一方的信號

wclk:寫時鐘

wrst_n:寫復位,低有效

rclk:讀時鐘

rrst_n:讀復位,低有效

winc:外部輸入的寫使能信號

rinc:外部輸入的讀使能信號

wdata :要寫進數據,要寫進FIFO裏面存儲的數據。

rdata:讀數據,從FIFO裏面讀取出來的數據。

wdata:要讀出的數據,要讀出FIFO裏面存儲的數據

wfull:寫滿的狀態信號

rempty:讀空的狀態信號

wclken:RAM的允許寫信號,在這個信號有效的情況下,RAM才能寫得進數據。

rclken:RAM的允許讀信號,在這個信號有效的情況下,RAM才能讀得出數據。

waddr:RAM的寫地址。

raddr:RAM的讀地址

wptr:要同步到寫時鐘域的讀指針(讀地址)。

rptr:要同步到讀時鐘域的寫指針(寫時鐘)

wq2_rptr:讀地址rptr同步到寫時鐘域的讀地址(格雷碼,後面會說爲什麼用格雷碼)

rq2_wptr:寫地址rptr同步到讀時鐘域的讀地址(格雷碼,後面會說爲什麼用格雷碼)

syn_r2w:讀同步到寫觸發器鏈中間信號。

syn_w2r:寫同步到讀觸發器鏈中間信號。

介紹完這些信號之後,我開始聊聊FIFO設計前的一些問題。

  ·FIFO的空滿信號產生

空狀態信號:

  一開始復位的時候,空信號是有效的,當寫了數據之後,空信號就無效了。然後當數據被讀取完之後,空信號就有效了。那麼什麼時候數據被讀取完了呢,也就是數據被讀取完的時候有什麼特徵呢?特徵就是讀地址和寫地址相等,如下所示:

                 

 

  由於讀地址要追趕寫地址,在趕上的時候,地址全等就證明了讀空了。

  也許有人會問:寫地址由於要同步到讀時鐘域去,會存在同步延時的,比如 說t=0s的時候同步過去,此時寫地址爲A;在t=2s的時候A同步過來了,但是這個 時候寫地址已經變爲A+2,而你同步過來的這個寫地址爲A。如果在t=2s這個時候讀地址=A,即讀地址=寫地址,讀趕上了寫,按照上面的設計想法就會產生讀空信號,但是實際上是不相等的,也就是實際上讀並沒有趕上寫,即沒有讀空的,這不就是產生錯誤的讀空信號了嗎?

  首先,是存在這樣的情況,但是這種情況不是設計錯誤。一方面由於我們要產生讀空信號,目的是也就是防止繼續讀從而讀出錯誤的數據;實際上沒有讀空,即使產生了讀空信號,也是沒有影響,相當於提前判斷產生讀空信號而已。另一方面由於是讀時鐘域採樣的讀的地址,這個讀地址是實時的;寫地址是延時的,當這個兩者相等時,我們這個實時的地址實際的寫地址的時候就產生讀空信號,防止了讀空。因此即使產生讀空信號,也不會因爲讀空而產生錯誤的數據。因此是沒有設計錯誤的。

寫滿狀態:

  一開始復位之後,進行寫數據;由於地址(假設地址是4位,也就是深度是4位)是可以回捲的,也就是說,寫指針從3寫到15後,繼續寫又會返回到3那裏;假如復位後讀操作只讀到地址3那裏就不讀了,那麼這個時候就寫滿了。也就是說,寫滿的時候,寫地址和讀地址是相等的,如下所示:

             

 

於是乎,我們該怎麼區分在讀地址寫地址相同的時候是讀空還是寫滿呢?下面來介紹一種常用的方法:

  將地址深度拓寬1位當做標誌位,回捲一次標誌位取反。比如上面的例子中,4bit地址拓寬爲5bit,那麼讀地址就是3(由於讀地址沒有回捲,所以是(0)0011)那裏,當寫地址回捲之後與讀地址相同(由於寫地址回捲了,最高位取反,所以是(1)0011),因此這就是寫滿了。當讀地址回捲之後,變成10011,這個時候,就讀空了。也就說,雖然DPRAM的深度還是4bit,但是我們在進行設計地址寄存器的時候,增多一位當做狀態。然後讀寫地址全相等的時候,表示是讀空;除了標誌位外,剩餘的地址爲全部相等,那麼就表示是寫滿

  這裏還是會產生與前面的空信號一樣的問題,也就是同步過來的讀信號是延時的值,與前面一樣,是不會影響寫滿信號的,不屬於設計錯誤。

  

  除了上面這種方法之外,在同步FIFO中,還可以使用計數器的方法。設置一個狀態計數器,復位的時候爲0。的時候,計數器加1的時候,計數器減1。那麼很容易得出,計數器爲0的時候,就是讀空就有效了;當計數器等於FIFO的深度(2^n  -  1)時,就說明寫滿了。這種方法如果FIFO深度很大的話,就需要很大的計數器了,所以有侷限性。

  從上面的分析中,由此也可以知道,空信號的產生需要把寫地址同步到讀時鐘域,然後進行比較(比較之後產生);滿的信號需要把讀地址同步到寫時鐘域,然後進行比較(比較之後產生)。

 

  ·爲什麼要選擇格雷碼作爲同步地址的編碼

  首先,我們知道,讀地址需要跟寫地址比較來產生空和滿信號,然後對於異步FIFO,讀寫爲不同時鐘,如果直接採樣,就會有:類似前面數據產生多位亞穩態的問題,(時序圖就不畫了)比如寫地址從00111改變從01000的時候,讀時鐘恰好採樣,那麼除了最高位外,其它的4位都有可能產生亞穩態,有可能同步得錯誤的地址。這是引入格雷碼的一個原因。另外一個原因就是:無論是讀地址還是寫地址,在(允許)進行讀和寫之後,地址都是加1,而不是加2或者加3等其他的值。爲什麼會這樣呢?我們來看看格雷碼的編碼:

               

  從上圖中我們可以知道,從地址0變成地址1,格雷碼和二進制碼都是0000變成0001;地址從1變成地址2,格雷碼是0001變成0011,而二進制是0010......我們很容易得到,在相鄰地址變化中,格雷碼只有一位發生變化,如地址從7變爲8時,格雷碼是0100變成1100,也就是隻有最高位發送變化;我們再來看看二進制編碼,二進制編碼則有可能全部都改變,地址從7變爲8時,二進制碼是0111變成1000,4位都發生了變化。假如採樣的時候地址恰好從7變爲8時,那麼二進制編碼就有多位發生亞穩態,穩定後的值什麼都有可能;而格雷碼由於只有最高位跳變,第三位由於沒有跳變,不會產生亞穩態可以穩定正確採樣,穩定後的值只有0100和1100,地址只差數值1,是不會影響判斷的結果的(因爲是同步過來的,是個延時的值,不打緊)。

  知道了格雷碼的優點之後,我們就要使用各格雷碼了。由於RAM的讀寫地址都是(傳統)二進制編碼,這裏使用格雷碼有兩種使用方法,第一種使用方式是,將二進制編碼轉換成格雷碼,然後把格雷碼同步過去,再把同步過來的格雷碼反轉換成二進制碼,進行二進制地址和二進制地址的比較;另外一種使用方式是,將二進制編碼轉換成格雷碼,然後把格雷碼同步過去,然後使用格雷碼進行比較。這裏使用第一種方式,雖然這種方式比較需要多兩塊格雷碼轉二進制的電路,但是我們可以實時比較,能將尋址的二進制馬上與同步過來的“延時”二進制進行比較;使用格雷碼比較的話,實際值會慢一拍(因爲實時方的格雷碼需要寄存輸出,會慢一拍,如果不寄存輸出,就有可能產生毛刺)。

然後格雷碼的與二進制的互相轉換如上圖,下面是轉換講解(左邊爲格雷轉二進制,右邊爲二進制轉格雷):

                  

在布爾代數裏面有A^B=C →A=B^C

 

  ·FIFO的深度選擇

  首先,FIFO是有寬度深度的。FIFO的寬度就是RAM的位寬,也是要存入/取出數據的位寬;然後深度就RAM的地址深度,也就是最多可以存多少個數據。例如FIFO的寬度是8bit,那麼FIFO每個時鐘存入的數據的寬度也是8bit;FIFO的深度是10bit,那麼FIFO就最多可以存2^10=1024個8bit的數據。

  我們要存儲數據,FIFO的深度選小了,在寫的時候就很有可能寫溢出;深度選大了,就會浪費存儲面積。選擇一個合適的深度,最主要的就是防止寫溢出;由於FIFO要讀也要寫,那麼FIFO的(地址)深度該選多少合適呢?

  這就和你的讀寫速度有關了,根據讀寫速度來選擇FIFO深度,此外需要注意的是,在使用FIFO的時候,寫的平均吞吐量要和讀的平均吞吐量相等。

現在舉例來說明:設你的寫時鐘頻率爲100M,讀時鐘爲200M;寫速度爲:100個時鐘寫如60個數據,讀速度爲:100個時鐘讀出30個數據 。

①首先驗證你的數據吞吐量是否相等:

    寫的平均吞吐量=100M*60/100=60M個數據/S

    讀的平均吞吐量=200M*30/100=60M個數據/S

因此這兩個是相等的,不會發生寫溢出;如果寫大於讀,那麼FIFO早晚會很快寫滿溢出;如果讀大於寫,那麼FIFO遲早會讀空。因此需要讀寫吞吐量相同。

②求最低深度

  我們知道讀寫速度之後,就可以判斷FIFO要多少深度才合適了,由於FIFO的深度考慮是出於我們要防止寫溢出(寫滿),因此我們考慮寫的情況:

寫的時候是100個時鐘寫60個數據,我們不知道它是怎麼樣子寫的,我們從悲觀的角度出發,也就是從寫得最密集的角度出發:前100個寫時鐘的最後60個時鐘寫60個數據,然後後100個寫時鐘的最前60個時鐘寫入60個數據,也就是在120個寫時鐘內寫入了120數據。

這120個寫時鐘的時間是:

                      

 

在這段時間內,根據讀寫的速率要求,肯定是要讀數據的,讀出的數據爲:

                      

因此我們FIFO需要的深讀就等於沒有讀出的數據的個數就是:

                  120-72 =48

然而由於上面讀的方式是一個平均的方式,此外FIFO的深度一般是2的整數次冪,要符合格雷碼的編碼轉換規則,因此我們深度一般不選擇48,而是選擇比它大的2的整數次冪的數,比如64或者128。FIFO深度的選擇過程就如上面所述,(這裏參考《FPGA深度解析》)。

 

四、FIFO的設計(與仿真測試)

接下來我們就要設計一個異步FIFO了,這裏我們設計的FIFO跟上面的有點不同,整體結構如下所示:

                 

這裏主要是多出了兩個狀態信號:

  wfull_almost:將滿信號。爲了預防萬一,FIFO要滿的時候,使這個信號有效,當面的模塊時鐘(前級電路)檢測到這個信號有效後,就把winc變爲無效,用來提供給前面電路的指示信號。這個信號要比full信號提前,因爲考慮到在判斷出滿之後,還需要一些動作(延時),才能不寫;於是乎我們就用將滿信號來補充這些延時,而不是等到滿信號才做出反應。

  rempty_almost:將空信號。這個也是爲了考慮在空信號判斷出來之後,到禁止繼續讀可能有延時,從而設立這個標識,在將空的時候就禁止繼續讀數據。

將滿信號和將空信號的關鍵因素就是讀寫地址之間的舉例(間隔),那我們來看看寫和讀的間隔怎麼產生:

對於寫時鐘域,我們是要產生幾乎滿信號,這對應的間隔就是看看寫地址還有多少就趕上了讀地址,求出這兩個地址之間的間隔,然後再與預設的間距比較,如果這個間隔小於預設的間距,那麼就產生幾乎滿的信號。那麼我們這個間隔怎麼求:

  ·當讀寫狀態位相同的時候,如下圖所示:

                    

 

  由於最高位相同,所以寫需要回卷才能最上讀,那麼間隔也就是A+B;假設FIFO的深度是D,寫地址爲waddr,讀地址爲raddr,那麼間隔就是D-C=D-(waddr-raddr)=D+raddr-waddr.(注意,這裏的讀/寫地址不包括狀態位)

  ·當讀寫狀態不同位時,如下圖所示:

                   

這時候waddr再有C就追上raddr了,因此間隔就是raddr-waddr。

 

上面是對於寫區域間隔的生成,下面就來說說讀區域的間隔怎麼產生吧:

  ·狀態位一樣的時候,也就是沒有回捲的時候,如下圖所示:

                     

很顯然,無論是加不加狀態位,都是間隔都是waddr-raddr,也就是說,還有waddr-raddr的舉例,raddr就追上了waddr。

  ·當狀態位不一樣時:

                   

 

  需要回捲才能追上寫,因此間隔就是:

  FIFO的深度-(raddr-waddr)=FIFO+waddr-raddr(這裏的讀寫地址不包括狀態位)。

  當加上狀態位之後,我們發現,間隔是可以用raddr-waddr來表示的,比如raddr=1011,waddr是0011,間隔是8;加上狀態位後,Raddr=01011,Waddr=10011,間隔也可以表示爲01011-10011=01000=8(借位是會被省略掉的),因此用加上狀態位後,間隔可以表示爲waddr-raddr。

因此在讀時鐘域,間隔的表示就是帶狀態位的waddr-raddr。

 

  說完了幾乎滿和幾乎空信號,我們再聊聊上面的框圖,整個FIFO可以分成寫邏輯模塊、讀邏輯模塊、寫/讀同步讀/寫模塊。其中

·寫邏輯的模塊的功能是:根據狀態信號和外部的寫信號產生對RAM的寫控制信號、產生RAM的地址信號、產生空和將空的狀態的狀態信號。因此寫邏輯模塊可以分成3個部分:①(RAM)寫控制邏輯部分;②RAM寫地址產生部分;③狀態產生部分。

  ①RAM寫控制邏輯部分的功能就是,產生RAM的寫使能信號:wclken有效的條件是:外部信號寫使能信號winc來了,而且此時滿信號沒有效,這個時候就允許往RAM裏面寫數據了。

  ②RAM寫地址產生部分的功能就是產生RAM的地址和產生格雷碼地址(產生的格雷碼地址傳輸給同步模塊):復位的時候,RAM的地址waddr爲0;此後,在寫時鐘上升沿檢測到RAM的寫使能wclken有效之後,waddr自動加一,指向下一個單元,wclken無效waddr則不變。我們使用比RAM地址寬1位的地址寄存器進行遞增,地址寄存器的最高位充當空滿信號時候的狀態比較位。

  ③狀態產生部分的功能就是:將同步模塊過來的格雷碼轉換成二進制,然後跟RAM寫地址產生部分傳來的地址進行比較,產生將滿信號和滿信號。(將滿信號的產生就是兩個地址小於某個間隔時有效,滿信號產生則是間隔等於0或者:間隔只有一個地址只差,但是這個時候RAM的寫信號還有效)。

·讀邏輯也是一樣,這裏不再詳述,具體細節我們在代碼後面進行討論。

·寫/讀同步讀/寫模塊其實就是雙D觸發器(鏈)

代碼如下所示:

頂層模塊
寫時鐘域
讀時鐘域
同步器
簡單的仿真代碼

這裏的簡單仿真代碼仿真了寫時鐘間隔,讀時鐘一直讀的情況,使用modelsim的仿真波形如下所示:

 

 最後我們來小節一下:

  異步FIFO,主要用於跨時鐘域的數據信號傳輸,它的基本架構如下所示(純手工畫):

根據從上面電路架構圖,就可以寫代碼實現。

需要注意的是問題有:一個就是地址同步的問題,另外一個是空滿信號產生的問題。(深度選擇問題這裏就不說了)

地址同步主要是用格雷碼同步實現;空滿信號則通過拓寬地址寄存器來實現。

格雷碼與二進制的轉換關係上面說了。格雷碼的優點就是相鄰之間只有一位信號變化,因此常常用來異步設計的編碼;缺點就是需要增加相應的組合邏輯。

 

五、跨時鐘域中的數據信號傳輸總結

   跨時鐘域的數據信號傳輸到這裏就結束了,在這裏進行總結一下:

  ·數據變化速率比採樣速率低、或者比採樣速率略快時,可以使用握手信號進行。

  ·無論是快到慢,還是慢到快,FIFO通喫。

  ·FIFO的設計需要注意FIFO空滿信號產生問題、格雷碼的應用問題、深度選擇問題等。

  ·說到格雷碼的應用問題,也許會想到能不能先把數據變成格雷碼,然後再通過雙D觸發器同步過去呢?這明顯是不能的啊,你的數據不像FIFO的地址產生那樣,是具有相鄰性的,也就是隻差一個1;因此不能把數據變成格雷碼,再傳輸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章