OpenCores
URL https://opencores.org/ocsvn/lxp32/lxp32/trunk

Subversion Repositories lxp32

[/] [lxp32/] [trunk/] [verify/] [icache/] [src/] [tb/] [cpu_model.vhd] - Rev 9

Compare with Previous | Blame | View Log

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

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.