diff --git a/Makefile b/Makefile index 2a856de..49f7cc1 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ all: $(all) $(shell scripts/make_version.sh git.vhdl) core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \ - utils.vhdl plru.vhdl plrufn.vhdl cache_ram.vhdl icache.vhdl \ + utils.vhdl plrufn.vhdl cache_ram.vhdl icache.vhdl \ predecode.vhdl decode1.vhdl helpers.vhdl insn_helpers.vhdl \ control.vhdl decode2.vhdl register_file.vhdl \ cr_file.vhdl crhelpers.vhdl ppc_fx_insns.vhdl rotator.vhdl \ diff --git a/microwatt.core b/microwatt.core index bb6770d..bab35fa 100644 --- a/microwatt.core +++ b/microwatt.core @@ -33,7 +33,6 @@ filesets: - insn_helpers.vhdl - core.vhdl - icache.vhdl - - plru.vhdl - plrufn.vhdl - cache_ram.vhdl - core_debug.vhdl diff --git a/plru.vhdl b/plru.vhdl deleted file mode 100644 index 1c6533d..0000000 --- a/plru.vhdl +++ /dev/null @@ -1,86 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use ieee.math_real.all; - -entity plru is - generic ( - BITS : positive := 2 - ) - ; - port ( - clk : in std_ulogic; - rst : in std_ulogic; - - acc : in std_ulogic_vector(BITS-1 downto 0); - acc_en : in std_ulogic; - lru : out std_ulogic_vector(BITS-1 downto 0) - ); -end entity plru; - -architecture rtl of plru is - -- Each level of the tree (from leaf to root) has half the number of nodes - -- of the previous level. So for a 2^N bits LRU, we have a level of N/2 bits - -- one of N/4 bits etc.. down to 1. This gives us 2^N-1 nodes. Ie, 2 bits - -- LRU has 3 nodes (2 + 1), 4 bits LRU has 15 nodes (8 + 4 + 2 + 1) etc... - constant count : positive := 2 ** BITS - 1; - subtype node_t is integer range 0 to count - 1; - type tree_t is array(node_t) of std_ulogic; - - signal tree: tree_t; -begin - - -- XXX Check if we can turn that into a little ROM instead that - -- takes the tree bit vector and returns the LRU. See if it's better - -- in term of FPGA resource usage... - get_lru: process(tree) - variable node : node_t; - variable abit : std_ulogic; - begin - node := 0; - for i in 0 to BITS-1 loop --- report "GET: i:" & integer'image(i) & " node:" & integer'image(node) & " val:" & std_ulogic'image(tree(node)); - abit := tree(node); - lru(BITS-1-i) <= abit; - if i /= BITS-1 then - node := node * 2; - if abit = '1' then - node := node + 2; - else - node := node + 1; - end if; - end if; - end loop; - end process; - - update_lru: process(clk) - variable node : node_t; - variable abit : std_ulogic; - begin - if rising_edge(clk) then - if rst = '1' then - tree <= (others => '0'); - elsif acc_en = '1' then - node := 0; - for i in 0 to BITS-1 loop - abit := acc(BITS-1-i); - tree(node) <= not abit; --- report "UPD: i:" & integer'image(i) & " node:" & integer'image(node) & " val" & std_ulogic'image(not abit); - if i /= BITS-1 then - node := node * 2; - if abit = '1' then - node := node + 2; - else - node := node + 1; - end if; - end if; - end loop; - end if; - end if; --- if falling_edge(clk) then --- if acc_en = '1' then --- report "UPD: tree:" & to_string(tree); --- end if; --- end if; - end process; -end; diff --git a/plru_tb.vhdl b/plru_tb.vhdl index 2cd09f9..fa9c115 100644 --- a/plru_tb.vhdl +++ b/plru_tb.vhdl @@ -3,6 +3,7 @@ context vunit_lib.vunit_context; library ieee; use ieee.std_logic_1164.all; +use ieee.numeric_std.all; library work; use work.common.all; @@ -17,22 +18,25 @@ architecture behave of plru_tb is signal rst : std_ulogic; constant clk_period : time := 10 ns; + constant plru_bits : integer := 3; - signal acc_en : std_ulogic; - signal acc : std_ulogic_vector(2 downto 0); - signal lru : std_ulogic_vector(2 downto 0); + subtype plru_val_t is std_ulogic_vector(plru_bits - 1 downto 0); + subtype plru_tree_t is std_ulogic_vector(2 ** plru_bits - 2 downto 0); + signal do_update : std_ulogic := '0'; + signal acc : plru_val_t; + signal lru : plru_val_t; + signal state : plru_tree_t; + signal state_upd : plru_tree_t; begin - plru0: entity work.plru + plrufn0: entity work.plrufn generic map( - BITS => 3 + BITS => plru_bits ) port map( - clk => clk, - rst => rst, - acc => acc, - acc_en => acc_en, + tree_in => state, + tree_out => state_upd, lru => lru ); @@ -52,75 +56,59 @@ begin wait; end process; - stim: process + plru_process: process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + state <= (others => '0'); + elsif do_update = '1' then + state <= state_upd; + end if; + end if; + end process; + + stim_process: process + procedure test_access(acc_val: integer; expected: integer) is + begin + acc <= std_ulogic_vector(to_unsigned(acc_val, acc'length)); + do_update <= '1'; + wait for clk_period; + info("accessed " & integer'image(acc_val) & " LRU=" & to_hstring(lru)); + check_equal(lru, expected, result("LRU ACC=" & integer'image(acc_val))); + end procedure; begin test_runner_setup(runner, runner_cfg); wait for 8*clk_period; info("reset state:" & to_hstring(lru)); - check_equal(lru, 0, result("LRU")); - - info("accessing 1:"); - acc <= "001"; - acc_en <= '1'; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 4, result("LRU")); - - info("accessing 2:"); - acc <= "010"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 4, result("LRU")); - - info("accessing 7:"); - acc <= "111"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 0, result("LRU")); - - info("accessing 4:"); - acc <= "100"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 0, result("LRU")); + check_equal(lru, 0, result("LRU ")); + + test_access(1, 4); + test_access(2, 4); + test_access(7, 0); + test_access(4, 0); + test_access(3, 6); + test_access(5, 0); + test_access(3, 6); + test_access(5, 0); + test_access(6, 0); + test_access(0, 4); + test_access(1, 4); + test_access(2, 4); + test_access(3, 4); + test_access(4, 0); + test_access(5, 0); + test_access(6, 0); + test_access(7, 0); + test_access(6, 0); + test_access(5, 0); + test_access(4, 0); + test_access(3, 7); + test_access(2, 7); + test_access(1, 7); + test_access(0, 7); - info("accessing 3:"); - acc <= "011"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 6, result("LRU")); - - info("accessing 5:"); - acc <= "101"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 0, result("LRU")); - - info("accessing 3:"); - acc <= "011"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 6, result("LRU")); - - info("accessing 5:"); - acc <= "101"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 0, result("LRU")); - - info("accessing 6:"); - acc <= "110"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 0, result("LRU")); - - info("accessing 0:"); - acc <= "000"; - wait for clk_period; - info("lru:" & to_hstring(lru)); - check_equal(lru, 4, result("LRU")); wait for clk_period; wait for clk_period;