Can a vhdl function return a range?

M

mksuth

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));
 
K

KJ

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
 
M

MBodnar

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
 
M

mksuth

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.
 
K

KJ

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
 
T

Tricky

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top