1. 项目概述与核心价值
在嵌入式系统,尤其是那些需要处理多路并发任务或集成多个智能外设的复杂应用中,一个核心的挑战是如何让多个“主设备”(Master Device)高效、有序地共享同一套系统总线。想象一下,在一个车间里,只有一条传送带(总线),但有多台机器(主设备,如CPU、DMA控制器、协处理器)都需要用它来运送原料(数据)。如果大家一拥而上,必然导致混乱和碰撞。总线仲裁(Bus Arbitration)就是这套系统的“交通警察”和“调度员”,它定义了谁在什么时候可以独占传送带,以及如何安全地交接控制权。
MC68306,作为摩托罗拉(后飞思卡尔)M68000家族中的一款经典集成微处理器,其内置的总线仲裁单元是理解这类老派但设计精良的微处理器系统架构的绝佳范例。它不像现代基于高速串行总线的SoC那样复杂,但其清晰、严谨的“请求-应答”机制,以及与之紧密配合的异步操作时序,是构建稳定、可靠多主系统的基石。很多工业控制板、通信设备中的主控模块,其底层逻辑依然能看到这些设计的影子。
深入理解MC68306的总线仲裁,不仅仅是读懂一份二十多年前的数据手册。它的价值在于,你能掌握一套经典的多主系统协同方法论。当你需要调试一个DMA传输导致系统挂起的问题,或者设计一个带有多片处理器的板卡时,这些关于BR(Bus Request)、BG(Bus Grant)、BGACK(Bus Grant Acknowledge)信号何时拉高、何时拉低、如何同步的细节,就是定位问题的“手术刀”。本文将带你穿透时序图的表象,拆解三线与两线仲裁的运作差异,并厘清异步操作下DTACK、BERR、HALT这三个关键握手信号如何决定一个总线周期的“生死”。无论你是正在维护遗产系统,还是希望从经典设计中汲取营养,这篇文章都将提供可直接用于电路设计和软件调试的干货。
2. 总线仲裁机制深度解析
总线仲裁的本质,是解决多个主设备对共享资源的竞争问题。MC68306作为默认的总线主设备(通常是系统的中央处理器),它需要一套机制来响应外部其他主设备(如另一个CPU、DMA控制器或智能I/O处理器)使用总线的请求,并在适当时机交出控制权。
2.1 仲裁信号与基本流程
MC68306支持两种仲裁协议:三线仲裁和两线仲裁。核心信号如下:
BR(Bus Request):输入信号。由希望获得总线控制权的外部主设备发出。多个设备的BR信号可以通过“线或”(Wire-OR)的方式连接至处理器的BR引脚,这意味着任一设备拉低BR,处理器就能感知到请求。BG(Bus Grant):输出信号。处理器收到有效的BR后,在完成当前总线周期后,会发出BG信号,表示“我同意交出总线,你们外部仲裁逻辑可以开始决定下一个主设备是谁了”。BGACK(Bus Grant Acknowledge):输入信号(仅用于三线仲裁)。被授权成为新总线主设备的外部设备,在确认满足所有接管条件后,发出此信号。它向处理器和系统中所有设备宣告:“我现在是总线主设备了,总线由我控制”。
注意:“线或”连接通常需要集电极开路(Open-Collector)或漏极开路(Open-Drain)输出结构,以确保多个输出连接在同一线上时不会发生短路。但手册也提到,并非必须使用这类器件,只要逻辑设计能保证“或”的关系即可,这为设计提供了灵活性。
基本流程可以概括为:外部设备请求(BR) -> 处理器授权(BG) -> 外部设备确认并接管(BGACK,三线) -> 外部设备使用总线 -> 外部设备释放总线(撤销BGACK和BR) -> 处理器收回控制权。
2.2 三线仲裁 vs. 两线仲裁:设计取舍与适用场景
这是理解MC68306仲裁的关键。两种方案并非孰优孰劣,而是针对不同系统复杂度和成本的设计取舍。
三线仲裁(BR/BG/BGACK)这是功能最完整、安全性最高的方案。BGACK信号的存在,建立了一个明确的总线所有权“交接仪式”。
- 明确的占有宣告:
BGACK有效,是当前总线主设备的唯一、权威标识。所有从设备(Slave)都监听此信号,只响应当前BGACK有效的主设备的访问。 - 安全的释放条件:外部设备必须在
AS(地址选通)、DTACK(数据传输应答)和上一个BGACK均无效后,才能发出自己的BGACK。这确保了前任主设备已经完全释放了总线(AS无效),并且与从设备的交易也已结束(DTACK无效),避免了总线冲突。 - 支持重叠仲裁:处理器可以在当前外部主设备还未完成操作(
BGACK仍有效)时,就为下一个等待的请求再次发出BG。外部仲裁电路(如优先级编码器)可以提前决定下一任主设备,一旦当前BGACK撤销,下一任可以立即宣告接管,实现了总线使用权的“流水线”式交接,最大化总线利用率。
两线仲裁(BR/BG)此方案省去了BGACK信号,简化了硬件连接,但将更多的责任转移给了外部主设备。
- 简化与成本:减少一根信号线,对于简单系统或对成本敏感的设计有吸引力。
- 更长的请求保持:外部主设备必须持续保持
BR有效,直到它完成所有的总线操作。处理器在检测到BR撤销后,才会撤销BG。这意味着,总线控制权的释放时机完全由外部主设备通过BR信号来指示。 - 无重叠仲裁:由于没有
BGACK来明确标识当前主设备,处理器必须等待当前主设备撤销BR(表示用完)并随之撤销BG后,才能响应下一个BR请求。这会导致总线在两次主设备切换之间存在“空窗期”,利用率稍低。 - 对设计的要求更高:外部主设备必须非常清楚自己需要占用总线多久,并在完成后及时撤销
BR。如果BR撤销过早,可能导致操作未完成就被打断;撤销过晚,则浪费总线带宽。同时,所有从设备必须能够响应来自任何地址源的访问,因为它们无法通过BGACK区分主设备。
实操心得:方案选择
- 选三线:当系统中有多个(超过两个)潜在总线主设备,且对总线利用率和系统稳定性要求极高时。例如,一个由MC68306作为主CPU,搭配多个DMA控制器和通信协处理器的复杂通信网关。
- 选两线:当系统只有两个主设备(如一个CPU和一个DMA),且连接复杂度需要尽可能降低时。或者,当你使用的第三方IP核(作为总线主设备)只支持两线协议时。
3. 仲裁时序与状态机实战拆解
手册中的时序图是理论的呈现,而状态机则是其内在逻辑的抽象。结合两者,才能透彻理解。
3.1 关键时序节点剖析
我们以三线仲裁、处理器活跃(Processor Active)的时序图(对应手册图3-18)为例,拆解每一个关键边沿的意义:
- T0(请求发生):外部主设备在处理器某个总线周期(例如S2状态)期间发出
BR。注意,BR是异步信号。 - T1(内部同步):处理器在下一个时钟下降沿对
BR采样,再经过最多1.5个时钟周期的内部同步,产生有效的内部BR信号。这是所有异步输入(RESET,HALT,DTACK,BERR,IPL)的标准处理流程,旨在避免亚稳态。 - T2(授权发出):处理器在完成当前总线周期(图中
AS撤销,S7结束)后,立即在下一个时钟上升沿发出BG。同时,处理器将其地址、数据、控制总线置于高阻态(Three-state),与总线物理断开。 - T3(外部设备接管):外部设备检测到
BG有效,并等待AS、DTACK和BGACK(来自上一个主设备)全部无效。一旦条件满足,它便发出自己的BGACK。从BGACK生效的这一刻起,该设备正式成为总线主设备。 - T4(外部设备操作):新主设备开始驱动地址、数据线,发出
AS等进行读写操作。此时处理器“旁观”。 - T5(释放请求):外部设备应在发出
BGACK后,尽快撤销BR。如果系统中有其他等待的请求,处理器会在撤销BG几个时钟周期后,重新为下一个请求发出BG,实现重叠仲裁。 - T6(交还总线):外部设备完成操作后,先撤销
BGACK,然后(对于两线仲裁是撤销BR)。处理器在检测到BGACK撤销后,在下一个合适的时钟边沿收回总线控制权,并可能立即开始自己的下一个总线周期。
注意:图中有一个极易忽略的细节——
BG的撤销时机。手册指出,BG会在BGACK有效后的几个时钟周期被撤销。但如果此时有其他BRpending,处理器会在撤销当前BG后仅几个周期,就重新发出BG给下一个请求。这个设计保证了仲裁链的连续性。
3.2 状态机:仲裁逻辑的“大脑”
手册图3-17的有限状态机(FSM)是仲裁单元的核心逻辑。我们将其翻译成更易理解的描述:
- 状态0 (STATE 0):空闲态。无外部请求(R=0),无外部设备确认占用(A=0)。处理器控制总线(G=0, T=0)。
- 状态1 (STATE 1):请求收到。外部请求有效(R=1),但处理器可能还在进行自己的总线周期(S0或S1状态),此时状态机暂不跳转(见Note 1)。这是为了确保处理器完整完成当前原子操作。
- 状态2 (STATE 2):授权态。处理器已准备好释放总线,发出
BG(G=1),并准备将总线置为高阻(T=1)。它等待外部设备确认(A)。 - 状态3 (STATE 3):外部设备占用态。外部设备已发出
BGACK(A=1),总线处于高阻态(T=1),由外部设备驱动。处理器持续监控BR(R)。 - 状态4 (STATE 4):释放准备态。外部设备已撤销
BGACK(A=0),但可能BR仍有效(R=1,表示该设备或另一个设备还想用)。处理器撤销BG(G=0),但总线仍保持高阻(T=1),为一个新的仲裁周期做准备。
这个状态机清晰地刻画了从请求、授权、占用到释放的完整闭环,以及在不同输入(R, A)组合下的状态迁移路径。理解它,对于用硬件描述语言(如VHDL/Verilog)实现兼容的外部仲裁器至关重要。
3.3 特殊时序案例解析
手册还给出了两种特殊情况的时序图,这往往是实际调试中坑点所在:
- 总线空闲时请求(Bus Inactive):当处理器在执行内部长操作(如乘法指令)而不使用外部总线时,
AS持续无效。此时收到BR请求,处理器可以更快地响应,因为它无需等待当前总线周期结束。BG发出后,总线立即进入高阻态,外部设备可以更快接管。 - S0状态早期请求:如果
BR恰好在处理器刚启动一个新总线周期(进入S0状态)但还未发出AS时到来,BG的发出会被延迟一个额外的时钟周期。这是因为处理器需要先通过AS的生效向外部宣告“我正在用总线”,然后再处理释放。忽略这个细节可能导致对BG响应时间的误判。
4. 异步操作与总线周期终止控制
MC68306的经典之处在于其异步总线设计。它不依赖全局时钟的严格同步来协调主从设备,而是通过一组握手信号(AS,UDS/LDS,DTACK,BERR,HALT)来完成通信。这使得它可以与不同速度的外设协作,但同时也让总线周期的终止变得复杂。
4.1 握手信号的角色
AS(Address Strobe):主设备发出,表示地址线上的地址有效。是总线周期开始的标志。UDS/LDS(Upper/Lower Data Strobe):主设备发出,指示当前访问的是数据总线的高字节(D15-D8)、低字节(D7-D0)还是字(两者)。DTACK(Data Transfer Acknowledge):从设备(或外部控制逻辑)发出,向主设备确认“数据已准备好(读)”或“数据已接收(写)”。这是正常结束一个总线周期的关键信号。BERR(Bus Error):外部控制逻辑发出,告知主设备本次访问出错(如访问了不存在的地址、校验错误等)。HALT(Halt):外部设备发出,请求处理器暂停。
4.2 总线周期终止的四种命运
一个总线周期的结局,由DTACK、BERR、HALT在特定时刻的组合决定。手册表3-1是这方面的“圣经”,我们将其解读为四种命运:
- 正常终止 (Normal Termination):
DTACK在BERR和HALT无效时被断言。这是99%的情况。主设备在DTACK有效后,结束当前周期,继续执行。 - 暂停终止 (Halt Termination):
HALT在DTACK之前或同时有效,且BERR无效。处理器完成当前周期后进入暂停状态,直到HALT撤销。用于单步调试。 - 总线错误终止 (Bus Error Termination):
BERR在DTACK之前、同时或代替DTACK被断言。处理器终止当前周期,并触发总线错误异常,跳转到错误处理程序。这是处理硬件访问错误的标准机制。 - 重试终止 (Retry Termination):
BERR和HALT在DTACK之前或同时被断言。处理器终止当前周期,并在HALT撤销后自动重试该周期。这对于处理短暂的、可恢复的访问故障(如动态存储器的刷新冲突)非常有用。
重要提示:手册特别强调,对于读-修改-写周期(如
TAS测试并置位指令),处理器不会重试。一旦发生BERR,无论HALT是否有效,都按总线错误处理。这是因为读-修改-写是一个不可分割的原子操作,重试可能破坏其语义。
4.3 异步与伪异步操作模式
- 完全异步 (Fully Asynchronous):从设备完全忽略处理器时钟,仅根据
AS、UDS/LDS等握手信号来操作。DTACK可以在AS有效后的任意时间发出,处理器会无限插入等待状态(Wait States)直到收到DTACK或BERR。这种模式兼容性最好,但性能最低。 - 伪异步 (Pseudo-Asynchronous):从设备了解系统时钟频率,但不与其严格同步。它可以利用一些与时钟相关的建立(Setup)和保持(Hold)时间参数来优化性能。例如,它可以在数据真正稳定之前就提前发出
DTACK(参数#31规定了最大提前量),处理器会在下一个时钟边沿锁存数据,只要数据在锁存前满足建立时间即可。这能在保证兼容性的前提下提升速度。
实操心得:调试总线问题当遇到系统随机挂起、数据错误时,总线周期终止问题是首要怀疑对象。
- 逻辑分析仪是关键:必须抓取
AS、DTACK、BERR、HALT以及地址/数据线的波形。 - 检查
DTACK:DTACK是否在AS有效后的合理时间内(根据外设速度)被拉低?是否在AS撤销后及时拉高(参数#28)?如果DTACK一直为高,处理器会永远等待。 - 检查
BERR:是否意外被触发?可能是地址译码错误,或访问了未初始化的存储区域。 - 检查
HALT:调试接口是否意外拉低了HALT? - 注意同步问题:
DTACK/BERR/HALT是异步输入。它们必须在处理器时钟的特定边沿(上升沿)之前满足建立时间(参数#47),才能被正确采样。不稳定的信号毛刺或过长的走线延迟可能导致采样错误,引发不可预知的行为。在PCB设计时,这些信号线应作为关键路径处理。
5. 复位、双重总线故障与系统可靠性
5.1 复位操作时序
RESET信号用于初始化处理器。手册图3-27的时序需要关注两点:
- 外部复位:需要至少132个时钟周期的低电平,以确保内部逻辑完全复位。
- 复位序列:复位后,处理器从地址
$00000和$00004分别读取初始堆栈指针(SSP)和程序计数器(PC)。这两个地址必须存放有效的ROM代码地址,否则系统无法启动。这是一个常见的硬件设计检查点。
5.2 双重总线故障:最严重的错误
这是系统设计的“最后防线”,也是调试中最棘手的问题之一。
- 何时发生:当处理器在处理一个总线错误异常的过程中(即在执行异常处理程序的第一条指令之前,正在将状态寄存器、PC、错误信息压入堆栈时),再次发生总线错误。
- 后果:处理器认为系统已严重损坏,无法可靠地进行异常处理(因为连栈操作都可能失败)。它会停止一切操作,并拉高
HALT信号,进入“死机”状态。 - 恢复方法:只有外部复位(拉低
RESET引脚)才能让处理器从双重总线故障中恢复。
设计经验:双重总线故障通常意味着系统存在根本性硬件问题,例如:
- 用于异常堆栈的内存区域(通常是RAM)本身故障或不可访问。
- 地址/数据总线在异常处理期间发生严重冲突。
- 电源不稳定导致逻辑混乱。 在设计阶段,确保异常向量表和初始堆栈区位于绝对可靠的存储介质(如ROM或已初始化的静态RAM)中,是预防双重总线故障的关键。
6. 同步操作模式及其性能考量
虽然MC68306以异步总线闻名,但它也支持同步操作模式,以获取最高性能。
6.1 同步模式工作原理
在同步模式下,外部设备(通常是高速静态RAM)与处理器时钟紧密同步。它不再依赖异步的DTACK,而是根据时钟边沿来预测数据就绪时间。处理器在固定的时钟状态(如S4的下降沿)采样数据,只要数据在该边沿满足建立时间即可。
手册中图3-32和3-33的同步读写周期时序图显示,一个无等待状态的标准周期正好是4个时钟周期(S0-S7)。DTACK(在同步设备中可能由时钟逻辑生成)必须在S4状态下降沿之前满足建立时间(参数#47),这样才能让周期在S7正常结束。如果DTACK没准备好,处理器就会在S4之后插入整数倍的等待周期(整个时钟周期),直到DTACK满足条件。
6.2 同步与异步模式混合设计
一个典型的优化系统采用混合模式:
- 同步区域:将零等待状态(Zero Wait-State)的SRAM映射到关键的高速代码/数据区,使用同步接口,实现最大吞吐量。
- 异步区域:将低速的外设(如UART、定时器、ADC)以及大容量DRAM映射到其他地址区域,使用异步接口,简化设计,提高兼容性。
地址译码器需要根据访问的地址范围,来生成或选择不同的DTACK信号路径。对于同步区域,DTACK可能由固定延迟线或与时钟对齐的逻辑生成;对于异步区域,DTACK则来自实际外设的响应。
性能调优要点:
- 计算建立/保持时间:根据处理器时钟频率(如16MHz,周期62.5ns),仔细核算同步SRAM的访问时间(tAA)、输出使能时间(tOE)是否满足处理器的数据建立时间(参数#27,如20ns)和保持时间要求。
DTACK生成电路:对于同步设备,一个简单而可靠的方法是使用一个由地址译码输出和时钟共同触发的单稳态触发器或小型CPLD来产生脉宽固定的DTACK。必须确保其下降沿相对于时钟边沿的延迟是稳定且满足参数#47的。- 等待状态插入:如果SRAM速度不够快,无法在S4下降沿前提供数据,则需要在地址译码逻辑中设计等待状态发生器。常见的做法是用一个计数器,在
AS有效后开始计数,经过预定的时钟周期数(1个或多个)后再产生DTACK。