源文件:
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