- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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?
Ссылка скопирована
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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;
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
--- 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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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!- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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 ---- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.
- Отметить как новое
- Закладка
- Подписаться
- Отключить
- Подписка на RSS-канал
- Выделить
- Печать
- Сообщить о недопустимом содержимом
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.

- Подписка на RSS-канал
- Отметить тему как новую
- Отметить тему как прочитанную
- Выполнить отслеживание данной Тема для текущего пользователя
- Закладка
- Подписаться
- Страница в формате печати