FPGA实现二进制转BCD码

这篇具有很好参考价值的文章主要介绍了FPGA实现二进制转BCD码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

FPGA实现二进制转BCD码,FPGA学习,fpga开发,算法,bcd实现

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仿真验证
FPGA实现二进制转BCD码,FPGA学习,fpga开发,算法,bcd实现
至此,结束文章来源地址https://www.toymoban.com/news/detail-536388.html

到了这里,关于FPGA实现二进制转BCD码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于FPGA的3位二进制的乘法器VHDL代码Quartus 开发板

    名称:基于FPGA的3位二进制的乘法器VHDL代码Quartus  开发板(文末获取) 软件:Quartus 语言:VHDL 代码功能: 3位二进制的乘法器 该乘法器实现两个三位二进制的乘法,二极管LED2~LED0显示输入的被乘数,LED5~LED3显示乘数,数码管显示相应的十进制输入值和输出结果 本代码已在开

    2024年02月21日
    浏览(55)
  • verilog实现二进制转BCD码-加3移位法

    BCD码用4位二进制数表示一个十进制数,最常用的BCD码是8421码,用4’b0000-4’b1001表示十进制数字0-9,接下来默认BCD码就是8421码。 在FPGA中使用数码管时,段选信号不好记,所以我们用BCD码表示一个数码管的数值,将BCD码转化为段选信号驱动数码管,数码管驱动可以这篇文章:

    2024年02月06日
    浏览(60)
  • 【FPGA】Verilog:二进制并行加法器 | 超前进位 | 实现 4 位二进制并行加法器和减法器 | MSI/LSI 运算电路

    0x00 并行加法器和减法器 如果我们要对 4 位加法器和减法器进行关于二进制并行运算功能,可以通过将加法器和减法器以 N 个并行连接的方式,创建一个执行 N 位加法和减法运算的电路。 4 位二进制并行加法器 4 位二进制并行减法器

    2024年02月05日
    浏览(57)
  • 【FPGA】Verilog:计数器 | 异步计数器 | 同步计数器 | 2位二进制计数器的实现 | 4位十进制计数器的实现

    目录 Ⅰ. 实践说明 0x00 计数器(Counter) 0x01 异步计数器(Asynchronous Counter)

    2024年02月05日
    浏览(57)
  • 【FPGA仿真】Matlab生成二进制、十六进制的txt数据以及Vivado读取二进制、十六进制数据并将结果以txt格式保存

    在使用Vivado软件进行Verilog程序仿真时可能需要对模块输入仿真的数据,因此我们需要一个产生数据的方法(二进制或者十六进制的数据),Matlab软件是一个很好的工具,当然你也可以使用VS等工具。 以下分别给出了使用Matlab模拟产生二进制和十六进制数据的例子,例子仅供参

    2024年02月01日
    浏览(60)
  • [FPGA]用Verilog写一个简单三位二进制加法器和减法器

    加法器和减法器是数字电路中的基本组件,它们可以对二进制数进行算术运算。加法器可以将两个或多个二进制数相加,得到一个和和一个进位。减法器可以将两个二进制数相减,得到一个差和一个借位。加法器和减法器可以用来实现更高级的运算,例如乘法、除法、移位等

    2024年02月04日
    浏览(45)
  • 【FPGA】Verilog:时序电路设计 | 二进制计数器 | 计数器 | 分频器 | 时序约束

    前言: 本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例:计数器与分频器   ​​ 功能特性: 采用 Xilinx Artix-7 XC7A35T芯片  配置方式:USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度  存储器:2Mbit SRAM   N25Q064A SPI Flash(样图旧款为N25Q032A) 通用

    2024年02月02日
    浏览(62)
  • 用74LS73设计四位二进制加法计数器和8421BCD加法计数器

     (1)用2片74LS73实现该电路,由CP端输入单脉冲,设计并画出4位异步二进制加法计数器电路图。  (2)由CP端输入单脉冲,测试并记录Q1~Q4端状态及波形。 四位二进制加法计数器状态迁移表如下: Q 4n Q 3n Q 2n Q 1n Q 4n+1 Q 3n+1 Q 2n+1 Q 1n+1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0

    2024年02月10日
    浏览(90)
  • 二进制安全学习 第一天

    (仅用作自己学习)XMCVE 2020 CTF Pwn入门课程_哔哩哔哩_bilibili   屏幕剪辑的捕获时间: 2024/3/15 17:13     Terminal:终端 shell:区别于GUI的提供给系统的用户接口   为什么c和c++的市场占额会下不去? 很多编译型语言都存在,Gc:垃圾收集器,例如 go语言,虽然也能编译成二进制程

    2024年04月17日
    浏览(38)
  • 二进制学习(pwn)-shellcode

    安装好了pwntool、ROPgadget、onegadget以及pwngdb,读懂并手写脚本复现了上一篇中基于64位有后门的栈溢出漏洞,恭喜你少年,你已经完成二进制的筑基啦。接下来,我们要介绍的是栈溢出的第二种利用形式:基于shellcode的栈溢出。 在编程语言中要想获得系统执行权限,可以使用s

    2024年02月08日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包