---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- CPU model
|
-- CPU model
|
--
|
--
|
-- Part of the LXP32 instruction cache testbench
|
-- Part of the LXP32 instruction cache testbench
|
--
|
--
|
-- Copyright (c) 2016 by Alex I. Kuznetsov
|
-- Copyright (c) 2016 by Alex I. Kuznetsov
|
--
|
--
|
-- Requests data from cache
|
-- Requests data from cache
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
use ieee.math_real.all;
|
use ieee.math_real.all;
|
|
|
use work.common_pkg.all;
|
use work.common_pkg.all;
|
use work.tb_pkg.all;
|
use work.tb_pkg.all;
|
|
|
entity cpu_model is
|
entity cpu_model is
|
generic(
|
generic(
|
BLOCKS: integer;
|
BLOCKS: integer;
|
VERBOSE: boolean
|
VERBOSE: boolean
|
);
|
);
|
port(
|
port(
|
clk_i: in std_logic;
|
clk_i: in std_logic;
|
|
|
lli_re_o: out std_logic;
|
lli_re_o: out std_logic;
|
lli_adr_o: out std_logic_vector(29 downto 0);
|
lli_adr_o: out std_logic_vector(29 downto 0);
|
lli_dat_i: in std_logic_vector(31 downto 0);
|
lli_dat_i: in std_logic_vector(31 downto 0);
|
lli_busy_i: in std_logic;
|
lli_busy_i: in std_logic;
|
|
|
finish_o: out std_logic
|
finish_o: out std_logic
|
);
|
);
|
end entity;
|
end entity;
|
|
|
architecture sim of cpu_model is
|
architecture sim of cpu_model is
|
|
|
constant bursts: integer:=10000;
|
constant bursts: integer:=10000;
|
|
|
signal re: std_logic:='0';
|
signal re: std_logic:='0';
|
signal lli_adr: std_logic_vector(29 downto 0);
|
signal lli_adr: std_logic_vector(29 downto 0);
|
|
|
signal request: std_logic:='0';
|
signal request: std_logic:='0';
|
signal request_addr: std_logic_vector(29 downto 0);
|
signal request_addr: std_logic_vector(29 downto 0);
|
|
|
signal finish: std_logic:='0';
|
signal finish: std_logic:='0';
|
|
|
signal current_latency: integer:=1;
|
signal current_latency: integer:=1;
|
signal max_latency: integer:=-1;
|
signal max_latency: integer:=-1;
|
signal total_latency: integer:=0;
|
signal total_latency: integer:=0;
|
signal spurious_misses: integer:=0;
|
signal spurious_misses: integer:=0;
|
|
|
begin
|
begin
|
|
|
process is
|
process is
|
variable b: integer:=1;
|
variable b: integer:=1;
|
variable start: integer;
|
variable start: integer;
|
variable size: integer;
|
variable size: integer;
|
variable addr: integer:=0;
|
variable addr: integer:=0;
|
variable delay: integer;
|
variable delay: integer;
|
variable rng_state: rng_state_type;
|
variable rng_state: rng_state_type;
|
variable r: integer;
|
variable r: integer;
|
variable total_requests: integer:=0;
|
variable total_requests: integer:=0;
|
begin
|
begin
|
while b<=BLOCKS loop
|
while b<=BLOCKS loop
|
rand(rng_state,1,10,r);
|
rand(rng_state,1,10,r);
|
if r=1 then -- insert large block occasionally
|
if r=1 then -- insert large block occasionally
|
rand(rng_state,1,400,size);
|
rand(rng_state,1,400,size);
|
else -- small block
|
else -- small block
|
rand(rng_state,1,32,size);
|
rand(rng_state,1,32,size);
|
end if;
|
end if;
|
|
|
rand(rng_state,0,1,r);
|
rand(rng_state,0,1,r);
|
if r=0 then -- long jump
|
if r=0 then -- long jump
|
rand(rng_state,0,1024,start);
|
rand(rng_state,0,1024,start);
|
addr:=start;
|
addr:=start;
|
if VERBOSE then
|
if VERBOSE then
|
report "Fetching block #"&integer'image(b)&" at address "&integer'image(addr)&
|
report "Fetching block #"&integer'image(b)&" at address "&integer'image(addr)&
|
" of size "&integer'image(size);
|
" of size "&integer'image(size);
|
end if;
|
end if;
|
else -- short jump
|
else -- short jump
|
rand(rng_state,-10,10,r);
|
rand(rng_state,-10,10,r);
|
start:=addr+r;
|
start:=addr+r;
|
if start<0 then
|
if start<0 then
|
start:=0;
|
start:=0;
|
end if;
|
end if;
|
addr:=start;
|
addr:=start;
|
if VERBOSE then
|
if VERBOSE then
|
report "Fetching block #"&integer'image(b)&" at address "&integer'image(addr)&
|
report "Fetching block #"&integer'image(b)&" at address "&integer'image(addr)&
|
" of size "&integer'image(size)&" (short jump)";
|
" of size "&integer'image(size)&" (short jump)";
|
end if;
|
end if;
|
end if;
|
end if;
|
|
|
while addr<start+size loop
|
while addr<start+size loop
|
re<='1';
|
re<='1';
|
total_requests:=total_requests+1;
|
total_requests:=total_requests+1;
|
lli_adr<=std_logic_vector(to_unsigned(addr,30));
|
lli_adr<=std_logic_vector(to_unsigned(addr,30));
|
wait until rising_edge(clk_i) and lli_busy_i='0';
|
wait until rising_edge(clk_i) and lli_busy_i='0';
|
re<='0';
|
re<='0';
|
addr:=addr+1;
|
addr:=addr+1;
|
rand(rng_state,0,4,delay);
|
rand(rng_state,0,4,delay);
|
if delay>0 then
|
if delay>0 then
|
for i in 1 to delay loop
|
for i in 1 to delay loop
|
wait until rising_edge(clk_i);
|
wait until rising_edge(clk_i);
|
end loop;
|
end loop;
|
end if;
|
end if;
|
end loop;
|
end loop;
|
|
|
if (b mod 10000)=0 then
|
if (b mod 10000)=0 then
|
report integer'image(b)&" BLOCKS PROCESSED";
|
report integer'image(b)&" BLOCKS PROCESSED";
|
end if;
|
end if;
|
|
|
b:=b+1;
|
b:=b+1;
|
end loop;
|
end loop;
|
|
|
report "Number of requests: "&integer'image(total_requests);
|
report "Number of requests: "&integer'image(total_requests);
|
report "Maximum latency: "&integer'image(max_latency);
|
report "Maximum latency: "&integer'image(max_latency);
|
report "Average latency: "&real'image(real(total_latency)/real(total_requests));
|
report "Average latency: "&real'image(real(total_latency)/real(total_requests));
|
report "Number of spurious misses: "&integer'image(spurious_misses);
|
report "Number of spurious misses: "&integer'image(spurious_misses);
|
|
|
finish<='1';
|
finish<='1';
|
wait;
|
wait;
|
end process;
|
end process;
|
|
|
lli_re_o<=re;
|
lli_re_o<=re;
|
lli_adr_o<=lli_adr;
|
lli_adr_o<=lli_adr;
|
|
|
process (clk_i) is
|
process (clk_i) is
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if lli_busy_i='0' then
|
if lli_busy_i='0' then
|
if request='1' then
|
if request='1' then
|
assert lli_dat_i=(("00"&request_addr) xor xor_constant)
|
assert lli_dat_i=(("00"&request_addr) xor xor_constant)
|
report "Data mismatch: expected 0x"&
|
report "Data mismatch: expected 0x"&
|
hex_string(("00"&request_addr) xor xor_constant)&
|
hex_string(("00"&request_addr) xor xor_constant)&
|
", got 0x"&hex_string(lli_dat_i)
|
", got 0x"&hex_string(lli_dat_i)
|
severity failure;
|
severity failure;
|
end if;
|
end if;
|
|
|
request<=re;
|
request<=re;
|
request_addr<=lli_adr;
|
request_addr<=lli_adr;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
finish_o<=finish;
|
finish_o<=finish;
|
|
|
-- Measure latency
|
-- Measure latency
|
|
|
process (clk_i) is
|
process (clk_i) is
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if lli_busy_i='0' then
|
if lli_busy_i='0' then
|
if request='1' then
|
if request='1' then
|
total_latency<=total_latency+current_latency;
|
total_latency<=total_latency+current_latency;
|
if current_latency>max_latency then
|
if current_latency>max_latency then
|
max_latency<=current_latency;
|
max_latency<=current_latency;
|
end if;
|
end if;
|
end if;
|
end if;
|
current_latency<=1;
|
current_latency<=1;
|
else
|
else
|
if lli_dat_i=(("00"&request_addr) xor xor_constant) and current_latency=1 then
|
if lli_dat_i=(("00"&request_addr) xor xor_constant) and current_latency=1 then
|
spurious_misses<=spurious_misses+1;
|
spurious_misses<=spurious_misses+1;
|
end if;
|
end if;
|
current_latency<=current_latency+1;
|
current_latency<=current_latency+1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
process (clk_i) is
|
process (clk_i) is
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
assert lli_busy_i='0' or request='1'
|
assert lli_busy_i='0' or request='1'
|
report "LLI busy signal asserted without a request"
|
report "LLI busy signal asserted without a request"
|
severity failure;
|
severity failure;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
end architecture;
|
end architecture;
|
|
|