#/* $begin pipe-all-hcl */ #################################################################### # HCL Description of Control for Pipelined Y86 Processor # # Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2002 # #################################################################### #################################################################### # C Include's. Don't alter these # #################################################################### quote '#include ' 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);}' #################################################################### # Declarations. Do not change/remove/delete any of these # #################################################################### ##### Symbolic representation of Y86 Instruction Codes ############# intsig INOP 'I_NOP' intsig IHALT 'I_HALT' intsig IRRMOVL 'I_RRMOVL' intsig IIRMOVL 'I_IRMOVL' intsig IRMMOVL 'I_RMMOVL' intsig IMRMOVL 'I_MRMOVL' intsig IOPL 'I_ALU' intsig IJXX 'I_JMP' intsig ICALL 'I_CALL' intsig IRET 'I_RET' intsig IPUSHL 'I_PUSHL' intsig IPOPL 'I_POPL' ##### Symbolic representation of Y86 Registers referenced explicitly ##### intsig RESP 'REG_ESP' # Stack Pointer intsig RNONE 'REG_NONE' # Special value indicating "no register" ##### ALU Functions referenced explicitly ########################## intsig ALUADD 'A_ADD' # ALU should add its arguments ##### Signals that can be referenced by control logic ############## ##### Pipeline Register F ########################################## intsig F_predPC 'pc_curr->pc' # Predicted value of PC ##### Intermediate Values in Fetch Stage ########################### intsig f_icode 'if_id_next->icode' # Fetched instruction code intsig f_ifun 'if_id_next->ifun' # Fetched instruction function intsig f_valC 'if_id_next->valc' # Constant data of fetched instruction intsig f_valP 'if_id_next->valp' # Address of following instruction ##### Pipeline Register D ########################################## intsig D_icode 'if_id_curr->icode' # Instruction code intsig D_rA 'if_id_curr->ra' # rA field from instruction intsig D_rB 'if_id_curr->rb' # rB field from instruction intsig D_valP 'if_id_curr->valp' # Incremented PC ##### Intermediate Values in Decode Stage ######################### intsig d_srcA 'id_ex_next->srca' # srcA from decoded instruction intsig d_srcB 'id_ex_next->srcb' # srcB from decoded instruction intsig d_rvalA 'd_regvala' # valA read from register file intsig d_rvalB 'd_regvalb' # valB read from register file ##### Pipeline Register E ########################################## intsig E_icode 'id_ex_curr->icode' # Instruction code intsig E_ifun 'id_ex_curr->ifun' # Instruction function intsig E_valC 'id_ex_curr->valc' # Constant data intsig E_srcA 'id_ex_curr->srca' # Source A register ID intsig E_valA 'id_ex_curr->vala' # Source A value intsig E_srcB 'id_ex_curr->srcb' # Source B register ID intsig E_valB 'id_ex_curr->valb' # Source B value intsig E_dstE 'id_ex_curr->deste' # Destination E register ID intsig E_dstM 'id_ex_curr->destm' # Destination M register ID ##### Intermediate Values in Execute Stage ######################### intsig e_valE 'ex_mem_next->vale' # valE generated by ALU boolsig e_Bch 'ex_mem_next->takebranch' # Am I about to branch? ##### Pipeline Register M ##### intsig M_icode 'ex_mem_curr->icode' # Instruction code intsig M_ifun 'ex_mem_curr->ifun' # Instruction function intsig M_valA 'ex_mem_curr->vala' # Source A value intsig M_dstE 'ex_mem_curr->deste' # Destination E register ID intsig M_valE 'ex_mem_curr->vale' # ALU E value intsig M_dstM 'ex_mem_curr->destm' # Destination M register ID boolsig M_Bch 'ex_mem_curr->takebranch' # Branch Taken flag ##### Intermediate Values in Memory Stage ########################## intsig m_valM 'mem_wb_next->valm' # valM generated by memory ##### Pipeline Register W ########################################## intsig W_icode 'mem_wb_curr->icode' # Instruction code intsig W_dstE 'mem_wb_curr->deste' # Destination E register ID intsig W_valE 'mem_wb_curr->vale' # ALU E value intsig W_dstM 'mem_wb_curr->destm' # Destination M register ID intsig W_valM 'mem_wb_curr->valm' # Memory M value #################################################################### # Control Signal Definitions. # #################################################################### ################ Fetch Stage ################################### ## What address should instruction be fetched at int f_pc = [ # Mispredicted branch. Fetch at incremented PC M_icode == IJXX && !M_Bch : M_valA; # Completion of RET instruction. W_icode == IRET : W_valM; # Default: Use predicted value of PC 1 : F_predPC; ]; # Does fetched instruction require a regid byte? bool need_regids = f_icode in { IRRMOVL, IOPL, IPUSHL, IPOPL, IIRMOVL, IRMMOVL, IMRMOVL }; # Does fetched instruction require a constant word? bool need_valC = f_icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL }; bool instr_valid = f_icode in { INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL, IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL }; # Predict next value of PC int new_F_predPC = [ f_icode in { IJXX, ICALL } : f_valC; 1 : f_valP; ]; ################ Decode Stage ###################################### ## What register should be used as the A source? int new_E_srcA = [ D_icode in { IRRMOVL, IRMMOVL, IOPL, IPUSHL } : D_rA; D_icode in { IPOPL, IRET } : RESP; 1 : RNONE; # Don't need register ]; ## What register should be used as the B source? int new_E_srcB = [ D_icode in { IOPL, IRMMOVL, IMRMOVL } : D_rB; D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP; 1 : RNONE; # Don't need register ]; ## What register should be used as the E destination? int new_E_dstE = [ D_icode in { IRRMOVL, IIRMOVL, IOPL} : D_rB; D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP; 1 : RNONE; # Don't need register ]; ## What register should be used as the M destination? int new_E_dstM = [ D_icode in { IMRMOVL, IPOPL } : D_rA; 1 : RNONE; # Don't need register ]; ## What should be the A value? ## Forward into decode stage for valA int new_E_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 ]; int new_E_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 ]; ################ Execute Stage ##################################### ## Select input A to ALU int aluA = [ E_icode in { IRRMOVL, IOPL } : E_valA; E_icode in { IIRMOVL, IRMMOVL, IMRMOVL } : E_valC; E_icode in { ICALL, IPUSHL } : -4; E_icode in { IRET, IPOPL } : 4; # Other instructions don't need ALU ]; ## Select input B to ALU int aluB = [ E_icode in { IRMMOVL, IMRMOVL, IOPL, ICALL, IPUSHL, IRET, IPOPL } : E_valB; E_icode in { IRRMOVL, IIRMOVL } : 0; # Other instructions don't need ALU ]; ## Set the ALU function int alufun = [ E_icode == IOPL : E_ifun; 1 : ALUADD; ]; ## Should the condition codes be updated? bool set_cc = E_icode == IOPL; ################ Memory Stage ###################################### ## Select memory address int mem_addr = [ M_icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : M_valE; M_icode in { IPOPL, IRET } : M_valA; # Other instructions don't need address ]; ## Set read control signal bool mem_read = M_icode in { IMRMOVL, IPOPL, IRET }; ## Set write control signal bool mem_write = M_icode in { IRMMOVL, IPUSHL, ICALL }; ################ Pipeline Register Control ######################### # Should I stall or inject a bubble into Pipeline Register F? # At most one of these can be true. bool F_bubble = 0; bool F_stall = # Conditions for a load/use hazard E_icode in { IMRMOVL, IPOPL } && E_dstM in { d_srcA, d_srcB } || # Stalling at fetch while ret passes through pipeline IRET in { D_icode, E_icode, M_icode }; # Should I stall or inject a bubble into Pipeline Register D? # At most one of these can be true. bool D_stall = # Conditions for a load/use hazard E_icode in { IMRMOVL, IPOPL } && E_dstM in { d_srcA, d_srcB }; bool D_bubble = # Mispredicted branch (E_icode == IJXX && !e_Bch) || # Stalling at fetch while ret passes through pipeline # but not condition for a load/use hazard !(E_icode in { IMRMOVL, IPOPL } && E_dstM in { d_srcA, d_srcB }) && IRET in { D_icode, E_icode, M_icode }; # Should I stall or inject a bubble into Pipeline Register E? # At most one of these can be true. bool E_stall = 0; bool E_bubble = # Mispredicted branch (E_icode == IJXX && !e_Bch) || # Conditions for a load/use hazard E_icode in { IMRMOVL, IPOPL } && E_dstM in { d_srcA, d_srcB}; # Should I stall or inject a bubble into Pipeline Register M? # At most one of these can be true. bool M_stall = 0; bool M_bubble = 0; #/* $end pipe-all-hcl */