09-21-2015 01:50 PM
I'm working on a Zynq design that contains 2 fully independent 32-bit Legacy PCI devices that need to be connected to a shared Address/Data bus. Both have fully implemented IO buffering and have high-z outputs when they are not active (see image).
The problem is, Vivado chokes during implementation due to multi-driver net errors. Yes, there are multiple devices that could in theory drive the bus simultaneously. This won't ever happen, because PCI devices only speak when spoken to, and the arbiter (not in my part of the design) ensures that only one device is driving the bus at a time.
Can I somehow suppress these errors? Or is there a deeper reason why Vivado doesn't allow mutiple devices with tri-state capable IO to share a bus?
09-23-2015 06:10 PM
There are no internal tristates in any modern Xilinx FPGA - the OBUFT is purely an output buffer which drives only an output pin. So this is not a warning to be supressed, but is an architectural error.
Some versions of the tool were able to convert internal tristate busses that are free of contention to multiplexed busses, but you are at the mercy of the tool as to whether it properly recognizes the structure and converts it. I don't know how good Vivado synthesis at this... Also, the tristates have to be implemented behaviorally, not through instantiations of OBUFT for this to even have a chance of working.
The "right" way to fix this is to change the RTL code to eliminate the internal tristate and implement a multiplexer at the top level of the design. If you bring out the value and enables from both blocks it is fairly easy to combine these together to generate the MUX
assign out = en1 ? out1 : out2;
10-05-2015 05:24 AM
I agree with avrumw. You can't expect that tool will allow connection of two IOBUFs to one signal/wire.
A note to three-state logic inside FPGA:
We were using a lot of three-state logic _inside_ our designs (local internal bus for internal control registers). It worked in ISE and Vivado with no problem. The synthesis simulates three-state logic by wired-OR or wired-AND behavior. The synthesis process does not analyze conflicts. It just combines all outputs with their enables into one final signal which is then fed to all connected inputs. In ISE it is possible to select which one behavior (AND or OR) via undocumented attribute tristate2logic_pullup set to "yes" or "no" connected to the bus wire.
Unfortunately since Vivado 2015_1 something in synthesis is broken. The tool generates correct RTL logic (with RTL_TRISTATE buffers) as expected. During synthesis some combinations of three-state logic are translated to multiplexers but _some_ other combinations are translated a wrong way. The synthesis process forgets to add (multiplexing) logic and connects LUT6 outputs directly together which a short circuit ([Synth8-3352] multi-driven net critical warning). During implementation the process fails with [Opt31-37] Multi-driven net found error.
I hope it will be corrected in future.