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
  1. We have transistors. They’re electronic switches.
  2. You can make logic by combining transistors.
  3. You can make arithmetic from logic.
  4. Transistors can also make basic memory.
  5. Combine arithmetic and logic circuits to make an Arithmetic/Logic Unit (ALU)
  6. Combine memory elements to make registers to store values
  7. Combine the ALU, registers, and other stuff to make a full CPU!
  8. Use other transistor configurations to make large-scale RAM.
  9. RAM is too slow, so add cache, another form of memory to speed it up.
  10. We have storage in the form of hard drives and SSDs.
  11. Use storage and RAM together: this is virtual memory, which allows us to run more programs with more efficiency.
  12. We halt the CPU with exceptions to handle things like I/O to storage.
  13. The modern computer is governed by basic software called the operating system.
  14. We have networking to connect multiple computers.
  15. CPU performance is increased by various techniques, including pipelining.

Lec2 Transistor to Gates

Vcc & Gnd

Vcc就是power(高电平), Gnd就是ground(低电平)。高电平用1V表示,低电平用0V表示。两个不可以直接连,会短路!

Transistor

NMOS and PMOS
2 types:

  • NMOS (左边没带圈圈的)
    • gate是1的时候接通,0是断线
  • PMOS (右边带圈圈的)
    • gate是0的时候接通,1的时候断线

CMOS

Complementary MOS
CMOS
上面接了一个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

NOR 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
NOR gate and truth table

diagram of 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

  1. Pick between 2 inputs (2to1Mux)
  2. Make a truth table (S = 0 pick A, S = 1 pick B)
  3. Sum of product to get formula
  4. Find the rows where the output is 1
    (!A & B & S) | (A & !B & !S) | (A & B & !S) | (A & B & S)
  5. Simplifying this formula: (A & !S) | (B & S)

通过简化过的formula构成2to1的Mux:
2to1mux

通过这个可以进行进一步的组合,2to1Mux变成4to1变成8to1变成16to1变成32to1(通过不断增加selector的bits数量)


DeMorgan’s Laws
DeMorgan's Laws


Lec4 Number Representations

二进制没啥可说的

二进制转化为16进制(0x开头),可以把二进制四位四位分开,每一位分别计算,作为16进制的一位。
二进制十进制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

4 to 2 encoder
2 to 4 decoder

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

1bit full adder
一位全加器


RCA

ripple carry adder
rca
每一个adder都有两个unit的delay(因为从input到output需要穿过两个gate),所以rca的delay是很大的,需要一个一个adder的过,N个adder的delay就会是2N。


CSA

carry select adder
32bits CSA
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

  1. 首先先把10进制的数字变成二进制的小数
  2. 比如现在的结果是100.010101
  3. 现在挪移小数点到1.00010101
  4. 现在小数点左移了2位(左移n位)
  5. 小数点后的部分作为玛莎拉
  6. 碎片部分是127+n的结果转化为八位二进制
  7. 符号为正常填入

ieee754变成float

  1. 现在先看符号位置找到符号
  2. 把碎片部分换算为十进制
  3. 碎片 = n + 127
  4. 得到了n之后,玛莎拉部分小数点之前加上1
  5. 把加1之后的结果乘2的n次方(这也是个二进制,所以挪移小数点)

Lec6 Storage and Clocking1

SR Latch

SR latch
为什么不可以输入两个都为1?

因为两个都为1会导致输出结果不平衡,不会有一个固定的结果。

其他的输入都会有在最终平衡,输入不再改变。

sr latch


Data Latch

data latch
为了处理srlatch可能会出现的两个都是1的情况,data latch在输入的时候加入了一个not gate,使R和S输入的数据一定是相反的。

enable作为一个开关,去决定Q的输入,当enable是1的时候,Q的输出才会根据D而发生改变,假如enable为0,Q的输入就会保持当前的输入不变。

data latch

可以使用clock作为enable

Strawman: Level Triggered

看ppt


Lec7 Storage and Clocking2

DFF

DFF
相比于data latch的持续监测,dff的enable就是一个脉冲(clk从down到high),当出现脉冲的时候,记录当前状态,然后就继续保持不变直到下一个脉冲激活。
DFF
把两个dff对接起来的时候,需要ensure signals reach DFF before clk rises
会存在delay,因为两个dff都需要输入,这时候怎么减小delay呢?可以让c从另一边输入


Register

reg
写入的时候使用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,就是什么都没有)

tri-state


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
  • 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

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

r type

假如我想加上一个常数怎么办?

  1. 把常数放到寄存器中
  2. 使用带immediate的instruction

I type

1
I Type: <op> rt, rs, immediate

I-type

正常操作之后带i基本上就是需要immdiate的操作

有许多isns有immediate形式:

  1. addi, andi, ori, xori之类的都有
  2. 没有sub (表达减法使用加上负数来表示)
  3. 没有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

convert a function to assembly


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]
    Directives examples

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 程序栈储存在内存里:从内存的顶部一路往下
    stack frames

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

  1. Establish stack frame
    • subtract the frame size from the stack pointer
      • subiu $sp, $sp, <frame-size>
    • Typically, minimum frame size is 32 bytes (8words)
  2. 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
  3. Establish Frame pointer
    • Add the stack - 4 to the address in $sp
    • addiu $fp, $sp, - 4

On return from a call

  1. Put returned values in registers $v0, [$v1]
  2. Restore callee-saved registers
    • restore $fp and other saved registers. [$ra, $s0 - $s7]
  3. Pop the stack
    • add the frame size to $sp addiu $sp, $sp, <frame-size>
  4. Return
    • jr to address in $ra

Lec12 ISAs and MIPS 4

execution example
内存就像是一栋大楼,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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int leaf_example (int g, int h, int i, int j)
{
int f;

f = (g+h)-(i+j);
return f;
}

leap_example:
addi $sp, $sp, -12 # adjust stack to make room for 3 items
sw $t1, 8($sp)
sw $t0, 4($sp)
sw $s0, 0($sp)

add $t0, $a0, $a1
add $tl, $a2, $a3
sub $s0, $t0, $t1

add $s0, $t0, $zero

lw $s0, 0($sp) # restore register $sO for caller
lw $tO, 4($sp) # restore register $tO for caller
lw $t1, 8($sp) # restore register $t1 for caller
addi $sp, $sp, 12 # adjust stack to delete 3 items

jr $ra # jump back to calling routine

参数变量 g、 h、 l 和j对应参数寄存器 $a0、 $a1、 $a2 和 $a3, f对应 $s0。编译后的 程序是以如下标号开始的过程


现在有一个c函数,i 和 j存放在寄存器 $s3 和 $s5 中,数组 save 的基址存放在寄存器 $s6

1
2
while(save[i]==k)
i+=1;
1
2
3
4
5
6
7
8
Loop:
sll $t1, $s3, 2
add $t1, $t1, $s6
lw $t2, 0($t1)
bne $t2, $s5, Exit
addi $s3, $s3, 1
j Loop
Exit:

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指令包含如下五个处理步骤:

  1. 从指令储存器中读取指令
  2. 指令译码的同时读取寄存器。MIPS的指令格式允许同时进行指令译码和读寄存器
  3. 执行操作或者计算地址
  4. 从数据存储器中读取操作数
  5. 将结果写回寄存器

所有的流水级(pipeline stage)都只花费一个时钟周期的时间,因此,时钟周期必须够满足最慢的操作的执行需要。比如上图的200ps。

性能加速比归纳为一个公式:
指令执行时间流水线 = 指令执行时间非流水线/流水线级数

The von Neumann Model (VN loop)

  1. Instruction Fetch: read insn bits from memory
  2. Decode: Figure out what those bits mean
  3. Operand Fetch: read registers (+ mem to get sources)
  4. Execute: do the actual operation (add the #s)
  5. Result Store: write result to register or memory
  6. 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

作者

Felix Chen

发布于

2023-10-01

更新于

2023-11-29

许可协议

评论