Icarus Verilog安装&&计组实验ALU(32位算术逻辑运算器)

1.安装软件

下载地址:http://bleyer.org/icarus/

配置环境变量

手动添加C:\iverilog\gtkwave\bin 和 C:\iverilog\bin(默认C盘)

 

 2.编写 Verilog代码和test

test中格外添加

$dumpfile("test.vcd");
$dumpvars;

3.编译仿真

1.win +R ,输入cmd 打开命令行;

2.cd+代码所在文件夹    进入.v所在文件夹

3.执行 iverilog -o dsn alu32_tb.v得到文件dsn

4.执行vvp dsn

4.用gtkwave打开vcd仿真波形

执行 gtkwave test.vcd 打开仿真波形

5. 计组实验alu代码文件

1.alu32.v

`include"ALU1.v"
`include"ALU2.v"
`include"ALU3.v"
`include"ALU4.v"
module alu32(a,b,op,out,z,c,n,ov,clk);
	parameter width=32;
	input [width-1:0] a,b;
	input [3:0] op;
	input clk;
	output reg [width-1:0] out;
	output reg z,c,n,ov;
	wire [width-1:0] out1,out2,out3,out4;
	wire z1,z2,z3,z4,c1,c2,c3,c4,n1,n2,n3,n4,ov1,ov2,ov3,ov4;
	ALU1 alu1(a,b,op[1:0],out1,z1,c1,n1,ov1);
	ALU2 alu2(a,b,op[1:0],out2,z2,c2,n2,ov2);
	ALU3 alu3(a,b,op[1:0],out3,z3,c3,n3,ov3);
	ALU4 alu4(a,b,op[1:0],out4,z4,c4,n4,ov4);
	always@*
	begin
		case(op[3:2])
			2'b00:
			begin
			out=out1;
			z=z1;
			c=c1;
			n=n1;
			ov=ov1;
			end
			2'b01:
			begin
			out=out2;
			z=z2;
			c=c2;
			n=n2;
			ov=ov2;
			end
			2'b10:
			begin
			out=out3;
			z=z3;
			c=c3;
			n=n3;
			ov=ov3;
			end
			2'b11:
			begin
			out=out4;
			z=z4;
			c=c4;
			n=n4;
			ov=ov4;
			end
		endcase
	end
endmodule

2.ALU1.v

module ALU1(a,b,op,out,z,c,n,ov);
	parameter width=32;
	input [width-1:0] a,b;
	input [1:0] op;
	output reg[width-1:0] out;
	output reg z,c,n,ov;
	wire [width-1:0] out1,out2,out3,out4;
	wire z1,z2,z3,z4,c1,c2,c3,c4,n1,n2,n3,n4,ov1,ov2,ov3,ov4;
	wire[width+1:0] out5,out11,out12,out8,out9,out10;
//add
	assign out1=a+b;
	assign z1=(out1==0)?1:0;
	assign out5={1'b0,a[width-1],a};
	assign out11={1'b0,b[width-1],b};
	assign ov1=((a[width-1]==b[width-1])&&(~out1[width-1]==a[width-1]))?1:0;
	assign out12=out5+out11;
	assign c1=out12[width+1];
	assign n1=out12[width];
//sub
	assign out2=a-b;
	assign z2=(out2==0)?1:0;
	assign out8={1'b0,a[width-1],a};
	assign out9={1'b0,b[width-1],b};
	assign out10=out8-out9;
	assign ov2=(a[width-1]==!b[width-1])?1:0;
    	assign c2=out10[width+1];
	assign n2=out10[width];
//add1
	wire [width:0] out6;
	assign out6=a+1;
	assign out3=out6[width-1:0];
	assign ov3=out6[width];
	assign z3=(out3==0)?1:0;
	assign c3=out6[width];
	assign n3=out3[width-1];
//sub1
	wire [width:0] out7;
	assign out7=a-1;
	assign out4=out7[width-1:0];
	assign ov4=(a==0)?1:0;
	assign z4=(out4==0)?1:0;
	assign n4=out4[width-1];
	assign c4=ov4;
always@(*)
begin
         case(op)
	2'b00://add
	begin
	out=out1;
	z=z1;
	ov=ov1;
	c=c1;
	n=n1;
	end
	2'b01://sub
	begin
	out=out2;
	z=z2;
	ov=ov2;
    	c=c2;
	n=n2;
	end
	2'b10://add1
	begin
	   out=out3;
	   ov=ov3;
	   z=z3;
	   c=c3;
	   n=n3;
	end
	2'b11://sub1
	   begin
	   out=out4;
	   ov=ov4;
	   z=z4;
	   n=n4;
	   c=c4;
	   end
         endcase
end
endmodule

3.ALU2.v

module ALU2(a,b,op,out,z,c,n,ov);
	parameter width=32;
	input [width-1:0] a,b;
	input [1:0] op;
	output reg[width-1:0] out;
	output reg z,c,n,ov;
	wire [width-1:0] out1,out2,out3,out4;
//and
	assign out1=a&b;
//or
	assign out2=a|b;
//xor
	assign out3=a^b;
//neg
	assign out4=(~a);	
always @ (*)
begin
         case(op)
	2'b00://and
	begin
	out=out1;
	end
	2'b01://or
	begin
	out=out2;
	end
	2'b10://xor
	begin
	out=out3;
	end
	2'b11://neg
	begin
	out=out4;
	end
          endcase
	z=(out==0)?1:0;
	c=0;
	n=0;
	ov=0;
end
	
endmodule

4.alu3.v

module ALU3(a,b,op,out,z,c,n,ov);
	parameter width=32;
	input [width-1:0] a,b;
	input [1:0] op;
	output reg[width-1:0] out;
	output reg z,c,n,ov;
	wire [width-1:0] out1,out2,out3,out4;
	wire z1,z2,z3,z4,c1,c2,c3,c4,n1,n2,n3,n4,ov1,ov2,ov3,ov4;
//sla
	wire [width:0] q1;
	assign q1=($signed(a))<<<b;
	assign out1=($signed(a))<<<b;
     	assign ov1=q1[width];
     	assign z1=(out1==0)?1:0;
	assign c1=q1[width];
	assign n1=a[width-1];
//sll
	wire [width:0] q2;
	assign q2=a<<b;
	assign out2=a<<b;
     	assign ov2=q2[width];
	assign c2=q2[width];
     	assign z2=(out2==0)?1:0;
	assign n2=0;
//sra
	wire [width:0] q3;
	assign q3=($signed(a))>>>b;
	assign out3=($signed(a))>>>b;
     	assign ov3=q3[width];
     	assign z3=(out3==0)?1:0;
	assign c3=q3[width];
	assign n3=a[width-1];
//srl
	wire [width:0] q4;
	assign q4=a>>b;
	assign out4=a>>b;
     	assign ov4=q4[width];
	assign c4=q4[width];
     	assign z4=(out4==0)?1:0;
	assign n4=0;
always@(*)
begin
          case(op)
	2'b00://sla
	begin
	out=out1;
     	ov=ov1;
     	z=z1;
	c=c1;
	n=n1;
	end
	2'b01://sll
	begin
	out=out2;
     	ov=ov2;
	c=c2;
     	z=z2;
	n=n2;
	end
	2'b10://sra
	begin
	out=out3;
     	ov=ov3;
     	z=z3;
	c=c3;
	n=n3;
	end
	2'b11://srl
	begin
	out=out4;
     	ov=ov4;
	c=c4;
     	z=z4;
	n=n4;
	end
	endcase
end
endmodule

5.alu4.v

module ALU4(a,b,op,out,z,c,n,ov);
	parameter width=32;
	input [width-1:0] a,b;
	input [1:0] op;
	output reg[width-1:0] out;
	output reg z,c,n,ov;
	wire [width-1:0] out1,out2;
	wire z1,z2,c1,c2,n1,n2,ov1,ov2;
	integer i,j;
//exc
	assign out1[31]=a[15];
	assign out1[30]=a[14];
	assign out1[29]=a[13];
	assign out1[28]=a[12];
	assign out1[27]=a[11];
	assign out1[26]=a[10];
	assign out1[25]=a[9];
	assign out1[24]=a[8];
	assign out1[23]=a[7];
	assign out1[22]=a[6];
	assign out1[21]=a[5];
	assign out1[20]=a[4];
	assign out1[19]=a[3];
	assign out1[18]=a[2];
	assign out1[17]=a[1];
	assign out1[16]=a[0];
	assign out1[15]=a[31];
	assign out1[14]=a[30];
	assign out1[13]=a[29];
	assign out1[12]=a[28];
	assign out1[11]=a[27];
	assign out1[10]=a[26];
	assign out1[9]=a[25];
	assign out1[8]=a[24];
	assign out1[7]=a[23];
	assign out1[6]=a[22];
	assign out1[5]=a[21];
	assign out1[4]=a[20];
	assign out1[3]=a[19];
	assign out1[2]=a[18];
	assign out1[1]=a[17];
	assign out1[0]=a[16];
	assign ov1=0;
	assign z1=(out1==0)?0:1;
	assign c1=0;
	assign n1=out1[31];
//mul
	reg [width-1:0] a_b [width-1:0];
	always @*
	begin
	for(i=0;i<width-1;i=i+1)
		for(j=0;j<width-1;j=j+1) a_b[i][j]=a[i]&b[j];
	for(i=0;i<width-1;i=i+1) a_b[i][width-1]=~(a[i]&b[width-1]);
	for(j=0;j<width-1;j=j+1) a_b[width-1][j]=~(a[width-1]&b[j]);
	a_b[width-1][width-1]=a[width-1]&b[width-1];
	end
	wire [2*width-1:0] out3;
	assign out3=(({32'b1,a_b[0][31],a_b[0][30:0]}+{31'b0,a_b[1][31],a_b[1][30:0],1'b0})+
                ({30'b0,a_b[2][31],a_b[2][30:0],2'b0}+{29'b0,a_b[3][31],a_b[3][30:0],3'b0})+
                ({28'b0,a_b[4][31],a_b[4][30:0],4'b0}+{27'b0,a_b[5][31],a_b[5][30:0],5'b0})+
                ({26'b0,a_b[6][31],a_b[6][30:0],6'b0}+{25'b0,a_b[7][31],a_b[7][30:0],7'b0})+
                ({24'b0,a_b[8][31],a_b[8][30:0],8'b0}+{23'b0,a_b[9][31],a_b[9][30:0],9'b0})+
                ({22'b0,a_b[10][31],a_b[10][30:0],10'b0}+{21'b0,a_b[11][31],a_b[11][30:0],11'b0})+
                ({20'b0,a_b[12][31],a_b[12][30:0],12'b0}+{19'b0,a_b[13][31],a_b[13][30:0],13'b0})+
                ({18'b0,a_b[14][31],a_b[14][30:0],14'b0}+{17'b0,a_b[15][31],a_b[15][30:0],15'b0})+
                ({16'b0,a_b[16][31],a_b[16][30:0],16'b0}+{15'b0,a_b[17][31],a_b[17][30:0],17'b0})+
                ({14'b0,a_b[18][31],a_b[18][30:0],18'b0}+{13'b0,a_b[19][31],a_b[19][30:0],19'b0})+
                ({12'b0,a_b[20][31],a_b[20][30:0],20'b0}+{11'b0,a_b[21][31],a_b[21][30:0],21'b0})+
                ({10'b0,a_b[22][31],a_b[22][30:0],22'b0}+{9'b0,a_b[23][31],a_b[23][30:0],23'b0})+
                ({8'b0,a_b[24][31],a_b[24][30:0],24'b0}+{7'b0,a_b[25][31],a_b[25][30:0],25'b0})+
                ({6'b0,a_b[26][31],a_b[26][30:0],26'b0}+{5'b0,a_b[27][31],a_b[27][30:0],27'b0})+
                ({4'b0,a_b[28][31],a_b[28][30:0],28'b0}+{3'b0,a_b[29][31],a_b[29][30:0],29'b0})+
                ({2'b0,a_b[30][31],a_b[30][30:0],30'b0}+{1'b1,a_b[31][31],a_b[31][30:0],31'b0}));
	assign out2=out3[2*width-1:width];
	assign ov2=out3[63]^out3[62];
	assign z2=(out2==0)?1:0;
	assign c2=0;
	assign n2=out2[width-1];
always @ (*)
begin
	case(op)
	   2'b00://exc
	   begin
	   out=out1;
	   ov=ov1;
	   z=z1;
	   c=c1;
	   n=n1;
	   end
	   2'b01://mul
	   begin
	   out=out2;
	   ov=ov2;
	   z=z2;
	   n=n2;
	   c=c2;
	   end
	   default:
	   begin
	   out=0;
	   z=0;
	   n=0;
	   c=0;
	   ov=0;
	   end
	endcase
end
endmodule

6.alu32_tb.v

`include "alu32.v"
module alu32_tb;
	parameter width=32;
	wire [width-1:0] out;
	wire z,c,n,ov;
	reg [width-1:0] a,b;
	reg [3:0] op;
	reg clk;
	alu32 m(a,b,op,out,z,c,n,ov,clk);
	initial begin
	$dumpfile("test.vcd");
	$dumpvars;
	a=32'h80000000;
	b=32'h80000000;
	clk=1;
	op=4'b1101;
	$write("time\t a\t  b\t   op\t out  z c n ov\n");
	$monitor("%g\t %h %h %h %h %b %b %b %b",$time,a,b,op,out,z,c,n,ov);
	#100;
	end
endmodule

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值