Processing method of single pulse across clock domain

Posted by nthomp on Mon, 16 Dec 2019 21:46:48 +0100

In the development and design of FPGA, many clocks are working in the same module at the same time. At the same time, the communication between signals in the clock domain must be ensured. It is necessary to deal with the timing problem, that is, the establishment and holding time of signals.

  r_PULSE_O <= { r_PULSE_O[1:0] , r_PULSE_I} ;   

Theoretically, it is equivalent to the beat operation of a single bit signal in the target clock domain; however, some syntax detection tools such as questa CDC will think that CDC processing is not carried out and EDA alarms can be ignored.

 assign  PULSE_O = (r_PULSE_O[2] != r_PULSE_O[1])  ;      

The input single beat pulse will be expanded to two beats in the target clock domain;

 reference: http://www.eetop.cn/blog/html/17/743817-24614.html

`timescale 1 ps / 1 ps
module PULSE_GEN (
XRST , // (i) Reset Input ( Asynchronous )
CLK_I , // (i) Clock At Input Side
CLK_O , // (i) Clock At Output Side
PULSE_I , // (i) Pulse Input
PULSE_O // (o) Pulse Output
) ;

parameter P_TYPE = 8'd0 ;

//==========================================================
// Declare the port directions
//==========================================================

input XRST ; // (i) Reset Input ( Asynchronous )
input CLK_I ; // (i) Clock At Input Side
input CLK_O ; // (i) Clock At Output Side
input PULSE_I ; // (i) Pulse Input
output PULSE_O ; // (o) Pulse Output

//==========================================================
// Internal signals define
//==========================================================

reg r_PULSE_I ;
reg [2:0] r_PULSE_O ; // r_PULSE_O[0], r_pluse_o[1] Should Not Be Duplicated
// Synthesis Attribute MAX_FANOUT of r_PULSE_O is 9999;

//==========================================================
// RTL Body
//==========================================================

generate
if(P_TYPE == 0) begin :TYPE_0_PULSEGEN

//==========================================================
// Input Pulse Keep ( CLK_I domain )
//==========================================================
always @( posedge CLK_I or negedge XRST ) begin
if( !XRST ) begin
r_PULSE_I <= 1'b0 ;
end else begin
if ( PULSE_I == 1'b1 ) begin
r_PULSE_I <= ~r_PULSE_I ;
end
end
end

//==========================================================
// Output Pulse Sync. And Generate ( CLK_O Domain )
//==========================================================
always @( posedge CLK_O or negedge XRST ) begin
if( !XRST ) begin
r_PULSE_O <= 3'b000 ;
end else begin
r_PULSE_O <= { r_PULSE_O[1:0] , r_PULSE_I } ;
end
end

assign PULSE_O = (r_PULSE_O[2] != r_PULSE_O[1] ) ; // 0 -> 1

end
endgenerate

endmodule


Topics: Verilog Attribute