Duke ECE550K
纯在折磨这个课 本人期中依托,参考慎重,不知道意义何在
可能会有很多不完善的地方,我也有很多地方感觉一知半解,欢迎讨论和交流。
评论区欢迎补充,需要打开vpn查看
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
尼玛exam2清朝老题,做往年卷子去吧。。。
Lec1 Introduction
Processors are made of transistors
Levels of Abstraction
- Transistors: “electrical switch”
- Gates: a few transistors
- Meaningful logic elements: a handful of gates
- Large elements (stages, units): combining logic elements
- Core
- Chip
- We have transistors. They’re electronic switches.
- You can make logic by combining transistors.
- You can make arithmetic from logic.
- Transistors can also make basic memory.
- Combine arithmetic and logic circuits to make an Arithmetic/Logic Unit (ALU)
- Combine memory elements to make registers to store values
- Combine the ALU, registers, and other stuff to make a full CPU!
- Use other transistor configurations to make large-scale RAM.
- RAM is too slow, so add cache, another form of memory to speed it up.
- We have storage in the form of hard drives and SSDs.
- Use storage and RAM together: this is virtual memory, which allows us to run more programs with more efficiency.
- We halt the CPU with exceptions to handle things like I/O to storage.
- The modern computer is governed by basic software called the operating system.
- We have networking to connect multiple computers.
- CPU performance is increased by various techniques, including pipelining.
Lec2 Transistor to Gates
Vcc & Gnd
Vcc就是power(高电平), Gnd就是ground(低电平)。高电平用1V表示,低电平用0V表示。两个不可以直接连,会短路!
Transistor
2 types:
- NMOS (左边没带圈圈的)
- gate是1的时候接通,0是断线
- PMOS (右边带圈圈的)
- gate是0的时候接通,1的时候断线
CMOS
Complementary MOS
上面接了一个PMOS,底下接了一个NMOS
- 当input等于1的时候(PMOS断,NMOS接),output为0
- 当input为0的时候(NMOS断,PMOS接),output为1
Switching delays
当input切换的时候,output的转变不会立刻发生,因为有延迟,影响延迟的因素有:
- Voltage
- Higher voltage = faster switching, more power/energy 高电压可以减小延迟
- Resistance
- lower resistance = faster switching 低电阻
- Capacitance
- lower capacitance = faster switching 低电容
所以可以想象电流在电线中是不断向前流动的,只有完全的流过了这个电路,output和各个管线的结果才是我们想象的结果。
CMOS可以构成not gate
这就是一个小小的abstraction,只有interface是有逻辑的,内部实现是transistor实现的
build a gate
build a 2-input NOR gate
- write down the truth table of NOR gate.
- output = 1 when A and B = 0 看真值表,只有A和B为0的时候结果才是1
- connect PMOS in series
- (Not A) and (Not B)
- output = 0 when A or B = 1
- Connect NMOS in parallel
- Not (A or B)
NOTE: 这两个方程逻辑相等通过DeMorgan’s Laws(看纸质笔记或者hw计算)
- bar(A*B) = barA + barB
- bar(A+B) = barA * barB
两个gates相乘就是串联,相加就是并联
画图时not是用not gate实现的,比如在下拉电路中有一个barA,那也就是A进入NMOS之前需要过一个not gate
在设计此类图的时候PMOS一定是在output的上沿,NMOS在output下沿。
同理设计一个NAND gate
先看真值表:
- output = 0的时候,(Not A) and (Not B),所以下沿是两个NMOS串联。
- output = 1的时候,Not(A or B),所以上沿是两个PMOS并联。
Boolean gates
- 底部是直的是AND
- 底部是弯的是OR
- 底部有两条的是XOR
- 带圈圈的是基础班加NOT
XOR gate 可以用来表示二进制加法
可以使用buffer to increase speed
Lec3 Combinational Logic
three inputs NOR gate
在处理多个gate的时候,complementary nature非常重要。
假如不注意的话就会出现短路的情况(Vcc和Gnd直接连接),烧毁电路板。
PMOS的方程,应该等于CMOS的方程,例如:
PMOS: ((NotA) or (NotB)) and (NotC)
NMOS: Not(C or (A and B)) = (NotC) and (Not(A and B)) = (Not C) and ((Not A) or (Not B))
所以可以得出,正确的情况下,uppull和downpull的两个方程应该是相等的
所以And gate 是怎么实现的呢:NAND gate后面跟着一个Not gate即可。
- Not(Nand(a, b))
- Nor(NotA, NotB)
Circuits are made from a network of gates.
不要把两个input直接连在一起,会短路
Mux
是一个选择器,input会有正常的input和一个selector,mux通过selector去选择input中的一部分output出来。
How to make a mux
- Pick between 2 inputs (2to1Mux)
- Make a truth table (S = 0 pick A, S = 1 pick B)
- Sum of product to get formula
- Find the rows where the output is 1
(!A & B & S) | (A & !B & !S) | (A & B & !S) | (A & B & S) - Simplifying this formula: (A & !S) | (B & S)
通过简化过的formula构成2to1的Mux:
通过这个可以进行进一步的组合,2to1Mux变成4to1变成8to1变成16to1变成32to1(通过不断增加selector的bits数量)
DeMorgan’s Laws
Lec4 Number Representations
二进制没啥可说的
二进制转化为16进制(0x开头),可以把二进制四位四位分开,每一位分别计算,作为16进制的一位。
需要负数怎么办?
开头第一位出来,0就是正数,1就是负数
如何把一个正数变成负数?正数取反+1
overflow
但是出现了一个问题
两个positive numbers相加得到一个negative number,这是不对的
原因是发生了overflow!溢出了!
什么情况是发生了overflow?
- Signed addition: CI != CO of last bit 最后一位的cin和cout不同
- Unsigned addition: CO != 0 of the last bit
detect in hardware
- signed: XOR CI and CO of last bit
- unsigned: CO of last bit
减法怎么做?
- A - B = A + ~B + 1
- A-B就是A+B的取反然后cin变成1
one-hot
独热编码,懂得都懂
decoder & encoder
Delays
- 开关不是instant的。
- gate越多,延迟也就越多。
- wire也有延迟。
- Fan-out: how many gates the output drives
- related to capacitance
- high fan-out = slow
- sometimes better to replicate logic to reduce its fan-out
Lec5 Digital Arithmetic
1bit adder
一位全加器
RCA
ripple carry adder
每一个adder都有两个unit的delay(因为从input到output需要穿过两个gate),所以rca的delay是很大的,需要一个一个adder的过,N个adder的delay就会是2N。
CSA
carry select adder
CSA的优点就是可以同时进行不同位数的计算,只需要根据低位的cout选择高位的计算结果拼接上去就可以得出正确结果。
但这个的问题是用空间换时间,他的delay是会比RCA小,但是所需空间会比RCA大。
这个的delay取决于一个CSA模块所需要的delay和mux的delay之和(一般来说一个mux的delay约等于2 units)。
ALU
Arithmetic Logic Unit
- left shift (<<>>)
- Moves left, bringing in 0s at right, excess bits “fall off”
- 10010001 << 2 = 01000100
- x << k corresponds to x*2^k
- 想象一下用手把数字往左侧推,然后在右侧的空格里补0
- logical (or unsigned) right shift (>>)
- Moves bits right, bringing in 0s at left, excess bits “fall off” 无脑补0
- 10010001 >> 3 = 00010010
- x >>k corresponds to x / 2^k for unsigned x
- arithmetic (or signed) right shift (>>)
- Moves bits right, brining in (sign bit) at left 根据最高位的数字补对应的数字
- 10010001 >> 3= 11110010
- x >>k corresponds to x / 2k for signed x
Floating point example
float变成ieee754
- 首先先把10进制的数字变成二进制的小数
- 比如现在的结果是100.010101
- 现在挪移小数点到1.00010101
- 现在小数点左移了2位(左移n位)
- 小数点后的部分作为玛莎拉
- 碎片部分是127+n的结果转化为八位二进制
- 符号为正常填入
ieee754变成float
- 现在先看符号位置找到符号
- 把碎片部分换算为十进制
- 碎片 = n + 127
- 得到了n之后,玛莎拉部分小数点之前加上1
- 把加1之后的结果乘2的n次方(这也是个二进制,所以挪移小数点)
Lec6 Storage and Clocking1
SR Latch
为什么不可以输入两个都为1?
因为两个都为1会导致输出结果不平衡,不会有一个固定的结果。
其他的输入都会有在最终平衡,输入不再改变。
Data Latch
为了处理srlatch可能会出现的两个都是1的情况,data latch在输入的时候加入了一个not gate,使R和S输入的数据一定是相反的。
enable作为一个开关,去决定Q的输入,当enable是1的时候,Q的输出才会根据D而发生改变,假如enable为0,Q的输入就会保持当前的输入不变。
可以使用clock作为enable
Strawman: Level Triggered
看ppt
Lec7 Storage and Clocking2
DFF
相比于data latch的持续监测,dff的enable就是一个脉冲(clk从down到high),当出现脉冲的时候,记录当前状态,然后就继续保持不变直到下一个脉冲激活。
DFF
把两个dff对接起来的时候,需要ensure signals reach DFF before clk rises
会存在delay,因为两个dff都需要输入,这时候怎么减小delay呢?可以让c从另一边输入
Register
写入的时候使用decoder:
- decoder读入一个selcode,然后解码为一个one-hot code,对是1的那位写入数据
- 比如是32位的,就需要一个5位的selcode,然后进行解码,出来的结果应该是一个32bits的独热编码
- 不用mux,因为mux太慢了
读取的时候也使用了decoder
- 使用了tri-state buffer
- 指当enable为1的时候,才可以写入data是0/1
- 当enable为0的时候,保持高阻态Z(既不是0,也不是1,就是什么都没有)
Lec8 Finite State Machines
FSM: Input + Current State = Output + New State
有两种machine
- mealy machine
- moore machine
这两个有一定的区别:FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)
- Transition function: (state*inputs)->state (Helpful to draw as diagram)
- Output function: (state*inputs)->outputs
Division
???
细节的图和画法得看ppt,复习的时候去看一下
Lec9 ISAs & MIPS
Assembly
- Assembly programming:
- 1 machine instruction at a time 一次一个机器指令
- still in human readable form
- much lower level than any other programming
- Limited number of register vs unlimited variables
- Flat scope
Registers
- Two places processors can store data
- Register
- in processor
- fast
- Memory
- outside of processor
- huge
- slow
- Register
- think of registers like “variables”
- $1 = $2 + $3 much like x = y + z
simple running example
- line1:
- loop: line label
- lw = load words指读取memory对应位置的32位words
- $1 把从memory中阅读的结果放到reg1里
- Memory[1004] = address in memory to read from (where x lives)
几乎所有的MIPS都是把distination放到第一位。
- line2:
- 把1008位置的words从memory读取到reg2中存放
- line3
- 把reg1里的内容+reg2的内容然后放在reg3里
- line4
- 把reg3和reg4相加然后放到reg4里
- line5
- jump出line1的loop
以上的代码是人可以读的,但是不是机器执行的。
instructions are numbers too!
在MIPS中,每一个assembly instruction都可以被转化为一个独特的32bits的表示。
而完成这个转化的就是assembler.
What must be specified?
- Instruction “opcode” (比如是add还是sub)
- Location of oprands and result(register还是memory还是immediates)
- Data type and Size(比如signed还是unsigned)
- what instruction comes next?(比如jump去哪?)
ISA
instructions set architecture
- contract between hardware and software 软硬件之间的合同
- specifies everything hardware and software need to agree on
- instruction encoding and effects
- memory structure
- etc
有很多ISA的种类:x86, ARM, MIPS
我们主要就说MIPS
RISC vs CISC
- 2 broad categories of ISAa
- Complex instruction set computing (CISC)
- come first, days when people always directly wrote assembly
- big complex instructions
- Reduced instruction set computing (RISC)
- goal: make hardware simple and fast
- write in high level language, compiler do the dirty work
- Complex instruction set computing (CISC)
RISC
fixed length instruction encoding
few memory addressing modes (更少的内存地址模式)
有更多的寄存器 32
three-oprand arithmetic
load-store ISA
CISC
variable length instruction encoding
many addresssing modes
few registers 8
various oprand models(stack, two-operand, implicit operands)
可以直接操作内存
说句实话我不知道这节ppt后面半截的作用是什么,有人能告诉我吗?
所以后面有一个executing add的例子,非常显而易见。
在address里是一行一行执行的,然后instruction会调用register进行计算,再把结果重新赋值到指定的register里去。
Lec10 ISAs & MIPS 2
R type
1 | R Type: <OP> rd, rs, rt |
假如我想加上一个常数怎么办?
- 把常数放到寄存器中
- 使用带immediate的instruction
I type
1 | I Type: <op> rt, rs, immediate |
正常操作之后带i基本上就是需要immdiate的操作
有许多isns有immediate形式:
- addi, andi, ori, xori之类的都有
- 没有sub (表达减法使用加上负数来表示)
- 没有muli和divi
Accessing memory
- MIPS is a “load-store” ISA (RISC)
- only load and store insns access memory
- different with x86 which allows
- add reg = (memory location) + reg
- add (memory location) = (memory location) + reg
l开头的是把内存里的数据赋值给寄存器,s开头的是把寄存器的数据保存到内存里
后面都是例子,直接看ppt
这里在**q=x的时候,为什么不直接使用sw $1, $3
?
因为只能操作一层指针,所以必须先得到第一层指针,才可以得到第二层指针里的value
Lec11 ISAs & MIPS 3
1 | J-Type <op> immediate |
jtype provide long range, unconditional jump:
31-26: Op
25-0: target
Can jump anywhere with jr $reg
(jump register)
write a function f2c
Call: Jump… but also remember where to go back
- May be many calls to f2c() in the program
- Need some way to know where we were
- Instruction for this jal
jal label
- Store PC +4 into register $31
- Jump to label
Return: Jump… back to wherever we were
- Instruction for this jr
jr $31
- Jump back to address stored by jal in $31
ra寄存器(Return Address Register):
- 作用:$ra 寄存器用于存储函数调用的返回地址。当一个函数被调用时,程序会跳转到函数的代码执行,并在函数执行完成后返回到调用它的地方。
$ra
寄存器用于保存调用函数之前的程序执行地址,以便在函数返回时能够回到正确的执行位置。 - 使用示例:在函数调用之前,程序通常会将返回地址保存在
$ra
寄存器中,然后在函数执行完毕后,使用jr $ra
指令将控制返回到保存的地址。
v0寄存器:
- 作用:
$v0
寄存器通常用于存储函数的返回值。在 MIPS 汇编中,函数返回值通常存储在$v0
寄存器中,以便调用者可以访问和使用返回的结果。 - 使用示例:如果一个函数计算了某个值,并希望将这个值作为返回值返回给调用者,它通常会将计算结果存储在
$v0
寄存器中。调用者可以使用$v0
寄存器中的值来获取函数的返回值。
Assembly language
- Directives: tell the assembler what to do 解释要做什么
- Format
"."<string> [arg1], [arg2]
Stack
为什么需要栈?
- local variables
- saving register
- across calls
- spilling variables (not enough regs)
- passing more than 4 arguments
stack layout
在内存里 use loads and stores to access
two registers for stack: (一个开头一个结尾)
- stack pointer ($sp): points at end (bottom) of stack
- frame pointer ($fp): points at top of current stack frame
procedure calls obey stack discipline 程序被call的时候遵循stack原则
- local procedure state contained in stack frame 本地的程序储存在stack frame里
- procedure stack is in memory 程序栈储存在内存里:从内存的顶部一路往下
Calling Procedure
- Step1: Setup the arguments
- 头四个arguments(arg0-arg3)被传入寄存器$a0-$a3
- 剩下的被推入栈中
- Step2: save caller-saved registers
- save registers $t0-$t9 if they contain live values at the call site
- Step3: Execute a jal instruction
- Step4: Cleanup stack by updating $sp (if more than 4 args)
Called Routine
- Establish stack frame
- subtract the frame size from the stack pointer
subiu $sp, $sp, <frame-size>
- Typically, minimum frame size is 32 bytes (8words)
- subtract the frame size from the stack pointer
- Save callee saved registers in the frame
- register $fp is always saved
- register $ra is saved if routine makes a call
- registers $s0-$s7 are saved if they are used
- Establish Frame pointer
- Add the stack - 4 to the address in $sp
- addiu $fp, $sp,
- 4
On return from a call
- Put returned values in registers
$v0, [$v1]
- Restore callee-saved registers
- restore
$fp
and other saved registers. [$ra, $s0 - $s7]
- restore
- Pop the stack
- add the frame size to $sp
addiu $sp, $sp, <frame-size>
- add the frame size to $sp
- Return
- jr to address in $ra
Lec12 ISAs and MIPS 4
内存就像是一栋大楼,address就是每个房间的门牌号,value就是住在房子里的人,住在房子里的既可以是储存的数字,也可以是储存的其他房间的门牌号。
register就像是一个工位,通过address把里面的value拽出来储存在寄存器里(load),然后让他们工作(计算之类),结束再保存回内存去(save)。
现在让我们看这个图
PC一直是下一步需要运行的地址
subiu $sp, $sp, 16
这条指令的作用是将栈指针 $sp
减去16,这会使栈指针向低地址方向移动16字节,为当前函数调用分配16字节的栈空间。在函数执行期间,可以使用 $sp
寄存器来访问分配的栈空间,例如存储和读取局部变量的值。当函数退出时,通常会使用 addiu $sp, $sp, 16
或类似的指令来释放分配的栈空间,将栈指针还原到调用函数时的位置,以确保不会发生内存泄漏。
sw $fp, 0($sp)
把栈顶储存在向大楼要求的四个房间里的第一个,故偏移量是0
sw $ra 4($sp)
把完成之后要跳回的地址(也就是$ra),存在房间里
sw $s0 8($sp)
把s0寄存器里value放到内存里 什么事callee saves?
addiu $fp, $sp, 12
把$fp的位置更新偏移量,也就是更新申请的房子用了几个门牌号,(4个房间用了三个)
这时候到了address 1018的位置,1018指向了address位4200的位置
$ra会更新为0000101C,因为等4200位置的方法返回之后,程序需要从101C这里重新进行。
然后从房间里取出来一开始存进去的东西
stack的特点是 first in last out
取东西的时候是用栈顶开始取得
$fp是栈顶的门牌号,$sp是栈底的门牌号
取的时候使用的是关于栈顶的偏移量
因为只用了三个房间,所以需要从$fp 偏移量为-4的地方开始读取,依次是-4,-8,-12
addiu $sp, $sp, 16 归还使用的房间
jr $ra 根据之前来的时候储存的地址,跳回调用这个函数的地方。
为什么需要$fp
balabalabala
system call instruction
system call被用来和操作系统和要求服务(memory allocation, I/O)
syscall instruction in MIPS
General Rules
Midterm 补充
1 | int leaf_example (int g, int h, int i, int j) |
参数变量 g、 h、 l 和j对应参数寄存器 $a0、 $a1、 $a2 和 $a3, f对应 $s0。编译后的 程序是以如下标号开始的过程
现在有一个c函数,i 和 j存放在寄存器 $s3 和 $s5 中,数组 save 的基址存放在寄存器 $s6
1 | while(save[i]==k) |
1 | Loop: |
Floating point: single precision, double precision (double and float?)
Arithemetic/logical operations
adder: rca, csa
subtraction
overflow
bit-wise operation: shift
ALU: 以上加起来
storage
SR latch (has illegal state)
data latch
DFF (two dlatch)
register (dff only 1bit, reg could have many bits)
register file: tri-state gate
FSM
- new state = f(Input, Current state)
- output = g(Input, Current state)
this is meanly machine
moore machine
- output = g(Current state)
state table
state diagram
excitation table
hardware implementation
application: division
MIPS
ISA
instruction set architecture
assembly programming
risc v cisc
MIPS: R type, I type, J type(jump)
PC
RA(return address)
sp(stack pointer)
fp(frame pointer)
v0-v1: results
a0-a3: arguments
t0-t9: caller saves registers
s0-s7: callee saves registers
这里来解释一下t register和s register的用法(个人见解)
首先,所有的register都是在任何时候都可以save和load的,但是这里需要说到几个register的区别(也就是惯例用法)
t register是caller save也就是在当前函数中被保存
s register是callee save也就是在被call的函数中保存
a register是保存argument的的register,a0-3都是不用在stack里的,
用一个比喻来说,register都是一个桌子,而stack里的储存空间就是locker。
这时function0会在使用过程中call function1。
OK,那也就是func0在桌子上办公到一半的时候,func1会接手这个桌子继续办公
那在function0来到这个桌子的时候,他需要保存好他上面一个func给他遗留的s register里的东西
但是由于这时候桌子上的t register里的东西应该是上一个func里已经save好的了,所以function0可以直接使用t register不用考虑一开始的储存问题
好的,现在function0要离开桌子了,function1马上要接受桌子开始工作
在func0走之前,func0需要把自己在t register里的东西储存到stack里,但是不需要管自己目前在s register里的东西。
func1来了之后需要帮func0把s reg里的东西储存好,才可以正常使用s reg。
func1工作完了之后,需要跳回func0,这时候func1需要把func0当时留在s reg里的东西从locker里取出来(被func1放到了stack),放回桌子上
func0回到了自己的桌子上,已经有了所有的s reg(被func1摆好了),这是在去locker里找回自己的当时存的t register里的东西使用。
这就是整个的过程
当需要stack储存的时候,假如说我们需要储存三个数据,那也就需要4*3=12的空间,$sp
也就需要向下挪移12位。
该方法写作addi $sp, $sp, -12
然后保存第一个的时候就是sw $reg0, 0($sp)
第二个是sw $reg1, 4($sp)
第三个是sw $reg2, 8($sp)
然后取出来存的东西lw $reg2, 8($sp)
第二个是lw $reg1, 4($sp)
第三个是lw $reg0, 0($sp)
最后恢复$sp
的位置,addi $sp, $sp, 12
Btw,感觉其实保存和取出的顺序并不重要,重要的是偏移量是相对$sp
对的就ok
三种跳跃j, jr, jal
j
用于无条件跳转到指定地址,不保存返回地址。(去了就不回了)jal
用于跳到指定地址,并保存返回地址,以便后续返回。(一般call函数的时候使用)jr
用于从寄存器中读取地址并跳转,通常用于函数返回。(call完函数跳回来的时候使用)
Lec13 Datapath
一台计算机的性能由三个关键因素决定 : 指令数目,时钟周期长度和每条指令所需时钟周期数 (CPI)。
MIPS是如何运行的,是在一个抽象为流程图中进行的运行:
并不是每一个部分都会在运行mips时被使用,只有一部分会被使用,比如计算就用不上数据储存器。
建立数据通路
设计数据通路的方法是先分析每种MIPS指令时需要哪些主要部件
- 数据通路部件 datapath element:一个用来操作或保存处理器中数据的单元 。 在 MIPS 实现中,数据通路部 件包括指令存储器、数据存储器、寄存器堆、 ALU 和加法器 。
- 程序计数器 program counter PC:存放下一条将要被执行指令的地址的寄存器 。
- 寄存器堆 register file:包含一系列寄存器的状态单元,可以通过提供寄存器号进行读写。
一个简单的例子,比如说add $t1, $t2, $t3
。
用上面那个图来说,pc会储存下一行的地址,在寄存器堆中,有四个输入和两个输出,首先使用的是三个地址的输入(t1, t2, t3),然后把2和3的value通过两个输出交付给ALU进行计算,然后通过ALUop的指引,两个value在alu中进行相应的计算,alu结果输出,这时结果被传送到寄存器堆的第四个输入处(写数据),并被写入t1中。
再来第二个例子addi $t1, $t2, immed(16)
因为接线是固定的,所以并不会修改内部的wire,那么问题来了,要是进来的是一个addi而不是add,那就t1就变成了输出结果的存储reg,但是由于mips的结构问题,原来在add里t1是在d上的,现在d上位置却变成了immed,这种问题如何解决呢?
好的,那我们rs的位置不变,现在的rs是t2,连接位置是s1。当发现输入的addi的时候,就是用mux把原来连接在s2位置上的rt转移到d上(其实s2位置上也还是t1,只是没有人管他了,后续也不动他了),这样t1就变成了储存结果的reg了。然后16位的immed被输入进去,通过SX(sign-extend)变成可计算的value,和t2的value在alu中计算并返回到reg file里然后成功储存在d上。
第三个例子lw RT, off16(RS)
下面考虑 MIPS 的存取指令,其一般形式为: lw $t1,offset_value ($t2)
或 sw $t1 , offset_value($t2)
。 在这类指令中,通过将基址寄存器 $t2 的内容与指令中的 16 位带符号偏移地址相加,得到存储器地址。如果是存储指令,要从寄存器 $t1 中读出要存储的数据; 如果是取数指令,则要将从存储器中读出的数据存入指定的寄存器$t1中。
第四个例子sw RT, off16(RS)
同上
第五个例子beq RS, RT, off16
两个寄存器用来比较是否相等,16位偏移量用于计算相对分支所在地址的分支目标地址 branch target address。pc+4(下一条指令的地址)于偏移量相加得到分支目标地址。
系统结构还规定偏移量左移2位以指示以字为单位的偏移量,这样偏移量的有效范围 就扩大了4倍。所以为了这种情况,需要把偏移量左移两位。
然后还需要确定是否需要跳转,假如分支条件为真(分支发生 branch taken),假如操作数不等,那就pc正常自增+4,不需要跳转,分支未发生(branch not taken)
ALU中做减法,结果从z中传出。
第六个例子j addr28
beq青春版,跳就完事了,注意的是需要跳的内容是直接由immed提供的
第七个jal
jal用于跳转到指定地址,并储存原来的地址+4,给跳回来的时候使用
所以直接从pc的地址拿出来+4并放到寄存器(reg file)中
第八个jr
jr用于跳转回pc储存的地方,所以使用reg file去读取寄存器内的地址送到pc中。和j的区别是地址是reg file里读出来的,不是immed
what is control?
- Rwe (Register Write Enable): 这个信号决定了是否应该将数据写入寄存器文件(Register File)。当Rwe为1时,数据会被写入寄存器;当Rwe为0时,寄存器文件保持不变。
- Rdst (Register Destination): 这个信号选择应该写入哪个寄存器。通常在有选择的操作中使用,例如某些指令可能会选择写入一个特定的寄存器或另一个寄存器。
- ALUop (Arithmetic Logic Unit Operation): 这个信号决定了算术逻辑单元(ALU)应该执行的操作。例如,它可以是加、减、与、或等操作。
- ALUinB: 这个信号决定了从寄存器文件(Register File)传递给ALU的第二个操作数是什么。它可能是一个直接从寄存器文件中读取的值,或者是某种立即数(immediate value)。
- DMwe (Data Memory Write Enable): 这个信号决定了是否应该将数据写入数据内存(Data Mem)。当DMwe为1时,数据会被写入内存;当DMwe为0时,数据内存保持不变。
- Rwd (Read Data): 这个信号从数据内存(Data Mem)中读取数据。
- BR: 这个信号与分支指令相关。当处理器执行一个分支指令,并且满足分支条件时,这个信号会被激活。
- JP: 这个信号与跳转指令相关。它表示当处理器执行一个跳转指令时的行为。
control for add
当aluop为0的时候是加法,aluop为1的时候是减法
control for sw
control for beq
control for lw
Implementing Control
那么如何实现一个control呢?
Each insn has a unique set of control signals
- most are function of opcode
- some may be encoded in the instruction itself
- the aluop signal is some portion of the mips func field
- requires careful ISA design
ROM
ROM (read only memory): think rows of bits
- bits in data words are control signals
- lines indexed by opcode
- rom control for 6-insn MIPS datapath
- X is dont care
就是整个编码,给他编出来
对这个有疑问,得求解释
只有PC,register file和data memory是有clock的,他是一个一个被送进来,其实就是流水线操作。但现在有一个问题,就是单周期可以用流水线吗,假如需要到data memory的时候,PC都已经是+12的了。??????
解释:可能是因为single-cycle的时候其实只有PC接了时钟?所以所有的操作都是在一个上升沿的时候完成的。这也就不会出现上面所说的问题。
Lec14 Datapath2
single-cycle datapath performance
- low cycles per instruction (CPI): 1 一圈下来跑一行instruction
- long clock period: to accommodate slowest insn 要去适应最长的那个insn需要的时间,每个period
Performance
三个部分组成了performance
- number of instructions (which is compiler’s job)
- cycles per instruciton (CPI)
- clock period (1/clock frequency)
Insns/Program: determind by compiler + ISA
- generally assume fixed program when doing micro-architecture
micro-architecture
- the details of how the ISA is implemented
- affects CPI and Clock frequency
Performance modeling&analysis
Single-Cycle Datapath Performance
CPI为1,clk period得适应最长insn
取代的是Multi-Cycle Datapath
多循环datapath:攻击high clk period
- 把datapath分为多个阶段(这里是5个),用Flipflop隔开
- FSM控制insn的流动在各个stage中,通过stage控制信号
- insns可以越过一些stage并提前退出
Multi-cycle datapath FSM
Multi-cycle datapath example: add
- Short clk period 低时长
- High CPI 高cycle per insn
CPI depends on instructions
- Branches / jumps: 3 cycles
- ALUs: 4 cycles
- Stores: 4 cycles
- Loads: 5 cycles
overall CPI is weighted average
例如:20%loads,15% stores,20% branches,45% ALU
CPI = 0.2 * 5 + 0.15 * 4 + 0.2 * 3 + 0.45 * 4 = 4.0
加入added logic (flip flops)
所以每个clk period不都是1/5个周期,会稍微的长一点
Clk period * CPI = Performance
一些部分的重复,提高利用效率,这就是piplining的作用
Lec15 Pipelining 1
通常一个MIPS指令包含如下五个处理步骤:
- 从指令储存器中读取指令
- 指令译码的同时读取寄存器。MIPS的指令格式允许同时进行指令译码和读寄存器
- 执行操作或者计算地址
- 从数据存储器中读取操作数
- 将结果写回寄存器
所有的流水级(pipeline stage)都只花费一个时钟周期的时间,因此,时钟周期必须够满足最慢的操作的执行需要。比如上图的200ps。
性能加速比归纳为一个公式:
指令执行时间流水线 = 指令执行时间非流水线/流水线级数
The von Neumann Model (VN loop)
- Instruction Fetch: read insn bits from memory
- Decode: Figure out what those bits mean
- Operand Fetch: read registers (+ mem to get sources)
- Execute: do the actual operation (add the #s)
- Result Store: write result to register or memory
- Next Instruction: figure out mem addr of next insn, repeat
5 stage piplined datapath
stages: Fetch, Decode, eXecute, Memory, Writeback
Latches (pipeline registers): PC, F/D, D/X, X/M, M/W
pipeline registers (latches): use registers between stages to carry data and control
比如说load:
if: instruction fetch (instruction memory)
- fetch the instruction from the instruciton memory
id: instruction decode (read ports) - register fetch and insn decode
ex: calculate the memory address (ALU)
mem: read the data from data memory (data memory)
wb: write the data back to register file (write port)
Temporary values (PC,IR,A,B,O,D) re-latched every stage
- notice, PC not latched after ALU stage
应该是因为pc需要等到alu计算完之后才可以下一步行动,不然乱跳转
pipeline terminology
- Scalar pipeline: one insn per stage per cycle
- in-order pipeline: insns enter execute stage in VN order
- pipeline depth: number of pipeline stages
- nothing magical about five
- trend has been to deeper pipelines
假如一个lw insn和r type一起进去,一个是有5个stage,一个是有4个stages,但是就会出现两个都在第五个时间段进行wr的操作。这就会产生data hazard
解决方法,所有的step都要比上个周期相同的step晚一个周期进行,不会同时进入开始抢夺。
pipeline diagram
图像:shorthand for what we just saw
Across: cycles
Down: insns
Convention: X means lw $4, 0($5) finished execute stage and writes into X/M latch at end of cycle4
把controler的signals也一去通过pipeline传送过去
pass control signals with instruction through pipeline
pipeline performance calculation
Why is pipeline clock period > delay thru datapath / number of pipeline stages?
- latches(FFs) add delay latch有延迟
- pipeline stages have different delays, clock period is max delay 不同的管道延迟是不同的,clk需要选择最长的那个延迟
- both fators have implications for ideal number pipeline stages 这两个因素对理想的管道级数都有影响
Why is pipeline cpi > 1?
- cpi for scalar in-order pipeline is 1 + stall penalties
笔记太多了我选择看ppt