function with given range attribute as argument

O

Olaf

Guest
Hi,

after some hours I found an error in my testbench, since I forgot the
bondaries of use (I wrote it some time ago). Here the origin function:

function str2sulv(vec : in string) return std_ulogic_vector is
variable temp : std_ulogic_vector(vec'range) := (others => 'X');
begin
for i in vec'range loop
if (vec(i) = '1') then
temp(i) := '1';
elsif (vec(i) = '0') then
temp(i) := '0';
end if;
end loop;
return temp;
end function;

I called this with vec = "1111111_000000" - the underline was the
problem. No I would like to write it using an argument more: the range
to avoid such problem for the future. How can I add it?

function str2sulv(
vec : in string;
rg : in ???????)
return std_ulogic_vector is
variable temp : std_ulogic_vector(rg) := (others => 'X');

which I want to call like:

data <= str2sulv("1111111_0000000", data'range);

Thanks
Olaf
 
Olaf wrote:

I called this with vec = "1111111_000000" - the underline was the
problem.
See the function vec_image here for reference:
http://home.comcast.net/~mike_treseler/

I would use standard vector types, and convert
those to strings as need for report statements.
Why reinvent the error checking the compiler provides for free?

-- Mike Treseler
 
On Sat, 12 May 2007 21:42:26 +0200, Olaf
<olaf@mdcc.de> wrote:

Olaf

function str2sulv(vec : in string) return std_ulogic_vector is
variable temp : std_ulogic_vector(vec'range) := (others => 'X');
[...]

I called this with vec = "1111111_000000" - the underline was the
problem. No I would like to write it using an argument more: the range
to avoid such problem for the future. How can I add it?

function str2sulv(
vec : in string;
rg : in ???????)
return std_ulogic_vector is
variable temp : std_ulogic_vector(rg) := (others => 'X');

which I want to call like:

data <= str2sulv("1111111_0000000", data'range);
There is nothing in VHDL that can directly store a range,
or pass a range as a parameter to a function.

Are you *sure* you want this interface to your conversion function?
I guess it's vaguely similar to the numeric_std conversion functions
such as TO_UNSIGNED(value, length) which simply take a length
(number of bits) as a second argument. They return a vector
of range (0 to length-1) which, of course, is OK to copy on to
any other vector of the same type and length. However, if
you really must convert strings (is this input from a text file?)
then a slightly different approach may be better. Why not
work out the vector size *within* the function itself?
Here's how I might do it:

function str2sulv(s: string) return std_ulogic_vector is
-- Make a sulv of the largest possible size
variable v: std_ulogic_vector(1 to s'length);
variable p: integer := 1; -- index into the sulv
begin
for i in s'range loop
-- Ignore anything that isn't '0' or '1'.
if s(i) = '0' then
v(p) := '0';
p := p + 1;
elsif s(i) = '1' then
v(p) := '1';
p := p + 1;
end if;
end loop;
-- Now, bits 1 to p-1 of the vector are valid.
return v(1 to p-1);
end;

With a bit more work you could make the function process a
whole range of bit-pattern string representations including
hex, Verilog-style, and so on.

I think I would also give the str2sulv function an *optional*
length parameter that defaults to zero. Then, if that parameter
is zero, the function behaves as I indicate above - it returns
a vector with as many bits as there were digits in the string.
But if the length parameter is non-zero, it guarantees to return
a vector of exactly that length, padding or truncating as required.
Maybe something like this...

function str2sulv(s: string; len: natural := 0)
return std_ulogic_vector is

and then replace the final "return" statement with this...

if len = 0 then
-- return exactly what we were given
return v(1 to p-1);
elsif len < p then
-- we need to truncate; lose some MSBs
return v(p-len to p-1);
else
-- we need zero-padding
return (std_ulogic_vector'(0 to len-p => '0')) & v;
end if;

Works for me :)
--
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 Sat, 12 May 2007 21:51:01 +0100, Jonathan Bromley
<jonathan.bromley@MYCOMPANY.com> wrote:


AARGH, hit send before doing the last edit...

-- we need zero-padding
return (std_ulogic_vector'(0 to len-p => '0')) & v(1 to p-1);
Note the correction: added subscript range on v(). Whoops.
--
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 May 12, 2:42 pm, Olaf <o...@mdcc.de> wrote:
Hi,

after some hours I found an error in my testbench, since I forgot the
bondaries of use (I wrote it some time ago). Here the origin function:

function str2sulv(vec : in string) return std_ulogic_vector is
variable temp : std_ulogic_vector(vec'range) := (others => 'X');
begin
for i in vec'range loop
if (vec(i) = '1') then
temp(i) := '1';
elsif (vec(i) = '0') then
temp(i) := '0';
end if;
end loop;
return temp;
end function;

I called this with vec = "1111111_000000" - the underline was the
problem. No I would like to write it using an argument more: the range
to avoid such problem for the future. How can I add it?

function str2sulv(
vec : in string;
rg : in ???????)
return std_ulogic_vector is
variable temp : std_ulogic_vector(rg) := (others => 'X');

which I want to call like:

data <= str2sulv("1111111_0000000", data'range);

Thanks
Olaf
If you really need to do this (other replies have valid points), I
suggest you simply send a vector of the desired size (could be the
vector itself) in as an argument, and use its 'range attribute inside
the function. This is used in various overloads of several functions
in the fixed point package for an example.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top