Slicing of an array: wrong direction

T

Tero Kapanen

I have variables declared as:
variable data : std_logic_vector (9 downto 0);
variable temp : std_logic_vector (2 downto 0);

I want to take a slice of the data and put it to temp. I have done it like:
temp(0) := data(5);
temp(1) := data(4);
temp(2) := data(3);

It works like it should but my problem is that it is not elegant solution.
Maybe someday I want to slice 64 bits and then I would prefer some other
way. :)

I can always write a function for it but isn't there already one or what is
the most elegant way to do it.

- tero
 
Y

Yves Deweerdt

Tero said:
I have variables declared as:
variable data : std_logic_vector (9 downto 0);
variable temp : std_logic_vector (2 downto 0);

I want to take a slice of the data and put it to temp. I have done it like:
temp(0) := data(5);
temp(1) := data(4);
temp(2) := data(3);

It works like it should but my problem is that it is not elegant solution.
Maybe someday I want to slice 64 bits and then I would prefer some other
way. :)

I can always write a function for it but isn't there already one or what is
the most elegant way to do it.

- tero

Hi Tero,

how about this one:

temp(2 downto 0) := data(5 downto 3);

Kind regards,

yd
 
T

Tero Kapanen

Hi Yves,

Yves Deweerdt said:
temp(2 downto 0) := data(5 downto 3);

If I understood correctly your line is equivalent to the following:
temp(2) := data(5);
temp(1) := data(4);
temp(0) := data(3);

and I want something like
Have to test it anyway 'cause maybe i am wrong.

- tero
 
J

Jim Lewis

Tero,
This is bruteforce and only slightly more elegant
than you other solution, but I like it for small
problems because it is immediately readable:

temp := data(3) & data(4) & data(5) ;

Note you are right about slicing the arrays, you
cannot do it in the "wrong" direction:
-- temp := data(3 to 5) ; -- illegal


For bigger problems, I would use a for loop. The
problem with a for loop is that as you are debugging,
there is always a question as to whether you got the
indexing right or not (with concatenation, as above,
this is not an issue):

for i in temp'range loop
temp(i) := data(5 - i ) ;
end loop ;

If you do lots of this, I would probably go the route
you suggested and write a function and use it as follows:

temp := rev_array(data(5 downto 3)) ;


Note there may be a function like this somewhere in one
of the packages.

Cheers,
Jim
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jim Lewis
Director of Training mailto:[email protected]
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

Expert VHDL Training for Hardware Design and Verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
J

Jonathan Bromley

hi Tero,

Tero Kapanen said:
Hi Yves,


If I understood correctly your line is equivalent to the following:
temp(2) := data(5);
temp(1) := data(4);
temp(0) := data(3);

and I want something like

If you want to reverse the left-to-right order of bits in a
vector, you must do the reversal using some kind of loop.
VHDL copying will ALWAYS preserve the left-to-right order
of elements in an array, regardless of the element numbers
or subscript range direction.

I've already offered the following very general-purpose
bit reversal function...

function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(a'RANGE);
alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
for i in aa'RANGE loop
result(i) := aa(i);
end loop;
return result;
end; -- function reverse_any_vector

Given that function, you could solve your problem by...

temp (2 downto 0) := reverse_any_vector(data(5 downto 3));

HTH
--

Jonathan Bromley, Consultant

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

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
T

Tero Kapanen

Hi Jonathan,

Thank you for your reply.

This is just what I afraid of. There is no elegant way to do it in VHDL. You
always have to go through some kind of a loop.

Changing the direction of the vector in the first place does not help much
if you need to take couple of slices some in correct order and some in
reversed order.

Best Regards,
tero
 
F

fe

function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(a'RANGE);
alias aa: std_logic_vector(a'REVERSE_RANGE) is a;
begin
for i in aa'RANGE loop
result(i) := aa(i);
end loop;
return result;
end; -- function reverse_any_vector

Jonathan, you don't need the alias aa. You just need to put result in the
reverse range of a.

function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(a'REVERSE_RANGE);
begin
for i in a'RANGE loop
result(i) := a(i);
end loop;
return result;
end; -- function reverse_any_vector

cheers
fe
 
J

Jonathan Bromley

fe said:
Jonathan, you don't need the alias aa. You just need to put result in the
reverse range of a.

function reverse_any_vector (a: in std_logic_vector)
return std_logic_vector is
variable result: std_logic_vector(a'REVERSE_RANGE);
begin
for i in a'RANGE loop
result(i) := a(i);
end loop;
return result;
end; -- function reverse_any_vector

Your solution is cleaner and easier.
I'm now desperately trying to remember why I put in
the alias in the first place...

I can just, with extreme difficulty, imagine a situation
where I would prefer the result's range to have the same
direction as the input's.

Cheers
--

Jonathan Bromley, Consultant

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

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
J

Jonathan Bromley

This is just what I afraid of.
There is no elegant way to do it in VHDL.

I'm at a loss to see what's inelegant about VHDL's
copying rules, but I suppose everyone's entitled to
their opinion.
Changing the direction of the vector in the first place
does not help much if you need to take couple of slices
some in correct order and some in reversed order.

I think you missed my point. Using a function like the
one I described, you can easily reverse any fragment of
any vector - and then use concatenation to reassemble
the fragments, if you wish. Just for fun, this code
re-maps the bits of an 8-bit word as follows:

- the most significant 3 bits are reversed and copied
into the least significant 3 bits;
- the least significant 3 bits are reversed and
copied into the most significant 3 bits;
- the middle 2 bits are unchanged.

variable V, Map: std_logic_vector(7 downto 0);
...
Map := reverse_any_vector( V(2 downto 0) )
& V(4 downto 3)
& reverse_any_vector( V(7 downto 5) );

Easy and explicit. Or, alternatively, if you prefer:

Map(7 downto 5) := reverse_any_vector( V(2 downto 0) );
Map(4 downto 3) := V(4 downto 3);
Map(2 downto 0) := reverse_any_vector( V(7 downto 5) );

In what way does this "not help much"?
--
Jonathan Bromley, Consultant

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

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
T

Tero Kapanen

Dear Jonathan,

Jonathan Bromley said:
I'm at a loss to see what's inelegant about VHDL's
copying rules, but I suppose everyone's entitled to
their opinion.

Maybe there is nothing inelegant but I have quate much software background
and new to VHDL.
I thought that it would take more time when it needs to go through loop.
Maybe my assumbtion was wrong and after synthesis all the bits are reversed
at ones => smaller propagation delay => higher possible clock frequency.
I think you missed my point. Using a function like the
one I described, you can easily reverse any fragment of
any vector - and then use concatenation to reassemble
the fragments, if you wish. Just for fun, this code
re-maps the bits of an 8-bit word as follows:

I understood your point correctly and can't deny that it is helpful.
In what way does this "not help much"?

by that I meant it does not help to change the direction of the original
vector
from "variable temp : std_logic_vector (2 downto 0);"
to "variable temp : std_logic_vector (0 to 2);"

Best Regards,
tero
 
J

Jonathan Bromley

Maybe there is nothing inelegant but I have quate much software background
and new to VHDL.
I thought that it would take more time when it needs to go through loop.
Maybe my assumbtion was wrong and after synthesis all the bits are reversed
at ones => smaller propagation delay => higher possible clock frequency.

This is a very fair question. In SIMULATION, the loop will probably
take some additional time (although copying ANY array will always
involve the execution of an internal loop, except in some very
simple cases that can be optimised to single-word copies).
However, in SYNTHESIS, any copy operation will be converted
into a bunch of wire connections. The loop, explicit or implicit,
is unrolled by the synthesis tool into an array of connections.
No additional propagation delay in the finished hardware.

[...]
by that I meant it does not help to change the direction of the original
vector
from "variable temp : std_logic_vector (2 downto 0);"
to "variable temp : std_logic_vector (0 to 2);"

Indeed.

Like most people, I tend to use descending ranges for the
elements of a vector of bits - so that the left-hand, more
significant bits have higher bit numbers - but I use
ascending ranges for the elements of an array of larger
objects - to make it look like an array in any other
programming languages. But the slice direction has no
impact on the meaning of the array taken as a whole.
--

Jonathan Bromley, Consultant

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

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
A

Allan Herriman

Like most people, I tend to use descending ranges for the
elements of a vector of bits - so that the left-hand, more
significant bits have higher bit numbers - but I use
ascending ranges for the elements of an array of larger
objects - to make it look like an array in any other
programming languages. But the slice direction has no
impact on the meaning of the array taken as a whole.

I found a compelling reason to use descending vector ranges on top
level ports.

The back end tools I use (Xilinx) can extract gate level VHDL from the
placed and routed design. The original port direction has been lost
well before this (in the synthesiser) so the tools have to guess a
direction when they turn individual bits back into vectors, and they
always guess descending.

The testbench therefore must expect descending ranges on the ports of
the entity under test.
I guess most people will use the same testbench for the RTL design and
the gate level design, therefore the RTL design also needs to have
descending ranges on its ports.

I wrote this requirement into a coding standard at my last job. (I
actually went a bit further - all slvs were required to have
descending ranges.)

Regards,
Allan.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top