Search code examples
benchmarkingvhdlcpu-architecture

Creating a cache memory benchmark in VHDL


I have a working VHDL design for Data&Instruction Caches. I want to evaluate it (find miss rates and so) with a testbench.

So I want to know how to create random requests to the caches? and how to make them favor some type of locality or have a pattern (like sequential access but with occasional random jumps in a program for example)?

In other words, how to make a VHDL Benchmark to evaluate the cache designs in different conditions and memory access patterns?


Solution

  • Think about the types of cache patterns you would like to see, and you should be able to code them fairly easily in your testbench using IEEE.MATH_REAL.uniform.

    To take your example of sequential access with occasional random jumps:

    library IEEE;
    use IEEE.STD_LOGIC_1164.all;
    use IEEE.NUMERIC_STD.all;
    use IEEE.MATH_REAL.all;
    
    entity ...
    
    architecture ...
        signal cache_read : std_logic := '0';
        signal cache_addr : unsigned(31 downto 0) := (others=>'0');
    
        ...
    begin
        sequential_and_jumps: process
                variable seed1, seed2 : positive := 42;
                variable rand         : real;
                variable loops        : integer;
                variable addr         : integer;
        begin
            cache_read <= '0';
            wait until reset='0' and rising_edge(clk);
    
            -- Starting address.
            addr := 0;
    
            -- Continual repeated accesses.
            loop
                -- Randomly jump to a new address between 0x0 and 0x10000
                -- with a chance of 10%.
                uniform(seed1, seed2, rand);
                if(rand < 0.1) then
                    uniform(seed1, seed2, rand);
                    addr := integer(trunc(rand * real(16#10000#)));
                end if;
    
                -- Wait 0-15 cycles prior to the cache request.
                uniform(seed1, seed2, rand);
                loops := integer(trunc(rand*16.0));
                for i in 1 to loops loop
                    wait until rising_edge(clk);
                end loop;
    
                -- Randomly request 1-32 words.
                uniform(seed1, seed2, rand);
                loops := integer(trunc(rand*32.0)) + 1;
                for i in 1 to loops loop
                    cache_addr <= to_unsigned(addr, cache_addr'length);
                    cache_read <= '1';
                    wait until rising_edge(clk);
                    cache_read <= '0';
                    -- Assumes word addresses.
                    -- For byte addresses, increment by e.g. 4 for 32-bit words.
                    addr := addr + 1;
                end loop;
            end loop;
        end process;
    end architecture;
    

    Other access patterns can be achieved in a similar manner.