FPGA——zhixin培训 Day_09——二进制转BCD+练习(非常重要)
A、二进制转BCD
一、设计背景:
1. 二进制
二进制中只有 0 和 1 两个状态,如开关的接通和断开,晶体管的导通和截止、磁元件的正负剩磁、电位电平的低与高等都可表示 0、1 两个数码。使用二进制,电子器件具有实现的可行性。 电子器件中,所有的数据都是用二进制来表示的。
2. BCD 码
BCD 码(Binary-Coded Decimal )亦称二进码十进数或二-十进制代码。用 4 位二进制数来表示 1 位十进制数中的 0~9 这 10 个数码。BCD 码是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD 码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。
二、设计需求:
将 8 位的二进制转成 BCD 码。
三、设计方案:
1.对 10 求余法
将需要转换的数字除以“权”,然后对 10 求余,得出数字各个位上的数字。例如:8’b1000_0000(10 进制中的 128),将此数字对 10 求余,得出个位“8”,然后将“8”赋给最低的 4 位。将此数字(128)除以 10,得出 12(在 FPGA 计算中,自动取整),对 10 求余,然后得出十位“2”,把“2”赋给次低的 4 位。将此数字(128)除以 100,得出 1,对 10 求余,然后得出百位“1”,把“1”赋给另外的 4 位。这样就转换出了 BCD 码。 这类方法中,利用了大量的除法和求余,占用了大量的逻辑资源。但是,实现比较简单,如果芯片的逻辑资源足够的话,可以采取使用这种方法。
代码:
module bin_bcd(bin,bcd);
input [7:0] bin;
output reg [11:0] bcd;
always @(*)
begin
bcd [ 3:0] = bin % 10;//个位
bcd [ 7:4] = bin /10 % 10;//十位
bcd [11:8] = bin / 100 % 10;//百位
end
endmodule
仿真验证:
如下
0 `timescale 1ns/1ns
1
2 module tb_bin_bcd();
3
4 reg [7:0] bin;
5
6 wire [11:0] bcd;
7
8 bin_bcd bin_bcd_inst(
9 .bin(bin),
10 .bcd(bcd)
11 );
12
13 initial
14 begin
15 bin = 0;
16 #50
17 bin = 5;
18 #100
19 bin = 8'd12;
20 #100
21 bin = 8'd55;
22 #100
23 bin = 8'd123;
24 #200
25 $stop;
26 end
27
28 endmodule
2.大四加三法
(1)原理
进行移位,然后进行判断。如果大于四,则加三。最后得出我
们想要的 BCD 码(下述是按照转换 7 位讲解的原理)。
(2)架构图:
bin_data[7:0]:输入的二进制数据。 bin_data[11:0]:输出的 BCD 码(输入的二进制数据为 8 位,最大为 8’b1111_1111(255),每四位二进制表示一个 BCD 码,故而 12 位)。
(3)代码:
顶层:
0 module bcd_converter(bin,bcd);
1
2 input [7:0] bin;
3
4 output [11:0] bcd;
5
6 wire [19:0] data0,data1,data2,data3,data4;
7 wire [19:0] data5,data6,data7,data8;
8
9 assign data0 = {12'd0,bin};
10
11 bcd_modify bcd_modify_mo(.bcd_in(data0),.bcd_out(data1));
12 bcd_modify bcd_modify_m1(.bcd_in(data1),.bcd_out(data2));
13 bcd_modify bcd_modify_m2(.bcd_in(data2),.bcd_out(data3));
14 bcd_modify bcd_modify_m3(.bcd_in(data3),.bcd_out(data4));
15 bcd_modify bcd_modify_m4(.bcd_in(data4),.bcd_out(data5));
16 bcd_modify bcd_modify_m5(.bcd_in(data5),.bcd_out(data6));
17 bcd_modify bcd_modify_m6(.bcd_in(data6),.bcd_out(data7));
18 bcd_modify bcd_modify_m7(.bcd_in(data7),.bcd_out(data8));
19
20 assign bcd = data8[19:8];
21
22 endmodule
子模块1:
0 module bcd_modify(bcd_in,bcd_out);
1
2 input [19:0] bcd_in;
3
4 output [19:0] bcd_out;
5
6 wire [3:0] reg_0;
7 wire [3:0] reg_1;
8 wire [3:0] reg_2;
9
10 bcd_single_modify bcd_single_modify_hig (.bin_in(bcd_in[19:16]),.bcd_out(reg_0));
11 bcd_single_modify bcd_single_modify_med(.bin_in(bcd_in[15:12]),.bcd_out(reg_1));
12 bcd_single_modify bcd_single_modify_low (.bin_in(bcd_in[11: 8]),.bcd_out(reg_2));
13
14 assign bcd_out = {reg_0[2:0],reg_1,reg_2,bcd_in[7:0],1'b0};
15
16 endmodule
子模块2:
0 module bcd_single_modify(bin_in,bcd_out);
1
2 input [3:0] bin_in;
3
4 output reg [3:0] bcd_out;
5
6 always @(*)
7 begin
8 if(bin_in > 4'd4)
9 begin
10 bcd_out = bin_in + 4'd3;
11 end
12 else
13 begin
14 bcd_out = bin_in;
15 end
16 end
17
18 //assign bcd_out = (bin_in > 4'd4) ? (bin_in + 4'd3 ):bcd_out
19
20 endmodule
仿真验证:
0 `timescale 1ns/1ns
1
2 module tb_bin_bcd();
3
4 reg [7:0] bin;
5
6 wire [11:0] bcd;
7
8 bcd_converter bcd_converter_inst(
9 .bin(bin),
10 .bcd(bcd)
11 );
12
13 initial
14 begin
15 bin = 0;
16 #50
17 bin = 0;
18 #100
19 bin = 8'd255;
20 // #100
21 // bin = 8'd55;
22 // #100
23 // bin = 8'd123;
24 #200
25 $stop;
26 end
27
28 endmodule
B、练习:
一、设计要求:
应用:消抖,边沿检测,数码管,bcd,按键,计数:0----255-----0;
二、设计思路
通过按键(两个)控制数码管,按键0按一下,数码管显示的数字加1;按键1按一下,数码管的数字减1;数码管显示的数字可从0----255;
三、框架图:
四、代码:
上述模块在前几次课中都有。
RTL视图:
仿真验证和下板验证,与设计要求相符。