Verilog——格雷碼計數器
阿新 • • 發佈:2019-01-27
- 格雷碼(Gray code):
第一次接觸格雷碼是在本科的數電課本上,其在可靠性編碼佔據重要位置。後來所學的卡諾圖與格雷碼關係密切。
格雷碼特點在於相鄰性和單位距離性。在程式碼傳輸過程中,彼此相鄰位置僅有一位數碼不同,故有著較好的可靠性。
4位格雷碼:
十進位制 | 二進位制 | 格雷碼 |
---|---|---|
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 |
- Verilog的實現:
格雷碼計數器的Verilog實現,即用格雷碼計數的方式,完成資料的累加。
實現方式有多種,參考J.Bhasker的書,此處貼上第一種。
程式碼的基本流程為:首先將初始化的格雷碼轉變為二級制碼,二進位制完成累加,最後再講二級制碼轉化為格雷碼。
- 格雷碼轉二進位制碼的基本思路:
最高位不變,次高位往下依次完成自異或運算,得到對應二進位制碼的各位資料,運算次數為位寬-1 - 二進位制碼轉格雷碼的基本思路:
最高位不變,最低位依次往前完成自異或運算,得到對應二進位制碼的各位資料,運算次數為位寬-1 - 注:這樣的自異或運算與其他人給出的格雷碼+二進位制共同運算的方式不同,前一種可能存在侷限性,待發現後說明
非同步復位的N位格雷碼計數器
`timescale 1ns/1ns
module gray_counter1(ck,preclear,q);
parameter NBITS = 4; //決定格雷碼計數的頻寬
input ck,preclear;
output [0:NBITS-1] q;
reg [0:NBITS-1] q;
reg [0:NBITS-1] gray_cnt;
integer k;
always @(posedge ck or negedge preclear)
begin
if(!preclear) //非同步清零訊號,訊號為低時,計數清零
q <= 0;
else
begin
gray_cnt = q;
//將資料存在在臨時變數中
for(k=1;k<NBITS;k=k+1)
if(gray_cnt[k-1])
gray_cnt[k] = !gray_cnt[k];//高位為高,低位取反,本質上是異或操作
//完成格雷碼到二進位制的轉換,二進位制計數
gray_cnt = gray_cnt + 1;
for(k=NBITS-1;k>0;k=k-1)
if(gray_cnt[k-1])
gray_cnt[k] = !gray_cnt[k];
//二進位制轉回格雷碼
q <= gray_cnt;
end
end
endmodule
module gray_counter1_tb; //測試檔案
parameter NBITS = 4;
reg ck,preclear;
wire [0:NBITS-1] q;
gray_counter1 U1(ck,preclear,q);
always #50 ck = !ck; //計數時鐘,週期100ns
initial
begin
ck = 0;
preclear = 1;
#70 preclear = 0;
#70 preclear = 1;
end
endmodule