CSAPP第四章家庭作业参考答案
(CSAPP第三版系列)导航篇传送门
4.46
A. 这段代码序列没有正确描述指令popq %rsp的行为。该段代码序列使%rsp的值为(%rsp)+8,而指令popq%rsp执行后,%rsp的值应为(%rsp)。
B. 改写代码序列:
addq $8 , %rsp
movq-8(%rsp) , REG
4.48
冒泡排序函数的测试和交换(6-11行)代码:
if(data[i+1] < data[i]){/*Swap adjacent elements*/long t = data[i+1];data[i+1] = data[i];data[i] = t;
}
对应的Y86-64代码修改为条件转移,代码如下:
mrmovq (%rdx), %r8
rrmovq %rdx, %rsi
addq %r10, %rsi
mrmovq (%rsi), %rcx
rrmovq %rcx, %r10
subq %r8, %r10
rrmovq %rcx, %r10
cmovl %r8, %r10
rmmovq %r10, (%rsi)
rrmovq %r8, %r10
cmovl %rcx, %r10
rmmovq %r10, (%rdx)
4.50
Y86-64代码如下:
# Execution begins at address 0 .pos 0irmovq stack, %rsp # Set up stack pointercall main # Execute main programhalt # Terminate program
# Array of 8 elements.align 8
vals: .quad 0x000000000000.quad 0x000000000000.quad 0x000000000000.quad 0x000000000000.quad 0x000000000000.quad 0x000000000000.quad 0x000000000000.quad 0x000000000000jump_table:.quad L1.quad L4.quad L2.quad L3.quad L4.quad L2main: irmovq vals, %r12irmovq $-1,%rdicall switchv rmmovq %rax, (%r12)irmovq $0,%rdicall switchv rmmovq %rax, 0x8(%r12)irmovq $1,%rdicall switchv rmmovq %rax, 0x10(%r12)irmovq $2,%rdicall switchv rmmovq %rax, 0x18(%r12)irmovq $3,%rdicall switchv rmmovq %rax, 0x20(%r12)irmovq $4,%rdicall switchv rmmovq %rax, 0x28(%r12)irmovq $5,%rdicall switchv rmmovq %rax, 0x30(%r12)irmovq $6,%rdicall switchv rmmovq %rax, 0x38(%r12)ret# long switchv(long idx)
# idx in %rdi
switchv:rrmovq %rdi, %r8irmovq $5, %r9subq %r9, %r8jg L4andq %rdi, %rdijl L4irmovq jump_table, %r8irmovq $8, %r9irmovq $1, %r10
loop:subq %r10, %rdijl endloopaddq %r9, %r8jmp loop
endloop:mrmovq (%r8), %r8pushq %r8ret L1: irmovq 0xaaa, %raxret
L2: irmovq 0xbbb, %raxret
L3:irmovq 0xccc, %raxret
L4:irmovq 0xddd, %rax #defaultret# Stack starts here and grows to lower addresses.pos 0x300 #栈开始地址不能太小
stack:
测试结果截图:
4.52
设计思想:
分析seq-full.hcl,需要对Instr_valid, need_regids, need_valC, srcB, dstE, aluA, aluB进行修改。
bool Instr_valid = icode in{…}; 大括号中所列指令需加上IIADDQ
bool need_regids = icode in{…}; 大括号中所列指令需加上IIADDQ
bool need_valC = icode in{…}; 大括号中所列指令需加上IIADDQ
word srcB = [
icode in {…} : rB; 大括号中所列指令需加上IIADDQ
…
];
word dstE = [
…
icode in {…} : rB; 大括号中所列指令需加上IIADDQ
…
];
word aluA = [
…
icode in {… } : valC; 大括号中所列指令需加上IIADDQ
…
];
word aluB = [
icode in { … } : valB; 大括号中所列指令需加上IIADDQ
…
];
添加IIADDQ指令后seq-full.hcl文件:
#/* $begin seq-all-hcl */
####################################################################
# HCL Description of Control for Single Cycle Y86-64 Processor SEQ #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010 #
###################################################################### Your task is to implement the iaddq instruction
## The file contains a declaration of the icodes
## for iaddq (IIADDQ)
## Your job is to add the rest of the logic to make it work####################################################################
# C Include's. Don't alter these #
####################################################################quote '#include <stdio.h>'
quote '#include "isa.h"'
quote '#include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'word_t gen_pc(){return 0;}'
quote 'int main(int argc, char *argv[])'
quote ' {plusmode=0;return sim_main(argc,argv);}'####################################################################
# Declarations. Do not change/remove/delete any of these #
######################################################################### 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'
# Instruction code for iaddq instruction
wordsig IIADDQ 'I_IADDQ'##### Symbolic represenations of Y86-64 function codes #####
wordsig FNONE 'F_NONE' # Default function code##### Symbolic representation of Y86-64 Registers referenced explicitly #####
wordsig RRSP 'REG_RSP' # Stack Pointer
wordsig RNONE 'REG_NONE' # Special value indicating "no register"##### ALU Functions referenced explicitly #####
wordsig ALUADD 'A_ADD' # ALU should add its arguments##### Possible instruction status values #####
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##### Signals that can be referenced by control logic ######################### Fetch stage inputs #####
wordsig pc 'pc' # Program counter
##### Fetch stage computations #####
wordsig imem_icode 'imem_icode' # icode field from instruction memory
wordsig imem_ifun 'imem_ifun' # ifun field from instruction memory
wordsig icode 'icode' # Instruction control code
wordsig ifun 'ifun' # Instruction function
wordsig rA 'ra' # rA field from instruction
wordsig rB 'rb' # rB field from instruction
wordsig valC 'valc' # Constant from instruction
wordsig valP 'valp' # Address of following instruction
boolsig imem_error 'imem_error' # Error signal from instruction memory
boolsig instr_valid 'instr_valid' # Is fetched instruction valid?##### Decode stage computations #####
wordsig valA 'vala' # Value from register A port
wordsig valB 'valb' # Value from register B port##### Execute stage computations #####
wordsig valE 'vale' # Value computed by ALU
boolsig Cnd 'cond' # Branch test##### Memory stage computations #####
wordsig valM 'valm' # Value read from memory
boolsig dmem_error 'dmem_error' # Error signal from data memory####################################################################
# Control Signal Definitions. #
#################################################################################### Fetch Stage #################################### Determine instruction code
word icode = [imem_error: INOP;1: imem_icode; # Default: get from instruction memory
];# Determine instruction function
word ifun = [imem_error: FNONE;1: imem_ifun; # Default: get from instruction memory
];bool instr_valid = icode in { INOP, IHALT, IRRMOVQ, IIRMOVQ, IIADDQ, IRMMOVQ, IMRMOVQ,IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ };# Does fetched instruction require a regid byte?
bool need_regids =icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IIADDQ, IRMMOVQ, IMRMOVQ };# Does fetched instruction require a constant word?
bool need_valC =icode in { IIRMOVQ, IIADDQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };################ Decode Stage ##################################### What register should be used as the A source?
word srcA = [icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ } : rA;icode in { IPOPQ, IRET } : RRSP;1 : RNONE; # Don't need register
];## What register should be used as the B source?
word srcB = [icode in { IOPQ, IRMMOVQ, IMRMOVQ, IIADDQ } : rB;icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;1 : RNONE; # Don't need register
];## What register should be used as the E destination?
word dstE = [icode in { IRRMOVQ } && Cnd : rB;icode in { IIRMOVQ, IOPQ, IIADDQ} : rB;icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;1 : RNONE; # Don't write any register
];## What register should be used as the M destination?
word dstM = [icode in { IMRMOVQ, IPOPQ } : rA;1 : RNONE; # Don't write any register
];################ Execute Stage ##################################### Select input A to ALU
word aluA = [icode in { IRRMOVQ, IOPQ } : valA;icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IIADDQ } : valC;icode in { ICALL, IPUSHQ } : -8;icode in { IRET, IPOPQ } : 8;# Other instructions don't need ALU
];## Select input B to ALU
word aluB = [icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ, IIADDQ } : valB;icode in { IRRMOVQ, IIRMOVQ } : 0;# Other instructions don't need ALU
];## Set the ALU function
word alufun = [icode == IOPQ : ifun;1 : ALUADD;
];## Should the condition codes be updated?
bool set_cc = icode in { IOPQ, IIADDQ };################ Memory Stage ##################################### Set read control signal
bool mem_read = icode in { IMRMOVQ, IPOPQ, IRET };## Set write control signal
bool mem_write = icode in { IRMMOVQ, IPUSHQ, ICALL };## Select memory address
word mem_addr = [icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ } : valE;icode in { IPOPQ, IRET } : valA;# Other instructions don't need address
];## Select memory input data
word mem_data = [# Value from registericode in { IRMMOVQ, IPUSHQ } : valA;# Return PCicode == ICALL : valP;# Default: Don't write anything
];## Determine instruction status
word Stat = [imem_error || dmem_error : SADR;!instr_valid: SINS;icode == IHALT : SHLT;1 : SAOK;
];################ Program Counter Update ############################## What address should instruction be fetched atword new_pc = [# Call. Use instruction constanticode == ICALL : valC;# Taken branch. Use instruction constanticode == IJXX && Cnd : valC;# Completion of RET instruction. Use value from stackicode == IRET : valM;# Default: Use incremented PC1 : valP;
];
#/* $end seq-all-hcl */
模拟器测试结果截图(ISA Check Succeeds):
4.54
设计思想:
分析pipe-full.hcl,需要对Instr_valid, need_regids, need_valC, srcB, dstE, aluA, aluB, set_cc进行修改。
bool Instr_valid = ficode in{…}; 大括号中所列指令需加上IIADDQ
bool need_regids = ficode in{…}; 大括号中所列指令需加上IIADDQ
bool need_valC = ficode in{…}; 大括号中所列指令需加上IIADDQ
word d_srcB = [
D_icode in {…} : D_rB; 大括号中所列指令需加上IIADDQ
…
];
word d_dstE = [
D_icode in {…} : D_rB; 大括号中所列指令需加上IIADDQ
…
];
word aluA = [
…
E_icode in {… } : E_valC; 大括号中所列指令需加上IIADDQ
…
];
word aluB = [
icode in { … } : E_valB; 大括号中所列指令需加上IIADDQ
…
];
bool set_cc = E_icode == IOPQ && …改为:
boolset_cc = (E_icode == IOPQ || E_icode == IIADDQ) &&…
修改后pipe-full.hcl文件:
#/* $begin pipe-all-hcl */
####################################################################
# HCL Description of Control for Pipelined Y86-64 Processor #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2014 #
###################################################################### Your task is to implement the iaddq instruction
## The file contains a declaration of the icodes
## for iaddq (IIADDQ)
## Your job is to add the rest of the logic to make it work####################################################################
# 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-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'
# Instruction code for iaddq instruction
wordsig IIADDQ 'I_IADDQ'##### Symbolic represenations of Y86-64 function codes #####
wordsig FNONE 'F_NONE' # Default function code##### Symbolic representation of Y86-64 Registers referenced #####
wordsig RRSP 'REG_RSP' # Stack Pointer
wordsig RNONE 'REG_NONE' # Special value indicating "no register"##### ALU Functions referenced explicitly ##########################
wordsig ALUADD 'A_ADD' # ALU should add its arguments##### 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##### Signals that can be referenced by control logic ################### Pipeline Register F ##########################################wordsig F_predPC 'pc_curr->pc' # Predicted value of PC##### 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?##### 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##### 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##### 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##### 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)##### 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##### 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)##### 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####################################################################
# Control Signal Definitions. #
#################################################################################### Fetch Stage ##################################### What address should instruction be fetched at
word f_pc = [# Mispredicted branch. Fetch at incremented PCM_icode == IJXX && !M_Cnd : M_valA;# Completion of RET instructionW_icode == IRET : W_valM;# Default: Use predicted value of PC1 : F_predPC;
];## Determine icode of fetched instruction
word f_icode = [imem_error : INOP;1: imem_icode;
];# Determine ifun
word f_ifun = [imem_error : FNONE;1: imem_ifun;
];# Is instruction valid?
bool instr_valid = f_icode in { INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ, IIADDQ };# Determine status code for fetched instruction
word f_stat = [imem_error: SADR;!instr_valid : SINS;f_icode == IHALT : SHLT;1 : SAOK;
];# Does fetched instruction require a regid byte?
bool need_regids =f_icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IRMMOVQ, IMRMOVQ, IIADDQ };# Does fetched instruction require a constant word?
bool need_valC =f_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL, IIADDQ };# Predict next value of PC
word f_predPC = [f_icode in { IJXX, ICALL } : f_valC;1 : f_valP;
];################ Decode Stage ######################################## 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
];## What register should be used as the B source?
word d_srcB = [D_icode in { IOPQ, IRMMOVQ, IMRMOVQ, IIADDQ } : D_rB;D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;1 : RNONE; # Don't need register
];## What register should be used as the E destination?
word d_dstE = [D_icode in { IRRMOVQ, IIRMOVQ, IOPQ, IIADDQ} : D_rB;D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } : RRSP;1 : RNONE; # Don't write any register
];## 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
];## What should be the A value?
## Forward into decode stage for valA
word d_valA = [D_icode in { ICALL, IJXX } : D_valP; # Use incremented PCd_srcA == e_dstE : e_valE; # Forward valE from executed_srcA == M_dstM : m_valM; # Forward valM from memoryd_srcA == M_dstE : M_valE; # Forward valE from memoryd_srcA == W_dstM : W_valM; # Forward valM from write backd_srcA == W_dstE : W_valE; # Forward valE from write back1 : d_rvalA; # Use value read from register file
];word d_valB = [d_srcB == e_dstE : e_valE; # Forward valE from executed_srcB == M_dstM : m_valM; # Forward valM from memoryd_srcB == M_dstE : M_valE; # Forward valE from memoryd_srcB == W_dstM : W_valM; # Forward valM from write backd_srcB == W_dstE : W_valE; # Forward valE from write back1 : d_rvalB; # Use value read from register file
];################ Execute Stage ####################################### Select input A to ALU
word aluA = [E_icode in { IRRMOVQ, IOPQ } : E_valA;E_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IIADDQ } : E_valC;E_icode in { ICALL, IPUSHQ } : -8;E_icode in { IRET, IPOPQ } : 8;# Other instructions don't need ALU
];## Select input B to ALU
word aluB = [E_icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ, IIADDQ } : E_valB;E_icode in { IRRMOVQ, IIRMOVQ } : 0;# Other instructions don't need ALU
];## Set the ALU function
word alufun = [E_icode == IOPQ : E_ifun;1 : ALUADD;
];## Should the condition codes be updated?
bool set_cc = (E_icode == IOPQ || E_icode == IIADDQ) &&# State changes only during normal operation!m_stat in { SADR, SINS, SHLT } && !W_stat in { SADR, SINS, SHLT };## Generate valA in execute stage
word e_valA = E_valA; # Pass valA through stage## Set dstE to RNONE in event of not-taken conditional move
word e_dstE = [E_icode == IRRMOVQ && !e_Cnd : RNONE;1 : E_dstE;
];################ Memory Stage ######################################## 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
];## Set read control signal
bool mem_read = M_icode in { IMRMOVQ, IPOPQ, IRET };## Set write control signal
bool mem_write = M_icode in { IRMMOVQ, IPUSHQ, ICALL };#/* $begin pipe-m_stat-hcl */
## Update the status
word m_stat = [dmem_error : SADR;1 : M_stat;
];
#/* $end pipe-m_stat-hcl */## Set E port register ID
word w_dstE = W_dstE;## Set E port value
word w_valE = W_valE;## Set M port register ID
word w_dstM = W_dstM;## Set M port value
word w_valM = W_valM;## Update processor status
word Stat = [W_stat == SBUB : SAOK;1 : W_stat;
];################ 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 hazardE_icode in { IMRMOVQ, IPOPQ } &&E_dstM in { d_srcA, d_srcB } ||# Stalling at fetch while ret passes through pipelineIRET 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 hazardE_icode in { IMRMOVQ, IPOPQ } &&E_dstM in { d_srcA, d_srcB };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 { IMRMOVQ, IPOPQ } && 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_Cnd) ||# Conditions for a load/use hazardE_icode in { IMRMOVQ, IPOPQ } &&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;
# 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 };# Should I stall or inject a bubble into Pipeline Register W?
bool W_stall = W_stat in { SADR, SINS, SHLT };
bool W_bubble = 0;
#/* $end pipe-all-hcl */
模拟器测试结果截图(ISA Checks Succeed):
4.56
设计思想:
分析pipe-btfnt.hcl,需要对f_pc, fpredPC, aluA, aluB, D_bubble, E_bubble进行修改。
word f_pc = [
M_icode == IJXX && !M_Cnd : M_valA;
W_icode == IRET : W_valM;
1 : F_predPC;
];
修改为:
word f_pc = [
M_icode == IJXX && M_ifun != UNCOND&& M_valE < M_valA && !M_Cnd : M_valA;
W_icode == IJXX && M_ifun != UNCOND&& M_valE >= M_valA && M_Cnd : M_valE;
W_icode == IRET : W_valM;
1 : F_predPC;
];
word f_predPC = [
f_icode in { IJXX, ICALL } : f_valC;
1 : f_valP;
];
修改为:
word f_predPC = [
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;
];
word aluA = [
…
E_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ } :E_valC;大括号列指令需加上IJXX
…
];
word aluB = [
…
E_icode in { IRRMOVQ, IIRMOVQ } :0;大括号列指令需加上IJXX
…
];
bool D_bubble =
(E_icode == IJXX && !e_Cnd) || !(E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB })&& IRET in { D_icode, E_icode, M_icode };
修改为:
bool D_bubble =
(E_icode == IJXX && E_ifun !=UNCOND && E_valC < E_valA && !e_Cnd) || (E_icode == IJXX && E_ifun !=UNCOND && E_valC >= E_valA && e_Cnd)||! (E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB })&& IRET in { D_icode, E_icode, M_icode };
bool E_bubble =
(E_icode == IJXX && !e_Cnd) ||E_icode in { IMRMOVQ, IPOPQ } && E_dstM in { d_srcA, d_srcB };
修改为:
bool E_bubble =
(E_icode== IJXX && E_ifun != UNCOND && E_valC < E_valA &&!e_Cnd) || (E_icode == IJXX && E_ifun != UNCOND && E_valC >=E_valA && e_Cnd)|| E_icode in { IMRMOVQ, IPOPQ} && E_dstM in { d_srcA, d_srcB };
修改后pipe-btfnt.hcl文件:
#/* $begin pipe-all-hcl */
####################################################################
# HCL Description of Control for Pipelined Y86-64 Processor #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2014 #
###################################################################### Your task is to modify the design so that conditional branches are
## predicted as being taken when backward and not-taken when forward
## The code here is nearly identical to that for the normal pipeline.
## Comments starting with keyword "BBTFNT" have been added at places
## relevant to the exercise.####################################################################
# 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-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'##### Symbolic represenations of Y86-64 function codes #####
wordsig FNONE 'F_NONE' # Default function code##### Symbolic representation of Y86-64 Registers referenced #####
wordsig RRSP 'REG_RSP' # Stack Pointer
wordsig RNONE 'REG_NONE' # Special value indicating "no register"##### ALU Functions referenced explicitly ##########################
wordsig ALUADD 'A_ADD' # ALU should add its arguments
## BBTFNT: For modified branch prediction, need to distinguish
## conditional vs. unconditional branches
##### Jump conditions referenced explicitly
wordsig UNCOND 'C_YES' # Unconditional transfer##### 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##### Signals that can be referenced by control logic ################### Pipeline Register F ##########################################wordsig F_predPC 'pc_curr->pc' # Predicted value of PC##### 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?##### 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##### 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##### 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##### 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)##### 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##### 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)##### 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####################################################################
# Control Signal Definitions. #
#################################################################################### Fetch Stage ##################################### What address should instruction be fetched at
word f_pc = [# Mispredicted branch. Fetch at incremented PC# backwardM_icode == IJXX && M_ifun != UNCOND && M_valE < M_valA && !M_Cnd : M_valA;# forwardM_icode == IJXX && M_ifun != UNCOND && M_valE >= M_valA && M_Cnd : M_valE;# Completion of RET instructionW_icode == IRET : W_valM;# Default: Use predicted value of PC1 : F_predPC;
];## Determine icode of fetched instruction
word f_icode = [imem_error : INOP;1: imem_icode;
];# Determine ifun
word f_ifun = [imem_error : FNONE;1: imem_ifun;
];# Is instruction valid?
bool instr_valid = f_icode in { INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ };# Determine status code for fetched instruction
word f_stat = [imem_error: SADR;!instr_valid : SINS;f_icode == IHALT : SHLT;1 : SAOK;
];# Does fetched instruction require a regid byte?
bool need_regids =f_icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IRMMOVQ, IMRMOVQ };# Does fetched instruction require a constant word?
bool need_valC =f_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };# Predict next value of PC
word f_predPC = [# BBTFNT: This is where you'll change the branch prediction rulef_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;
];################ Decode Stage ######################################## 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
];## 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
];## 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
];## 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
];## What should be the A value?
## Forward into decode stage for valA
word d_valA = [D_icode in { ICALL, IJXX } : D_valP; # Use incremented PCd_srcA == e_dstE : e_valE; # Forward valE from executed_srcA == M_dstM : m_valM; # Forward valM from memoryd_srcA == M_dstE : M_valE; # Forward valE from memoryd_srcA == W_dstM : W_valM; # Forward valM from write backd_srcA == W_dstE : W_valE; # Forward valE from write back1 : d_rvalA; # Use value read from register file
];word d_valB = [d_srcB == e_dstE : e_valE; # Forward valE from executed_srcB == M_dstM : m_valM; # Forward valM from memoryd_srcB == M_dstE : M_valE; # Forward valE from memoryd_srcB == W_dstM : W_valM; # Forward valM from write backd_srcB == W_dstE : W_valE; # Forward valE from write back1 : d_rvalB; # Use value read from register file
];################ Execute Stage ###################################### BBTFNT: When some branches are predicted as not-taken, you need some
# way to get valC into pipeline register M, so that
# you can correct for a mispredicted branch.## Select input A to ALU
word aluA = [E_icode in { IRRMOVQ, IOPQ } : E_valA;E_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX } : E_valC;E_icode in { ICALL, IPUSHQ } : -8;E_icode in { IRET, IPOPQ } : 8;# Other instructions don't need ALU
];## Select input B to ALU
word aluB = [E_icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ } : E_valB;E_icode in { IRRMOVQ, IIRMOVQ, IJXX } : 0;# Other instructions don't need ALU
];## Set the ALU function
word alufun = [E_icode == IOPQ : E_ifun;1 : ALUADD;
];## 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 };## Generate valA in execute stage
word e_valA = E_valA; # Pass valA through stage## Set dstE to RNONE in event of not-taken conditional move
word e_dstE = [E_icode == IRRMOVQ && !e_Cnd : RNONE;1 : E_dstE;
];################ Memory Stage ######################################## 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
];## Set read control signal
bool mem_read = M_icode in { IMRMOVQ, IPOPQ, IRET };## Set write control signal
bool mem_write = M_icode in { IRMMOVQ, IPUSHQ, ICALL };#/* $begin pipe-m_stat-hcl */
## Update the status
word m_stat = [dmem_error : SADR;1 : M_stat;
];
#/* $end pipe-m_stat-hcl */## Set E port register ID
word w_dstE = W_dstE;## Set E port value
word w_valE = W_valE;## Set M port register ID
word w_dstM = W_dstM;## Set M port value
word w_valM = W_valM;## Update processor status
word Stat = [W_stat == SBUB : SAOK;1 : W_stat;
];################ 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 hazardE_icode in { IMRMOVQ, IPOPQ } &&E_dstM in { d_srcA, d_srcB } ||# Stalling at fetch while ret passes through pipelineIRET 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 hazardE_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 };# 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: 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 hazardE_icode in { IMRMOVQ, IPOPQ } &&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;
# 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 };# Should I stall or inject a bubble into Pipeline Register W?
bool W_stall = W_stat in { SADR, SINS, SHLT };
bool W_bubble = 0;
#/* $end pipe-all-hcl */
模拟器测试结果截图(ISA Checks Succeed):
4.58
设计思想:
分析pipe-1w.hcl,需要对f_icode, instr_valid,need_regids, f_predPC, d_srcA, d_srcB, d_dstM, aluA, aluB, mem_addr, mem_read,F_stall, D_stall, D_bubble, E_bubble进行修改。
word f_icode = [
Imem_error : INOP;
1 : imem_icode;
];
修改为:
word f_icode = [
Imem_error : INOP;
D_icode == IPOPQ : IPOP2;
1 : imem_icode;
];
bool instr_valid = f_icode in{…}; 大括号中所列指令需加上IPOP2
bool need_regids = f_icode in{…}; 大括号中所列指令需加上IPOP2
word f_predPC = [
f_icode in { IJXX, ICALL } : f_valC;
1 : f_valP;
];
修改为:
word f_predPC = [
f_icode in { IJXX, ICALL } : f_valC;
f_icode == IPOPQ : f_pc;
1 : f_valP;
];
word d_srcA = [
..
D_icode in { RET } : RRSP; 大括号中所列指令需加上IPOP2
…
];
word d_srcB = [
…
D_icode in { IPUSHQ, IPOPQ, ICALL, IRET } :RRSP;大括号中所列指令需加上IPOP2
…
];
word d_dstM = [
D_icode in { IMRMOVQ, IPOPQ } : D_rA;
1 : RNONE;
];
修改为:
word d_dstM = [
D_icode in { IMRMOVQ, IPOP2 } : D_rA;
1 : RNONE;
];
word aluA = [
…
E_icode in { ICALL, IPUSHQ } : -8 大括号中所列指令需加上IPOP2
…
];
word aluB = [
…
E_icode in { … } : E_valB; 大括号中所列指令需加上IPOP2
…
];
word mem_addr = [
M_icode in { IRMMOVQ, IPUSHQ, ICALL,IMRMOVQ } : M_valE;
M_icode in { IPOPQ, IRET } : M_valA;
];
修改为:
word mem_addr = [
M_icode in { IRMMOVQ, IPUSHQ, ICALL,IMRMOVQ, IPOP2} : M_valE;
M_icode in { IRET } : M_valA;
];
bool mem_read = M_icode in { IMRMOVQ,IPOPQ, IRET };
修改为:bool mem_read = M_icode in {IMRMOVQ, IPOP2, IRET };
bool F_stall =
E_icode in { IMRMOVQ, IPOPQ } &&E_dstM in { d_srcA, d_srcB } || IRET in { D_icode, E_icode, M_icode };
修改为:
bool F_stall =
E_icode in { IMRMOVQ, IPOP2 } &&E_dstM in { d_srcA, d_srcB } || IRET in { D_icode, E_icode, M_icode };
bool D_stall =
E_icode in { IMRMOVQ, IPOPQ } &&E_dstM in { d_srcA, d_srcB };
修改为:
bool D_stall =
E_icode in { IMRMOVQ, IPOP2 } &&E_dstM in { d_srcA, d_srcB };
bool D_bubble = …中IPOPQ换为IPOP2。
boolE_bubble = …中IPOPQ换为POP2。
修改后pipe-1w.hcl文件:
#/* $begin pipe-all-hcl */
####################################################################
# HCL Description of Control for Pipelined Y86-64 Processor #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2014 #
###################################################################### Your task is to modify the design so that on any cycle, only
## one of the two possible (valE and valM) register writes will occur.
## This requires special handling of the popq instruction.
## Overall strategy: IPOPQ passes through pipe,
## treated as stack pointer increment, but not incrementing the PC
## On refetch, modify fetched icode to indicate an instruction "IPOP2",
## which reads from memory.
## This requires modifying the definition of f_icode
## and lots of other changes. Relevant positions to change
## are indicated by comments starting with keyword "1W".####################################################################
# 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-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'
# 1W: Special instruction code for second try of popq
wordsig IPOP2 'I_POP2'##### Symbolic represenations of Y86-64 function codes #####
wordsig FNONE 'F_NONE' # Default function code##### Symbolic representation of Y86-64 Registers referenced #####
wordsig RRSP 'REG_RSP' # Stack Pointer
wordsig RNONE 'REG_NONE' # Special value indicating "no register"##### ALU Functions referenced explicitly ##########################
wordsig ALUADD 'A_ADD' # ALU should add its arguments##### 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##### Signals that can be referenced by control logic ################### Pipeline Register F ##########################################wordsig F_predPC 'pc_curr->pc' # Predicted value of PC##### 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
## 1W: Provide access to the PC value for the current instruction
wordsig f_pc 'f_pc' # Address of fetched instruction
boolsig imem_error 'imem_error' # Error signal from instruction memory
boolsig instr_valid 'instr_valid' # Is fetched instruction valid?##### 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##### 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##### 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##### 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)##### 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##### 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)##### 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####################################################################
# Control Signal Definitions. #
#################################################################################### Fetch Stage ##################################### What address should instruction be fetched at
word f_pc = [# Mispredicted branch. Fetch at incremented PCM_icode == IJXX && !M_Cnd : M_valA;# Completion of RET instructionW_icode == IRET : W_valM;# Default: Use predicted value of PC1 : F_predPC;
];## Determine icode of fetched instruction
## 1W: To split ipopq into two cycles, need to be able to
## modify value of icode,
## so that it will be IPOP2 when fetched for second time.
word f_icode = [imem_error : INOP;D_icode == IPOPQ : IPOP2;1: imem_icode;
];# Determine ifun
word f_ifun = [imem_error : FNONE;1: imem_ifun;
];# Is instruction valid?
bool instr_valid = f_icode in { INOP, IHALT, IRRMOVQ, IIRMOVQ, IRMMOVQ, IMRMOVQ,IOPQ, IJXX, ICALL, IRET, IPUSHQ, IPOPQ, IPOP2 };# Determine status code for fetched instruction
word f_stat = [imem_error: SADR;!instr_valid : SINS;f_icode == IHALT : SHLT;1 : SAOK;
];# Does fetched instruction require a regid byte?
bool need_regids =f_icode in { IRRMOVQ, IOPQ, IPUSHQ, IPOPQ, IIRMOVQ, IRMMOVQ, IMRMOVQ, IPOP2 };# Does fetched instruction require a constant word?
bool need_valC =f_icode in { IIRMOVQ, IRMMOVQ, IMRMOVQ, IJXX, ICALL };# Predict next value of PC
word f_predPC = [f_icode in { IJXX, ICALL } : f_valC;## 1W: Want to refetch popq one timef_icode == IPOPQ : f_pc;1 : f_valP;
];################ Decode Stage ######################################## W1: Strategy. Decoding of popq rA should be treated the same
## as would iaddq $8, %rsp
## Decoding of pop2 rA treated same as mrmovq -8(%rsp), rA## What register should be used as the A source?
word d_srcA = [D_icode in { IRRMOVQ, IRMMOVQ, IOPQ, IPUSHQ } : D_rA;D_icode in { IRET } : RRSP;1 : RNONE; # Don't need register
];## 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, IPOP2 } : RRSP;1 : RNONE; # Don't need register
];## 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
];## What register should be used as the M destination?
word d_dstM = [D_icode in { IMRMOVQ, IPOP2 } : D_rA;1 : RNONE; # Don't write any register
];## What should be the A value?
## Forward into decode stage for valA
word d_valA = [D_icode in { ICALL, IJXX } : D_valP; # Use incremented PCd_srcA == e_dstE : e_valE; # Forward valE from executed_srcA == M_dstM : m_valM; # Forward valM from memoryd_srcA == M_dstE : M_valE; # Forward valE from memoryd_srcA == W_dstM : W_valM; # Forward valM from write backd_srcA == W_dstE : W_valE; # Forward valE from write back1 : d_rvalA; # Use value read from register file
];word d_valB = [d_srcB == e_dstE : e_valE; # Forward valE from executed_srcB == M_dstM : m_valM; # Forward valM from memoryd_srcB == M_dstE : M_valE; # Forward valE from memoryd_srcB == W_dstM : W_valM; # Forward valM from write backd_srcB == W_dstE : W_valE; # Forward valE from write back1 : d_rvalB; # Use value read from register file
];################ Execute Stage ####################################### 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, IPOP2 } : -8;E_icode in { IRET, IPOPQ } : 8;# Other instructions don't need ALU
];## Select input B to ALU
word aluB = [E_icode in { IRMMOVQ, IMRMOVQ, IOPQ, ICALL, IPUSHQ, IRET, IPOPQ, IPOP2 } : E_valB;E_icode in { IRRMOVQ, IIRMOVQ } : 0;# Other instructions don't need ALU
];## Set the ALU function
word alufun = [E_icode == IOPQ : E_ifun;1 : ALUADD;
];## 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 };## Generate valA in execute stage
word e_valA = E_valA; # Pass valA through stage## Set dstE to RNONE in event of not-taken conditional move
word e_dstE = [E_icode == IRRMOVQ && !e_Cnd : RNONE;1 : E_dstE;
];################ Memory Stage ######################################## Select memory address
word mem_addr = [M_icode in { IRMMOVQ, IPUSHQ, ICALL, IMRMOVQ, IPOP2 } : M_valE;M_icode in { IRET } : M_valA;# Other instructions don't need address
];## Set read control signal
bool mem_read = M_icode in { IMRMOVQ, IPOP2, IRET };## Set write control signal
bool mem_write = M_icode in { IRMMOVQ, IPUSHQ, ICALL };#/* $begin pipe-m_stat-hcl */
## Update the status
word m_stat = [dmem_error : SADR;1 : M_stat;
];
#/* $end pipe-m_stat-hcl */################ Write back stage #################################### 1W: For this problem, we introduce a multiplexor that merges
## valE and valM into a single value for writing to register port E.
## DO NOT CHANGE THIS LOGIC
## Merge both write back sources onto register port E
## Set E port register ID
word w_dstE = [## writing from valMW_dstM != RNONE : W_dstM;1: W_dstE;
];## Set E port value
word w_valE = [W_dstM != RNONE : W_valM;1: W_valE;
];## Disable register port M
## Set M port register ID
word w_dstM = RNONE;## Set M port value
word w_valM = 0;## Update processor status
word Stat = [W_stat == SBUB : SAOK;1 : W_stat;
];################ 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 hazardE_icode in { IMRMOVQ, IPOP2 } &&E_dstM in { d_srcA, d_srcB } ||# Stalling at fetch while ret passes through pipelineIRET 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 hazardE_icode in { IMRMOVQ, IPOP2 } &&E_dstM in { d_srcA, d_srcB };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 { IMRMOVQ, IPOP2 } && E_dstM in { d_srcA, d_srcB }) &&# 1W: This condition will changeIRET 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_Cnd) ||# Conditions for a load/use hazardE_icode in { IMRMOVQ, IPOP2 } &&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;
# 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 };# Should I stall or inject a bubble into Pipeline Register W?
bool W_stall = W_stat in { SADR, SINS, SHLT };
bool W_bubble = 0;
#/* $end pipe-all-hcl */
模拟器测试结果截图(ISA Checks Succeed):
CSAPP第四章家庭作业参考答案相关推荐
- CSAPP第7章家庭作业参考答案
7.6 buf 有 m.o 外部 .data bufp0 有 swap.o 全局 .data bufp1 有 swap.o 局部 .bss incr 有 swap.o 局部 .text count 有 ...
- CSAPP第五章家庭作业参考答案
(CSAPP第三版系列)导航篇传送门 5.14编写5.13的6*1循环展开版本 代码如下: /* Inner product. Accumulate in temporary */ void inne ...
- CSAPP第4章家庭作业参考答案
4.45 不正确 push %rsp的指令会将rsp减8之前的old value压栈 应该是如下代码: movq REG, -8(%rsp) sub $8, %rsp 4.46 不正确 应该改为 ad ...
- CSAPP第二章家庭作业参考答案
(CSAPP第三版系列)导航篇传送门 2.56 用不同的示例值运行show_bytes的代码. #include <stdio.h>typedef unsigned char *byte_ ...
- 《软件工程教程》(第2版) 主编:吴迪 马宏茹 丁万宁 第四章课后习题参考答案
第4章 总体设计 课后习题参考答案 一.选择题(单选或多选) (1)面向数据流的软件设计方法中,一般将信息流分为(A). A.变换流和事务流 B.变换流和控制流 C.事务流和控制流 D.数据流和 ...
- html第四章课后作业,物理化学答案——第四章化学平衡习题解答.doc
物理化学答案--第四章化学平衡习题解答.doc 第四章 化学平衡一.基本公式和内容提要1. 化学反应的方向和限度(1)反应系统的吉布斯自由能和反应进度反应进行过程中,A和B均各以纯态存在而没有相互混合 ...
- [第三章] 深入理解计算机系统第三版 家庭作业参考答案
人非圣贤孰能无过,欢迎大家提问与纠错 3.58 long decode2(long x, long y, long z) {y -= z;x *= y;return ((y << 63) ...
- [第六章] 深入理解计算机系统第三版 家庭作业参考答案
6.22 磁道数 d 与 r - x * r 成正比 设 d = k(r - x * r) = kr(1 - x) 总容量 c = 2πxk(r^2)(1 - x) = 2πk(r^2)(x - x^ ...
- [第五章] 深入理解计算机系统第三版 家庭作业参考答案
5.13 A. 画图: 关键路径为第三幅图加粗部分 B. 下界为浮点加法的延迟界限,CPE 为 3.00 C. 整数加法的延迟界限,CPE 为 1.00 D. 关键路径上只有浮点加法 5.14 voi ...
- C++ Primer Plus(第六版)第四章编程练习参考答案
答案出于菜鸟之手,希望大家参考,提出建议!!! 一. #include<iostream>using namespace std;int main() {char fname[20];ch ...
最新文章
- 【Joomla】本地化汇总
- (2) 第二章 WCF服务与数据契约 服务契约详解(二)- 如何引用WCF提供的服务
- layer output 激活函数_深入理解YOLO v3实现细节 - 第3篇 构建v3的Loss_layer
- C++中的 auto类型详解
- ar ebs 销售订单关闭_有关销售订单的工作流(workflow)定义和处理方式
- 标志位鼠标Java_检查标志位java
- Net5 已经来临,让我来送你一个成功
- 大数据利器2018版
- 标准化设计解决方案 - 标记语言和样式手册 表单
- Stanford机器学习---第二讲. 多变量线性回归 Linear Regression with multiple variable
- 学计算机应用基础学到了什么,2021年学习计算机应用基础心得体会-得范文网
- 空间里相片批量导入u盘_怎么批量把空间照片保存到u盘
- android两个app合并
- ie11浏览器For win7 x64 官方下载 V9600 官方版
- 分析:公众号运营+引流,怎么从0到1运营
- 解决selenium实例化时警告问题
- 【心理】执行功能障碍
- 桌面上 计算机 图标打不开,突然间电脑桌面上的所有图标都打不开了,怎么回事,求大神讲解...
- FT232RL如何区分正品与盗版
- OpenCV 画任意圆弧曲线
热门文章
- 使用emitter的坑,
- vue.js+muse-ui制作在线简历编辑
- r语言中的或怎么表示什么不同_R语言 基本语法
- Firefox 地址栏的“手气不错”
- 怎么把手机字体改成繁体_手机繁体字怎么改成简体,8步就能轻松完成!
- 面矢量栅格化(python)
- idea解决Cannot Download Sources
- Python学习之文件操作【基本操作,JSON文件操作】
- adobe服务器无响应,链接不到adobe服务器
- 一文读懂 | 云上用户如何灵活应用定制化网络服务