FPGA系统性学习笔记连载_Day14【BCD转二进制、二进制转BCD】 【原理及verilog仿真】
本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。
连载《叁芯智能fpga设计与研发-第14天》 【BCD转二进制、二进制转BCD】 【原理及verilog仿真】
原创作者:紫枫术河 转载请联系群主授权,否则追究责任
本篇文章,记录BCD转二进制、二进制转BCD的原理,及verilog代码仿真
一、BCD转二进制
BCD码:俗称8421码,意思是用4bit来表示一个10进制数,注意这个4bit表示的数据范围是 0-9;
我做一个表格,来展示,10进制数和BCD码之间的关系
从图中可以看出来,一个十进制数,是用4bit 二进制数来表示的,且每个十进制数 A = 2^3 2^2 2^1 2^0来计算。
1.1、如果我们要将一个189,表示为BCD码就是 0001_1000_1001,可以看出189占据12bit,每个数占4bit
1.2、将BCD189,用二进制表示只需要8bit,2^8 = 256
1.3、所以我们定义BCD为12bit,这样就可以做0-255之间的BCD转二进制实验了。
1.4、下面我做了一个图来表示BCD189 转换为二进制的过程
1.5、verilog代码实现
代码语言:javascript复制module bcd_to_bin(
input [11:0] bcd,
output [7:0] bin
);
wire [3:0] a;
wire [3:0] b;
wire [3:0] c;
wire [9:0] a_r;
wire [6:0] b_r;
wire [9:0] bin_temp;
assign a = bcd[11:8];
assign b = bcd[7:4];
assign c = bcd[3:0];
//百位=1*100=1*(64 32 4)
assign a_r = (a <<6) (a <<5) (a<<2);
//十位=1*10=1*(8 2)
assign b_r = (b<<3) (b<<1);
assign bin_temp = a_r b_r c;
assign bin = bin_temp[7:0];
endmodule
1.6、仿真文件
代码语言:javascript复制`timescale 1ns/1ps
module bcd_to_bin_tb;
reg [11:0] bcd;
wire [7:0] bin;
reg clk;
reg [3:0] a;
reg [3:0] b;
reg [3:0] c;
initial begin
repeat(20000)begin
a = {$random}%3;
b = {$random};
c = {$random};
if((a*100 b*10 c)>255)begin
b = 5;
c = 5;
end
bcd = {a,b,c};
#50;
end
end
bcd_to_bin bcd_to_bin_inst(
.bcd (bcd),
.bin (bin)
);
endmodule
1.7、仿真效果
仿真结果正确。
二、2进制转BCD
2进制转BCD:因为在FPGA中,我们使用除法器和乘法器会非常占资源,为了节省PFGA的逻辑资源,我们需要
设计一个算法来实现2进制到BCD的高效转换,这个算法就是大四加三算法。
1.1、大四加三算法过程,这里展示二进制178(1011_0010)转换为BCD178(0001_0111_1000)码的过程
从图中可以看出来,二进制转BCD码大四加三算法,需要进行8次判断当前BCD码是否大于4,如果大于4,进行加3,
然后才能左移,注意:左移一定要在判断之后,否则转换错误
1.2、verilog代码实现
这个代码我分为bin_to_bcd.v、cmp.v、left_shift.v
1.3、bin_to_bcd.v
代码语言:javascript复制module bin_to_bcd(
input [7:0] data,
output [11:0] bcd
);
wire [19:0] data_temp1;
wire [19:0] data_temp2;
wire [19:0] data_temp3;
wire [19:0] data_temp4;
wire [19:0] data_temp5;
wire [19:0] data_temp6;
wire [19:0] data_temp7;
wire [19:0] data_temp8;
wire [19:0] data_temp9;
assign data_temp1 = {12'd0,data};
left_shift left_shift_inst_1(
.data_in (data_temp1),
.data_out (data_temp2)
);
left_shift left_shift_inst_2(
.data_in (data_temp2),
.data_out (data_temp3)
);
left_shift left_shift_inst_3(
.data_in (data_temp3),
.data_out (data_temp4)
);
left_shift left_shift_inst_4(
.data_in (data_temp4),
.data_out (data_temp5)
);
left_shift left_shift_inst_5(
.data_in (data_temp5),
.data_out (data_temp6)
);
left_shift left_shift_inst_6(
.data_in (data_temp6),
.data_out (data_temp7)
);
left_shift left_shift_inst_7(
.data_in (data_temp7),
.data_out (data_temp8)
);
left_shift left_shift_inst_8(
.data_in (data_temp8),
.data_out (data_temp9)
);
assign bcd = data_temp9[19:8];
endmodule
1.4、cmp.v
代码语言:javascript复制module cmp(
input [3:0] data_in,
output [3:0] data_out
);
assign data_out = (data_in > 4'd4) ?(data_in 3'd3):data_in;
endmodule
1.5、left_shift.v
代码语言:javascript复制module left_shift(
input [19:0] data_in,
output [19:0] data_out
);
wire [3:0] a;
wire [3:0] b;
wire [3:0] c;
cmp cmp_inst1(
.data_in (data_in[19:16]),
.data_out (a)
);
cmp cmp_inst2(
.data_in (data_in[15:12]),
.data_out (b)
);
cmp cmp_inst3(
.data_in (data_in[11:8]),
.data_out (c)
);
assign data_out = {a[2:0],b,c,data_in[7:0],1'b0};
endmodule
1.6、仿真脚本
代码语言:javascript复制`timescale 1ns/1ps
module bin_to_bcd_tb;
reg clk;
reg [7:0] data;
wire [11:0] bcd;
initial begin
clk = 0;
repeat(20)begin
data={$random}%6;
#20;
end
end
bin_to_bcd bin_to_bcd_inst(
.data (data),
.bcd (bcd)
);
always #10 clk = ~clk;
endmodule
1.7、仿真结果
仿真结果正确。
【QQ交流群】
群号:173560979,进群暗语:FPGA技术江湖粉丝。
多年的FPGA企业开发经验,各种通俗易懂的学习资料以及学习方法,浓厚的交流学习氛围,QQ群目前已有1000多名志同道合的小伙伴,无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有。
【微信交流群】
现微信交流群已建立09群,人数已达数千人,欢迎关注“FPGA技术江湖”微信公众号,可获取进群方式。
完
后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。
江湖偌大,继续闯荡,愿大侠一切安好,有缘再见!