cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
studentx233
Newbie
Newbie
18,806 Views
Registered: ‎07-10-2012

Descirbing an n-Shifter in VHDL

Hello,

 

I need to describe a shifter that shifts a 32-Bit register n-times to the left. How the hell do I descirbe this in VHDL. When I try to synthetisize this piece of code right here, it will say that the for loop needs constant ranges and that the variable const aint allowed there. Look, heres my code:

 

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_misc.all;

use IEEE.std_logic_signed.all;

use IEEE.numeric_std.all;



entity shifter is

	port (

		s : in std_logic_vector (4 downto 0);

		d : in std_logic_vector (31 downto 0);

		q : out std_logic_vector (31 downto 0)

	);

end shifter;



architecture behavior of shifter

begin

	process(s, d)

		variable const : Integer;

		variable temp : std_logic_vector(31 downto 0);

	begin

		const := conv_integer(s);

		temp := d;



		if const >= 1 and const <= 32 then

			for i in 1 to const loop

				temp := temp(30 downto 0) & '0'

			end loop;

		end if;



		q <= temp;

	end process;

end behavior;

 

0 Kudos
8 Replies
gszakacs
Instructor
Instructor
18,805 Views
Registered: ‎08-14-2007

XST has a limitation that loops need to iterate a fixed number of times.  So your

loop "for i in 1 to const" where "const" isn't really constant means that XST has a

problem with the loop.

 

One way to work around this is to always loop for i from 1 to 32, and then use a conditional

to only shift while i is less than or equal to const.

 

On the other hand this seems like a hard way to do a shifter.  In Verilog this would

just be something like

 

assign q = d << s;

 

-- Gabor

-- Gabor
studentx233
Newbie
Newbie
18,800 Views
Registered: ‎07-10-2012

So basically youre sayin, im supposed to do it like this, right? My aim is to kinda get a barel shifter synthetizised.

 

 

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_misc.all;

use IEEE.std_logic_signed.all;

use IEEE.numeric_std.all;



entity shifter is

	port (

		s : in std_logic_vector (4 downto 0);

		d : in std_logic_vector (31 downto 0);

		q : out std_logic_vector (31 downto 0)

	);

end shifter;



architecture behavior of shifter

begin

	process(s, d)

		variable const : Integer;

		variable temp : std_logic_vector(31 downto 0);

	begin

		const := conv_integer(s);

		temp := d;


		for i in 1 to 32 loop
			if i <= const then

				temp := temp(30 downto 0) & '0';
			end if;

		end loop;


		q <= temp;

	end process;

end behavior;

 

0 Kudos
gszakacs
Instructor
Instructor
18,796 Views
Registered: ‎08-14-2007


@studentx233 wrote:

So basically youre sayin, im supposed to do it like this, right? My aim is to kinda get a barel shifter synthetizised.

 

 



Yes, that looks like it.  Did you try to synthesize this version?

 

-- Gabor

-- Gabor
0 Kudos
rcingham
Teacher
Teacher
18,773 Views
Registered: ‎09-09-2010

en.wikipedia.org/wiki/Barrel_shifter

and

www.google.com/search?q=barrel+shifter+vhdl

 


------------------------------------------
"If it don't work in simulation, it won't work on the board."
bassman59
Historian
Historian
18,760 Views
Registered: ‎02-25-2008

A barrel shifter is more easily implemented as a mux whose select is the number of positions you wish to shift. Unless, of course, you can stand the n clocks of latency to actually rotate the data in the shifter. There is actually one mux per bit position. A 32-bit barrel shifter, then, has thirty-two 32-input multiplexors.

 

Your specific requirement is to shift n bits to the left, so we can assume you're shifting in zeros. In other words, the bits to the right of n are irrelevant. But let's ignore that, unless it's actually important.

 

I'm usually loathe to do someone's homework, but this seemed like an interesting problem to solve, so I spent a few minutes at lunchtime thinking about it, and here's what I came up with. 

 

library ieee;
use ieee.std_logic_1164.all;

entity barrelshifter is
    port (
        inword   : in std_logic_vector;
        shift    : in natural;
        outword  : out std_logic_vector);
end entity barrelshifter;


architecture barrel of barrelshifter is
begin

   -- Each bit in the output vector has its own mux.
   -- Use the input word bit position as an "offset," to which the new
   -- position is subtracted, modulo the word size, to give the mux select.

       EachBit: for bitpos in inword'range generate

      outword(bitpos) <= inword((bitpos - shift) mod (inword'high + 1));
   end generate EachBit;
end architecture barrel;

 

I take advantage of a couple of VHDL features to make the shifter as general as possible.

 

First, note that the input and output words are unconstrained std_logic_vectors, meaning they can be any width you like. How do you set the width? Read your VHDL text. But basically, when you instantiate the entity in a higher-level entity, the actuals used on the port map must be constrained.

 

Also, the position port is an unconstrained natural, meaning it's a 32-bit number (very big). Your instance's port map should connect it to a natural whose range is the same as the number of bits in data vectors.

 

Finally, the generate creates one mux per bit in the input word. The mux select is derived from the bit position in the output vector we're creating a mux for and the shift amount. The modulo is necessary so you don't try to select an illegal bit position.

 

You can improve the code by adding assertions to test whether the input and output vectors are the same size, and also to flag if the shift amount exceeds the number of bits in the data vectors.

 

Here's a simple test bench.

 

library ieee;
use ieee.std_logic_1164.all;


entity barrelshifter_tb is
end entity barrelshifter_tb;


architecture testbench of barrelshifter_tb is

    signal inword  : std_logic_vector(31 downto 0) := (others => '0');
    signal shift   : natural range 0 to 31 := 0;
    signal outword : std_logic_vector(31 downto 0);

begin -- architecture testbench

    dut : entity work.barrelshifter
        port map (
            inword  => inword,
            shift   => shift,
            outword => outword);

 

    MainTest : process is
    begin -- process MainTest
        wait for 100 NS;
        inword <= X"00000001";
        LoopOverShift : for pos in 0 to 31 loop
            wait for 100 NS;
            shift <= pos;
        end loop LoopOverShift;

        wait;
    end process MainTest;
end architecture testbench;

 

Do NOT use both std_logic_arith/std_logic_unsigned and numeric_std in your code. numeric_std only, please.

----------------------------Yes, I do this for a living.
0 Kudos
shuklaankita
Visitor
Visitor
18,108 Views
Registered: ‎02-22-2013

Can anyone help me with the code for interfacing lvds camera  with fpga on video starter kit???? virtex-4 XC4VSX35

Kindly help me I donot hv a month also to complete ma project... please...

0 Kudos
bassman59
Historian
Historian
18,076 Views
Registered: ‎02-25-2008


@shuklaankita wrote:

Can anyone help me with the code for interfacing lvds camera  with fpga on video starter kit???? virtex-4 XC4VSX35

Kindly help me I donot hv a month also to complete ma project... please...


You really should have thought of starting to work on your project at the beginning of the semester.

I can help you but it will cost you dearly.

----------------------------Yes, I do this for a living.
0 Kudos
shuklaankita
Visitor
Visitor
18,050 Views
Registered: ‎02-22-2013

thank u sir

0 Kudos