当前位置:网站首页>【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
边栏推荐
- 云平台下ESB产品开发步骤说明
- 阿里低代码框架 lowcode-engine 之自定义物料篇
- Goodbye Guangzhou paper invoices!The issuance of electronic invoices for accommodation fees will completely replace the invoices of hotels, restaurants and gas stations
- 一次简单的 JVM 调优,学会拿去写到简历里
- font
- A simple JVM tuning, learn to write it on your resume
- 调试技巧总结
- 论文精度 —— 2017 CVPR《High-Resolution Image Inpainting using Multi-Scale Neural Patch Synthesis》
- DNS separation resolution and intelligent resolution
- typedef定义结构体数组类型
猜你喜欢

rac备库双节点查询到的表最后更新时间不一致

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

flink The object probably contains or references non serializable fields.

CSDN 博客更换皮肤

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?

A simple JVM tuning, learn to write it on your resume
![[idea error] Invalid target distribution: 17 solution reference](/img/39/cec5d854b1d941e866c7166b75aa22.png)
[idea error] Invalid target distribution: 17 solution reference

Is Redis old?Performance comparison between Redis and Dragonfly

基于改进YOLOv5轻量化的烟火检测

DNS分离解析和智能解析
随机推荐
How can users overcome emotional issues in programmatic trading?
Talk about the understanding of RPC
[yu gong series] Go program 035-08 2022 interfaces and inheritance and transformation and empty interface
Summary of debugging skills
Audio codec, using FAAC to implement AAC encoding
Unity2D animation (1) introduction to Unity scheme - animation system composition and the function of use
Redis老了吗?Redis与Dragonfly性能比较
flink The object probably contains or references non serializable fields.
(Nips-2015) Spatial Transformer Network
Idea (preferred) cherry-pick operation
程序化交易改变了什么?
输入起始位置,终止位置截取链表
【愚公系列】2022年08月 Go教学课程 035-接口和继承和转换与空接口
MongoDB 基础了解(二)
添加用户报错useradd: cannot open /etc/passwd
Paper Accuracy - 2017 CVPR "High-Resolution Image Inpainting using Multi-Scale Neural Patch Synthesis"
没想到MySQL还会问这些...
【Yugong Series】August 2022 Go Teaching Course 036-Type Assertion
轮转数组问题:如何实现数组“整体逆序,内部有序”?“三步转换法”妙转数组
A brief analysis of whether programmatic futures trading or manual order is better?