如图所示,先看原理。1110_1010对应的十进制是3位,所以bcd码有12位。先12位bcd全部取0,然后二进制码左移一位,从个位开始判断是否大于4,不大于4继续左移。大于4就加3(0011),然后再左移一位,然后再进行判断,直至所有二进制码全部左移完。

框图如下

这里输入的二进制码是20位,对应十进制是6位,bcd码也就是24位。 输出是个位,十位直到十万位总共6个输出。

下面是波形图,data_shift是暂时存放输入的data和24位bcd码,合计44位。shift_flag一个周期内低电平进行判断运算,高电平进行移位运算,一个周期处理一位数据。这里22位一个周期的原因是最头0是赋初值,1-20是对应20位数据。21是末尾取值。

 下面是verilog代码

module  bcd_8421
(
    input   wire            sys_clk     ,
    input   wire            sys_rst_n   ,
    input   wire    [19:0]  data        ,

    output  reg     [3:0]   unit        ,
    output  reg     [3:0]   ten         ,
    output  reg     [3:0]   hun         ,
    output  reg     [3:0]   tho         ,
    output  reg     [3:0]   t_tho       ,
    output  reg     [3:0]   h_hun
);

reg     [4:0]   cnt_shift   ;
reg     [43:0]  data_shift  ;
reg             shift_flag  ;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        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;
    else
        cnt_shift   <=  cnt_shift;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_shift  <=  44'b0;
    else    if(cnt_shift == 5'd0)
        data_shift  <=  {24'b0,data};
    else    if((cnt_shift <= 20) && (shift_flag == 1'b0))
        begin
            data_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]);
        end
    else    if((cnt_shift <= 20) && (shift_flag == 1'b1))
        data_shift  <=  data_shift << 1;
    else
        data_shift  <=  data_shift;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        shift_flag  <=  1'b0;
    else
        shift_flag  <=  ~shift_flag;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            unit    <=  4'b0;
            ten     <=  4'b0;
            hun     <=  4'b0;
            tho     <=  4'b0;
            t_tho   <=  4'b0;
            h_hun   <=  4'b0;
        end
    else    if(cnt_shift == 5'd21)
        begin
            unit    <=  data_shift[23:20];
            ten     <=  data_shift[27:24];
            hun     <=  data_shift[31:28];
            tho     <=  data_shift[35:32];
            t_tho   <=  data_shift[39:36];
            h_hun   <=  data_shift[43:40];
        end

endmodule

更多推荐

FPGA自学之路12(二进制转换8421bcd码)