首页 > 其他分享 >二进制转BCD8421码

二进制转BCD8421码

时间:2023-07-02 16:45:20浏览次数:47  
标签:wire 20 二进制 d3 BCD8421 data reg

8421码是BCD码中最常用的编码,使用4位二进制表示十进制数0~9,即0000~1001。例如十进制数12转二进制为1100,转化为8421码为0001 0010(十进制为18),两个编码相减得6。二进制转8421的规则是≥10就加6,否则不加6进行校正。

\[\begin{array}{r} 10010B\\ -1100B\\ \hline 0110B \end{array} \]

double dabble算法是先让要转换的二进制数左移一位(相当于乘2),原来的规则就变为了≥5就加3。

左移前的判断式:\(x≥10?+6:+0\),左移后变为\(2x≥10?+6:+0\),解出新的判断式\(x≥5?+3:+0\)

举个例子:将13转为8421码0001 0011

移位次数等于要转换的二进制位数。

使用Verilog实现20位二进制数转8421码

module bcd8421(
	input 	wire				clk,
	input 	wire				reset_n,
	
	input 	wire	[19:0] 		data,	//要转换的二进制数据,0~999_999需要20bit
	
	//分别输出6位
	output	reg		[3:0] 		unit,	//个位
	output	reg 	[3:0] 		ten,	//十位
	output	reg 	[3:0] 		hun,	//百位
	output	reg 	[3:0] 		tho,	//千位
	output	reg 	[3:0] 		t_tho,	//万位
	output	reg 	[3:0] 		h_tho	//十万位
);
	reg [43:0]	data_all;	//43~20是BCD码,19~0是要转换的二进制数据
							//低20位数据每次左移一位至高24位
	
	reg shift_flag;		//左移标志位
	reg [4:0] shift_cnt;	//移位计数,原来有20位二进制数要左移20次 
	
	//完成一次判断和移位操作后,计数加一
	always@(posedge clk or negedge reset_n)
		if(!reset_n)
			shift_cnt <= 5'b0;
		else if((shift_cnt == 5'd21) && (shift_flag == 1'b1))
			shift_cnt <= 5'b0;
		else if(shift_flag == 1'b1)
			shift_cnt <= shift_cnt + 1;
		else
			shift_cnt <= shift_cnt;
		
	always@(posedge clk or negedge reset_n)
		if(!reset_n)
			data_all <= 44'b0;
		else if(shift_cnt <= 5'd0)
			data_all <= {24'b0,data};
		else if((shift_cnt <= 5'd20) && (shift_flag == 1'b0))	//判断是否大于4,大于4则加3
			begin
				data_all[23:20]   <=  (data_all[23:20] > 4) ? (data_all[23:20] + 2'd3) : (data_all[23:20]);
				data_all[27:24]   <=  (data_all[27:24] > 4) ? (data_all[27:24] + 2'd3) : (data_all[27:24]);
				data_all[31:28]   <=  (data_all[31:28] > 4) ? (data_all[31:28] + 2'd3) : (data_all[31:28]);
				data_all[35:32]   <=  (data_all[35:32] > 4) ? (data_all[35:32] + 2'd3) : (data_all[35:32]);
				data_all[39:36]   <=  (data_all[39:36] > 4) ? (data_all[39:36] + 2'd3) : (data_all[39:36]);
				data_all[43:40]   <=  (data_all[43:40] > 4) ? (data_all[43:40] + 2'd3) : (data_all[43:40]);
			end
		else if((shift_cnt <= 5'd20) && (shift_flag == 1'b1))
			data_all <= data_all << 1;
		else
			data_all <= data_all;
	
	always@(posedge clk or negedge reset_n)
		if(!reset_n)
			shift_flag <= 1'b0;
		else 
			shift_flag <= ~shift_flag;	//每次上升沿状态取反,0:大于4加三,1:执行左移操作
			
	//当计数器等于20时,移位判断操作完成,对各个位数的BCD码进行赋值		
	always@(posedge clk or negedge reset_n)
		if(!reset_n) begin
			unit	<= 4'b0;	
			ten		<= 4'b0;	
			hun		<= 4'b0;	
			tho		<= 4'b0;	
			t_tho	<= 4'b0;
			h_tho	<= 4'b0;
		end
		else if(shift_cnt == 5'd21) begin	//shift_cnt等于21时表示所有操作已经完成
			unit	<= data_all[23:20];	
			ten		<= data_all[27:24];	
			hun		<= data_all[31:28];	
			tho		<= data_all[35:32];	
			t_tho	<= data_all[39:36];
			h_tho	<= data_all[43:40];
		end

endmodule

编写testbench仿真文件

`timescale 1ns/1ns

module bcd8421_tb();
	reg				clk;
	reg				reset_n;
	reg     [19:0]		data;
	wire	[3:0] 		unit;	//个位
	wire 	[3:0] 		ten;	//十位
	wire 	[3:0] 		hun;	//百位
	wire 	[3:0] 		tho;	//千位
	wire 	[3:0] 		t_tho;	//万位
	wire 	[3:0] 		h_tho;	//十万位
	
	initial
    begin
        clk     =   1'b1;
		data    =   20'd123456;
        reset_n   <=  1'b0;
        #100
        reset_n   <=  1'b1;
    end

	//clk:产生时钟
	always	#10 clk <=  ~clk;
	
	bcd8421 bcd8421_inst(
		.clk			(clk),
		.reset_n		(reset_n),
		.data			(data),	//要转换的二进制数据,0~999_999需要20bit
		.unit			(unit),	//个位
		.ten			(ten),	//十位
		.hun			(hun),	//百位
		.tho			(tho),	//千位
		.t_tho			(t_tho),	//万位
		.h_tho			(h_tho)	//十万位
	);
	
endmodule

将十进制数123456转为BCD码,仿真结果如图所示。

参考资料:野火FPGA

标签:wire,20,二进制,d3,BCD8421,data,reg
From: https://www.cnblogs.com/qianxiaohan/p/17520946.html

相关文章

  • 背包问题-二进制优化
    Smiling&Weeping----不讨好所有冷漠不辜负所有热爱 #[NOIP1996提高组]砝码称重 ##题目描述 设有$1\mathrm{g}$、$2\mathrm{g}$、$3\mathrm{g}$、$5\mathrm{g}$、$10\mathrm{g}$、$20\mathrm{g}$的砝码各若干枚(其总重$\le......
  • 401. 二进制手表
    这里可以通过遍历的方式做出来。i从0~1111111111进行遍历,如果1的个数等于要求的个数tournedOn,此时进一步判断时钟位和分钟为是否符合要求,满足要求则放入结果容器中。classSolution{public:vector<string>readBinaryWatch(intturnedOn){vector<string>res;......
  • 2023.6.29 重构 2 行二进制矩阵
    考虑贪心策略。每一列,把1优先放在lower和upper两行中较大的那一行上。implSolution{pubfnreconstruct_matrix(upper:i32,lower:i32,colsum:Vec<i32>)->Vec<Vec<i32>>{letn=colsum.len();let(mutupper,mutlower)=(upper,l......
  • 力扣---1253. 重构 2 行二进制矩阵
    给你一个 2 行 n 列的二进制数组:矩阵是一个二进制矩阵,这意味着矩阵中的每个元素不是 0 就是 1。第 0 行的元素之和为 upper。第 1 行的元素之和为 lower。第 i 列(从 0 开始编号)的元素之和为 colsum[i],colsum 是一个长度为 n 的整数数组。你需要利用 ......
  • 如何配置mysql主从复制中的二进制日志传输?
    要配置MySQL主从复制中的二进制日志传输,需要进行以下步骤:确保主服务器的二进制日志功能已启用:在主服务器的配置文件(通常是my.cnf或my.ini)中,找到并确认以下配置项已启用:log_bin=ONbinlog_format=ROWlog_bin表示启用二进制日志功能,binlog_format设置......
  • 浮点数-Float-Double转二进制在线工具
    浮点数-Float-Double转二进制Float转二进制,Double转浮点数-Float-Double转二进制https://tooltt.com/floatconverter/在线单双精度(Float,Double)浮点数转二进制浮点数,是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。具体的说,这个实数由一......
  • C++学习---qt的公有类、私有类、Q_Q、Q_D、二进制兼容
    1、二进制兼容如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的。如果不能保证库的二进制兼容性,就意味着每次发布库的新版本时,依赖该库的所有程序都必须重新编译才能正常运行。2、公有类、私有类是解决......
  • 1、Elasticsearch单机与集群的安装(包安装、二进制安装与Docker安装)
    ElasticsearchElasticsearch是一个实时的全文搜索,存储库和分析引擎https://www.elastic.co/cn/what-is/elasticsearchElasticsearch在速度和可扩展性方面都表现出色,而且还能够索引多种类型的内容,可用于多种场景:应用程序搜索网站搜索企业搜索日志处理和分析基础设施指标和......
  • Linux MySQL 5.7二进制 小版本升级
    LinuxMySQL5.7二进制小版本升级LinuxMySQL5.7二进制小版本升级MySQL5.7二进制安装在Unix/Linux上升级时,分为就地和逻辑升级方法。1就地升级就地升级包括关闭旧的MySQL服务器,用新的MySQL服务器替换旧的MySQL二进制文件或软件包,在现有数据目录上重新启动MySQL,以及运行mys......
  • mysql的二进制日志和中继日志文件的分析、恢复、清理
    1.mysql的二进制日志目录1.mysql的二进制日志1.1.概述1.2.MySQL中二进制日志(binlog)3种不同的格式(Mixed,Statement,Row)1.2.1.Row1.2.2.Statement1.2.3.Mixed1.3.binglog格式设置1.4.二进制日志文件的清理1.4.1.自动清理binglog1.4.1.修改过期时间1.4.2.手动清除......