1. 布尔门
布尔门是对布尔函数的物理实现,简单的布尔门相互连接可以实现复杂芯片的功能
1.1 布尔代数/布尔函数
- 布尔代数处理布尔型(二进制型)数值
- 布尔函数是指输入输出数值均为布尔型数值的函数
计算机硬件基于二进制数据表示和处理,所以布尔函数在硬件体系结构的描述,构建和优化过程中扮演着十分重要的角色,如何正确地表达和分析布尔函数是迈向构建计算机体系结构地第一步
每个布尔函数,不管有多复杂都可以只用三个布尔算子And
,Or
,Not
来完全表示(在布尔中,我们处于有限的世界)
比如对于下面的真值表
x | y | z | f |
---|---|---|---|
0 | 0 | 0 | 1 |
0 | 0 | 1 | 0 |
0 | 1 | 0 | 1 |
0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 |
1 | 0 | 1 | 0 |
1 | 1 | 0 | 0 |
1 | 1 | 1 | 0 |
首先构建仅对| 0 | 0 | 0 | 1 |
成立的布尔函数
(NOT(x) AND NOT(y)AND NOT(z))
再构建仅对| 0 | 1 | 0 | 1 |
成立的布尔函数
(NOT(x)AND y AND NOT(z))
再构建仅对| 1 | 0 | 0 | 1 |
成立的布尔函数
(x AND NOT(y) AND NOT(z))
三个表达式进行或运算即为最终结果
(NOT(x)AND NOT(y)AND NOT(z)) OR
(NOT(x)AND y AND NOT(z)) OR
(x AND NOT(y) AND NOT(z))
对于任何布尔函数我们都能只用AND
和NOT
两个布尔算子来表示
为了证明这点我们仅需证明OR
可以使用AND
和NOT
两个布尔算子来表示
(x OR y) = NOT(NOT(x) AND NOT(y))
对于任何布尔函数我们都能只用NAND
布尔算子来表示
NADN
仅有两个输入都为1结果才为0即(x NADN Y)=NOT(x AND y)
为了证明任何布尔函数我们都能只用NAND
布尔算子来表示即证明AND
和NOT
可以用它表示
NOT(x) = (x NAND x)
(x AND y) = NOT(x NAND y)
1.2 门逻辑
- 门是用来实现布尔函数地物理设备;如果布尔函数f有n个输入变量,返回m个二进制地结果,那么用来实现这个函数的门将会有n个输入管脚和m个输出管脚
- 复杂的门电路由基本的门组成
- 最简单的门由微小的开关设备(晶体管)构成
物理实现:电气工程
1.3 HDL
(Hardware Description Language
)
硬件描述语言HDL是一种用于定义和测试芯片的规范,硬件设计者通过编写HDL程序来描述芯片的结构,该程序将使用硬件仿真器进行测试,硬件仿真器接受输入HDL程序,在计算机内存内构建该虚拟芯片的内存映像进行测试
文件扩展名:
每个芯片都定义在一个独立的文本文件中,即名为Xxx的芯片被定义在文件Xxx.hdl
中
芯片结构:
CHIP 芯片名{
//描述头
IN 输入管脚名, 输入管脚名, ...;
OUT 输出管脚名, 输出管脚名, ...;
//描述体
PARTS:
内部芯片单元语句;
内部芯片单元语句;
..,
}
芯片的定义由描述头header
和描述体parts
组成
- 描述头定义了芯片的接口,也就是芯片的名称,输入输出管脚的名称,充当芯片API或公共文档的角色
- 描述体parts定义了其实现,描述了所有底层电路的名称和拓扑结构,这些电路是构成该芯片的基本部分,每个部分都用一个
statement
来表示,他描述了该部分的名称以及与其他部分的连接方式;内部模块的连接是通过建立和连接的内部管脚来描述的
例如要设计一个Xor
功能芯片,Xor
是可以通过And
,Or
,Not
组合实现的Xor(a,b)=Or(And(a,Not(b)),And(Not(a),b))
- 该HDL程序需要调用的内部函数
Xxx
都代表一个独立的芯片,被定义在独立的Xxx.hdl
程序中,比如上面表达式中我们需要使用的And
,Or
,Not
都被定义在And.hdl
,Or.hdl
,Not.hdl
- 我们假设现在程序使用的3个底层程序(
Xor.hdl
,Or.hdl
,Not.hdl
)都是可以现成使用的,设计者只需要关注如何在构建芯片的过程中正确地组织这些内部芯片
/* Xor gate:
if a<>b out 1 else out 0
*/
CHIP Xor{
IN a, b;
OUT out;
PARTS:
Not(in=a, out=nota);
Not(in=b, out=notb);
And(a=a, b=notb, out=w1);
And(a=nota, b=b, out=w2);
Or(a=w1, b=w2, out=out)
}
可以看到内部模块的连接是通过建立和连接内部管脚来描述的,比如上面的Not门的输出管脚又和And门的输入管脚相连,HDL代码通过Not(in=a, out=nota)
和And(a=nota, b=b, out=w2)
来描述这个连接
- 第一个语句
Not(in=a, out=nota)
建立了一个名为nota
的内部管脚并作为Not
门的输出 - 第二个语句
And(a=nota, b=b, out=w2)
将nota
作为And
门的输入管脚
1.4 NAND
的实现
1.5 使用NAND
门实现AND
, OR
, XOR
基础芯片的实现:使用Nand门,构建基本逻辑门
计算机系统要素的笔记
使用Nand实现各种基本逻辑门
//NOTa
out = Nand(a,a)
//a AND b
out = Not(Nand(a,b))
//a OR b
out = Nand(Not(a),Not(b))
//a XOR b
out = Or(And(a,Not(b)),And(Not(a), b))
//多路复用
out = Or(And(Not(sel),a),And(sel,b))
//多路分解
a=And(in, Not(sel))
b=And(in,sel)
① Not
out = Nand(a,a)
② And
out = Not(Nand(a,b))
③ Or
out = Nand(Not(a),Not(b))
④ Xor
当两个输入不一样时,异或门输出1
out = Or(And(a,Not(b)),And(Not(a), b))
⑤ 选择器 多路复用
选择器元件选择两个输入中的一个作为输出,s为选择比特,决定选择哪个输入
- 为0时,选择d0;
- 为1时,选择d1
out = Or(And(Not(sel),a),And(sel,b))
⑥ 开关 多路分解
开关元件将数据比特送到2个输出之一,s(选择位)决定d(数据位)是从c1还是c0输出
a=And(in, Not(sel))
b=And(in,sel)
2. 布尔运算
2.1 计算机中的数值表示
2.1.1 机器码/真值
机器数
一个数在计算机中的二进制表示形式, 叫做这个数的机器数,机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1
比如,十进制中的数 +3
,计算机字长为8位,转换成二进制就是00000011
。如果是 -3
,就是 10000011
真值
因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011
,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011
转换成十进制等于131)
所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值
例:
0000 0001
的真值 =+000 0001
=+1
1000 0001
的真值 =–000 0001
=–1
2.1.2 原码/补码/反码
原码
原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值,比如如果是8位二进制
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位,因为第一位是符号位,所以8位二进制数的取值范围就是:[1111 1111 , 0111 1111]
,即[-127 , 127]
;
原码是人脑最容易理解和计算的表示方式
反码
反码的表示方法是:
- 正数的反码是其本身
- 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反
比如:
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
补码
补码的表示方法是:
- 正数的补码就是其本身
- 负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1(即在反码的基础上+1)
比如:
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补
2.1.3 为何要使用原码/反码/补码
对于计算机,加减乘数已经是最基础的运算,要设计的尽量简单;
计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂,于是人们想出了将符号位也参与运算的方法;
根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0
, 所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了;使用补码可以达到这个目的,基本原理看原码, 反码, 补码 详解
更准确的说,这意味着能使用单一芯片(算数逻辑单元ALU)将硬件执行的基本算数操作和逻辑操作都封装起来
2.2 加法器
① 半加器
加法元件将两个比特相加。结果是个2位的值。
h输出是高位,l输出是低位(就像在2位10进制数中,十位是高位,个位是低位)
② 全加器
一个加法元件,有3个输入:a, b, 和c。
输出是一个2位的数值。h是高位、l是低位。
③ 多位全加器
一个能加两个2位数和1位进位的加法器。
输入
- a1 a0是一个2位数字。
- b1 b0是一个2位数字。
- c(进位输入)是一个1位数字。
输出 - 输入数字的和,是一个3位数字:c s1 s0其中c是最高位
④ 自加器
让一个16位数增加1,忽略溢出,1可以使用异或门+非门得到
2.3 减法
2.4 ALU
冯诺依曼体系
不在硬件中实现的部分可以在软件层面增强,就像在软件层面实现乘除一样
具体实现
【计算机系统要素】实现加法器和简单的ALU