Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
17268 Discussions

Problem with hold timing violation

Altera_Forum
Honored Contributor II
1,832 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
639 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
639 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
639 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
639 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