基於FPGA的二進制轉BCD設計與實現(移位加3法)


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)

(2)陪您一起學習FPGA-郝旭帥團隊_嗶哩嗶哩_bilibili


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM