多bit跨时钟域:双向handshake

1、master的req发送请求信号 to slave

2、slave的ack接收回复信号   to master

两者进行握手

`timescale 1ns/1ps

module sync_handshake(
	input 			rstn_i,
	input 			clk_i,
	input 			in_vld,
	input 	   [7:0]din,
	output 			in_ack,
	input 			rstn_o,
	input 			clk_o,
	output reg      out_vld,
	output reg [7:0]dout
);
	reg [2:0]out_ack_reg;
	reg [2:0]in_ack_reg;
	reg req;
	reg ack;
	reg [7:0]din_reg;
	assign in_ack=(!out_ack_reg[1])&(!req);//ack拉低,才能让master的req重新拉高发送新数据

//1、slave的ack,在master时钟域打拍
	always@(posedge clk_i or negedge rstn_i)begin
		if(!rstn_i)
			out_ack_reg<=0;
		else
			out_ack_reg<={out_ack_reg[1:0],ack};
	end
//2、master向slave发req请求信号	
	always@(posedge clk_i or negedge rstn_i)begin
		if(!rstn_i)
			req<=0;
		else if(in_vld&in_ack)
			req<=1'b1;
		//slave的回应信号ack的pos说明接收到数据,master的req拉低
		else if(!out_ack_reg[2]&out_ack_reg[1])
			req<=1'b0;
		else
			req<=req;
	end
//3、master向slave发送数据
	always@(posedge clk_i or negedge rstn_i)begin
		if(!rstn_i)
			din_reg<=0;
		else if(in_vld&in_ack)
			din_reg<=din;
		else
			din_reg<=din_reg;
	end
//4、master的req,在slave时钟域打拍	
	always@(posedge clk_o or negedge rstn_o)begin
		if(!rstn_o)
			in_ack_reg<=0;
		else
			in_ack_reg<={in_ack_reg[1:0],req};
	end

//5、slave接收数据有效标志位	
	always@(posedge clk_o or negedge rstn_o)begin
		if(!rstn_o)
			out_vld<=0;
		else if(!in_ack_reg[2]&&in_ack_reg[1])
			out_vld<=1'b1;
		else
			out_vld<=1'b0;
	end
//6、slave给master的回应信号ack	
	always@(posedge clk_o or negedge rstn_o)begin
		if(!rstn_o)
			ack<=0;
		else if(in_ack_reg[1])
			ack<=1'b1;
		else
			ack<=0;
	end	
//7、slave接收的数据dout	
	always@(posedge clk_o or negedge rstn_o)begin
		if(!rstn_o)
			dout<=0;
		else if(!in_ack_reg[2]&in_ack_reg[1])
			dout<=din_reg;
		else
			dout<=dout;
	end
	
endmodule	

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Example of protocol with TRG-STA-GRS command cycle The initialization and reconnection of the communication is described in the chapter before. In order to initialize the communication, the MS toggles the Sync flag between 0 and 1 with cycle duration of 500 ms. Once the SC recognizes the Sync flag, it answers with an ACK frame of the same value as the detected Sync flag. The command STA is set to 2 (STA(02)) by the SC to request continuous status information. Hereupon, the MS sends its state with every answer. A prerequisite to accept commands by the MS is STA(01) (reply code from halm MS) and TOK(01). Direction Command code Reply Code Flag Remark SC → MS STA(02),TRG(01) Trigger a measurement * MS → SC Handshake acknowledge MS → SC STA(01), TRG(01) Trigger accepted SC → MS Handshake acknowledge SC → MS STA(02), TRG(FF) Command completed MS → SC Handshake acknowledge MS → SC TRG(FF), STA(02) TOK(FF) Reply completed, MS busy, cell transport not allowed SC → MS Handshake acknowledge MS → SC STA(02) TOK(01) Cell transport allowed SC → MS Handshake acknowledge MS → SC STA(01) RES(01) Measurement result data available SC → MS Handshake acknowledge SC → MS STA(02), GRS(01) MS → SC Handshake acknowledge MS → SC STA(01), GRS(01) RES(FF) Including result data SC → MS Handshake acknowledge SC → MS STA(02), GRS(FF) Command completed MS → SC Handshake acknowledge MS → SC STA(01), GRS(FF) Reply completed SC → MS Handshake acknowledge * SC sends TWO commands within one frame. In consequence, MS will reply with TWO answers. Same procedure for THREE commands. Please always send STA(02) together with every command. Do not send STA(FF) which will stop MS sending status and results.根据这个协议,帮我写一份UDP通讯的demo
06-01
好的,这里是一份简单的基于UDP通讯的TRG-STA-GRS命令循环协议的demo,希望能对您有所帮助。 ```python import socket import struct import time # 定义UDP通讯参数 UDP_IP = "192.168.0.1" # MS设备IP地址 UDP_PORT = 5005 # MS设备接收数据的端口号 # 创建UDP通讯对象 sock = socket.socket(socket.AF_INET, # Internet socket.SOCK_DGRAM) # UDP # 初始化通讯:MS设备发送Sync flag,SC设备返回ACK for i in range(2): sync_flag = i % 2 # Sync flag为0或1 data = struct.pack('B', sync_flag) # 打包Sync flag数据 sock.sendto(data, (UDP_IP, UDP_PORT)) print('发送Sync flag:', sync_flag) time.sleep(0.5) # 延时500ms data, addr = sock.recvfrom(1024) # 接收ACK ack_flag = struct.unpack('B', data)[0] # 解包ACK flag数据 print('收到ACK flag:', ack_flag) # 发送TRG-STA-GRS命令循环 while True: # 命令1:TRG(01), STA(02) cmd1 = b'\x01\x02' # TRG(01), STA(02) data = struct.pack('2s', cmd1) # 打包命令1数据 sock.sendto(data, (UDP_IP, UDP_PORT)) print('发送命令1:TRG(01), STA(02)') data, addr = sock.recvfrom(1024) # 接收回复 reply1 = struct.unpack('2B', data) # 解包命令1的回复数据 print('收到命令1的回复:', reply1) # 命令2:TRG(FF), STA(02) cmd2 = b'\xFF\x02' # TRG(FF), STA(02) data = struct.pack('2s', cmd2) # 打包命令2数据 sock.sendto(data, (UDP_IP, UDP_PORT)) print('发送命令2:TRG(FF), STA(02)') data, addr = sock.recvfrom(1024) # 接收回复 reply2 = struct.unpack('2B', data) # 解包命令2的回复数据 print('收到命令2的回复:', reply2) # 命令3:GRS(01), STA(02) cmd3 = b'\x02\x01' # GRS(01), STA(02) data = struct.pack('2s', cmd3) # 打包命令3数据 sock.sendto(data, (UDP_IP, UDP_PORT)) print('发送命令3:GRS(01), STA(02)') data, addr = sock.recvfrom(1024) # 接收回复 reply3 = struct.unpack('2B', data) # 解包命令3的回复数据 print('收到命令3的回复:', reply3) # 判断是否需要继续命令循环 if reply2[1] == 0xFF: # 如果命令2回复为TRG(FF), STA(02),则退出循环 break # 关闭UDP通讯对象 sock.close() ``` 以上代码仅供参考,具体实现需要根据您的具体需求进行修改。注意,这里的demo仅实现了命令循环的基本功能,如果需要实现更多的功能,还需要根据协议进行相应的扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值