03-01-2013 02:44 AM
I have a design with several processes which looks like this one:
if (rising_edge(clkDiv16384)) then
if (GlobalResetSel='1') then
medDSP_par_ref_level <= (others => '0');
medDSP_par_ref_level <= syn_inp_tmp;
end if;--global reset
clkDiv16384 is NOT a dived clock but just another name for my global 50MHz clock. The GlobalEnable16384 is a CE signal which is high for one clock period every 16384 clock cycle. This implies that I have a multi_cycle path of 16384 cycles but I am unable to generate a timing constraint which works for my case.
I would like to have a constraint which only involes the GlobalEnable16384, as the signal is used for several nets throughout the design.
To re-write the vhdl-code is not an option.
I am using the Vivado 2012.4 and I am not really used to the new xdc syntax.
Any help would be appreciated.
03-02-2013 05:43 AM
Here is the constraint in Vivado
set mcp_ffs [all_fanout -only_cells -startpoints_only -flat [get_nets GlobalEnable16384]]
set_multicycle_path -from $mcp_ffs -to $mcp_ffs 16384
set_multicycle_path -from $mcp_ffs -to $mcp_ffs -hold 16383
The first line identifies all the clocked elements anywhere in the design that are combinatorially reachable from the specified net. The next two declare the MCP.
BUT there is a risk with doing this (in Vivado as well as in ISE). Whenever synthesis is involved, you can never actually predict the construction of the circuits. The all_fanout will definitely capture all the FFs that use the enable signal, but there is also a risk that it may include some unintended endpoints. For example lets consider this (relatively sloppy) generation of the GlobalEnable16384
always @(posedge clk) if (counter == 16383) counter <= 0; else counter <= counter + 1; assign GlobalEnable16384 = (counter == 16383);
In this case, the synthesis tool may internally share the "counter == 16383" term. As a result, the all_fanout will include the "counter" flip-flops. Thus, the paths from to and from the "counter" FFs will also be declared multicycle, which they most certainly are not.
This can still occur even if the generation of the GlobalEnable16384 is done in a submodule, but the net identified for the all_fanout is outside this module - a net is a net, and the all_fanout will find elements even if they are inside a module which looks to be "upstream" from the net specified in the all_fanout.
This problem has always existed - the same thing occurs if you use a TNM on the GlobalEnable16384 net in UCF. Most people are unaware of it, but it can lead to incorrect results (I have seen it).
If you are going to rely on this, then you are going to have to be very careful in the generation of the GlobalEnable16384. Make sure the tool cannot use this net for anything else, including the generation of itself. Making sure that it comes directly from a FF, and that the FF cannot be shared with any other logic is a start - I am not certain if there is a foolproof methodology to ensure that this doesn't happen (and as a result I don't advocate using this kind of structure).