`timescale 1ns / 1ps
//
module Executs32 (
input [31:0] Read_data_1, // 从译码单元的Read_data_1中来
input [31:0] Read_data_2, // 从译码单元的Read_data_2中来
input [31:0] Sign_extend, // 从译码单元来的扩展后的立即数
input [5:0] Function_opcode, // 取指单元来的r-类型指令功能码,r-form instructions[5:0]
input [5:0] Exe_opcode, // 取指单元来的操作码
input [1:0] ALUOp, // 来自控制单元的运算指令控制编码
input [4:0] Shamt, // 来自取指单元的instruction[10:6],指定移位次数
input Sftmd, // 来自控制单元的,表明是移位指令
input ALUSrc, // 来自控制单元,表明第二个操作数是立即数(beq,bne除外)
input I_format, // 来自控制单元,表明是除beq, bne, LW, SW之外的I-类型指令
input Jrn, // 来自控制单元,书名是JR指令
output Zero, // 为1表明计算值为0
output [31:0] ALU_Result, // 计算的数据结果
output [31:0] Add_Result, // 计算的地址结果
input [31:0] PC_plus_4 // 来自取指单元的PC+4
);
reg[31:0] ALU_Result;
wire[31:0] Ainput,Binput;
reg[31:0] Cinput,Dinput;
reg[31:0] Einput,Finput;
reg[31:0] Ginput,Hinput;
reg[31:0] Sinput;
reg[31:0] ALU_output_mux;
wire[2:0] ALU_ctl;
wire[5:0] Exe_code;
wire[2:0] Sftm;
assign Sftm = Function_opcode[2:0]; // 实际有用的只有低三位(移位指令)
assign Exe_code = (I_format==0) ? Function_opcode : {3'b000,Exe_opcode[2:0]};
assign Ainput = Read_data_1;
assign Binput = (ALUSrc == 0) ? Read_data_2 : Sign_extend[31:0]; //R/LW,SW sft else的时候含LW和SW
assign ALU_ctl[0] = (Exe_code[0] | Exe_code[3]) & ALUOp[1]; //24H AND
assign ALU_ctl[1] = ((!Exe_code[2]) | (!ALUOp[1]));
assign ALU_ctl[2] = (Exe_code[1] & ALUOp[1]) | ALUOp[0];
always @* begin
case(Sftm[2:0])
3'b000: Sinput = Binput << Shamt; // Sll rd, rt, shamt
3'b010: Sinput = Binput >> Shamt; // Srl rd, rt, shamt
3'b100: Sinput = Binput << Read_data_2; // Sllv rd, rt, rs
3'b110: Sinput = Binput >> Read_data_2; // Srlv rd, rt, rs
3'b011: Sinput = $signed(Binput) >>> Shamt; // Sra rd, rt, shamt (算术右移,保留符号位)
3'b111: Sinput = $signed(Binput) >>> Read_data_2; // Srav rd, rt, rs (算术右移,保留符号位)
default: Sinput = Binput;
endcase
end
always @* begin
if (((ALU_ctl == 3'b111) && (Exe_code[3] == 1)) || ((ALU_ctl[2:1] == 2'b11) && (I_format == 1))) begin
// Handle SLT class instructions
// ALU_Result = ????; // Fill in the logic for SLT class instructions
end
else if ((ALU_ctl == 3'b101) && (I_format == 1)) begin
// Handle LUI instruction
// ALU_Result[31:0] = ????; // Fill in the logic for LUI instruction
end
else if (Sftmd == 1) begin
// Handle shift instructions
ALU_Result = Sinput; // Move the result of shift operation to ALU_Result
end
else begin
ALU_Result = ALU_output_mux[31:0]; // Otherwise, use ALU_output_mux as ALU_Result
end
end
assign Add_Result = PC_plus_4[31:0] + {Sign_extend[29:0],2'b00}; // 给取指单元作为beq和bne指令的跳转地址
assign Zero = (ALU_output_mux[31:0]== 32'h00000000) ? 1'b1 : 1'b0;
always @* begin
case (ALU_ctl)
3'b000: ALU_output_mux = Ainput + Binput; // Addition
3'b001: ALU_output_mux = Ainput - Binput; // Subtraction
3'b010: ALU_output_mux = Ainput & Binput; // Bitwise AND
3'b011: ALU_output_mux = Ainput | Binput; // Bitwise OR
3'b100: ALU_output_mux = Ainput ^ Binput; // Bitwise XOR
3'b101: ALU_output_mux = {32'h00000000, Ainput[15:0]}; // LUI operation
3'b110: ALU_output_mux = Ainput + Sign_extend; // Addition with immediate value
3'b111: ALU_output_mux = Ainput - Sign_extend; // Subtraction with immediate value
default: ALU_output_mux = 32'h00000000;
endcase
end
endmodule
仿真文件如下
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date:
// Design Name:
// Module Name: exe_sim
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module exe_sim ();
// input
reg[31:0] Read_data_1 = 32'h00000005; //r-form rs
reg[31:0] Read_data_2 = 32'h00000006; //r-form rt
reg[31:0] Sign_extend = 32'hffffff40; //i-form
reg[5:0] Function_opcode = 6'b100000; //add
reg[5:0] Exe_opcode = 6'b000000; //op code
reg[1:0] ALUOp = 2'b10;
reg[4:0] Shamt = 5'b00000;
reg Sftmd = 1'b0;
reg ALUSrc = 1'b0;
reg I_format = 1'b0;
reg Jrn = 1'b0;
reg[31:0] PC_plus_4 = 32'h00000004;
// output
wire Zero;
wire[31:0] ALU_Result;
wire[31:0] Add_Result; //pc op
Executs32 Uexe (
.Read_data_1 (Read_data_1),
.Read_data_2 (Read_data_2),
.Sign_extend (Sign_extend),
.Function_opcode (Function_opcode),
.Exe_opcode (Exe_opcode),
.ALUOp (ALUOp),
.Shamt (Shamt),
.Sftmd (Sftmd),
.ALUSrc (ALUSrc),
.I_format (I_format),
.Jrn (Jrn),
.Zero (Zero),
.ALU_Result (ALU_Result),
.Add_Result (Add_Result),
.PC_plus_4 (PC_plus_4)
);
initial begin
#200 begin
Exe_opcode = 6'b001000; //addi
Read_data_1 = 32'h00000003; //r-form rs
Read_data_2 = 32'h00000006; //r-form rt
Sign_extend = 32'hffffff40;
Function_opcode = 6'b100000; //addi
ALUOp = 2'b10;
Shamt = 5'b00000;
Sftmd = 1'b0;
ALUSrc = 1'b1;
I_format = 1'b1;
PC_plus_4 = 32'h00000008;
end
#200 begin
Exe_opcode = 6'b000000; //and
Read_data_1 = 32'h000000ff; //r-form rs
Read_data_2 = 32'h00000ff0; //r-form rt
Sign_extend = 32'hffffff40;
Function_opcode = 6'b100100; //and
ALUOp = 2'b10;
Shamt = 5'b00000;
Sftmd = 1'b0;
ALUSrc = 1'b0;
I_format = 1'b0;
PC_plus_4 = 32'h0000000c;
end
#200 begin
Exe_opcode = 6'b000000; //sll
Read_data_1 = 32'h00000001; //r-form rs
Read_data_2 = 32'h00000002; //r-form rt
Sign_extend = 32'hffffff40;
Function_opcode = 6'b000000; //sll
ALUOp = 2'b10;
Shamt = 5'b00011;
Sftmd = 1'b1;
ALUSrc = 1'b0;
I_format = 1'b0;
PC_plus_4 = 32'h00000010;
end
#200 begin
Exe_opcode = 6'b001111; // LUI
Read_data_1 = 32'h00000001; //r-form rs
Read_data_2 = 32'h00000002; //r-form rt
Sign_extend = 32'h00000040;
Function_opcode = 6'b000000; //LUI
ALUOp = 2'b10;
Shamt = 5'b00001;
Sftmd = 1'b0;
ALUSrc = 1'b1;
I_format = 1'b1;
PC_plus_4 = 32'h00000014;
end
#200 begin
Exe_opcode = 6'b000100; // BEQ
Read_data_1 = 32'h00000001; //r-form rs
Read_data_2 = 32'h00000001; //r-form rt
Sign_extend = 32'h00000004;
Function_opcode = 6'b000100; //LUI
ALUOp = 2'b01;
Shamt = 5'b00000;
Sftmd = 1'b0;
ALUSrc = 1'b0;
I_format = 1'b0;
PC_plus_4 = 32'h00000018;
end
end
endmodule
仿真波形图如下