一、引子
总线上连接了多个设备,设备之间要进行通讯。
所以,我们必须要解决下面两个问题:
1.总线的判优控制
多个设备可能同时向总线发出占用请求,到底哪个设备来占用总线呢?
总线在同一时刻只能有一对设备进行使用。
2.总线的通信控制
这一对设备占用总线之后,就要进行通讯,那么如何完成通讯过程,保证通讯过程的正确性?
二、总线判优控制
1.基本概念
根据是否能提出总线请求,可以分成两类:
①主设备(主模块)
对总线有控制权。
可以提出总线的占用申请,并且在占用总线之后,可以控制和另外一台设备之间进行的通讯过程。
②从设备(从模块)
本身不能对总线进行控制,也不能提出总线的占用请求。
只能响应从主设备发来的总线命令。
计算机中有些设备,既可以作为主设备也可以作为从设备。有些总线有多个主设备,有的总线只能有一个主设备。
2.方式
总线判优控制可以分为两种方法。
(1)集中式
把总线的判优逻辑做在一个部件上,比如放在CPU中。
①链式查询方式
总线控制部件是集中在一起的。
- 数据总线:用于信息交换过程中数据的传输。
- 地址总线:主设备占用总线之后,要与从设备进行数据传输。
主设备要通过地址总线找到要通讯的从设备。
- BR:所有设备都通过这一条线发出“总线占用或者总线使用”的请求。
- BS:如果某一个设备,占用了总线的控制权,那么就通过这条线告诉总线控制部件或者其他部件“总线忙”。
- BG:链式查询的特点就在BG这一条线。一个一个地向下进行查询。
:book:分析
如果挂接在总线上的I/O接口有总线占用请求的话,就会通过BR这条线,向“总线控制部件”提出占用请求。
总线控制部件接收到占用请求之后并且可以让出总线的控制权,就是可以将总线的控制权交给I/O设备使用。
这个时候,就要进行查询。因为所有的外部设备都是通过一条线(BR)提出的总线请求。这时候不知道哪一个设备的优先权更高,总线的控制权应该交给哪一个设备。
所以,要通过BG这一条线,逐步向下查询。首先看一下“I/O接口0”是否提出占用请求,如果是它提出的,那么总线的使用权就交给它。
这个例子中,我们是“I/O接口1”和“I/O接口n”发出了总线占用请求。
所以总线授权的信号,会向下进行传送,直到碰到第一个提出总线占用的接口。
现在是接口1发出了,那么接口1就获得了总线的控制权。
然后接口1通过BS这一条线设置“总线忙”,它就获得了总线的使用权。
如下:
:red_car:特点
- 结构简单
如果想增删设备,就非常容易。如果想增加设备,放一个接口上去就可以了,向后一直排下去。
优先级的算法也非常简单。
- 进行可靠性设计的时候,比较容易实现。
比如要把BS这一条线换成两条线(避免一条线断了以后,这个电路不能用),也可以把BG换成两条线(避免一条线断了之后,判优过程无法进行下去)。
- 各个设备占用总线的优先级如何确定?
这个优先级和BG信号线的查询顺序有直接关系,它的查询顺序就是各个I/O设备占用总线优先权的先后顺序。
这个优先级的连接方式事先已经确定了,如果某一个I/O设备的优先权比较低,那么很可能它的总线占用请求就会迟迟得不到应答。
- 对电路故障特别敏感。
尤其是允许的这一条线(授权的线)在向下传送的过程中,如果某一个接口电路出现了电路故障,这个信号无法向下传,那么后面的设备就再也无法获得总线的使用权了。
所以这种方式,对电路故障非常敏感。
- 速度慢
因为要一直向下进行查询。
总结:链式从头往后走,BG找BR,然后出BS。这种结构一般用在微型计算机或者一些简单的嵌入式系统中。
②计数器定时查询方式
- 数据线:用于数据的传输。
- 地址线:用于从设备的查找。
- 设备地址:这个上面传输的地址,实际上是计数器给出的。通过这个地址,来查找某一个设备是否发出了总线的占用请求。
- BR:总线请求。
- BS:总先忙。
:book:分析
来分析一下它的判优过程。
总线控制部件里面,有一个计数器,它的初始值可以是0,或者其他的值。
如果某一个设备,想要占用总线,和某一个从设备进行数据传输。
那么它通过BR向总线控制部件发出总线占用请求,总线控制器接收到了总线请求信号之后,在能够响应,可以让出总线使用权的情况下,就会启动计数器。
这个计数器的值,是通过设备地址这一条线,向外进行传输。
设备地址这条线给出信号之后,比如现在计数器的值是0,那么就对I/O接口里面的0进行查询。看一下I/O接口0上的设备是不是提出了总线占用请求。
如果它没有提出总线占用请求的话,计数器就会自动加一,然后对I/O接口1的设备进行判断,判断这个接口是否提出了总线占用请求。
如果I/O接口1提出了总线占用请求,那么接口1就会进行响应。通过BS这一条线进行应答。
如下:
:red_car:特点
- 这个方式判优的优先级非常灵活。
可以是事先确定的,比如说每次查询的时候,计数器的计时都是从0开始,然后1,2,...,n。对各个部件或接口的查询也是从I/O接口0开始一直到I/O接口n。
如果计数器的启动不是从0开始,比如要从上一个停止计数的地方开始,优先级就变成了循环优先级。
如果计数器可以通过软件的方式来设定初值,比如设置一个初值k,那么I/O接口k优先级就变成了最高。还可以对总线控制部件进行设置,使优先级的顺序更加灵活。
- 分析一下这种方式需要多少条线。
抛开数据线和地址线不算(其他方式也有这两条线),和前面的链式查询方式相比,它少了BG这一条线,但是多了一条设备地址线。
设备地址线的宽度和设备数有关,它是一个计时,要把所有设备都进行编码。比如n个设备,进行二进制编码的话,这个编码至少需要log2^n
向上取整。
所以,设备地址至少需要log2^n
向上取整,加上BS和BR这两条线。
③独立请求方式
前面两种方式,查找是哪一个高优先级的设备提出的总线占用请求,都是按顺序进行查找的,速度都比较慢。
而独立请求方式,确定哪个设备能够占用总线的速度更快。
可以看到,任何一个I/O接口,都增加了两条线:
BR:提出总线的占用请求。
BG:应答信号。哪一个BG有效,相应的接口就会占用总线的使用权。
优先级的排列,是由总线控制部件内部一个集中电路完成的。
所以内部会有一个排队器。
这种方式,优先级的确定就非常灵活,主要看排队器如何设置。
可以有预定的方式,把设备进行排队,事先确定好设备的优先级。
还可以有自适应方式,哪些设备在工作当中,比较重要,就可以给它比较高的优先级。
也可以采用计数器的方式,循环的进行设置,对某一个设备使用总线的请求应答,获得应答的设备就占用了总线的使用权。
(2)分布式
它的判优逻辑分布到各个设备,或者各个设备的端口上。
三、总线通信控制
1.基本概念
目的:解决通信双方协调配合的问题。
总线传输周期:主设备和从设备之间完成一次完整可靠的通讯所需要的时间。
这个过程中,主要解决下面几个问题:
- 申请分配阶段
主设备获得总线使用权,这是由前面讲的总线判优逻辑(或者叫总线仲裁)来解决的。
- 寻址阶段
主设备要找到从设备发出的地址和命令,通过地址找到从设备,通过命令控制从设备完成相应的操作。
- 传数阶段
数据传输阶段。如果从设备已经准备好数据,那它就可以发送数据。如果从设备已经准备好进行数据接收,那么在这个阶段就是进行数据接收。
- 结束阶段
最后是结束阶段,主模块撤销相关的信息,同时从模块也撤销相关的信息。
2.方式
(1)同步通信
①介绍
要有一个统一的定宽定距的时标来进行控制数据传输。
每一个操作,每一个信号的给出,都是在固定的时间点,由时标进行控制。
特点:在固定的时间点上,给出固定的操作。
②同步式数据输入
假如CPU采用同步的方式,从某一个外部设备进行数据输入。
同步通信的特征是要有一个定宽定距的时标来控制整个数据的传输。
- 时钟信号
整个总线周期由四个时钟周期构成。
这四个时钟周期就可以完成一次完整的可靠的数据通讯。
- 地址信号
除了时钟信号之外,CPU要完成数据输入的话,还需要地址信号。如下:
需要读信号。
这个从设备在给定的时间点上要给出数据的输出。对CPU来说是数据的输入。
:book: 分析
总线传输周期现在分成了四个。
<1> 在t1时钟的上升沿,必须要给出地址信号。
这个地址信号是主设备给出的。(在我们这个例子是CPU给出的)
<2> 在第二个时钟周期,它的上升沿,必须给出读命令信号。
告诉从设备CPU要从从模块或者从设备读入数据。
<3> 在第三个时钟周期,上升沿到达之前,从设备必须要给出数据信号。(通过数据总线给出)
<4> 第四个是时钟周期的上升沿,数据信号和控制信号就可以撤销了。
<5> 在第四个时钟周期结束的时候,地址信号也撤销了。
:mobile_phone_off:叨叨
第一个上升,给出地址,就是之前PC发出命令,然后T1时间段内完成。
PC到MAR,然后到存储体再到MDR到IR,T2上升就是IR接收到读命令并发出那一瞬间。
T2的上升沿,IR给出读命令信号,T2时钟周期内,主设备告诉从设备,主设备要从从设备读入数据。
T3的上升沿,从设备通过数据总线给出数据信号,T3时钟周期内,从从设备读取数据。
T5的下降沿,地址信号撤销。
第一行是时钟周期,这里只看最左边的上升沿,上升的时候更新所有状态,地址和数据传的是数据,不关心具体是高电平还是低电平,读命令传的是确定的电平。
简单来说就是通过时钟脉冲的高低电平来控制各个功能的开始结束点。
比如在第一个时钟上升沿给出地址,在第二个时钟给出读信号,第三个时钟开始从从模块读入数据。
有个前提就是从模块必须把数据放到dbus上,然后t3读入数据,t4撤销总线信号,释放总线。
T1是IR中的地址码给到内存的mAR,T2是将CPU告诉内存是我要读操作,T3是把内存的中数据调出到打比方ACC的过程,T4是结束数据传输命令,总线忙信号取消等等,就是一个阶段做一个步骤。
注意:
一定要有定宽定距的时钟,来控制整个数据传输的过程。还要在给定的时间点上,完成相应的操作。
③同步数据输出
和上面的同步数据输入类似,首先需要一个定宽定距的时钟,由它来控制整个数据输出的过程。
假设CPU要把数据输出到某一个模块上去。
除了时钟之外,还需要地址信号(向哪一个从模块进行数据传输),然后是输出操作(把数据输送到从模块上),所以还需要给出数据。既然是写操作,就要对外进行输出,就要给出写命令。如下:
:book: 分析
<1> 在第一个时钟的上升沿,给出地址信号。
<2> 在第一个时钟的下降沿,要给出数据。
<3> 在第二个时钟的上升沿,要给出写命令。
向从设备进行数据写入。
<4> 在第三个时钟的上升沿,在做写入操作。
<5> 第四个时钟的上升沿,CPU或者是主设备撤销数据。
撤销写命令。
<6> 第四个时钟周期结束的时候,把地址信息也撤销掉。
完成输出操作。
同步方式的话,所有的从模块都用同一个时标进行控制。要在同一个时限当中完成规定的操作。
(就是按规定时间做事情,而且要抢时间,所以数据提前拿出来,收到写入命令的时候直接拿数据写)
主从模块是强制同步的,对多个速度不同的模块,必须要选择速度最慢的模块作为统一时标。即使有的设备速度比较快,也要按照速度慢的进行数据传输。
==所以一般这种方式(同步式),应用在总线长度比较短,并且各个模块存取时间比较一致的情况下。==
:red_car:注意
上升沿与下降沿:
看最顶部的时钟,一个周期的上升沿就是最左边的竖线,下降沿就是中间的竖线
然后例如写命令在T2上升沿变成了低电平,低电平有效,写命令就开启了。等到T4上升沿,写命令高电平,失效。
为什么这个方式要求总线长度比较短?
这是因为,同步方式对任何两个设备之间的通信都给予同样的时间安排。就总线长度来讲,必须按距离最长的两个设备的传输延迟来设计公共时钟。但是总线长了势必降低传输频率。
(2)异步通信
①介绍
没有统一的时标,是采用应答的方式来做的。
异步通信是通过请求和回答这两个握手信号来完成通信联络的。
主设备发出这次总线的通讯(请求),从设备受到主设备的控制,给出应答信号。然后进行数据传输。
和同步相比,这个方式没有定宽定距的时钟,但是要增加两条线:
请求线(由主设备发出请求信号用的)和应答线(从设备对主设备发出的请求进行应答)
②不互锁
主设备发出通信请求,从设备接收到通信请求之后进行应答。
然后主设备撤销请求信号,从设备也撤销应答信号。
在这个过程中,主设备不管是否接收到了这个应答信号,经过一定的延迟以后,都会撤销请求信号。从设备不管是否接收到了应答信号,经过一段时间之后,都会撤销这个应答信号。
这种方式,通信的可靠性是有问题的。
③半互锁
主设备发送请求,从设备接收到通信请求之后发出应答信号。
主设备接收到应答信号之后,再撤销这个请求。
如果接收不到的话,这个请求就会保持。
从设备发出应答信号之后,不管对方是否已经接纳这个应答信息,经过一段时间延续以后,它都会撤销应答信号。
半互锁有可能造成请求信号一直保持高电平。
因为主设备没有收到应答,而从设备又关闭了信号发送,则主设备始终处于高电平状态里。
④全互锁
全互锁可以解决半互锁存在的问题。
主设备发送请求,从设备接收到通信请求之后发出应答信号。
主设备接收到应答信号之后,才会撤销i请求信号。
只有主设备的请求信号撤销之后,从设备才会撤销自己的应答信号。
这种方式可以完成可靠的数据传输。
如果传输过程发现数据出错,可以请求从设备重新发送或者接收数据。
(3)半同步通信
①介绍
主要解决不同速度的两个模块,或者两个设备之间进行通讯的问题。
是同步和异步的结合。
同步:有一个定宽定距的时钟来管理整个通讯过程。
异步:并不要求两个设备要以相同的速度进行工作,允许不同速度的设备之间协调工作。
为了调整主从设备速度的差异,这里增加了一条等待信号(WAIT),这个等待信号是由从设备给出。
②以输入数据为例的半同步通信时序
假设通信过程或者总线周期还是四个时钟周期。
T1上升沿:主模块发送地址
T2上升沿:主模块发送命令(读信号)
正常情况下,在T3的上升沿到来之前,从模块要能提供数据并且将数据放在数据总线上。
主模块开始在数据总线上接收数据。
T4:从模块撤销数据,主模块撤销命令。
如果CPU和存储器的工作速度不一致,CPU的工作速度可能比存储器快,在T3时钟到来之前,从模块无法向主模块提供数据。如果在同步通讯过程中,这样就会出错。
所以在T3到来之前,从模块要发出WAIT信号(低电平有效)。
主模块检测WAIT信号线,如果检测到WAIT是一个低电平,就会插入一个T周期,等待数据的到来。
在下一个时钟周期到来之前,主模块还会检测WAIT信号是否为低电平。如果还是低电平,那么还会等待一个时钟周期。
直到在某一个时钟周期到来之前,主模块发现WAIT信号上已经比变成了高电平。
从模块已经准备好了,可以发送数据了。这个时候进入到T3周期,由从模块给出数据。
③半同步通信
假设CPU要从某一个外部设备或是内存单元中读入数据。
那么CPU要先给出地址。
还要给出读信号。
因为外部设备和CPU之间有速度差异,在指给定的时间点上可能无法提供CPU需要的数据。
所以外部设备还要给出一条线,就是WAIT信号。让CPU等待数据的到来。
还需要数据线,数据准备好以后,外部设备或者内存发出,通过数据总线传送给CPU。
<1> 在第一个时钟周期开始的时候,CPU要通过地址总线给出地址信号。
<2> 在第二个时钟周期开始的时候,由于是读操作,所以CPU要给出读信号。
<3> 在第三个周期开始之前,从设备如果不能把数据准备好,那么就要通过WAIT信号给出一个低电平,告诉CPU进行等待。
CPU检测WAIT信号,如果是低电平,就会在T3到来之前,插入WAIT周期。
<4> 在下一个时钟周期开始之前,主设备依然要检测WAIT信号,WAIT信号依然是低电平,还是要插入一个时钟周期进行等待。
<5> 现在WAIT信号已经变成了高电平,数据已经准备好了,放在数据总线上,CPU可以进行数据接收。
那么就可以进入T3周期了。
<6> 在第四个时钟周期开始的时候,读命令信号和数据信号从总线上撤销。
<7>第四个时钟周期结束,地址总线上的地址信号也撤销了,半同步传输也就结束了。
半同步传输,允许不同速度的主从设备之间进行信息交换。
(4)分离式通信
①介绍
可以看到,从模块准备数据的时候,是不占用总线的,也就是此时总线是空闲的,这是对总线资源的浪费。
那有办法让这段空闲时间用起来吗?
分离式通信就可以充分挖掘系统总线每一个瞬间的潜力,让系统总线发挥它的最大效能。
一个总线的传输周期可以分为两个子周期:
主设备发出地址、命令占用总线。
地址和命令发送以后,主设备和总线之间的连接断开,主设备放弃总线的使用权。
这时候,从设备准备数据接收或是准备要发送的数据。如果从设备已经准备好了,就再次发出占用总线的请求。
==这个时候从模块已经从从模块变成了主模块,它发起了总线的占用请求,进行数据传输。==
区别在于分离式,主模块发送完地址和请求之后就不占用总线了,而半同步式主模块会在总线上继续await到从模块准备完成
从模块准备的时间总线已经给其它设备使用了,因为主模块失去总线控制权了。只有从模块准备好了之后再申请总线控制权发送数据
②特点
<1> 各模块有权申请占用总线
所有模块都可以从从模块变成主模块。
<2> 采用同步方式通信,不等对方回答
从模块准备好数据之后,后面的通讯过程,是通过一个定宽定距的时钟来完成的。
<3>各个模块准备数据时,不占用总线
<4> 总线被占用时,无空闲
总线被占用的时候,一定在进行数据通信,或是在传输/控制命令。
这样就充分利用了带宽。
整理不容易,多多支持~