bidirectional 'inout' woes! How to connect

B

benn

Guest
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?
 
benn <benn686@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
 
On Jul 24, 7:09 am, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
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:

(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
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
 
gabor <gabor@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
 
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
 
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.
 
sharp@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
 
On Aug 4, 10:23 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
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
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
 

Welcome to EDABoard.com

Sponsor

Back
Top