Bootstrap

单周期CPU设计(四)执行模块(minisys)(verilog)(vivado)

`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

仿真波形图如下

 

 

;