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

Problem with hold timing violation

Altera_Forum
Honored Contributor II
1,451 Views

Hi all, 

 

I always a have a "timing not met" critical warning when compiling a VHDL module. I think the problem is restricted to this part of code, since the involved signal appears only here. 

 

signal rx_clk : std_logic; p_on: process(clk,sreset) begin if (sreset = '1') then run <= '0'; run2 <= '0'; elsif rising_edge(clk) then if (crs_intern = '0')and(crs_intern2 = '0')and(rx_clk = '0') then run <= '0'; elsif (crs_intern = '1')and(rxd_intern = "01") then run <= '1'; end if; if (rx_clk = '1') then run2 <= run; end if; end if; end process p_on; p_receive: process(clk,sreset) begin if (sreset = '1') then rx_clk <= '0'; low_rxd_intern <= "00"; out_rxd_intern <= "0000"; elsif rising_edge(clk) then if (run = '0')and(crs_intern = '1')and(rxd_intern = "01") then rx_clk <= '0'; else rx_clk <= not rx_clk; end if; if (rx_clk = '0') then low_rxd_intern <= rxd_intern2; end if; if (run = '0') then out_rxd_intern <= "0000"; else if (rx_clk = '1') then out_rxd_intern <= rxd_intern2 & low_rxd_intern; end if; end if; end if; end process p_receive; mac_RXD <= out_rxd_intern; mac_RX_CLK <= rx_clk;  

 

TimeQuest reports 2 hold viming violations. 

The reported failing path is the same for both (?), but the hold slack is usually different: i.e. -2.26ns and -2.44ns 

Launch clock: rx_clk falling edge 

From node: rx_clk|q 

Latch clock: clk rising edge 

To node: rx_clk|d 

clk frequency is 50MHz 

 

I can't understand why I get this error. Maybe is something evident for a VHDL expert, who I am not. 

In particular I can't understand why I have rx_clk falling edge as launch clock; I don't use this edge for sampling anything; all is synchronized to clk. 

Neither I can understand why I have 2 identical failing paths with different slacks. 

 

Regards 

Cris
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
258 Views

1) Two paths just means there is more than one combinatorial path. 

2) rx_clk is a clock. I don't see it in the code but it certainly is. 

3) rx_clk is also a data path, i.e. it feeds itself. This is known as clock-as-data, and is generally correct. Note that when your clock is data, both rising and falling edges are relevant, which is also correct. (An example would be sampling a slower clock into a faster clock). 

4) The question is if the analysis is correct. It's basically when a falling edge out of rx_clk|q wraps around and feeds back inot rx_clk|d and is clocked in by clk. I'm actually surprised this could be a hold violation. Breaking out the full path is probably necessary. Do you have a generated clock statement on rx_clk?
0 Kudos
Altera_Forum
Honored Contributor II
258 Views

Hi Rysc, 

You are right, rx_clk is a clock. It feeds an ethernet_mac. The code I posted comes from the MII to RMII converter. 

Please note that I never had problems with this design. It works perfectly, but I'm concerned about this timing warning. 

Initially I thought the problem was within the mac, but I tried to apply another rx clock to the mac (from a pll), but the timing violation was always exactly the same. 

In that case rx_clk wasn't used for anything at all outside the RMII converter: so I restricted the problem to those few lines of code you see above. 

 

I don't have a generated clock statement for rx_clk, but this one: 

create_clock -name {MAC_rx_clk} -period 40.000 -waveform { 0.000 20.000 } [get_registers {RMII*rx_clk}] 

Maybe this is the problem? Should I use create_generated_clock? 

I tried but I get a warning: Ignored assignment 

 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
258 Views

I tried again with create_generated_clock and the hold violation disappeared. 

I get the "Ignored assignment" warning when I use it in the command line. 

Now I inserted it in sdc file and it was eventually accepted. Is this correct? 

 

thank you again for you hints, Rysc 

 

 

Cris
0 Kudos
Altera_Forum
Honored Contributor II
258 Views

Yes. Having a create_clock assignment on a register basically means that clock "just appears" there. It's edge starts there at time 0. The clock for clk also starts at time 0, but has a long delay to rx_clk, and hence the large clock skew causes a hold violation. Making a generated clock that works is the best method. (And I never enter constraints in the console. Always put them in the .sdc. If you want to enter them via the GUI, open the .sdc in Quartus and go to Edit -> Insert Constraint). 

Now that the generated clock is correct, the delay to clock rx_clk is accounted for, the skew goes away, and it meets timing.
0 Kudos
Reply