根据mips指令集实现能进行12种算数逻辑运算单元,不支持例外处理。
模块输入包括两个操作数和选择进行何种运算的 片选信号(alu_control) 和一个结果输出端口。结果输出端用了一个无优先级的多路选择器实现结果选择。
12种运算类型分别为:
- 加法
- 减法
- 有符号比较小于置为1
- 无符号比较小于置为1
- 与,非或,或,异或四种逻辑运算
- 逻辑左、右移
- 算数右移
- 置寄存器高16位
具体代码如下:
module alu (
input [11:0] alu_control,
input [31:0] alu_src1,
input [31:0] alu_src2,
output [31:0] alu_result
);
//control
wire op_add = alu_control[0];
wire op_sub = alu_control[1];
wire op_slt = alu_control[2];
wire op_sltu = alu_control[3];
wire op_and = alu_control[4];
wire op_nor = alu_control[5];
wire op_or = alu_control[6];
wire op_xor = alu_control[7];
wire op_sll = alu_control[8];
wire op_srl = alu_control[9];
wire op_sra = alu_control[10];
wire op_lui = alu_control[11];
//result
wire [31:0] add_sub_res;
wire [31:0] slt_res;
wire [31:0] sltu_res;
wire [31:0] and_res;
wire [31:0] nor_res;
wire [31:0] or_res;
wire [31:0] xor_res;
wire [31:0] sll_res;
wire [31:0] srl_res;
wire [31:0] sra_res;
wire [31:0] lui_res;
//logic
assign and_res = alu_src1 & alu_src2;
assign or_res = alu_src1 | alu_src2;
assign xor_res = alu_src1 ^ alu_src2;
assign nor_res = ~or_res;
assign lui_res = {alu_src2[15:0], 16'b0};
//adder
wire [31:0] adder1;
wire [31:0] adder2;
wire adder_cin;
wire [31:0] adder_res;
wire adder_cout;
assign adder1 = alu_src1;
assign adder2 = (op_sub | op_slt | op_sltu) ? ~alu_src2 : alu_src2;
assign adder_cin = (op_sub | op_slt | op_sltu) ? 1'b1 : 1'b0;
assign {adder_cout,adder_res} = adder1 + adder2 + adder_cin;
assign add_sun_res = adder_res;
//slt && sltu
assign slt_res [31:1] = 31'b0;
assign sltu_res[31:1] = 31'b0;
assign sltu_res[0] = ~adder_cout;
assign slt_res [0] = (alu_src1[31] & ~alu_src2[31])
| ( ~(alu_src1[31] ^ alu_src2[31]) & adder_res[31]) ;
//sll && srl && sra
assign sll_res = alu_src2 << alu_src1[4:0];
assign srl_res = alu_src2 >> alu_src1[4:0];
assign sra_res = ($signed(alu_src2)) >>> alu_src1[4:0];
//cout_result
assign alu_result = ({32{op_add | op_sub}} & add_sub_res)
| ({32{op_slt }} & slt_res)
| ({32{op_sltu }} & sltu_res)
| ({32{op_and }} & and_res)
| ({32{op_nor }} & nor_res)
| ({32{op_or }} & or_res)
| ({32{op_xor }} & xor_res)
| ({32{op_sll }} & sll_res)
| ({32{op_srl }} & srl_res)
| ({32{op_sra }} & sra_res)
| ({32{op_lui }} & lui_res);
endmodule