FPGA实现二进制转BCD码

news2024/11/15 21:20:45

在这里插入图片描述

1、简介

bcd码:以4bit二进制码表示一个十进制码

例如,432(d) = 0100-0011-0010(bcd)
这里具体的判断方法为:(满5)加3法
二进制位宽为W,则BCD位宽只需要(W + (W - 4) / 3+1)位

2、参考链接

FPGA Verilog实现二进制转BCD码

二进制数转换成BCD码的Verilog实现

3、实现方案

3-1、wiki实现

/*方法1:来自维基百科,可以看出,二进制位宽为W,则BCD位宽只需要(W + (W - 4) / 3+1)位。
如W=8,只需要10位,范围0-255,百位只需要两位就可以表示。
*/
module binary2bcd#(parameter WIDTH = 20)(	
	input			[WIDTH-1:00]	bin_data, //
	output	reg 	[WIDTH+(WIDTH-4)/3:00]	bcd_data	
);
//Parameter Declarations
	integer i,j;

	always @(bin_data)begin 
		for(i = 0;i <= WIDTH+(WIDTH-4)/3; i = i + 1) 
			bcd_data[i] = 0;
		bcd_data[WIDTH-1:0] = bin_data;
		for(i = 0;i <= WIDTH-4; i = i + 1) 
			for(j = 0;j <= i / 3; j = j + 1)
				if(bcd_data[WIDTH-i+4*j-:4] > 4)begin
					bcd_data[WIDTH-i+4*j-:4] <= bcd_data[WIDTH-i+4*j-:4] + 4'd3; 
				end 
		
	end //always end

endmodule

3-2、状态机实现

方法2:状态机实现,延迟时间为 (输入数据位宽+2) * Tclk
/* ================================================ *\
		Filename    ﹕ binary2bcd.v
		Author      ﹕ Adolph
		Description ﹕ 实现32bit以内的二进制数据转换为BCD
		Called by   ﹕ 
Revision History    ﹕ 2023-07-07 11:50:10
					Revision 1.0
			Email﹕ adolph1354238998@gamil.com
			Company﹕ AWCloud...Std 
\* ================================================ */
module binary2bcd #(parameter BIN_W = 32, BCD_W = 40)(
	input  					Clk		, //system clock 50MHz
	input  			 		Rst_n	, //reset, low valid
	
	input					Start	, //
	input 	   [BIN_W-1:00]	Bin_data, //
	output reg				bcd_vld	, //	
	output reg [BCD_W-1:00]	Bcd_data  //
);
//Parameter Declarations
	//状态机参数定义
	parameter	
		IDLE	=	4'b0001, 
		READY	=	4'b0010,
		SHIFT	=	4'b0100,
		DONE	=	4'b1000;

//Internal wire/reg declarations
	reg		[BIN_W-1:00] 	din_r; //
	
	reg		[05:00]	cnt		; //Counter 移位计数器
	wire			add_cnt ; //Counter Enable
	wire			end_cnt ; //Counter Reset 

	reg		[03:00]	state_c, state_n; //

	reg		[03:00] mem_r  	[09:00]	; //
	wire	[03:00] mem_w	[09:00]	; //
	
	wire	[39:00] bcd_res ; //
	wire 			idle2ready	; //
	wire 			shift2done	; //
	// reg			 	bcd_vld 	; //
	
	
//Logic Description
	always @(posedge Clk or negedge Rst_n)begin
		if(!Rst_n)begin  
			cnt <= 'd0; 
		end  
		else if(add_cnt)begin  
			if(end_cnt)begin  
				cnt <= 'd0; 
			end  
			else begin  
				cnt <= cnt + 1'b1; 
			end  
		end  
		else begin  
			cnt <= cnt;  
		end  
	end 
			
	assign add_cnt = state_c == SHIFT; 
	assign end_cnt = add_cnt && cnt >= BIN_W - 1; 

	
	//第一段设置状态转移空间
	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 end
	//第二段、组合逻辑定义状态转移
	always@(*)begin
		case(state_c)
			IDLE:begin
				if(idle2ready)begin
					state_n = READY;
				end
				else begin
					state_n = state_c;
				end
			end
			READY:begin
				state_n = SHIFT;
			end
			SHIFT:begin
				if(shift2done)begin
					state_n = DONE;
				end 
				else begin
					state_n = state_c;	
				end 
			end
			DONE:begin
				state_n = IDLE;
			end 
			default: begin
				state_n = IDLE;
			end
		endcase
	end //always end
			
	assign	idle2ready	=	state_c == IDLE	 && Start;
	assign	shift2done	=	state_c	== SHIFT &&	end_cnt;
			
	//第三段,定义状态机输出情况,可以时序逻辑,也可以组合逻辑
	always @(posedge Clk or negedge Rst_n)begin  
		if(!Rst_n)begin  
			din_r <= 'd0;
		end  
		else if(Start)begin  
			din_r <= Bin_data;
		end  
		else if(state_c == SHIFT)begin //移位状态下,每个时钟周期向左移1位
			din_r <= din_r << 1;
		end
		else begin  
			din_r <= din_r;
		end  
	end //always end

	always @(posedge Clk or negedge Rst_n)begin 
		if(!Rst_n)begin
			mem_r[0] <= 4'd0;		
			mem_r[1] <= 4'd0;	
			mem_r[2] <= 4'd0;	
			mem_r[3] <= 4'd0;	
			mem_r[4] <= 4'd0;	
			mem_r[5] <= 4'd0;	
			mem_r[6] <= 4'd0;	
			mem_r[7] <= 4'd0;	
			mem_r[8] <= 4'd0;	
			mem_r[9] <= 4'd0;		
		end  
		else if(idle2ready)begin
			mem_r[0] <= 4'd0;		
			mem_r[1] <= 4'd0;	
			mem_r[2] <= 4'd0;	
			mem_r[3] <= 4'd0;	
			mem_r[4] <= 4'd0;	
			mem_r[5] <= 4'd0;	
			mem_r[6] <= 4'd0;	
			mem_r[7] <= 4'd0;	
			mem_r[8] <= 4'd0;	
			mem_r[9] <= 4'd0;	
		end  
		else if(state_c == SHIFT)begin
			mem_r[0] <= {mem_w[0][2:0],din_r[BIN_W-1]};		
			mem_r[1] <= {mem_w[1][2:0],mem_w[0][3]   };	
			mem_r[2] <= {mem_w[2][2:0],mem_w[1][3]   };	
			mem_r[3] <= {mem_w[3][2:0],mem_w[2][3]   };	
			mem_r[4] <= {mem_w[4][2:0],mem_w[3][3]   };	
			mem_r[5] <= {mem_w[5][2:0],mem_w[4][3]   };	
			mem_r[6] <= {mem_w[6][2:0],mem_w[5][3]   };	
			mem_r[7] <= {mem_w[7][2:0],mem_w[6][3]   };	
			mem_r[8] <= {mem_w[8][2:0],mem_w[7][3]   };	
			mem_r[9] <= {mem_w[9][2:0],mem_w[8][3]   };	
		end
		else ;
	end //always end
	
	//组合逻辑近乎没有时延
	assign mem_w[0] = (mem_r[0] > 4'd4) ? (mem_r[0] + 4'd3) : mem_r[0];
	assign mem_w[1] = (mem_r[1] > 4'd4) ? (mem_r[1] + 4'd3) : mem_r[1];
	assign mem_w[2] = (mem_r[2] > 4'd4) ? (mem_r[2] + 4'd3) : mem_r[2];
	assign mem_w[3] = (mem_r[3] > 4'd4) ? (mem_r[3] + 4'd3) : mem_r[3];
	assign mem_w[4] = (mem_r[4] > 4'd4) ? (mem_r[4] + 4'd3) : mem_r[4];
	assign mem_w[5] = (mem_r[5] > 4'd4) ? (mem_r[5] + 4'd3) : mem_r[5];
	assign mem_w[6] = (mem_r[6] > 4'd4) ? (mem_r[6] + 4'd3) : mem_r[6];
	assign mem_w[7] = (mem_r[7] > 4'd4) ? (mem_r[7] + 4'd3) : mem_r[7];
	assign mem_w[8] = (mem_r[8] > 4'd4) ? (mem_r[8] + 4'd3) : mem_r[8];
	assign mem_w[9] = (mem_r[9] > 4'd4) ? (mem_r[9] + 4'd3) : mem_r[9];

	assign bcd_res = {mem_r[9],mem_r[8],mem_r[7],mem_r[6],mem_r[5],mem_r[4],mem_r[3],mem_r[2],mem_r[1],mem_r[0]};

	always @(posedge Clk or negedge Rst_n)begin 
		if(!Rst_n)begin
			bcd_vld <= 1'b0;
		end  
		else begin
			bcd_vld <= (state_c == DONE);
		end
	end //always end
	
	always @(posedge Clk or negedge Rst_n)begin 
		if(!Rst_n)begin
			Bcd_data <= 'd0;
		end  
		else if(state_c == DONE)begin
			Bcd_data <= bcd_res[BCD_W-1:0];
		end  
		else begin
			Bcd_data <= Bcd_data;
		end
	end //always end
	
endmodule
//仿真测试文件
/* ================================================ *\
		Filename    ﹕ tb_binary2bcd.v
		Author      ﹕ Adolph
		Description ﹕ 
		Called by   ﹕ 
Revision History    ﹕ 2023-07-07 11:50:10
					Revision 1.0
			Email﹕ adolph1354238998@gamil.com
			Company﹕ AWCloud...Std 
\* ================================================ */ 

`timescale 1ns/1ns 		//仿真系统时间尺度定义

`define clk_period 20  	//时钟周期宏定义	

module tb_binary2bcd; 
//激励信号定义  
	reg				Clk		; 
	reg				Rst_n	; 
	reg		[31:00] bin_data; //
	reg			 	Start 	; //
	
//响应信号定义	  
// 	wire 	[24:00]	bcd_data;	

//实例化
	binary2bcd #(.BIN_W (32), .BCD_W(40)) BIN2BCD(
		/*input  					*/.Clk		(Clk	 ), //system clock 50MHz
		/*input  			 		*/.Rst_n	(Rst_n	 ), //reset, low valid	
		/*input						*/.Start	(Start	 ), //
		/*input 	   [BIN_W-1:00]	*/.Bin_data (bin_data), //
		/*output reg				*/.bcd_vld	(), //	
		/*output reg [BCD_W-1:00]	*/.Bcd_data ()  //
	);

//产生时钟							       		 
	initial Clk = 1'b0;		       		 
	always #(`clk_period / 2) Clk = ~Clk;  		 

//产生激励	 
	initial  begin	 
		Rst_n = 1'b0;	 
		bin_data = 0;
		Start = 1'b0;
		#(`clk_period * 1 + 3);	 
		Rst_n = 1'b1;	 
		repeat(30)begin
			bin_data = {$random} % 99999;
			Start = 1'b1;
			#`clk_period Start = 1'b0;
			@(negedge BIN2BCD.bcd_vld);
			#`clk_period;
		end
		#(`clk_period * 20); 
		$stop(2); 
	end	 

endmodule

3-3、仿真测试

modelsim仿真验证
在这里插入图片描述
至此,结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/731013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JS 实现CSV文件转换SQL文件小工具

一. 需求 最近在项目中遇到一个问题&#xff0c;客户提供的数据是CSV格式的&#xff0c; 需要将CSV文件中的数据转换为SQL语句文件。 &#x1f605;由于本人不会Excel的vba编程&#xff0c;因此决定使用JS来实现。 二. 实现思路 提供一个文件上传框&#xff0c;支持多文件上…

微信小程序全局配置详解

通过全局配置实现的效果 开发者 微信公众平台 登录网址 https://mp.weixin.qq.com/ 注册网址 https://mp.weixin.qq.com/cgi-bin/wx?token&langzh_CN 微信小程序开发者工具 下载地址 https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 小…

WPF grid控件定义行和列

在此已经学习了wpf Grid控件&#xff0c; WPF布局控件Grid的基本使用 - 使用kaxaml_bcbobo21cn的博客-CSDN博客 下面继续学习&#xff1b; 定义3行3列的基本代码如下&#xff1b;为了看清效果&#xff0c;设置 ShowGridLines"True"&#xff1b; <Grid ShowGrid…

Tkinter_鼠标选中样式

前言 使用tkinter库创建窗口应用程序示例&#xff0c;包含不同鼠标样式标签。 一、方法 import tkinter as tkclass Mouse_Style:def __init__(self):self.root tk.Tk()self.root.title(样式)self.root.geometry("200x5201100150")self.interface()def interface(…

【G431】多路ADC+DMA采集

文章目录 前言1.CubeMx的配置步骤3.测试代码4.演示效果 总结 前言 之前蓝桥杯程序中使用的是查询方式的ADC&#xff0c;缺点是当采集通道多的时候会导致CPU速率变低从而导致查询ADC代码之后的程序会被阻塞。而DMA就不会&#xff0c;DMA会绕开CPU直接传输。 1.CubeMx的配置步骤…

GDB 查看、修改变量

1、info args : 查看函数的入参内容 2、set print null-stop :遇到无效的字符就不显示出来了 3、set print pretty :让结构体以定义的形式展示出来&#xff0c;一个字段一行 4、 set print arry on :让数组中的元素每个占一行显示 5、 p sizeof(xxx) : 查看xxx的大小&#xff…

STM32 DSP库CUBEMX配置+FFT频率计算

文章目录 前言一、DSP库添加1.1 加一个define1.2 添加文件路径1.3 主函数 二、FFT运算求频率2.1 初始版本版本2 总结 前言 使用DSP中的函数加快计算。 本文首先讲述如何通过添加dsp库。 再讲述使用DSP库进行实数FFT运算。&#xff08;FFT运算用到了前面讲述的STM32CubeMX-ADC …

mysql 安装

常用存储引擎功能对比&#xff1a; mysql 安装流程&#xff1a; 如果直接本地安装&#xff0c;就只需要安装好然后配置环境变量就行了&#xff0c;my.ini文件会自动帮你写好&#xff0c;如果是zip压缩包安装就需要自己写my.ini文件&#xff0c;下面详细介绍zip压缩包安装 下载…

提示工程的前世今生

原文链接&#xff1a;芝士AI吃鱼 通过提示进行情境学习 在生物学中&#xff0c;涌现是一种令人难以置信的特性&#xff0c;由于相互作用的结果&#xff0c;各个部分聚集在一起&#xff0c;表现出新的行为&#xff08;称为涌现&#xff09;&#xff0c;这是你在较小的尺度上看不…

分别基于红黑树、timefd、多级时间轮实现定时器

文章目录 一、定时器的应用二、定时器的触发方式2.1 网络事件和定时事件在一个线程中处理2.2 二、定时器的设计2.1 接口设计2.2 数据结构设计2.2.1 红黑树2.2.3 最小堆2.2.4 时间轮 三、利用红黑树实现定时器3.1 数据结构3.2 接口实现3.2.1 初始化定时器3.2.2 添加定时器3.2.3 …

【CPU】关于x86、x86_64/x64、amd64和arm64/aarch64

为什么叫x86和x86_64和AMD64? 为什么大家叫x86为32位系统&#xff1f; 为什么软件版本会注明 for amd64版本&#xff0c;不是intel64呢&#xff1f; x86是指intel的开发的一种32位指令集&#xff0c;从386开始时代开始的&#xff0c;一直沿用至今&#xff0c;是一种cisc指令…

Github 标星68.5K,不愧是阿里P8架构师整理的 Java 面试复盘笔记

Java 面试 2021 已经过半&#xff0c;不知道大家在今年的金三银四是否拿到了自己理想的 Offer&#xff1f;大家的技术面一共面了多少轮&#xff1f;作为一名程序员&#xff0c;技术面试是不可避免的一个环节&#xff0c;一般技术面试官都会通过自己的方式去考察程序员的技术功…

Java性能诊断利器:arthas详细教程

目录 1.概述 2.使用 2.1.安装使用 2.2.启动 2.3.全局监控 2.4.方法级别的监控 2.4.1.插件 2.4.2.watch 2.3.3.trace 2.3.4.stack 2.4.线上问题定位 2.4.1.反编译 2.4.2.CPU占用率 2.4.3.死锁 1.概述 arthas是Alibaba推出的一款JVM性能诊断调优工具&#xff0c;主…

C++之代理模式

目录 模式思想 简介 组成 优点 代码实现 情景 如果不使用代理的话&#xff1a; 加代理的话&#xff1a; 结果 模式思想 简介 代理模式&#xff1a; 通过代理类&#xff0c;来控制实际对象的访问权限。 在某些情况下&#xff0c;一个对象不适合或者不能直接引用另…

深入理解java虚拟机精华总结:硬件的效率与一致性、Java内存模型、Java与线程、Java与协程

深入理解java虚拟机精华总结&#xff1a;硬件的效率与一致性、Java内存模型、Java与线程、Java与协程 硬件的效率与一致性Java内存模型主内存与工作内存内存间交互操作对于volatile型变量的特殊规则针对long和double型变量的特殊规则原子性、可见性与有序性原子性可见性有序性 …

数学建模之灰色预测方法

数学建模之灰色预测方法 目录灰色关联度矩阵关联系数关联矩阵 GM(1,1)模型相关原理matlab程序 目录 灰色关联度矩阵 关联系数 计算关联系数公式 步骤 第一步 第二步 求参考数列和待比较数列矩阵数值做差之后的最小值和最大值 第三步利用公式计算关联度系数&#xff0c;其中将…

【C++修炼之路】32.智能指针

每一个不曾起舞的日子都是对生命的辜负 智能指针 一.为什么需要智能指针&#xff1f;二.智能指针解决new抛异常的示例三.智能指针的使用及其原理3.1 RAII3.2 SmartPtr存在的问题3.3 std::auto_ptr3.4 std::unique_ptr3.5 std::shared_ptrstd::shared_ptr的基本设计std::shared_…

海明码(汉明码)原理及其计算方法

海明码&#xff08;汉明码&#xff09;是一种利用奇偶性检测和纠正错误的编码方法。在传输和储存数据时&#xff0c;可能会发生传输错误或数据损坏。海明码通过在数据中添加冗余位来检测错误并进行纠正&#xff0c;提高了传输和存储数据的可靠性。 基本原理&#xff1a;将原始…

【数据结构复习】汉诺塔:快速回忆汉诺塔问题

题目 题解 众所周知这是一个递归问题&#xff08; 我们只需要注意两点&#xff1a;①什么时候退出递归 ②怎么从n-1推出n ①什么时候退出递归&#xff1a;很明显啦&#xff0c;n1的时候&#xff0c;我们直接把A位置的唯一盘子移到C上&#xff0c;大功告成。 ②怎么从n-1推出n…

Vision Pro销售策略曝光,面罩/头带/屈光镜片加大零售难度

彭博社Mark Gurman再次发布了关于苹果Vision Pro的销售策略&#xff0c;以及零售方面的难题。 一、销售计划和策略 1&#xff0c;2024年初先在美国部分门店销售&#xff0c;仅线下购买&#xff0c;线上暂不开放。购买方式是先线上预约&#xff08;可能要提供面部扫描图、眼镜…