Verilog2001/SystemVerilog Generic Functions

A

Amal

Guest
How does one code the following VHDL function snippet, in Verilog2001/
SystemVerilog?

function mult( a : std_logic_vector; b : std_logic_vector )
return std_logic_vector is
variable result : std_logic_vector(a'length+b'length downto 0);
begin
result := a * b;
return result;
end function mult;

I thought of doing it this way first:

function bit[] mult( const bit [] a, const bit [] b )
bit [a.size+b.size:0] result;

result = a * b;
return result;
endfunction : mult;

But apparently this does not work!

Better yet, I do not think there is function overloading in
Verilog2001/SystemVerilog, then how can I define another function with
different arguments with the same name?

function mult( a : std_logic_vector; b : integer ) return
std_logic_vector;

I though Verilog/SystemVerilog added VHDL features that were missing!
It is a pity if these are not available. I might not be aware of how
to do the same thing in Verilog/SystemVerilog. It should be pretty
simple to do these simple things for Verilog2001/SystemVerilog fluent
coders hopefully. ;)

Cheers,
-- Amal
 
On Wed, 26 Mar 2008 13:43:02 -0700 (PDT), Amal wrote:

How does one code the following VHDL function snippet, in Verilog2001/
SystemVerilog?
Distant sounds of manic laughter.....

function mult( a : std_logic_vector; b : std_logic_vector )
return std_logic_vector is
variable result : std_logic_vector(a'length+b'length downto 0);
begin
result := a * b;
return result;
end function mult;
You can't. SystemVerilog has dynamic arrays and queues,
but nothing that works the same way as VHDL unconstrained
arrays; and the bit width of any arithmetic expression in
Verilog must be determined at elaboration time, whereas
in VHDL the subtype (bit width, for vectors) of an
expression is determined dynamically.

I thought of doing it this way first:

function bit[] mult( const bit [] a, const bit [] b )
bit [a.size+b.size:0] result;

result = a * b;
return result;
endfunction : mult;

But apparently this does not work!
Indeed it does not.

Better yet, I do not think there is function overloading in
Verilog2001/SystemVerilog
That isn't exactly true. SystemVerilog allows you to overload
the arithmetic operators for new data types, although there
is no overloading of user-defined functions or of class
methods. However, I'm not aware of any commercially
available tool that supports operator overloading just now.

function mult( a : std_logic_vector; b : integer ) return
std_logic_vector;
But in Verilog you would never need to do this, since
any integral type can participate in any arithmetic
expression without further ado (although there are
complex and arcane rules for determining the bit width
of the result).

I though Verilog/SystemVerilog added VHDL features that were missing!
It is a pity if these are not available. I might not be aware of how
to do the same thing in Verilog/SystemVerilog. It should be pretty
simple to do these simple things for Verilog2001/SystemVerilog fluent
coders hopefully. ;)
It's a bit like the old joke about asking for directions in a
foreign country, and being told "if you want to get there,
I wouldn't start from here". One-to-one mapping of VHDL
constructs on to SystemVerilog is doomed to failure, but
it's usually possible to find ways to get the desired result.
And, of course, SystemVerilog has some tricks up its sleeves
that VHDL lacks.

My personal opinion, for what little it's worth: SystemVerilog
has spectacularly improved Verilog's expressive power for RTL
design, overtaking VHDL in a few areas for the first time.
But it's in the verification arena where the vast new feature
set of SystemVerilog really makes a difference. For ordinary
everyday RTL coding, VHDL remains my language of choice because
of the flexibility and opportunities for re-use that it gives
through exactly the features you mention: function overloading,
and unconstrained ports and arguments. Others would profoundly
disagree, pointing to Verilog's conciseness, its preprocessor,
and a few useful constructs like "casez".
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mar 27, 7:28 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Wed, 26 Mar 2008 13:43:02 -0700 (PDT), Amal wrote:
How does one code the following VHDL function snippet, in Verilog2001/
SystemVerilog?

Distant sounds of manic laughter.....

function mult( a : std_logic_vector; b : std_logic_vector )
return std_logic_vector is
variable result : std_logic_vector(a'length+b'length downto 0);
begin
result := a * b;
return result;
end function mult;

You can't. SystemVerilog has dynamic arrays and queues,
but nothing that works the same way as VHDL unconstrained
arrays; and the bit width of any arithmetic expression in
Verilog must be determined at elaboration time, whereas
in VHDL the subtype (bit width, for vectors) of an
expression is determined dynamically.

I thought of doing it this way first:

function bit[] mult( const bit [] a, const bit [] b )
bit [a.size+b.size:0] result;

result = a * b;
return result;
endfunction : mult;

But apparently this does not work!

Indeed it does not.

Better yet, I do not think there is function overloading in
Verilog2001/SystemVerilog

That isn't exactly true. SystemVerilog allows you to overload
the arithmetic operators for new data types, although there
is no overloading of user-defined functions or of class
methods. However, I'm not aware of any commercially
available tool that supports operator overloading just now.

function mult( a : std_logic_vector; b : integer ) return
std_logic_vector;

But in Verilog you would never need to do this, since
any integral type can participate in any arithmetic
expression without further ado (although there are
complex and arcane rules for determining the bit width
of the result).

I though Verilog/SystemVerilog added VHDL features that were missing!
It is a pity if these are not available. I might not be aware of how
to do the same thing in Verilog/SystemVerilog. It should be pretty
simple to do these simple things for Verilog2001/SystemVerilog fluent
coders hopefully. ;)

It's a bit like the old joke about asking for directions in a
foreign country, and being told "if you want to get there,
I wouldn't start from here". One-to-one mapping of VHDL
constructs on to SystemVerilog is doomed to failure, but
it's usually possible to find ways to get the desired result.
And, of course, SystemVerilog has some tricks up its sleeves
that VHDL lacks.

My personal opinion, for what little it's worth: SystemVerilog
has spectacularly improved Verilog's expressive power for RTL
design, overtaking VHDL in a few areas for the first time.
But it's in the verification arena where the vast new feature
set of SystemVerilog really makes a difference. For ordinary
everyday RTL coding, VHDL remains my language of choice because
of the flexibility and opportunities for re-use that it gives
through exactly the features you mention: function overloading,
and unconstrained ports and arguments. Others would profoundly
disagree, pointing to Verilog's conciseness, its preprocessor,
and a few useful constructs like "casez".
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

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

VHDL's unconstrained arrays/records, function/operator overloading and
the new package generics do wonders for reuse.

And yes, I think, after many years of coding in Verilog and VHDL, I
started to look at SystemVerilog for both design and Verification.
Well, the big buzz and big push from different people was that
Verilog2001 brought synthesis/design aspects that were missing in
Verilog1995 from VHDL 1993. I beg to differ now and I wish that
wasn't the case.

SystemVerilog has great features that I like a lot., Interfaces,
packages and parameterized classes. Correct me if I am wrong, but
classes are not synthesizable. Well, if they were, I could get away
from using unconstrained arrays and functions overloading and using
parameterized classes to do the same thing. Function/operator
overloading, unconstrained arrays and functions using them do wonders
in many different areas. I hate to not have these in SystemVerilog.
I hear from many Verilog designers that overloading confuses them and
hides details. I can say that is the purpose and how classes came
about to show up in SystemVerilog. Abstraction, data hiding, and
polymorphism. All these concepts have been used by software people
for so many years now and now digital designers and verification
people are becoming more familiar with this.

I am a great proponent of reuse. Whether reuse in design, or reuse in
testbench modules. I agree that SystemVerilog added many great
features for verification that VHDL needs a lot to catch up. But as
you mentioned, I think even though VHDL is still missing a few nice
aspects of SystemVerilog RTL subset, but it is superior to either
Verilog2001 or SystemVerlog.

Not that I want to start language wars again. Although, I am multi-
lingual, but I would rather stick with one language. And I thought
that was the philosophy of SystemVerilog from the beginning. To bring
up the level of abstraction of the gate-level Verilog to VHDL and even
higher to testbench constructs.

Well, I hope these features and other RTL subsets present in VHDL,
would someday be added to SystemVerilog.
-- Amal
 
On Thu, 27 Mar 2008 21:45:31 -0700 (PDT), Amal wrote:

classes are not synthesizable.
True, as far as I know.

Well, if they were, I could get away
from using unconstrained arrays and functions overloading and using
parameterized classes to do the same thing. Function/operator
overloading, unconstrained arrays and functions using them do wonders
in many different areas. I hate to not have these in SystemVerilog.
Yes, but we *do* have type parameters in SV. Type-parameterized
modules are a great innovation, and provide a different route
to flexibility. They should be OK for synthesis (providing, of
course, that the logic you write in your parameterized module is
itself synthesisable).

I hear from many Verilog designers that overloading confuses them and
hides details.
Sure. But assembler-code programmers used to complain that
compilers hide too many details. Happily, you don't get
very many programmers saying that sort of thing today.
The dinosaurs who insist on designing at, or close to,
the gate level in Verilog are well on the way to extinction.
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Mar 28, 5:56 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Thu, 27 Mar 2008 21:45:31 -0700 (PDT), Amal wrote:
classes are not synthesizable.

True, as far as I know.

Well, if they were, I could get away
from using unconstrained arrays and functions overloading and using
parameterized classes to do the same thing. Function/operator
overloading, unconstrained arrays and functions using them do wonders
in many different areas. I hate to not have these in SystemVerilog.

Yes, but we *do* have type parameters in SV. Type-parameterized
modules are a great innovation, and provide a different route
to flexibility. They should be OK for synthesis (providing, of
course, that the logic you write in your parameterized module is
itself synthesisable).

I hear from many Verilog designers that overloading confuses them and
hides details.

Sure. But assembler-code programmers used to complain that
compilers hide too many details. Happily, you don't get
very many programmers saying that sort of thing today.
The dinosaurs who insist on designing at, or close to,
the gate level in Verilog are well on the way to extinction.
--
Jonathan Bromley, Consultant

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

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
I have a generic crc_generator package that I created a while ago to
do any CRC calculation with any polynomial specified and any number of
bits with various options for initial values, final adjustments and
all the bells and whistles that one can think of. It has successfully
been used one various projects and I always keep adding features. It
is fully synthesizable and can also be used for simulation off course.

The other day, I tried to rewrite it in SystemVerilog for an exercise
for me. That's how I encountered the difficulties with the
unconstrained arrays and overloaded functions. Without these and the
fact that classes cannot be synthesized, I could not think of a clean
way to implement these versatile, reusable functions and components in
an easy fashion.

And that is where my frustration about design aspects of SystemVerilog
arouse.

Hopefully new revisions to the standard will add these and a lot more
soon, or I would stick with VHDL for design.
-- Amal
 
On Mar 26, 4:43 pm, Amal <akhailt...@gmail.com> wrote:
How does one code the following VHDL function snippet, in Verilog2001/
SystemVerilog?

  function mult( a : std_logic_vector; b : std_logic_vector )
      return std_logic_vector is
    variable result : std_logic_vector(a'length+b'length downto 0);
  begin
    result := a * b;
    return result;
  end function mult;
I would expect to code it by using the '*' operator to do the
multiplication, and not use a function at all. Verilog has a lot of
operators, so most common situations don't require using functions.

There are more complex situations where a function is called for.
Verilog does not allow writing functions that handle arbitrary width
arguments and return values. It partially compensates for that by
allowing implicit conversion between its integral types of any width.
The usual solution to this problem would be to declare a function with
arguments and return values as wide as the widest values used in the
design, and then use this function everywhere. The actual arguments
will be calculated at the wider width of the formals, and then passed
in. The wider result returned by the function will be used in the
expression in which it appears. If assigned to a narrower value, it
will be truncated back to the narrower width.

It isn't quite as flexible, since you need to know up front what the
widest width is that you need to deal with. It is not elegant. But
it works for many practical cases. Synthesis tools should be
sophisticated enough to discard any excess width, and synthesize
hardware of the width actually required.

In many cases, a function will only be used on data of a particular
width within a module. That width may be parameterized, but the
function width can be parameterized also. When the module is
instantiated with a particular width, a function within the module can
be instantiated with the correct width for it.

You could also encapsulate a parameterized function inside a
parameterized wrapper module. Then you could create different module
instances with different parameter values, each of which contains a
function of the appropriate parameterized width. Then you could use
hierarchical references to call the instance of the function
appropriate to that particular call. It would be clumsy, and
synthesis tools don't like hierarchical references, but it could be
done.

In SV, parameterized classes provide the opportunity to declare a
parameterized collection of data, along with parameterized functions
to operate on it. Again, I would not expect this to be synthesizable.
 
On Apr 7, 3:27 pm, sh...@cadence.com wrote:
On Mar 26, 4:43 pm, Amal <akhailt...@gmail.com> wrote:

How does one code the following VHDL function snippet, in Verilog2001/
SystemVerilog?

function mult( a : std_logic_vector; b : std_logic_vector )
return std_logic_vector is
variable result : std_logic_vector(a'length+b'length downto 0);
begin
result := a * b;
return result;
end function mult;

I would expect to code it by using the '*' operator to do the
multiplication, and not use a function at all. Verilog has a lot of
operators, so most common situations don't require using functions.

There are more complex situations where a function is called for.
Verilog does not allow writing functions that handle arbitrary width
arguments and return values. It partially compensates for that by
allowing implicit conversion between its integral types of any width.
The usual solution to this problem would be to declare a function with
arguments and return values as wide as the widest values used in the
design, and then use this function everywhere. The actual arguments
will be calculated at the wider width of the formals, and then passed
in. The wider result returned by the function will be used in the
expression in which it appears. If assigned to a narrower value, it
will be truncated back to the narrower width.

It isn't quite as flexible, since you need to know up front what the
widest width is that you need to deal with. It is not elegant. But
it works for many practical cases. Synthesis tools should be
sophisticated enough to discard any excess width, and synthesize
hardware of the width actually required.

In many cases, a function will only be used on data of a particular
width within a module. That width may be parameterized, but the
function width can be parameterized also. When the module is
instantiated with a particular width, a function within the module can
be instantiated with the correct width for it.

You could also encapsulate a parameterized function inside a
parameterized wrapper module. Then you could create different module
instances with different parameter values, each of which contains a
function of the appropriate parameterized width. Then you could use
hierarchical references to call the instance of the function
appropriate to that particular call. It would be clumsy, and
synthesis tools don't like hierarchical references, but it could be
done.

In SV, parameterized classes provide the opportunity to declare a
parameterized collection of data, along with parameterized functions
to operate on it. Again, I would not expect this to be synthesizable.
The mult example was just to give an example. This is simple enough
that can be done with operators. My intention is to use functions for
more complicated operations. CRC, LFSR, different Encoder/
Decoders, .... Defining these and other functions with fixed size is
not practical. Even if one returns a larger size and takes only the
bits needed is not a good practice. I need reusable, generic
functions that can be synthesized. I guess I have to stick to VHDL
for this. Even though Verilog2001/SystemVerilog were touted to have
everything VHDL has and even more.

-- Amal
 

Welcome to EDABoard.com

Sponsor

Back
Top