Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Rotate by variable

Reply
Thread Tools

Rotate by variable

 
 
Patrick Moore
Guest
Posts: n/a
 
      02-16-2004

Hi all,

sorry to drop in like this but I'm having a problem and thought I may be
able to gain some information from you all...

I'm trying to achieve a variable rotate as below. i.e. it takes in two
numbers, one 32 bits long, the other 5 bits long, and outputs the 32 bit
number, rotated left by 5 bits.

Now, this will compile fine (i.e. it's syntactically correct) but can't be
synthesised in Synplify Pro.

Does anyone have any suggestions, or code snippets that would be able to
make this synthesisable for a Virtex II (Pro).

tia,

patrick.



entity ro_lft is
port(
quantity : in STD_LOGIC_VECTOR(31 downto 0);
amount : in STD_LOGIC_VECTOR(4 downto 0);
clk : in STD_LOGIC;
output : out STD_LOGIC_VECTOR(31 downto 0)
);
end ro_lft;

--}} End of automatically maintained section

architecture ro_lft of ro_lft is

signal rotated : STD_LOGIC_VECTOR(31 downto 0);
--signal result: integer;
--signal a_std_vec : std_logic_vector (31 downto 0);
signal rotate_by : std_logic_vector(4 downto 0);

begin

-- enter your statements here --

rotate_by <= amount;

process (clk)
begin
if clk = '1' and clk'event then

rotated <= std_logic_vector(unsigned(quantity) rol
to_integer(signed(rotate_by)));

end if;
end process;

output <= rotated;

end ro_lft;
 
Reply With Quote
 
 
 
 
Egbert Molenkamp
Guest
Posts: n/a
 
      02-16-2004
In your case the shift operator (ROL) can shift data to the left and to the
right (depends on sign of 'rotate_by').
As an alternative you could try the functions that are part of the
numeric_package:
shift_right en shift_left

I changed your code a little bit (only shift to the right). If your tool
supports this you can extend it to make a shift to the left and right.



library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ro_lft is
port(
quantity : in unsigned(31 downto 0);
amount : in unsigned(4 downto 0);
clk : in STD_LOGIC;
output : out STD_LOGIC_VECTOR(31 downto 0)
);
end ro_lft;

--}} End of automatically maintained section

architecture ro_lft of ro_lft is

signal rotated : STD_LOGIC_VECTOR(31 downto 0);
signal rotate_by : unsigned(4 downto 0);

begin

-- enter your statements here --

rotate_by <= amount;

process (clk)
begin
if clk = '1' and clk'event then
rotated <=
std_logic_vector(shift_right(quantity,to_integer(u nsigned(rotate_by))));
end if;
end process;

output <= rotated;

end ro_lft;


Egbert Molenkamp

"Patrick Moore" <(E-Mail Removed)> schreef in bericht
news(E-Mail Removed)...
>
> Hi all,
>
> sorry to drop in like this but I'm having a problem and thought I may be
> able to gain some information from you all...
>
> I'm trying to achieve a variable rotate as below. i.e. it takes in two
> numbers, one 32 bits long, the other 5 bits long, and outputs the 32 bit
> number, rotated left by 5 bits.
>
> Now, this will compile fine (i.e. it's syntactically correct) but can't be
> synthesised in Synplify Pro.
>
> Does anyone have any suggestions, or code snippets that would be able to
> make this synthesisable for a Virtex II (Pro).
>
> tia,
>
> patrick.
>
>
>
> entity ro_lft is
> port(
> quantity : in STD_LOGIC_VECTOR(31 downto 0);
> amount : in STD_LOGIC_VECTOR(4 downto 0);
> clk : in STD_LOGIC;
> output : out STD_LOGIC_VECTOR(31 downto 0)
> );
> end ro_lft;
>
> --}} End of automatically maintained section
>
> architecture ro_lft of ro_lft is
>
> signal rotated : STD_LOGIC_VECTOR(31 downto 0);
> --signal result: integer;
> --signal a_std_vec : std_logic_vector (31 downto 0);
> signal rotate_by : std_logic_vector(4 downto 0);
>
> begin
>
> -- enter your statements here --
>
> rotate_by <= amount;
>
> process (clk)
> begin
> if clk = '1' and clk'event then
>
> rotated <= std_logic_vector(unsigned(quantity) rol
> to_integer(signed(rotate_by)));
>
> end if;
> end process;
>
> output <= rotated;
>
> end ro_lft;



 
Reply With Quote
 
 
 
 
Jonathan Bromley
Guest
Posts: n/a
 
      02-17-2004
"Patrick Moore" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...

> I'm trying to achieve a variable rotate as below. i.e. it takes in two
> numbers, one 32 bits long, the other 5 bits long, and outputs the 32 bit
> number, rotated left by 5 bits.
>
> Now, this will compile fine (i.e. it's syntactically correct) but can't be
> synthesised in Synplify Pro.


Can we ALL please bang VERY LOUDLY on Synplicity's door until they
finally support variable-length shifts?

> Does anyone have any suggestions, or code snippets that would be able to
> make this synthesisable for a Virtex II (Pro).


Two suggestions. Both work, but you need to try them out in your
synthesis tool - we've found that this barrel shift construct is
one which shows up some very big differences among tools.
You may need to tweak the details to suit your precise definition
of a barrel shift - mine rotates to the right.

For the sake of argument, let's suppose we have the following
entity:

entity barrel_shift is
port (
A : in std_logic_vector(31 downto 0); -- input word
S : in std_logic_vector(4 downto 0); -- rotate count
F : out std_logic_vector(31 downto 0) -- rotated output
);
end;

(1) Consider a funnel shifter. Stick two copies of the original
word together, then pick bits off it.

architecture funnel of barrel_shift is
begin
process (A, S)
variable double: std_logic_vector(63 downto 0);
begin
double := A & A; -- two copies of the input word
for i in 0 to 31 loop
F(i) <= double(to_integer(unsigned(S)) + i);
end loop;
end process;
end;


This depends on the tool correctly optimising the subscript
calculation by unrolling the loop.

(2) Use variable-length slices:

architecture slice of barrel_shift is
begin
F <= A(to_integer(unsigned(S)) - 1 downto 0) &
A(31 downto to_integer(unsigned(S)));
end;

I have seen this work correctly in some tools.

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: http://www.velocityreviews.com/forums/(E-Mail 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.




 
Reply With Quote
 
Patrick Moore
Guest
Posts: n/a
 
      02-17-2004
On Tue, 17 Feb 2004 09:57:38 -0000, Jonathan Bromley
<(E-Mail Removed)> wrote:



>
> architecture funnel of barrel_shift is
> begin
> process (A, S)
> variable double: std_logic_vector(63 downto 0);
> begin
> double := A & A; -- two copies of the input word
> for i in 0 to 31 loop
> F(i) <= double(to_integer(unsigned(S)) + i);
> end loop;
> end process;
> end;


This one works, and even Synplify likes it, which is saying something.

What's the best way to reverse the rotate on this? (make it rotate left)

I guess doing a

temp := 32-S

and

F(i)<= double(to_integer(unsigned(temp)) + i);

Would do it, but I'm unsure of the fine tuning? :S (or if there's a
better way around it...)

As you can tell, I'm not very experienced in this whole thing, but
hopefully over time ...

> This depends on the tool correctly optimising the subscript
> calculation by unrolling the loop.
>
> (2) Use variable-length slices:
>
> architecture slice of barrel_shift is
> begin
> F <= A(to_integer(unsigned(S)) - 1 downto 0) &
> A(31 downto to_integer(unsigned(S)));
> end;
>
> I have seen this work correctly in some tools.


Unfortunately, Synplify Pro 7.2 doesn't like that one.. ;/

> HTH


It did, thanks.

atb,

Patrick
 
Reply With Quote
 
Jonathan Bromley
Guest
Posts: n/a
 
      02-17-2004
"Patrick Moore" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...

> > architecture funnel of barrel_shift is
> > begin
> > process (A, S)
> > variable double: std_logic_vector(63 downto 0);
> > begin
> > double := A & A; -- two copies of the input word
> > for i in 0 to 31 loop
> > F(i) <= double(to_integer(unsigned(S)) + i);
> > end loop;
> > end process;
> > end;

>
> This one works, and even Synplify likes it


It's the version that I have found to be most portable
across synthesis tools. You may possibly get a harmless
warning about one of the bits of "double" being unused.

> What's the best way to reverse the rotate on this?
> (make it rotate left)


Reverse the order of bit numbering in all the vector
declarations - ports and internal signals A, F, double:
std_logic_vector(0 to 31) etc. Other code unchanged.
Unconventional but effective.

> I guess doing a
>
> temp := 32-S
>
> and
>
> F(i)<= double(to_integer(unsigned(temp)) + i);
>
> Would do it, but I'm unsure of the fine tuning


That, or something very close, sounds OK. But I would get
a bit jumpy about doing any unnecessary arithmetic on the
shift value; it would be OK in simulation but you really,
really don't want any adders in the select path. Hence
my preference for getting the left shift by re-numbering bits.
It's probably fine either way in most tools, but I've been
bitten with such things before now.

> As you can tell, I'm not very experienced in this whole thing, but
> hopefully over time ...


It's the usual engineering thing: there's no substitute for
lots of experience and plenty of paranoia.

> > (2) Use variable-length slices:

[...]
> Unfortunately, Synplify Pro 7.2 doesn't like that one.. ;/


Don't say I didn't warn you In fairness, that one is a
bit hard on synthesis tools; it implies data paths whose
widths vary as a function of one of the input values, which
doesn't sound very sensible. Only when you stick the two
variable-width pieces together can the tool discover that
the result is of constant width.

--

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



 
Reply With Quote
 
Egbert Molenkamp
Guest
Posts: n/a
 
      02-18-2004

"Jonathan Bromley" <(E-Mail Removed)> wrote in message
news:c0sola$qf9$1$(E-Mail Removed)...
> Can we ALL please bang VERY LOUDLY on Synplicity's door until they
> finally support variable-length shifts?


I did .. and just received the answer that the issue is solved in 7.5 and
that the version is available for download.

Egbert Molenkamp





 
Reply With Quote
 
Jonathan Bromley
Guest
Posts: n/a
 
      02-18-2004
"Egbert Molenkamp" <(E-Mail Removed)> wrote
in message news:c0vdlc$5ig$(E-Mail Removed)...
>
> "Jonathan Bromley" <(E-Mail Removed)> wrote in message
> news:c0sola$qf9$1$(E-Mail Removed)...
> > Can we ALL please bang VERY LOUDLY on Synplicity's door until they
> > finally support variable-length shifts?

>
> I did .. and just received the answer that the issue is solved in 7.5

and
> that the version is available for download.


Yippee! Thanks Egbert.

--

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



 
Reply With Quote
 
ALuPin
Guest
Posts: n/a
 
      02-18-2004
Hi,

I tried to compile your code with
Altera QuartusII v3.0 SP2

and got the following warning:

Warning: VHDL Subtype or Type Declaration warning at numeric_std.vhd(87:
subtype or type has null range Switching left and right bound of range.

Was does that mean?

Rgds
A.Vazquez

"Egbert Molenkamp" <(E-Mail Removed)> wrote in message news:<c0re3t$3bd$(E-Mail Removed)>...
> In your case the shift operator (ROL) can shift data to the left and to the
> right (depends on sign of 'rotate_by').
> As an alternative you could try the functions that are part of the
> numeric_package:
> shift_right en shift_left
>
> I changed your code a little bit (only shift to the right). If your tool
> supports this you can extend it to make a shift to the left and right.
>
>
>
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;
> entity ro_lft is
> port(
> quantity : in unsigned(31 downto 0);
> amount : in unsigned(4 downto 0);
> clk : in STD_LOGIC;
> output : out STD_LOGIC_VECTOR(31 downto 0)
> );
> end ro_lft;
>
> --}} End of automatically maintained section
>
> architecture ro_lft of ro_lft is
>
> signal rotated : STD_LOGIC_VECTOR(31 downto 0);
> signal rotate_by : unsigned(4 downto 0);
>
> begin
>
> -- enter your statements here --
>
> rotate_by <= amount;
>
> process (clk)
> begin
> if clk = '1' and clk'event then
> rotated <=
> std_logic_vector(shift_right(quantity,to_integer(u nsigned(rotate_by))));
> end if;
> end process;
>
> output <= rotated;
>
> end ro_lft;
>
>
> Egbert Molenkamp
>
> "Patrick Moore" <(E-Mail Removed)> schreef in bericht
> news(E-Mail Removed)...
> >
> > Hi all,
> >
> > sorry to drop in like this but I'm having a problem and thought I may be
> > able to gain some information from you all...
> >
> > I'm trying to achieve a variable rotate as below. i.e. it takes in two
> > numbers, one 32 bits long, the other 5 bits long, and outputs the 32 bit
> > number, rotated left by 5 bits.
> >
> > Now, this will compile fine (i.e. it's syntactically correct) but can't be
> > synthesised in Synplify Pro.
> >
> > Does anyone have any suggestions, or code snippets that would be able to
> > make this synthesisable for a Virtex II (Pro).
> >
> > tia,
> >
> > patrick.
> >
> >
> >
> > entity ro_lft is
> > port(
> > quantity : in STD_LOGIC_VECTOR(31 downto 0);
> > amount : in STD_LOGIC_VECTOR(4 downto 0);
> > clk : in STD_LOGIC;
> > output : out STD_LOGIC_VECTOR(31 downto 0)
> > );
> > end ro_lft;
> >
> > --}} End of automatically maintained section
> >
> > architecture ro_lft of ro_lft is
> >
> > signal rotated : STD_LOGIC_VECTOR(31 downto 0);
> > --signal result: integer;
> > --signal a_std_vec : std_logic_vector (31 downto 0);
> > signal rotate_by : std_logic_vector(4 downto 0);
> >
> > begin
> >
> > -- enter your statements here --
> >
> > rotate_by <= amount;
> >
> > process (clk)
> > begin
> > if clk = '1' and clk'event then
> >
> > rotated <= std_logic_vector(unsigned(quantity) rol
> > to_integer(signed(rotate_by)));
> >
> > end if;
> > end process;
> >
> > output <= rotated;
> >
> > end ro_lft;

 
Reply With Quote
 
Jonathan Bromley
Guest
Posts: n/a
 
      02-18-2004
"ALuPin" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hi,
>
> I tried to compile your code with
> Altera QuartusII v3.0 SP2
>
> and got the following warning:
>
> Warning: VHDL Subtype or Type Declaration warning at
> numeric_std.vhd(87: subtype or type has null range


That's a completely reasonable warning, but VHDL is
supposed to allow null ranges. Many tools issue a warning,
but then go on to process the null range correctly. However,
Quartus says....

> Switching left and right bound of range.


AARGH!!!! This is absurd. Given

signal s: std_logic_vector (7 downto 0);

* the range (0 downto 0) is just a single bit s(0)
* the range (0 downto 1) is a null range - no bits at all
* the range (1 downto 0) is two bits wide

Therefore, switching the left and right bound is
completely unacceptable - it changes the meaning of
the code in a disastrous way.

> Was does that mean?


It means Quartus is doing something that it has no right to do.

See my other replies in this thread for a different solution
that does not require null ranges.


 
Reply With Quote
 
ALuPin
Guest
Posts: n/a
 
      02-18-2004
Apart from that I get the Info
"No valid register-to-register paths exist for clock Clk"

What does go wrong with timing calculation?

Rgds

"Egbert Molenkamp" <(E-Mail Removed)> wrote in message news:<c0re3t$3bd$(E-Mail Removed)>...
> In your case the shift operator (ROL) can shift data to the left and to the
> right (depends on sign of 'rotate_by').
> As an alternative you could try the functions that are part of the
> numeric_package:
> shift_right en shift_left
>
> I changed your code a little bit (only shift to the right). If your tool
> supports this you can extend it to make a shift to the left and right.
>
>
>
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;
> entity ro_lft is
> port(
> quantity : in unsigned(31 downto 0);
> amount : in unsigned(4 downto 0);
> clk : in STD_LOGIC;
> output : out STD_LOGIC_VECTOR(31 downto 0)
> );
> end ro_lft;
>
> --}} End of automatically maintained section
>
> architecture ro_lft of ro_lft is
>
> signal rotated : STD_LOGIC_VECTOR(31 downto 0);
> signal rotate_by : unsigned(4 downto 0);
>
> begin
>
> -- enter your statements here --
>
> rotate_by <= amount;
>
> process (clk)
> begin
> if clk = '1' and clk'event then
> rotated <=
> std_logic_vector(shift_right(quantity,to_integer(u nsigned(rotate_by))));
> end if;
> end process;
>
> output <= rotated;
>
> end ro_lft;
>
>
> Egbert Molenkamp
>
> "Patrick Moore" <(E-Mail Removed)> schreef in bericht
> news(E-Mail Removed)...
> >
> > Hi all,
> >
> > sorry to drop in like this but I'm having a problem and thought I may be
> > able to gain some information from you all...
> >
> > I'm trying to achieve a variable rotate as below. i.e. it takes in two
> > numbers, one 32 bits long, the other 5 bits long, and outputs the 32 bit
> > number, rotated left by 5 bits.
> >
> > Now, this will compile fine (i.e. it's syntactically correct) but can't be
> > synthesised in Synplify Pro.
> >
> > Does anyone have any suggestions, or code snippets that would be able to
> > make this synthesisable for a Virtex II (Pro).
> >
> > tia,
> >
> > patrick.
> >
> >
> >
> > entity ro_lft is
> > port(
> > quantity : in STD_LOGIC_VECTOR(31 downto 0);
> > amount : in STD_LOGIC_VECTOR(4 downto 0);
> > clk : in STD_LOGIC;
> > output : out STD_LOGIC_VECTOR(31 downto 0)
> > );
> > end ro_lft;
> >
> > --}} End of automatically maintained section
> >
> > architecture ro_lft of ro_lft is
> >
> > signal rotated : STD_LOGIC_VECTOR(31 downto 0);
> > --signal result: integer;
> > --signal a_std_vec : std_logic_vector (31 downto 0);
> > signal rotate_by : std_logic_vector(4 downto 0);
> >
> > begin
> >
> > -- enter your statements here --
> >
> > rotate_by <= amount;
> >
> > process (clk)
> > begin
> > if clk = '1' and clk'event then
> >
> > rotated <= std_logic_vector(unsigned(quantity) rol
> > to_integer(signed(rotate_by)));
> >
> > end if;
> > end process;
> >
> > output <= rotated;
> >
> > end ro_lft;

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
left shift operator behaves like left rotate when the operand is a variable. pc C Programming 2 06-08-2011 06:58 PM
PIL rotate : Rotate By Shear / Paeth Rotation? IanJSparks Python 0 01-10-2008 04:50 PM
"Variable variable name" or "variable lvalue" mfglinux Python 11 09-12-2007 03:08 AM
Rotate the graphics without rotate the text in SVG RC XML 1 08-03-2006 07:45 AM
How do I scope a variable if the variable name contains a variable? David Filmer Perl Misc 19 05-21-2004 03:55 PM



Advertisments