Velocity Reviews > VHDL > Can a vhdl function return a range?

# Can a vhdl function return a range?

mksuth
Guest
Posts: n/a

 12-16-2011
I'd like to use a function to compute the 'X downto Y' range of a
vector. Is there a clean way of doing this?

-- something like this would be nice:
function get_slice(n : natural) return range is
begin
return (n+1)*4 downto n*4;
end function

-- so I can use it on an slv like this:
a <= b(get_slice(2));

KJ
Guest
Posts: n/a

 12-16-2011
On Dec 16, 1:53*pm, mksuth <(E-Mail Removed)> wrote:
> I'd like to use a function to compute the 'X downto Y' range of a
> vector. Is there a clean way of doing this?
>
> -- something like this would be nice:
> function get_slice(n : natural) return range is
> begin
> * *return (n+1)*4 downto n*4;
> end function
>
> -- so I can use it on an slv like this:
> a <= b(get_slice(2));

No you can't return a range. However you could instead send the
vector and the selection into get_slice to have it return the vector
slice.

function get_slice(v: std_logic_vector; n : natural) return
std_logic_vector is
begin
return v((n+1)*4 downto n*4);
end function

-- so you can use it on an slv like this:
a <= get_slice(b, 2);

The difference between the two approaches on the usage are basically
cosmetic.

Kevin Jennings

MBodnar
Guest
Posts: n/a

 12-19-2011
On Dec 16, 2:30*pm, KJ <(E-Mail Removed)> wrote:
> On Dec 16, 1:53*pm, mksuth <(E-Mail Removed)> wrote:
>
> > I'd like to use a function to compute the 'X downto Y' range of a
> > vector. Is there a clean way of doing this?

>
> > -- something like this would be nice:
> > function get_slice(n : natural) return range is
> > begin
> > * *return (n+1)*4 downto n*4;
> > end function

>
> > -- so I can use it on an slv like this:
> > a <= b(get_slice(2));

>
> No you can't return a range. *However you could instead send the
> vector and the selection into get_slice to have it return the vector
> slice.
>
> function get_slice(v: std_logic_vector; n : natural) return
> std_logic_vector is
> begin
> * *return v((n+1)*4 downto n*4);
> end function
>
> -- so you can use it on an slv like this:
> a <= get_slice(b, 2);
>
> The difference between the two approaches on the usage are basically
> cosmetic.
>
> Kevin Jennings

I don't have a compiler in front of me, but I wonder if this would be
YACDA (yet another cosmetically-different approach):

function get_range(n : natural) return
std_logic_vector is
variable v : std_logic_vector((n+1)*4 downto n*4)) := (others =>
'0');
begin
return v;
end function

-- usage
a <= b(get_range(2)'range);

I like this less than KJ's approach (especially because his get_slice
takes in the aggregate vector, clearly expressing intent), but I
thought I'd still pose it for discussion.

MB

mksuth
Guest
Posts: n/a

 12-19-2011
Thanks for the replies.

KJ's solution works great provided you're using it on the RHS of the
assignment (as in my original example), but it doesn't work on the LHS
of an assignment:

get_slice(a,2) <= b; -- will not compile

MB's solution on the other hand will work for both the LHS and RHS of
an assignment.

KJ
Guest
Posts: n/a

 12-19-2011
On Dec 19, 10:18*am, mksuth <(E-Mail Removed)> wrote:
> Thanks for the replies.
>
> KJ's solution works great provided you're using it on the RHS of the
> assignment (as in my original example), but it doesn't work on the LHS
> of an assignment:
>
> get_slice(a,2) <= b; -- will not compile
>
> MB's solution on the other hand will work for both the LHS and RHS of
> an assignment.

The slice on the left hand side will be useful only under the
following conditions:
- The slice selection is constant (like in your example, it is '2')
- You use this inside a process

Otherwise you'll find that other drivers of the signal (i.e. the other
assignment statements that assign the other bits of the vector) will
cause you problems...in particular, synthesis will fail for having
multiple drivers.

Kevin Jennings

Tricky
Guest
Posts: n/a

 12-20-2011
On Dec 19, 3:18*pm, mksuth <(E-Mail Removed)> wrote:
> Thanks for the replies.
>
> KJ's solution works great provided you're using it on the RHS of the
> assignment (as in my original example), but it doesn't work on the LHS
> of an assignment:
>
> get_slice(a,2) <= b; -- will not compile
>
> MB's solution on the other hand will work for both the LHS and RHS of
> an assignment.

You cant do this, because functions return a constant and not a
signal. So the returned value has no reference back to "a". In this
case, you would have to do this:

a( get_slice(a,2)'range ) <= b;

It works the other way around because you can assign a constant to a
signal.