PCI系统总线

PCI总线

21f08b1e-f426-4aa2-b077-db6d46f6fad9

这里先分析用“古老的”电脑看电影大概需要多少的总线带宽这个问题。这里设需要按1024*768分辨率、30FPS、24位真彩色的规格展示视频,那么色彩决定每个像素需要3个字节(24位),1024*768个像素是2 359 296字节,每秒需要30个帧共67.5MB,所以需要67.5MB/s的带宽。不过这只是“显示”占用的带宽,实际播放过程是先把外存数据载入内存,再把内存数据变为图像。考虑到“古老的”电脑只有1条总线,没有独立显卡(集成显卡的显存就是内存),内存不足以把电影一次性装入内存。所以播放过程是2阶段流水线式的“一边读外存数据到内存、一边把内存数据用于播放视频”,这样2个阶段的流量会同时被1条总线承载,所以实际需要翻倍的135MB/s的总线带宽。

早期使用ISA总线的IBM PC没有图形用户界面(GUI),这时的计算机在显示器上输出内容时,总线带宽不受上述分析的限制。后来进入Windows时代,这时的计算机可以在显示器上输出复杂的图形界面,那么这时的计算机就会受上述分析的限制。由于ISA总线只有16.7MB/s的带宽,由ISA升级来的EISA总线也只有33MB/s的带宽,于是这时候的总线成为了计算机性能的瓶颈。

1990年Intel预见到这种情况,设计了PCI总线,并将专利免费公开。第一代PCI的带宽是133MB/s,最后一代是533MB/s,PCI不再是图形的瓶颈。但仅凭PCI还是无法解决2个问题,一是其不适合做内存总线,二是其不兼容旧ISA设备。为此Intel设计了1种使用PCI总线的总线结构,将其用于奔腾CPU计算机中,这个结构如上图所示。其中PCI桥ISA桥芯片其关键作用,它们是最初的北桥和南桥。该结构中的速度分3档,最快第1档是内存总线,第2档是PCI总线,第3档是用于兼容的ISA总线

 

PCI总线操作

7302d82d-75dd-411b-9608-586da5a2123e

PCI是种同步总线,其上的总线事务(从请求总线到通过仲裁最后到释放总线的过程)都发生在发起者(主设备)与接收者(从设备)之间。PCI为了控制管脚数目,其地址线与数据线是复用的,并且占用64个管脚。这种复用使得PCI总线需要更多周期完成任务,具体的“读设备”流程的例子如下:

周期1) 发起者在可复用管脚上准备好接收者所需的地址数据,在控制线准备好相应数据;

周期2) 发起者撤销地址数据,释放总线并把总线交给接收者;

周期3) 接收者向可复用管脚输出所请求的数据;

如接收者未能在这3个周期内响应,还能继续插入等待周期。另外PCI支持按突发式访问

另外仅通过PCI地址信号是能定位到PCI设备的,上图是种32位PCI地址分配的例子。可发现每个PCI设备会分到一段地址(所有设备共享相同的地址空间)。PCI规定每个接入设备必须内置可读写的PCI配置区(寄存器),接入设备的首地址就保存在PCI配置区。PCI配置区也可供其他PCI设备读取。

 

PCI总线仲裁

b36d3c85-6ff4-4f49-a096-d47d9013fadc

PCI的仲裁方案基于集中式仲裁独立请求方案,其结构如上图所示。其中的\(REQ\)和\(GNT\)分别对应之前讨论过的独立请求方案中的总线请求信号与总线同意信号。PCI总线协议中并未规定具体采用什么仲裁策略。由于PCI总线仲裁所同意的是PCI总线事务,由于事务并未规定占用的时钟数,所以从理论上来说1个设备可以一直占着总线。通常来说两个相邻事务会用1个空闲时钟周期隔开,不过在没有总线竞争时,同一个设备也可以不插入空闲周期的直接连续的执行2个事务。当出现1个设备长期占用总线,而其他设备在请求总线时,PCI的仲裁器可能会把\(GNT\)取消,此时占用总线的设备发现自己的\(GNT\)被撤销,那么就知道自己必须在下个周期交出总线。这种仲裁方式在缺乏总线竞争时让设备更高效传输数据,在出现总线竞争时较快速的向设备们反馈竞争结果。

 

PCI总线信号

9f453623-768b-4618-9233-32b679d7c254

PCI总线标准规定PCI总线信号分为必备信号可选信号的2类,其中32位总线宽度(124线插槽)的支持必备信号,64位宽度(188线插槽)的支持必备信号+可选信号。上图中的2个表格给出了部分PCI的必备信号与可选信号,该表格中的主设备/总设备栏中的“叉”表示这种信号只能从主设备/从设备发出,如果主设备/总设备栏都没有“叉”则说明这个信号是其他设备发出的,比如前面提过在Intel主板中,晶振的输出被南桥转化为时钟,该时钟就可看作是外部设备或总线自己(南桥可看作总线系统的一部分)发出的。

PCI总线的部分必备信号的更详细作用如下所示:

1) CLK:PCI是由时钟信号CLK驱动的同步总线,大部分PCI信号都与CLK同步。PCI事务的起点通常在CLK下降沿(时钟周期的中间点);

2) AD:通常是在周期1传输地址信号,周期3传输数据信号。

3) PAR:1位的校验位,用作地址信号和数据信号;

4) C/BE#:通常是在周期1声明做什么操作(比如读内存等),在周期2会用4位组合指明之后传输的数据哪些字节有效(比如读内存时,周期1指定了地址,那么这里就会指定周期3将要传输的数据中哪些字节有效。如果使用了C/BE#信号,就可以指定第2个字节、前3个字节等等);

5) #FRAME:由主设备发出用于在周期1声明启动1个总线事务,并且声明此时(同样也在周期1)的AD和C/BE#信号已经是稳定和和正确的,从设备会收到并处理这些信息;

6) IRDY#:对于,IRDY#通常会在周期1和#FRAME一起发出,用于声明“主设备准备好了,从设备可以发送数据了”。而对于,IRDY#则会待要发的数据到达总线后发出;

7) IDESL:用于读PCI配置区的信号。部分操作系统提供的PCI热插拔功能就基于IDESL;

8) DEVSEL#:让从设备声明已收到主设备经AD发出的地址信号。若从设备未在规定时间发出DEVSEL#,则主设备会认为地址对应的从设备不在总线上;

9) TRYD#:对于从设备发出IRDY#表示待读取数据已经在AD上。对于,从设备发出IRDY#表示已经准备接受待写数据;

PCI可选信号主要用于将32位扩展到64位,LOCK/SBO#/SDONE则主要用于支持多CPU

 

PCI总线事务

bcaf5e03-1d9d-402f-8bb0-34dff0628155

PCI总线事务相对简单,是一个接一个的。上图是连续执行2个事务的例子,其中周期1,2,3是是读内存事务,周期5,6,7是写内存事务。通常事务间有1个空闲周期。读内存事务流程如下:

\(T_1\)) 主设备发出的地址信号、读内存的操作信号、事务启动信号在该周期下降沿有效;

\(T_2\)) 主设备修改C/BE#表示需要读入具体哪几个字节、并且交出总线让从设备能在\(T_3\)使用;

\(T_3\)) 从设备发出DEVSEL#通知主设备已得到地址,把数据放到AD,发出TRDY#通知主设备数据已经准备好。如果从设备需要更多的时间去准备数据,它则会一直保持DEVSEL#信号表明它占用着总线,直到数据准备好后才会发出TRDY#;

发表评论

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

滚动至顶部