当前位置: 首页 > news >正文

fpga系列 HDL:跨时钟域同步 4-phase handshake(四相握手通信协议,请求-确认机制)浅释与代码实现

目录

    • 应用场景
    • 四相握手的四个阶段
        • Phase 1: 数据准备与请求
        • Phase 2: 数据传输与确认
        • Phase 3: 请求信号复位
        • Phase 4: 应答信号复位
    • 特点与优势
        • 可靠性
        • 灵活性
        • 双向同步
        • 容错能力
    • CODE
      • Sender
      • Receiver
  • CG
    • 上图绘制代码

4-phase handshake(四相握手协议) 是一种用于同步和通信的协议,广泛应用于异步电路设计、数据传输以及硬件模块之间的通信。它的核心目标是确保发送方和接收方之间的数据传递是可靠且有序的,避免数据丢失或冲突。

应用场景

  • 异步电路设计:用于模块之间的通信,尤其是在没有全局时钟的情况下。
  • 总线通信:如处理器与外设之间的数据传输。
  • FIFO 缓冲区管理:用于控制 FIFO 的读写操作,确保数据不会溢出或丢失。
  • 分布式系统:用于节点之间的消息传递和同步。

四相握手的四个阶段

  • 四相握手协议是一种基于请求(Request)和应答(Acknowledge)信号的通信机制。它通过四个阶段完成一次数据传输,因此得名“四相握手”。
Phase 1: 数据准备与请求
  • 发送方将数据准备好,并将 Req 信号置为高电平(或激活状态),通知接收方数据已准备好。
  • 接收方检测到 Req 信号的变化后,知道可以开始接收数据。
Phase 2: 数据传输与确认
  • 接收方读取数据,并在成功接收后将 Ack 信号置为高电平(或激活状态),通知发送方数据已被接收。
  • 发送方检测到 Ack 信号的变化后,知道数据传输已完成。
Phase 3: 请求信号复位
  • 发送方将 Req 信号复位(置为低电平或非激活状态),表示当前数据传输已结束。
  • 接收方检测到 Req 信号的变化后,知道可以准备接收下一个数据。
Phase 4: 应答信号复位
  • 接收方将 Ack 信号复位(置为低电平或非激活状态),表示已经准备好接收下一次数据。
  • 发送方检测到 Ack 信号的变化后,知道可以开始下一轮数据传输。
 FIFO数据控制模块Sender                        数据使用模块ReceiverREN_FIFO<=1;| 读取一位数据到REGSendIrq <= 1'b1;     ======== a~b =========> if(SendIrq == 1'b1)       |使用读取的数据  if(SendAck == 1'b1)  <======= b~c ==========    SendAck <= 1'b1;|SendIrq <= 1'b0;     ======== c~d =========> if(SendIrq == 1'b0)    |SendAck <= 1'b0;Status <= 1'b0;

在这里插入图片描述

特点与优势

可靠性
  • 每次数据传输都需要双方确认,确保数据不会丢失或被重复处理。
  • 即使系统时钟不同步,也能正常工作,适用于异步通信。
灵活性
  • 不依赖于全局时钟信号,适合异步电路设计。
  • 支持动态调整数据传输速率,适应不同的应用场景。
双向同步
  • 发送方和接收方通过 ReqAck 信号实现双向同步,确保双方的状态一致。
容错能力
  • 如果一方出现故障(例如未及时响应),另一方可以通过超时机制或其他方式检测并处理。

CODE

Sender

// FIFO 控制,第一个数为数据的长度,通过循环读取确保数据读取完成
always@(negedge CLK_for_FIFO or negedge SYS_RST)
beginif(~SYS_RST)begin	REN_to_CMDFIFO <=0;	DataNum <= 0;	ReadCount <=0;DelayCount <= 0;		SendIrq    <= 1'b0;SendIrq <= 1'b0;SenderStatus<=0;end	else begincase(SenderStatus) // 状态机开始位置!!!0:beginif(USEDW >= 1)beginREN_to_CMDFIFO	<= 1;DataNum 		<= 0;ReadCount 	    <= 0;SenderStatus	<= 1;			endend	1:beginDataNum     	<= D_from_CMDFIFO;// FIFFO的输出数据REN_to_CMDFIFO	<= 0;DelayCount 		<= 0;SenderStatus	<= 2;end2: beginif( USEDW >= DataNum )  // 如果FIFO中数据量>= DataNumbeginSenderStatus <= 4;endelsebeginSenderStatus <= 3; // 状态3是起延时作用end	end3:begin			if(DelayCount == 500000)beginDelayCount 		<= 16'b0;SenderStatus 	<= 0; // 直接回到状态2可能会导致状态机继续无效循环,而回到状态0则可以重新评估是否应该继续尝试读取数据end	elsebeginDelayCount 		<= DelayCount + 1'b1;SenderStatus 	<= 2;endend4:beginif( USEDW>=1 )beginREN_to_CMDFIFO  <= 1; // 可以进行读取了ReadCount       <= ReadCount + 1'b1;SenderStatus    <= 5;			end				end5:beginSerialData[7:0]	    <= D_from_CMDFIFO[7:0];	// 读取一位数据		REN_to_CMDFIFO		<= 0;SendIrq    			<= 1'b1; SenderStatus		<= 6;	end6:beginif(SendAck == 1'b1)  // SendAck是和SendIrq关联的控制寄存器beginSendIrq        <= 1'b0;SenderStatus   <= 7;endend7:beginif(ReadCount == DataNum)beginSenderStatus <= 0;      // 如果已经读取固定长度的数据,转到状态0endelsebeginSenderStatus <= 4;      // ReadCount != DataNum,继续读取并发送数据end		enddefault:beginSenderStatus	<= 0;endendcaseend
end

Receiver

always@(posedge CLK_for_FIFO or negedge SYS_RST)
beginif(~SYS_RST)beginReceiverStatus <= 0;endelsebegincase(ReceiverStatus)0: // 等待中断信号SendIrq有效beginif(SendIrq == 1'b1) // 读取一位数据进行发送请求beginReceiverStatus <= 1;endend1:  // 根据TempSend300HzBuf和PNFlag的值决定下一步操作begin		OUT[0] = SerialData[0]; // 从FIFO读取的数据ReceiverStatus <= 2;end2:beginif(count_receiver == 200000 ) // 状态2:延时200000个时钟周期后beginSendAck 	    <= 1;count_receiver 	<= 0;			ReceiverStatus 	<= 3;endelsebegincount_receiver   <= count_receiver + 1'b1;end	end3:beginif(SendIrq == 1'b0) // 状态11:等待SendIrq无效后回到控制数据读取初始状态0beginSendAck 	    <= 0;ReceiverStatus 	<= 0;endenddefault: // 默认情况下重置所有相关寄存器和变量beginTempSerialData    <= 0;ReceiverStatus 	  <= 0;SendAck 	      <= 0;endendcaseend
end

CG

  • 数字芯片设计中常见的三个握手协议

上图绘制代码

// https://wavedrom.com/editor.html
{signal: [{name: 'clk', wave: 'p.........'}, {name: 'req', wave: '0.1...0...',node: '..a...c...'},{name: 'ack', wave: '0....1...0',node: '.....b...d'},{name: 'dat', wave: '.x=..x....', data: ['data']},
],head:{text:'4-phase Handshake',tick:0,every:2},edge: ['a~b', 'b~c', 'c~d', ]
}

http://www.mrgr.cn/news/97629.html

相关文章:

  • 嵌入式---加速度计
  • 搭建hadoop集群模式并运行
  • SearXNG
  • MCP基础学习一:MCP概述与基础
  • Linux 性能调优之CPU调优认知
  • 【回眸】Linux 内核 (十三)进程间通讯 之 共享内存
  • QML Loader:动态加载与控件创建
  • MCP-Playwright: 赋予AI模型操控浏览器的能力
  • c# 数据结构 链表篇 有关单链表的一切
  • 力扣hot100_回溯(2)_python版本
  • Wideband Sparse Reconstruction for Scanning Radar论文阅读
  • 【Pandas】pandas DataFrame infer_objects
  • AnimateCC基础教学:随机抽取花名册,不能重复
  • nginx如何实现负载均衡?
  • Python 快速搭建一个小型的小行星轨道预测模型 Demo
  • 数字电子技术基础(四十)——使用Digital软件和Multisim软件模拟显示译码器
  • C++隐式转换的机制、风险与消除方法
  • Model Context Protocol(MCP)介绍
  • 机器学习 Day09 线性回归
  • 0基础 | 硬件 | LM386芯片