处理器芯片的本质是数字电路
0
和1
的芯片
需要先理解信息在数字电路中是如何表示, 处理和存储的
0
和1
的含义\[1110_{B}=2^3\times1+2^2\times1+2^1\times1+2^0\times0=14\]
每一个二进制位都代表真值的大小,
这种表示称为无符号二进制整数
(unsigned binary integer),
简称无符号数
计算机如何表示负数?
-
后添加这个负数的绝对值(如-5
)有符号二进制整数
(signed binary integer),
简称有符号数
最高位表示符号位(0
为正数, 1
为负数),
其余位表示对应真值的绝对值
0b00000111 = 7
0b10000111 = -7
0b00100010 = 34
0b10100010 = -34
# 考虑采用8位的RCA进行原码加法:
0b00000111 (7) 0b10000111 (-7) 0b10000111 (-7) 0b00000111 (7)
+0b00100010 (34) +0b10100010 (-34) +0b00100010 (34) +0b10000111 (-7)
----------- ----------- ----------- -----------
0b00101001 (41) 0b00101001 (41) 0b10101001 (-41) 0b10001110 (-14)
观察后得出结论:
要实现原码加法器, 需要先实现减法器, 并根据两数符号和绝对值的情况, 选择出正确的处理结果
反码尝试解决原码加法中涉及负数的问题
0
, 其表示与原码一致0b00000111 = 7
0b11111000 = -7
0b00100010 = 34
0b11011101 = -34
# 考虑采用8位的RCA进行反码加法:
0b00000111 (7) 0b11111000 (-7) 0b11111000 (-7) 0b00000111 (7)
+0b00100010 (34) +0b11011101 (-34) +0b00100010 (34) +0b11111000 (-7)
----------- ----------- ----------- -----------
0b00101001 (41) 0b11010101 (-42) 0b00011010 (26) 0b11111111 (-0)
观察后得出结论:
0b00000111 (7) 0b11111000 (-7) 0b11111000 (-7) 0b00000111 (7)
+0b00100010 (34) +0b11011101 (-34) +0b00100010 (34) +0b11111000 (-7)
----------- ----------- ----------- -----------
0b00101001 (41) 0b11010101 (-42) 0b00011010 (26) 0b11111111 (-0)
0b11111111
-0
0
, 则RCA结果正确让-0
作为RCA的输入进行计算, 又会得到不正确的结果:
反码加法器的一种实现方式:
补码进一步修复了反码计算错误时结果的偏差
0
, 其表示与原码一致1
0b011...11
, 对应的真值是\(2^{n-1}-1\)0b100...00
, 对应的真值是\(-2^{n-1}\)
取反加1
来得到0b01111111=127
取反加1
,
得到的是0b10000001=-127
0b10000000=-128
, 对其进行取反加1
,
得到的是0b01111111+1=0b10000000=-128
, 与其自身相同设某正数\(p\)的补码表示为\(\mathrm{0b}0p_{n-2}p_{n-3}\dots p_1p_0\), 并设其相反数\(q\)的补码表示为\(\mathrm{0b}1q_{n-2}q_{n-3}\dots q_1q_0\)
根据补码的定义, 有 \[\mathrm{0b}q_{n-2}q_{n-3}\dots q_1q_0=\mathrm{0b}\overline{p_{n-2}}\overline{p_{n-3}}\dots\overline{p_1}\overline{p_0}+1\] 其中\(\overline{p_i}\)表示\(p_i\)的按位取反
将两侧的二进制表示加权展开, 有 \[\sum_{i=0}^{n-2}2^iq_i=\sum_{i=0}^{n-2}2^i\overline{p_i}+1\]
此外, 由于\(p_i\)为0
或1
,
故\(\overline{p_i}\)为1
或0
,
因此有\(p_i+\overline{p_i}=1\)
考虑\(q\)的真值, 有 \[\begin{array}{ll} q&\displaystyle=-p=-(\mathrm{0b}0p_{n-2}p_{n-3}\dots p_1p_0)=-\sum_{i=0}^{n-2}2^ip_i \\ &\displaystyle=-\sum_{i=0}^{n-2}2^i(1-\overline{p_i})=-\sum_{i=0}^{n-2}2^i+\sum_{i=0}^{n-2}2^i\overline{p_i} \\ &\displaystyle=-(2^{n-1}-1)+\sum_{i=0}^{n-2}2^i\overline{p_i}=-2^{n-1}+(\sum_{i=0}^{n-2}2^i\overline{p_i}+1) \\ &\displaystyle=-2^{n-1}+\sum_{i=0}^{n-2}2^iq_i \\ \end{array}\]
\[q=\mathrm{0b}1q_{n-2}q_{n-3}\dots q_1q_0=-2^{n-1}+\sum_{i=0}^{n-2}2^iq_i\]
结论: 补码的符号位可以以\(-2^{n-1}\)为权来展开, 从而求得补码的真值
例如, 用这种方式对0b11111001
加权展开, 则有 \[-2^7+2^6+2^5+2^4+2^3+2^0=-7\]
与编码的真值一致
# 考虑采用8位的RCA进行补码加法
0b00000111 (7) 0b11111001 (-7) 0b11111001 (-7) 0b00000111 (7)
+0b00100010 (34) +0b11011110 (-34) +0b00100010 (34) +0b11111001 (-7)
----------- ----------- ----------- -----------
0b00101001 (41) 0b11010111 (-41) 0b00011011 (27) 0b00000000 (0)
观察后得出结论: 用RCA计算补码加法时, 即使输入包含负数, RCA所得结果仍然符合数学意义
进一步地: 可以用RCA来计算补码的减法!
A-B=A+(-B)
A
和B
为何值,
RCA所得结果都符合数学意义A+(-B)
= 数学意义上的A+(-B)
=
数学意义上的A-B
正是由于可以用同一个加法器电路来计算补码的加法和减法, 现代计算机中普遍用补码来表示整数
以4位二进制数为例, 将二进制数按顺时针顺序排列(时钟模型):
0000 (0)
(-1) 1111 0001 (1)
(-2) 1110 ^ 0010 (2)
(-3) 1101 | 0011 (3)
(-4) 1100 + 0100 (4)
(-5) 1011 0101 (5)
(-6) 1010 0110 (6)
(-7) 1001 0111 (7)
1000 (-8)
RCA是在二进制层次上进行加法:
要让某种编码的加法结果符合数学意义, 就要让其真值也按顺时针递增
上图的括号()
展示了补码的例子:
7
和-8
之间的边界,
用RCA计算的结果总是符合数学意义 原码 反码
0000 (0) 0000 (0)
(-7) 1111 0001 (1) (-0) 1111 0001 (1)
(-6) 1110 ^ 0010 (2) (-1) 1110 ^ 0010 (2)
(-5) 1101 | 0011 (3) (-2) 1101 | 0011 (3)
(-4) 1100 + 0100 (4) (-3) 1100 + 0100 (4)
(-3) 1011 0101 (5) (-4) 1011 0101 (5)
(-2) 1010 0110 (6) (-5) 1010 0110 (6)
(-1) 1001 0111 (7) (-6) 1001 0111 (7)
1000 (-0) 1000 (-7)
原码存在两个问题:
0b0000
和0b1111
之间不连续 =>
计算0+(-1)
, 得到-7
(-4)+1
,
得到-5
反码通过取反
操作修复了问题2, 但问题1仍然存在
0b0000
和0b1111
之间不连续 =>
计算0+(-1)
, 得到-0
补码通过编码上的+1
操作, 将负数真值往顺时针转动1格,
修复了问题1
即使是补码, 也存在编码连续但真值不连续的边界
0b0111...111
和最小数0b1000...000
之间的边界如果加法的计算跨越了这个边界, 所得结果将与数学意义不符
这个边界是必然存在的:
这种计算结果超过编码表示范围的情况,
称为溢出
(overflow)
从时钟模型的角度来看, 跨越不连续边界分两种情况:
从数学意义的角度来看, 这两种情况分别对应:
在真值表中考虑符号位的加法情况, 即可检查是否发生溢出!
\(A_{n-1}\) | \(B_{n-1}\) | \(C_{n-1}\) | \(|\) | \(C_n\) | \(S_{n-1}\) | 溢出 |
---|---|---|---|---|---|---|
0 | 0 | 0 | \(|\) | 0 | 0 | 否 |
0 | 0 | 1 | \(|\) | 0 | 1 | 是 |
… | … | … | \(|\) | … | … | … |
新的秒数 = 旧的秒数 + 1
?
我们需要新的电路特性:
\(Q\)和\(\overline{Q}\)分别经过两个反相器后, 保持不变
0
; \(Q=1,
\overline{Q}=0\), 则认为存储1
如果从某时刻开始, \(Q=\overline{Q}=0\), 会怎样?
不过, 即使上述电路位于稳定状态, 也使无法更新\(Q\)和\(\overline{Q}\)
S | R | \(|\) | Q |
---|---|---|---|
0 | 0 | \(|\) | 保持 |
0 | 1 | \(|\) | 0 |
1 | 0 | \(|\) | 1 |
1 | 1 | \(|\) | 禁止 |
S(et)R(eset)锁存器, 其中S和R用于控制锁存器的状态
#T(SR latch) = 2#T(nor) = 2 * 6 = 12
不允许S=R=1
思想: 额外添加两个与门, 将SR锁存器的4种输入限制成3种合法输入
WE | D | \(|\) | S | R | \(|\) | Q |
---|---|---|---|---|---|---|
0 | 0 | \(|\) | 0 | 0 | \(|\) | 保持 |
0 | 1 | \(|\) | 0 | 0 | \(|\) | 保持 |
1 | 0 | \(|\) | 0 | 1 | \(|\) | 0 |
1 | 1 | \(|\) | 1 | 0 | \(|\) | 1 |
#T(D latch) = #T(SR latch) + 2#T(and) + #T(not) = 12 + 2 * 8 + 2 = 30
#T(D latch) = 4#T(nand) = 4 * 6 = 24
面积更小
WE | D | \(|\) | \(\overline{S}\) | \(\overline{R}\) | \(|\) | Q |
---|---|---|---|---|---|---|
0 | 0 | \(|\) | 1 | 1 | \(|\) | 保持 |
0 | 1 | \(|\) | 1 | 1 | \(|\) | 保持 |
1 | 0 | \(|\) | 1 | 0 | \(|\) | 0 |
1 | 1 | \(|\) | 0 | 1 | \(|\) | 1 |
WE=1
时, 下方传输门导通, 上方传输门截止,
Q=D
WE=0
时
Q
的值D
无法影响锁存的值#T(D latch) = 3#T(not) + 2#T(tg) = 3 * 2 + 2 * 2 = 10
一个复杂系统包含多个模块, 需要考虑如何控制多个模块协同工作
需要正确实现一种同步关系
需要额外的机制来实现同步关系
时钟信号 = 在高低电平之间来回翻转的脉冲信号
+--- positive edge +--- negative edge
V V
+---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+
| | | | | | | | | | | | | | | |
+---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +
同步电路: 通过全局时钟信号实现同步关系
时钟信号的不同周期存在天然的先后顺序
异步电路 = 通过模块之间的局部通信信号实现同步关系
在同步电路中, 所有模块都在时钟信号的控制下工作
和同步电路相比, 异步电路:
同步电路被业界广泛采用
同步电路: 存储单元仅在时钟边沿到达时写入数据, 且在该时钟周期中稳定读出该数据
D锁存器的性质: WE有效时, 输入的变化马上传播到输出
将时钟连到D锁存器的WE端仍然无法实现
锁存器属于电平触发(level-triggered)的存储元件
我们需要一种边沿触发(edge-triggered)的存储元件
>
表示该端口需要连接时钟信号
#T(DFF) = 2#T(D-latch) + #T(not) = 2 * 10 + 2 = 22
clk
为低电平, 主锁存器WE
有效,
D
可从外部进入主锁存器WE
无效,
故D
无法传播到从锁存器Q
保持不变clk
上升沿到来, 主锁存器WE
无效,
D
无法从外部进入主锁存器
D
的后续变化将无法对主锁存器造成影响D
“锁”在主锁存器中WE
开始有效, 主锁存器中
“锁住”的数据将传播到从锁存器
clk
为高电平, 主锁存器WE
无效,
不受D
变化的影响WE
虽然有效, 但由于输入保持不变,
故输出也保持不变Q
保持不变
D触发器符合同步电路对存储元件的要求
复位端有效时, 可将D触发器清零
其中, resetn
为低电平有效的复位信号
resetn
为1
时,
其功能与之前的D触发器相同resetn
为0
时,
将往D触发器写入0
#T(DFFR) = #T(DFF) + #T(and) = 22 + 8 = 30
即使resetn
为0
,
也需要等待clk
上升沿到来时, 才会清零
resetn
信号在clk
上升沿到来前就撤销,
将不会发生清零
这种复位方式称为同步复位
异步复位
方式在复位信号有效时, 马上将D触发器清零, 不必等待时钟上升沿到来
置位端有效时, 可将D触发器置1
同步置位
和异步置位
两种方式
异步置位信号setn
有效时,
主锁存器和从锁存器中存储的值直接变为1
两种复位/置位方式对电路的时序有不同影响, 暂不深入讨论
EN
有效时,
选择外部数据D
作为D触发器的输入EN
无效时, 选择D触发器中存储的当前数据作为D触发器的输入
#T(DFFE) = #T(DFF) + #T(2-1 mux) = 22 + 6 = 28
由多个D触发器组成
可采用带复位端或置位端的D触发器, 实现寄存器的初始化
9=0b1001
, 可依次采用DFFS, DFFR, DFFR,
DFFS来构成4位寄存器, 使其在电路复位后存储9
一个32位无初值的寄存器所需的晶体管数量约为:
#T(reg32) = 32#T(DFFE) = 32 * 28 = 896
除了对等设计原则, 实际的电路(如标准单元库)仍然需要考虑其他电气特性
#T(x)
的计算并未考虑这些反相器
#T(x)
对面积的估计是偏低的#T(x)
需要考虑过多细节
#T(x)
仅用于进行大致的估算
在真实的项目中, 通常由EDA工具读取标准单元库的面积数据来进行面积评估
0
与原码一致,
负数为相应相反数的原码的按位取反0
与原码一致,
负数为相应反码加1