当前位置:网站首页>【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
边栏推荐
- Environment configuration of ESP32 (arduino arduino2.0 VScode platform which is easy to use?)
- 你不知道的 console.log 替代品
- EasyCVR接入GB28181设备时,设备接入正常但视频无法播放是什么原因?
- 构建程序化交易系统需要注意什么问题?
- font
- CSDN blog replacement skin
- The solution to the height collapse problem
- console.log alternatives you didn't know about
- 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?
- MongoDB 基础了解(二)
猜你喜欢

字体反扒

"Life Is Like First Seen" is ill-fated, full of characters, and the contrast of Zhu Yawen's characters is too surprising

Qnet Weak Network Test Tool Operation Guide

调试技巧总结

The most unlucky and the luckiest

Homework 8.10 TFTP protocol download function

Traversal of DOM tree-----modify styles, select elements, create and delete nodes

console.log alternatives you didn't know about

音视频开发,为什么要学习FFmpeg?应该怎么入手FFmpeg学习?

电力机柜数据监测RTU
随机推荐
Multi-merchant mall system function disassembly 26 lectures - platform-side distribution settings
C语言 recv()函数、recvfrom()函数、recvmsg()函数
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?
没想到MySQL还会问这些...
(CVPR - 2017) in depth and potential body learning context awareness feature for pedestrian recognition
Add user error useradd: cannot open /etc/passwd
CSDN 博客更换皮肤
Google search skills - programmer is recommended
MYSQLg高级------回表
Build Zabbix Kubernetes cluster monitoring platform
按摩椅控制板的开发让按摩椅变得简约智能
2022-08-10 第六小组 瞒春 学习笔记
Homework 8.10 TFTP protocol download function
调试技巧总结
KingbaseES有什么办法,默认不读取sys_catalog下的系统视图?
rac备库双节点查询到的表最后更新时间不一致
FTP错误代码列表
荣威imax8ev魔方电池安全感,背后隐藏着哪些黑化膨胀?
程序化交易与主观交易对盈利曲线的影响!
浅析一下期货程序化交易好还是手工单好?