Slicing of an array: wrong direction

T

Tero Kapanen

Guest
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
 
Tero Kapanen wrote:
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
 
Hi Yves,

"Yves Deweerdt" <yves@news.be> wrote in message
news:3FA7DA78.9080809@news.be...
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
temp(0) := data(5);
temp(1) := data(4);
temp(2) := data(3);
Have to test it anyway 'cause maybe i am wrong.

- tero
 
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:Jim@SynthWorks.com
SynthWorks Design Inc. http://www.SynthWorks.com
1-503-590-4787

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



Tero Kapanen wrote:

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,

"Tero Kapanen" <tero.kapanen#POISTA#@kolumbus.fi> wrote in
message news:bo8mku$5jo$1@phys-news1.kolumbus.fi...
Hi Yves,

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
temp(0) := data(5);
temp(1) := data(4);
temp(2) := data(3);
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: jonathan.bromley@doulos.com
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.
 
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
 
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
 
"fe" <notvalid@nowhere.com> wrote in message
news:ROTpb.60645$of7.1646930@wagner.videotron.net...
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: jonathan.bromley@doulos.com
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.
 
"Tero Kapanen" <tero.kapanen#POISTA#@kolumbus.fi> wrote in
message news:bo901q$487$1@phys-news1.kolumbus.fi...

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: jonathan.bromley@doulos.com
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.
 
Dear Jonathan,

"Jonathan Bromley" <jonathan.bromley@doulos.com> wrote in message
news:bobopt$gkb$1$8300dec7@news.demon.co.uk...
"Tero Kapanen" <tero.kapanen#POISTA#@kolumbus.fi> wrote in
message news:bo901q$487$1@phys-news1.kolumbus.fi...

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

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:
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
 
"Tero Kapanen" <tero.kapanen#POISTA#@kolumbus.fi> wrote in
message news:bobq6p$q5$1@phys-news1.kolumbus.fi...

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.

[...]
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);"
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: jonathan.bromley@doulos.com
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.
 
On Thu, 6 Nov 2003 23:20:41 -0000, "Jonathan Bromley"
<jonathan.bromley@doulos.com> wrote:

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.
 

Welcome to EDABoard.com

Sponsor

Back
Top