Created
October 15, 2013 04:12
-
-
Save phoeagon/6986365 to your computer and use it in GitHub Desktop.
pipe-full.hcl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/* $begin pipe-all-hcl */ | |
#################################################################### | |
# HCL Description of Control for Pipelined Y86 Processor # | |
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2002 # | |
#################################################################### | |
## Your task is to implement the iaddl and leave instructions | |
## The file contains a declaration of the icodes | |
## for iaddl (IIADDL) and leave (ILEAVE). | |
## Your job is to add the rest of the logic to make it work | |
# | |
# | |
# Qiu Zhe | |
# * implements LEAVE and IADDL instructions | |
# * implements Load Forward | |
# | |
# | |
#################################################################### | |
# 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);}' | |
#################################################################### | |
# 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' | |
# Instruction code for iaddl instruction | |
intsig IIADDL 'I_IADDL' | |
# Instruction code for leave instruction | |
intsig ILEAVE 'I_LEAVE' | |
##### Symbolic representation of Y86 Registers referenced explicitly ##### | |
intsig RESP 'REG_ESP' # Stack Pointer | |
intsig REBP 'REG_EBP' # Frame 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, IIADDL }; | |
# Does fetched instruction require a constant word? | |
bool need_valC = | |
f_icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL , IIADDL }; | |
bool instr_valid = f_icode in | |
{ INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL, | |
IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL, IIADDL , ILEAVE }; | |
# 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; | |
D_icode in { ILEAVE } : REBP; | |
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; | |
D_icode in { IIADDL } : D_rB; | |
D_icode in { ILEAVE } : REBP; | |
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 , IIADDL} : D_rB; | |
D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP; | |
D_icode in { ILEAVE } : 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; | |
D_icode in { ILEAVE } : REBP; | |
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 , IIADDL } : E_valC; | |
E_icode in { ICALL, IPUSHL } : -4; | |
E_icode in { IRET, IPOPL , ILEAVE } : 4; | |
# Other instructions don't need ALU | |
]; | |
## Select input B to ALU | |
int aluB = [ | |
E_icode in { IRMMOVL, IMRMOVL, IOPL, ICALL, | |
IPUSHL, IRET, IPOPL , IIADDL , ILEAVE } : 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 in { IOPL , IIADDL , IIADDL }; | |
## Generate M_valA | |
## LB: With load forwarding, want to insert valM | |
## from memory stage when appropriate | |
## Here it is set to the default used in the normal pipeline | |
int new_M_valA = [ | |
M_dstM in { E_srcA } && E_icode in { IPUSHL, IRMMOVL } : m_valM; | |
# Use valA | |
1 : E_valA; | |
]; | |
################ Memory Stage ###################################### | |
## Select memory address | |
int mem_addr = [ | |
M_icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : M_valE; | |
M_icode in { IPOPL, IRET , ILEAVE } : M_valA; | |
# Other instructions don't need address | |
]; | |
## Set read control signal | |
bool mem_read = M_icode in { IMRMOVL, IPOPL, IRET , ILEAVE }; | |
## 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 , ILEAVE } && | |
( E_dstM in { d_srcB } || | |
( !D_icode in { IRMMOVL, IPUSHL , ILEAVE } && E_dstM in { d_srcA }) ) ) || | |
# 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 , ILEAVE } && | |
( E_dstM in { d_srcB } || | |
( !D_icode in { IRMMOVL, IPUSHL } && E_dstM in { d_srcA }) ); | |
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 , ILEAVE } && 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 , ILEAVE } && | |
( E_dstM in { d_srcB } || | |
( !D_icode in { IRMMOVL, IPUSHL , ILEAVE } && E_dstM in { d_srcA }) ) ); | |
# 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 */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment