Friday, August 15, 2008

VHDL Part 11 : Shift Register III

There are times when I am given a specific length of vector but the input and the output are only a bit each. The shift register I need is a serial in, serial out. For this, I need to have a variable in which to store the vector where the bits entering one by one are temporarily stored. Note the placement of the variable declaration. As I had mentioned before (see VHDL Part 7 : signal vs variable), variables are local to the process. I had also appended _v to my variable name to remind me that it is a variable. This is especially good for long codes. I arbitrarily chose the LSB as the output bit for shift-right register and MSB for the shift-left register. Here's how I did it..

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity shiftReg is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
shiftEn : in STD_LOGIC;-- enable
sh_in : in STD_LOGIC;
sh_out : out STD_LOGIC);
end shiftReg;


architecture Behavioral of shiftReg is

begin

process (rst, clk)
-- I alloted 5 bits as the length of the bits' bank; replace 4 with the number you want
variable sh_v : std_logic_vector (4 downto 0)
begin

if rst = '1' then

-- initialize the output and the variable to 0
sh _out <= '0'; sh_v := (others => '0');

elsif
clk'event and clk = '1' then
if shiftEn = '1' then

-- the statement below is for shift-right register, for shift-left register, replace the statement below with: sh _v <= sh_v (3 downto 0) & sh_in;
sh_v := sh_in & sh_v (4 downto 1);

end if;
end if;
-- the statement below is for shift-right register, for shift-left register, replace the statement below with: sh _out <= sh_v (4);
sh_out <= sh_v(0);
end process;

end Behavioral;
----------------------------------------------------------------------------------

sh_out being placed outside the if-end if clause simply means that it is default, sh_out will always take the LSB (or MSB) at all times whether reset is high or low, whether the clock is at its rising or falling edge. If this is causing instability in the design, put the statement sh_out <= sh_v(0); inside the clock (inside elsif clk'event and clk = '1' then...end if).

Special thanks to Xilinx for the teaching me how to do this (also for the previous post).
Xilinx Shift Register toolbox

No comments: