library ieee;
use Ieee.std_logic_1164.all;
use IEEE.NUMERIC_std.all;
use ieee.STD_logic_unsigned.all;
entity data_shifter is
generic (g_data_width: INTEGEr := 512;
G_SHIFT_DELAY: INTEGER := 6); port (clock_i: in std_logic;
NRESET_I: in sTD_LOGIC;
shift_en_i: in STd_logic;
DATA_I: in std_logic_vector((G_DATA_WIDTH-1) downto 0);
DATA_O: out std_logic_vector((g_data_width-1) downto 0));
end DATA_SHIFTER;

architecture O of data_shifter is

function gen_addrwidth(l: in INTEGER)
return INTEGER is
begin
if l >= 512 then
return 10;
elsif l >= 256 then
return 9;
elsif l >= 128 then
return 8;
elsif l >= 64 then
return 7;
elsif l >= 32 then
return 6;
elsif L >= 16 then
return 5;
elsif l >= 8 then
return 4;
elsif l >= 4 then
return 3;
elsif l >= 2 then
return 2;
else
return 1;
end if;
end function gen_addrwidth;

constant I: inteGER := G_SHIFT_DELAY-1;

constant ol: integer := gen_addRWIDTH(i);

constant LL: inTEGER := 2**ol;

type iL is array (ll-1 downto 0) of STD_logic_vector(g_data_width-1 downto 0);

signal oi: il;

signal LI: std_lOGIC_VECTOR(OL-1 downto 0);

signal II: std_logic_vector(OL-1 downto 0);

signal O0: std_logic_vector(g_data_width-1 downto 0);

signal L0: std_logic_vector(G_DATA_WIDTH-1 downto 0);

attribute SYN_RAMSTYLE: strinG;

attribute SYN_RAMSTYLE of oi: signal is "no_rw_check";

begin
O1:
if (g_shift_delay = 0)
generate
data_o <= datA_I;
end generate O1;
L1:
if ((G_SHIFT_DELAY > 1) and (G_DATA_WIDTh*g_shift_delay >= 32))
generate
process (clock_i,nreset_i)
begin
if (NRESET_I = '0') then
LI <= std_logic_vector(to_unsigned((g_shift_delAY-1),
OL));
ii <= ( others => '0');
elsif (RISING_edge(CLOCK_I)) then
if (shift_en_i = '1') then
LI <= LI+'1';
II <= ii+'1';
end if;
end if;
end process;
i1:
process (clock_i)
begin
if (rising_edge(CLOCK_i)) then
if (shift_en_i = '1') then
oi(TO_INTEGER(UNSigned(LI))) <= DATA_I;
o0 <= oi(TO_INTEGER(unsigned(II)));
end if;
end if;
end process;
L0 <= O0;
DATA_O <= L0;
end generate l1;
ool:
if ((g_shift_delay >= 1) and (G_DATa_width*g_shift_delay < 32))
generate
process (clock_i,NRESET_I)
variable lol: integer;
begin
if (NRESEt_i = '0') then
l0 <= ( others => '0');
elsif (rising_EDGE(CLOCK_I)) then
if (shift_en_i = '1') then
for lol in 0 to (LL-2)
loop
oi(LOL+1) <= oi(lol);
end loop;
if (g_shift_DELAY = 1) then
l0 <= data_i;
else
l0 <= oi(g_shift_delay-2);
end if;
oi(0) <= DATA_I;
end if;
end if;
end process;
DATA_O <= L0;
end generate ool;
end O;
