01-20-2016 07:06 AM
I'm pretty new at this, and I'm not sure if this is the right section, so I appoligize if it doesn't fit here.
I have a design which looks like this:
And the mux's are only activate in a way that the path is either:
in -> circuit1 -> circuit2 -> out
in -> circuit2 -> circuit3 -> out
Is there a way to 'tell' this to vivado so that the timing and implementation will take this in to account when determining if I meet the timing constraints?
01-20-2016 07:45 AM
Look up how to use "set false path" constraints.
I will warn you that setting false paths can be tricky, and often not setting them at all results in a better place and route.
You could also pipeline the logic (add a register after each mux) which would allow it to go much faster without any fancy constraints. Adding pipeline registers may affect the function of your design, as you may have to add registers somewhere else to synchronize the resulting outputs (pipelining changes functionality, so it must be done carefully and verified that it still works the way you intended). Pipelining adds latency, but latency may not be a concern in your system.
01-20-2016 08:48 AM
I agree with @austin - the better solution is to find a way around having these complex combinatorial paths.
This kind of micro-architecting is usually not necessary.
When we design synchronous circuits using Register Transfer Languge (RTL), we define the registers explicitly, and the transfer functions between them behaviorally. We then let the tools convert the behavioral description of the transfer functions into gates. The tools attempt to do this while respecting our timing constraints - the most important of which is the clock period defined using the create_clock command.
Normally we don't care how the synthesis tool actually constructs the combinatorial logic - as long as it can meet timing, any structure is fine (the synthesis tools ensure that the functionality of the implemented gate level design matches that of the RTL). So we normally don't worry about false combinatorial paths in synchronous logic.
So - first - what are you trying to do here? Are you trying to design a purely combinatorial design (with no pipelining)? This can be done but is very rarely useful in an FPGA. Or does your design have flip-flops in it, and the "path" you are showing is the data flow, and not a true combinatorial path. If it is not a combinatorial path, then this is not a timing issue; the the tools will time each combinatorial path from flip-flop to flip-flop independently, regardless of the overall data flow.
However, if (for whatever case) this is a true combinatorial path and has the attributes you mention, then you can define a false path, but (as @austin said), it can be tricky.
The basic format of the command would be
set_false_path -through <point_a> -through <point_b>
set_false_path -through <point_a> -through <point_b> -through <point_c>
but choosing point_a, point_b (and point_c) can be difficult.
Your representation with the MUXes is fine conceptually, but may not actually exist after synthesis - remember, synthesis is doing all kinds of optimizations to make your circuit efficient. If the MUXes remain then
set_false_path -through [get_pins mux_a/I0] -through [get_pins mux_b/I0]
will work (assuming the first MUX is mux_a and the second is mux_b, and the I0 input is the top input).
But these MUXes may vanish - the FPGA may implement them in a LUT, potentially along with other logic. You can try and keep them by putting a DONT_TOUCH attribute on the net driving the inputs. This can be done in the RTL or in the .xdc file. With the DONT_TOUCH set, you could use
set_false_path -through [get_nets net_a] -through [get_nets net_b]
where net_a is connected to the I0 input to mux_a (and the same for b)
Alternatively, if you don't do this you may be able to use points in the hierarchy to define the false path. If (and this is essential for doing this), you set the synthesis option "flatten_hierarchy" to "none", then the inputs and outputs of your sub-modules will exist. Then you could use
set_false_path -through [get_pins circuit1/out] -through [get_pins circuit2/out] -through [get_pins circuit3/out]
This can all work, but will
a) interfere with the synthesis tools ability to optimize the logic and
b) can slow down your synthesis and implementation runs (make the tools run longer)
So, when possible, all of this should be avoided...
01-20-2016 01:48 PM
You don't show how the Muxes are controlled. Just by your description it would seem that both muxes would be controlled by a single select line. If you care about the mux switching time (changing paths when the select toggles) then don't do this, but you could ignore timing for the mux control. Theoretically using a common mux control should mean that Vivado could figure out that the worst case timing would not need to include all three of your "circuits."
01-20-2016 02:59 PM
Theoretically using a common mux control should mean that Vivado could figure out that the worst case timing would not need to include all three of your "circuits."
I am pretty sure that static timing analysis (STA) can't do this. In STA, only the static structure of the design is considered, not the functionality; the tool works only with propagation paths - it doesn't attempt to do any analysis of "blocked" paths due to mutually exclusive sub-paths. So, the tools will happily time through both MUXes even if the control has a common source - the path goes through circuits1, 2, and 3...
Of course, during synthesis, the functionality does matter; due to sharing and propagation, the reconvergent path may disappear - but it also might not (and it won't if hierarchy is preserved).
The only operation that would be able to understand the two cases like this is set_case_analysis, whereby the structure of the design is statically pruned (from the STA point of view). So you could do the analysis for case 1 (common MUX control=0) and again for case 2 (common MUX control=1), and get timing reports for both, but for implementation only one or the other can be considered using case analysis.