cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
616 Views
Registered: ‎01-16-2020

How to fix Intra-clock path setup timing error

Jump to solution

Hi,

I get an intra-clock path setup timing error in the following path:

Intraclock.jpg

 

I am not experienced with the time constraints that I can play with, so I have been playing with the Constraints Wizard and tried many constraints that I've seen in the documentation 'Vivado design suite user guide - using constraints', such as set_multicycle_path, set_max_delay.... but with no luck. If I decrease the main_clk_wiz frequency I can get rid of the timing errors, but I actually need to increase even further for my application. I do not care about the path delay, as long as the outputs of the array 'Out_regs[*]' remain synchronized, so I believe it should be possible to relax the timing constraints somehow.

Among the timing constraints I've tried is this one:

set_max_delay -from [get_pins {main_i/AXI_output_register_0/U0/AXI_output_register_v1_0_S00_AXI_inst/slot_counter_reg[1]/C}] -to [get_pins {main_i/AXI_output_register_0/U0/AXI_output_register_v1_0_S00_AXI_inst/Out_regs[*].out_reg/output_reg/D}] 2.000

but it only worsens the slack on that path. So then I tried using a negative delay -2, it did not work either. However, swapping the -to and -from pins did work.... but I'm not sure why exactly.

Is this the proper approach? perhaps adding other time constraints, changing the VHDL code, adding pipelines... might be the solution. Please help.

best regards,

0 Kudos
1 Solution

Accepted Solutions
Highlighted
490 Views
Registered: ‎01-22-2015

Re: How to fix Intra-clock path setup timing error

Jump to solution

alejandro.diaztormo@ugent.be 

It is often math operations that limit the operation frequency maximum, FMAX, of our HDL – because math operations typically produce lots of combinational logic.

Sometimes, we can add registers around the math operation and synthesis will distribute the registers to breakup the long strings of combinational logic.  Using registers to breakup combinational logic is called pipelining and often leads to improved FMAX.  The VHDL below shows one way to add registers around your math operation for current_value_off_plus_on.

sl_on_p1 <= slot_mem_on(a);
sl_off_p1 <= slot_mem_off(a);
cv_p1 <= sl_on_p1 + sl_off_p1;
cv_p2 <= cv_p1;
current_value_off_plus_on <= cv_p2;


A tradeoff of pipelining is latency.  That is, your original code for the math operation executed in one clock cycle.  However, the pipelined version that I have shown takes four clock cycles.  Extra latency can lead to some unexpected results (synchronization problems), so you should always run simulation on your HDL after adding pipelining.

The pipelining I have shown for your math operation will cause sync problems for your VHDL.  That is, your original code calculated both current_value_off and current_value_off_plus_on in one clock cycle.  However, with pipelining of only current_value_off_plus_on, the two values are now calculated with a different number of clock cycles.  This means that when you use these two values later on to calculate (x,y,z) then current_value_off is derived from a different value of slot_counter than current_value_off_plus_on (ie. they will be out of sync with each other).   You can solve this problem by pipelining the assignment statement for current_value_off in the same way that we pipelined the assignment(math) statement for current_value_off_plus_on.  

There may be other sync problems with your code that are caused by pipelining.  Simulation will help you find them and you now have some idea how to solve them.

Cheers,
Mark

View solution in original post

6 Replies
Highlighted
Voyager
Voyager
609 Views
Registered: ‎06-28-2018

Re: How to fix Intra-clock path setup timing error

Jump to solution

Hi alejandro.diaztormo@ugent.be 

Carelessly constraining your design is not the right way to handle this situation. Add constraints only if the design requires them.

You need to pipeline the operations if you're planning to run this design at even higher frequencies.


Highlighted
606 Views
Registered: ‎01-16-2020

Re: How to fix Intra-clock path setup timing error

Jump to solution

Of course, I'm just trying lo learn. I've seen in other posts that pipelining is an option I just did not know how to implement that properly. I guess that means adding a register, so an assignment <= somewhere in the vhdl code. But I don't know where exactly. Could you please be a bit more specific? here is my code:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL;

entity output_register is
Generic(
slots : integer := 3;
num_bits : integer := 8;
REG_ADDR : integer := 0
);
Port(
addr : in unsigned(7 downto 0);
slot : in unsigned(1 downto 0); -- changed from 8 to 2!
slot_value_on : in unsigned(num_bits-1 downto 0); -- changed from 8 to 10 bits
slot_value_off : in unsigned(num_bits-1 downto 0); -- changed from 8 to 10 bits
slot_counter : in unsigned(1 downto 0); -- changed from 8 to 2!
value_counter : in unsigned(num_bits-1 downto 0); -- changed from 8 to 10 bits
clk : in STD_LOGIC;
output : out STD_LOGIC
);
end output_register;

architecture Behavioral of output_register is

type slot_arr is array (slots - 1 downto 0) of unsigned(num_bits-1 downto 0);

signal slot_mem_on : slot_arr := (others => (others => '0'));
signal slot_mem_off : slot_arr := (others => (others => '0'));
signal current_value_off : unsigned(num_bits-1 downto 0) := (others => '0');
signal current_value_off_plus_on : unsigned(num_bits-1 downto 0) := (others => '0');

begin

current_value_off <= slot_mem_off(to_integer(slot_counter));
current_value_off_plus_on <= slot_mem_on(to_integer(slot_counter)) + slot_mem_off(to_integer(slot_counter));

process(addr, slot, slot_value_on, slot_value_off)
begin
if (REG_ADDR = to_integer(addr)) then

slot_mem_on(to_integer(slot)) <= slot_value_on;
slot_mem_off(to_integer(slot)) <= slot_value_off;
end if;
end process;

process(clk)
begin
if rising_edge(clk) then
if (value_counter > current_value_off and value_counter <= current_value_off_plus_on) then
output <= '1';
else
output <= '0';
end if;

end if;
end process;

end Behavioral;

0 Kudos
Highlighted
562 Views
Registered: ‎01-22-2015

Re: How to fix Intra-clock path setup timing error

Jump to solution

alejandro.diaztormo@ugent.be 

The timing path you have highlighted has a long string of combinational logic - and the combined delay of this string is causing the timing failure.

As baltintop suggests, you need to pipeline (ie. add some registers into this chain of combinational logic). 

All of your code shown below is being implemented as combinational logic.

current_value_off <= slot_mem_off(to_integer(slot_counter));
current_value_off_plus_on <= slot_mem_on(to_integer(slot_counter)) + slot_mem_off(to_integer(slot_counter));

process(addr, slot, slot_value_on, slot_value_off)
begin
  if (REG_ADDR = to_integer(addr)) then
    slot_mem_on(to_integer(slot)) <= slot_value_on;
    slot_mem_off(to_integer(slot)) <= slot_value_off;
  end if;
end process;

Think about putting some (all) of this in a clocked process  (ie. one that uses "if rising_edge(clk)...").  This will add registers to your design and should help with timing analysis.

Mark

Highlighted
504 Views
Registered: ‎01-16-2020

Re: How to fix Intra-clock path setup timing error

Jump to solution

Thanks you so much, @baltintop and markg@prosensing.com

I've implemented pipelining in my code as suggested. I created intermediate signals to do so as much as possible (maybe I went too far? xD). The result is that the clock frequency could be increased from 150MHz to 220MHz while meeting time constraints, great!

However, now I wonder if I could be able to increase the clock frequency even further. If you think so, could you point me in the right direction?

process(clk)
begin

    if rising_edge(clk) then
        a <= to_integer(slot_counter);
            
        current_value_off  <= slot_mem_off(a);
        current_value_off_plus_on <= slot_mem_on(a) + slot_mem_off(a);

        b <= to_integer(addr);
        c <= to_integer(slot);
        aux_on <= slot_value_on;
        aux_off <= slot_value_off;
        if (REG_ADDR = b) then
                        
            slot_mem_on(c)  <= aux_on;
            slot_mem_off(c) <= aux_off;

        end if;
            
        x <= (value_counter > current_value_off);
        y <= (value_counter <= current_value_off_plus_on);
        z <= x and y;
            
        if (z) then
            output <= '1';
        else
            output <= '0';
        end if;

    end if;
end process;
0 Kudos
Highlighted
491 Views
Registered: ‎01-22-2015

Re: How to fix Intra-clock path setup timing error

Jump to solution

alejandro.diaztormo@ugent.be 

It is often math operations that limit the operation frequency maximum, FMAX, of our HDL – because math operations typically produce lots of combinational logic.

Sometimes, we can add registers around the math operation and synthesis will distribute the registers to breakup the long strings of combinational logic.  Using registers to breakup combinational logic is called pipelining and often leads to improved FMAX.  The VHDL below shows one way to add registers around your math operation for current_value_off_plus_on.

sl_on_p1 <= slot_mem_on(a);
sl_off_p1 <= slot_mem_off(a);
cv_p1 <= sl_on_p1 + sl_off_p1;
cv_p2 <= cv_p1;
current_value_off_plus_on <= cv_p2;


A tradeoff of pipelining is latency.  That is, your original code for the math operation executed in one clock cycle.  However, the pipelined version that I have shown takes four clock cycles.  Extra latency can lead to some unexpected results (synchronization problems), so you should always run simulation on your HDL after adding pipelining.

The pipelining I have shown for your math operation will cause sync problems for your VHDL.  That is, your original code calculated both current_value_off and current_value_off_plus_on in one clock cycle.  However, with pipelining of only current_value_off_plus_on, the two values are now calculated with a different number of clock cycles.  This means that when you use these two values later on to calculate (x,y,z) then current_value_off is derived from a different value of slot_counter than current_value_off_plus_on (ie. they will be out of sync with each other).   You can solve this problem by pipelining the assignment statement for current_value_off in the same way that we pipelined the assignment(math) statement for current_value_off_plus_on.  

There may be other sync problems with your code that are caused by pipelining.  Simulation will help you find them and you now have some idea how to solve them.

Cheers,
Mark

View solution in original post

Highlighted
293 Views
Registered: ‎01-16-2020

Re: How to fix Intra-clock path setup timing error

Jump to solution

I thought I was going too far with the pipelining, but you tell me to add more.... and it worked! With your advice I managed to increase the clock frequency from 220 to 240 MHz. 

Thanks so much for the advice,

0 Kudos