Files
SharpMZ/zpu/cpu/zpu_core_evo_L2.vhd

227 lines
9.1 KiB
VHDL

-- Byte Addressed 32bit BRAM module for the ZPU Evo implementation.
--
-- Copyright 2018-2019 - Philip Smart for the ZPU Evo implementation.
--
-- The FreeBSD license
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
--
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above
-- copyright notice, this list of conditions and the following
-- disclaimer in the documentation and/or other materials
-- provided with the distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE ZPU PROJECT ``AS IS'' AND ANY
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-- ZPU PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-- The views and conclusions contained in the software and documentation
-- are those of the authors and should not be interpreted as representing
-- official policies, either expressed or implied, of the ZPU Project.
library ieee;
library pkgs;
library work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.zpu_pkg.all;
use work.zpu_soc_pkg.all;
entity evo_L2cache is
generic
(
addrbits : integer := 16
);
port
(
clk : in std_logic;
memAAddr : in std_logic_vector(addrbits-1 downto 0);
memAWriteEnable : in std_logic;
memAWriteByte : in std_logic;
memAWriteHalfWord : in std_logic;
memAWrite : in std_logic_vector(WORD_32BIT_RANGE);
memARead : out std_logic_vector(WORD_32BIT_RANGE);
memBAddr : in std_logic_vector(addrbits-1 downto 2);
memBWrite : in std_logic_vector(WORD_32BIT_RANGE);
memBWriteEnable : in std_logic;
memBRead : out std_logic_vector(WORD_32BIT_RANGE)
);
end evo_L2cache;
architecture arch of evo_L2cache is
-- Declare 4 byte wide arrays for byte level addressing.
type ramArray is array(natural range 0 to (2**(addrbits-2))-1) of std_logic_vector(7 downto 0);
shared variable RAM0 : ramArray :=
(
others => X"00"
);
shared variable RAM1 : ramArray :=
(
others => X"00"
);
shared variable RAM2 : ramArray :=
(
others => X"00"
);
shared variable RAM3 : ramArray :=
(
others => X"00"
);
signal RAM0_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM1_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM2_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM3_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM0_WREN : std_logic; -- Write Enable for this particular byte in word.
signal RAM1_WREN : std_logic; -- Write Enable for this particular byte in word.
signal RAM2_WREN : std_logic; -- Write Enable for this particular byte in word.
signal RAM3_WREN : std_logic; -- Write Enable for this particular byte in word.
begin
-- Correctly assigning the Little Endian value to the correct array, byte writes the data is in '7 downto 0', h-word writes
-- the data is in '15 downto 0'.
--
RAM0_DATA <= memAWrite(7 downto 0);
RAM1_DATA <= memAWrite(15 downto 8) when (memAWriteByte = '0' and memAWriteHalfWord = '0') or memAWriteHalfWord = '1'
else
memAWrite(7 downto 0);
RAM2_DATA <= memAWrite(23 downto 16) when (memAWriteByte = '0' and memAWriteHalfWord = '0')
else
memAWrite(7 downto 0);
RAM3_DATA <= memAWrite(31 downto 24) when (memAWriteByte = '0' and memAWriteHalfWord = '0')
else
memAWrite(15 downto 8) when memAWriteHalfWord = '1'
else
memAWrite(7 downto 0);
RAM0_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0') or (memAWriteByte = '1' and memAAddr(1 downto 0) = "11") or (memAWriteHalfWord = '1' and memAAddr(1) = '1'))
else '0';
RAM1_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0') or (memAWriteByte = '1' and memAAddr(1 downto 0) = "10") or (memAWriteHalfWord = '1' and memAAddr(1) = '1'))
else '0';
RAM2_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0') or (memAWriteByte = '1' and memAAddr(1 downto 0) = "01") or (memAWriteHalfWord = '1' and memAAddr(1) = '0'))
else '0';
RAM3_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0') or (memAWriteByte = '1' and memAAddr(1 downto 0) = "00") or (memAWriteHalfWord = '1' and memAAddr(1) = '0'))
else '0';
-- RAM Byte 0 - Port A - bits 7 to 0
process(clk)
begin
if rising_edge(clk) then
if RAM0_WREN = '1' then
RAM0(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM0_DATA;
else
memARead(7 downto 0) <= RAM0(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- RAM Byte 1 - Port A - bits 15 to 8
process(clk)
begin
if rising_edge(clk) then
if RAM1_WREN = '1' then
RAM1(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM1_DATA;
else
memARead(15 downto 8) <= RAM1(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- RAM Byte 2 - Port A - bits 23 to 16
process(clk)
begin
if rising_edge(clk) then
if RAM2_WREN = '1' then
RAM2(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM2_DATA;
else
memARead(23 downto 16) <= RAM2(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- RAM Byte 3 - Port A - bits 31 to 24
process(clk)
begin
if rising_edge(clk) then
if RAM3_WREN = '1' then
RAM3(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM3_DATA;
else
memARead(31 downto 24) <= RAM3(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- BRAM Byte 0 - Port B - bits 7 downto 0
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM0(to_integer(unsigned(memBAddr(addrbits-1 downto 2)))) := memBWrite(7 downto 0);
memBRead(7 downto 0) <= memBWrite(7 downto 0);
else
memBRead(7 downto 0) <= RAM0(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- BRAM Byte 1 - Port B - bits 15 downto 8
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM1(to_integer(unsigned(memBAddr(addrbits-1 downto 2)))) := memBWrite(15 downto 8);
memBRead(15 downto 8) <= memBWrite(15 downto 8);
else
memBRead(15 downto 8) <= RAM1(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- BRAM Byte 2 - Port B - bits 23 downto 16
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM2(to_integer(unsigned(memBAddr(addrbits-1 downto 2)))) := memBWrite(23 downto 16);
memBRead(23 downto 16) <= memBWrite(23 downto 16);
else
memBRead(23 downto 16) <= RAM2(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
-- BRAM Byte 3 - Port B - bits 31 downto 24
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM3(to_integer(unsigned(memBAddr(addrbits-1 downto 2)))) := memBWrite(31 downto 24);
memBRead(31 downto 24) <= memBWrite(31 downto 24);
else
memBRead(31 downto 24) <= RAM3(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
end if;
end if;
end process;
end arch;