【Verilog 常见设计】(0)二进制码和格雷码互转 Verilog 实现
目錄
格雷碼介紹
轉(zhuǎn)化原理
Verilog 實(shí)現(xiàn)
testbench 測(cè)試代碼
仿真波形
格雷碼介紹
在一組數(shù)的編碼中,若任意兩個(gè)相鄰的代碼只有一位二進(jìn)制數(shù)不同,則稱(chēng)這種編碼為格雷碼(Gray Code),另外由于最大數(shù)與最小數(shù)之間也僅一位數(shù)不同,即“首尾相連”,因此又稱(chēng)循環(huán)碼或反射碼。在數(shù)字系統(tǒng)中,常要求代碼按一定順序變化。例如,按自然數(shù)遞增計(jì)數(shù),若采用8421碼,則數(shù)0111變到1000時(shí)四位均要變化,而在實(shí)際電路中,4位的變化不可能絕對(duì)同時(shí)發(fā)生,則計(jì)數(shù)中可能出現(xiàn)短暫的其它代碼(1100、1111等)。在特定情況下可能導(dǎo)致電路狀態(tài)錯(cuò)誤或輸入錯(cuò)誤。使用格雷碼可以避免這種錯(cuò)誤。
在常見(jiàn)的 IP 設(shè)計(jì)中就會(huì)用到格雷碼,比如異步 FIFO 的實(shí)現(xiàn),在讀時(shí)鐘域同步到寫(xiě)時(shí)鐘域或?qū)憰r(shí)鐘域同步到讀時(shí)鐘域時(shí),就需要將數(shù)據(jù)由二進(jìn)制碼轉(zhuǎn)化為格雷碼,轉(zhuǎn)化后的數(shù)據(jù)響相鄰數(shù)據(jù)之間只有一位不同,這樣就大大降低了數(shù)據(jù)同步時(shí)出錯(cuò)的概率。
以下為四位二進(jìn)制碼和格雷碼之間的對(duì)應(yīng)關(guān)系:
| Decimal | Binary | Gray Code |
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
可以很明顯的看出,隨著數(shù)值增大,格雷碼相鄰數(shù)之間的差別只有一位之差,下面介紹二進(jìn)制碼和格雷碼之間是如何互相轉(zhuǎn)化的。
轉(zhuǎn)化原理
二進(jìn)制碼轉(zhuǎn)格雷碼
如下圖所示,二進(jìn)制碼轉(zhuǎn)格雷碼,格雷碼的最高位和二進(jìn)制的最高位一致,次高位為二進(jìn)制的最高位和次高位的異或結(jié)果,同理可得格雷碼最低位為二進(jìn)制碼的第1位和第0位的異或結(jié)果。
格雷碼轉(zhuǎn)二進(jìn)制碼
如下圖所示,格雷碼轉(zhuǎn)二進(jìn)制碼,二進(jìn)制碼的最高位和格雷碼的最高位一致,次高位為格雷碼的最高位和二進(jìn)制碼的次高位的異或結(jié)果,同理可得格雷碼最低位為格雷碼的第1位和二進(jìn)制碼的第0位的異或結(jié)果。
Verilog 實(shí)現(xiàn)
二進(jìn)制碼轉(zhuǎn)格雷碼
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Engineer : Linest-5 /* File : bin2gray.v /* Create : 2022-08-30 15:35:07 /* Revise : 2022-08-30 15:35:07 /* Module Name : bin2gray /* Description : 二進(jìn)制碼轉(zhuǎn)格雷碼 /* Editor : sublime text3, tab size (4) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/module bin2gray#( parameter DATA_WIDTH = 'd8)(input [DATA_WIDTH-1:0] bin_code,output [DATA_WIDTH-1:0] gray_code );generategenvar i;for (i=0;i<DATA_WIDTH-1;i=i+1) beginassign gray_code[i] = bin_code[i+1] ^ bin_code[i];end endgenerateassign gray_code[DATA_WIDTH-1] = bin_code[DATA_WIDTH-1];endmodule格雷碼轉(zhuǎn)二進(jìn)制碼
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Engineer : Lqc /* File : gray2bin.v /* Create : 2022-08-30 15:09:27 /* Revise : 2022-08-30 15:09:27 /* Module Name : gray2bin /* Description : 格雷碼轉(zhuǎn)二進(jìn)制碼 /* Editor : sublime text3, tab size (4) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/module gray2bin#(parameter DATA_WIDTH = 'd8)(input [DATA_WIDTH-1:0] gray_code,output [DATA_WIDTH-1:0] bin_code );generategenvar i;for (i=0;i<DATA_WIDTH-1;i=i+1) beginassign bin_code[i] = bin_code[i+1] ^ gray_code[i];end endgenerateassign bin_code[DATA_WIDTH-1] = gray_code[DATA_WIDTH-1];endmoduletestbench 測(cè)試代碼
將兩個(gè)模塊都例化到測(cè)試模塊中,輸入二進(jìn)制碼轉(zhuǎn)化成格雷碼,然后再轉(zhuǎn)化回二進(jìn)制碼,以此來(lái)驗(yàn)證兩個(gè)模塊的設(shè)計(jì)正確性。
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* Engineer : Lqc /* File : tb_bin_gray.v /* Create : 2022-08-30 15:40:10 /* Revise : 2022-08-30 15:40:10 /* Module Name : tb_bin_gray /* Description : 二進(jìn)制碼和格雷碼互轉(zhuǎn)仿真模塊 /* Editor : sublime text3, tab size (4) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ `timescale 1ns/1ps module tb_bin_gray();reg [7:0] bin_code_in; wire [7:0] gray_code_out; wire [7:0] bin_code_out;//每10個(gè)單位時(shí)間輸入的數(shù)據(jù)加1 integer i; initial beginfor (i=0;i<256;i=i+1) beginbin_code_in = #20 i;end end //例化二進(jìn)制碼轉(zhuǎn)格雷碼模塊 bin2gray #(.DATA_WIDTH(8) ) inst_bin2gray (.bin_code(bin_code_in), .gray_code(gray_code_out) );//例化格雷碼轉(zhuǎn)二進(jìn)制碼模塊 gray2bin #(.DATA_WIDTH(8) ) inst_gray2bin (.gray_code(gray_code_out), .bin_code(bin_code_out) );endmodule仿真波形
依次輸入8位二進(jìn)制數(shù)據(jù) 0-255,可以看到格雷碼相鄰的數(shù)據(jù)都只變化一位,并且重新轉(zhuǎn)化為二進(jìn)制碼的數(shù)據(jù)也和輸入的數(shù)據(jù)一致,設(shè)計(jì)正確!
總結(jié)
以上是生活随笔為你收集整理的【Verilog 常见设计】(0)二进制码和格雷码互转 Verilog 实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: tomcat内存溢出,性能优化配置讲解
- 下一篇: 5个不可多得的PPT小技巧,工作再忙也要