FPGA学习altera 系列 第二十三篇 二进制转BCD

2020-12-29 17:33:10 浏览数 (1)

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

今天给大侠带来“FPGA学习系列 altera"系列,持续更新。此学习心得是本人之前所写,所用设计软件为Quartus II 13.1,现Quartus II 新版本已更新到19 ,以下仅供初学者学习参考。后续会更新其他系列,敬请关注。话不多说,上货。

对于每一个的小实验,我们都可以把它看作是一个小项目,逐步的去分析,设计,调试,最后完成功能。下面我们就开始我们的“小项目”。

项目名称:二进制转BCD

具体要求:将8位的二进制转成BCD码。

项目分析:

1. 二进制

二进制中只有0和1两个状态,可以表示0、1两种状态的电子器件很多,如开关的接通和断开,晶体管的导通和截止、磁元件的正负剩磁、电位电平的低与高等都可表示0、1两个数码。使用二进制,电子器件具有实现的可行性。

二进制数的运算法则少,运算简单,使计算机运算器的硬件结构大大简化。由于二进制0和1正好和逻辑代数的假(false)和真(true)相对应,有逻辑代数的理论基础,用二进制表示二值逻辑很自然。

电子器件中,所有的数据都是用二进制来表示的。

2. BCD码

BCD码(Binary-Coded Decimal)亦称二进码十进数或二-十进制代码。用4位二进制数来表示1位十进制数中的0~9这10个数码。BCD码是一种二进制的数字编码形式,用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。

3. 实现方法

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码。

这类方法中,利用了大量的除法和求余,占用了大量的逻辑资源。但是,实现比较简单,如果芯片的逻辑资源足够的话,可以采取使用这种方法。

2) 大四加三法

进行移位,然后进行判断。如果大于四,则加三。最后得出我们想要的BCD码(下述是按照转换7位讲解的原理)。

架构图如下:

bin_data[7:0]:输入的二进制数据。

bin_data[11:0]:输出的BCD码(输入的二进制数据为8位,最大为8’b1111_1111(255),每四位二进制表示一个BCD码,故而12位)。

系统设计:

1. 工程的名称:bin_to_bcd

2. 实现方法:使用组合逻辑实现。

设计代码如下:

代码语言:javascript复制
/*
模块名称:bin_to_bcd
模块功能:将8位的二进制转成BCD码(对10求余法)。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bin_to_bcd (bin_data, bcd_data);

  input [7:0] bin_data;

  output reg [11:0] bcd_data;

  always @ (*)
    begin
      bcd_data[3:0] = bin_data % 10;
      bcd_data[7:4] = (bin_data / 10 ) % 10;
      bcd_data[11:8] = (bin_data / 100) % 10;
    end

endmodule

激励代码如下:

代码语言:javascript复制
/*
模块名称:bin_to_bcd_tb
模块功能:为bin_to_bcd模块提供激励信号
作者:郝旭帅
邮箱:746833924@qq.com
*/
`timescale 1ns/1ps

module bin_to_bcd_tb;

  reg [7:0] bin_data;

  wire [11:0] bcd_data;

  initial begin
    bin_data = 8'd147;
    # 200
    bin_data = 8'd58;
    # 200
    bin_data = 8'd169;
    # 200
    $stop;
  end

  bin_to_bcd bin_to_bcd_dut(
      .bin_data(bin_data),
      .bcd_data(bcd_data)
    );

endmodule

代码解析:

bin_data赋值时,不要大于255,因为8位的二进制数据最大就是255,若超过255,将出现不正确的赋值。

仿真波形如下:

将bin_data设置成无符号位,将bcd_data设置成十六进制,4位的二进制正好一位十六进制。

通过仿真,证明设计正确。

下面是大四加三法的设计代码以及仿真:在设计中,我们使用层次化设计的方法,逐步完成。

设计代码如下:

代码语言:javascript复制
  /*
模块名称:bin_to_bcd
模块功能:将8位的二进制转成BCD码(大四加三法)。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bin_to_bcd (bin_data, bcd_data);

  input [7:0] bin_data;

  output [11:0] bcd_data;

wire [19:0] shift_data[7:0];//位宽20,深度8的shift_data

  assign shift_data[0] = {18'd0,bin_data,1'b0};//左移

  bcd_modify bcd_modify_0(
        .in_data(shift_data[0]), 
        .out_data(shift_data[1])
      );//第一次调整并左移

  bcd_modify bcd_modify_1(
        .in_data(shift_data[1]), 
        .out_data(shift_data[2])
      ); //第二次调整并左移

  bcd_modify bcd_modify_2(
        .in_data(shift_data[2]), 
        .out_data(shift_data[3])
      ); //第三次调整并左移

  bcd_modify bcd_modify_3(
        .in_data(shift_data[3]), 
        .out_data(shift_data[4])
      ); //第四次调整并左移

  bcd_modify bcd_modify_4(
        .in_data(shift_data[4]),
        .out_data(shift_data[5])
      ); //第五次调整并左移

  bcd_modify bcd_modify_5(
        .in_data(shift_data[5]), 
        .out_data(shift_data[6])
      ); //第六次调整并左移

  bcd_modify bcd_modify_6(
        .in_data(shift_data[6]),
        .out_data(shift_data[7])
      ); //第七次调整并左移

  assign bcd_data = shift_data[7] [19:8];

endmodule
代码语言:javascript复制
/*
模块名称:bcd_modify
模块功能:调整并且进行左移。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bcd_modify (in_data, out_data);

  input [19:0] in_data;

  output [19:0] out_data;

  wire [19:0] reg_data;

  bcd_singel bcd_singel_0(
        .in_data(in_data[19:16]), 
        .out_data(reg_data[19:16])
      );//调整

  bcd_singel bcd_singel_1(
        .in_data(in_data[15:12]), 
        .out_data(reg_data[15:12])
      ); //调整

  bcd_singel bcd_singel_2(
        .in_data(in_data[11:8]), 
        .out_data(reg_data[11:8])
      ); //调整

  assign reg_data[7:0] = in_data[7:0];

  assign out_data = {reg_data[18:0],1'b0};//左移

endmodule
代码语言:javascript复制
/*
模块名称:bcd_singel
模块功能:调整(大四加三)。
作者:郝旭帅
邮箱:746833924@qq.com
*/
module bcd_singel (in_data, out_data);

  input [3:0] in_data;

  output [3:0] out_data;

  assign out_data = (in_data > 4) ? in_data   4'd3 : in_data;
//如果大于4,则加四,否则,原值输出。
endmodule

激励代码如下:

代码语言:javascript复制
/*
模块名称:bin_to_bcd_tb
模块功能:为bin_to_bcd模块提供激励信号
作者:郝旭帅
邮箱:746833924@qq.com
*/
`timescale 1ns/1ps

module bin_to_bcd_tb;

  reg [7:0] bin_data;

  wire [11:0] bcd_data;

  initial begin
    bin_data = 8'd147;
    # 200
    bin_data = 8'd58;
    # 200
    bin_data = 8'd169;
    # 200
    $stop;
  end

  bin_to_bcd bin_to_bcd_dut(
      .bin_data(bin_data),
      .bcd_data(bcd_data)
    );

endmodule

代码解析:

bin_data赋值时,不要大于255,因为8位的二进制数据最大就是255,若超过255,将出现不正确的赋值。

仿真波形如下:

将bin_data设置成无符号位,将bcd_data设置成十六进制,4位的二进制正好一位十六进制。通过仿真,证明设计正确。

如果设计要求或者本地晶振与笔者的设计不同,请自行更改设计,以保证设计的正确性。如果还是有不明白的读者可以发邮件到我邮箱或者加群询问。

END

0 人点赞