Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Problem with hold timing violation

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

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.