Lothar Miller wrote:
> insert it into your posts text surrounded by the vhdl tokens
1 | [vhdl] VHDL Code [/vhdl]
|
Ok, I did it for you. Now lets start:
Never use both of the arithmetic libraries together:
1 | use ieee.numeric_std.all;
|
2 | use ieee.std_logic_unsigned.all;
|
Use the numeric_std and the conversions in it only!
Otherwise you may have double defined datatypes in your VHDL code.
This could be written gerneric in one line:
1 | for i in 1 to shift loop
|
2 | append(i) := '0';
|
3 | end loop;
|
Do it this way:
1 | append := (others=>'0');
|
Where is this "15" from?
1 | variable V: std_logic_vector((shift+15) downto 0);
|
And why should you try to shift a 16 bit vector 65536 times?
1 | variable shift:integer range 0 to 65535:= to_integer(unsigned(B));
|
The actual problem is this here:
This here is not possible, because shift must be constant because (x
downto y) only accept constants. But shift is evaluated out of B, and
B istn't constant:
1 | variable shift:integer range 0 to 65535:= to_integer(unsigned(B));
|
2 | variable append: std_logic_vector (shift downto 1); -- shift must be constant!
|
And also the begin and the end of a loop must be constant:
1 | for i in 0 to shift loop
|
Why do you do the thing so circiutous?
You must look at the problem not with a programmers "software view", but
with a sense for the hardware you want. So there is the quuestion: what
is a barrel shifter? Fairly easy: a big multiplexer.
And after knowing what you need you must describe this big multiplexer.
Thats all.
You nearly got the way by shifting the input in a bigger vector and
cutting out the slice you want (thats the multiplexer actually).
So first is to say: a 16 bit vector can be shifted either 16 bits the
one or 16 the other way. Then it may look like this:
1 | library ieee;
|
2 | use ieee.std_logic_1164.all;
|
3 | use ieee.numeric_std.all;
|
4 |
|
5 | entity barrelshifter is
|
6 | port(A: IN std_logic_vector(15 downto 0);
|
7 | B: IN std_logic_vector(3 downto 0);
|
8 | D: IN std_logic;
|
9 | ShiftOut: OUT std_logic_vector (15 downto 0));
|
10 | end barrelshifter;
|
11 |
|
12 | architecture behavior of barrelshifter is
|
13 | begin
|
14 |
|
15 | process (A,B,D)
|
16 | variable s : integer range 0 to 15;
|
17 | variable r : std_logic_vector(15 downto 0);
|
18 | begin
|
19 | s := to_integer(unsigned(B));
|
20 | r := (others=>'0');
|
21 | for i in 0 to 15 loop
|
22 | if D = '1' then r(s+i) := A(i);
|
23 | else r(i) := A(i+s);
|
24 | end if;
|
25 | if (s+i =15) then exit; end if;
|
26 | end loop;
|
27 | ShiftOut <= r;
|
28 | end process;
|
29 | end behavior;
|
Its fine, I tested it with this TB:
1 | library ieee;
|
2 | use ieee.std_logic_1164.all;
|
3 | use ieee.numeric_std.all;
|
4 |
|
5 | entity tb_barrelshifter is
|
6 | end tb_barrelshifter;
|
7 |
|
8 | architecture structure of tb_barrelshifter is
|
9 | component barrelshifter
|
10 | port(A: IN std_logic_vector(15 downto 0);
|
11 | B: IN std_logic_vector(3 downto 0);
|
12 | D: IN std_logic;
|
13 | ShiftOut: OUT std_logic_vector(15 downto 0));
|
14 | end component;
|
15 |
|
16 | signal B: std_logic_vector(3 downto 0);
|
17 | signal A,ShiftOut: std_logic_vector(15 downto 0);
|
18 | signal D: std_logic;
|
19 |
|
20 | begin
|
21 | DUT: barrelshifter port map(A,B,D,ShiftOut);
|
22 |
|
23 | process
|
24 | begin
|
25 | for i in 0 to 15 loop
|
26 | A<= x"8001";
|
27 | B<= std_logic_vector(to_unsigned(i,4));
|
28 | D <='0';
|
29 | wait for 20 ns;
|
30 | end loop;
|
31 |
|
32 | wait for 200 ns;
|
33 |
|
34 | for i in 0 to 15 loop
|
35 | A<= x"8001";
|
36 | B<= std_logic_vector(to_unsigned(i,4));
|
37 | D <='1';
|
38 | wait for 20 ns;
|
39 | end loop;
|
40 |
|
41 | wait for 200 ns;
|
42 |
|
43 | end process;
|
44 | end structure;
|