计算机的心脏是中央处理单元,简称“CPU” 。这篇文章就利用前几篇文章中提到过的ALU,RAM,寄存器组件做一个CPU。
CPU负责运行程序,程序是由一个个操作组成的,这些操作叫做指令,因为他们“指示”计算机要做什么.
数学计算指令:让ALU去做加减乘除或者更复杂的数学计算
内存指令:CPU会和内存(RAM)通信,然后操作内存进行读写值
首先把上一篇文章的RAM拿出来(只有16个地址意味着是每个内存是16位的,每个地址又可以存8位可以得出是8个内存组装在一起的;因此这个RAM可以看到是由8个16位内存组成)。
内存条的寻址空间意味着每块内存可以可以存储的位数,内存条中的每个地址可以存多少位又是由多少个内存组成。
可以看到每个地址都存储着8位,在后面讲解指令表的时候要注意这八位数字的表示方式。前四位代表操作码,后四位代表的是地址OR寄存器
回顾一下:
上一篇文章中讲到八位的寄存器无非是把八个锁存器链接在一起,8个数据输入线,8个数据输出线,还有一个链接着所有锁存器中的允许写入线。总共17条线
寄存器的作用:用来临时存储数据和操作数据
数据是以二进制值存储在内存里,程序也可以在内存里。
指令:所有CPU支持的指令都会分配一个指令ID也就是表中的第一个INSTRUCTION中的LOAD_A
描述:就是描述这个指令ID是用来做什么操作的
4-BIT OPCODE(操作码):这个指令要做的操作,用4位的操作码表示
ADDRESS OR REGISTERS(地址OR 寄存器):也是4位,表示的是操作码需要使用的地址或者寄存器(比如加载一个内存里的值放入寄存器中就需要指定打开的是哪个内存地址)
在之前我们拿出RAM,可以看到每个地址都存储着8位数字,前四位代表的就是操作码,后四位代表的是地址OR寄存器 .
之后我们会模拟CPU的执行过程,要执行怎样的操作以及怎么样执行就是通过RAM中存储的这八位数字来运行的。
指令地址寄存器:追踪程序运行到哪里了。用于通过地址定位到内存条中的哪条指令,也就是存储当前指令的内存地址ADDRESS
指令寄存器:用于存储当前运行的指令DATA。通过指令地址寄存器读取RAM中指定ADDRESS的DATA然后并写入这个寄存器
启动计算机时,所有的寄存器都是0.
在RAM中放了一个程序(ADDRESS,DATA),现在就是要过一遍运行这个程序的过程
该阶段负责拿到指令,即指令地址寄存器读取RAM中对应地址的值复制到指令寄存器
1.首先将指令地址寄存器连接到RAM中(ADDRESS INPUT),寄存器的初始值为0,因此会去读取RAM中ADDRESS为0的DATA
2.DATA会被复制到指令寄存器中,现在指令寄存器存储了00101110这个指令
现在我们拿到了指令,前四位是操作码对应的是指令表中的LOAD A指令。对应的描述是将RAM的值放入寄存器A
后四位1110是RAM的内存地址,转成十进制就是14.
指令通过”控制单元“进行解码。解码的作用就是判断这个操作码对应的操作是什么(通过少量的逻辑门即可判断)
针对不同的操作码有对应的指令判断电路从而执行不同的操作。例如下面这个就是检查操作码是不是LOADA(0010)指令。
指令寄存器拿到数据DATA后通过控制单元进行解码,现在我们知道了这个是LOADA指令,就可以进行执行阶段了
1.打开RAM允许读取线:我们将检查LOADA指令的电路连接到RAM的READ ENBALE中(如果LOADA输输出为1那么READN ENANLE也是1因此就会打开RAM的允许读取线),并把地址14传入过去。
2.读取RAM 对应地址的值:RAM拿到地址14上的值,0000 0001也就是十进制的三
3.RAM DATA线连接所有的寄存器:LOAD_A指令代表这个值存储在A寄存器中并不影响其他寄存器。因此需要将RAM读出来的值给到寄存器,所以RAM的DATA数据线需要将所有的寄存器都连接起来(DATA线既可以用来做输入又可以用来做输出使用)。
4.打开指定寄存器的允许输入线:用检查“是否为LOADA指令的电路”打开寄存器A的允许写入线(因为是LOADA指令,所以需要将A寄存器的允许写入打开),这样就将RAM中地址为14的值输出保存到了寄存器A中。
5.取下一条指令指令地址寄存器+1:执行阶段结束。开始下一个取指令阶段(读取0001的RAM地址到指令寄存器中,然后在解码执行........之后一直重复这个过程)
上面解释的只是一个LOADA指令,不同的指令由不同的逻辑电路解码,这些逻辑电路会配置CPU内的组件来执行对应操作。这些逻辑电路太复杂我们可以把整个逻辑电路封装为上面所说的控制单元。
也就是下图中的线路。可以看到控制单元链接了所有的寄存器(用于存放和读取数字),和RAM链接的是允许读取和允许输入线(READ ENABLE WRITE ENABLE),还有一条线是ADDRESS INPUT ,这条线是用来告知使用的是16个地址空间中的哪个地址(比如之前的14)
上面解释了指令表中的LOADA指令,LOADB指令和LOADA原理一致,包括STOREB也是只不过是相反过来打开寄存器的允许读取和RAM的允许写入传入地址最后将寄存器的值通过DATA线给到RAM对应地址。但是ADD指令有些不同,我们看下这个操作码是如何做处理的。
在指令表中我们看到ADD指令的后四位寄存器 OR RAM地址一列中,列出来的不是之前的RAM地址而是两位的寄存器ID。两位可以表示四个数字,正好对应ABCD四个寄存器。
从上面的RAM中可以看到,指令地址2就是一个ADD的指令
。
拆解出这个ADD要使用的两个寄存器(后四位):0100
01表示寄存器B,00表示寄存器A。
所以1000 0100的意思是:将寄存器B的值加到寄存器A中
加法需要利用到上一篇文章讲的ALU逻辑运算单元。因为ALU需要接受输入而控制单元可以控制素有的寄存器所以需要把ALU连接至控制单元。通过控制单元打开对应的寄存器输出来让ALU接受输入,来看下面的步骤:
1.让ALU接受输入:控制单元启用寄存器B的允许读取线,作为ALU的第一个输入,控制单元启用寄存器A的允许读取线,作为ALU的第二个输入
2.告知ALU进行哪种运算操作: 控制单元传递ALU中的ADD操作码告知ALU进行加法运算
3.ALU输出结果保存:注意此时的A的允许读取还打开着并且ALU还在继续工作,如果控制单元直接把输出给到寄存器A,那么ALU就会不断进行运算。所以控制单元有一个自己的寄存器暂时保存结果,接着关闭ALU,然后把值再写入正确的寄存器A中
4.取下一条指令指令地址寄存器+1:执行阶段结束。开始下一个取指令阶段,又开始下一次的循环~~
用一张图来表示。当ALU计算出结果后将结果传送至控制单元,控制单元内部寄存器存储这个结果,然后把ALU关闭,再把内部寄存器存储的值给到寄存器A(这是打开的是寄存器A的允许写入)
刚刚我们是一步一步进行讲解的这个过程:”取指令-》解码-》执行“,计算机中控制执行这个循环的节奏是通过”时钟“来负责的。
时钟以精确的间隔,触发电信号,控制单元用这个信号,推进CPU的内部操作,确保一切按顺序执行。时钟不能太快,因为就算是电也要有一定时间来传输
CPU ”取指令-》解码-》执行“的速度叫做”时钟速度“。单位是赫兹HZ,赫兹是用来表示频率的单位,一赫兹表示一个周期。下面那个Clock就是时钟的代表
这是他的微架构,可以看到和我们上面组装的差不多。
上面的第一个单芯片CPU,它的时钟速度达到了740千次赫兹,每秒74万次,这已经很快了,但是现在更快~~
一兆赫兹是一秒一百万个时钟周期,现在人们用的电脑和手机肯定几千兆赫兹,也就是一秒钟十亿次时钟周期
也就是修改时钟速度,加快CPU速度
芯片制造商经常给CPU留一点余地,可以接受一点超频,但是超频过多会让CPU过热或产生乱码,因为信号跟不上时钟
有时我们没有必要让处理器全速允许,比如用户走开了,或者在跑一个性能要求极低的程序,把CPU的速度降下来,可以省很多电.
省电对于用电池的设备很重要,比如笔记本和手机,为了更省电,很多现代处理器可以按需求加快或减慢时钟速度,这叫动态调整频率.
RAM是在CPU外面的独立组件,CPU和RAM之间通过”地址线“,”数据线“和”允许读/写线“进行通信, 上面提到的很多机制依然存在于现代处理器里。
下一篇文章我们进行加强CPU,给他扩展更多指令
【计算机科学速成课】[40集全/精校] - Crash Course ComputerScience
Youtube 原视频
原文链接:使用ALU,RAM,寄存器打造一个CPU - 掘金 (juejin.cn)