数字IC手撕代码-格雷码的编码与解码
?前言:
????????本專欄旨在記錄高頻筆面試手撕代碼題,以備數(shù)字前端秋招,本專欄所有文章提供原理分析、代碼及波形,所有代碼均經過本人驗證。
目錄如下:
1.數(shù)字IC手撕代碼-分頻器(任意偶數(shù)分頻)
2.數(shù)字IC手撕代碼-分頻器(任意奇數(shù)分頻)
3.數(shù)字IC手撕代碼-分頻器(任意小數(shù)分頻)
4.數(shù)字IC手撕代碼-異步復位同步釋放
5.數(shù)字IC手撕代碼-邊沿檢測(上升沿、下降沿、雙邊沿)
6.數(shù)字IC手撕代碼-序列檢測(狀態(tài)機寫法)
7.數(shù)字IC手撕代碼-序列檢測(移位寄存器寫法)
8.數(shù)字IC手撕代碼-半加器、全加器
9.數(shù)字IC手撕代碼-串轉并、并轉串
10.數(shù)字IC手撕代碼-數(shù)據(jù)位寬轉換器(寬-窄,窄-寬轉換)
11.數(shù)字IC手撕代碼-有限狀態(tài)機FSM-飲料機
12.數(shù)字IC手撕代碼-握手信號(READY-VALID)
13.數(shù)字IC手撕代碼-流水握手(利用握手解決流水線斷流、反壓問題)
14.數(shù)字IC手撕代碼-泰凌微筆試真題
15.數(shù)字IC手撕代碼-平頭哥技術終面手撕真題
16.數(shù)字IC手撕代碼-兆易創(chuàng)新筆試真題
17.數(shù)字IC手撕代碼-樂鑫科技筆試真題(4倍頻)
18.數(shù)字IC手撕代碼-雙端口RAM(dual-port-RAM)
????????...持續(xù)更新
為了方便可以收藏導覽博客:?數(shù)字IC手撕代碼-導覽目錄
目錄
格雷碼介紹
binary_to_gray?
代碼
testbench
波形
gray_to_binary
代碼?
testbench
波形
格雷碼介紹
????????格雷碼的主要特點是相鄰編碼值中只有一個比特發(fā)生改變,如下表所示。
從表中可以看到,相鄰編碼值中只有一個比特發(fā)生改變,那么這個特性有什么用呢?
這非常重要!
????????當今格雷碼被廣泛應用于 使用兩個不同時鐘的異步FIFO(First In First Out,先入先出存儲器)中。當數(shù)值從一個時鐘域傳遞到另一個時鐘域時,單比特翻轉的特性就會變得極為重要。
????????在異步FIFO中,寫地址和度地址是根據(jù)讀寫操作,發(fā)生連續(xù)的改變,其地址是用二進制計數(shù)器進行表示的。以4比特計數(shù)器為例,該計數(shù)器從0計數(shù),數(shù)到15,到達15后歸零。在FIFO里,首先我們要使用轉換公式把二進制編碼轉換成格雷碼,并使用格雷碼值從一個時鐘域傳遞到另一個時鐘域,然后使用另一個轉換公式將格雷碼轉換為二進制碼。
? ? ? ?當多比特位寬的信號從一個時鐘域到另一個時鐘域時,需要使用上面電路。開始時,信號轉換成格雷碼,然后進入CLKA時鐘域的寄存器。此后,通過兩級同步器(稱為打兩拍)同步到目的時鐘域。實現(xiàn)同步后,通過相反的譯碼過程(gray2bin)就可以實現(xiàn)多比特在兩個時鐘域之間的傳遞,看似繁瑣,但這一轉換是必要的!
? ? ? ? 比如三比特的二進制進行跨時鐘域轉換。當CLKA時鐘域中,數(shù)值從5變到6時,經同步器后,目的時鐘域的格雷碼變?yōu)?01,或者因為延遲,數(shù)值沒有改變,格雷碼還是111,要等到下一個周期(第三拍)之后才能變成101。可以看出,無論是101還是111,最終傳遞的結果都是按照順序出現(xiàn)合法的編碼值。假如不使用這種二進制-格雷碼、格雷碼-二進制的轉換電路,直接在CLKB時鐘域打兩拍接收數(shù)據(jù)會出現(xiàn)什么情況呢?
? ? ? ? 經過兩級同步后,同步之后的二進制值可能是101(舊值)、110(新值),但也可能變成100或者111(因為打兩拍過程是為了解決亞穩(wěn)態(tài),而信號翻轉時的亞穩(wěn)態(tài)不確定采樣到0還是采樣到1,所以低兩位變化結果不確定)。由于兩個時鐘相互獨立,同步器輸入的兩個比特分別進行跨時鐘域同步,這些獨立同步并輸出的值可能出現(xiàn)在不同的時鐘周期上。
????????雖然最終所有比特會輸出正確的值,并且最終輸出將變?yōu)?10。然而,在轉變過程中,可能輸出違反計數(shù)規(guī)則的值,這是極其致命的。
????????對于FIFO來說,其空、滿狀態(tài)是根據(jù)其內部數(shù)據(jù)深度進行判斷得到的,當出現(xiàn)這些臨時的非法值時,FIFO可能會產生錯誤的空、滿狀態(tài),從而造成外部電路對其內部存儲數(shù)據(jù)量的錯誤判斷,把一個有數(shù)據(jù)的FIFO認為是空,把一個未滿的FIFO認為是滿,造成系統(tǒng)錯誤,甚至奔潰。
????????說了那么多,我們已經知道為什么格雷碼很重要,以及格雷碼的用途(異步FIFO數(shù)據(jù)傳輸),下面我們來給出格雷碼和二進制相互轉換的模塊。
binary_to_gray?
?????????二進制轉換格雷碼機制:格雷碼的最高位和二進制的最高位是一樣的,格雷碼的其他位可以用二進制對應位和相鄰高位的異或得到,即
????????assign gray_value[ i ] = binary_value[ i ] ^ binary_value[ i + 1 ];
比對一下格雷碼二進制轉換表,符合我們上面說的規(guī)律,知道轉換原理,寫代碼就簡單了。
代碼
module binary_to_gray#(parameter WIDTH = 4 )(input [WIDTH-1:0] binary_value ,output [WIDTH-1:0] gray_value );genvar i; generatefor(i=0;i<(WIDTH-1);i=i+1)beginassign gray_value[i] = binary_value[i] ^ binary_value[i+1];end endgenerateassign gray_value[WIDTH-1] = binary_value[WIDTH-1]; // highest bitendmoduletestbench
module binary_to_gray_tb#(parameter WIDTH = 4 )( );wire [WIDTH-1:0] gray_value; reg [WIDTH-1:0] binary_value;initial beginbinary_value <= 4'b0000; endalways #5 binary_value <= binary_value + 1'b1;binary_to_gray u_binary_to_gray(.gray_value (gray_value) ,.binary_value (binary_value) );endmodule波形
gray_to_binary
????????格雷碼轉二進制也是一樣的道理,二進制最高位和格雷碼最高位一致。二進制的其他位可以由格雷碼對應位對應二進制的相鄰高位的異或得到。用公式表示即:
Binary[n]????= Gray[n];
Binary[n-1] = Binary[n] ^ Gray[n-1];?
代碼?
module gray_to_binary#(parameter WIDTH = 4 )(output [WIDTH-1:0] binary_value ,input [WIDTH-1:0] gray_value );genvar i; generatefor(i=WIDTH-1;i>=1;i=i-1)beginassign binary_value[i-1] = binary_value[i] ^ gray_value[i-1];end endgenerateassign binary_value[WIDTH-1] = gray_value[WIDTH-1]; // highest bitendmoduletestbench
module gray_to_binary_tb#(parameter WIDTH = 4 )( );reg [WIDTH-1:0] gray_value; wire [WIDTH-1:0] binary_value;initial begingray_value <= 4'b0000; endalways #5 gray_value <= gray_value + 1'b1;gray_to_binary u_gray_to_binary(.gray_value (gray_value) ,.binary_value (binary_value) );endmodule波形
所有結果都和我們設計的一樣,好,以上就是格雷碼轉二進制及二進制轉格雷碼的全部內容。?
總結
以上是生活随笔為你收集整理的数字IC手撕代码-格雷码的编码与解码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 获取sd卡目录失败_树莓
- 下一篇: 单例设计模式-双重检查