CPU管脚信号与总线操作

CPU管脚信号

bb06aaef-9a2f-4c00-a713-85a58796f2a4

如果不了解CPU的部分特性就很难分析总线,这里先了解CPU管脚信号,以及CPU同内存与IO设备的交互方式。CPU管脚信号同样可像内存那样分类为地址信号数据信号控制信号

从内存取指令时可能是这样的流程:“CPU先将指令所在内存地址从自己的地址信号管脚发出,然后再从自己的管脚发出控制信号,用于通知内存自己想要读某个字,内存在收到通知后会把这个字的数据送到CPU的数据信号管脚,然后也发出控制信号,声明自己完成了任务,再然后CPU会收到内存发来的控制信号,接着从自己的数据信号管脚获取这个数据,最终完成从内存取指令的任务”。

CPU性能与数据信号地址信号的管脚数有关,有\(m\)个地址信号管脚的CPU可以寻址\(2^m\)个地址(通常称为可寻址\(2^m\)的地址空间),现代CPU常见的地址空间大小是16、32、64。类似的有\(n\)个数据信号管脚的CPU可“一次性”读写\(n\)位,现代CPU常见的\(n\)为8、32、64。当CPU数据信号管脚只有8个,那么其在读32位的字时就需要“4次操作”,所以32个数据信号管脚的CPU可能比8个的快很多。

CPU控制信号用于对数据的输入输出和时间的控制,及其他功能。所有CPU都同具备的3种控制信号为电源(通常是1.2V或1.5V)、接地时钟,其他控制信号包括但不限于这几类:

1) 总线控制信号:几乎都是从CPU输出到总线的(也就是发给内存和IO设备的信号),比如用来表明CPU是想要读还是写内存。总之其用于让CPU表示自己想干什么;

2) 中断信号:是IO设备输出到CPU的一类信号。当CPU在启动IO设备任务后,IO设备因为能力原因,会以远低于CPU的速度工作,CPU会转去做其他事情,IO设备完成任务后会发出中断信号给CPU,CPU通常立即暂停手上的事情,去处理该中断相关事项,比如检查是否有IO错误;

3) 总线仲裁信号:用于控制总线的通讯流量,防止多个设备同时使用总线。总线仲裁就是仲裁哪些设备可使用总线,仲裁时CPU也会被当作普通设备,需要申请使用总线;

4) 协处理器信号:部分CPU是设计为跟协处理器共同工作的,常见的有浮点运算芯片,甚至图形运算芯片。这种CPU和其协处理器会通过特定管脚来互相通讯;

 

总线

756cdffa-2d38-4125-afce-72267bfa1874 e9099693-01ce-4065-bf74-3a6663509023

e028ea27-331a-469f-95eb-dbbecac7d044 b3267f0c-db61-42ea-b2b1-5721e1d3d6e6

总线用于让连接到其上的设备们互相通讯。之前提过可把总线先当成“类似导线功能”的设备,因为早期总线是几十根公用的平行导线,并且在用类似电路图的方式分析总线时,常会把总线计做平行导线。当然现在的总线远远强于“公共导线”了。总线可按“连接的部件”分为3类:

1) 片内总线(内部总线):CPU芯片内部的总线,用于连接寄存器与寄存器、寄存器与ALU等;

2) 通信总线(外部总线):连接计算机与外部设备(U盘、路由器等)。可分为2个子类:

2.1) 串行通信总线:串行通信是指数据在1条数据线上按顺序的1次1位的传输;

2.2) 并行通信总线:并行通信时数据在多条数据线上一次性传输多个位;

3) 系统总线(板级总线):连接CPU、内存、IO设备等这一层次的部件,由于系统总线的实体常是主板电路。狭义上的总线一般就是指系统总线。系统总线类似于CPU,1条系统总线上常可分出地址信号线控制信号线数据信号线,不过这并不是说CPU的这三类管脚与总线的这三类信号线存在一一对应。比如有的CPU通过3个管脚表示自己正在做“内存读”、“内存写”、“外设读”、“外设写”等等。而这个CPU连接到的总线可能是用1个独立的信号线专门表示“内存读”,用另外3个信号线表示“内存写”、“外设读”、“外设写”。也就是说在CPU和系统总线间会需要译码芯片来转化信号;

整个计算机系统中的总线结构还可以按总线数目分为如下的2类:

1) 单总线结构:只通过1条总线连接CPU、内存等,是早期计算机的方案。其劣势在于1条总线使得同1时刻只能有1对设备在传递信号,这种情况只优化带宽是不行的,所以有了多总线结构;

2) 多总线结构:上图给出了不同的多总线结构,可发现其第一大的改动就是把IO设备通过“通道”从内存总线上剥离出来,统一放到IO总线上。因为IO设备速度慢数据多,总占用总线会影响CPU和内存通信。这个“通道”的实体是具有CPU部分功能的芯片,其能合理协调IO总线和内存总线的通信。其他更多级总线更提供更好的多级协调能力和多设备并行通信能力;

通常总线有如下几种常见评价指标

1) 总线宽度:通常是指总线数据信号线的根数,单位是位;

2) 总线带宽:指总线单位时间可传输的位数,缩短总线时钟显然能提高总线带宽。但实际上总线中的每根线的传输速度有细微差别,这种现象称为总线偏离。且随着时钟周期缩短,其“相对偏离”就越大,达到一定速度就不能再提升总线速度了;

3) 异步同步:根据有无时钟信号把总线分为同步总线异步总线

4) 总线复用:能否用分时的方式在同样的物理线路上传输多种信号。比如传统的系统总线都是在设计时就确定好数据线和地址线的,但是支持总线复用的总线可以让数据和地址在同一个物理线路上分时传输,这种总线也称为混合总线

5) 信号线数:地址线、数据线、控制线的总根数;

6) 控制方式:包括突发配置、自动配置、仲裁式、逻辑式、计数式;

7) 其他:包括负载能力、电源电压、是否可扩展总线宽度等等;

可以发现通信总线是相对独立于计算机的,而片内总线则更适合在放到CPU这个整体中做分析。所以本文重点讨论系统总线。公共导线/单条总线并行性差,而将所有设备采用两两连接的话,可能有好的并行性但根本不现实,多级总线则是对2者比较好的折衷。

 

系统总线

9fb0726b-0fbb-4a87-a840-4ac2dc1a23ea

a293d93d-047c-4f7d-9e62-c428f2ae44fc

历史上曾提出过多种系统总线,比如ISA、PCI、PCIe等等。这里需强调的是,现代个人计算机中最流行的PCIe不算是传统总线,因为PCIe的功能太过强大和复杂,使得早已超出普通总线的能力范围,而更像是计算机硬件内部使用的网络设备

现代个人计算机常在CPU和内存间置内存总线,以及至少1条连接O设备的IO总线,比如上图的“最小计算机系统”就是这样,其展示了系统总线与片内总线。其中系统总线的总线控制器就是上面所提到过的“通道”。接入特定总线的设备必须遵循特定的规范,称为总线协议,而总线协议通常非常详细,会具体到电气特性、时序特性,甚至插槽形状这样的机械特性。

当两个设备通过1条系统总线通信时,主动请求总线并获得其控制权的称为主设备,主设备在总线上通过信号启用从设备,然后与其传输数据。上图有几种主从组合的例子,大多时候的主设备是CPU,但在发生DMA等流程时,IO设备会作为主设备去控制总线。又有些时候CPU也会作为从设备的。不过在任何时候内存都只能是从设备

为了避免接入总线的设备无法提供足够强的二进制电信号,会让所有接入总线的设备中只能做主设备的通过总线驱动器连接总线,只能做从设备的通过总线接收器连接总线,能做主设备或从设备的通过总线转发器连接总线。这3种芯片都能在不使用总线时提供断路状态,而不只是0信号,这样能避免干扰使用总线的设备。这样的芯片内部存在提供0/1/断路三种状态的三态门

 

总线仲裁

cbd24212-dbcf-467d-a6b8-f0e9c3e92126

前面提到过除了CPU能作主设备,协处理器、发送中断信号的IO设备、执行DMA的IO设备等都可作主设备。如果它们都在同1条总线下,就可能会同时申请作为主设备。通常1条总线只允许同一时刻只有1个主设备,所以这种情况下会导致冲突,需要引入总线仲裁机制,起作用是从这些设备中选1个做为当前的主设备。总裁机制可以被分类为2种:

1) 集中式仲裁:通过独立的总线仲裁器部件进行仲裁,该部件可能被内置于CPU中,也可能是独立的芯片。其又包含如下的3种的具体方案:

1.1) 菊链查询:仲裁器提供\(BS,BR,BG\)分别表示总线忙总线请求总线同意。其中\(BS,BR\)是所有设备直接“并联”的,也就是说\(BS,BR\)有效时只能知道当前是否有总线忙和总线请求,而不知道具体哪些设备发出信号。而\(BG\)则是“串联”的,设备会“接力”该信号,如果接力到的设备发出过总线请求,它不会继续接力而是会置\(BS\)有效,并占用总线,其他设备发现\(BS\)有效时不会企图申请总线。这种方式下的设备优先级与其到仲裁器的“距离”有关;

1.2) 计数器定时查询:相比前者多了设备地址信号,少了总线同意信号。这里每个设备具有0,1,2…的设备地址,当总线在空闲时收到请求,其会在设备地址线发出一个设备地址,如果请求总线的设备中有等于这个地址的,那么其就会成为主设备。这里总线仲裁器发出的设备地址是由计数器控制的,计数器一般是从0开始,每次请求结束后+1(或归0)。这种方式下的设备优先级相等;

1.3) 独立请求式:每个设备有自己的总线请求总线同意线。当多个设备同时请求总线,总线能够知道哪些设备发出了请求,接着这时总线就能通过自定义的优先级决定响应哪个设备;

2) 分布式仲裁:没有独立的仲裁部件,仲裁逻辑被分散在每个设备上;

 

总线操作 — 读内存字(同步总线)

3fbeabc8-3350-49b3-9f7d-c06b2af26d3f

同步总线用时钟信号控制流程,该时钟称为总线时钟。上图给出了同步总线下CPU读内存的例子,其时钟周期为10ns,电平上升下降需1ns(实际电路的电平不可能瞬间变化),且该内存在地址信号建立后至多15ns才能稳定输出数据。上图表格给出整个过程遵循的时序规定。下面来看该流程:

1) 总线时钟周期\(T_1\)上升沿触发CPU开始准备内存地址数据,且时序规定再留4ns(\(T_{AD}\))稳定数据;

2) 到\(T_1\)下降沿时刻,时序规定地址数据在稳定状态下继续维持至少2ns才能操作内存,故CPU至少2ns后才会使\(\overline{MREQ}\)和\(\overline{RD}\)为有效信号,分别表示“想要访问的设备是内存”和“想要读取”。由于2ns刚好使\(\overline{MREQ}\)和\(\overline{RD}\)错过下降沿的时刻,只能等下个时钟边沿被“推送”出去;

3) 到\(T_2\)上升沿时刻,\(\overline{MREQ}\)和\(\overline{RD}\)信号被送到内存,内存知道自己需至多15ns才能稳定输出数据,故先保持\(\overline{WAIT}\)信号,CPU接到后进入等待直到该信号撤回;

4) 到\(T_3\)上升沿时刻,内存确定其能在\(T_3\)下降沿到达前输出稳定数据。且不仅如此,根据时序规定,还能保证在\(T_3\)下降沿到达前数据已在稳定状态下维持至少2ns。故内存在该时刻撤销\(\overline{WAIT}\)信号;

5) 由于\(\overline{WAIT}\)信号撤销,CPU在\(T_3\)下降沿时刻选通了数据线,然后这个内存字会被读入某个寄存器暂存起来,根据时序规定这个数据需要保持至少3ns作为读取时间。读取完后CPU会立即撤销\(\overline{MREQ}\)和\(\overline{RD}\)信号。到这里就算完成1次读内存,共耗费3个时钟周期。

该流程简化了很多更深入的细节,也可能缺乏十分准确描述,但这就是对同步总线核心流程的刻画。根据这个流程,可以发现一些同步型总线的缺点:

1) 需要严格遵守同步信号,从而会浪费一定的时间。比如CPU和内存芯片如果能在3.1个时钟周期读完内存,那么总线也会将时间拉长为4个完整时钟周期;

2) 难以发挥未来更高速设备的性能。比如把这个内存芯片从15ns换做8ns的,那么该总线在工作时会取消\(T_2\)这个CPU等待时间,只需要2个周期就能完成内存读。但如果未来有了更快的4ns内存芯片,那么这个总线的逻辑决定了其最少也还是需要2个周期;

3) 把(2)换一个说法就是在设计同步总线时,其逻辑是要考虑到并兼容较慢的设备的。在这种设计思路的指导下,更快速的设备在总线上不能发挥全力;

 

总线操作 — 读内存字(异步总线)

e3f43924-8d4d-46b8-8771-89f5c3e970e7

异步总线放弃用时钟控制和推进流程的方式,而是采用了称为握手的应答式的方式,握手常见于网络通信。握手的流程简单来说就是在主设备准备好数据后,会立即主动发出信号请求从设备,然后等待从设备完成任务并发出应答信号。上图给出了一种异步总线下CPU读内存的流程:

1) CPU一次性准备好所需的地址、\(\overline{MREQ}\)、\(\overline{RD}\)的信号,然后立即置主同步信号\(\overline{MSYN}\)有效;

2) 内存获取到\(\overline{MSYN}\)后立即根据CPU前面提供的信号完成任务,然后置从同步信号\(\overline{SSYN}\)有效;

3) CPU收到\(\overline{SSYN}\)后从数据线读取内存字,最后撤销\(\overline{MSYN}\)和CPU前面提供的信号;

4) 内存发现\(\overline{MSYN}\)被撤销后,也撤销\(\overline{SSYN}\)。至此可以认为该CPU读内存的流程结束,总线恢复到了(1)前的状态,可进行下一次读内存操作;

异步总线的应答方式可分为不互锁半互锁全互锁这3种,上述流程使用的是全互锁的方式,全互锁的特点是主设备发出\(\overline{MSYN}\)后,必须要等到从设备应答后才撤销\(\overline{MSYN}\)。而从设备在发出应答后,必须要等到\(\overline{MSYN}\)撤销后才会撤销\(\overline{SSYN}\)。这里不讨论另外2种方式。

异步总线能改善上述同步总线的缺点,所以其是更有优势的。但目前大多数总线都仍是同步总线,这是因为同步总线比异步总线更加的容易设计和制造,并且在同步总线上的积累和投资比较大。

 

其他总线操作 — 内存的突发读取

41123936-ec9e-4e80-9458-12be155f9b31

上文讨论了同步总线和异步总线下的“读内存字”的总线操作例子,这种方法对“连续读多个字”不友好,只有关于上一个字的最后一个时钟周期结束后,才能启动对下一个字的读取。不过有的系统总线/内存总线支持称为内存突发读取的操作,比如DDR总线(由于DDR内存通常是不经过其他总线直连CPU的,所以可认为CPU和DDR内存是通过名为“DDR总线”的系统总线连接)。

突发读取简单说就是提供起始内存地址突发长度(BL),并告诉内存需要进行突发读取,然后内存会把起始内存地址(包括起始地址)后的连续BL个字快速的逐个输出到数据线上,这样就等于读出了成块(多个连续地址的数据称为块)的数据。上图给出了这样1种突发读取的时序的例子,CPU在准备内存地址时,还会在数据线额外提供“需要从该地址连续读几个字”的数据。然后接下来CPU会同时提供\(\overline{MREQ}\)和\(\overline{RD}\)的控制信号,不过此时CPU还会额外提供\(\overline{BLOCK}\)信号,用于声明是需要按块读取的。最后这个内存块数据会按1个周期1个字的输出到数据线上。这比多次读多个字占用更少的时钟周期。

这种突发读取经常被用于对Cache的管理,因为Cache要利用局部性原理

 

其他总线操作 — 内存的“一次性读改写”

通常CPU在做完“任务”后,会放弃总线控制权,如果CPU还需要做“任务”就需要申请总线控制权,且不一定通过仲裁。这种情况下CPU修改内存字可能需要在总线上做2个“任务”:

1) 申请到总线,读出指定的内存字,放弃总线控制权;

2) CPU修改读出的字;

3) 申请到总线,把修改后的字写回原位置,放弃总线控制权;

在多CPU(核)的计算机系统中,不同的CPU(核)是会独立的去申请总线控制权的。这里会有个“线程安全”问题,就是在很多时候,我们希望在一段时间里能保证只有1个CPU能访问修改特定的内存数据(类似于编写多线程程序的人总希望在部分流程里保证只有1个线程能修改某全局变量)。在这种要求下,如果CPU读内存要抢一次总线,写内存又要抢一次,那无法保证2次中间有没有其他CPU插手。为避免其他CPU插手,可以考虑避免其他CPU中途抢总线!实现这种思路可以让该计算机系统支持“在抢到1次总线时,CPU能不放弃总线,并一次性做完‘读,修改,写回’的连贯操作”。

 

其他总线操作 — 中断与中断控制器

af54f665-88f5-4083-bffc-5c21cb0d84c2

之前提到过IO设备在完成CPU指派的任务后,会通过中断信号让CPU做后续的处理。这里可能有多个IO设备短时间内同时发出中断,普通的解决方法就是把时间最紧迫的设备赋予最高的总线仲裁优先级,然后其就能得到总线控制权并发出中断。目前有了更好的解决方法,就是通过标准化的中断控制器,比如Intel芯片组中的8259A芯片,其管脚信号如上图。

一个8259A芯片可连接至多8个IO设备(IO控制器),8259A收到1个或多个设备的中断请求后,会向CPU发出中断请求\({INT}\),如果CPU能够响应中断,则会回复终端应答\(INTA\)。然后8259A会在总线数据线输出中断号,用于说明是哪个设备的中断。然后CPU会利用中断号查询中断向量表,得到处理该中断的程序的入口地址。这整个过程需要若干个时钟周期。

8259A芯片中包含若干寄存器,CPU可以通过读\(\overline{RD}\),写\(\overline{WR}\),片选\(\overline{CS}\),\(\overline{A_0}\)这4个信号来读写这些寄存器,进而控制8259A芯片的状态。比如CPU处理完中断后可以控制其撤销中断请求信号,比如可以屏蔽一些中断等等。当计算机系统IO设备较多时,可以级联8259A芯片,比如把其8个输入再接入8个8259A芯片,这样的9个8259A芯片就可以处理64个IO设备的中断。8259A包含专用于级联的引脚。目前的8259A不是独立的芯片,而是内置在其他芯片中。

 

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部