您的位置:首页 > 理论基础

CPU的组成结构及其原理(三)

2017-11-11 10:41 1471 查看
控制电路

额。。。控制电路这个东西其实就是个超大号的组合逻辑电路,由于控制信号众多,指令也不少,所以手动列真值表然后把电路的逻辑算出来会估计得花好一段时间,这里就不做了。

控制电路的真值表在此:



其中的X表示它们可以设置成任意值
我们规定:
ALUop = 000时,ALU做加法运算;
ALUop = 001时,ALU做减法运算;
ALUop = 011时,ALU做NAND运算;
ALUop = 010时,ALU做OR运算;
ALUop = 100时,ALU做移位运算;

下面我举几个例子来解释一下这张表格式是怎么回事,请务必对照着楼上完成的数据通路电路来看。

比如说LOAD指令:



LOAD指令下,INST线的3-0位是0000. 
N和Z的值对于这个指令来说无所谓,因为LOAD指令并不需要N和Z的值。
因为需要执行PC = PC + 1,所以PCSel = 0,PCWrite = 1;
LOAD指令会往寄存器组里写数据,所以RegWrite = 1;
LOAD指令需要从内存里读取数据到寄存器组,所以MenRead = 1,RFin = 1;
LOAD指令需要寄存器组从INST线7-4位读取寄存器编号,所以R1Sel = 0;
LOAD指令不需要向内存写入数据,所以MemWrite = 0;
LOAD指令不需要ALU做任何运算,所以ALU2和ALUop怎么样都无所谓

再比如说NAND指令:



4000
NAND指令下,INST线3-0位是1000
同样,NAND指令不需要N和Z
因为需要执行PC = PC + 1,所以PCSel = 0,PCWrite = 1;
NAND指令确实会往寄存器组里写数据,所以RegWrite = 1;
NAND指令不需要读取内存,所以MemRead = 0;
NAND指令需要寄存器组从INST线7-4位读取寄存器编号,所以R1Sel = 0;
NAND指令不需要向内存写入数据,所以MemWrite = 0;
NAND指令下,ALU需要从指令指定的两个寄存器R1,R2输入数据进行运算,所以ALU2 = 00;
NAND指令写入寄存器组的数据是从ALU那边过来的,所以RFin = 0;
最后,我们规定控制ALUop = 011时,ALU会进行NAND运算;

你可以尝试看看表格里的其他内容是否合乎逻辑!

这么大个的真值表就不要手算电路了,还是让Quartus II之类的软件自动生成好了


-------------------------------------------------------------------------------------------------------------------

唉。。。搞个简单的处理器也这么累


好吧咱还没完呢,下次更新我会稍微讲讲时钟信号的问题
接着我们将会改动一下上面这个单周期数据通路(Single Cycle Datapath)
把它变成一个多周期数据通路(Multicycle Datapath)
而且控制电路也会因此从组合逻辑电路变成有限状态机(Finite State Machine, FSM)
多周期数据通路:

在单个时钟信号周期内完成一个指令的数据通路就叫做单周期数据通路
相对地,用多个时钟周期完成一个指令的数据通路就是多周期数据通路
我们将会看到,这种数据通路有利于提高工作效率

这个CPU仍然由数据通路和控制电路两个部分组成,只不过这回完成一个指令需要多个周期,而且控制信号在每个周期还不一样

还记得53楼的指令集吗?每个指令我都写出了CPU内部的实现步骤。
在单周期数据通路中,这些步骤都是在单个时钟周期内完成的
现在就该变成一个周期只执行一个步骤了。。。

指令的大致实现步骤如下:
周期1: 从内存读取指令
周期2:解码指令,同时读取寄存器(如果需要的话)
周期3: ALU进行运算,或者读取内存数据
周期4:把运算结果写回寄存器
周期5:计算下一个指令的内存地址,并且将该值写入PC寄存器

ORI指令需要两个周期读取寄存器,所以需要6个周期完成该指令;而STORE不需要把运算结果写回寄存器组,所以只要4个周期即可;BZ,BNZ,BPZ这些指令也不需要写回寄存器组,也只需要4个周期

---------------------------------------------------------------------------------------------

这个多周期数据通路的样子就是文章一开头的那个图了!!



用Quartus II软件生成的CPU电路简图:



没看懂这图的话没关系,因为我也看得很郁闷。。。毕竟是软件自动生成的东西,只要知道中间那个FSM模块代表CPU的控制电路即可

那么FSM模块内部的结构如何呢?如下图,还是软件自动生成的。。。



复杂度同样坑爹!!!
要知道这个8-bit CPU已经很简单了,现在你能想象你电脑和智能机用的CPU有多复杂了吗?要不要肃然起敬一下?~~


-------------------------------------------------------------------------------------------------

第一个周期:从内存取得指令并且把PC寄存器加一

PCWrite=1,AddrSel=1,MemRead=1,MemWrite=0,IRload=1,MDRload=0
这样IR寄存器就可以从内存读到指令了



同时要做的事情还有PC=PC+1,这就是为什么PCWrite信号要设为1;
ALU1=0, ALU2=001



概括起来,第一个周期所做的事情就是:
[IR] = Mem[ [PC] ] 
[PC] = [PC] + 1

这次我们把PC=PC+1这个步骤放在第一个周期是一种优化选择,是为了减少完成每个指令所需的周期数。像以前那样把PC=PC+1放在最后当然也没问题,同样能行

------------------------------------------------------------------------

R1,R2寄存器读取寄存器组
另外就是控制电路这个时候正在解码指令,设置各个控制信号
所以数据通路这个时候并不知道该指令是否需要寄存器组

注意:有些指令编码的7-4位并不代表寄存器编号,而是其他的东西,这些指令也不需要来自寄存器组的数据,不过这个动作并不会影响指令的正确执行。

既然有可能晚些时候需要寄存器组的数据,那就干脆先读取好了,就算没用也不会出错
所以说读取寄存器组是一种优化选择



-----------------------------------------------------------------------------------

到了第三个周期,CPU就会根据不同指令来做不同的事情了

ADD,SUB和NAND指令:
周期3,ALU进行ADD,SUB或NAND运算,并且把运算结果放入ALUout寄存器
周期4,结果被写回寄存器组



SHIFT指令:
周期3,ALU进行SHIFT运算,并且把运算结果放入ALUout寄存器
周期4,结果被写回寄存器组



ORI指令:
周期3,从寄存器组内的01寄存器读取数据
周期4,ALU做OR运算,结果存入ALUout寄存器
周期5,结果被写回寄存器组





LOAD指令:
周期3,从指定的内存地址读取数据,把读得数据存入MDR寄存器
周期4,把读得的数据从MDR寄存器写到寄存器组



STORE指令:
周期3,把寄存器组的数据写入内存的指定位置



BZ,BPZ,BNZ指令:
周期3,ALU运算下一条指令的地址,并且改写PC寄存器



-----------------------------------------------------------------------

控制信号每个周期都会改变一次
这个控制电路本身是一个大号的有限状态机
状态之间如何转换,在写Verilog HDL代码的时候就已经完全定义好了,电路只需要按照我的定义“见机行事”就好。。
97楼的那个图就是软件为我写的代码自动生成的电路
大学数电会教你有限状态机的相关内容。。这个东西要科普略难,比较抽象,我就不讲了


当年LZ给这个CPU扩展指令集的时候其实就是对有限状态机做出改动,增加状态的数量。

---------------------------------------------------------------------------------
好了,CPU搭完了。。这个帖子也该结束了~~


我知道要完全看懂这些内容需要相当的耐心以及知识储备
但LZ写这个帖子的目的并不是为了让你们对CPU工作原理作很深入的了解

如果说你能够耐着性子,即使很多东西都不懂也把整个帖子看完了的话
那么多多少少也应该能看出一丁点名堂来
若是因此能对你面前的电脑或智能手机肃然起敬的话
LZ的目的也就达到了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算机原理 内核 cpu