代码写的真好,转载以作记录和学习。
代码 :
module ALU(
input [3:0] op,
input [31:0] rs1,
input [31:0] rs2,
input [19:0] imm,
output [31:0] rd,
output overflow
);
wire [31:0]out1;
wire [31:0]out2;
wire [31:0]out3;
wire [31:0]out4;
wire [31:0]out5;
wire [31:0]out6;
wire [31:0]out7;
wire [31:0]out8;
wire [31:0]out9;
wire [31:0]out10;
wire [31:0]out11;
wire [32:0]sum;
wire [63:0]mul;
assign sum = rs1 + rs2;
assign mul = rs1 * rs2;
assign overflow = ((op == 4'b0011)) & sum[32] | ((op == 4'b1011) & (mul[63:32] > 0));
//第一层mux
assign out1 = op[0] ? rs1>>rs2 : rs1<<rs2;
assign out2 = op[0] ? sum[31:0] : (( {{31{rs1[31]}}, 1'b0 } << (~rs2[4:0]) ) | (rs1 >> rs2[4:0]));
assign out3 = op[0] ? {imm,12'd0} : rs1-rs2;
assign out4 = op[0] ? rs1<rs2 : ((rs1[31] ^~ rs2[31]) & (rs1 < rs2)) | (rs1[31] & ~rs2[31]);
assign out5 = op[0] ? rs1 | rs2 : rs1^rs2;
assign out6 = op[0] ? mul[31:0] : rs1&rs2;
//第二层mux
assign out7 = op[1] ? out2 : out1;
assign out8 = op[1] ? out4 : out3;
assign out9 = op[1] ? out6 : out5;
//第三层mux
assign out10 = op[2] ? out8 : out7;
assign out11 = op[2] ? {32{1'bZ}} : out9;
//第四层mux
assign rd = op[3] ? out11 : out10;
endmodule
testbench
module ALU_tb(
);
reg [3:0] op;
reg [31:0] rs1;
reg [31:0] rs2;
reg [19:0] imm;
wire [31:0] rd;
wire overflow;
ALU alu0(
.op(op),
.rs1(rs1),
.rs2(rs2),
.imm(imm),
.rd(rd),
.overflow(overflow)
);
initial
begin
op = 0;
rs1 = 32'h0fffffff;
rs2 = 32'hfffffffe;
imm = 3;
#20
op = 1;
#20
op = 2;
#20
op = 3;
#20
op = 4;
#20
op = 5;
#20
op = 6;
#20
op = 7;
#20
op = 8;
#20
op = 9;
#20
op = 10;
#20
op = 11;
#20
op = 12;
end
endmodule