Actual is not a globally static expression

V

valentin tihomirov

Guest
Here is example:
U: A_COMPONENT port map (A => A, B => not B);

I've learned for the newsgroup that on-the-fly conversion is not allowed. A
conversion function must be used instead, e.g. the following is compied ok:
port map (A => A, B => "not"(B));

Seems that the "not" function is defined in STD_LOGIC_1164 paclage in IEEE
library together with "and", "or" functions. However, the following cannot
be compiled:
port map (A => A, B => "and"(B, C));
port map (A => A, B => "not"(B and C));
 
Hi Valentin,

The reason is that conversion functions must have a specific signature.
They take only a single parameter of the appropriate type.

Actually, conversion functions were introduced in VHDL to
connect signals in port maps that are of different type.
They are not intended to introduce some kind of "embedded"
operations during signal association.
Hence, the conversion functions have only a single
parameter (the signal to be converted).

--
Edwin
 
Hence, the conversion functions have only a single
parameter (the signal to be converted).
Isn't expression

A and B

evaluated into a single parameter? Writing a special conversion function

CONVERT(i: std_logic) return std_logic;

cannot be used in the port map as well:

u1: CIRCUIT port map (a, b, CONVERT(a and b)) -- Actual is not a globally
static expression
 
valentin tihomirov wrote:
Hence, the conversion functions have only a single
parameter (the signal to be converted).


Isn't expression

A and B

evaluated into a single parameter? Writing a special conversion function

CONVERT(i: std_logic) return std_logic;

cannot be used in the port map as well:

u1: CIRCUIT port map (a, b, CONVERT(a and b)) -- Actual is not a globally
static expression
VHDL requires that formal (port signal of the instantiated
component) and actual are *both* signals. Port association is
just wiring together ports and signals. The conversion
function is a "trick" to change the *type* of the
signal "on-the-fly". However, the basic concept is still
to wire together a formal and an actual *signal*.

In VHDL >= 93 there is one exception: IN ports may be
associated with constant values (the value must be
computable at elaboration time). However, because
a and b are signals (I guess they are), expression
"CONVERT(a and b)" is not static.

So I assume that you compiler assumed that you want
to associate the port with an expression (and not
a signal) but finally discovered that the expression
is not constant... (i.e., I assume that you compiler
did not see any conversion function here).

In your previous example

port map (A => A, B => "not"(B));

the compiler actually assumed function "not" to be
a conversion function.


--
Edwin
 
In article <c0qfa4$19u4an$1@ID-212430.news.uni-berlin.de>,
valentin tihomirov <valentin_NOSPAM_NOWORMS@abelectron.com> wrote:
Hi Valentin,

The reason is that conversion functions must have a specific signature.
They take only a single parameter of the appropriate type.

Actually, conversion functions were introduced in VHDL to
connect signals in port maps that are of different type.
They are not intended to introduce some kind of "embedded"
operations during signal association.
Hence, the conversion functions have only a single
parameter (the signal to be converted).
Somewhat related to this, are conversion functions legal on both
input and output simultaneously?

e.g.

component foo
port(
A: inout type1
);
end component;

signal bar: type2;

U1: foo port map(
func1(A) => func2(bar)
);

The standard is not 100% clear if this is permissible, and what the
semantics ought to be.

I don't see anyone doing this in real life, as an inout port is
required, and therefore a resolved type is required, and the only
resolved type that we regularly use is std_logic[_vector], but...

- What is the required return type of func1? Must it be type2,
or can it be any type, as long as the return types of func1
and func2 are the same?

The semantics seem to infer that there are two separate data
transfer functions going on here, as if this were shorthand for:

U1: foo port map(
func1(A) => bar, -- data flows out of component
A => func2(bar) -- data flows into component
);

-- except for the fact that one can't bind a port twice.
 
"David Jones" <dej@coup.inode.org> wrote in message
news:_moYb.4085$d34.693944@news20.bellglobal.com...

[...]

are conversion functions legal on both
input and output simultaneously?

component foo
port(
A: inout type1
);
end component;

signal bar: type2;

U1: foo port map(
func1(A) => func2(bar)
);

The standard is not 100% clear if this is permissible, and what the
semantics ought to be.
This is definitely OK. func1 and func2 must have appropriate
overloads:

function func1[type1] return type2;
function func2[type2] return type1;

func1 converts output values from foo:A so that they can
be driven on to bar. func2 converts input values on bar
so that they can be driven on to foo:A.

I don't see anyone doing this in real life, as an inout port is
required, and therefore a resolved type is required, and the only
resolved type that we regularly use is std_logic[_vector], but...
I have to admit that I have never had cause to use it "in anger".

- What is the required return type of func1? Must it be type2,
or can it be any type, as long as the return types of func1
and func2 are the same?
nope; my description above, and yours below, describe the
correct situation.

The semantics seem to infer that there are two separate data
transfer functions going on here, as if this were shorthand for:

U1: foo port map(
func1(A) => bar, -- data flows out of component
A => func2(bar) -- data flows into component
);
Yes

-- except for the fact that one can't bind a port twice.
Indeed.

At one stage I thought that this application of functions
in both directions on an inout port binding might allow us
to model wires and bidirectional pass switches in VHDL, but
I don't now believe that it makes any difference.

One small point: In VHDL-93 and later, the "function" can
also be a type conversion between closely related types,
which isn't strictly a function but has the same syntactic
appearance. This, of course, is appropriate and good -
I don't want to have to write silly wrapper functions
merely to cast from unsigned to std_logic_vector across
a port map. Sadly, this idea doesn't extend to a "conversion
function" that has been implemented as a lookup in a table
of constants, even though array subscripting looks very much
like calling a monadic function. We look forward to VHDL-2012
in which we can overload both the function call and array
subscript operators... :)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
In article <c0t8eu$qfo$1$8300dec7@news.demon.co.uk>,
Jonathan Bromley <jonathan.bromley@doulos.com> wrote:
At one stage I thought that this application of functions
in both directions on an inout port binding might allow us
to model wires and bidirectional pass switches in VHDL, but
I don't now believe that it makes any difference.
Hmmm... that brings up another question: where are the semantics of
inout ports clearly described?

In Verilog, an inout port/connection is treated as if the internal and
external nets are connected with a "tran" object. Makes sense in
Verilog, but VHDL has no such thing.

LRM 12.6.2 doesn't make much sense to me at first reading, especially
in this scenario:

inout port, connecting nets FOO and BAR, type std_logic.

Initially FOO and BAR are 'Z'.

FOO changes to '1'. Now BAR sees a driver driving '1', and when
resolved with other drivers driving 'Z', works out to '1'.
So far so good.

Now FOO changes back to 'Z', or at least the driver that was driving
the '1' now drives a 'Z'. But in that delta, BAR is still '1', so
is the inout port still driving a '1' onto FOO?

The expected result is that everything will return to 'Z', but it's
not clear how this happens.
 
"David Jones" <dej@coup.inode.org> wrote in message
news:7KpYb.4532$d34.724750@news20.bellglobal.com...

Hmmm... that brings up another question: where are the semantics of
inout ports clearly described?
I'll check the LRM and find the relevant references when I
have a few moments. Somewhere in the discussion of drivers,
I think.

In Verilog, an inout port/connection is treated as if the internal and
external nets are connected with a "tran" object. Makes sense in
Verilog, but VHDL has no such thing.
In Verilog, unidirectional port connections have an implicit
continuous assignment across the port, no? And simulators
can choose to "port-collapse" by making the nets identical.

In VHDL, nets (signals) on either side of a port are effectively the
same net. All drivers are resolved together, on whichever side of
the port they reside; all "receivers" (processes that read the value
of the signal) see the same value at all times, regardless of which
side of the port they reside. This is pretty much the same
as a collapsed port connection in Verilog, I think. Collapsed
inout ports give the simulator less work to do than "tran"
primitives.

[Scenario...]
inout port, connecting nets FOO and BAR, type std_logic.
Initially FOO and BAR are 'Z'.

FOO changes to '1'. Now BAR sees a driver driving '1', and when
resolved with other drivers driving 'Z', works out to '1'.
FOO sees exactly the same.

So far so good.

Now FOO changes back to 'Z', or at least the driver that was driving
the '1' now drives a 'Z'. But in that delta, BAR is still '1', so
is the inout port still driving a '1' onto FOO?
No, certainly not. BAR has its drivers, whose value(s) are controlled
by processes on that side of the port, and those drivers continue
to drive Z just as they always did. The visible value of BAR drops
back to Z at EXACTLY the same time as does the visible value of FOO,
because they're the same.

Of course, if you were to build some kind of "keeper" circuit
on the BAR side, things would be different:

process (BAR)
begin
case BAR is
when '1' | 'H' => BAR <= 'H';
when '0' | 'L' => BAR <= 'L';
when others => BAR <= 'W';
end case;
end process;

In Verilog-speak that's (near enough)
assign (weak0, weak1) BAR = BAR;
You wouldn't expect to get that in Verilog without asking
for it; nor do you get it unexpectedly in VHDL.

The expected result is that everything will return to 'Z'
Just as well, really :)

Sorry if I sound a bit jaundiced about all of this. I'm
working hard today on getting a clear understanding of
SystemVerilog's scheduling model with its stratified
event queue of ELEVEN regions, and thinking to myself
how much clearer and simpler things are in VHDL.

--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: jonathan.bromley@doulos.com
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Welcome to EDABoard.com

Sponsor

Back
Top