|
Message
From: ezaffar@v...
Date: Tue, 18 Nov 2003 08:28:56 +0100
Subject: [oc] implementing prefetch and instruction cache
Hi,
I am trying to add a prefetch queue and instruction cache to a 5 stage
pipeline 16 bit processor. I am kind of stuck. I am fairly new to vhdl.
here is the code for prefetch, I haven't included the condition for branch
yet. :
use STD.standard.all;
use STD.textio.all;
library IEEE;
use IEEE.std_logic_1164.all;
entity prefetch64 is
port(
CLK : in std_logic;
CEN : in std_logic;
A : in std_logic_vector(15 downto 0);
iadsin : in std_logic;
aout : out std_logic_vector(15 downto 0);
iadsout : out std_logic;
din : in std_logic_vector(63 downto 0);
irdyin : in std_logic;
irdy : out std_logic;
Q : out std_logic_vector(15 downto 0));
end prefetch64;
architecture prefetch64_arc of prefetch64 is
-- declare signals
signal line : std_logic_vector(63 downto 0);
signal empty : boolean := true;
--signal prev_addr : std_logic_vector(15 downto 0);
begin
--process(clk)
--begin
--end process;
process(clk)
variable prev_addr : integer := 0;
variable address : integer := 0;
variable counter : integer := 0;
--variable empty : boolean := true;
begin
address := 0;
if a(0) = '1' then
address := address + 1;
end if;
if a(1) = '1' then
address := address + 2;
end if;
if a(2) = '1' then
address := address + 4;
end if;
if a(3) = '1' then
address := address + 8;
end if;
if a(4) = '1' then
address := address + 16;
end if;
if a(5) = '1' then
address := address + 32;
end if;
--if (address /= prev_addr + 1) then -- branch or first inst? shall I
compare the prev addr here?
-- empty <= true;
-- irdy <= '0';
-- iadsout <= '1';
-- aout <= a;
--else
--if (iadsin = '1') then
if (empty) then
irdy <= '0'; aout <= a; iadsout <= '1';
if (irdyin = '1') then
empty <= false;
line <= din;
--iadsout <= '0';
case A(1 downto 0) is
when "00" =>
Q <= line(15 downto 0);
irdy <= '1'; --iadsout <= '0';
when "01" =>
Q <= line(31 downto 16);
irdy <= '1'; --iadsout <= '0';
when "10" =>
Q <= line(47 downto 32);
irdy <= '1'; --iadsout <= '0';
when "11" =>
Q <= line(63 downto 48);
irdy <= '1'; empty <= true; --iadsout <= '0';
when others =>
Q <= (others => 'Z');
irdy <= '0'; --iadsout <= '0';
end case;
end if;
else
case A(1 downto 0) is
when "00" =>
Q <= line(15 downto 0);
irdy <= '1'; iadsout <= '0';
when "01" =>
Q <= line(31 downto 16);
irdy <= '1'; iadsout <= '0';
when "10" =>
Q <= line(47 downto 32);
irdy <= '1'; iadsout <= '0';
when "11" =>
Q <= line(63 downto 48);
irdy <= '1'; empty <= true; iadsout <= '0';
when others =>
Q <= (others => 'Z');
irdy <= '0'; iadsout <= '0';
end case;
end if;
-- end if;
--end if;
prev_addr := address;
end process;
end prefetch64_arc;
===============
use STD.standard.all;
use STD.textio.all;
library IEEE;
use IEEE.std_logic_1164.all;
entity icache_4x64 is
generic(delay : time := 5 ns);
port(
CLK : in std_logic;
cen : in std_logic;
a : in std_logic_vector(15 downto 0);
iadsin : in std_logic;
aout : out std_logic_vector(15 downto 0);
iadsout : out std_logic;
irdyin : in std_logic;
irdyout : out std_logic;
burst : out std_logic;
dbin : in std_logic_vector(15 downto 0);
dbout : out std_logic_vector(63 downto 0));
end icache_4x64;
use STD.standard.all;
use STD.textio.all;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
architecture icache_arc of icache_4x64 is
type CacheLine is
record
tag : std_logic_vector(11 downto 0);
valid : std_logic;
data : std_logic_vector(63 downto 0);
end record;
type cacheType is array(0 to 3) of CacheLine;
--signal word : integer range 0 to 3;
--signal line : integer range 0 to 3;
--signal burstcount : integer range 0 to 3 := 0 ;
signal iCache : cacheType;
signal miss : std_logic;
-- declare signals
begin
process(clk)
-- implement array, how to implement tag, valid etc., get data in bursts
--
variable word : integer range 0 to 3;
variable line : integer range 0 to 3;
variable burstcount : integer range 0 to 3 := 0 ;
-- variable iCache : cacheType;
--variable miss : boolean := true;
begin
-- get cache line
line := 0;
if a(2) = '1' then
line := line + 1;
end if;
if a(3) = '1' then
line := line + 2;
end if;
word := 0;
if a(0) = '1' then
word := word + 1;
end if;
if a(1) = '1' then
word := word + 2;
end if;
if clk'event and clk = '1' then
if cen = '0' then
if iadsin = '1' then
-- match tag
--irdyout <= '0';
if (iCache(line).tag = a(15 downto 4)) and (iCache(line).valid = '1')
then -- cache hit
dbout <= iCache(line).data after delay;
miss <= '0'; iadsout <= '0'; burst <= '0'; irdyout <= '0', '1' after
delay;
else -- cache miss, get from ROM
miss <= '1'; irdyout <= '0'; aout <= a; iadsout <= '1'; burst <= '1';
-- wait until irdyin becomes high, need this???
-- data comes in one clk at a time?
if (irdyin = '1') then
case burstcount is
when 0 =>
case word is
when 0 =>
iCache(line).data(15 downto 0) <= dbin;
when 1 =>
iCache(line).data(31 downto 16) <= dbin;
when 2 =>
iCache(line).data(47 downto 32) <= dbin;
when 3 =>
iCache(line).data(63 downto 48) <= dbin;
end case;
when 1 =>
case word is
when 0 =>
iCache(line).data(31 downto 16) <= dbin;
when 1 =>
iCache(line).data(47 downto 32) <= dbin;
when 2 =>
iCache(line).data(63 downto 48) <= dbin;
when 3 =>
iCache(line).data(15 downto 0) <= dbin;
end case;
when 2 =>
case word is
when 0 =>
iCache(line).data(47 downto 32) <= dbin;
when 1 =>
iCache(line).data(63 downto 48) <= dbin;
when 2 =>
iCache(line).data(15 downto 0) <= dbin;
when 3 =>
iCache(line).data(31 downto 16) <= dbin;
end case;
when 3 =>
case word is
when 0 =>
iCache(line).data(63 downto 48) <= dbin;
when 1 =>
iCache(line).data(15 downto 0) <= dbin;
when 2 =>
iCache(line).data(31 downto 16) <= dbin;
when 3 =>
iCache(line).data(47 downto 32) <= dbin;
end case;
iCache(line).valid <= '1';
iCache(line).tag <= a(15 downto 4);
end case;
burstcount := (burstcount + 1) mod 4;
end if;
end if;
end if;
end if;
end if;
end process;
end icache_arc;
|
 |