23- BCD码

时间:2023-07-06 22:03:27来源:博客园


(资料图片)

1.BCD码

  • 数码管动态显示的data[19:0]使用二进制数表示的多位十进制数,不能直接生成段选和片选信号,需要使用BCD码表示的十进制数
  • BCD码(Binary-Coded Decimal),又称为二-十进制码,使用四位二进制数来表示1位十进制数中的0-9这十个数,是一种二进制的数字编码形式,用二进制编码的十进制代码
  • 分类:有权码和无权码,这里的权字表示权值,有权码四位二进制数中的
  • 有权码:8421码,5421码,2421码
  • 无权码:余三码,余三循环码,格雷码
  • 使用多位数码管表示234,二进制表示就是1110_1010,使用8421码表示0010_0011_0100
  • 使用多位数码管显示234,需要使用动态扫描的方式,要依次显示个位,十位,百位,要求能从传入的数据中得到个位,十位,百位,所以使用BCD码可以直接得到位选信号和段选信号

1.1 二进制数转换为BCD码

  • 实现转换的第一步,就是在输入的二进制码之前补多少个0,补(十进制数位数*4)个0
  • 234 -- 前面补12个0,然后看BCD码每一位,如果小于等于4,就保持不变,进行移位操作(左移);如果大于4,就将补的BCD码进行加3
  • 直到二进制数为0,补充的BCD码位就是对应的二进制数的BCD码,十进制数-->二进制数-->BCD码
  • 移位次数:输入多少位二进制数,就会移位多少次

2.BCD码转换模块

2.1 模块框图

添加BCD码转换模块

  • 输入时钟和复位信号
  • 输入十进制数的二进制编码
  • 输出六路BCD码4bit,输出的6路BCD码分别用个位,十位,百位,千位,万位,十万位表示系统框图需要进行修改

2.2 波形图

  • 二进制码向BCD码的转换是通过判断运算加移位操作实现的,移位次数是与二进制数的位数相关的,需要移位计数器对于判断运算和移位次数进行计数,移位次数是20次,所以位宽为5bit
  • 需要一个中间变量存储中间的数据,data_shift[43:0],(二进制数位数+BCD码位数)
  • 判断运算在前,移位操作在后,需要一个标志信号区分这两个操作(shift_flag),但是这两个操作是在一个时钟周期内完成的,每次移位操作都是在判断计算之后进行的

2.3 RTL

module bcd_8421(inputwiresys_clk,inputwiresys_rst_n,inputwire[19:0]data,outputreg[3:0]unit,outputreg[3:0]ten,outputreg[3:0]hun,outputreg[3:0]thou,outputreg[3:0]t_thou,outputreg[3:0]h_hun,);reg[4:0]cnt_shift;reg[43:0]data_shift;regshift_flag;always@(posedge sys_clk or negedge sys_rst_n)if(sys_clk == 1"b1)cnt_shift <= 5"d0;else if((cnt_shift == 5"d21)&&(shift_flag == 1"b1))cnt_shift <= 5"d0;else if(shift_flag == 1"b1)cnt_shift <= cnt_shift + 1"b1;elsecnt_shift <= cnt_shift;always@(posedge sys_clk or negedge sys_rst_n)if(sys_clk == 1"b1)data_shift <= 44"b0;else if(cnt_shift == 5"d0)data_shift <= {24"b0,data};else if((shift_flag == 1"b0) && (cnt_shift <= 20))begindata_shift[23:20] <= (data_shift[23:20] > 4) ? (data_shift[23:20] + 2"d3) : data_shift[23:20];    data_shift[27:24] <= (data_shift[27:24] > 4) ? (data_shift[27:24] + 2"d3) : data_shift[27:24];    data_shift[31:28] <= (data_shift[31:28] > 4) ? (data_shift[31:28] + 2"d3) : data_shift[31:28];    data_shift[35:32] <= (data_shift[35:32] > 4) ? (data_shift[35:32] + 2"d3) : data_shift[35:32];    data_shift[39:36] <= (data_shift[39:36] > 4) ? (data_shift[39:36] + 2"d3) : data_shift[39:36];    data_shift[43:40] <= (data_shift[43:40] > 4) ? (data_shift[43:40] + 2"d3) : data_shift[43:40];endelse if((shift_flag == 1"b1)&&(cnt_shift <= 20))data_shift <= data_shift << 1;elsedata_shift <= data_shift;always@(posedge sys_clk or negedge sys_rst_n)if(sys_clk == 1"b1)shift_flag <= 1"b0;else shift_flag <= ~shift_flag;// 输出信号always@(posedge sys_clk or negedge sys_rst_n)if(sys_clk == 1"b1)beginunit<= 4"b0;ten<= 4"b0;hun<= 4"b0;thou<= 4"b0;t_thou<= 4"b0;h_hun<= 4"b0;endelse if(data_shift == 5"d21)beginunit<= data_shift[23:20];ten<= data_shift[27:24];                hun<= data_shift[31:28];                thou<= data_shift[35:32];                t_thou<= data_shift[39:36];h_hun<= data_shift[43:40];endendmodule

2.4 Testbench

`timescale 1ns/1nsmodule tb_bcd_8421();regsys_clk;regsys_rst_n;reg[19:0]data;wire [3:0]unit;wire [3:0]ten;wire [3:0]hun;wire [3:0]thou;wire [3:0]t_thou;wire [3:0]h_hun;initial beginsys_clk = 1"b1;sys_rst_n <= 1"b0;data <= 20"d0;#30sys_rst_n <= 1"b1;data <= 20"d123_456;#3000;data <= 20"d654_321;#3000;data <= 20"d987_654;#2000;data <= 20"d999_999;endalways #10 sys_clk = ~sys_clk;bcd_8421 bcd_8421_inst(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.data(data),.unit(unit),.ten(ten),.hun(hun),.thou(thou),.t_thou(t_thou),.h_hun(h_hun),);endmodule

2.5 仿真

关键词:

相关资讯
热门频道