Add Tercel PHY reset synchronization
[microwatt.git] / plru.vhdl
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use ieee.math_real.all;
5
6 entity plru is
7 generic (
8 BITS : positive := 2
9 )
10 ;
11 port (
12 clk : in std_ulogic;
13 rst : in std_ulogic;
14
15 acc : in std_ulogic_vector(BITS-1 downto 0);
16 acc_en : in std_ulogic;
17 lru : out std_ulogic_vector(BITS-1 downto 0)
18 );
19 end entity plru;
20
21 architecture rtl of plru is
22 constant count : positive := 2 ** BITS - 1;
23 subtype node_t is integer range 0 to count;
24 type tree_t is array(node_t) of std_ulogic;
25
26 signal tree: tree_t;
27 begin
28
29 -- XXX Check if we can turn that into a little ROM instead that
30 -- takes the tree bit vector and returns the LRU. See if it's better
31 -- in term of FPGA resouces usage...
32 get_lru: process(tree)
33 variable node : node_t;
34 begin
35 node := 0;
36 for i in 0 to BITS-1 loop
37 -- report "GET: i:" & integer'image(i) & " node:" & integer'image(node) & " val:" & std_ulogic'image(tree(node));
38 lru(BITS-1-i) <= tree(node);
39 if i /= BITS-1 then
40 node := node * 2;
41 if tree(node) = '1' then
42 node := node + 2;
43 else
44 node := node + 1;
45 end if;
46 end if;
47 end loop;
48 end process;
49
50 update_lru: process(clk)
51 variable node : node_t;
52 variable abit : std_ulogic;
53 begin
54 if rising_edge(clk) then
55 if rst = '1' then
56 tree <= (others => '0');
57 elsif acc_en = '1' then
58 node := 0;
59 for i in 0 to BITS-1 loop
60 abit := acc(BITS-1-i);
61 tree(node) <= not abit;
62 -- report "UPD: i:" & integer'image(i) & " node:" & integer'image(node) & " val" & std_ulogic'image(not abit);
63 if i /= BITS-1 then
64 node := node * 2;
65 if abit = '1' then
66 node := node + 2;
67 else
68 node := node + 1;
69 end if;
70 end if;
71 end loop;
72 end if;
73 end if;
74 end process;
75 end;
76
77