1 項目介紹
在顯示溫度、電壓、電流等數據時,通常需要將二進制數據轉換成十進制進行顯示。最常用的方法是將二進制轉換成BCD碼(8421)。
對於一個兩位的數值,對10取除可以得到其十位的數值,對10取余可以得到個位的數值。對於Verilog來說它的標准是支持除法和取余運算的,綜合器也會有IP可以進行除法運算。但是這樣未免會耗費太多資源,使用移位加3算法就可以實現二進制到BCD碼之間的轉換。
2 設計要求: 采用移位加3算法實現二進制轉BCD碼電路。
3 設計分析
(1) 移位加3算法
移位加3算法簡單來說就是,有多少位二進制說,就進行多少次移位,以八位的二進制為例,其數值最高可為三位十進制數,進行如下表左移,在移位的過程中,如果移位出的數值大於4,則將改為的數值加3后再進行移位。
這里為什么大於四,BCD碼是四位二進制數表示一個十進制數的一位,如果這以為大於4,比如5,4’b0101,下一次移位后變成了4’b1010,BCD碼中是沒有4’b1010的,所以要加6,向高位進位。這里就是移位后加6和移位前加3,兩種方法修正,我這里選擇了移位前加3。(4’b0011左移后也是4’b0110,移位前和移位后都是一樣的對BCD碼的位數進行修正)。
(2)系統結構
系統端口及其意義
- bin[7:0]: 二進制輸入信號,其數值范圍為0~256;
- bcd[11:0]: BCD碼輸出信號,bcd[11:8]表示百位,bcd[7:4]表示十位,bcd[3:0]表示個位。8位的二進制能夠表示最大的數字為255,共有三個BCD碼,輸出共有12位。
(3)架構設計
4 設計實現
4.1 移位加3算法模塊設計
1 module adjust_shift( 2 input wire [19:0] idata, 3 output wire [19:0] odata 4 ); 5 6 wire [19:0] adjust_data; 7 8 assign adjust_data[19:16] = idata[19:16] > 4'd4 ? idata[19:16] + 4'd3 : idata[19:16]; 9 assign adjust_data[15:12] = idata[15:12] > 4'd4 ? idata[15:12] + 4'd3 : idata[15:12]; 10 assign adjust_data[11:8] = idata[11:8] > 4'd4 ? idata[11:8] + 4'd3 : idata[11:8]; 11 assign adjust_data[7:0] = idata[7:0]; 12 13 assign odata = adjust_data << 1'b1; 14 15 endmodule
4.2 頂層模塊
1 module bin2bcd2( 2 input wire [7:0] bin, 3 output wire [11:0] bcd 4 ); 5 6 wire [19:0] part_0; 7 wire [19:0] part_1; 8 wire [19:0] part_2; 9 wire [19:0] part_3; 10 wire [19:0] part_4; 11 wire [19:0] part_5; 12 wire [19:0] part_6; 13 wire [19:0] part_7; 14 15 adjust_shift adjust_shift_inst0(.idata ({12'd0, bin}), .odata(part_0)); 16 adjust_shift adjust_shift_inst1(.idata (part_0), .odata(part_1)); 17 adjust_shift adjust_shift_inst2(.idata (part_1), .odata(part_2)); 18 adjust_shift adjust_shift_inst3(.idata (part_2), .odata(part_3)); 19 adjust_shift adjust_shift_inst4(.idata (part_3), .odata(part_4)); 20 adjust_shift adjust_shift_inst5(.idata (part_4), .odata(part_5)); 21 adjust_shift adjust_shift_inst6(.idata (part_5), .odata(part_6)); 22 adjust_shift adjust_shift_inst7(.idata (part_6), .odata(part_7)); 23 24 assign bcd = part_7[19:8]; 25 26 endmodule
5 仿真驗證
1 `timescale 1ns/1ps 2 3 module bin2bcd2_tb(); 4 5 reg [7:0] bin; 6 wire [11:0] bcd; 7 8 wire [7:0] tb_bin; 9 10 assign tb_bin = bcd[3:0] + bcd[7:4]*10 + bcd[11:8]*100; 11 12 bin2bcd2 bin2bcd2_inst( 13 .bin (bin), 14 .bcd (bcd) 15 ); 16 17 initial begin 18 repeat(500)begin 19 bin = {$random}%256; 20 #20; 21 end 22 $display("Test right!!"); 23 $stop; 24 end 25 26 always@(bin)begin 27 #2; 28 if(bin != tb_bin)begin 29 $display("Test error!!"); 30 $stop; 31 end 32 end 33 34 endmodule
6 參考文獻
(1)基於Verilog HDL的二進制轉BCD碼實現 - NingHeChuan - 博客園 (cnblogs.com);