//
//		async2h.v - transfer pulsess from one clock domain to another
//
// 				(C) Copyright 2004-2009 John B. Stephensen
//
// This Verilog source file and all its derivatives are licensed only for
// personal non-profit educational use in the Amateur Radio Service and
// the license is not transferrable. The information is provided as-is for
// experimental purposes and the author does not warranty its freedom
// from defects or its suitability for any specific application.
//
//	This module is designed for asynchronous clocks and includes a 1/2 output
// clock period delay for metastable states.
//
//	379 MHz maximum. 3 slices used.
//
module async2h(a, aclk, arst, b, bclk, brst);
	 input a;		// input
	 input aclk;	// input clock
	 input arst;	// reset input
	 output b;		// output
	 input bclk;	// output clock
	 input brst;	// reset output
// registers
reg t;				// clock domain A
reg s0,s1,s2,s3;	// clock domain B
// flip-flop toggles when input true
always @ (posedge aclk)
begin
	if (arst) t <= 1'b0;
	else t <= t^a;
end
// output logic synchronizes transition to output clock
// first flip-flop can enter meta-stable states
// second flip-flop waits for instablity to end
// next two flip-flops convert transition to one clock long pulse
always @ (posedge bclk)
begin
	if (brst) s0 <= 0;
	else s0 <= t;		// unstable
end
always @ (negedge bclk)
begin
	if (brst) s1 <= 0;
	else s1 <= s0;	// absorbs instability
end
always @ (posedge bclk)
begin
	if (brst) s2 <= 0;
	else s2 <= s1;		// for transition detection
	if (brst) s3 <= 0;
	else s3 <= s1 ^ s2;	// creates pulse
end
assign b = s3;
endmodule
