-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathleft_shift.vhd
114 lines (97 loc) · 3.75 KB
/
left_shift.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity left_shift is
generic (
SHIFT_BITS : positive := 1;
WORD_WIDTH : positive := 8;
NUM_WORDS : positive := 2);
port (
clk : in std_logic;
rst : in std_logic;
en : in std_logic := '1';
input : in std_logic_vector(WORD_WIDTH*NUM_WORDS-1 downto 0);
shift_amount : in std_logic_vector(SHIFT_BITS-1 downto 0);
output : out std_logic_vector(WORD_WIDTH*NUM_WORDS-1 downto 0);
valid_in : in std_logic;
valid_out : out std_logic);
end left_shift;
architecture DEFAULT of left_shift is
constant LEVELS : positive := SHIFT_BITS;
type word_array is array (0 to LEVELS-1, 0 to NUM_WORDS-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
signal words : word_array;
type input_array is array (0 to NUM_WORDS-1) of std_logic_vector(WORD_WIDTH-1 downto 0);
signal inputs : input_array;
type shift_array is array (0 to LEVELS-1) of std_logic_vector(SHIFT_BITS-1 downto 0);
signal shift : shift_array;
begin
-- convert input vector into 2d array
process(input)
begin
for i in 0 to NUM_WORDS-1 loop
inputs(i) <= input(input'length-i*WORD_WIDTH-1 downto input'length-(i+1)*WORD_WIDTH);
end loop;
end process;
process(clk, rst)
begin
if (rst = '1') then
for i in 0 to LEVELS-1 loop
for j in 0 to NUM_WORDS-1 loop
words(i, j) <= (others => '0');
end loop;
shift(i) <= (others => '0');
end loop;
elsif (rising_edge(clk)) then
-- level 0
for j in 0 to NUM_WORDS-1 loop
if (en = '1') then
if (shift_amount(LEVELS-1) = '1') then
if (j+2**(LEVELS-1) >= NUM_WORDS) then
words(0, j) <= (others => '0');
else
words(0, j) <= inputs(j+2**(LEVELS-1));
end if;
else
words(0, j) <= inputs(j);
end if;
shift(0) <= shift_amount;
end if;
end loop;
for i in 1 to LEVELS-1 loop
shift(i) <= shift(i-1);
for j in 0 to NUM_WORDS-1 loop
if (en = '1') then
if (shift(i-1)(LEVELS-i-1) = '1') then
-- if word to shift from doesn't exist, shift in 0
-- else, shift in words based on the level
if (j+2**(LEVELS-i-1) >= NUM_WORDS) then
words(i, j) <= (others => '0');
else
words(i, j) <= words(i-1, j+2**(LEVELS-i-1));
end if;
else
words(i, j) <= words(i-1, j);
end if;
end if;
end loop;
end loop;
end if;
end process;
process(words)
begin
for i in 0 to NUM_WORDS-1 loop
output((NUM_WORDS-i)*WORD_WIDTH-1 downto (NUM_WORDS-i-1)*WORD_WIDTH) <= words(LEVELS-1, i);
end loop;
end process;
U_DELAY : entity work.delay
generic map (
width => 1,
cycles => LEVELS,
init => "0")
port map (
clk => clk,
rst => rst,
en => en,
input(0) => valid_in,
output(0) => valid_out);
end DEFAULT;