[comp.lang.vhdl] Overloading signal assignments

george@ole.UUCP (George Lippincott) (06/06/91)

   VHDL allows overloading of arithmetic and logic operators, but not the
assignment operator.  It seems like the ability to overload these operators
would be a useful feature.  This would allow automatic type-conversion
between various signal or variable types.  This would solve several problems
that I am running in to.  For example, say I am trying to write a behavioral
model for an n-bit wide flip-flop with a clear option.  To perform the clear
operation, I would like to say  Q <= "0";.   Unfortunately, the width of Q is
passed in using a generic and I don't think there is any way to control the
width of a literal.  If I could overload the "<=" operator I could use an
assignment function that automatically determined the width of the signal on
the left side and assigned a value to each bit. 
   Another place this comes up is if I write arithmetic functions that operate
on bit vectors or multi-valued-logic vectors.  Consider the following equation:

        sum <= A + B + cin 

   I have to somehow determine how many bits to return from the "+" operation
and this has to match the number of bits in sum.  If I could override the
"<=" operator, I could do sign-extension, truncation, or whatever is necessary
to make the number of bits match up.

   This seems like something that would be as easy to implement as any of the
other overloading.  Perhaps someone can comment on why this is not the case.

ward@rtpark.rtp.semi.harris.com (06/10/91)

NOTE:

I am posting this for Paul Menchini.  Direct any e-mail to the addresses below.
================================================================================
In message  <1988@ole.UUCP>, dated: 6 Jun 91 00:34:28 GMT, George Lippincott
(george@ole.UUCP) writes:

>    VHDL allows overloading of arithmetic and logic operators, but not the
> assignment operator.  It seems like the ability to overload these operators
> would be a useful feature.  This would allow automatic type-conversion
> between various signal or variable types.  This would solve several problems
> that I am running in to.  For example, say I am trying to write a behavioral
> model for an n-bit wide flip-flop with a clear option.  To perform the clear
> operation, I would like to say  Q <= "0";.   Unfortunately, the width of Q is
> passed in using a generic and I don't think there is any way to control the
> width of a literal.  If I could overload the "<=" operator I could use an
> assignment function that automatically determined the width of the signal on
> the left side and assigned a value to each bit. 
>    Another place this comes up is if I write arithmetic functions that operate
> on bit vectors or multi-valued-logic vectors.  Consider the following equation:
>
>         sum <= A + B + cin 
>
>    I have to somehow determine how many bits to return from the "+" operation
> and this has to match the number of bits in sum.  If I could override the
> "<=" operator, I could do sign-extension, truncation, or whatever is necessary
> to make the number of bits match up.
>
>    This seems like something that would be as easy to implement as any of the
> other overloading.  Perhaps someone can comment on why this is not the case.

Be happy to.  On the language level, the assignment "operator" (plural,
actually; there are separate symbols for signal and variable assignment) are
not operators at all.  VHDL, unlike C and some other languages, is not an
expression language; i.e., A := B := C is not legal because "B := C" is not an
expression.

Nevertheless, we could conceivably extend the notion of "operator overloading"
to allow the overloading of the symbols "<=", and ":=".  The overloading would
presumably have to occur through the use of procedures, not functions:

	procedure ":=" (variable Target: out Bit; Source: in Boolean);

This is reasonably straightforward for variable assignment (as illustrated).
However, what about signal assignment?  Even restricting ourselves to just the
simple case (e.g., "A <= B after 1 ns;"), you have to have two components to
the source, a value and a time; moreover, you can have multiple waveform
elements: "A <= B after 1 ns, C after 2 ns, D after 3 ns, ...;".  This of
course could be solved with unconstrained arrays:

	type value_array is array (Natural range <>) of Integer;
	type time_array  is array (Natural range <>) of Time;
	procedure "<=" (signal Target: out Integer;
			Source_Value: value_array;
			Source_Time:  time_array);

But, you must enforce several conditions: Source_Value'Length =
Source_Time'Length; Source_Time(i) >= 0 ns, for all i in Source_Time'Range;
Source_Time(n1) < Source_Time (n2) for all n1 < n2.  Where will this be
enforced?  In the procedure (which will then be impossible to check) or
outside?  This approach adds a lot of compications to the language, both for
implementors and to users.

We also have to consider waveform editing, which is how VHDL implements
inertial delay.  The language would have to make the drivers accessible in
order to allow the procedure to edit the waveforms.  Consider your colleagues
on the synthesis side, who would have to synthesize the arbitrary things you
could do inside of these procedures (wait statements, calling other procedures,
etc.)

On the whole, this approach has the flavor of killing flies with dynamite.
Your application, (automatic type conversion) is easily handled with VHDL's
existing features. (Well, almost.  The "automatic" part really isn't, because
it is antithetical to VHDL's philosophy.  But VHDL has two flavors of explicit
type conversion, which can be used in expressions and in association lists,
automatic subtype conversion, as well as other features to aid data type
conversion.)  To work your examples:

> ... say I am trying to write a behavioral
> model for an n-bit wide flip-flop with a clear option.  To perform the clear
> operation, I would like to say  Q <= "0";.   Unfortunately, the width of Q is
> passed in using a generic and I don't think there is any way to control the
> width of a literal.

Specifically, let us assume that the interface is something approximating:

	entity DFF is
	  port (D:   in  Bit_Vector;
		Clk: in  Bit;
		Pre: in  Bit;
		Clr: in  Bit;
		Q:   out Bit_Vector;

The problem is how to drive Q when you don't know how wide it is, but do know
that it has a definite width.  Easy, use an aggregate:

	Q <= (others => '0');

>    Another place this comes up is if I write arithmetic functions that operate
> on bit vectors or multi-valued-logic vectors.  Consider the following equation:
>
>         sum <= A + B + cin 
>
>    I have to somehow determine how many bits to return from the "+" operation
> and this has to match the number of bits in sum.  If I could override the
> "<=" operator, I could do sign-extension, truncation, or whatever is necessary
> to make the number of bits match up.

There's no need to do this calculation dynamically, as it's statically
determinable.  "A + B" *must* return max (A'Length, B'Length) + 1 bits
(assuming some standard representation, such as two's complement); there's no
choice.  Therefore if sum isn't exactly max (A'Length, B'Length, Cin'Length) +
1 bits wide, you must extend or truncate.  Define L = max (A'Length, B'Length,
Cin'Length) + 1, and assume that Sum is defined with an ascending range and
that Sum'Left = 1.  If sum must be extended,

	Sum (Sum'Right-L+1 to Sum'Right) <= A + B + Cin;
	Sum (Sum'Left to Sum'Right-L)    <= (others => Sum (Sum'Right-L+1));

will do the trick.  To truncate:

	Sum <= "+" (A + B, Cin)(L-Sum'Length to L);

I know that this looks complex, but these are exactly the computations you'd
have to make inside of the procedure, and they'd occur dynamically, not
statically, so your simulations would be slower.

Besides, many people complain that the language is already too complex.
Imagine how they'd feel about this! (;-)

>    This seems like something that would be as easy to implement as any of the
> other overloading.

Hopefully I've showed that this is not the case.

--Paul J. Menchini
  Principal Scientist
  CLSI Solutions

Internet: mench@clsi.com
	  mench%clsi.com@uunet.uu.net	(if "mench@clsi.com" doesn't work)
	  menchin@elmo.el.wpafb.af.mil
uucp:	  ...!uunet!clsi!mench
US Mail:  CLSI Solutions
	  P.O. Box 13036
	  Research Triangle Park, NC  27709-3036
	  USA
Voice:	  +1 919-361-1913
FAX:	  +1 919-361-2642

"If an undetectable error occurs, the processor continues as if no error had
occurred." -- IBM S/360 Principles of Operation

"The base type of a type mark is, by definition, the base type of the type or
subtype denoted by the type mark."  -- IEEE Std. 1076-1987