当前位置:网站首页>【FPGA】day19-二进制转换为十进制(BCD码)
【FPGA】day19-二进制转换为十进制(BCD码)
2022-08-11 03:28:00 【春风浅作序】
一、为什么要用BCD码
FPGA的资源中是没有除法器的,在用到除法时FPGA会使用逻辑单元(LE)中的查找表(LUT)去搭建除法器。如果是对一个大数进行取余、取整,就会占用大量的逻辑资源,然后导致一定的路径延时。
造成的影响:
①时序问题。系统时钟周期20ns内无法给出结果,频率无法达到50M,导致后面一系列数据出现问题。
②资源问题。占用大量逻辑资源。
因此可以使用BCD码,用速度换面积
流水线,为面积换速度
二、BCD码的实现方法
用于分离十进数的各个数位,这种称为 移位加3算法 的算法 只使用加减和移位运算,它可以满足代码移植性的要求,移位加三算法的流程如下(这里假设要分离的只有 3 个数位):
1、将二进制数左移一位移入BCD数(未满 4 位在前面填 0)
2、如果移动了 8 位,那么二进制数就在 百位、十位和个位列,计算结束
3、在任何一个 BCD 列中,如果任何一个二进制数 大于或者等于 5,就把这个数 加上 3
4、回到步骤 1

三、代码实现
module binary2bcd#(parameter DIN_W = 32,DOUT_W = 40) (
input clk ,
input rst_n ,
input en ,
input [DIN_W-1:0] binary_din , //输入二进制数据
output reg [DOUT_W-1:0] bcd_dout , //输出BCD码数据
output reg bcd_dout_vld
);
//状态机参数定义
localparam IDLE = 4'b0001,
READY = 4'b0010,
SHIFT = 4'b0100,
DONE = 4'b1000;
//信号定义
reg [3:0] state_c ;
reg [3:0] state_n ;
reg [DIN_W-1:0] din_r ; //数据锁存
reg [5:0] shift_cnt ; //移位次数计数器
wire add_shift_cnt ;
wire end_shift_cnt ;
reg [3:0] mem_r0 ;
reg [3:0] mem_r1 ;
reg [3:0] mem_r2 ;
reg [3:0] mem_r3 ;
reg [3:0] mem_r4 ;
reg [3:0] mem_r5 ;
reg [3:0] mem_r6 ;
reg [3:0] mem_r7 ;
reg [3:0] mem_r8 ;
reg [3:0] mem_r9 ;
wire [3:0] mem_w0 ;
wire [3:0] mem_w1 ;
wire [3:0] mem_w2 ;
wire [3:0] mem_w3 ;
wire [3:0] mem_w4 ;
wire [3:0] mem_w5 ;
wire [3:0] mem_w6 ;
wire [3:0] mem_w7 ;
wire [3:0] mem_w8 ;
wire [3:0] mem_w9 ;
wire [39:0] bcd_res ;
wire idle2ready ;
wire shift2done ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
state_c <= IDLE ;
end
else begin
state_c <= state_n ;
end
end
always @(*) begin
case (state_c)
IDLE :begin
if(idle2ready)
state_n = READY ;
else
state_n = state_c;
end
READY:begin
state_n = SHIFT;
end
SHIFT:begin
if(shift2done)
state_n = DONE ;
else
state_n = state_c;
end
DONE :begin
state_n = IDLE;
end
default:state_n = IDLE;
endcase
end
assign idle2ready = state_c == IDLE && (en) ;
assign shift2done = state_c == SHIFT && (end_shift_cnt);
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
shift_cnt <= 1'd0;
end
else if(add_shift_cnt)begin
if(end_shift_cnt)begin
shift_cnt <= 1'd0;
end
else begin
shift_cnt <= shift_cnt + 1'd1;
end
end
end
assign add_shift_cnt = state_c == SHIFT;
assign end_shift_cnt = add_shift_cnt && shift_cnt == DIN_W - 1 ;
//din_r
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
din_r <= 1'b0;
end
else if(en)begin
din_r <= binary_din;
end
else if(state_c == SHIFT)begin //移位状态下,每个时钟周期向左移一位
din_r <= din_r << 1'b1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
mem_r0 <= 0;
mem_r1 <= 0;
mem_r2 <= 0;
mem_r3 <= 0;
mem_r4 <= 0;
mem_r5 <= 0;
mem_r6 <= 0;
mem_r7 <= 0;
mem_r8 <= 0;
mem_r9 <= 0;
end
else if(idle2ready)begin
mem_r0 <= 0;
mem_r1 <= 0;
mem_r2 <= 0;
mem_r3 <= 0;
mem_r4 <= 0;
mem_r5 <= 0;
mem_r6 <= 0;
mem_r7 <= 0;
mem_r8 <= 0;
mem_r9 <= 0;
end
else if(state_c == SHIFT)begin
mem_r0 <= {
mem_w0[2:0],din_r[DIN_W-1]};
mem_r1 <= {
mem_w1[2:0],mem_w0[3]};
mem_r2 <= {
mem_w2[2:0],mem_w1[3]};
mem_r3 <= {
mem_w3[2:0],mem_w2[3]};
mem_r4 <= {
mem_w4[2:0],mem_w3[3]};
mem_r5 <= {
mem_w5[2:0],mem_w4[3]};
mem_r6 <= {
mem_w6[2:0],mem_w5[3]};
mem_r7 <= {
mem_w7[2:0],mem_w6[3]};
mem_r8 <= {
mem_w8[2:0],mem_w7[3]};
mem_r9 <= {
mem_w9[2:0],mem_w8[3]};
end
end
assign mem_w0 = (mem_r0 > 4'd4)?(mem_r0 + 4'd3):mem_r0;
assign mem_w1 = (mem_r1 > 4'd4)?(mem_r1 + 4'd3):mem_r1;
assign mem_w2 = (mem_r2 > 4'd4)?(mem_r2 + 4'd3):mem_r2;
assign mem_w3 = (mem_r3 > 4'd4)?(mem_r3 + 4'd3):mem_r3;
assign mem_w4 = (mem_r4 > 4'd4)?(mem_r4 + 4'd3):mem_r4;
assign mem_w5 = (mem_r5 > 4'd4)?(mem_r5 + 4'd3):mem_r5;
assign mem_w6 = (mem_r6 > 4'd4)?(mem_r6 + 4'd3):mem_r6;
assign mem_w7 = (mem_r7 > 4'd4)?(mem_r7 + 4'd3):mem_r7;
assign mem_w8 = (mem_r8 > 4'd4)?(mem_r8 + 4'd3):mem_r8;
assign mem_w9 = (mem_r9 > 4'd4)?(mem_r9 + 4'd3):mem_r9;
assign bcd_res = {
mem_r9,mem_r8,mem_r7,mem_r6,mem_r5,mem_r4,mem_r3,mem_r2,mem_r1,mem_r0};
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
bcd_dout <= 1'b0;
end
else if(state_c == DONE)begin
bcd_dout <= bcd_res[DOUT_W-1:0];
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
bcd_dout_vld <= 1'b0;
end
else begin
bcd_dout_vld <= state_c == DONE;
end
end
endmodule
边栏推荐
- A large horse carries 2 stone of grain, a middle horse carries 1 stone of grain, and two ponies carry one stone of grain. It takes 100 horses to carry 100 stone of grain. How to distribute it?
- Talk about the understanding of RPC
- uni-app - 获取汉字拼音首字母(根据中文获取拼音首字母)
- 基于改进YOLOv5轻量化的烟火检测
- QueryDet: Cascading Sparse Query Accelerates Small Object Detection at High Resolution
- MYSQLg高级------回表
- 程序化交易与主观交易对盈利曲线的影响!
- EasyCVR接入海康大华设备选择其它集群服务器时,通道ServerID错误该如何解决?
- The negative semantic transformation layer
- Goodbye Chengdu paper invoices!The issuance of electronic invoices for accommodation expenses will soon completely replace the invoices of hotels, catering and gas stations
猜你喜欢

Ten Advanced Concepts of SQL Development

flink The object probably contains or references non serializable fields.

Unity2D animation (1) introduction to Unity scheme - animation system composition and the function of use
![[yu gong series] Go program 035-08 2022 interfaces and inheritance and transformation and empty interface](/img/cb/41e5f553b0b776dccf0e39f9bf377f.png)
[yu gong series] Go program 035-08 2022 interfaces and inheritance and transformation and empty interface

Homework 8.10 TFTP protocol download function

EasyCVR接入GB28181设备时,设备接入正常但视频无法播放是什么原因?

多商户商城系统功能拆解26讲-平台端分销设置

电商项目——商城限时秒杀功能系统

互换性测量技术-几何误差

font
随机推荐
Docker 链接sqlserver时出现en-us is an invalid culture错误解决方案
输入起始位置,终止位置截取链表
互换性测量与技术——偏差与公差的计算,公差图的绘制,配合与公差等级的选择方法
E-commerce project - mall time-limited seckill function system
音视频开发,为什么要学习FFmpeg?应该怎么入手FFmpeg学习?
增加对 Textbundle 的支持
En-us is an invalid culture error solution when Docker links sqlserver
The thirteenth day of learning programming
What problems should we pay attention to when building a programmatic trading system?
[DB operation management/development solution] Shanghai Daoning provides you with an integrated development tool to improve the convenience of work - Orange
STC8H development (15): GPIO drive Ci24R1 wireless module
[BX] and loop
Add support for Textbundle
Idea (优选)cherry-pick操作
C language recv() function, recvfrom() function, recvmsg() function
LeetCode Hot Questions (12. The Best Time to Buy and Sell Stocks)
Multi-merchant mall system function disassembly 26 lectures - platform-side distribution settings
【ADI低功耗2k代码】基于ADuCM4050的ADXL363、TMP75的加速度、温度检测及串口打印、蜂鸣器播放音乐(孤勇者)
Rotary array problem: how to realize the array "overall reverse, internal orderly"?"Three-step conversion method" wonderful array
uni-app - 获取汉字拼音首字母(根据中文获取拼音首字母)