Re: [vhdl-200x] Minutes for VHDL-200X-FT meeting, San Jose Dec 4, 2003


Subject: Re: [vhdl-200x] Minutes for VHDL-200X-FT meeting, San Jose Dec 4, 2003
From: Matthias Wächter (matthias@waechter.wiz.at)
Date: Wed Dec 10 2003 - 05:49:54 PST


On Wed, 10 Dec 2003, Jonas Nilsson wrote:

> Hamish Moffatt wrote:
> > to_string seems to duplicate 'image to some extent; could 'image be
> > improved instead?
> I agree.
> Augmenting 'image to be a more universal attribute (not
> only an attribute on types) would be a big improvement.
>
> a'IMAGE would be much easier to use and understand than
> INTEGER'IMAGE(a). I give VHDL courses, and have seen this
> mistake made by students thousands of times. a'IMAGE
> is a very reasonable thing to try to do.

Sorry for sneaking in, I have not attended to the San Jose meeting and am
not a (voting) member, but I have some input to this one. I included some
general San Jose critics below as well.

Similarly to Jonas's input, it would be a great benefit to have access to
not only the base type of a type (using type'base or sub_type'base) but
also to the type of a variable/constant or signal. This would improve
object-oriented approaches and code re-use. Underlying ranges of the base
type can already be taken from signals, but not the base type itself.

For example:

--------------
-- always use constants...
constant VAR_WIDTH : natural := 8;

-- just to make things more clear, declare some basic subtypes
subtype RANGE_VAR is natural range VAR_WIDTH-1 downto 0;
subtype UTYPE_VAR is std_ulogic_vector(RANGE_VAR);

variable var: UTYPE_VAR;
variable var_mirror: var'base; -- <--- this produces an error
variable var_via_range : std_ulogic_vector(var'range); -- <-- this works
--------------

Of course, if var and var_mirror are declared in subsequent lines like in
the given example, referring to the type of var is not of much use, but
assume in a block you have to declare additional variables or signals
based on the type given in the main architecture, or even better, given on
the entity using generics, then you have to know the type of var instead
of defining "a variable/signal that has the same type as var".

Additionally, what I'd like to see in VHDL and what should be no big deal
is a way of using ranges in aggregate assignments - the only range that
can be used is the term 'others'. For example (sorry for the excessive use
of subtypes/ranges):

--------------
constant SIG_WIDTH : natural := 9;
constant NIBBLE_WIDTH : natural := 4;

subtype RANGE_SIG is natural range SIG_WIDTH-1 downto 0;
subtype RANGE_NIBBLE is natural range NIBBLE_WIDTH-1 downto 0;
subtype RANGE_SIG_LOWNIBBLE is natural range
  RANGE_SIG'low+NIBBLE_WIDTH-1 downto RANGE_SIG'low;
subtype RANGE_SIG_HIGHNIBBLE is natural range
  RANGE_SIG_LOWNIBBLE'high+NIBBLE_WIDTH downto RANGE_SIG_LOWNIBBLE'high+1;
constant RANGE_SIG_PARITY: natural :=
  RANGE_SIG_HIGHNIBBLE'high+1;

subtype UTYPE_SIG is std_ulogic_vector(RANGE_SIG);
subtype UTYPE_NIBBLE is std_ulogic_vector(RANGE_NIBBLE);
subtype UTYPE_PARITY is std_ulogic;

signal sig: UTYPE_SIG;
signal nibble_high, nibble_low : UTYPE_NIBBLE;
signal parity : UTYPE_PARITY;

...

  -- the following gives an error (only the RANGE_SIG_PARITY works)

  sig <= (RANGE_SIG_HIGHNIBBLE => nibble_high,
          RANGE_SIG_LOWNIBBLE => nibble_low,
          RANGE_SIG_PARITY => parity,
          others => '0');

  -- the following works but is unnecessarily verbose (currently used)

  P_SIG: process(nibble_high, nibble_low, parity)
  begin
    sig <= (others => '0');
    sig(RANGE_SIG_HIGHNIBBLE) <= nibble_high;
    sig(RANGE_SIG_LOWNIBBLE) <= nibble_low;
    sig(RANGE_SIG_PARITY) <= parity;
  end process P_SIG;

  -- the following works but implies local knowledge of the precise layout
  -- of the signal and will be broken code when ranges or positions
  -- change, so deprecated for reusable code

  sig <= parity & nibble_high & nibble_low;

--------------

In general, what's missing (and may be a big deal) in VHDL for more
sophisticated object-oriented approaches is type passing for functions and
generics (component instantiation) as well as the requirement for the
simulation tool to make delta cycles visible for making data flow over
software interfaces visible; But I think that we cannot discuss this topic
just as a reply to the discussion about the San Jose meeting, I'm a little
bit off-topic already :-)

==============================================================

My opinion about the San Jose paper in general:

What I very much appreciate about the proposal is the introduction of
combining direction information and records at the entity level,
although type generics (see above) are missing that could improve this a
lot. But let's start with the direction records and continue afterwards.
Btw, using direction records and Signal Spy has some interesting
implications on whether driver or spy is used on such a record.
Additionally, there are a lot of issues about support for records in the
tools, so I expect a lot of tool iterations when this new feature is
frequently used.

Second, adding Signal Spy as a VHDL feature is very much appreciated, it's
used at our side already, and having it tool vendor independent in the
future is very good. However, I think that actually _using_ Signal Spy
breaks a feature that makes VHDL superior over Verilog: Guaranteed
encapsulation. For applications where this has to be assured, maybe a tool
switch or a configuration ("for my_component feature
signal_spy(unit_no_driver, input_no_driver, unit_no_spy); end for;")
statement can make assure that Signal Spy is _not_ used in special
hierarchy levels or compilation/design loading will stop with an error
otherwise. Note that, given the example above, for failure-free testing,
spying into a component may be allowed, but no spy/driver usage within the
unit (and all sub-units). For testing of failures, also driving into the
unit may be given as a configuration feature for a different
configuration. If someone agrees here, this has to be worked out in a
better way, it's just a rough statement here.

Another word to Signal Spy: Please add a way of 'relative' addressing,
like with file system pathes that can be addressed relative to the current
one using '..'. Otherwise you have to write a lot of function or pass a
lot of generics to get from one branch of the tree to another one.

Another word about ternary operators: Why write

AReg <= A when rising_edge(Clk);

and not

AReg <= A when rising_edge(Clk) else AReg;

This would not be much overhead but would specify all pathes
unambiguously. And, I _don't_ like the

AReg <= A if rising_edge(Clk);

approach, I agree that this is already implemented well with 'when', and
differentiating between the always-when meaning 'when' and the
situation-if meaning 'if' is a major step to understanding the
parallelisms in VHDL concurrent statements versus the sequential
statements within procedures, functions and processes.

Finally, I don't like Boolean Equivalence. The designer should clearly
state what he wants and not let the tool guess. Being a little bit more
verbose clears the issue whether A='1', (A='1' or A='H') or nA='0' is
meant. If someone wants to use a signal as a boolean, then he has to
declare it as a boolean (of course, then all the cool std_logic stuff like
'X', 'L', 'H' is lost).

Thanks for reading,

Yours,
- Matthias Waechter
TTChip Entwicklungs-GesmbH
Vienna, Austria
www.ttchip.com

-- 
                    "To get control over people, make them trust you.
                                            To make people trust you
                      don't try to tell them the truth about history
                 but make happen what you told them about the future."



This archive was generated by hypermail 2b28 : Wed Dec 10 2003 - 05:52:23 PST