Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17256 Discussions

Do I need synchronizer block for this

Altera_Forum
Honored Contributor II
2,389 Views

i am feeding reset, aclk and siga to the fpga as input. aclk is running very fast may be 350mhz. siga is one aclk period wide and derived from synchronizer block and then anded to gather before going into fpga. something like this in verilog testbench 

 

//generate stimulus 

initial begin 

siga1 = 1'b0; 

siga2 = 1'b0; 

reset = 1'b1;# 520 //keep reset asserted for a while  

reset = 1'b0;# 1000; //give some time before generating siga 

@(posedge aclk); 

siga1 = 1'b1; 

@(posedge aclk); 

siga2 = 1'b1;# 5000; 

siga1 = 1'b0; 

siga2 = 1'b0;# 3000; 

$finish; 

end  

 

assign# 1 siga = (siga1 & ~siga2); //mimic external and gate that ultimately generates one aclk wide pulse 

 

in this case i do not know the board trace length mis-match between aclk and siga. if so, do i need to synchronize siga signal inside the fpga?  

 

 

also how to pass the siga signal to different or slower clock domain?  

0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
967 Views

You will need to register your input to ensure your design does not have issues. If your design permits, I recommend registering all inbound signals before using them in your logic. 

 

To pass the clock-wide pulse to a slower domain is not horrible, it just takes some logic to work. I am not great at verilog, so I'm posting a VHDL clock sync design. It isn't the greatest, but you should be able to get an idea on how it can work. It has restrictions on maximum pulse rate on fast clock domain vs fast/slow clock speed ratio. *Disclaimer: I did not try to compile this so errors may exist. 

 

PROCESS(FAST_CLK,RESET) BEGIN IF(RESET = '1') THEN input_register_s <= '0'; feedback_register_s <= '0'; ELSIF (rising_edge(FAST_CLK)) THEN input_register_s <= SigA; //register the input feedback_register_s <= slow_domain_status_register_s; //register the feedback from slow domain IF (input_register_s = '1') THEN //if pulse detected, set feedforward feedforward_register_s <= '1'; ELSIF (feedback_register_s = '1') THEN //if feedback indicates pulse seen at slow domain clear feedforward feedforward_register_s <= '0'; END IF; END IF; END PROCESS; PROCESS(SLOW_CLK, RESET) BEGIN IF (RESET = '1') THEN slow_domain_status_register_s <= '0'; slow_domain_status_register1_s <= '0'; slow_domain_SigA <= '0'; ELSIF (rising_edge(SLOW_CLK)) THEN slow_domain_status_register_s <= input_register_s; //register on new clock domain slow_domain_status_register1_s <= slow_domain_status_register_s; //remember what last value was IF ((slow_domain_status_register1_s = '0') AND (slow_domain_status_register_s = '1')) THEN //rising edge detect slow_domain_SigA <= '1'; //send pulse in slow domain ELSE slow_domain_SigA <= '0'; END IF; END IF; END PROCESS;
0 Kudos
Altera_Forum
Honored Contributor II
967 Views

 

--- Quote Start ---  

You will need to register your input to ensure your design does not have issues. If your design permits, I recommend registering all inbound signals before using them in your logic. 

 

To pass the clock-wide pulse to a slower domain is not horrible, it just takes some logic to work. I am not great at verilog, so I'm posting a VHDL clock sync design. It isn't the greatest, but you should be able to get an idea on how it can work. It has restrictions on maximum pulse rate on fast clock domain vs fast/slow clock speed ratio. *Disclaimer: I did not try to compile this so errors may exist. 

 

PROCESS(FAST_CLK,RESET) BEGIN IF(RESET = '1') THEN input_register_s <= '0'; feedback_register_s <= '0'; ELSIF (rising_edge(FAST_CLK)) THEN input_register_s <= SigA; //register the input feedback_register_s <= slow_domain_status_register_s; //register the feedback from slow domain IF (input_register_s = '1') THEN //if pulse detected, set feedforward feedforward_register_s <= '1'; ELSIF (feedback_register_s = '1') THEN //if feedback indicates pulse seen at slow domain clear feedforward feedforward_register_s <= '0'; END IF; END IF; END PROCESS; PROCESS(SLOW_CLK, RESET) BEGIN IF (RESET = '1') THEN slow_domain_status_register_s <= '0'; slow_domain_status_register1_s <= '0'; slow_domain_SigA <= '0'; ELSIF (rising_edge(SLOW_CLK)) THEN slow_domain_status_register_s <= input_register_s; //register on new clock domain slow_domain_status_register1_s <= slow_domain_status_register_s; //remember what last value was IF ((slow_domain_status_register1_s = '0') AND (slow_domain_status_register_s = '1')) THEN //rising edge detect slow_domain_SigA <= '1'; //send pulse in slow domain ELSE slow_domain_SigA <= '0'; END IF; END IF; END PROCESS;  

--- Quote End ---  

 

 

Thanks for getting back to me. Can we not just set input_register_s to 1 upon SigA assertion? Then pass the Input_register_s to slow clock domain - synchronize it and generate single pulse using AND gate. Doing so will ensure that it works in any clock domain fast to slow or slow to fast. This method does not require feedback as there is only one SigA pulse. Also as per my understanding, it takes two flipflop to synchronize the asynchronous signal. Just curious. Sorry here is what I was thinking in verilog.  

 

//Synchronize the input signal as it is going through AND gate 

//Also not clear on the external trace length mis-match  

//between AClk and SigA 

always @(posedge AClk or posedge Reset) begin 

if (Reset) begin 

SigAQ0 <= 1'b0; 

SigAQ1 <= 1'b0; 

end 

else begin 

SigAQ0 <= SigA; 

SigAQ1 <= SigAQ0; 

end 

end 

 

//Generate SigAFlag based on SigAQ1 pulse 

//SigAFlag asserts upon SigA assertion 

always @(posedge AClk or posedge Reset) begin 

if (Reset) begin 

SigAFlag <= 1'b0; 

end 

else begin 

if (SigAQ1) begin 

SigAFlag <= 1'b1; 

end 

else begin 

SigAFlag <= SigAFlag; 

end 

end 

end  

//Synchronize the SigAFlag to BClk domain and generate SigB 

always @(posedge BClk or posedge Reset) begin 

if (Reset) begin 

SigBQ0 <= 1'b0; 

SigBQ1 <= 1'b0; 

SigBQ2 <= 1'b0; 

SigB <= 1'b0; 

end 

else begin  

SigBQ0 <= SigAFlag; 

SigBQ1 <= SigBQ0; 

SigBQ2 <= SigBQ1; 

SigB <= SigBQ1 & ~SigBQ2; 

end 

end  

 

It will be great if you can provide feedback.
0 Kudos
Altera_Forum
Honored Contributor II
967 Views

The reason for the feedback is to clear the flag in the fast clock domain to look for more pulses. If you will only have one ever between resets, your code should work fine. If you have multiple pulses, you need a way to clear SigAFlag in your fast domain.  

 

I have seen recommendations to use two registers to cross clock domains. Although it may be bad practice, I have always used one and had no real issues with it. Using two shouldn't be a problem, it will just take a little more time and a few more resources. Good luck with your design!
0 Kudos
Altera_Forum
Honored Contributor II
967 Views

Thanks for response. I am bit concerned about the way I have used the AND gate to derive single pulse as in following statement 

 

SigB <= SigBQ1 & ~SigBQ2; 

 

 

Normally I see people using XOR gate. I do not know why to use XOR instead of AND.  

 

I see the following paper from Cadence suggesting some issue with AND gate but they did not provide a solution. In the figure CLKA and CLKB to be same clock frequency.  

 

 

http://w2.cadence.com/whitepapers/cdc_wp.pdf Section 3.3 figure 6. 

 

 

 

--- Quote Start ---  

The reason for the feedback is to clear the flag in the fast clock domain to look for more pulses. If you will only have one ever between resets, your code should work fine. If you have multiple pulses, you need a way to clear SigAFlag in your fast domain.  

 

I have seen recommendations to use two registers to cross clock domains. Although it may be bad practice, I have always used one and had no real issues with it. Using two shouldn't be a problem, it will just take a little more time and a few more resources. Good luck with your design! 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
967 Views

If a straight XOR is used, you will get two pulses, one for the rising edge, and one for the falling edge. Your use of the & operator should not be a problem. Both SigBQ1 and SigBQ2 are not crossing domains as shown in your document's figure 6.

0 Kudos
Altera_Forum
Honored Contributor II
967 Views

SigBQ1 is going high and staying high and then one clock later SigBQ2 is doing the same thing. so AND or XOR gate should generate the same result of one BClk wide pulse.

0 Kudos
Reply