⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode.v

📁 日立SH-2 CPU核的VERLOG源码
💻 V
📖 第 1 页 / 共 5 页
字号:
    // check register conflict
    //------------------------
    // following conditions mean register conflict
    // (1) EX_RDREG_X and WB1_WRREG_W and (EX_REGNUM_X == WB1_REGNUM_W)
    // (2) EX_RDREG_Y and WB1_WRREG_W and (EX_REGNUM_Y == WB1_REGNUM_W)
    // (3) EX_WRREG_Z and WB1_WRREG_W and (EX_REGNUM_Z == WB1_REGNUM_W)
    // (4) EX_RDPR_X and WB1_WRPR_W
    // (5) EX_RDPR_Y and WB1_WRPR_W
    // (6) EX_WRPR_Z and WB1_WRPR_W
    // (7) (EX_ALUFUNC == `ALU_ADDR0) and WB1_WRREG_W and (WB1_REGNUM_W == 4'h0)


    always @(EX_RDREG_X  or EX_RDREG_Y or EX_WRREG_Z
          or EX_REGNUM_X or EX_REGNUM_Y or EX_REGNUM_Z  // Thorn Aitch 2003/12/10
          or WB1_WRREG_W or WB1_REGNUM_W
          or EX_RDPR_X   or EX_RDPR_Y  or EX_WRPR_Z
          or WB1_WRPR_W
       // or EX_RDMACH_X or EX_RDMACH_Y or WB1_WRMACH
       // or EX_RDMACL_X or EX_RDMACL_Y or WB1_WRMACL
          or EX_ALUFUNC)
    //always @(posedge CLK)
    begin
        if ((EX_RDREG_X & WB1_WRREG_W & (EX_REGNUM_X == WB1_REGNUM_W))
          | (EX_RDREG_Y & WB1_WRREG_W & (EX_REGNUM_Y == WB1_REGNUM_W))
          | (EX_WRREG_Z & WB1_WRREG_W & (EX_REGNUM_Z == WB1_REGNUM_W))
          | (EX_RDPR_X & WB1_WRPR_W)
          | (EX_RDPR_Y & WB1_WRPR_W)
          | (EX_WRPR_Z & WB1_WRPR_W)
       // | (EX_RDMACH_X & WB1_WRMACH)
       // | (EX_RDMACH_Y & WB1_WRMACH)
       // | (EX_RDMACL_X & WB1_WRMACL)
       // | (EX_RDMACL_Y & WB1_WRMACL)
          | ((EX_ALUFUNC == `ALU_ADDR0) & WB1_WRREG_W & (WB1_REGNUM_W == 4'h0)) 
           )
            REG_CONF <= 1;
        else
            REG_CONF <= 0;
    end

    //---------------------------
    // check forwarding condition
    //---------------------------
    // following conditions mean register forwarding from W-bus to X/Y-bus
    // (1) RDREG_X and WRREG_W and (REGNUM_X == REGNUM_W) : W-bus to X-bus
    // (2) RDREG_Y and WRREG_W and (REGNUM_Y == REGNUM_W) : W-bus to Y-bus
    // (3) RDPR_X and WRPR_W : W-bus to X-bus
    // (4) RDPR_Y and WRPR_W : W-bus to Y-bus
    // (5) RDMACH_X and WRMACH : W-bus to X-bus
    // (6) RDMACH_Y and WRMACH : W-bus to Y-bus
    // (7) RDMACL_X and WRMACL : W-bus to X-bus
    // (8) RDMACL_Y and WRMACL : W-bus to Y-bus
  
    reg  REG_FWD_X;     // register forward from W-bus to X-bus
    reg  REG_FWD_Y;     // register forward from W-bus to Y-bus

    always @(RDREG_X  or RDREG_Y 
          or REGNUM_X or REGNUM_Y 
          or WRREG_W or REGNUM_W
          or RDPR_X or RDPR_Y or WRPR_W
       // or RDMACH_X or RDMACH_Y or WRMACH
       // or RDMACL_X or RDMACL_Y or WRMACL
          or FWD_W2X)
    begin
        if ((FWD_W2X)
          | (RDREG_X & WRREG_W & (REGNUM_X == REGNUM_W))
          | (RDPR_X & WRPR_W)) 
       // | (RDMACH_X & WRMACH)
       // | (RDMACL_X & WRMACL)
            REG_FWD_X <= 1'b1;
        else
            REG_FWD_X <= 1'b0;

        if ((RDREG_Y & WRREG_W & (REGNUM_Y == REGNUM_W))
          | (RDPR_Y & WRPR_W))
       // | (RDMACH_Y & WRMACH)
       // | (RDMACL_Y & WRMACL)
            REG_FWD_Y <= 1'b1;
        else
            REG_FWD_Y <= 1'b0;
    end

//------------------------------------
// Output Signals : A huge truth table
//------------------------------------
    always @(INSTR_STATE or INSTR_SEQ or T_BCC or NEXT_ID_STALL)
    begin
        // ---- CAUTION ----------------------------------------------------------------
        // To simplify the RTL description rule, 
        // only non-blocking substitution (<=) is recommended for this project.
        // But in this "always @" statement, 
        // I use blocking substitution (=) to reduce typing errors. 
        // You should take care when you modify or reuse this statement.
        //
        // Moreover, in this scope area, I use casex to specify "don't care input ?".
	    // But the use of casex is permitted only for this truth table.
        //------------------------------------------------------------------------------

	   //===============
        // default values
	   //===============
        DISPATCH = 0;
        {ID_IF_ISSUE,ID_IF_JP} =  2'b00;
        {EX_IF_ISSUE,EX_IF_JP} =  2'b00;
        {EX_RDREG_X, EX_RDREG_Y, EX_WRREG_Z, WB_WRREG_W } =  4'b0000;
        // {EX_REGNUM_X,EX_REGNUM_Y,EX_REGNUM_Z,WB_REGNUM_W} = 16'hxxxx; // Thorn Aitch 2003/12/10
	   {EX_REGNUM_X,EX_REGNUM_Y,EX_REGNUM_Z,WB_REGNUM_W} = 16'h0000;    // Thorn Aitch 2003/12/10
        {EX_ALUFUNC}  = `ALU_NOP;
        {EX_MULCOM1, EX_MULCOM2}   = 9'b000000000;
        {WB_MULCOM1, WB_MULCOM2}   = 9'b000000000;
        {EX_MACSEL1,EX_MACSEL2}   =  4'b0000;
        {WB_MACSEL1,WB_MACSEL2}   =  4'b0000;
        {EX_WRMACH,EX_WRMACL}     =  2'b00;
        {WB_WRMACH,WB_WRMACL}     =  2'b00;
        {EX_RDMACH_X,EX_RDMACL_X} = 2'b00; 
        {EX_RDMACH_Y,EX_RDMACL_Y} = 2'b00;
        {WB_MAC_BUSY, EX_MAC_BUSY, MAC_STALL_SENSE} = 3'b000;
        {EX_RDSR_X, EX_RDSR_Y, EX_WRSR_Z, WB_WRSR_W}     = 4'b0000;
        {MAC_S_LATCH} = 1'b0;
        {EX_RDGBR_X, EX_RDGBR_Y, EX_WRGBR_Z, WB_WRGBR_W} = 4'b0000;
        {EX_RDVBR_X, EX_RDVBR_Y, EX_WRVBR_Z, WB_WRVBR_W} = 4'b0000;
        {EX_RDPR_X, EX_RDPR_Y, EX_WRPR_Z, WB_WRPR_W, EX_WRPR_PC} = 5'b00000;
        // {EX_MA_ISSUE,EX_MA_WR,EX_MA_SZ,EX_KEEP_CYC} =  5'b0xxxx; // Thorn Aitch 2003/12/10
	   {EX_MA_ISSUE,EX_MA_WR,EX_MA_SZ,EX_KEEP_CYC} =  5'b00000;    // Thorn Aitch 2003/12/10
        {EX_WRMAAD_Z,EX_WRMADW_X,EX_WRMADW_Y,WB_RDMADR_W} = 4'b0000;    
        {EX_RDPC_X,EX_RDPC_Y,EX_WRPC_Z,ID_INCPC} = 4'b0000;
        {ID_IFADSEL, EX_IFADSEL}                 = 2'b00;
        {EX_CONST_ZERO4,EX_CONST_ZERO42,EX_CONST_ZERO44} = 3'b000;
        {EX_CONST_ZERO8,EX_CONST_ZERO82,EX_CONST_ZERO84} = 3'b000;
        {EX_CONST_SIGN8,EX_CONST_SIGN82,EX_CONST_SIGN122} = 3'b000;
        {EX_RDCONST_X,EX_RDCONST_Y} = 2'b00;
        // {EX_CMPCOM}  = 3'bxxx;  // Thorn Aitch 2003/12/10
	   {EX_CMPCOM}  = 3'b000;     // Thorn Aitch 2003/12/10
        // {EX_SFTFUNC} = 5'bxxxx; // Thorn Aitch 2003/12/10
	   {EX_SFTFUNC} = 5'b0000;    // Thorn Aitch 2003/12/10
        {EX_RDSFT_Z} = 1'b0;
        {EX_T_CMPSET, EX_T_CRYSET, EX_T_TSTSET, EX_T_SFTSET} = 4'b0000;
        {EX_QT_DV1SET, EX_MQT_DV0SET} = 2'b00;
        {EX_T_CLR, EX_T_SET, EX_MQ_CLR} = 3'b000;
        {EX_RDTEMP_X, EX_WRTEMP_Z, EX_WRMAAD_TEMP} = 3'b000;
        {EX_FWD_W2X} = 1'b0;
        {EVENT_ACK_0, RST_SR, ILEVEL_CAP, WR_IBIT} = 4'b0000;
        {MASKINT_NEXT} = 1'b0;
        {SLP} = 1'b0;
        {DELAY_JUMP} = 1'b0;

        //============================================
        // Line 0xxx
        //============================================
        casex (INSTR_STATE[15:12])
          4'b0000 : // 0xxx
        //------------------
        // STC SR,  Rn (0n02)
        // STC GBR, Rn (0n12)
        // STC VBR, Rn (0n22)
        //------------------
            casex (INSTR_STATE[3:0])
              4'b0010 : // 0xx2
                begin
                  casex (INSTR_STATE[5:4])
                    2'b00   : EX_RDSR_Y  = 1'b1;
                    2'b01   : EX_RDGBR_Y = 1'b1;
                    2'b1?   : EX_RDVBR_Y = 1'b1;
                    default : ;
                  endcase
                  EX_ALUFUNC = `ALU_THRUY;
                  EX_REGNUM_Z = INSTR_STATE[11:8]; // Rn
                  EX_WRREG_Z = 1'b1;
                  ID_INCPC = 1'b1;
                  ID_IF_ISSUE = 1'b1;
                  DISPATCH = 1'b1;
                end
        //---------------
        // BSRF Rm (0m03)
        // BRAF Rm (0m23) 
        //---------------
              4'b0011 : // 0xx3 
                begin
                  case (INSTR_SEQ)
                    0: begin                 
                         EX_RDPC_X = 1'b1;
                         EX_RDREG_Y = 1'b1;
                         EX_REGNUM_Y = INSTR_STATE[11:8];
                         EX_ALUFUNC = `ALU_ADD;
                         EX_WRPC_Z = 1'b1;
                         if (~INSTR_STATE[5]) EX_WRPR_PC = 1; // BSRF operation
                         ID_INCPC = 1'b1;
                       end
                    1: begin
                         ID_IF_ISSUE = 1'b1;
                         ID_IFADSEL = 1'b1;
                         ID_IF_JP = 1'b1;
                         DISPATCH = 1'b1;
                         DELAY_JUMP = 1'b1;
                       end
                    default : ;
                  endcase
                end
        //---------------------------
        // MUL.L Rm, Rn        (0nm7)
        //---------------------------
              4'b01?? : // 0xx4, 0xx5, 0xx6, 0xx7  
                begin 
                  if (INSTR_STATE[1:0] == 2'b11) // 0xx7
                    begin
                      MAC_STALL_SENSE = 1'b1;
                      EX_MAC_BUSY = (NEXT_ID_STALL)? 1'b0:1'b1;
                      EX_RDREG_X = 1'b1;
                      EX_REGNUM_X = INSTR_STATE[11:8]; // Rn
                      EX_RDREG_Y = 1'b1;
                      EX_REGNUM_Y = INSTR_STATE[7:4]; // Rm
                      EX_MACSEL1 = 2'b00; // XBUS -> MACIN1
                      EX_MACSEL2 = 2'b00; // YBUS -> MACIN2
                      EX_MULCOM1 = 1'b1;
                      EX_MULCOM2 = {1'b1, INSTR_STATE[14:12], INSTR_STATE[3:0]};
                      ID_INCPC = 1'b1;
                      ID_IF_ISSUE = 1'b1;
                      DISPATCH = 1'b1;
                    end              
        //---------------------------
        // MOV.B Rm, @(R0, Rn) (0nm4)
        // MOV.W Rm, @(R0, Rn) (0nm5)
        // MOV.L Rm, @(R0, Rn) (0nm6)
        //---------------------------
                  else // 0xx4, 0xx5, 0xx6
                    begin
                      EX_RDREG_X = 1'b1;
                      EX_REGNUM_X = INSTR_STATE[11:8]; //Rn
                      EX_ALUFUNC = `ALU_ADDR0; //@(R0, Rn)
                      EX_WRMAAD_Z = 1'b1;
                      EX_RDREG_Y = 1'b1;
                      EX_REGNUM_Y = INSTR_STATE[7:4];  //Rm
                      EX_WRMADW_Y = 1'b1;
                      {EX_MA_ISSUE,EX_MA_WR} =  2'b11;
                      EX_MA_SZ = INSTR_STATE[1:0];
                      ID_INCPC = 1'b1;
                      ID_IF_ISSUE = 1'b1;
                      DISPATCH = 1'b1;
                    end
                  end
        //--------------
        // CLRT   (0008)
        // SETT   (0018)
        // CLRMAC (0028)
        //--------------
              4'b1000 : // 0xx8
                begin
                  casex (INSTR_STATE[5:4])
                    2'b00   : EX_T_CLR = 1'b1;
                    2'b01   : EX_T_SET = 1'b1;
                    2'b1?   : {EX_WRMACH, EX_WRMACL, MAC_STALL_SENSE} = 3'b111;
                    default : ;
                  endcase
                  ID_INCPC = 1'b1;
                  ID_IF_ISSUE = 1'b1;
                  DISPATCH = 1'b1;
                end
        //---------------
        // NOP (0009)
        //---------------
              4'b1001 : // 0xx9
                begin
                  if(INSTR_STATE[5:4] == 2'b00) //(don't care INSTR_STATE[11:6])
                    begin // ID
                      ID_INCPC = 1'b1;
                      ID_IF_ISSUE = 1'b1;
                      DISPATCH = 1'b1;
                    end
        //---------------
        // DIV0U (0019)
        //---------------
                  else if (INSTR_STATE[5:4] == 2'b01) //(don't care INSTR_STATE[11:6])
                    begin
                      EX_T_CLR = 1'b1;
                      EX_MQ_CLR = 1'b1;
                      ID_INCPC = 1'b1;
                      ID_IF_ISSUE = 1'b1;
                      DISPATCH = 1'b1;
                    end
        //---------------
        // MOVT Rn (0n29)
        //---------------
                  else
                    begin
                      if (T_BCC) EX_ALUFUNC = `ALU_INCX; // if T=1 then 1->Rn else 0->Rn
                      EX_WRREG_Z = 1'b1;
                      EX_REGNUM_Z = INSTR_STATE[11:8];
                      ID_INCPC = 1'b1;
                      ID_IF_ISSUE = 1'b1;
                      DISPATCH = 1'b1;
                    end
                end
        //--------------------
        // STS MACH, Rn (0n0A)
        // STS MACL, Rn (0n1A)
        // STS PR  , Rn (0n2A) 
        //--------------------
              4'b1010 : // 0xxA
                begin
                  casex (INSTR_STATE[5:4])
                    2'b00   : // don't care INSTR_STATE[7:6]
                              {EX_RDMACH_Y, MAC_STALL_SENSE} = 2'b11; 
                    2'b01   : // don't care INSTR_STATE[7:6]
                              {EX_RDMACL_Y, MAC_STALL_SENSE} = 2'b11;
                    2'b1?   : EX_RDPR_Y = 1'b1;   // don't care INSTR_STATE[7:6],[4]
                    default : ;
                  endcase
                  EX_ALUFUNC = `ALU_THRUY;
                  EX_REGNUM_Z = INSTR_STATE[11:8]; // Rn
                  EX_WRREG_Z = 1'b1;
                  ID_INCPC = 1'b1;
                  ID_IF_ISSUE = 1'b1;
                  DISPATCH = 1'b1;
                end
        //-----------
        // RTS (000B)
        //-----------
              4'b1011 : // 0xxB
                begin
                  if(INSTR_STATE[5:4] == 2'b00) // 000B (don't care INSTR_STATE[11:6])
                    case (INSTR_SEQ)
                      0: begin
                           EX_RDPR_Y = 1'b1;
                           EX_ALUFUNC = `ALU_THRUY;
                           EX_WRPC_Z = 1'b1;
                         end
                      1: begin
                           ID_IF_ISSUE = 1'b1;
                           ID_IFADSEL = 1'b1;
                           ID_IF_JP = 1'b1;
                           DISPATCH = 1'b1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -