我有一个适用于数据和指令缓存的 VHDL 设计。我想用一个测试台来评估它(查找未命中率等)。
所以我想知道如何创建对缓存的随机请求?以及如何使它们偏爱某种类型的局部性或具有某种模式(例如顺序访问,但在程序中偶尔会出现随机跳转)?
换句话说,如何制作一个 VHDL Benchmark 来评估不同条件和内存访问模式下的缓存设计?
我有一个适用于数据和指令缓存的 VHDL 设计。我想用一个测试台来评估它(查找未命中率等)。
所以我想知道如何创建对缓存的随机请求?以及如何使它们偏爱某种类型的局部性或具有某种模式(例如顺序访问,但在程序中偶尔会出现随机跳转)?
换句话说,如何制作一个 VHDL Benchmark 来评估不同条件和内存访问模式下的缓存设计?
要获取随机数,请使用OSVVM - 开源 VHDL 验证方法库。
为了获得“有趣的模式”,您可以利用 Hennessey 和 Patterson 的经典计算机体系结构中提供的缓存访问数据来创建各种大小块大小和分隔的现实概率。
考虑一下您希望看到的缓存模式类型,您应该能够使用 IEEE.MATH_REAL.uniform 在您的测试平台中相当轻松地对它们进行编码。
以偶尔随机跳转的顺序访问为例:
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;
其他访问模式可以以类似的方式实现。