verilog 8位乘法器构建(附门级电路失败构建)

8位乘法器的构建

实验原理

8位乘法器有多种构建方式

  1. 门级建模:先构建一位全加器,构建出16位全加器,构建1*8乘法器,将乘数a每一位与另一个乘数b相乘,结果加到最终结果里,然后左移一位进行下一步。(正文附录有失败方法可供参考)
  2. 数据流建模:乘数a每一位与乘数b相与,再将结果移相当的位相加,此方法太麻烦且很难使用循环,所以此报告不讨论。
  3. 行为建模:抽象算法,取出乘数a的一位,如果为1,则d相加结果,否则不进行任何操作,最后d左移一位(一开始把b的值赋给b)

行为级建模乘法器

verilog代码实现

module a8bitmulti(a,b,c,out1,out2,out3,out4);
	   input [7:0]a,b;//输入
	   output reg[15:0]c;
	   integer i,b1;
	   output reg[7:0] out1,out2,out3,out4;
     always @(a,b)
            begin
	           b1=a;
	           c = 16'b0000_0000_0000_0000;//结果赋初值
	           for (i=0;i<8;i=i+1)
		          begin
			         if(b[i] == 1) //如果为一就相加
				    c = c + b1;
		                  b1 = b1*2;//移位
		          end 
            end
endmodule

测试激励文件

verilog代码

// 8位乘法器的测试激励
`timescale 1us/1us
module test_multiple_8x8;
	reg[7:0] X,Y,c1,c2,c3,c4;
	wire[15:0] Z;
	
	a8bitmulti test(X,Y,Z);
	
	initial
	begin![]()
		X = 8'b00000000; Y = 8'b00000000;
	#10 X = 8'b01010100; Y = 8'b00000000;
	#10 X = 8'b10011010; Y = 8'b01010111;
	#10 X = 8'b10100111; Y = 8'b10111011;
	#10 X = 8'b11111111; Y = 8'b00000000;
	#10 X = 8'b11111111; Y = 8'b01111010;
	#10 X = 8'b11111111; Y = 8'b11111111;
	#10 $stop;
	end
	
	initial
	begin
	$monitor($time,"X = %8b, Y = %8b",X,Y,"===== Z = %16b",Z);
	end
endmodule

波形图

结果分析

8位乘法器构建完成

数码管接入电路

veirlog代码

always @(c) 
begin
//first segment
	case(c[3:0])
	4'h0: out1[7:0]=8'b1000_0000;
	4'h1: out1[7:0]=8'b1111_1001;
	4'h2: out1[7:0]=8'b1010_0100;
	4'h3: out1[7:0]=8'b1011_0000;
	4'h4: out1[7:0]=8'b1001_1001;
	4'h5: out1[7:0]=8'b1001_0010;
	4'h6: out1[7:0]=8'b1000_0010;
	4'h7: out1[7:0]=8'b1111_1000;
	4'h8: out1[7:0]=8'b1000_0000;
	4'h9: out1[7:0]=8'b1001_0000;
	default: out1[7:0]=8'b1111_1111;
	endcase

	case(c[7:4])
	4'h0: out2[7:0]=8'b1000_0000;
	4'h1: out2[7:0]=8'b1111_1001;
	4'h2: out2[7:0]=8'b1010_0100;
	4'h3: out2[7:0]=8'b1011_0000;
	4'h4: out2[7:0]=8'b1001_1001;
	4'h5: out2[7:0]=8'b1001_0010;
	4'h6: out2[7:0]=8'b1000_0010;
	4'h7: out2[7:0]=8'b1111_1000;
	4'h8: out2[7:0]=8'b1000_0000;
	4'h9: out2[7:0]=8'b1001_0000;
	default: out2[7:0]=8'b1111_1111;
	endcase
//third segment
	case(c[11:8])
	4'h0: out3[7:0]=8'b1000_0000;
	4'h1: out3[7:0]=8'b1111_1001;
	4'h2: out3[7:0]=8'b1010_0100;
	4'h3: out3[7:0]=8'b1011_0000;
	4'h4: out3[7:0]=8'b1001_1001;
	4'h5: out3[7:0]=8'b1001_0010;
	4'h6: out3[7:0]=8'b1000_0010;
	4'h7: out3[7:0]=8'b1111_1000;
	4'h8: out3[7:0]=8'b1000_0000;
	4'h9: out3[7:0]=8'b1001_0000;
	default: out3[7:0]=8'b1111_1111;
	endcase
//fourth segment
	case(c[15:12])
	4'h0: out4[7:0]=8'b1000_0000;
	4'h1: out4[7:0]=8'b1111_1001;
	4'h2: out4[7:0]=8'b1010_0100;
	4'h3: out4[7:0]=8'b1011_0000;
	4'h4: out4[7:0]=8'b1001_1001;
	4'h5: out4[7:0]=8'b1001_0010;
	4'h6: out4[7:0]=8'b1000_0010;
	4'h7: out4[7:0]=8'b1111_1000;
	4'h8: out4[7:0]=8'b1000_0000;
	4'h9: out4[7:0]=8'b1001_0000;
	default: out4[7:0]=8'b1111_1111;
	endcase

end

附录:门级8位乘法器的构建

由于上次实验有8位全加器的构建模块,所以一开始我采用了模块化的思想,构建出16位全加器和1*8的乘法器,再逐项逐项移位相加

但门级电路不能使用for循环和if判断(大坑),如果在门级电路里使用会变成generate for循环段 和generate if 判断段
但最终失败在门线电路的赋值,经历过无数的报错后放弃了这一设想

verilog代码

module A16bitmulit(A,B,c); //1*8乘法器
	input [15:0]A;
	input B;
	output [15:0]c;
	and (c[0],A[0],B);
	and (c[1],A[1],B);
	and (c[2],A[2],B);
	and (c[3],A[3],B);
	and (c[4],A[4],B);
	and (c[5],A[5],B);
	and (c[6],A[6],B);
	and (c[7],A[7],B);
	and (c[8],A[8],B);
	and (c[9],A[9],B);
	and (c[10],A[10],B);
	and (c[11],A[11],B);
	and (c[12],A[12],B);
	and (c[13],A[13],B);
	and (c[14],A[14],B);
	and (c[15],A[15],B);
	
endmodule	
module fulladder(Sum,Co,A,B,Ci);//一位全加器
	input A,B,Ci;
	output Sum,Co;
	wire 	S1,S2,S3;
		xor (Sum,A,B,Ci);
		and (S1,A,B);
		xor (S2,A,B);
		and	(S3,Ci,S2);
		or  (Co,S1,S3);
endmodule		

module bitfulladder(Sum,A,B);//16位全加器
	input [15:0] A,B;
	wire [15:0] Co;
	output [15:0]Sum;
		fulladder	UO(Sum[0],Co[0],A[0],B[0],0);
		fulladder	U1(Sum[1],Co[1],A[1],B[1],Co[0]);
		fulladder 	U2(Sum[2],Co[2],A[2],B[2],Co[1]);
		fulladder	U3(Sum[3],Co[3],A[3],B[3],Co[2]);
		fulladder	U4(Sum[4],Co[4],A[4],B[4],Co[3]);
		fulladder	U5(Sum[5],Co[5],A[5],B[5],Co[4]);
		fulladder	U6(Sum[6],Co[6],A[6],B[6],Co[5]);
		fulladder	U7(Sum[7],Co[7],A[7],B[7],Co[6]);
		fulladder	U8(Sum[8],Co[8],A[8],B[8],Co[7]);
		fulladder	U9(Sum[9],Co[9],A[9],B[9],Co[8]);
		fulladder 	U10(Sum[10],Co[10],A[10],B[10],Co[9]);
		fulladder	U11(Sum[11],Co[11],A[11],B[11],Co[10]);
		fulladder	U12(Sum[12],Co[12],A[12],B[12],Co[11]);
		fulladder	U13(Sum[13],Co[13],A[13],B[13],Co[12]);
		fulladder	U14(Sum[14],Co[14],A[14],B[14],Co[13]);
		fulladder	U15(Sum[15],Co[15],A[15],B[15],Co[14]);
endmodule

/*
module leftmove(A,B);//16位移位器
	input reg[15:0]A;
	output reg[15:0]B;
	
	B[15:1]=A[14:0];
	/*
	B[1] = A[0];
	B[2] = A[1];
	B[3] = A[2];
	B[4] = A[3];
	B[5] = A[4];
	B[6] = A[5];
	B[7] = A[6];
	B[8] = A[7];
	B[9] = A[8];
	B[10] = A[9];
	B[11] = A[10];
	B[12] = A[11];
	B[13] = A[12];
	B[14] = A[13];
	B[15] = A[14];
	
endmodule
*/
module eightbitmulit (A,B,C);//8位乘法器
/*
取出一位,如果为1,就结果左移一位后相加乘数,如果为0就全加0
*/
	input	[7:0] A,B;
	output  [15:0] C;
	reg [7:0] D;
	wire [15:0] B1,Co,E;
	initial 
	begin
	D = 8'b0000_0000;
	end
	assign B1 = {D,A};
	
	A16bitmulit D1(B1,B[0],E);
	bitfulladder X1(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D2(B1,B[1],E);
	bitfulladder X2(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D3(B1,B[2],E);
	bitfulladder X3(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D4(B1,B[3],E);
	bitfulladder X4(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D5(B1,B[4],E);
	bitfulladder X5(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D6(B1,B[5],E);
	bitfulladder X6(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D7(B1,B[6],E);
	bitfulladder X7(C,C,E);
	assign B1 = B1<<1;
	
	A16bitmulit D8(B1,B[7],E);
	bitfulladder X8(C,C,E);
	assign B1 = B1<<1;


endmodule

作者想说的话

其实8位乘法器思路非常简单,但整整花了我三天的时间去构建这个模型,原因在于我忽略了verilog是一门现实描述语言,得考虑现实的电路搭建。如果采用c语言那种软件的思路去编写很快能编写完成,但并不能成功。

你可能感兴趣的:(verilog)