3
\$\begingroup\$

I have a doubt question. I know that I can use "inout ports" to connect to a pin, but can I use "inout ports" to connect internally 2 modules?

I'm asking this because I have written an SRAM controller and a HDL model of the SRAM, and I'm getting this error:

ERROR:Xst:528 - Multi-source in Unit <top> on signal <data_bus<0>>;
   this signal is connected to multiple drivers.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Very, very old FPGAs allowed this. Any parts (AFAIK) introduced since 1995 or so have not. \$\endgroup\$
    – The Photon
    Commented Oct 18, 2018 at 14:51

3 Answers 3

0
\$\begingroup\$

What you are trying to do is fine for simulation, but you should not be trying to synthesize your testbench.

\$\endgroup\$
5
  • \$\begingroup\$ one thing, why not ? \$\endgroup\$
    – user204415
    Commented Oct 18, 2018 at 11:49
  • \$\begingroup\$ Because then your testbench would have to comply with all of the rules imposed by the FPGA, which includes "no internal tristate buses". \$\endgroup\$
    – Dave Tweed
    Commented Oct 18, 2018 at 11:50
  • \$\begingroup\$ so, inout ports cannot be used to connect 2 modules, right? It only works to connect a module with the external pins, right? \$\endgroup\$
    – user204415
    Commented Oct 18, 2018 at 12:00
  • \$\begingroup\$ Yes, that's right. \$\endgroup\$
    – Dave Tweed
    Commented Oct 18, 2018 at 12:03
  • \$\begingroup\$ They're also used for power connections when doing physical design on an asic. My point is not that you should use them, but rather that many verilog features have specific purposes and are not there for general logic design use. \$\endgroup\$
    – Matt
    Commented Oct 27, 2019 at 20:18
0
\$\begingroup\$
ERROR:Xst:528 - Multi-source in Unit <top> on signal <data_bus<0>>;
this signal is connected to multiple drivers.

This message tells you that you have multiple outputs connected together at the same time. You must implement multiplexer and have some select signal (and optionally enable signal if output is expected to tristate - NOT in case for internal lines).

For bi-directional lines you implement two multiplexers, making one device being output and another device being input with single select signal. When it is high communication goes into one direction, when low - into another. If you have multiple devices on the internal bus, you just build up a select logic.

However do you really need internal bi-directional bus? Did you estimate if it is effective from performance and resource usage?

I suspect external inout pins are designed for pin economy purposes - thus already a kind of hardware optimization. By forcing your FPGA/CPLD internals the same hardware-optimized way you, probably, disable Verilog compiler optimization, which can be waaay better than inout scheme.

\$\endgroup\$
1
  • \$\begingroup\$ Can you show an example of how to connect 2 inout ports? What I'm trying to do is to connect an SRAM controller with an SRAM model. I just want to simulate the behaviour of the SRAM. \$\endgroup\$
    – user204415
    Commented Oct 18, 2018 at 14:38
0
\$\begingroup\$

An inout pin is really a combination of an in pin, and an out pin with an enable.

When you route that to an external pin, those are conveniently the signals that can be connected to the IO block.

For internal signals, you can generate demultiplexer tables that combine the data signals based on the enables. Before the optimizer, table outputs can have "invalid" entries that the optimizer can set to whatever it wants to reduce logic size.

In the trivial case, with a single driver, the table is

D E |
0 0 | -
0 1 | 0
1 0 | -
1 1 | 1

With two drivers, you get

D E  D E |
0 0  0 0 | -
0 0  0 1 | 0
0 0  1 0 | -
0 0  1 1 | 1
0 1  0 0 | 0
0 1  0 1 | 0
0 1  1 0 | 0
0 1  1 1 | -
1 0  0 0 | -
1 0  0 1 | 0
1 0  1 0 | -
1 0  1 1 | 1
1 1  0 0 | 1
1 1  0 1 | -
1 1  1 0 | 1
1 1  1 1 | 1

A possible optimization of this is to assume the second signal's enable is the inverse of the first, so every two rows in the table above collapse into one, with the "don't care" values replaced by the value from the other row. This substitution is valid because it was an invalid state before, and there are no 0/1 conflicts:

D E  D |
0 0  0 | 0
0 0  1 | 1
0 1  0 | 0
0 1  1 | 0
1 0  0 | 0
1 0  1 | 1
1 1  0 | 1
1 1  1 | 1

But, equally valid, we can collapse by removing the first enable signal:

D  D E |
0  0 0 | 0
0  0 1 | 0
0  1 0 | 0
0  1 1 | 1
1  0 0 | 1
1  0 1 | 0
1  1 0 | 1
1  1 1 | 1

The result for the valid states is the same, but it differs in the invalid states.

So: it is synthesizable, but you are heavily relying on the optimizer here, and it generates extra tables that consume resources, and that could be avoided by building directional ports between components.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.