接上文,本文介绍SEQ CPU的逻辑和硬件实现.着重使用HCL语言描述SEQ CPU的逻辑.
Y86/SEQ概述
————
SEQ是 Sequential CPU的实现,表现在指令的执行要依次经历各个阶段(Fetch->Decode->Execut->Memory->WriteBack->PC Update).每一个指令在一个时钟周期内完成(这条指令执行的所有状态State在时钟上升时更新.意味着时钟周期很长,效率很低,以后再讨论).
下面先给出 SEQ的硬件结构(如下图),然后慢慢讨论各个部分的控制逻辑和硬件实现.
注:
注:指令执行图是从下到上的. 这种设计的原因等到PIPE的实现时我们会解释的. 之所以Write back阶段和PC Update阶段要回下来, 是因为他们要访问Registerfile和PC这两个前面阶段用过的部件. 要注意的是虽然在语义动作中说各个可能写状态的阶段写状态的动作是顺序发生的.但实际上对于硬件来说,它们是同时在clockrising的时候发生的.
HCL中的宏
————
宏用在HCL中表示指令、寄存器、操作符类型. 见下表.
取指逻辑
————
1.硬件结构
2.硬件单元(蓝色框)
-程序计数器PC(本实现其实并没有这个硬件单元,而是使用控制逻辑来完成的).
-指令寄存器.
-Split:将指令字节分为指令和功能码.
-Align:获取指令中的rA, rB, valC
3.控制逻辑(灰色框)
控制逻辑是组合电路,用来产生所需要的逻辑. HCL主要就是要描述控制逻辑的.
-instr_valid:是否是有效指令.
-need_regids:指令是否有寄存器.
-need_valC:指令是否有valC.
4. HCL描述控制逻辑
boolinstr_valid = icode in { INOP, IHALT, IRRMOVL, IIRMOVL, IRMMOVL, IMRMOVL, IOPL,IJXX, ICALL, IRET, IPUSHL, IPOPL };
boolneed_regids = icode in { IRRMOVL, IOPL, IPUSHL, IPOPL, IIRMOVL, IRMMOVL,IMRMOVL };
bool need_valC = icode in{ IIRMOVL, IRMMOVL, IMRMOVL, IJXX, ICALL };
译码和写回逻辑
————
1.硬件结构
2.硬件单元(蓝色框)
寄存器文件:有四个端口.它支持同时进行两个读(端口A和B)和两个写(在端口E和M上).每个端口都有一个地址连接和一个数据连接(srcA, valA; srcB, valB; dstE, valE;dstM, valE).地址连接是一个寄存器ID,如果地址端口上的值为oxF(RNONE),则表明不需要访问寄存器.
3.控制逻辑(灰色框)
-srcA srcB:读端口地址
-dstE dstM:写端口地址
4. HCL描述控制逻辑
统一处理的原则:在excute阶段, valA尽量不参与运算,使用valB参与运算;在memory阶段,都是valA参与运算(为了使得pushl和rmmovl统一处理).
译码逻辑:
int srcA= [
icode in { IRRMOVL, IRMMOVL, IOPL, IPUSHL } : rA; #计算
icode in { IPOPL, IRET } : RESP; #访存阶段[获取读存储器的有效地址]
1 : RNONE; # Don't need register
];
int srcB= [
icode in { IOPL, IRMMOVL, IMRMOVL } :rB; #计算
icode in { IPUSHL, IPOPL, ICALL, IRET } : RESP; # 执行阶段[栈%esp]
1 : RNONE; # Don't need register
];
写回逻辑:
int dstE = [
icode in { IRRMOVL, IIRMOVL, IOPL} :rB; #写回rB
icode in { IPUSHL, IPOPL, ICALL, IRET }:RESP; #涉及栈,写回%esp
1: RNONE; # Don't need register
];
考虑到cmovXX指令
int dstE = [
icodein { IRRMOVL } && Cnd : rB;
icode in { IIRMOVL,IOPL} : rB;
icodein { IPUSHL, IPOPL, ICALL, IRET ) : RESP;
1: RNONE; # Don't write any register
];
int dstM = [
icode in { IMRMOVL, IPOPL } : rA; #只有这两个指令是从memory->register
1 : RNONE; # Don't write any register
];
执行
————
1.硬件结构
2.硬件单元(蓝色框)
-算术/逻辑单元ALU
-CC
-cond:用于条件分支或者条件数据传送.
3.控制逻辑(灰色框)
-ALU A
-ALU B
-Set CC
-ALU fun.
4. HCL描述控制逻辑
boolset_cc = icode in {IOPL};
int aluA= [
icode in { IRRMOVL, IOPL } : valA;
icode in { IIRMOVL, IRMMOVL,IMRMOVL} : valC;
icode in { ICALL, IPUSHL } : -4;
icode in { IRET, IPOPL } : 4;
# Other instructions don't need ALU
];
int aluB= [
icode in { IRMMOVL, IMRMOVL, IOPL, ICALL, IPUSHL, IRET, IPOPL } :valB;
icode in { IRRMOVL, IIRMOVL ) : 0;
# Other instructions don't need ALU
];
intalufun = [
icode == IOPL : ifun;
1 : ALUADD;
];
访存逻辑
————
1.硬件结构
2. HCL描述控制逻辑
Mem read/write逻辑: Mem read信号和Memwrite信号不会同时为1.
boolmem_read = icode in { IMRMOVL, IPOPL, IRET };
boolmem_write = icode in { IRMMOVL, IPUSHL, ICALL };
intmem_addr = [
icode in { IRMMOVL, IPUSHL, ICALL, IMRMOVL } : valE; # valE: memory write address
icode in { IPOPL, IRET } : valA; # valA: memory read address
# Other instructions don'tneed address
];
intmem_data = [
# Value from register
icode in { IRMMOVL, IPUSHL } : valA;
# Return PC
icode == ICALL : valP;
# Default: Don't write anything
];
PC更新逻辑
————
1.硬件结构
2. HCL描述控制逻辑
intnew_pc = [
# Call. Use instruction constants
icode == ICALL : valC;
# Taken branch. Use instruction constants
icode == IJXX && Cnd : valC;
# Completion of RET instruction. Use value from stack
icode == IRET : valM;
# Default: Use incremented PC
1 : valP;
];
注*:本篇中的图片均来自本书的官网,我进行了改造(注释和添加),详见http://csapp.cs.cmu.edu/public/figures.html
(Copyright© 2011, Randal E. Bryant and David R. O'Hallaron )
reference:
1. 深入理解计算机系统(原书第2版)
(版权所有,转载时请注明作者和出处-dennis_fan-http://blog.csdn.net/dennis_fan )