多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<=1b1;
		//slave的回应信号ack的pos说明接收到数据,master的req拉低
		else if(!out_ack_reg[2]&out_ack_reg[1])
			req<=1b0;
		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<=1b1;
		else
			out_vld<=1b0;
	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<=1b1;
		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
经验分享 程序员 微信小程序 职场和发展