- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page