Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bidirectional 'inout' woes! How to connect

5,671 views
Skip to first unread message

benn

unread,
Jul 24, 2010, 1:50:11 AM7/24/10
to
I'm trying to wire a bidirectional pin to an intermediate wire that
then goes to a bidirectional port of a sub-module:

module top
(
inout biDirectionalPin
);

wire InternalSignal;
assign InternalSignal = biDirectionalPin; // assign biDirectionalPin
= InternalSignal;

innerModule innerModuleInstance
(
.bidirect_to_and_from_port ( InternalSignal );
);


Unfortunately, the synthesizer complains of an 'illegal directional
connection'. Of course it does work if I map the signal directly
(i.e. .bidirect_to_and_from_port ( biDirectionalPin ); )

However, how can this be done using an intermediate wire'? Since the
wire 'InternalSignal' is *ONLY* used to connect 2 bidirectional ports
together, I don't see why the synthesizer has a problem with it?

glen herrmannsfeldt

unread,
Jul 24, 2010, 7:09:20 AM7/24/10
to
benn <ben...@hotmail.com> wrote:
> I'm trying to wire a bidirectional pin to an intermediate wire that
> then goes to a bidirectional port of a sub-module:

(snip)


> wire InternalSignal;
> assign InternalSignal = biDirectionalPin; // assign biDirectionalPin
> = InternalSignal;

(snip)


> Unfortunately, the synthesizer complains of an 'illegal directional
> connection'. Of course it does work if I map the signal directly
> (i.e. .bidirect_to_and_from_port ( biDirectionalPin ); )

I believe that assign is directional, so it would seem to me
right that it should complain.

Well, you should be able to assign to a bidirectional signal, but
the assignment would be one directional, like connecting an input
to a bidirectional bus.

As far as I know, the verilog primitives include ones that can
do a bidirectional connection, but not assign. That is, ones
with names like tran. (I don't have my book here to look it up.)

-- glen

gabor

unread,
Jul 25, 2010, 6:14:22 PM7/25/10
to
On Jul 24, 7:09 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

I'm not sure you should bother with tran gates. I tried to do just
this
and found that it wasn't synthesizable, at least in FPGA's. If you're
doing ASIC design the tran gates are there, but then you're not really
creating a wire.

I usually do the intermediate wire to collect top level ports
into buses. I know I could do that at the port itself, but I like
the ports to match the schematic net names for automatic board-level
connectivity checks. In the end I just gave up and connected a
concatenation of port wires to the lower-level module like
.addr
{ADDR09,ADDR08,ADDR07,ADDR06,ADDR05,ADDR04,ADDR03,ADDR02,ADDR01,ADDR00}),

Not very pretty, especially with a 32-bit bus, but it gets the job
done.

Regards,
Gabor

glen herrmannsfeldt

unread,
Jul 25, 2010, 6:36:43 PM7/25/10
to
gabor <ga...@alacron.com> wrote:
(snip)

>> As far as I know, the verilog primitives include ones that can
>> do a bidirectional connection, but not assign.  That is, ones
>> with names like tran.  (I don't have my book here to look it up.)

> I'm not sure you should bother with tran gates. I tried to
> do just this and found that it wasn't synthesizable, at least
> in FPGA's. If you're doing ASIC design the tran gates are
> there, but then you're not really creating a wire.

I was trying to answer the question, not ask why.

As far as I know, the current FPGA tools can synthesize
internal tristate lines using MUX-like logic. The early FPGA
families did have true tristate internal logic, but now they
need to buffer the lines and need to know which way the
buffers go.



> I usually do the intermediate wire to collect top level ports
> into buses. I know I could do that at the port itself, but I like
> the ports to match the schematic net names for automatic board-level
> connectivity checks. In the end I just gave up and connected a
> concatenation of port wires to the lower-level module like
> .addr{ADDR09,ADDR08,ADDR07,ADDR06,ADDR05,ADDR04,ADDR03,ADDR02,
> ADDR01,ADDR00}), Not very pretty, especially with a 32-bit bus,
> but it gets the job done.

-- glen

Jonathan Bromley

unread,
Jul 27, 2010, 10:13:15 AM7/27/10
to
On Jul 24, 6:50 am, benn <benn...@hotmail.com> wrote:
> I'm trying to wire a bidirectional pin to an intermediate wire that
> then goes to a bidirectional port of a sub-module:
>
> module top
> (
>      inout biDirectionalPin
> );
>
> wire InternalSignal;
> assign InternalSignal = biDirectionalPin;  //  assign biDirectionalPin
> = InternalSignal;
>
> innerModule innerModuleInstance
> (
>      .bidirect_to_and_from_port ( InternalSignal );
> );


As already seen, you can't use assigns to do this.

Could you live with connecting the outer port directly to your inner
instance?

module top (inout bidiPin);
innerModule innerInst(.bidi_port(bidiPin));
endmodule

--
Jonathan Bromley

sh...@cadence.com

unread,
Aug 4, 2010, 9:25:57 PM8/4/10
to
On Jul 24, 1:50 am, benn <benn...@hotmail.com> wrote:
>
> However, how can this be done using an intermediate wire'?   Since the
> wire 'InternalSignal' is *ONLY* used to connect 2 bidirectional ports
> together, I don't see why the synthesizer has a problem with it?

Presumably because the assign has a direction. A value on
biDirectionalPin will get driven onto InternalSignal by the
assignment, but a value on InternalSignal won't get driven onto
biDirectionalPin by the assignment. And don't try to add a second
assignment the other direction, since that will lock up the values.
Two buffers connected front to back is not a bidirectional connection!

You could connect the two signals with a tran primitive, which is a
bidirectional connection. But I don't know what your synthesis tool
would do with that. Probably assume you are actually requesting some
kind of transistor there, and reject it.

The usual way of forcing two signals to be connected in a
bidirectional way is to use an "aliasing" module (sometimes called a
"via" module, like a via used to connect wires on different levels of
a chip). A simple example would be

module via (.a(w), .b(w));
inout w;
wire w;
endmodule

The two bidirectional ports a and b are internally connected to a
single wire. Then you can instantiate this to connect together two
wires:

via my_via(biDirectionalPin, InternalSignal);

This trick isn't obvious at all, but it works nicely. The use of
external names for the ports allows named connections instead, as in

via my_via(.a(biDirectionalPin), .b(InternalSignal));

Even less obvious is the fact that Verilog will allow you to declare
an aliasing module that doesn't have different external ports for the
name, as in:

module via (w, w);
inout w;
endmodule

Oddly, this works, even though the two ports have the same name. You
can't connect the ports using named connections, since they don't have
distinct names. But you can still connect them positionally.

glen herrmannsfeldt

unread,
Aug 4, 2010, 10:23:20 PM8/4/10
to
sh...@cadence.com wrote:
(snip)


> You could connect the two signals with a tran primitive, which is a
> bidirectional connection. But I don't know what your synthesis tool
> would do with that. Probably assume you are actually requesting some
> kind of transistor there, and reject it.

I don't have my verilog book close, but I believe that there is
a gated tran, which would be implemented as a pass transistor,
and an ungated one which would be more like a wire.

-- glen

gabor

unread,
Aug 5, 2010, 9:30:14 AM8/5/10
to

You mean tranif1 or tranif0 (gated) and tran (not gated). As I posted
before, at least Synplify for Lattice won't accept that. But it's
certainly worth a try.

Regards,
Gabor

0 new messages