源文件:
module alu5(ena, clk, opcode, a, b, c,d);
parameter N = 32;
//状态编码
parameter sla=3'b000,
sra=3'b001,
add=3'b010,
sub=3'b011,
mul=3'b100,
andd=3'b101,
ord=3'b110,
notd=3'b111;
//定义输入输出端口
input ena, clk;
input [2 : 0] opcode;
input signed [N - 1 : 0] a, b; //输入有符号整数范围为[-128, 127]
output signed[N-1:0] c;
output signed[2:0] d;
//内部寄存器定义
reg signed [N : 0] temp;
reg cf;
reg [5:0] ii;
reg signed [N-1:0] c;
reg signed [2:0] d;
//逻辑实现
always@(posedge clk)
begin
if(ena)
begin
casex(opcode)
sla:
begin
c={a[31],a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1],a[0],1'b0};
if({a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1],a[0]}==30'b000000000000000000000000000000)
d[0]=1'b1;
else
d[0]=1'b0;
if(a[N-1]==1'b1)
d[2]=1'b1;
else
d[2]=1'b0;
d[1]=1'bz;
end
sra:
begin
c={a[31],a[31],a[30],a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1]};
if({a[31],a[30],a[29],a[28],a[27],a[26],a[25],a[24],a[23],a[22],a[21],a[20],a[19],a[18],a[17],a[16],a[15],a[14],a[13],a[12],a[11],a[10],a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1]}==31'b0000000000000000000000000000000)
d[0]=1'b1;
else
d[0]=1'b0;
if(a[N-1]==1'b1)
d[2]=1'b1;
else
d[2]=1'b0;
d[1]=1'bz;
end
add:
begin
temp=0;
temp={1'b0,a[N-1:0]}+{1'b0,b[N-1:0]};
c=temp[N-1:0];
cf=temp[N];
d[1]=c[N-1]^a[N-1]^b[N-1]^cf;
if(c==32'h00000000)
d[0]=1'b1;
else
d[0]=1'b0;
if(c[N-1]==1'b1)
d[2]=1'b1;
else
d[2]=1'b0;
end
sub:
begin
temp=0;
temp={1'b0,a[N-1:0]}-{1'b0,b[N-1:0]};
c=temp[N-1:0];
cf=temp[N];
d[1]=c[N-1]^a[N-1]^b[N-1]^cf;
if(c==32'h00000000)
d[0]=1'b1;
else
d[0]=1'b0;
if(c[N-1]==1'b1)
d[2]=1'b1;
else
d[2]=1'b0;
end
mul:
begin
c=0;
for(ii=0;ii<32;ii=ii+1)
if(b[ii])
c=c+(a<<(ii));
if(c==32'h00000000)
d[0]=1'b1;
else
d[0]=1'b0;
d[2]=a[31]^b[31];
d[1]=1'bz;
end
andd:
begin
c=a&b;
if(c==32'h00000000)
d[0]=1'b1;
else
d[0]=1'b1;
d[2]=1'b0;
d[1]=1'b0;
end
ord:
begin
c=a|b;
if(c==32'h00000000)
d[0]=1'b1;
else
d[0]=1'b0;
d[2]=1'b0;
d[1]=1'b0;
end
notd:
begin
c=~a;
if(c==32'h00000000)
d[0]=1'b1;
else
d[0]=1'b0;
d[2]=1'b0;
d[1]=1'b0;
end
default: c<=0;
endcase
end
end
endmodule
测试文件:
`timescale 1ns/1ns
`define half_period 5
module alu_t5(c,d);
//alu位宽定义
parameter N = 32;
parameter sla=3'b000,
sra=3'b001,
add=3'b010,
sub=3'b011,
mul=3'b100,
andd=3'b101,
ord=3'b110,
notd=3'b111;
//输出端口定义
output signed [N-1 : 0] c;
output signed [2 : 0] d;
//寄存器及连线定义
reg ena, clk;
reg [2 : 0] opcode;
reg signed [N - 1 : 0] a,b;
//产生测试信号
initial
begin
//设置电路初始状态
#20 clk = 0; ena = 0; opcode = 3'b000;
a = 32'd0; b = 32'd0;
#20 ena = 1;
//test sla
#20 a=32'hdffffffd;
opcode=sla;
#20 a=32'h4ffffff0;
opcode=sla;
//test sra
#20 a=32'hfffffffd;
opcode=sra;
#20 a=32'h3ffffff9;
opcode=sra;
//test add
#20 a=32'd1000;
b=32'd2000;
opcode=add;
#20 a=32'd2000;
b=-32'd5000;
opcode=add;
#20 a=-32'd120000;
b=-32'd10000;
opcode=add;
#20 a=32'd6000;
b=-32'd6000;
opcode=add;
//test sub
#20 a=32'd6000;
b=32'd5000;
opcode=sub;
#20 a=32'd2000;
b=32'd4000;
opcode=sub;
#20 a=32'd8000;
b=32'd8000;
opcode=sub;
//test mul
#20 a=32'd100;
b=32'd100;
opcode=mul;
#20 a=-32'd200;
b=32'd300;
opcode=mul;
#20 a=-32'd400;
b=-32'd200;
opcode=mul;
//test and
#20 a=32'h0101_1101;
b=32'h1100_0110;
opcode=andd;
#20 a=32'h1101_1001;
b=32'h0010_0110;
opcode=andd;
//test or
#20 a=32'h0111_0011;
b=32'h0001_1011;
opcode=ord;
#20 a=32'h1111_0000;
b=32'h1111_1111;
opcode=ord;
//test not
#20 a=32'h1111_0000;
opcode=notd;
#20 a=32'h1111_1111;
opcode=notd;
#100 $stop;
end
//产生时钟
always #`half_period clk = ~clk;
//实例化
alu5 m0(.ena(ena), .clk(clk), .opcode(opcode), .a(a), .b(b), .c(c), .d(d));
endmodule