多比特信号跨时钟域握手方案
来源:集成电路那些事 发布时间:2023-05-24 分享至微信
本篇文章我们来看一下握手控制,本文将从以下几点来总结:
  • 什么是握手信号

  • 多比特跨时钟域握手接口
  • 多比特跨时钟域握手设计方案一
    • 接口时序
    • 电路设计
  • 多比特跨时钟域握手设计方案二
    • 接口时序
    • 电路设计
什么是握手信号
握手指的是两个设备之间通信的一种方式,用来通信的信号就是握手信号。

简单的握手信号是 valid 和 ready,也可以叫 request 和 grant。

假设设备1向设备2发送数据,设备1不知道设备2什么时候可以接收数据,设备2也不知道设备1什么时候会发送数据,那么它们之间如果用握手通信可能是这样的顺序:
  1. 设备1将 valid 信号置1,告诉设备2,数据准备就绪了,请查收
  2. 设备2此刻正处于忙碌状态无法接收数据,设备2将 ready 信号保持为0
  3. 设备2空闲了,将 ready 信号置1接收设备1的数据
  4. 设备1看到设备2的 ready 为1,它知道设备2已经接收好数据了,将 valid 置0同时撤销数据,准备下一次发送。

可以看到因为有握手控制,可以确保数据的正确传输,不会丢失。

跨时钟域的握手设计就是利用握手控制这种优势,从而避免因为跨时钟域引起的数据传输错误。

多比特跨时钟域握手接口

图1是多比特跨时钟域的接口设计,可以看到握手模块其实就是一个桥梁,用来连接 clock1 时钟域和 clock2 时钟域。接口上看它有:

  • 两组时钟复位信号输入,(clk1,rst1) 和 (clk2,rst2)
  • 两组握手信号,(valid1,ready1)和(valid2,ready2)
  • 两路数据信号,(data1输入)和(data2输出)
多比特跨时钟域握手设计方案一

方案一和本文在第一部分讲的设备1和设备2通信的顺序是一样的。

接口时序

电路设计

按照图2的接口时序,我们可以先描述一下握手模块的功能和步骤:

  1. (跨时钟域)同步 clock1 时钟域的 valid1 信号到 clock2 时钟域,称之为 valid1_2
  2. (clock2时钟域)利用同步后的 valid1_2 产生一个脉冲信号 pulse_1
  3. (clock2时钟域)当看到 pulse1 为高电平时需要采样数据 data1 到寄存器 data1_2,同时拉高 valid2 信号,然后将寄存器 data1_2 存放的数据输出到 data2
  4. (clock2时钟域)当看到 ready2 为高同时 valid2 也为高时,拉低 valid2,同时产生一个脉冲信号,称之为 pulse2
  5. (跨时钟域)将脉冲信号 pulse2 同步到 clock1时钟域,同步后的脉冲信号称之为 pulse2_1
  6. (clock1时钟域)将脉冲信号pulse2_1输出到 ready1

描述完上述步骤之后,对应的电路/代码设计其实也一目了然了:

步骤1. 两级寄存器同步器
logic [1:0] valid1_2_ms_q;logic valid1_2_q;always_ff @(posedge clk2 or posedge rst2) if (rst2) begin valid1_2_ms_q <= 2'b00; valid1_2_q <= 1'b0; end else begin valid1_2_ms_q <= {valid1_2_ms_q[0], valid1}; valid1_2_q <= valid1_2_ms_q[1]; end

步骤2. 组合逻辑

logic pulse_1;always_comb begin pulse1 = !valid1_2_q & valid1_2_ms_q[1]; end
步骤3和4. 数据数据寄存器data1_2,标志寄存器valid2 + 控制组合逻辑
// 输出数据寄存器logic [N-1:0] data1_2_q;  // assume input data is N bitsalways_ff @(posedge clk2 or posedge rst2)  if (rst1) begin    data1_2_q <= '0;  end else begin    if (pulse_1) begin       data1_2  <= data1;    end  endassign data2  = data1_2_q;// 输出 valid 标记寄存器logic valid2_d, valid2_q;always_comb begin  valid2_d = valid2_q;  if (pulse_1) begin    valid2_d = 1'b1;  end else if (valid2_q & ready2) begin    valid2_d = 1'b0;  endendalways_ff @(posedge clk2 or posedge rst2)  if (rst1) begin    valid2_q <= '0;  end else begin    valid2_q <= valid2_d;  endassign valid2  = valid2_q;// 脉冲信号assign pulse2 = valid2 & ready2;

值得注意的是,这里数据data1是在 clock1 时钟域,而寄存器data1_2是在 clock2 时钟域,为什么可以直接采样而不会有问题呢。

从图2可以看到data1在valid1拉高之后是保持不变的,跨时钟域采样一个不变的数据是不会有问题的。

步骤5. 单比特脉冲跨时钟域同步器。

之前的文章FPGA设计之跨时钟域(二)已经介绍过单比特脉冲同步器的设计。

步骤6. 连线

assign ready1 = pulse2_1;
多比特跨时钟域握手设计方案二
接口时序
如图3所示,你能看出与图2的区别吗?


区别主要是在valid1,在图1的时序图中valid1是一个电平信号,而这里valid1变成了脉冲信号。

电路设计

因为valid1变成了一个脉冲信号,我们就不能用简单的两级寄存器来同步了。

需要用单比特脉冲同步器,同时看到valid1有效时要先将数据 data1 存储在clock1时钟域的寄存器中。

其他的逻辑基本上和方案一是一样的。
logic [N-1:0] data1_local_q;always_ff @(posedge clk1 or posedge rst1) if(rst1) begin data1_local_q <= '0; end else begin if(valid1) begin data1_local_q <= data1; end end
总结

在本篇文章中我们总结了多比特跨时钟域的握手原理和设计,包括两种不同方案的接口时序和电路设计。

以上内容转载自:FPGA开发之路,版权归原作者,如需转载本文,请联系原公众号,文
章中其它相关链接也请去原公众号内获取,欢迎大家留言讨论,谢谢!



简介


集成电路那些事(ID:ICKnowledge)专注于集成电路相关内容,是一个IC讯息的汇聚地,分享、转载好文一起学习,一起进步。

扫码关注

动动你的发财手,给个“在看”呗!

[ 新闻来源:集成电路那些事,更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj]
存入云盘 收藏
举报
全部评论

暂无评论哦,快来评论一下吧!