OpenCores
URL https://opencores.org/ocsvn/mips32r1/mips32r1/trunk

Subversion Repositories mips32r1

[/] [mips32r1/] [trunk/] [Hardware/] [MIPS32_Standalone/] [Control.v] - Rev 12

Go to most recent revision | Compare with Previous | Blame | View Log

    `timescale 1ns / 1ps
/*
 * File         : Control.v
 * Project      : University of Utah, XUM Project MIPS32 core
 * Creator(s)   : Grant Ayers (ayers@cs.utah.edu)
 *
 * Modification History:
 *   Rev   Date         Initials  Description of Change
 *   1.0    7-Jun-2011  GEA       Initial design.
 *   2.0   26-May-2012  GEA       Release version with CP0.
 *
 * Standards/Formatting:
 *   Verilog 2001, 4 soft tab, wide column.
 *
 * Description:
 *   The Datapath Controller. This module sets the datapath control
 *   bits for an incoming instruction. These control bits follow the
 *   instruction through each pipeline stage as needed, and constitute
 *   the effective operation of the processor through each pipeline stage.
 */
module Control(
    input  ID_Stall,
    input  [5:0] OpCode,
    input  [5:0] Funct,
    input  [4:0] Rs,        // used to differentiate mfc0 and mtc0
    input  [4:0] Rt,        // used to differentiate bgez,bgezal,bltz,bltzal,teqi,tgei,tgeiu,tlti,tltiu,tnei
    input  Cmp_EQ,
    input  Cmp_GZ,
    input  Cmp_GEZ,
    input  Cmp_LZ,
    input  Cmp_LEZ,
    //------------
    output IF_Flush,
    output reg [7:0] DP_Hazards,
    output [1:0] PCSrc,
    output SignExtend,
    output Link,
    output Movn,
    output Movz,
    output Mfc0,
    output Mtc0,
    output CP1,
    output CP2,
    output CP3,
    output Eret,
    output Trap,
    output TrapCond,
    output EXC_Sys,
    output EXC_Bp,
    output EXC_RI,
    output ID_CanErr,
    output EX_CanErr,
    output M_CanErr,
    output NextIsDelay,
    output RegDst,
    output ALUSrcImm,
    output reg [4:0] ALUOp,
    output LLSC,
    output MemWrite,
    output MemRead,
    output MemByte,
    output MemHalf,
    output MemSignExtend,
    output Left,
    output Right,
    output RegWrite,
    output MemtoReg
    );
 
    `include "MIPS_Parameters.v"
 
    wire Movc;
    wire Branch, Branch_EQ, Branch_GTZ, Branch_LEZ, Branch_NEQ, Branch_GEZ, Branch_LTZ;
    wire Unaligned_Mem;
 
    reg [15:0] Datapath;
    assign PCSrc[0]      = Datapath[14];
    assign Link          = Datapath[13];
    assign ALUSrcImm     = Datapath[12];
    assign Movc          = Datapath[11];
    assign Trap          = Datapath[10];
    assign TrapCond      = Datapath[9];
    assign RegDst        = Datapath[8];
    assign LLSC          = Datapath[7];
    assign MemRead       = Datapath[6];
    assign MemWrite      = Datapath[5];
    assign MemHalf       = Datapath[4];
    assign MemByte       = Datapath[3];
    assign MemSignExtend = Datapath[2];
    assign RegWrite      = Datapath[1];
    assign MemtoReg      = Datapath[0];
 
    reg [2:0] DP_Exceptions;
    assign ID_CanErr = DP_Exceptions[2];
    assign EX_CanErr = DP_Exceptions[1];
    assign  M_CanErr = DP_Exceptions[0];
 
    // Set the main datapath control signals based on the Op Code
    always @(*) begin
        if (ID_Stall)
            Datapath <= DP_None;
        else begin
            case (OpCode)
                // R-Type
                Op_Type_R  :
                    begin
                        case (Funct)
                            Funct_Add     : Datapath <= DP_Add;
                            Funct_Addu    : Datapath <= DP_Addu;
                            Funct_And     : Datapath <= DP_And;
                            Funct_Break   : Datapath <= DP_Break;
                            Funct_Div     : Datapath <= DP_Div;
                            Funct_Divu    : Datapath <= DP_Divu;
                            Funct_Jalr    : Datapath <= DP_Jalr;
                            Funct_Jr      : Datapath <= DP_Jr;
                            Funct_Mfhi    : Datapath <= DP_Mfhi;
                            Funct_Mflo    : Datapath <= DP_Mflo;
                            Funct_Movn    : Datapath <= DP_Movn;
                            Funct_Movz    : Datapath <= DP_Movz;
                            Funct_Mthi    : Datapath <= DP_Mthi;
                            Funct_Mtlo    : Datapath <= DP_Mtlo;
                            Funct_Mult    : Datapath <= DP_Mult;
                            Funct_Multu   : Datapath <= DP_Multu;
                            Funct_Nor     : Datapath <= DP_Nor;
                            Funct_Or      : Datapath <= DP_Or;
                            Funct_Sll     : Datapath <= DP_Sll;
                            Funct_Sllv    : Datapath <= DP_Sllv;
                            Funct_Slt     : Datapath <= DP_Slt;
                            Funct_Sltu    : Datapath <= DP_Sltu;
                            Funct_Sra     : Datapath <= DP_Sra;
                            Funct_Srav    : Datapath <= DP_Srav;
                            Funct_Srl     : Datapath <= DP_Srl;
                            Funct_Srlv    : Datapath <= DP_Srlv;
                            Funct_Sub     : Datapath <= DP_Sub;
                            Funct_Subu    : Datapath <= DP_Subu;
                            Funct_Syscall : Datapath <= DP_Syscall;
                            Funct_Teq     : Datapath <= DP_Teq;
                            Funct_Tge     : Datapath <= DP_Tge;
                            Funct_Tgeu    : Datapath <= DP_Tgeu;
                            Funct_Tlt     : Datapath <= DP_Tlt;
                            Funct_Tltu    : Datapath <= DP_Tltu;
                            Funct_Tne     : Datapath <= DP_Tne;
                            Funct_Xor     : Datapath <= DP_Xor;
                            default       : Datapath <= DP_None;
                        endcase
                    end
                // R2-Type
                Op_Type_R2 :
                    begin
                        case (Funct)
                            Funct_Clo   : Datapath <= DP_Clo;
                            Funct_Clz   : Datapath <= DP_Clz;
                            Funct_Madd  : Datapath <= DP_Madd;
                            Funct_Maddu : Datapath <= DP_Maddu;
                            Funct_Msub  : Datapath <= DP_Msub;
                            Funct_Msubu : Datapath <= DP_Msubu;
                            Funct_Mul   : Datapath <= DP_Mul;
                            default     : Datapath <= DP_None;
                        endcase
                    end
                // I-Type
                Op_Addi    : Datapath <= DP_Addi;
                Op_Addiu   : Datapath <= DP_Addiu;
                Op_Andi    : Datapath <= DP_Andi;
                Op_Ori     : Datapath <= DP_Ori;
                Op_Pref    : Datapath <= DP_Pref;
                Op_Slti    : Datapath <= DP_Slti;
                Op_Sltiu   : Datapath <= DP_Sltiu;
                Op_Xori    : Datapath <= DP_Xori;
                // Jumps (using immediates)
                Op_J       : Datapath <= DP_J;
                Op_Jal     : Datapath <= DP_Jal;
                // Branches and Traps
                Op_Type_BI :
                    begin
                        case (Rt)
                            OpRt_Bgez   : Datapath <= DP_Bgez;
                            OpRt_Bgezal : Datapath <= DP_Bgezal;
                            OpRt_Bltz   : Datapath <= DP_Bltz;
                            OpRt_Bltzal : Datapath <= DP_Bltzal;
                            OpRt_Teqi   : Datapath <= DP_Teqi;
                            OpRt_Tgei   : Datapath <= DP_Tgei;
                            OpRt_Tgeiu  : Datapath <= DP_Tgeiu;
                            OpRt_Tlti   : Datapath <= DP_Tlti;
                            OpRt_Tltiu  : Datapath <= DP_Tltiu;
                            OpRt_Tnei   : Datapath <= DP_Tnei;
                            default     : Datapath <= DP_None;
                        endcase
                    end                         
                Op_Beq     : Datapath <= DP_Beq;
                Op_Bgtz    : Datapath <= DP_Bgtz;
                Op_Blez    : Datapath <= DP_Blez;
                Op_Bne     : Datapath <= DP_Bne;
                // Coprocessor 0
                Op_Type_CP0 :
                    begin
                        case (Rs)
                            OpRs_MF   : Datapath <= DP_Mfc0;
                            OpRs_MT   : Datapath <= DP_Mtc0;
                            OpRs_ERET : Datapath <= (Funct == Funct_ERET) ? DP_Eret : DP_None;
                            default   : Datapath <= DP_None;
                        endcase
                    end
                // Memory
                Op_Lb   : Datapath <= DP_Lb;
                Op_Lbu  : Datapath <= DP_Lbu;
                Op_Lh   : Datapath <= DP_Lh;
                Op_Lhu  : Datapath <= DP_Lhu;
                Op_Ll   : Datapath <= DP_Ll;
                Op_Lui  : Datapath <= DP_Lui;
                Op_Lw   : Datapath <= DP_Lw;
                Op_Lwl  : Datapath <= DP_Lwl;
                Op_Lwr  : Datapath <= DP_Lwr;
                Op_Sb   : Datapath <= DP_Sb;
                Op_Sc   : Datapath <= DP_Sc;
                Op_Sh   : Datapath <= DP_Sh;
                Op_Sw   : Datapath <= DP_Sw;
                Op_Swl  : Datapath <= DP_Swl;
                Op_Swr  : Datapath <= DP_Swr;
                default : Datapath <= DP_None;
            endcase
        end
    end
 
    // Set the Hazard Control Signals and Exception Indicators based on the Op Code
    always @(*) begin
        case (OpCode)
            // R-Type
            Op_Type_R  :
                begin
                    case (Funct)
                        Funct_Add     : begin DP_Hazards <= HAZ_Add;     DP_Exceptions <= EXC_Add;     end
                        Funct_Addu    : begin DP_Hazards <= HAZ_Addu;    DP_Exceptions <= EXC_Addu;    end
                        Funct_And     : begin DP_Hazards <= HAZ_And;     DP_Exceptions <= EXC_And;     end
                        Funct_Break   : begin DP_Hazards <= HAZ_Break;   DP_Exceptions <= EXC_Break;   end
                        Funct_Div     : begin DP_Hazards <= HAZ_Div;     DP_Exceptions <= EXC_Div;     end
                        Funct_Divu    : begin DP_Hazards <= HAZ_Divu;    DP_Exceptions <= EXC_Divu;    end
                        Funct_Jalr    : begin DP_Hazards <= HAZ_Jalr;    DP_Exceptions <= EXC_Jalr;    end
                        Funct_Jr      : begin DP_Hazards <= HAZ_Jr;      DP_Exceptions <= EXC_Jr;      end
                        Funct_Mfhi    : begin DP_Hazards <= HAZ_Mfhi;    DP_Exceptions <= EXC_Mfhi;    end
                        Funct_Mflo    : begin DP_Hazards <= HAZ_Mflo;    DP_Exceptions <= EXC_Mflo;    end
                        Funct_Movn    : begin DP_Hazards <= HAZ_Movn;    DP_Exceptions <= EXC_Movn;    end
                        Funct_Movz    : begin DP_Hazards <= HAZ_Movz;    DP_Exceptions <= EXC_Movz;    end
                        Funct_Mthi    : begin DP_Hazards <= HAZ_Mthi;    DP_Exceptions <= EXC_Mthi;    end
                        Funct_Mtlo    : begin DP_Hazards <= HAZ_Mtlo;    DP_Exceptions <= EXC_Mtlo;    end
                        Funct_Mult    : begin DP_Hazards <= HAZ_Mult;    DP_Exceptions <= EXC_Mult;    end
                        Funct_Multu   : begin DP_Hazards <= HAZ_Multu;   DP_Exceptions <= EXC_Multu;   end
                        Funct_Nor     : begin DP_Hazards <= HAZ_Nor;     DP_Exceptions <= EXC_Nor;     end
                        Funct_Or      : begin DP_Hazards <= HAZ_Or;      DP_Exceptions <= EXC_Or;      end
                        Funct_Sll     : begin DP_Hazards <= HAZ_Sll;     DP_Exceptions <= EXC_Sll;     end
                        Funct_Sllv    : begin DP_Hazards <= HAZ_Sllv;    DP_Exceptions <= EXC_Sllv;    end
                        Funct_Slt     : begin DP_Hazards <= HAZ_Slt;     DP_Exceptions <= EXC_Slt;     end
                        Funct_Sltu    : begin DP_Hazards <= HAZ_Sltu;    DP_Exceptions <= EXC_Sltu;    end
                        Funct_Sra     : begin DP_Hazards <= HAZ_Sra;     DP_Exceptions <= EXC_Sra;     end
                        Funct_Srav    : begin DP_Hazards <= HAZ_Srav;    DP_Exceptions <= EXC_Srav;    end
                        Funct_Srl     : begin DP_Hazards <= HAZ_Srl;     DP_Exceptions <= EXC_Srl;     end
                        Funct_Srlv    : begin DP_Hazards <= HAZ_Srlv;    DP_Exceptions <= EXC_Srlv;    end
                        Funct_Sub     : begin DP_Hazards <= HAZ_Sub;     DP_Exceptions <= EXC_Sub;     end
                        Funct_Subu    : begin DP_Hazards <= HAZ_Subu;    DP_Exceptions <= EXC_Subu;    end
                        Funct_Syscall : begin DP_Hazards <= HAZ_Syscall; DP_Exceptions <= EXC_Syscall; end
                        Funct_Teq     : begin DP_Hazards <= HAZ_Teq;     DP_Exceptions <= EXC_Teq;     end
                        Funct_Tge     : begin DP_Hazards <= HAZ_Tge;     DP_Exceptions <= EXC_Tge;     end
                        Funct_Tgeu    : begin DP_Hazards <= HAZ_Tgeu;    DP_Exceptions <= EXC_Tgeu;    end
                        Funct_Tlt     : begin DP_Hazards <= HAZ_Tlt;     DP_Exceptions <= EXC_Tlt;     end
                        Funct_Tltu    : begin DP_Hazards <= HAZ_Tltu;    DP_Exceptions <= EXC_Tltu;    end
                        Funct_Tne     : begin DP_Hazards <= HAZ_Tne;     DP_Exceptions <= EXC_Tne;     end
                        Funct_Xor     : begin DP_Hazards <= HAZ_Xor;     DP_Exceptions <= EXC_Xor;     end
                        default       : begin DP_Hazards <= 8'hxx;       DP_Exceptions <= 3'bxxx;      end
                    endcase
                end
            // R2-Type
            Op_Type_R2 :
                begin
                    case (Funct)
                        Funct_Clo   : begin DP_Hazards <= HAZ_Clo;   DP_Exceptions <= EXC_Clo;   end
                        Funct_Clz   : begin DP_Hazards <= HAZ_Clz;   DP_Exceptions <= EXC_Clz;   end
                        Funct_Madd  : begin DP_Hazards <= HAZ_Madd;  DP_Exceptions <= EXC_Madd;  end
                        Funct_Maddu : begin DP_Hazards <= HAZ_Maddu; DP_Exceptions <= EXC_Maddu; end
                        Funct_Msub  : begin DP_Hazards <= HAZ_Msub;  DP_Exceptions <= EXC_Msub;  end
                        Funct_Msubu : begin DP_Hazards <= HAZ_Msubu; DP_Exceptions <= EXC_Msubu; end
                        Funct_Mul   : begin DP_Hazards <= HAZ_Mul;   DP_Exceptions <= EXC_Mul;   end
                        default     : begin DP_Hazards <= 8'hxx;     DP_Exceptions <= 3'bxxx;    end
                    endcase
                end
            // I-Type
            Op_Addi    : begin DP_Hazards <= HAZ_Addi;  DP_Exceptions <= EXC_Addi;  end
            Op_Addiu   : begin DP_Hazards <= HAZ_Addiu; DP_Exceptions <= EXC_Addiu; end
            Op_Andi    : begin DP_Hazards <= HAZ_Andi;  DP_Exceptions <= EXC_Andi;  end
            Op_Ori     : begin DP_Hazards <= HAZ_Ori;   DP_Exceptions <= EXC_Ori;   end
            Op_Pref    : begin DP_Hazards <= HAZ_Pref;  DP_Exceptions <= EXC_Pref;  end
            Op_Slti    : begin DP_Hazards <= HAZ_Slti;  DP_Exceptions <= EXC_Slti;  end
            Op_Sltiu   : begin DP_Hazards <= HAZ_Sltiu; DP_Exceptions <= EXC_Sltiu; end
            Op_Xori    : begin DP_Hazards <= HAZ_Xori;  DP_Exceptions <= EXC_Xori;  end
            // Jumps
            Op_J       : begin DP_Hazards <= HAZ_J;     DP_Exceptions <= EXC_J;     end
            Op_Jal     : begin DP_Hazards <= HAZ_Jal;   DP_Exceptions <= EXC_Jal;   end
            // Branches and Traps
            Op_Type_BI :
                begin
                    case (Rt)
                        OpRt_Bgez   : begin DP_Hazards <= HAZ_Bgez;   DP_Exceptions <= EXC_Bgez;   end
                        OpRt_Bgezal : begin DP_Hazards <= HAZ_Bgezal; DP_Exceptions <= EXC_Bgezal; end
                        OpRt_Bltz   : begin DP_Hazards <= HAZ_Bltz;   DP_Exceptions <= EXC_Bltz;   end
                        OpRt_Bltzal : begin DP_Hazards <= HAZ_Bltzal; DP_Exceptions <= EXC_Bltzal; end
                        OpRt_Teqi   : begin DP_Hazards <= HAZ_Teqi;   DP_Exceptions <= EXC_Teqi;   end
                        OpRt_Tgei   : begin DP_Hazards <= HAZ_Tgei;   DP_Exceptions <= EXC_Tgei;   end
                        OpRt_Tgeiu  : begin DP_Hazards <= HAZ_Tgeiu;  DP_Exceptions <= EXC_Tgeiu;  end
                        OpRt_Tlti   : begin DP_Hazards <= HAZ_Tlti;   DP_Exceptions <= EXC_Tlti;   end
                        OpRt_Tltiu  : begin DP_Hazards <= HAZ_Tltiu;  DP_Exceptions <= EXC_Tltiu;  end
                        OpRt_Tnei   : begin DP_Hazards <= HAZ_Tnei;   DP_Exceptions <= EXC_Tnei;   end
                        default     : begin DP_Hazards <= 8'hxx;      DP_Exceptions <= 3'bxxx;     end
                    endcase
                end                         
            Op_Beq     : begin DP_Hazards <= HAZ_Beq;  DP_Exceptions <= EXC_Beq;  end
            Op_Bgtz    : begin DP_Hazards <= HAZ_Bgtz; DP_Exceptions <= EXC_Bgtz; end
            Op_Blez    : begin DP_Hazards <= HAZ_Blez; DP_Exceptions <= EXC_Blez; end
            Op_Bne     : begin DP_Hazards <= HAZ_Bne;  DP_Exceptions <= EXC_Bne;  end
            // Coprocessor 0
            Op_Type_CP0 :
                begin
                    case (Rs)
                        OpRs_MF   : begin DP_Hazards <= HAZ_Mfc0; DP_Exceptions <= EXC_Mfc0; end
                        OpRs_MT   : begin DP_Hazards <= HAZ_Mtc0; DP_Exceptions <= EXC_Mtc0; end
                        OpRs_ERET : begin DP_Hazards <= (Funct == Funct_ERET) ? DP_Eret : 8'hxx; DP_Exceptions <= EXC_Eret; end
                        default   : begin DP_Hazards <= 8'hxx;    DP_Exceptions <= 3'bxxx;   end
                    endcase
                end
            // Memory
            Op_Lb   : begin DP_Hazards <= HAZ_Lb;  DP_Exceptions <= EXC_Lb;  end
            Op_Lbu  : begin DP_Hazards <= HAZ_Lbu; DP_Exceptions <= EXC_Lbu; end
            Op_Lh   : begin DP_Hazards <= HAZ_Lh;  DP_Exceptions <= EXC_Lh;  end
            Op_Lhu  : begin DP_Hazards <= HAZ_Lhu; DP_Exceptions <= EXC_Lhu; end
            Op_Ll   : begin DP_Hazards <= HAZ_Ll;  DP_Exceptions <= EXC_Ll;  end
            Op_Lui  : begin DP_Hazards <= HAZ_Lui; DP_Exceptions <= EXC_Lui; end
            Op_Lw   : begin DP_Hazards <= HAZ_Lw;  DP_Exceptions <= EXC_Lw;  end
            Op_Lwl  : begin DP_Hazards <= HAZ_Lwl; DP_Exceptions <= EXC_Lwl; end
            Op_Lwr  : begin DP_Hazards <= HAZ_Lwr; DP_Exceptions <= EXC_Lwr; end
            Op_Sb   : begin DP_Hazards <= HAZ_Sb;  DP_Exceptions <= EXC_Sb;  end
            Op_Sc   : begin DP_Hazards <= HAZ_Sc;  DP_Exceptions <= EXC_Sc;  end
            Op_Sh   : begin DP_Hazards <= HAZ_Sh;  DP_Exceptions <= EXC_Sh;  end
            Op_Sw   : begin DP_Hazards <= HAZ_Sw;  DP_Exceptions <= EXC_Sw;  end
            Op_Swl  : begin DP_Hazards <= HAZ_Swl; DP_Exceptions <= EXC_Swl; end
            Op_Swr  : begin DP_Hazards <= HAZ_Swr; DP_Exceptions <= EXC_Swr; end
            default : begin DP_Hazards <= 8'hxx;   DP_Exceptions <= 3'bxxx;  end
        endcase
    end
 
    // ALU Assignment
    always @(*) begin
        if (ID_Stall)
            ALUOp <= AluOp_Addu;  // Any Op that doesn't write HILO or cause exceptions
        else begin
            case (OpCode)
                Op_Type_R  :
                    begin
                        case (Funct)
                            Funct_Add     : ALUOp <= AluOp_Add;
                            Funct_Addu    : ALUOp <= AluOp_Addu;
                            Funct_And     : ALUOp <= AluOp_And;
                            Funct_Div     : ALUOp <= AluOp_Div;
                            Funct_Divu    : ALUOp <= AluOp_Divu;
                            Funct_Jalr    : ALUOp <= AluOp_Addu;
                            Funct_Mfhi    : ALUOp <= AluOp_Mfhi;
                            Funct_Mflo    : ALUOp <= AluOp_Mflo;
                            Funct_Movn    : ALUOp <= AluOp_Addu;
                            Funct_Movz    : ALUOp <= AluOp_Addu;
                            Funct_Mthi    : ALUOp <= AluOp_Mthi;
                            Funct_Mtlo    : ALUOp <= AluOp_Mtlo;
                            Funct_Mult    : ALUOp <= AluOp_Mult;
                            Funct_Multu   : ALUOp <= AluOp_Multu;
                            Funct_Nor     : ALUOp <= AluOp_Nor;
                            Funct_Or      : ALUOp <= AluOp_Or;
                            Funct_Sll     : ALUOp <= AluOp_Sll;
                            Funct_Sllv    : ALUOp <= AluOp_Sllv;
                            Funct_Slt     : ALUOp <= AluOp_Slt;
                            Funct_Sltu    : ALUOp <= AluOp_Sltu;
                            Funct_Sra     : ALUOp <= AluOp_Sra;
                            Funct_Srav    : ALUOp <= AluOp_Srav;
                            Funct_Srl     : ALUOp <= AluOp_Srl;
                            Funct_Srlv    : ALUOp <= AluOp_Srlv;
                            Funct_Sub     : ALUOp <= AluOp_Sub;
                            Funct_Subu    : ALUOp <= AluOp_Subu;
                            Funct_Syscall : ALUOp <= AluOp_Addu;
                            Funct_Teq     : ALUOp <= AluOp_Subu;
                            Funct_Tge     : ALUOp <= AluOp_Slt;
                            Funct_Tgeu    : ALUOp <= AluOp_Sltu;
                            Funct_Tlt     : ALUOp <= AluOp_Slt;
                            Funct_Tltu    : ALUOp <= AluOp_Sltu;
                            Funct_Tne     : ALUOp <= AluOp_Subu;
                            Funct_Xor     : ALUOp <= AluOp_Xor;
                            default       : ALUOp <= AluOp_Addu;
                        endcase
                    end
                Op_Type_R2 :
                    begin
                        case (Funct)
                            Funct_Clo   : ALUOp <= AluOp_Clo;
                            Funct_Clz   : ALUOp <= AluOp_Clz;
                            Funct_Madd  : ALUOp <= AluOp_Madd;
                            Funct_Maddu : ALUOp <= AluOp_Maddu;
                            Funct_Msub  : ALUOp <= AluOp_Msub;
                            Funct_Msubu : ALUOp <= AluOp_Msubu;
                            Funct_Mul   : ALUOp <= AluOp_Mul;
                            default     : ALUOp <= AluOp_Addu;
                        endcase
                    end
                Op_Type_BI  :
                    begin
                        case (Rt)
                            OpRt_Teqi   : ALUOp <= AluOp_Subu;
                            OpRt_Tgei   : ALUOp <= AluOp_Slt;
                            OpRt_Tgeiu  : ALUOp <= AluOp_Sltu;
                            OpRt_Tlti   : ALUOp <= AluOp_Slt;
                            OpRt_Tltiu  : ALUOp <= AluOp_Sltu;
                            OpRt_Tnei   : ALUOp <= AluOp_Subu;
                            default     : ALUOp <= AluOp_Addu;  // Branches don't matter.
                        endcase
                    end
                Op_Type_CP0 : ALUOp <= AluOp_Addu;
                Op_Addi     : ALUOp <= AluOp_Add;
                Op_Addiu    : ALUOp <= AluOp_Addu;
                Op_Andi     : ALUOp <= AluOp_And;
                Op_Jal      : ALUOp <= AluOp_Addu;
                Op_Lb       : ALUOp <= AluOp_Addu;
                Op_Lbu      : ALUOp <= AluOp_Addu;
                Op_Lh       : ALUOp <= AluOp_Addu;
                Op_Lhu      : ALUOp <= AluOp_Addu;
                Op_Ll       : ALUOp <= AluOp_Addu;
                Op_Lui      : ALUOp <= AluOp_Sllc;
                Op_Lw       : ALUOp <= AluOp_Addu;
                Op_Lwl      : ALUOp <= AluOp_Addu;
                Op_Lwr      : ALUOp <= AluOp_Addu;
                Op_Ori      : ALUOp <= AluOp_Or;
                Op_Sb       : ALUOp <= AluOp_Addu;
                Op_Sc       : ALUOp <= AluOp_Addu;  // XXX Needs HW implement
                Op_Sh       : ALUOp <= AluOp_Addu;
                Op_Slti     : ALUOp <= AluOp_Slt;
                Op_Sltiu    : ALUOp <= AluOp_Sltu;
                Op_Sw       : ALUOp <= AluOp_Addu;
                Op_Swl      : ALUOp <= AluOp_Addu;
                Op_Swr      : ALUOp <= AluOp_Addu;
                Op_Xori     : ALUOp <= AluOp_Xor;
                default     : ALUOp <= AluOp_Addu;
            endcase
        end
    end
 
    /*** 
     These remaining options cover portions of the datapath that are not
     controlled directly by the datapath bits. Note that some refer to bits of
     the opcode or other fields, which breaks the otherwise fully-abstracted view
     of instruction encodings. Make sure when adding custom instructions that
     no false positives/negatives are generated here.
     ***/
 
    // Branch Detection: Options are mutually exclusive.
    assign Branch_EQ  =  OpCode[2] & ~OpCode[1] & ~OpCode[0] &  Cmp_EQ;
    assign Branch_GTZ =  OpCode[2] &  OpCode[1] &  OpCode[0] &  Cmp_GZ;
    assign Branch_LEZ =  OpCode[2] &  OpCode[1] & ~OpCode[0] &  Cmp_LEZ;
    assign Branch_NEQ =  OpCode[2] & ~OpCode[1] &  OpCode[0] & ~Cmp_EQ;
    assign Branch_GEZ = ~OpCode[2] &  Rt[0] & Cmp_GEZ;
    assign Branch_LTZ = ~OpCode[2] & ~Rt[0] & Cmp_LZ;
 
    assign Branch = Branch_EQ | Branch_GTZ | Branch_LEZ | Branch_NEQ | Branch_GEZ | Branch_LTZ;
    assign PCSrc[1] = (Datapath[15] & ~Datapath[14]) ? Branch : Datapath[15];
 
    /* In MIPS32, all Branch and Jump operations execute the Branch Delay Slot,
     * or next instruction, regardless if the branch is taken or not. The exception
     * is the "Branch Likely" instruction group. These are deprecated, however, and not
     * implemented here. "IF_Flush" is defined to allow for the cancelation of a
     * Branch Delay Slot should these be implemented later.
     */
    assign IF_Flush = 0;
 
    // Indicator that next instruction is a Branch Delay Slot.
    assign NextIsDelay = Datapath[15] | Datapath[14];
 
    // Sign- or Zero-Extension Control. The only ops that require zero-extension are
    // Andi, Ori, and Xori. The following also zero-extends 'lui', however it does not alter the effect of lui.
    assign SignExtend = (OpCode[5:2] != 4'b0011);
 
    // Move Conditional
    assign Movn = Movc &  Funct[0];
    assign Movz = Movc & ~Funct[0];
 
    // Coprocessor 0 (Mfc0, Mtc0) control signals.
    assign Mfc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MF));
    assign Mtc0 = ((OpCode == Op_Type_CP0) && (Rs == OpRs_MT));
    assign Eret = ((OpCode == Op_Type_CP0) && (Rs == OpRs_ERET) && (Funct == Funct_ERET));
 
    // Coprocessor 1,2,3 accesses (not implemented)
    assign CP1 = (OpCode == Op_Type_CP1);
    assign CP2 = (OpCode == Op_Type_CP2);
    assign CP3 = (OpCode == Op_Type_CP3);
 
    // Exceptions found in ID
    assign EXC_Sys = ((OpCode == Op_Type_R) && (Funct == Funct_Syscall));
    assign EXC_Bp  = ((OpCode == Op_Type_R) && (Funct == Funct_Break));
 
    // Unaligned Memory Accesses (lwl, lwr, swl, swr)
    assign Unaligned_Mem = OpCode[5] & ~OpCode[4] & OpCode[1] & ~OpCode[0];
    assign Left  = Unaligned_Mem & ~OpCode[2];
    assign Right = Unaligned_Mem &  OpCode[2];
 
    // TODO: Reserved Instruction Exception must still be implemented
    assign EXC_RI  = 0;
 
endmodule
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.