EmbDev.net

Forum: FPGA, VHDL & Verilog Barrel Shifter


Author: Omar (Guest)
Posted on:
Attached files:

Rate this post
0 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
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 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
Reply
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...).

Author: Omar (Guest)
Posted on:

Rate this post
0 useful
not useful
Source code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity barrelshifter is
port(A,B: IN std_logic_vector(15 downto 0);
     D: IN std_logic;
     ShiftOut: OUT std_logic_vector (15 downto 0));
end barrelshifter;

architecture behavior of barrelshifter is


begin

process (A,B,D)
variable shift:integer range 0 to 65535:= to_integer(unsigned(B));
variable append: std_logic_vector (shift downto 1);
variable V: std_logic_vector((shift+15) downto 0);
  begin
  for i in 1 to shift loop
    append(i) := '0';
  end loop;
  if D = '1' then
    V := append & A;
    ShiftOut <= V(15 downto 0);
  else
    V := A & append;
    ShiftOut <= V((shift+15) downto shift);
  end if;
end process;
end behavior;

Test bench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity tb_barrelshifter is
end tb_barrelshifter;

architecture structure of tb_barrelshifter is
component barrelshifter
  port(A,B: IN std_logic_vector(15 downto 0);
       D: IN std_logic;
       ShiftOut: OUT std_logic_vector(15 downto 0));
end component;

signal A,B,ShiftOut: std_logic_vector(15 downto 0);
signal D: std_logic;

begin
DUT: barrelshifter port map(A,B,D,ShiftOut);

process
begin
wait for 0 ns; A<= x"0001"; B<=x"0002"; D <='0';
wait for 20 ns;
end process;
end structure;

configuration tb_barrelshifter_con of tb_barrelshifter is
for structure
end for;
end tb_barrelshifter_con;

: Edited by Moderator
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Lothar Miller wrote:
> insert it into your posts text surrounded by the vhdl tokens
[vhdl] VHDL Code [/vhdl]
Ok, I did it for you. Now lets start:

Never use both of the arithmetic libraries together:
use ieee.numeric_std.all;
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:
  for i in 1 to shift loop
    append(i) := '0';
  end loop;
Do it this way:
  append := (others=>'0');

Where is this "15" from?
variable V: std_logic_vector((shift+15) downto 0);

And why should you try to shift a 16 bit vector 65536 times?
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:
variable shift:integer range 0 to 65535:= to_integer(unsigned(B));
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:
  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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity barrelshifter is
port(A: IN std_logic_vector(15 downto 0);
     B: IN std_logic_vector(3 downto 0);
     D: IN std_logic;
     ShiftOut: OUT std_logic_vector (15 downto 0));
end barrelshifter;

architecture behavior of barrelshifter is
begin

  process (A,B,D)
  variable s : integer range 0 to 15;
  variable r : std_logic_vector(15 downto 0);
  begin
    s := to_integer(unsigned(B));
    r := (others=>'0');
    for i in 0 to 15 loop
      if D = '1' then r(s+i) := A(i);
      else            r(i) := A(i+s);
      end if;
      if (s+i =15) then exit; end if;
    end loop;
    ShiftOut <= r;
  end process;
end behavior;

Its fine, I tested it with this TB:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb_barrelshifter is
end tb_barrelshifter;

architecture structure of tb_barrelshifter is
component barrelshifter
port(A: IN std_logic_vector(15 downto 0);
     B: IN std_logic_vector(3 downto 0);
     D: IN std_logic;
ShiftOut: OUT std_logic_vector(15 downto 0));
end component;

signal B: std_logic_vector(3 downto 0);
signal A,ShiftOut: std_logic_vector(15 downto 0);
signal D: std_logic;

begin
DUT: barrelshifter port map(A,B,D,ShiftOut);

process
begin
for i in 0 to 15 loop
  A<= x"8001";
  B<= std_logic_vector(to_unsigned(i,4));
  D <='0';
  wait for 20 ns;
end loop;

wait for 200 ns;

for i in 0 to 15 loop
  A<= x"8001";
  B<= std_logic_vector(to_unsigned(i,4));
  D <='1';
  wait for 20 ns;
end loop;

wait for 200 ns;

end process;
end structure;

: Edited by Moderator
Author: Omar (Guest)
Posted on:

Rate this post
0 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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity barrelshifter is
port(A,B: IN std_logic_vector(15 downto 0);
     D: IN std_logic;
     ShiftOut: OUT std_logic_vector (15 downto 0));
end barrelshifter;

architecture behavior of barrelshifter is

begin

process (A,B,D)
variable shift:integer range 0 to 65535;
variable V: std_logic_vector(15 downto 0):= (others=> '0');
  begin
  shift:= to_integer(unsigned(B));
  for i in 0 to (15-shift) loop
    if D = '1' then
      V(shift+i) := A(i);
    else
      V(i) := A(shift+i);
    end if;
    if (shift+i = 15) then 
    exit;
    end if;
  end loop;
  ShiftOut <= V;
end process;
end behavior;

With this test bench
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity tb_barrelshifter is
end tb_barrelshifter;

architecture structure of tb_barrelshifter is
component barrelshifter
  port(A,B: IN std_logic_vector(15 downto 0);
       D: IN std_logic;
       ShiftOut: OUT std_logic_vector(15 downto 0));
end component;

signal A,B,ShiftOut: std_logic_vector(15 downto 0);
signal D: std_logic;

begin
DUT: barrelshifter port map(A,B,D,ShiftOut);

process
begin
wait for 0 ns; A<= x"0001"; B<=x"0002"; D <='0';
wait for 20 ns; A<= x"0050"; B<= x"0010"; D <= '1';
wait for 20 ns;

end process;
end structure;

configuration tb_barrelshifter_con of tb_barrelshifter is
for structure
end for;
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...

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:
Attached files:

Rate this post
0 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:
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?
  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:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity barrelshifter is
port(A,B: IN std_logic_vector(15 downto 0);
     D: IN std_logic;
     ShiftOut: OUT std_logic_vector (15 downto 0));
end barrelshifter;

architecture behavior of barrelshifter is

begin

process (A,B,D)
variable shift:integer range 0 to 65535;
variable V: std_logic_vector(15 downto 0);
  begin
  shift:= to_integer(unsigned(B));
  V    := (others=> '0');
  if shift <16 then
    for i in 0 to 15 loop
      if D = '1' then
        V(shift+i) := A(i);
      else
        V(i) := A(shift+i);
      end if;
      if (shift+i = 15) then 
        exit;
      end if;
    end loop;
  end if;
  ShiftOut <= V;
end process;
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

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.