逻辑门
先来认识(记)一下基础的逻辑门:
注意,NAND,NOR那里的那个小圆圈代表的是取反(negation),跟最底下的Negation是一个效果。
比如这里表达的是 $y = \neg (a \wedge \neg b) $ :
一般情况下堵在逻辑门出入口的圆圈指的是取反,而下面这种只是表示线路连接而已:
不要弄混了。
加法(Addition)
半加器(Der Halbaddierer ,HA)
半加器的目的是计算2个bit的加法,输出也为2个bit,即:
1 | a0 |
也可以用数学公式表达:
对应的真值表则是:
也就是说
对应的逻辑电路图:
左边是and,右边是xor。在之后的内容里用HA指代半加器。
Kosten和Tiefe分别是:C(HA) = 2, Depth(HA) = 1。
全加器(Der Volladdierer ,FA)
全加器的目的是计算3个bit的加法,输出为2个bit,即:
1 | a0 |
其中c是进位信息。
对应的数学表达:
真值表:
注意到:
(ha0表示2个数相加得到的s0位的值,ha1同理。)
逻辑电路图:
Kosten和Tiefe分别是:C(HA) = 5, Depth(HA) = 3。
选择器(Multiplexer,MUX)
选择器正如字面意思,会从2个数里选择一个数。数学表达:
注意到:
逻辑电路图:
后续一般用这个符号指代:
存储(Speichern)
RS-Latch / RS-FlipFlop
真值表:
D-Latch / D-FlipFlop
(设上面 and 的结果为S,下面 and 的结果为R,跟RS-Latch的位置一样。)
真值表:
2*2 Bit Speicher
(write位等于0代表读,等于1代表写;灰色的是选择器;上面的2个黄色部分是Adresse=0的结果,下面的是Adresse=1的。)
Inkrementer
自增器主要用于比如说更新程序计数器(Program counter),需要到达的效果类似:
1 | add pc, pc, 4 |
需要2个步骤,计算加法并且存储结果。所以对应的逻辑电路为:
RISC-V Single-Cycle Prozessor
先解释一下所有需要的部件:
Program Counter (PC):
Instruktionsspeicher:存储所有需要执行的指令
Registerbank:
会处理所有的寄存器。其中A1,A2是操作里的寄存器的地址,RD1和RD2是这两个寄存器里的具体内容。A3和WD3是第3个寄存器(存储计算结果的)。只有当WE3=1的时候才会写入第三个寄存器。
Arithmetic Logic Unit (ALU):
详细版:
ALU会进行所有的逻辑运算。ALUControl这个参数会指定执行具体哪项操作(如ADD, AND, SUB 等,以3 bit的格式)。注意,最后一个bit的内容(即 $\text{ALUControl}_0$)会传递给上面的Sum以及Sum上面的那个MUX。
比如:
- 000表示加法;
- 001表示减法
- 010表示AND;
- 011表示OR;
- 101表示进行是否等于0的判断。
Datenspeicher:
CLK表示系统内的计时器。A 是需要读取或者加载的地址。RD是读取到的信息(Read Data),WD是需要写入的信息(Write Data)。只有当WE=1的时候才会写入。
完整的RISC-V Single-Cycle Prozessor的结构:
解释一下每个参数:
PCSrc:决定当前地址,是继续下去还是回到返回地址。
- 0表示回到之前的地址继续
- 1表示在现在的地址基础上继续。
ResultSrc:决定当前输出。
- 如果是lw之类的操作,需要设为01,因为需要将读取到的信息存入结果寄存器(RD -> WD3)。
- 如果是R-Type之类的操作,则需要设为00。
MemWrite:决定当前是否要写入到Memory中。
- 0表示不写入;
- 1表示写入。
ALUControl:决定当前的ALU操作
add, and, sub 之类的R-Type操作直接设为操作本身就好(以3 bit的格式);
lw, sw需要设为add,因为需要通过加法计算地址;
beq等需要设为sub,因为这里判断a和b是否相等是通过直接传递a-b的计算结果实现的。
ALUSrc:决定当前是使用的第二个寄存器还是立即数(imm)。
- 0表示使用第二个寄存器的内容;
- 1表示使用imm。
ImmSrc:决定当前读取imm的格式,因为每种Type的指令存储imm的格式都不一样。
RegWrite:决定当前结果是否需要写入第3个寄存器。
- 0表示不写入;
- 1表示写入。
ControlUnit的部分构造稍微再具体一点是这样的:
一些常见操作的参数例子:
x表示不重要。比如说在 jal 那里,jump 的参数会被设为1,这个1会和 (zero AND Branch) 进行 or 操作,所以结果一定是1,也就意味着 Branch的结果在这个情况下无关紧要。
RISC-V Multicycle Prozessor
只用了一个硬件存储指令以及数据,并且加了很多个CLK,将整个流程拆成了很多步。
在Singlecycle里,takt的时间需要考虑最复杂的指令执行所需要的时间,比如说load之类的操作比其他的操作要久很多,所以整体看下来很亏,因为需要将就这种操作。
但在Multicycle里,会将每个操作拆成好多步,takt的时间只需要设置成这些步骤中最长的时间即可。