EmbDev.net

Forum: FPGA, VHDL & Verilog Barrel Shifter


von Omar (Guest)


Attached files:

Rate this post
useful
not useful
This is a source code for a linear shift barrel shifter (unclocked). I'm 
having trouble converting the binary input into an integer. Please view 
my code and error and tell me what I'm doing wrong.

BTW, the source and the tb both compile successfully through vhdlan.

: Edited by Moderator
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Omar wrote:
> Please view my code
Pls post your code once more as a vhdl attachmet. Or insert it into your 
posts text surrounded by the vhdl tokens (see the formatting options 
just a very few lines under
1
Reply
2
Rules — please read before posting
And you can also copy and paste the error messages.

I will not look at some pictures and retype all the code for a hint (and 
I have at least 4 of them...).

von Omar (Guest)


Rate this post
useful
not useful
Source code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
use ieee.std_logic_unsigned.all;
5
6
entity barrelshifter is
7
port(A,B: IN std_logic_vector(15 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
14
15
begin
16
17
process (A,B,D)
18
variable shift:integer range 0 to 65535:= to_integer(unsigned(B));
19
variable append: std_logic_vector (shift downto 1);
20
variable V: std_logic_vector((shift+15) downto 0);
21
  begin
22
  for i in 1 to shift loop
23
    append(i) := '0';
24
  end loop;
25
  if D = '1' then
26
    V := append & A;
27
    ShiftOut <= V(15 downto 0);
28
  else
29
    V := A & append;
30
    ShiftOut <= V((shift+15) downto shift);
31
  end if;
32
end process;
33
end behavior;

Test bench
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
use ieee.std_logic_unsigned.all;
5
6
entity tb_barrelshifter is
7
end tb_barrelshifter;
8
9
architecture structure of tb_barrelshifter is
10
component barrelshifter
11
  port(A,B: IN std_logic_vector(15 downto 0);
12
       D: IN std_logic;
13
       ShiftOut: OUT std_logic_vector(15 downto 0));
14
end component;
15
16
signal A,B,ShiftOut: std_logic_vector(15 downto 0);
17
signal D: std_logic;
18
19
begin
20
DUT: barrelshifter port map(A,B,D,ShiftOut);
21
22
process
23
begin
24
wait for 0 ns; A<= x"0001"; B<=x"0002"; D <='0';
25
wait for 20 ns;
26
end process;
27
end structure;
28
29
configuration tb_barrelshifter_con of tb_barrelshifter is
30
for structure
31
end for;
32
end tb_barrelshifter_con;

: Edited by Moderator
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Attached files:

Rate this post
useful
not useful
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;

: Edited by Moderator
von Omar (Guest)


Rate this post
useful
not useful
Thanks for your input. I have tried implementing your code with one 
minor change (I left B as an 8 bit vector because that is the assignment 
requirement - for some reason): This is my code:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity barrelshifter is
6
port(A,B: IN std_logic_vector(15 downto 0);
7
     D: IN std_logic;
8
     ShiftOut: OUT std_logic_vector (15 downto 0));
9
end barrelshifter;
10
11
architecture behavior of barrelshifter is
12
13
begin
14
15
process (A,B,D)
16
variable shift:integer range 0 to 65535;
17
variable V: std_logic_vector(15 downto 0):= (others=> '0');
18
  begin
19
  shift:= to_integer(unsigned(B));
20
  for i in 0 to (15-shift) loop
21
    if D = '1' then
22
      V(shift+i) := A(i);
23
    else
24
      V(i) := A(shift+i);
25
    end if;
26
    if (shift+i = 15) then 
27
    exit;
28
    end if;
29
  end loop;
30
  ShiftOut <= V;
31
end process;
32
end behavior;

With this test bench
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
use ieee.std_logic_unsigned.all;
5
6
entity tb_barrelshifter is
7
end tb_barrelshifter;
8
9
architecture structure of tb_barrelshifter is
10
component barrelshifter
11
  port(A,B: IN std_logic_vector(15 downto 0);
12
       D: IN std_logic;
13
       ShiftOut: OUT std_logic_vector(15 downto 0));
14
end component;
15
16
signal A,B,ShiftOut: std_logic_vector(15 downto 0);
17
signal D: std_logic;
18
19
begin
20
DUT: barrelshifter port map(A,B,D,ShiftOut);
21
22
process
23
begin
24
wait for 0 ns; A<= x"0001"; B<=x"0002"; D <='0';
25
wait for 20 ns; A<= x"0050"; B<= x"0010"; D <= '1';
26
wait for 20 ns;
27
28
end process;
29
end structure;
30
31
configuration tb_barrelshifter_con of tb_barrelshifter is
32
for structure
33
end for;
34
end tb_barrelshifter_con;

When I run the TB my ShiftOut is an undeclared most significant bit 
followed by zeros.... I do not get it...

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Attached files:

Rate this post
useful
not useful
Omar wrote:
> I do not get it...
No comment!

> With this test bench
> use ieee.numeric_std.all;
> use ieee.std_logic_unsigned.all;
Didn't you read my post? Or didn't you understand it?

Omar wrote:
> I have tried implementing your code with one minor change
You did some minor changes:
1
variable V: std_logic_vector(15 downto 0):= (others=> '0');
If you don't do the
A process isn't like a function call in software! It is evaluated bay 
the simulator each time one of the signals in the sensitivity list 
changes. If you don't do an explicit reset of V then it will memorize 
its value from the last evaluation! So you MUST reset it to zero the way 
I did!

And this here?
1
  for i in 0 to (15-shift) loop
Also just a minor change?

Omar wrote:
> an undeclared most significant bit
Have a look, what 'U' excalty means!

Omar wrote:
> - for some reason
If you shift a 16 bit vector more than 15 times, then the result is all 
zero.

Try 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,B: IN std_logic_vector(15 downto 0);
7
     D: IN std_logic;
8
     ShiftOut: OUT std_logic_vector (15 downto 0));
9
end barrelshifter;
10
11
architecture behavior of barrelshifter is
12
13
begin
14
15
process (A,B,D)
16
variable shift:integer range 0 to 65535;
17
variable V: std_logic_vector(15 downto 0);
18
  begin
19
  shift:= to_integer(unsigned(B));
20
  V    := (others=> '0');
21
  if shift <16 then
22
    for i in 0 to 15 loop
23
      if D = '1' then
24
        V(shift+i) := A(i);
25
      else
26
        V(i) := A(shift+i);
27
      end if;
28
      if (shift+i = 15) then 
29
        exit;
30
      end if;
31
    end loop;
32
  end if;
33
  ShiftOut <= V;
34
end process;
35
end behavior;
Now the simulation looks fine (screenshot). Just the stimuli is 
nonsense. Think about it!

And for the future: if somebody would present me a fully functional 
sample and I would do "just minor changes" and afterwards it would not 
run anymore, then I would try to figure out myself, what change caused 
the problem. This process is called "learning"!

: Edited by Moderator
von ebrahim (Guest)


Rate this post
useful
not useful
Design and implement a Sequence Detector.
1- Subject: FDesign a Sequence Detector.
2- Function requirements: FThe detector has an input terminal X,
signal is detected for the serial input binary sequence, the detector 
has an
output terminal Z, when a binary sequence have 4 consecutive 1, the
output is 1, the output of remaining cases is 0. For example:
X= 1101111110110
Z= 0000001110000

von Duke Scarring (Guest)


Rate this post
useful
not useful
New problem, new topic please!

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.