Team:Peking/jium

  1. /* $begin pipe-all-hcl */
  2. HCL Description of Control for Pipelined Y86-64 Processor #
  3. Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2014 #
    1. Your task is to modify the design so that conditional branches are
    2. predicted as being taken when backward and not-taken when forward
    3. The code here is nearly identical to that for the normal pipeline.
    4. Comments starting with keyword "BBTFNT" have been added at places
    5. relevant to the exercise.
  1. C Include's. Don't alter these #

quote '#include <stdio.h>' quote '#include "isa.h"' quote '#include "pipeline.h"' quote '#include "stages.h"' quote '#include "sim.h"' quote 'int sim_main(int argc, char *argv[]);' quote 'int main(int argc, char *argv[]){return sim_main(argc,argv);}'

  1. Declarations. Do not change/remove/delete any of these #
          1. Symbolic representation of Y86-64 Instruction Codes #############

wordsig INOP 'I_NOP' wordsig IHALT 'I_HALT' wordsig IRRMOVQ 'I_RRMOVQ' wordsig IIRMOVQ 'I_IRMOVQ' wordsig IRMMOVQ 'I_RMMOVQ' wordsig IMRMOVQ 'I_MRMOVQ' wordsig IOPQ 'I_ALU' wordsig IJXX 'I_JMP' wordsig ICALL 'I_CALL' wordsig IRET 'I_RET' wordsig IPUSHQ 'I_PUSHQ' wordsig IPOPQ 'I_POPQ'

          1. Symbolic represenations of Y86-64 function codes #####

wordsig FNONE 'F_NONE' # Default function code

          1. Symbolic representation of Y86-64 Registers referenced #####

wordsig RRSP 'REG_RSP' # Stack Pointer wordsig RNONE 'REG_NONE' # Special value indicating "no register"

          1. ALU Functions referenced explicitly ##########################

wordsig ALUADD 'A_ADD' # ALU should add its arguments

    1. BBTFNT: For modified branch prediction, need to distinguish
    2. conditional vs. unconditional branches
          1. Jump conditions referenced explicitly

wordsig UNCOND 'C_YES' # Unconditional transfer

          1. Possible instruction status values #####

wordsig SBUB 'STAT_BUB' # Bubble in stage wordsig SAOK 'STAT_AOK' # Normal execution wordsig SADR 'STAT_ADR' # Invalid memory address wordsig SINS 'STAT_INS' # Invalid instruction wordsig SHLT 'STAT_HLT' # Halt instruction encountered

          1. Signals that can be referenced by control logic ##############
          1. Pipeline Register F ##########################################

wordsig F_predPC 'pc_curr->pc' # Predicted value of PC

          1. Intermediate Values in Fetch Stage ###########################

wordsig imem_icode 'imem_icode' # icode field from instruction memory wordsig imem_ifun 'imem_ifun' # ifun field from instruction memory wordsig f_icode 'if_id_next->icode' # (Possibly modified) instruction code wordsig f_ifun 'if_id_next->ifun' # Fetched instruction function wordsig f_valC 'if_id_next->valc' # Constant data of fetched instruction wordsig f_valP 'if_id_next->valp' # Address of following instruction boolsig imem_error 'imem_error' # Error signal from instruction memory boolsig instr_valid 'instr_valid' # Is fetched instruction valid?

          1. Pipeline Register D ##########################################

wordsig D_icode 'if_id_curr->icode' # Instruction code wordsig D_rA 'if_id_curr->ra' # rA field from instruction wordsig D_rB 'if_id_curr->rb' # rB field from instruction wordsig D_valP 'if_id_curr->valp' # Incremented PC

          1. Intermediate Values in Decode Stage #########################

wordsig d_srcA 'id_ex_next->srca' # srcA from decoded instruction wordsig d_srcB 'id_ex_next->srcb' # srcB from decoded instruction wordsig d_rvalA 'd_regvala' # valA read from register file wordsig d_rvalB 'd_regvalb' # valB read from register file

          1. Pipeline Register E ##########################################

wordsig E_icode 'id_ex_curr->icode' # Instruction code wordsig E_ifun 'id_ex_curr->ifun' # Instruction function wordsig E_valC 'id_ex_curr->valc' # Constant data wordsig E_srcA 'id_ex_curr->srca' # Source A register ID wordsig E_valA 'id_ex_curr->vala' # Source A value wordsig E_srcB 'id_ex_curr->srcb' # Source B register ID wordsig E_valB 'id_ex_curr->valb' # Source B value wordsig E_dstE 'id_ex_curr->deste' # Destination E register ID wordsig E_dstM 'id_ex_curr->destm' # Destination M register ID

          1. Intermediate Values in Execute Stage #########################

wordsig e_valE 'ex_mem_next->vale' # valE generated by ALU boolsig e_Cnd 'ex_mem_next->takebranch' # Does condition hold? wordsig e_dstE 'ex_mem_next->deste' # dstE (possibly modified to be RNONE)

          1. Pipeline Register M #########################

wordsig M_stat 'ex_mem_curr->status' # Instruction status wordsig M_icode 'ex_mem_curr->icode' # Instruction code wordsig M_ifun 'ex_mem_curr->ifun' # Instruction function wordsig M_valA 'ex_mem_curr->vala' # Source A value wordsig M_dstE 'ex_mem_curr->deste' # Destination E register ID wordsig M_valE 'ex_mem_curr->vale' # ALU E value wordsig M_dstM 'ex_mem_curr->destm' # Destination M register ID boolsig M_Cnd 'ex_mem_curr->takebranch' # Condition flag boolsig dmem_error 'dmem_error' # Error signal from instruction memory

          1. Intermediate Values in Memory Stage ##########################

wordsig m_valM 'mem_wb_next->valm' # valM generated by memory wordsig m_stat 'mem_wb_next->status' # stat (possibly modified to be SADR)

          1. Pipeline Register W ##########################################

wordsig W_stat 'mem_wb_curr->status' # Instruction status wordsig W_icode 'mem_wb_curr->icode' # Instruction code wordsig W_dstE 'mem_wb_curr->deste' # Destination E register ID wordsig W_valE 'mem_wb_curr->vale' # ALU E value wordsig W_dstM 'mem_wb_curr->destm' # Destination M register ID wordsig W_valM 'mem_wb_curr->valm' # Memory M value

  1. Control Signal Definitions. #
                                1. Fetch Stage ###################################
    1. What address should instruction be fetched at

word f_pc = [ # Mispredicted branch. Fetch at incremented PC # backward taken error M_icode == IJXX && M_ifun != UNCOND && M_valE < M_valA && !M_Cnd : M_valA; # forward not-taken error M_icode == IJXX && M_ifun != UNCOND && M_valE >= M_valA && M_Cnd : M_valE; # Completion of RET instruction W_icode == IRET : W_valM; # Default: Use predicted value of PC 1 : F_predPC; ];

    1. Determine icode of fetched instruction

word f_icode = [ imem_error : INOP; 1: imem_icode; ];

  1. Determine ifun

word f_ifun = [ imem_error : FNONE; 1: imem_ifun; ];

  1. Is instruction valid?

bool instr_valid = f_icode in { INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ, IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ };

  1. Determine status code for fetched instruction

word f_stat = [ imem_error: SADR; !instr_valid : SINS; f_icode == IHALT : SHLT; 1 : SAOK; ];

  1. Does fetched instruction require a regid byte?

bool need_regids = f_icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IRMMOVQ, IMRMOVQ };

  1. Does fetched instruction require a constant word?

bool need_valC = f_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };

  1. Predict next value of PC

word f_predPC = [ # BBTFNT: This is where you'll change the branch prediction rule f_icode == IJXX && f_ifun != UNCOND && f_valC < f_valP : f_valC; f_icode == IJXX && f_ifun != UNCOND && f_valC >= f_valP : f_valP; f_icode in { IJXX, ICALL } : f_valC; 1 : f_valP; ];

                                1. Decode Stage ######################################


    1. What register should be used as the A source?

word d_srcA = [ D_icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ } : D_rA; D_icode in { IPOPQ, IRET } : RRSP; 1 : RNONE; # Don't need register ];

    1. What register should be used as the B source?

word d_srcB = [ D_icode in { IOPQ, IRMMOVQ, IMRMOVQ } : D_rB; D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP; 1 : RNONE; # Don't need register ];

    1. What register should be used as the E destination?

word d_dstE = [ D_icode in { IRRMOVQ, IIRMOVQ, IOPQ} : D_rB; D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP; 1 : RNONE; # Don't write any register ];

    1. What register should be used as the M destination?

word d_dstM = [ D_icode in { IMRMOVQ, IPOPQ } : D_rA; 1 : RNONE; # Don't write any register ];

    1. What should be the A value?
    2. Forward into decode stage for valA

word d_valA = [ D_icode in { ICALL, IJXX } : D_valP; # Use incremented PC d_srcA == e_dstE : e_valE; # Forward valE from execute d_srcA == M_dstM : m_valM; # Forward valM from memory d_srcA == M_dstE : M_valE; # Forward valE from memory d_srcA == W_dstM : W_valM; # Forward valM from write back d_srcA == W_dstE : W_valE; # Forward valE from write back 1 : d_rvalA; # Use value read from register file ];

word d_valB = [ d_srcB == e_dstE : e_valE; # Forward valE from execute d_srcB == M_dstM : m_valM; # Forward valM from memory d_srcB == M_dstE : M_valE; # Forward valE from memory d_srcB == W_dstM : W_valM; # Forward valM from write back d_srcB == W_dstE : W_valE; # Forward valE from write back 1 : d_rvalB; # Use value read from register file ];

                                1. Execute Stage #####################################
  1. BBTFNT: When some branches are predicted as not-taken, you need some
  2. way to get valC into pipeline register M, so that
  3. you can correct for a mispredicted branch.
    1. pass valC by M_valE, pass valP by M_valA
    1. Select input A to ALU

word aluA = [ E_icode in { IRRMOVQ, IOPQ } : E_valA; E_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ } : E_valC; E_icode in { ICALL, IPUSHQ } : -8; E_icode in { IRET, IPOPQ } : 8; E_icode in { IJXX } : E_valC; # Other instructions don't need ALU ];

    1. Select input B to ALU

word aluB = [ E_icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ } : E_valB; E_icode in { IRRMOVQ, IIRMOVQ } : 0; E_icode in { IJXX } : 0; # Other instructions don't need ALU ];

    1. Set the ALU function

word alufun = [ E_icode == IOPQ : E_ifun; 1 : ALUADD; ];

    1. Should the condition codes be updated?

bool set_cc = E_icode == IOPQ && # State changes only during normal operation !m_stat in { SADR, SINS, SHLT } && !W_stat in { SADR, SINS, SHLT };

    1. Generate valA in execute stage

word e_valA = E_valA; # Pass valA through stage

    1. Set dstE to RNONE in event of not-taken conditional move

word e_dstE = [ E_icode == IRRMOVQ && !e_Cnd : RNONE; 1 : E_dstE; ];

                                1. Memory Stage ######################################
    1. Select memory address

word mem_addr = [ M_icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ } : M_valE; M_icode in { IPOPQ, IRET } : M_valA; # Other instructions don't need address ];

    1. Set read control signal

bool mem_read = M_icode in { IMRMOVQ, IPOPQ, IRET };

    1. Set write control signal

bool mem_write = M_icode in { IRMMOVQ, IPUSHQ, ICALL };

  1. /* $begin pipe-m_stat-hcl */
    1. Update the status

word m_stat = [ dmem_error : SADR; 1 : M_stat; ];

  1. /* $end pipe-m_stat-hcl */
    1. Set E port register ID

word w_dstE = W_dstE;

    1. Set E port value

word w_valE = W_valE;

    1. Set M port register ID

word w_dstM = W_dstM;

    1. Set M port value

word w_valM = W_valM;

    1. Update processor status

word Stat = [ W_stat == SBUB : SAOK; 1 : W_stat; ];

                                1. Pipeline Register Control #########################
  1. Should I stall or inject a bubble into Pipeline Register F?
  2. At most one of these can be true.

bool F_bubble = 0; bool F_stall = # Conditions for a load/use hazard E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB } || # Stalling at fetch while ret passes through pipeline IRET in { D_icode, E_icode, M_icode };

  1. Should I stall or inject a bubble into Pipeline Register D?
  2. At most one of these can be true.

bool D_stall = # Conditions for a load/use hazard E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB };

bool D_bubble = # Mispredicted branch # backward taken error or forward not-taken error ( (E_icode == IJXX && E_ifun != UNCOND && E_valC < E_valA && !e_Cnd) || (E_icode == IJXX && E_ifun != UNCOND && E_valC >= E_valA && e_Cnd) ) || # BBTFNT: This condition will change # Stalling at fetch while ret passes through pipeline # but not condition for a load/use hazard !(E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB }) && IRET in { D_icode, E_icode, M_icode };

  1. Should I stall or inject a bubble into Pipeline Register E?
  2. At most one of these can be true.

bool E_stall = 0; bool E_bubble = # Mispredicted branch # backward taken error or forward not-taken error ( (E_icode == IJXX && E_ifun != UNCOND && E_valC < E_valA && !e_Cnd) || (E_icode == IJXX && E_ifun != UNCOND && E_valC >= E_valA && e_Cnd) ) || # BBTFNT: This condition will change # Conditions for a load/use hazard E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB};

  1. Should I stall or inject a bubble into Pipeline Register M?
  2. At most one of these can be true.

bool M_stall = 0;

  1. Start injecting bubbles as soon as exception passes through memory stage

bool M_bubble = m_stat in { SADR, SINS, SHLT } || W_stat in { SADR, SINS, SHLT };

  1. Should I stall or inject a bubble into Pipeline Register W?

bool W_stall = W_stat in { SADR, SINS, SHLT }; bool W_bubble = 0;

  1. /* $end pipe-all-hcl */