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