用FPGA设计8421BCD编码

8421BCD编码介绍:8421bcd码是最常用的BCD码,是十进制代码中最常用的一种。8421码适合于计算机处理。

运用介绍:8421BCD码中的“8421”表示从高到低各位二进制位对应的权值分别为8、4、2、1,将各二进制位与权值相乘,并将乘积相加就得相应的十进制数。

例如,8421BCD码“0111”,0×8+1×4+1×2+1×1=7D,其中D表示十进制

编码示意图:

模块框图:

bcd_8421模块代码(该代码参考了野火的8421bcd编码)

链接:数码管的动态显示 — [野火]FPGA Verilog开发实战指南——基于Altera EP4CE10 征途Mini开发板 文档 (embedfire.com)

module bcd_8421 
(
    input   wire             clk_50Mhz,      //系统时钟50Mhz     
    input   wire             rst_n,          //全局复位
    input   wire    [26:0]   data,           //待编码数据

    output  wire    [31:0]   bcd_data        //编码后的数据
);

//parameter define
parameter   CNT_SHIFT_NUM = 7'd27;  			// 由data的位宽决定

//reg define
reg [6:0]       cnt_shift;         				// 移位判断计数器
reg [58:0]      data_shift;        				// 移位判断数据寄存器,
reg             shift_flag;        				// 移位判断标志信号

reg     [3:0]   unit        ;   // 个位BCD码
reg     [3:0]   ten         ;   // 十位BCD码
reg     [3:0]   hun         ;   // 百位BCD码
reg     [3:0]   tho         ;   // 千位BCD码
reg     [3:0]   t_tho       ;   // 万位BCD码
reg     [3:0]   h_hun       ;   // 十万位BCD码
reg     [3:0]   hundred_tho  ;  // 百万位BCD码
reg     [3:0]   million      ;  // 千万位BCD码


assign  bcd_data = {million,hundred_tho,h_hun,t_tho,tho,hun,ten,unit};

//cnt_shift计数
always @(posedge clk_50Mhz or negedge rst_n) begin
    if (rst_n==1'b0) begin
        cnt_shift <= 7'd0;
    end
    else if ((cnt_shift == CNT_SHIFT_NUM + 1) && (shift_flag)) begin
        cnt_shift <= 7'd0;
    end
    else if (shift_flag) begin
        cnt_shift <= cnt_shift + 1'b1;
    end   
    else begin
        cnt_shift <= cnt_shift;
    end
end

//data_shift 计数器为0时赋初值,计数器为1~CNT_SHIFT_NUM时进行移位操作
always @(posedge clk_50Mhz or negedge rst_n) begin
    if (rst_n==1'b0) begin
        data_shift <= 59'd0;
    end
    else if (cnt_shift == 7'd0) begin
        data_shift <= {32'b0, data};
    end
    else if ((cnt_shift <= CNT_SHIFT_NUM) && (!shift_flag)) begin
        data_shift[30:27] <= (data_shift[30:27] > 4) ? (data_shift[30:27] + 4'b0011) : (data_shift[30:27]);
        data_shift[34:31] <= (data_shift[34:31] > 4) ? (data_shift[34:31] + 4'b0011) : (data_shift[34:31]);
        data_shift[38:35] <= (data_shift[38:35] > 4) ? (data_shift[38:35] + 4'b0011) : (data_shift[38:35]);
        data_shift[42:39] <= (data_shift[42:39] > 4) ? (data_shift[42:39] + 4'b0011) : (data_shift[42:39]);
        data_shift[46:43] <= (data_shift[46:43] > 4) ? (data_shift[46:43] + 4'b0011) : (data_shift[46:43]);
        data_shift[50:47] <= (data_shift[50:47] > 4) ? (data_shift[50:47] + 4'b0011) : (data_shift[50:47]);
        data_shift[54:51] <= (data_shift[54:51] > 4) ? (data_shift[54:51] + 4'b0011) : (data_shift[54:51]);
        data_shift[58:55] <= (data_shift[58:55] > 4) ? (data_shift[58:55] + 4'b0011) : (data_shift[58:55]);
    end
    else if ((cnt_shift <= CNT_SHIFT_NUM) && (shift_flag)) begin
        data_shift <= data_shift << 1;
    end
    else begin
        data_shift <= data_shift;
    end
end

//shift_flag 移位判断标志信号,用于控制移位判断的先后顺序
always @(posedge clk_50Mhz or negedge rst_n) begin
    if (rst_n==1'b0) begin
        shift_flag <= 1'b0;
    end
    else begin
        shift_flag <= ~shift_flag;
    end
end

// 当计数器等于26时,移位判断操作完成,对各个位数的BCD码进行赋值
always @(posedge clk_50Mhz or negedge rst_n) begin
    if (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;
        hundred_tho  <=  4'b0;
        million      <=  4'b0;
    end
    else if (cnt_shift == CNT_SHIFT_NUM + 1) begin
        unit         <=  data_shift[30:27];
        ten          <=  data_shift[34:31];
        hun          <=  data_shift[38:35];
        tho          <=  data_shift[42:39];
        t_tho        <=  data_shift[46:43];
        h_hun        <=  data_shift[50:47];
        hundred_tho  <=  data_shift[54:51];
        million      <=  data_shift[58:55];
    end
end

endmodule

  • 30
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值