LUT乘法器

LUT乘法器又称为查表法乘法器,就是先把各种各样的结果储存在一个表中,然后乘法的结果以“查表”的方式取得。

查表乘法器之所以被称为快速乘法器,因为查表乘法器只要用些许时钟去查表就可以求得乘法的结果。反之,非查表乘法器需要许多时钟用于乘法的运算。

查找表乘法器是“以空间换时间”的乘法器,因此查找表很消耗空间。

Quarter Square乘法查表

公式: ab=\left ( a+b \right )^{2}/4-\left ( a-b \right )^{2}/4

reg[8:0]I1,I2;
case(i)
	0:
	begin
		I1<={A[7],A}+{B[7],B};			//C=A+B
		I2<={A[7],A}+{~B[7],(~B+1'b1)};	//C=A-B
		//正数我们直接用二进制原码表示,负数用补码表示,按位取反末位加一
		i<=i+1'b1;
	end
	1: //在该步骤中,我们将负值全部转换成正值(因为正值的平方与负值的平方相等)从而正负值可以公用一个查找表
	begin 
		I1<=I1[8]?(~I1+1'b1):I1;
		I2<=I2[8]?(~I2+1'b1):I2;
		i<=i+1'b1;
	end

笔者的QuartusII下载失败,很是无语。天亡我哉?非也非也。主要目的是从中学到时序和流水线操作等知识,后期将知识移植到我用Vivado开发ZYNQ上。

//lut_multiplier_module.v 功能:取得I1=A+B, I2=A-B,然后将I1和I2分别转换为正值,再将I1和I2送到各自的查找表,
//根据得出的查找结果Q1_Sig与Q2_Sig的结果执行相减
module lut_multiplier_module
(
	input clk,
	input rst_n, 
	input Start_Sig,
	input [7:0]A, 
	input [7:0]B,
	
	
	output Done_Sig,
	output [15:0]Product,
	
	//仿真输出
	output [8:0]SQ_I1_Sig,
	output [8:0]SQ_I2_Sig,
	output [15:0]SQ_Q1_Sig,
	output [15:0]SQ_Q2_Sig
);

	wire[15:0]Q1_Sig;
	wire[15:0]Q2_Sig;
	
	reg[3:0]i;
	reg[8:0]I1;
	reg[8:0]I2;
	reg[15:0]Data;
	reg isDone;
	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin 
				i<=4'd0;
				I1<=9'd0;
				I2<=9'd0;
				Data<=16'd0;
				isData<=1'b0;
			end
		else if(Start_Sig)
			case(i)
				0:
				begin 
					I1<={A[7],A}+{B[7],B};
					I2<={A[7],A}+{~B[7],(~B+1'b1)};
					i<=i+1'b1;
				end
				1:
				begin //将I1I2都转换成正值
					I1<=I1[8]?(~I1+1'b1):I1;
					I2<=I2[8]?(~I2+1'b1):I2;
					i<=i+1'b1;
				end
				2:
				beign i<=i-1'b1;end
				3://Q1_Sig-Q2_Sig
				begin Data<=Q1_Sig+(~Q2_Sig+1'b1);i<=i+1'b1;end
				4:
				begin isDone<=1'b1;i<=i+1'b1;end
				5:
				begin isDone<=1'b0;i<=4'd0;end
			endcase
		
//U1是给I1使用的查表		
		lut_module 	U1
		(
			.clk(clk),
			.rst_n(rst_n),
			.addr(I1[7:0]),
			.Q(Q1_Sig)
		);
//U2是给I2使用的查表		
		lut_module U2
		(
			.clk(clk),
			.rst_n(rst_n),
			.addr(I2[7:0]),
			.Q(Q2_Sig)
		);
	assign Done_Sig=isDone;
	assign Product=Data;	//product由Data寄存器驱动

//仿真输出
	assign SQ_I1_Sig=I1;
	assign SQ_I2_Sig=I2;
	assign SQ_Q1_Sig=Q1_Sig;
	assign SQ_Q2_Sig=Q2_Sig;
endmodule
//lut_multiplier_module.vt
module lut_multiplier_module_simulation();
	reg clk;
	reg rst_n;
	reg Start_Sig;
	reg[7:0]A;
	reg[7:0]B;
	
	wire Done_Sig;
	wire[15:0]Product;
	
	wire[8:0]SQ_I1_Sig;
	wire[8:0]SQ_I2_Sig;
	wire[15:0]SQ_Q1_Sig;
	wire[15:0]SQ_Q2_Sig;
	
	lut_multiplier_module U1
	(
		.clk(clk),
		.rst_n(rst_n),
		.Start_Sig(Start_Sig),
		.A(A),
		.B(B),
		.Done_Sig(Done_Sig),
		.Product(Product),
		.SQ_I1_Sig(SQ_I1_Sig),
		.SQ_I2_Sig(SQ_I2_Sig),
		.SQ_Q1_Sig(SQ_Q1_Sig),
		.SQ_Q2_Sig(SQ_Q2_Sig)
	);
	
	initial
	begin 
		rst_n=0;rst_n=1;#10;
		clk=0;forever#10clk=~clk;
	end
	
	reg[3:0]i;
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			begin 
				i<=4'd0;
				Start_Sig<=1'b0;
				A<=8'd0;
				B<=8'd0;
			end
		else
			case(i)
				0://A=-127,B=127
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1;end
				else begin A<=8'b10000001;B<=8'd127;Start_Sig<=1'b1;end
				
				1://A=2,B=-4
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1;end
				else begin Start_Sig<=1'b0; i<=i+1'b1; end
				else begin A<=8'd2;B<=8'b11111100;Start_Sig<=1'b1;end
				
				2:
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1;end
				else begin A<=8'd10;B<=8'd100;Start_Sig<=1'b1;end
			
			
				3:
				if(Done_Sig)begin Start_Sig<=1'b0;i<=i+1'b1;end
				else begin A<=8'b10000001;B<=8'b10000001;Start_Sig<=1'b1;end
				
				4:
				i<=4'd4;
			endcase
endmodule 

				
				

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小菜鸡变形记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值