当前位置:   article > 正文

FPGA乘法计算时位宽太大引起的路径延时解决方法_大位宽数据相乘 fpga

大位宽数据相乘 fpga

1、fpga进行乘法计算的方法

① 使用官方提供的IP核 Multipler

优点:使用最少的DSP资源,可以进行有符号,无符号数计算;位宽2-64bit可调。
缺点:最大位宽只有64bit,数据再大不支持(eg:s数据放大2^50后计算,数据位宽大于64)。

在这里插入图片描述

② 使用乘法号 * 计算

优点:数据位宽可以任意调整,使用多个DSP资源。
缺点:DSP资源使用浪费,同样位宽计算,使用DSP数可能大于使用IP核;有符号计算时需要使用signed标识寄存器内数据是有符号数,不然会被当作无符号数计算。

2、案例描述

计算数据 32bit * 64bit;使用IP核Multipler计算,编译过后报时序警告,打开Implemented Design可以看到
在这里插入图片描述
在Device窗口点击Routing Resources 可以看到这为实现这个乘法计算所经过的路径
在这里插入图片描述
在右边的窗口中也可以看到,此时路径延时为13.244ns.系统时钟100M。
在这里插入图片描述
路径延时过大,可能会使得数据在时钟沿到来后无法处于稳定状态,从而数据无法被所存,出现亚稳态,在资源使用紧张,时序要求严苛的时候会导致系统无法正确运行。

3、解决方法

为处理数据路径延时过大导致亚稳态的问题,我们可以将大位宽数据拆分成多个位宽的数据放到多个寄存器中分开计算,并将结果移位相加。

方案原理:求 data_A[63:0] * data_B[31:0] 。
①:取两个数据最高位作为符号位flag。
②:取两个数据的绝对值data_A_Abs = |data_A| ; data_B_Abs = |data_B| 。
③:将大位宽拆成多个小位宽数据:data_A_H = data_A_Abs [63:32] ; data_A_L = data_B_Abs [31:0]。
④:将拆分的数据相乘data_buff1 = data_A_H * data_B_Abs ; data_buff2 = data_A_L * data_B_Abs 。
⑤:移位相加 data_o = data_buff1 <<32 + data_buff2 ;
Verilog代码设计:

`timescale 1ns / 1ps

module	Calculate(
	input							clk					,
	input							rst_n				,
	
	input							Calculate_en		,	
	
	input	signed		[63:0]		data_A				,
	input	signed		[31:0]		data_B				,
	
	output	reg	signed	[95:0]		data_o				
    );
	reg								Calculate_en1		;
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n==0)
			Calculate_en1		<=	'b0					;
		else
			Calculate_en1		<=	Calculate_en		;
	end
	assign	Calculate_en_raising	= ~ Calculate_en1 & Calculate_en;
	localparam					idle		=	0		,
								st1			=	1		,
								st2			=	2		,
								st3			=	3		;
	reg				[3:0]		cur_st					;
	
	reg				[31:0]		data_A_H				;
	reg				[31:0]		data_A_L				;
	
	reg				[63:0]		data_buff1 				;
	reg				[63:0]		data_buff2 				;

	reg				[63:0]		data_A_Abs				;
	reg				[31:0]		data_B_Abs				;
	reg							flag1					;
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n==0)
		begin
			data_A_Abs				<=	'b0					;
			data_B_Abs				<=	'b0					;
			data_A_H				<=	'b0					;
			data_A_L				<=	'b0					;
			
			data_buff1				<=	'b0					;
			data_buff2				<=	'b0					;
			data_o					<=	'b0					;
			flag1					<=	'b0					;
			
			cur_st					<=	idle				;
		end
		else
		begin
			case(cur_st)
			idle	:begin
				if(PR_en_raising)
				begin
					PR_out_en		<=	'b0							;
					case({data_B[31],data_A[63]})
					2'b00:	//++
					begin
						flag1		<=	'b0							;
						data_B_Abs	<=	data_B						;
						data_A_Abs	<=	data_A						;
					end
					2'b01:	//+-
					begin
						flag1		<=	'b1							;
						data_B_Abs	<=	data_B						;
						data_A_Abs	<=	- data_A					;
					end
					2'b10:	//-+
					begin
						flag1		<=	'b1							;
						data_B_Abs	<=	- data_B					;
						data_A_Abs	<=	data_A						;
					end
					2'b11:	//--
					begin
						flag1		<=	'b0							;
						data_B_Abs	<=	- data_B					;
						data_A_Abs	<=	- data_A					;
					end
					endcase

					cur_st			<=	st1							;
				end
				else
					cur_st			<=	idle						;
			end
			st1		:begin
				data_A_H			<=	data_A_Abs[63:32]			;
				data_A_L			<=	data_A_Abs[31:0]			;
				cur_st				<=	st2							;
			end
			st2		:begin			
				data_buff1			<=	data_B_Abs * data_A_H 		;
				data_buff2			<=	data_B_Abs * data_A_L 		;
				cur_st				<=	st3							;
			end
			st3		:begin
				if(flag1)
					data_o			<=	-({{32{data_buff2[63]}},data_buff2} + {data_buff1,32'b0})	;
				else
					data_o			<=	{{32{data_buff2[63]}},data_buff2} + {data_buff1,32'b0}		;
				cur_st				<=	idle						;
			end
			default	:begin
				
			end
			endcase
		end
	end
	
	
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/979522
推荐阅读
相关标签
  

闽ICP备14008679号