ArchLab PartB具體思路及實驗過程講解
阿新 • • 發佈:2018-12-01
extend the SEQ processor
1. 相關檔案: seq-full.hcl
2. 指令分析: 將指令 iaddl 和 leave 按照順序執行 CPU 的六個流程分解如下。
stage | iaddl | leave |
---|---|---|
Fetch | icode:ifun <- [PC] | icode:ifun <- [PC] |
rA:rB <- [PC+1] | ||
valC <- [PC+2] | ||
valP <- PC+6 | valP <- PC+1 | |
Decode | valA <- R[%ebp] | |
valB <- R[rB] | valB <- R[%ebp] | |
Execute | valE <- valB+valC | valE <- valB+4 |
Set CC | ||
Memory | valM <- [valA] | |
Write back | R[rB] <- valE | R[%esp] <- valE |
R[%ebp] <- valM | ||
PC update | PC <- valP | PC <- valP |
3. seq-ful.hcl 修改說明
- 在 instr_valid 新增 IIADDL 和 ILEAVE 讓指令有效。
bool instr_valid = icode in
{ INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL,
IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL, IIADDL, ILEAVE };
- 在 need_regids 新增 IIADDL。leave 指令不需要暫存器引數。
bool need_regids =
icode in { IRRMOVL, IOPL, IPUSHL, IPOPL,
IIRMOVL, IRMMOVL, IMRMOVL, IIADDL };
- 在 need_valC 新增 IIADDL。leave 指令不需要常數引數。
bool need_valC =
icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL, IIADDL };
- srcA 中,iaddl 指令無需設定,leave 指令設為 REBP。
int srcA = [
icode in { IRRMOVL, IRMMOVL, IOPL, IPUSHL } : rA;
icode in { IPOPL, IRET } : RESP;
icode in { ILEAVE } : REBP;
1 : RNONE; # Don't need register
];
- srcB 中,iaddl 指令設為 rB,leave 指令設為 REBP。
int srcB = [
icode in { IOPL, IRMMOVL, IMRMOVL, IIADDL } : rB;
icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP;
icode in { ILEAVE } : REBP;
1 : RNONE; # Don't need register
];
- dstE 中,iaddl 指令設為 rB,leave 指令設為 RESP。
int dstE = [
icode in { IRRMOVL } && Cnd : rB;
icode in { IIRMOVL, IOPL, IIADDL} : rB;
icode in { IPUSHL, IPOPL, ICALL, IRET, ILEAVE } : RESP;
1 : RNONE; # Don't write any register
];
- dstM 中,iaddl 指令無需設定,leave 指令設為 REBP。
int dstM = [
icode in { IMRMOVL, IPOPL } : rA;
icode in { ILEAVE } : REBP;
1 : RNONE; # Don't write any register
];
- aluA 中,iaddl 指令設為 valC, leave 指令設為 4。
int aluA = [
icode in { IRRMOVL, IOPL } : valA;
icode in { IIRMOVL, IRMMOVL, IMRMOVL, IIADDL } : valC;
icode in { ICALL, IPUSHL } : -4;
icode in { IRET, IPOPL, ILEAVE } : 4;
# Other instructions don't need ALU
];
- aluB 中,iaddl 指令和 leave 指令均設為 valB。
int aluB = [
icode in { IRMMOVL, IMRMOVL, IOPL, ICALL,
IPUSHL, IRET, IPOPL, IIADDL, ILEAVE } : valB;
icode in { IRRMOVL, IIRMOVL } : 0;
# Other instructions don't need ALU
];
- 在 set_cc 中新增 IIADDL,leave 指令不影響標誌位。
bool set_cc = icode in { IOPL, IIADDL };
- 在 mem_read 中新增 ILEAVE,iaddl 指令無需訪存。
bool mem_read = icode in { IMRMOVL, IPOPL, IRET, ILEAVE };
- mem_addr 中,leave 指令設為 valA,iaddl 指令無需設定。
int mem_addr = [
icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : valE;
icode in { IPOPL, IRET, ILEAVE } : valA;
# Other instructions don't need address
];
extend the PIPE processor
1. 相關檔案: pipe-full.hcl
2. 指令分析: 與順序流水線類似,需要注意的是,leave 存在載入/使用冒險,故應該在 F 階插入 stall,D 階段插入 stall,E 階段插入 bubble。
3. seq-ful.hcl 修改說明
- 在 instr_valid 新增 IIADDL 和 ILEAVE 讓指令有效。
bool instr_valid = f_icode in
{ INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL,
IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL, IIADDL, ILEAVE };
- 在 need_regids 新增 IIADDL。leave 指令不需要暫存器引數。
bool need_regids =
f_icode in { IRRMOVL, IOPL, IPUSHL, IPOPL,
IIRMOVL, IRMMOVL, IMRMOVL, IIADDL };
- 在 need_valC 新增 IIADDL。leave 指令不需要常數引數。
bool need_valC =
f_icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL, IIADDL };
- d_srcA 中,iaddl 指令無需設定,leave 指令設為 REBP。
int d_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
];
- d_srcB 中,iaddl 指令設為 rB,leave 指令設為 REBP。
int d_srcB = [
D_icode in { IOPL, IRMMOVL, IMRMOVL, IIADDL } : D_rB;
D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP;
D_icode in { ILEAVE } : REBP;
1 : RNONE; # Don't need register
];
- d_dstE 中,iaddl 指令設為 rB,leave 指令設為 RESP。
int d_dstE = [
D_icode in { IRRMOVL, IIRMOVL, IOPL, IIADDL } : D_rB;
D_icode in { IPUSHL, IPOPL, ICALL, IRET, ILEAVE } : RESP;
1 : RNONE; # Don't write any register
];
- d_dstM 中,iaddl 指令無需設定,leave 指令設為 REBP。
int d_dstM = [
D_icode in { IMRMOVL, IPOPL } : D_rA;
D_icode in { ILEAVE } : REBP;
1 : RNONE; # Don't write any register
];
- aluA 中,iaddl 指令設為 valC, leave 指令設為 4。
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
];
- aluB 中,iaddl 指令和 leave 指令均設為 valB。
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_cc 中新增 IIADDL,leave 指令不影響標誌位。
bool set_cc = E_icode in { IOPL, IIADDL } &&
# State changes only during normal operation
!m_stat in { SADR, SINS, SHLT } && !W_stat in { SADR, SINS, SHLT };
- mem_addr 中,leave 指令設為 valA,iaddl 指令無需設定。
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
];
- 在 mem_read 中新增 ILEAVE,iaddl 指令無需訪存。
bool mem_read = M_icode in { IMRMOVL, IPOPL, IRET, ILEAVE };
- 在 F_stall 的 E_icode 條件中新增 ILEAVE,iaddl 指令不存在載入/使用冒險。
bool F_stall =
# Conditions for a load/use hazard
E_icode in { IMRMOVL, IPOPL, ILEAVE } &&
E_dstM in { d_srcA, d_srcB } ||
# Stalling at fetch while ret passes through pipeline
IRET in { D_icode, E_icode, M_icode };
- 在 D_stall 的 E_icode 條件中新增 ILEAVE,iaddl 指令不存在載入/使用冒險。
bool D_stall =
# Conditions for a load/use hazard
E_icode in { IMRMOVL, IPOPL, ILEAVE } &&
E_dstM in { d_srcA, d_srcB };
- 在 D_bullle 的 E_icode 條件中新增 ILEAVE,防止插入 D_bubble。iaddl 指令不存在
載入/使用冒險。
bool D_bubble =
# Mispredicted branch
(E_icode == IJXX && !e_Cnd) ||
# 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 };
- 在 E_bubble 的 E_icode 條件中新增 ILEAVE,iaddl 指令不存在載入/使用冒險。
bool E_bubble =
# Mispredicted branch
(E_icode == IJXX && !e_Cnd) ||
# Conditions for a load/use hazard
E_icode in { IMRMOVL, IPOPL, ILEAVE } &&
E_dstM in { d_srcA, d_srcB};