6.3 跨时钟域与仲裁:并发世界的边界谈判


文档摘要

6.3 跨时钟域与仲裁:并发世界的边界谈判 本节摘要:两个时钟域之间没有共同的时间参考,任何直接穿越都是亚稳态赌博;同步器、握手与格雷码是三条正路。仲裁器处理多个请求者抢占同一资源:固定优先级简单但会饿人,轮转调度公平但复杂。这一节是并发设计的第一课,也是错误成本最高的领域。 状态机管好了单一时钟域内的秩序,但现代设计里多时钟域是常态:处理器一域、外设一域、接口一域。跨域信号直接连线,等于让两个没有共同参考的时间体系当庭对质——这一节审跨时钟域(CDC)的三条正路与仲裁器的两套写法。 亚稳态:穿越边界的第一风险 触发器的时序契约要求:数据在时钟沿前后的建立保持窗口内保持稳定。当数据来自另一个时钟域,它到达的时刻与本地时钟沿的关系是随机的——总有一些沿,数据恰好在窗口内翻转。

6.3 跨时钟域与仲裁:并发世界的边界谈判

本节摘要:两个时钟域之间没有共同的时间参考,任何直接穿越都是亚稳态赌博;同步器、握手与格雷码是三条正路。仲裁器处理多个请求者抢占同一资源:固定优先级简单但会饿人,轮转调度公平但复杂。这一节是并发设计的第一课,也是错误成本最高的领域。

状态机管好了单一时钟域内的秩序,但现代设计里多时钟域是常态:处理器一域、外设一域、接口一域。跨域信号直接连线,等于让两个没有共同参考的时间体系当庭对质——这一节审跨时钟域(CDC)的三条正路与仲裁器的两套写法。

亚稳态:穿越边界的第一风险

触发器的时序契约要求:数据在时钟沿前后的建立保持窗口内保持稳定。当数据来自另一个时钟域,它到达的时刻与本地时钟沿的关系是随机的——总有一些沿,数据恰好在窗口内翻转。此时触发器进入亚稳态:输出悬在 0 与 1 之间的过渡带,既不是 0 也不是 1,且要经过一段不确定的时间才随机落定。落定期间下游读到的值不可预期,亚稳态还会沿逻辑链传染。

亚稳态无法根除,只能压低概率。两级同步器是标准器械:

module sync_2ff( input wire clk_dst, // 目标域时钟 input wire rst_n, input wire sig_async, // 异步输入 output wire sig_sync ); reg ff1, ff2; always @(posedge clk_dst or negedge rst_n) begin if (!rst_n) begin ff1 <= 1'b0; ff2 <= 1'b0; end else begin ff1 <= sig_async; // 第一级:可能亚稳,给它一拍恢复时间 ff2 <= ff1; // 第二级:读到的是稳定后的值 end end assign sig_sync = ff2; endmodule

原理是「给亚稳态一拍恢复时间」:第一级采样到亚稳态时,第二级在下一个沿到来前有整整一个时钟周期等待它落定。同步器的失效概率随恢复时间指数下降,一级变二级是数量级的改善。两条纪律随之而来:同步器两级之间不能插任何组合逻辑(会吃掉恢复时间);同步器输出未落定前仍是「不确定但稳定」的值,业务逻辑要容忍它晚一拍到达。

06-06-fig01-3

多比特数据的正路:握手与异步 FIFO

两级同步器有一个致命局限:它只保证单个比特的完整性。一个八位总线逐位各自打两拍,各位的同步延迟互不相同,目标域可能在同一沿上读到「旧高半新低」的拼盘。多比特数据的正路有两条。

第一条是握手协议:数据在源域保持稳定,源域发一个单比特 valid 信号(它过两级同步器),目标域看到 valid 才采样数据——数据的各位在 valid 有效期间纹丝不动,不存在位间错位的窗口。valid、ready 两根线的完整握手是接口协议建模的基本功:

// 目标域侧:valid 同步后采样数据 reg valid_ff1, valid_ff2, valid_ff3; reg [7:0] data_q; always @(posedge clk_dst or negedge rst_n) begin if (!rst_n) begin {valid_ff3, valid_ff2, valid_ff1} <= 3'b000; data_q <= 8'd0; end else begin {valid_ff3, valid_ff2, valid_ff1} <= {valid_ff2, valid_ff1, valid_src}; if (valid_ff2 && !valid_ff3) begin // 上升沿检测:每个事务只采一次 data_q <= data_bus; // 数据在源域保持稳定,安全采样 end end end

第二条是异步 FIFO:双口存储器加两侧指针,写指针在写域更新、读域同步,读指针反之。直接同步多比特指针会遇到同样的位间错位问题,格雷码在这里登场——格雷码相邻数值只变一位,即使同步器采到「过渡态」,得到的指针要么是旧值要么是新值,绝不会是第三种拼盘。异步 FIFO 是跨域数据流的工业标准答案,第 8 章的时序约束流程里还会遇到它的伪路径声明。

案例展开:消失的使能脉冲。 背景:慢速外设域每秒发出一个宽度仅两个慢时钟周期的 start 脉冲,快域经两级同步器接收后偶发漏触发。操作:波形核查发现脉冲持续期短于快域同步链的响应窗口时,脉冲「进得去出不来」——第一级恢复前输入已撤,两级输出始终为低。结果:改用电平翻转协议,外设域每次事件翻转一次电平,快域同步后做边沿检测;事件率不变,漏触发归零。解读:两级同步器保真但不保宽——同步器的输出沿可能迟到、甚至被下一拍追平,窄脉冲穿越本质上是把「持续时间」当协议,而同步器破坏的恰恰是时间信息。电平翻转与边沿检测把「事件」编码进电平而不是脉宽,是脉冲跨域的标准解法。变式:事件密集到电平可能连翻时,用计数器把事件计数转成格雷码跨域,目标域对同步后的格雷码做差值——这就是异步 FIFO 指针同步的微缩版。

仲裁器:多请求者的排队规则

多路请求抢占单资源(总线、DMA 通道、中断线)需要仲裁。固定优先级用一条 if 链(3.3 节的优先级编码器就是现成写法):高优先级请求在场时低优先级永远等不到——饿死是它的结构性缺陷,但它简单、可预期,短事务场景依然是合理选择。

轮转调度把「上次谁赢了」记下来,下次从下家开始看。核心资产是一个位置寄存器加环形掩码逻辑:把请求向量按上次胜者的位置旋转,取旋转后的最低有效请求位,再旋回原位作为授权。这套「旋转取最低」的手法让每个请求者在无更高优先者时都有均等的出头机会——公平从祈祷变成了状态机保证。两种策略的选择标准:请求者地位平等用轮转,地位有差(实时性不同)用固定优先级或加权轮转。

// 四路固定优先级仲裁:if 链的直接应用 always @(*) begin if (req[3]) grant = 4'b1000; else if (req[2]) grant = 4'b0100; else if (req[1]) grant = 4'b0010; else if (req[0]) grant = 4'b0001; else grant = 4'b0000; end

并发审查清单

跨域与仲裁的代码评审有一张固定清单:每个跨域信号是否都过了同步器(包括复位、配置、中断);同步器两级之间是否干净(无组合逻辑、无扇出到多处);多比特数据是否走握手或 FIFO,有没有人偷懒逐位打拍;慢时钟域到快时钟域的脉冲是否用了电平翻转或展宽;仲裁器的饿死风险是否评估过;授权信号与对应的业务操作是否同一拍对齐。这张清单上的每一项,背后都是一类难以复现的现场事故。

本节要点回顾

  • 亚稳态无法根除:跨域信号的建立保持窗口随机失守,两级同步器把失效概率压到工程可接受;
  • 两级之间必须干净:同步器中间插逻辑等于没收恢复时间;
  • 同步器保真不保宽:窄脉冲跨域用电平翻转加边沿检测,脉宽不是协议;
  • 多比特数据禁逐位打拍:位间错位无解,正路是握手采样或格雷码指针异步 FIFO;
  • 仲裁两套写法:固定优先级可预期但饿人,轮转靠位置寄存器把公平变成状态;
  • 评审有清单:跨域信号、同步器洁净度、脉冲宽度、位间一致性、饿死风险,逐项过堂。

惯犯档案收档。下一章「庭审交锋」:给这些结构搭一座会提问的法庭——测试台、自检查与覆盖率。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U