/*
*****4.43
*/
A. 根据4.6可知,push %esp 是将%esp的旧值压入栈中;而这段代码压入的新值,两者不一致。
B. 将%esp的旧值先放入另一个寄存器中再进行操作
movl REG %eax
subl $4 %esp
movl %eax (%esp)
/*
*****4.44
*/
A. 和4.7中描述的情况相比,第二条指令将%esp的值多加了4。
B. 同样是引入另一个寄存器存放临时值
movl (%esp) ,%eax
addl $4 ,%esp
movl %eax ,REG
/*
*****4.45
*/
A.
void bubble_a(int *data, int count){
int i,next;
for(next = 1; next < count; next++){
for(i = next - 1; i >= 0; i--)
if(*(data + i + 1) < *(data + i)){
int t = *(data + i + 1);
*(data + i + 1) = *(data + i);
*(data + i) = t;
}
}
}
B.
IA32代码:
bubble_b:
.LFB22:
.cfi_startproc
pushl %edi
.cfi_def_cfa_offset 8
.cfi_offset 7, -8
pushl %esi
.cfi_def_cfa_offset 12
.cfi_offset 6, -12
pushl %ebx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movl 16(%esp), %edx
movl 20(%esp), %edi
cmpl $1, %edi
jle .L1
subl $1, %edi
movl $0, %esi
.L6:
movl %esi, %eax
testl %esi, %esi
js .L3
.L7:
movl 4(%edx,%eax,4), %ecx
movl (%edx,%eax,4), %ebx
cmpl %ebx, %ecx
jge .L4
movl %ebx, 4(%edx,%eax,4)
movl %ecx, (%edx,%eax,4)
.L4:
subl $1, %eax
cmpl $-1, %eax
jne .L7
.L3:
addl $1, %esi
cmpl %edi, %esi
jne .L6
.L1:
popl %ebx
.cfi_def_cfa_offset 12
.cfi_restore 3
popl %esi
.cfi_def_cfa_offset 8
.cfi_restore 6
popl %edi
.cfi_def_cfa_offset 4
.cfi_restore 7
ret
.cfi_endproc
.LFE22:
.size bubble_b, .-bubble_b
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d "
.text
.globl main
.type main, @function
bubble_b:
.LFB22:
.cfi_startproc
pushl %edi
.cfi_def_cfa_offset 8
.cfi_offset 7, -8
pushl %esi
.cfi_def_cfa_offset 12
.cfi_offset 6, -12
pushl %ebx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
mrmovl 16(%esp), %edx
mrmovl 20(%esp), %edi
irmovl $1, %eax
subl %eax, %edi
jle .L1
subl $1, %edi
irmovl $0, %esi
.L6:
rrmovl %esi, %eax
irmovl $0 , ebx
subl %ebx, %esi
jl .L3
.L7:
rrmovl %eax, %ecx
addl %ecx, %ecx
addl %ecx, %ecx
addl %edx, %ecx
mrmovl 4(%ecx), %ecx
rrmovl %eax, %ebx
addl %ecx, %ebx
addl %ecx, %ebx
addl %edx, %ebx
mrmovl (%ebx), %ebx
subl %ebx, %ecx
jge .L4
addl %eax, %eax
addl %eax, %eax
addl %edx, %eax
rmmovl %ebx, 4(%eax)
addl %eax, %eax
addl %eax, %eax
addl %edx, %eax
rmmovl %ecx, 4(%eax)
.L4:
subl $1, %eax
irmovl $-1, %edx
subl %edx, %eax
jne .L7
.L3:
addl $1, %esi
subl %edi, %esi
jne .L6
.L1:
popl %ebx
.cfi_def_cfa_offset 12
.cfi_restore 3
popl %esi
.cfi_def_cfa_offset 8
.cfi_restore 6
popl %edi
.cfi_def_cfa_offset 4
.cfi_restore 7
ret
.cfi_endproc
.LFE22:
.size bubble_b, .-bubble_b
.section .rodata.str1.1,"aMS",@progbits,1
/*
***4.46
*/
采用条件传送的循环代码如下:
源代码:
void bubble_c(int *data,int count)
{
int i , next;
int pre_ele,next_ele;
for(next = 1;next < count;next++)
{
for(i = next -1;i >= 0;i--)
{
pre_ele = *(data + i);
next_ele = *(data + i + 1);
*(data + i) = next_ele < pre_ele ? next_ele : pre_ele;
*(data + i + 1) = next_ele < pre_ele ? pre_ele : next_ele;
}
}
}
Y86代码:
.L6:
movl (%ebx,%eax,4), %edx
movl 4(%ebx,%eax,4), %ecx
cmpl %edx, %ecx
movl %edx, %ebp
cmovle %ecx, %ebp
movl %ebp, (%ebx,%eax,4)
cmovge %ecx, %edx
movl %edx, 4(%ebx,%eax,4)
subl $1, %eax
cmpl $-1, %eax
jne .L6
/*
*****4.47
*/
取值: icode:ifun <---- M1[PC]
ValP <----- PC + 1
译码: ValA <------ R[%ebp]
ValB <------ R[%ebp]
执行: ValE <----- ValB + 4
访存: ValM <----- M4[ValA]
写回: R[%esp] <----- ValE
R[%ebp] <----- ValM
更新PC: PC <----- ValP
/*
*****4.48
*/
取值: icode:ifun <---- M1[PC]
rA : rB <----- M1[PC + 1]
ValC <----- M4[PC + 2]
ValP <----- PC + 6
译码: ValB <------ R[rB]
执行: ValE <----- ValB + ValC
Set CC
访存:
写回: R[rB] <----- ValE
更新PC: PC <----- ValP
/*
*****4.49,4.50
*/
#/* $begin seq-all-hcl */
####################################################################
# HCL Description of Control for Single Cycle Y86 Processor SEQ #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010 #
####################################################################
## 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
####################################################################
# C Include's. Don't alter these #
####################################################################
quote '#include '
quote '#include "isa.h"'
quote '#include "sim.h"'
quote 'int sim_main(int argc, char *argv[]);'
quote 'int 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 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 represenations of Y86 function codes #####
intsig FNONE 'F_NONE' # Default function code
##### 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
##### Possible instruction status values #####
intsig SAOK 'STAT_AOK' # Normal execution
intsig SADR 'STAT_ADR' # Invalid memory address
intsig SINS 'STAT_INS' # Invalid instruction
intsig SHLT 'STAT_HLT' # Halt instruction encountered
##### Signals that can be referenced by control logic ####################
##### Fetch stage inputs #####
intsig pc 'pc' # Program counter
##### Fetch stage computations #####
intsig imem_icode 'imem_icode' # icode field from instruction memory
intsig imem_ifun 'imem_ifun' # ifun field from instruction memory
intsig icode 'icode' # Instruction control code
intsig ifun 'ifun' # Instruction function
intsig rA 'ra' # rA field from instruction
intsig rB 'rb' # rB field from instruction
intsig valC 'valc' # Constant from instruction
intsig 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 #####
intsig valA 'vala' # Value from register A port
intsig valB 'valb' # Value from register B port
##### Execute stage computations #####
intsig valE 'vale' # Value computed by ALU
boolsig Cnd 'cond' # Branch test
##### Memory stage computations #####
intsig valM 'valm' # Value read from memory
boolsig dmem_error 'dmem_error' # Error signal from data memory
####################################################################
# Control Signal Definitions. #
####################################################################
################ Fetch Stage ###################################
# Determine instruction code
int icode = [
imem_error: INOP;
1: imem_icode; # Default: get from instruction memory
];
# Determine instruction function
int ifun = [
imem_error: FNONE;
1: imem_ifun; # Default: get from instruction memory
];
bool instr_valid = icode in
{ INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL,
IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL,ILEAVE,IIADDL};
# Does fetched instruction require a regid byte?
bool need_regids =
icode in { IRRMOVL, IOPL, IPUSHL, IPOPL,
IIRMOVL, IRMMOVL, IMRMOVL ,IIADDL};
# Does fetched instruction require a constant word?
bool need_valC =
icode in { IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL ,IIADDL};
################ Decode Stage ###################################
## What register should be used as the A source?
int srcA = [
icode in { IRRMOVL, IRMMOVL, IOPL, IPUSHL } : rA;
icode in { IPOPL, IRET } : RESP;
icode in {ILEAVE} : REBP;
1 : RNONE; # Don't need register
];
## What register should be used as the B source?
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
];
## What register should be used as the E destination?
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
];
## What register should be used as the M destination?
int dstM = [
icode in { IMRMOVL, IPOPL } : rA;
icode in {ILEAVE} : REBP;
1 : RNONE; # Don't write any register
];
################ Execute Stage ###################################
## Select input A to ALU
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
];
## Select input B to ALU
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 the ALU function
int alufun = [
icode == IOPL : ifun;
1 : ALUADD;
];
## Should the condition codes be updated?
bool set_cc = icode in { IOPL , IIADDL};
################ Memory Stage ###################################
## Set read control signal
bool mem_read = icode in { IMRMOVL, IPOPL, IRET ,ILEAVE};
## Set write control signal
bool mem_write = icode in { IRMMOVL, IPUSHL, ICALL };
## Select memory address
int mem_addr = [
icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : valE;
icode in { IPOPL, IRET ,ILEAVE } : valA;
# Other instructions don't need address
];
## Select memory input data
int mem_data = [
# Value from register
icode in { IRMMOVL, IPUSHL } : valA;
# Return PC
icode == ICALL : valP;
# Default: Don't write anything
];
## Determine instruction status
int Stat = [
imem_error || dmem_error : SADR;
!instr_valid: SINS;
icode == IHALT : SHLT;
1 : SAOK;
];
################ Program Counter Update ############################
## What address should instruction be fetched at
int new_pc = [
# Call. Use instruction constant
icode == ICALL : valC;
# Taken branch. Use instruction constant
icode == IJXX && Cnd : valC;
# Completion of RET instruction. Use value from stack
icode == IRET : valM;
# Default: Use incremented PC
1 : valP;
];
#/* $end seq-all-hcl */
/*
***4.51-4.53
*/
#/* $begin pipe-all-hcl */
####################################################################
# HCL Description of Control for Pipelined Y86 Processor #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010 #
####################################################################
## 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
####################################################################
# 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'
# Instruction code for iaddl instruction
intsig IIADDL 'I_IADDL'
# Instruction code for leave instruction
intsig ILEAVE 'I_LEAVE'
##### Symbolic represenations of Y86 function codes #####
intsig FNONE 'F_NONE' # Default function code
##### Symbolic representation of Y86 Registers referenced #####
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
##### Possible instruction status values #####
intsig SBUB 'STAT_BUB' # Bubble in stage
intsig SAOK 'STAT_AOK' # Normal execution
intsig SADR 'STAT_ADR' # Invalid memory address
intsig SINS 'STAT_INS' # Invalid instruction
intsig SHLT 'STAT_HLT' # Halt instruction encountered
##### 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 imem_icode 'imem_icode' # icode field from instruction memory
intsig imem_ifun 'imem_ifun' # ifun field from instruction memory
intsig f_icode 'if_id_next->icode' # (Possibly modified) 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
boolsig imem_error 'imem_error' # Error signal from instruction memory
boolsig instr_valid 'instr_valid' # Is fetched instruction valid?
##### 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_Cnd 'ex_mem_next->takebranch' # Does condition hold?
intsig e_dstE 'ex_mem_next->deste' # dstE (possibly modified to be RNONE)
##### Pipeline Register M #########################
intsig M_stat 'ex_mem_curr->status' # Instruction status
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_Cnd 'ex_mem_curr->takebranch' # Condition flag
boolsig dmem_error 'dmem_error' # Error signal from instruction memory
##### Intermediate Values in Memory Stage ##########################
intsig m_valM 'mem_wb_next->valm' # valM generated by memory
intsig m_stat 'mem_wb_next->status' # stat (possibly modified to be SADR)
##### Pipeline Register W ##########################################
intsig W_stat 'mem_wb_curr->status' # Instruction status
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_Cnd : M_valA;
# Completion of RET instruction.
W_icode == IRET : W_valM;
# Default: Use predicted value of PC
1 : F_predPC;
];
## Determine icode of fetched instruction
int f_icode = [
imem_error : INOP;
1: imem_icode;
];
# Determine ifun
int f_ifun = [
imem_error : FNONE;
1: imem_ifun;
];
# Is instruction valid?
bool instr_valid = f_icode in
{ INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL,
IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL,ILEAVE,IIADDL };
# Determine status code for fetched instruction
int 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 { 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};
# Predict next value of PC
int f_predPC = [
f_icode in { IJXX, ICALL } : f_valC;
1 : f_valP;
];
################ Decode Stage ######################################
## What register should be used as the A source?
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
];
## What register should be used as the B source?
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
];
## What register should be used as the E destination?
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
];
## What register should be used as the M destination?
int d_dstM = [
D_icode in { IMRMOVL, IPOPL } : D_rA;
D_icode in {ILEAVE} :REBP;
1 : RNONE; # Don't write any register
];
## What should be the A value?
## Forward into decode stage for valA
int 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
];
int 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
];
################ 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,ILEAVE,IIADDL } : 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}) &&
# State changes only during normal operation
!m_stat in { SADR, SINS, SHLT } && !W_stat in { SADR, SINS, SHLT };
## Generate valA in execute stage
int e_valA = E_valA; # Pass valA through stage
## Set dstE to RNONE in event of not-taken conditional move
int e_dstE = [
E_icode == IRRMOVL && !e_Cnd : RNONE;
1 : E_dstE;
];
################ 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 };
#/* $begin pipe-m_stat-hcl */
## Update the status
int m_stat = [
dmem_error : SADR;
1 : M_stat;
];
#/* $end pipe-m_stat-hcl */
## Set E port register ID
int w_dstE = W_dstE;
## Set E port value
int w_valE = W_valE;
## Set M port register ID
int w_dstM = W_dstM;
## Set M port value
int w_valM = W_valM;
## Update processor status
int 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 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 };
# 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_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 { 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_Cnd) ||
# Conditions for a load/use hazard
E_icode in { IMRMOVL, IPOPL, ILEAVE } &&
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 */
/*
***4.54
*/
#/* $begin pipe-all-hcl */
####################################################################
# HCL Description of Control for Pipelined Y86 Processor #
# Copyright (C) Randal E. Bryant, David R. O'Hallaron, 2010 #
####################################################################
## Your task is to modify the design so that conditional branches are
## predicted as being not-taken. The code here is nearly identical
## to that for the normal pipeline.
## Comments starting with keyword "BNT" have been added at places
## relevant to the exercise.
####################################################################
# 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 represenations of Y86 function codes #####
intsig FNONE 'F_NONE' # Default function code
##### Symbolic representation of Y86 Registers referenced #####
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
## BNT: For modified branch prediction, need to distinguish
## conditional vs. unconditional branches
##### Jump conditions referenced explicitly
intsig UNCOND 'C_YES' # Unconditional transfer
##### Possible instruction status values #####
intsig SBUB 'STAT_BUB' # Bubble in stage
intsig SAOK 'STAT_AOK' # Normal execution
intsig SADR 'STAT_ADR' # Invalid memory address
intsig SINS 'STAT_INS' # Invalid instruction
intsig SHLT 'STAT_HLT' # Halt instruction encountered
##### 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 imem_icode 'imem_icode' # icode field from instruction memory
intsig imem_ifun 'imem_ifun' # ifun field from instruction memory
intsig f_icode 'if_id_next->icode' # (Possibly modified) 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
boolsig imem_error 'imem_error' # Error signal from instruction memory
boolsig instr_valid 'instr_valid' # Is fetched instruction valid?
##### 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
intsig D_valC 'if_id_curr->valc'
##### 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_Cnd 'ex_mem_next->takebranch' # Does condition hold?
intsig e_dstE 'ex_mem_next->deste' # dstE (possibly modified to be RNONE)
##### Pipeline Register M #########################
intsig M_stat 'ex_mem_curr->status' # Instruction status
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_Cnd 'ex_mem_curr->takebranch' # Condition flag
boolsig dmem_error 'dmem_error' # Error signal from instruction memory
##### Intermediate Values in Memory Stage ##########################
intsig m_valM 'mem_wb_next->valm' # valM generated by memory
intsig m_stat 'mem_wb_next->status' # stat (possibly modified to be SADR)
##### Pipeline Register W ##########################################
intsig W_stat 'mem_wb_curr->status' # Instruction status
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_Cnd : M_valA;
# Completion of RET instruction.
W_icode == IRET : W_valM;
# Default: Use predicted value of PC
1 : F_predPC;
];
## Determine icode of fetched instruction
int f_icode = [
imem_error : INOP;
1: imem_icode;
];
# Determine ifun
int f_ifun = [
imem_error : FNONE;
1: imem_ifun;
];
# Is instruction valid?
bool instr_valid = f_icode in
{ INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL,
IOPL, IJXX, ICALL, IRET, IPUSHL, IPOPL };
# Determine status code for fetched instruction
int 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 { 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 };
# Predict next value of PC
int f_predPC = [
# BNT: This is where you'll change the branch prediction rule
f_icode == ICALL : f_valC;
(f_icode == IJXX) && (f_ifun == 0) : f_valC;
1 : f_valP;
];
################ Decode Stage ######################################
## What register should be used as the A source?
int d_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 d_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 d_dstE = [
D_icode in { IRRMOVL, IIRMOVL, IOPL} : D_rB;
D_icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP;
1 : RNONE; # Don't write any register
];
## What register should be used as the M destination?
int d_dstM = [
D_icode in { IMRMOVL, IPOPL } : D_rA;
1 : RNONE; # Don't write any register
];
## What should be the A value?
## Forward into decode stage for valA
int d_valA = [
D_icode in { ICALL } : D_valP; # Use incremented PC
D_icode in {IJXX} : D_valC;
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 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
];
################ Execute Stage #####################################
# BNT: 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
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 &&
# State changes only during normal operation
!m_stat in { SADR, SINS, SHLT } && !W_stat in { SADR, SINS, SHLT };
## Generate valA in execute stage
int e_valA = E_valA; # Pass valA through stage
## Set dstE to RNONE in event of not-taken conditional move
int e_dstE = [
E_icode == IRRMOVL && !e_Cnd : RNONE;
1 : E_dstE;
];
################ 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 };
#/* $begin pipe-m_stat-hcl */
## Update the status
int m_stat = [
dmem_error : SADR;
1 : M_stat;
];
#/* $end pipe-m_stat-hcl */
## Set E port register ID
int w_dstE = W_dstE;
## Set E port value
int w_valE = W_valE;
## Set M port register ID
int w_dstM = W_dstM;
## Set M port value
int w_valM = W_valM;
## Update processor status
int 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 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_Cnd) ||
# 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_Cnd) ||
# 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;
# 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 */