Bug fix and start of stack cache being added

This commit is contained in:
Philip Smart
2021-02-06 11:45:11 +00:00
parent d0f7c57d49
commit 88b9d43165
29 changed files with 507765 additions and 160202 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,10 @@
-- Byte Addressed 32bit BRAM module for the ZPU Evo implementation.
--
-- Copyright 2018-2019 - Philip Smart for the ZPU Evo implementation.
-- Copyright 2018-2021 - Philip Smart for the ZPU Evo implementation.
-- History:
-- 20190618 - Initial 32 bit version of the cache using inference rather than IP Megacore packages.
-- 20210108 - Updated to 64bit, 32 bit Read/Write on Port A, 64bit Read/Write on Port B. This
-- change is to increase throughput on the cache decoder.
--
-- The FreeBSD license
--
@@ -31,6 +35,7 @@
-- 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;
@@ -38,7 +43,7 @@ library work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.zpu_pkg.all;
use work.zpu_soc_pkg.all;
--use work.zpu_soc_pkg.all;
entity evo_L2cache is
generic
@@ -55,17 +60,17 @@ entity evo_L2cache is
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);
memBAddr : in std_logic_vector(addrbits-1 downto 3);
memBWrite : in std_logic_vector(WORD_64BIT_RANGE);
memBWriteEnable : in std_logic;
memBRead : out std_logic_vector(WORD_32BIT_RANGE)
memBRead : out std_logic_vector(WORD_64BIT_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);
-- Declare 8 byte wide arrays for byte level addressing.
type ramArray is array(natural range 0 to (2**(addrbits-3))-1) of std_logic_vector(7 downto 0);
shared variable RAM0 : ramArray :=
(
@@ -87,50 +92,110 @@ architecture arch of evo_L2cache is
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.
shared variable RAM4 : ramArray :=
(
others => X"00"
);
shared variable RAM5 : ramArray :=
(
others => X"00"
);
shared variable RAM6 : ramArray :=
(
others => X"00"
);
shared variable RAM7 : 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 RAM4_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM5_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM6_DATA : std_logic_vector(7 downto 0); -- Buffer for byte in word to be written.
signal RAM7_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.
signal RAM4_WREN : std_logic; -- Write Enable for this particular byte in word.
signal RAM5_WREN : std_logic; -- Write Enable for this particular byte in word.
signal RAM6_WREN : std_logic; -- Write Enable for this particular byte in word.
signal RAM7_WREN : std_logic; -- Write Enable for this particular byte in word.
signal lowDataA : std_logic_vector(WORD_32BIT_RANGE); -- Low word in 64 bit output from RAM matrix.
signal highDataA : std_logic_vector(WORD_32BIT_RANGE); -- High word in 64 bit output from RAM matrix.
signal lowDataB : std_logic_vector(WORD_32BIT_RANGE); -- Low word in 64 bit output from RAM matrix.
signal highDataB : std_logic_vector(WORD_32BIT_RANGE); -- High word in 64 bit output from RAM matrix.
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'.
-- Correctly assign 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', word writes the data is in '31 downto 0'. Long words (64bits) are treated as two words for Endianness,
-- and not as one continuous long word, this is because the ZPU is 32bit even when accessing a 64bit chunk.
--
RAM0_DATA <= memAWrite(7 downto 0);
RAM1_DATA <= memAWrite(15 downto 8) when (memAWriteByte = '0' and memAWriteHalfWord = '0') or memAWriteHalfWord = '1'
RAM0_DATA <= memAWrite(7 downto 0) when memAAddr(2) = '0'
else (others => '0');
RAM1_DATA <= memAWrite(15 downto 8) when memAAddr(2) = '0' and ((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')
RAM2_DATA <= memAWrite(23 downto 16) when memAAddr(2) = '0' and ((memAWriteByte = '0' and memAWriteHalfWord = '0'))
else
memAWrite(7 downto 0);
RAM3_DATA <= memAWrite(31 downto 24) when (memAWriteByte = '0' and memAWriteHalfWord = '0')
RAM3_DATA <= memAWrite(31 downto 24) when memAAddr(2) = '0' and ((memAWriteByte = '0' and memAWriteHalfWord = '0'))
else
memAWrite(15 downto 8) when memAWriteHalfWord = '1'
memAWrite(15 downto 8) when memAAddr(2) = '0' and (memAWriteHalfWord = '1')
else
memAWrite(7 downto 0);
RAM4_DATA <= memAWrite(7 downto 0) when memAAddr(2) = '1'
else (others => '0');
RAM5_DATA <= memAWrite(15 downto 8) when memAAddr(2) = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0') or memAWriteHalfWord = '1')
else
memAWrite(7 downto 0);
RAM6_DATA <= memAWrite(23 downto 16) when memAAddr(2) = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0'))
else
memAWrite(7 downto 0);
RAM7_DATA <= memAWrite(31 downto 24) when memAAddr(2) = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0'))
else
memAWrite(15 downto 8) when memAAddr(2) = '1' and (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'))
RAM0_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '0') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "011") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "01"))
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'))
RAM1_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '0') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "010") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "01"))
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'))
RAM2_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '0') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "001") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "00"))
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'))
RAM3_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '0') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "000") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "00"))
else '0';
RAM4_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '1') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "111") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "11"))
else '0';
RAM5_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '1') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "110") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "11"))
else '0';
RAM6_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '1') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "101") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "10"))
else '0';
RAM7_WREN <= '1' when memAWriteEnable = '1' and ((memAWriteByte = '0' and memAWriteHalfWord = '0' and memAAddr(2) = '1') or (memAWriteByte = '1' and memAAddr(2 downto 0) = "100") or (memAWriteHalfWord = '1' and memAAddr(2 downto 1) = "10"))
else '0';
memARead <= lowDataA when memAAddr(2) = '0'
else
highDataA;
memBRead <= lowDataB & highDataB;
-- 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;
RAM0(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM0_DATA;
else
memARead(7 downto 0) <= RAM0(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
lowDataA(7 downto 0) <= RAM0(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
@@ -140,9 +205,9 @@ begin
begin
if rising_edge(clk) then
if RAM1_WREN = '1' then
RAM1(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM1_DATA;
RAM1(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM1_DATA;
else
memARead(15 downto 8) <= RAM1(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
lowDataA(15 downto 8) <= RAM1(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
@@ -152,9 +217,9 @@ begin
begin
if rising_edge(clk) then
if RAM2_WREN = '1' then
RAM2(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM2_DATA;
RAM2(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM2_DATA;
else
memARead(23 downto 16) <= RAM2(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
lowDataA(23 downto 16) <= RAM2(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
@@ -164,22 +229,71 @@ begin
begin
if rising_edge(clk) then
if RAM3_WREN = '1' then
RAM3(to_integer(unsigned(memAAddr(addrbits-1 downto 2)))) := RAM3_DATA;
RAM3(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM3_DATA;
else
memARead(31 downto 24) <= RAM3(to_integer(unsigned(memAAddr(addrbits-1 downto 2))));
lowDataA(31 downto 24) <= RAM3(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Byte 4 - Port A - bits 39 to 32
process(clk)
begin
if rising_edge(clk) then
if RAM4_WREN = '1' then
RAM4(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM4_DATA;
else
highDataA(7 downto 0) <= RAM4(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Byte 5 - Port A - bits 47 to 40
process(clk)
begin
if rising_edge(clk) then
if RAM5_WREN = '1' then
RAM5(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM5_DATA;
else
highDataA(15 downto 8) <= RAM5(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Byte 6 - Port A - bits 56 to 48
process(clk)
begin
if rising_edge(clk) then
if RAM6_WREN = '1' then
RAM6(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM6_DATA;
else
highDataA(23 downto 16) <= RAM6(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Byte 7 - Port A - bits 63 to 57
process(clk)
begin
if rising_edge(clk) then
if RAM7_WREN = '1' then
RAM7(to_integer(unsigned(memAAddr(addrbits-1 downto 3)))) := RAM7_DATA;
else
highDataA(31 downto 24) <= RAM7(to_integer(unsigned(memAAddr(addrbits-1 downto 3))));
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);
RAM0(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(7 downto 0);
lowDataB(7 downto 0) <= memBWrite(7 downto 0);
else
memBRead(7 downto 0) <= RAM0(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
lowDataB(7 downto 0) <= RAM0(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
@@ -189,10 +303,10 @@ begin
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);
RAM1(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(15 downto 8);
lowDataB(15 downto 8) <= memBWrite(15 downto 8);
else
memBRead(15 downto 8) <= RAM1(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
lowDataB(15 downto 8) <= RAM1(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
@@ -202,10 +316,10 @@ begin
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);
RAM2(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(23 downto 16);
lowDataB(23 downto 16) <= memBWrite(23 downto 16);
else
memBRead(23 downto 16) <= RAM2(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
lowDataB(23 downto 16) <= RAM2(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
@@ -215,10 +329,62 @@ begin
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);
RAM3(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(31 downto 24);
lowDataB(31 downto 24) <= memBWrite(31 downto 24);
else
memBRead(31 downto 24) <= RAM3(to_integer(unsigned(memBAddr(addrbits-1 downto 2))));
lowDataB(31 downto 24) <= RAM3(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- BRAM Byte 4 - Port B - bits 39 downto 32
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM4(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(39 downto 32);
highDataB(7 downto 0) <= memBWrite(39 downto 32);
else
highDataB(7 downto 0) <= RAM4(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- BRAM Byte 5 - Port B - bits 47 downto 40
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM5(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(47 downto 40);
highDataB(15 downto 8) <= memBWrite(47 downto 40);
else
highDataB(15 downto 8) <= RAM5(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- BRAM Byte 6 - Port B - bits 55 downto 48
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM6(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(55 downto 48);
highDataB(23 downto 16) <= memBWrite(55 downto 48);
else
highDataB(23 downto 16) <= RAM6(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- BRAM Byte 7 - Port B - bits 63 downto 56
process(clk)
begin
if rising_edge(clk) then
if memBWriteEnable = '1' then
RAM7(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := memBWrite(63 downto 56);
highDataB(31 downto 24) <= memBWrite(63 downto 56);
else
highDataB(31 downto 24) <= RAM7(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;

View File

@@ -0,0 +1,448 @@
-- 32bit Word Addressed BRAM module for the ZPU Evo implementation.
--
-- This memory is used for the stack cache. It has 64bit wide read/
-- write for the CPU side which represents TOS/NOS and 32bit wide
-- read/write for the interface between the MXP and the external memory.
--
-- Copyright 2018-2021 - 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_STcache is
generic
(
addrbits : integer := 16
);
port
(
clk : in std_logic;
memAAddr : in std_logic_vector(addrbits-1 downto 2);
memAWriteTOSEnable : in std_logic;
memAWriteNOSEnable : in std_logic;
memAWrite : in std_logic_vector(WORD_64BIT_RANGE);
memARead : out std_logic_vector(WORD_64BIT_RANGE);
memBAddr : in std_logic_vector(addrbits-1 downto 0);
memBWriteEnable : in std_logic;
memBWriteByte : in std_logic;
memBWriteHalfWord : in std_logic;
memBWrite : in std_logic_vector(WORD_32BIT_RANGE);
memBRead : out std_logic_vector(WORD_32BIT_RANGE)
);
end evo_STcache;
architecture arch of evo_STcache is
type ramArray is array(natural range 0 to (2**(addrbits-2))-1) of std_logic_vector(7 downto 0);
shared variable RAMTOS0 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS1 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS2 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS3 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS4 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS5 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS6 : ramArray :=
(
others => X"00"
);
shared variable RAMTOS7 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS0 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS1 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS2 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS3 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS4 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS5 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS6 : ramArray :=
(
others => X"00"
);
shared variable RAMNOS7 : ramArray :=
(
others => X"00"
);
signal TOSreadA : std_logic_vector(WORD_32BIT_RANGE); -- Buffer for reading a 64bit TOS word.
signal NOSreadA : std_logic_vector(WORD_32BIT_RANGE); -- Buffer for reading a 64bit NOS word.
signal TOSreadB : std_logic_vector(WORD_32BIT_RANGE); -- Buffer for reading a 32bit TOS word.
signal NOSreadB : std_logic_vector(WORD_32BIT_RANGE); -- Buffer for reading a 32bit NOS word.
signal RAMTOS_A_ADDR : unsigned(addrbits-1 downto 2); -- Address on Port A to read/write TOS from.
signal RAMNOS_A_ADDR : unsigned(addrbits-1 downto 2); -- Address on Port B to read/write NOS from.
signal RAMTOS0_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMTOS1_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMTOS2_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMTOS3_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMNOS0_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMNOS1_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMNOS2_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMNOS3_B_DATA : std_logic_vector(WORD_8BIT_RANGE); -- Buffer for selecting correct part of a 32bit word to be written in bytes.
signal RAMTOS_A_WREN : std_logic; -- Write Enable for the TOS word on the A Port.
signal RAMNOS_A_WREN : std_logic; -- Write Enable for the NOS word on the A Port.
signal RAMTOS0_B_WREN : std_logic; -- Write Enable for one byte of the TOS word on the B Port.
signal RAMTOS1_B_WREN : std_logic; -- Write Enable for one byte of the TOS word on the B Port.
signal RAMTOS2_B_WREN : std_logic; -- Write Enable for one byte of the TOS word on the B Port.
signal RAMTOS3_B_WREN : std_logic; -- Write Enable for one byte of the TOS word on the B Port.
signal RAMNOS0_B_WREN : std_logic; -- Write Enable for one byte of the NOS word on the B Port.
signal RAMNOS1_B_WREN : std_logic; -- Write Enable for one byte of the NOS word on the B Port.
signal RAMNOS2_B_WREN : std_logic; -- Write Enable for one byte of the NOS word on the B Port.
signal RAMNOS3_B_WREN : std_logic; -- Write Enable for one byte of the NOS word on the B Port.
begin
-- Signal processing. memARead is 64bit so combine the two arrays according to the LSB, memBRead is 32 bit so mux the correct word.
-- memAWrite is 64bit so write the given long word direct for even addresses or across 2 addresses if address is odd, memBWrite is 32bit so select the correct word to write.
memARead <= NOSreadA & TOSreadA;
memBRead <= TOSreadB when memBAddr(2) = '1'
else
NOSreadB;
RAMTOS_A_WREN <= '1' when memAWriteTOSEnable = '1' and memAAddr(2) = '0'
else
'1' when memAWriteNOSEnable = '1' and memAAddr(2) = '1'
else '0';
RAMNOS_A_WREN <= '1' when memAWriteNOSEnable = '1' and memAAddr(2) = '0'
else
'1' when memAWriteNOSEnable = '1' and memAAddr(2) = '1'
else '0';
RAMTOS_A_ADDR <= unsigned(memAAddr(addrbits-1 downto 2)) when memAAddr(2) = '0'
else
unsigned(memAAddr(addrbits-1 downto 2))-1;
RAMNOS_A_ADDR <= unsigned(memAAddr(addrbits-1 downto 2));
RAMTOS0_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '0') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "011") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "01"))
else '0';
RAMTOS1_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '0') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "010") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "01"))
else '0';
RAMTOS2_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '0') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "001") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "00"))
else '0';
RAMTOS3_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '0') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "000") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "00"))
else '0';
RAMNOS0_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '1') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "111") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "11"))
else '0';
RAMNOS1_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '1') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "110") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "11"))
else '0';
RAMNOS2_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '1') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "101") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "10"))
else '0';
RAMNOS3_B_WREN <= '1' when memBWriteEnable = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0' and memBAddr(2) = '1') or (memBWriteByte = '1' and memBAddr(2 downto 0) = "100") or (memBWriteHalfWord = '1' and memBAddr(2 downto 1) = "10"))
else '0';
RAMTOS0_B_DATA <= memBWrite(7 downto 0) when memBAddr(2) = '0'
else (others => '0');
RAMTOS1_B_DATA <= memBWrite(15 downto 8) when memBAddr(2) = '0' and ((memBWriteByte = '0' and memBWriteHalfWord = '0') or memBWriteHalfWord = '1')
else
memBWrite(7 downto 0);
RAMTOS2_B_DATA <= memBWrite(23 downto 16) when memBAddr(2) = '0' and ((memBWriteByte = '0' and memBWriteHalfWord = '0'))
else
memBWrite(7 downto 0);
RAMTOS3_B_DATA <= memBWrite(31 downto 24) when memBAddr(2) = '0' and ((memBWriteByte = '0' and memBWriteHalfWord = '0'))
else
memBWrite(15 downto 8) when memBAddr(2) = '0' and (memBWriteHalfWord = '1')
else
memBWrite(7 downto 0);
RAMNOS0_B_DATA <= memBWrite(7 downto 0) when memBAddr(2) = '1'
else (others => '0');
RAMNOS1_B_DATA <= memBWrite(15 downto 8) when memBAddr(2) = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0') or memBWriteHalfWord = '1')
else
memBWrite(7 downto 0);
RAMNOS2_B_DATA <= memBWrite(23 downto 16) when memBAddr(2) = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0'))
else
memBWrite(7 downto 0);
RAMNOS3_B_DATA <= memBWrite(31 downto 24) when memBAddr(2) = '1' and ((memBWriteByte = '0' and memBWriteHalfWord = '0'))
else
memBWrite(15 downto 8) when memBAddr(2) = '1' and (memBWriteHalfWord = '1')
else
memBWrite(7 downto 0);
----------------------------------------
-- Port A - 64bit wide.
-- Word addressable.
----------------------------------------
-- RAM Port A - TOS - bits 7 to 0 (7 downto 0 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS_A_WREN = '1' then
RAMTOS0(to_integer(RAMTOS_A_ADDR)) := memAWrite(7 downto 0);
TOSreadA(7 downto 0) <= memAWrite(7 downto 0);
else
TOSreadA(7 downto 0) <= RAMTOS0(to_integer(RAMTOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - TOS - bits 15 to 8 (15 downto 8 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS_A_WREN = '1' then
RAMTOS1(to_integer(RAMTOS_A_ADDR)) := memAWrite(15 downto 8);
TOSreadA(15 downto 8) <= memAWrite(15 downto 8);
else
TOSreadA(15 downto 8) <= RAMTOS1(to_integer(RAMTOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - TOS - bits 23 to 16 (23 downto 16 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS_A_WREN = '1' then
RAMTOS2(to_integer(RAMTOS_A_ADDR)) := memAWrite(23 downto 16);
TOSreadA(23 downto 16) <= memAWrite(23 downto 16);
else
TOSreadA(23 downto 16) <= RAMTOS2(to_integer(RAMTOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - TOS - bits 31 to 24 (31 downto 24 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS_A_WREN = '1' then
RAMTOS3(to_integer(RAMTOS_A_ADDR)) := memAWrite(31 downto 24);
TOSreadA(31 downto 24) <= memAWrite(31 downto 24);
else
TOSreadA(31 downto 24) <= RAMTOS3(to_integer(RAMTOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - NOS - bits 7 to 0 (39 downto 32 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS_A_WREN = '1' then
RAMNOS0(to_integer(RAMNOS_A_ADDR)) := memAWrite(39 downto 32);
NOSreadA(7 downto 0) <= memAWrite(39 downto 32);
else
NOSreadA(7 downto 0) <= RAMNOS0(to_integer(RAMNOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - NOS - bits 15 to 8 (47 downto 40 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS_A_WREN = '1' then
RAMNOS1(to_integer(RAMNOS_A_ADDR)) := memAWrite(47 downto 40);
NOSreadA(15 downto 8) <= memAWrite(47 downto 40);
else
NOSreadA(15 downto 8) <= RAMNOS1(to_integer(RAMNOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - NOS - bits 23 to 16 (55 downto 48 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS_A_WREN = '1' then
RAMNOS2(to_integer(RAMNOS_A_ADDR)) := memAWrite(55 downto 48);
NOSreadA(23 downto 16) <= memAWrite(55 downto 48);
else
NOSreadA(23 downto 16) <= RAMNOS2(to_integer(RAMNOS_A_ADDR));
end if;
end if;
end process;
-- RAM Port A - NOS - bits 31 to 24 (63 downto 56 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS_A_WREN = '1' then
RAMNOS3(to_integer(RAMNOS_A_ADDR)) := memAWrite(63 downto 56);
NOSreadA(31 downto 24) <= memAWrite(63 downto 56);
else
NOSreadA(31 downto 24) <= RAMNOS3(to_integer(RAMNOS_A_ADDR));
end if;
end if;
end process;
----------------------------------------
-- Port B - 32bit wide.
-- Byte addressable.
----------------------------------------
-- RAM Port B - TOS - bits 7 downto 0 (7 downto 0 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS0_B_WREN = '1' then
RAMTOS0(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMTOS0_B_DATA;
TOSreadB(7 downto 0) <= RAMTOS0_B_DATA;
else
TOSreadB(7 downto 0) <= RAMTOS0(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - TOS - bits 15 downto 8 (15 downto 8 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS1_B_WREN = '1' then
RAMTOS1(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMTOS1_B_DATA;
TOSreadB(15 downto 8) <= RAMTOS1_B_DATA;
else
TOSreadB(15 downto 8) <= RAMTOS1(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - TOS - bits 23 downto 16 (23 downto 16 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS2_B_WREN = '1' then
RAMTOS2(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMTOS2_B_DATA;
TOSreadB(23 downto 16) <= RAMTOS2_B_DATA;
else
TOSreadB(23 downto 16) <= RAMTOS2(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - TOS - bits 31 downto 24 (31 downto 24 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMTOS3_B_WREN = '1' then
RAMTOS3(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMTOS3_B_DATA;
TOSreadB(31 downto 24) <= RAMTOS3_B_DATA;
else
TOSreadB(31 downto 24) <= RAMTOS3(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - NOS - bits 7 downto 0 (39 downto 32 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS0_B_WREN = '1' then
RAMNOS0(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMNOS0_B_DATA;
NOSreadB(7 downto 0) <= RAMNOS0_B_DATA;
else
NOSreadB(7 downto 0) <= RAMNOS0(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - NOS - bits 15 downto 8 (47 downto 40 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS1_B_WREN = '1' then
RAMNOS1(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMNOS1_B_DATA;
NOSreadB(15 downto 8) <= RAMNOS1_B_DATA;
else
NOSreadB(15 downto 8) <= RAMNOS1(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - NOS - bits 23 downto 16 (55 downto 48 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS2_B_WREN = '1' then
RAMNOS2(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMNOS2_B_DATA;
NOSreadB(23 downto 16) <= RAMNOS2_B_DATA;
else
NOSreadB(23 downto 16) <= RAMNOS2(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
-- RAM Port B - NOS - bits 31 downto 24 (63 downto 56 in 64bit word).
process(clk)
begin
if rising_edge(clk) then
if RAMNOS3_B_WREN = '1' then
RAMNOS3(to_integer(unsigned(memBAddr(addrbits-1 downto 3)))) := RAMNOS3_B_DATA;
NOSreadB(31 downto 24) <= RAMNOS3_B_DATA;
else
NOSreadB(31 downto 24) <= RAMNOS3(to_integer(unsigned(memBAddr(addrbits-1 downto 3))));
end if;
end if;
end process;
end arch;

View File

@@ -52,8 +52,8 @@ package zpu_pkg is
-- Debug options.
--
constant DEBUG_CPU : boolean := false; -- Enable CPU debugging output.
constant DEBUG_LEVEL : integer := 0; -- Level of debugging output. 0 = Basic, such as Breakpoint, 1 =+ Executing Instructions, 2 =+ L1 Cache contents, 3 =+ L2 Cache contents, 4 =+ Memory contents, 5=+ 4Everything else.
constant DEBUG_CPU : boolean := true; -- Enable CPU debugging output.
constant DEBUG_LEVEL : integer := 2; -- Level of debugging output. 0 = Basic, such as Breakpoint, 1 =+ Executing Instructions, 2 =+ L1 Cache contents, 3 =+ L2 Cache contents, 4 =+ Memory contents, 5=+ 4Everything else.
constant DEBUG_MAX_TX_FIFO_BITS : integer := 12; -- Size of UART TX Fifo for debug output.
constant DEBUG_MAX_FIFO_BITS : integer := 3; -- Size of debug output data records fifo.
constant DEBUG_TX_BAUD_RATE : integer := 115200; --230400; -- Baud rate for the debug transmitter.
@@ -61,10 +61,13 @@ package zpu_pkg is
-- Constants common to all ZPU models source code.
constant Generate_Trace : boolean := false; -- generate trace output or not.
constant wordPower : integer := 5; -- The number of bits in a word, defined as 2^wordPower).
constant longWordPower : integer := 6; -- The number of bits in a word, defined as 2^wordPower).
constant DontCareValue : std_logic := 'X'; -- during simulation, set this to '0' to get matching trace.txt
constant byteBits : integer := wordPower-3; -- # of bits in a word that addresses bytes
constant wordSize : integer := 2**wordPower;
constant wordBytes : integer := wordSize/8;
constant longWordSize : integer := 2**longWordPower;
constant longWordBytes : integer := longWordSize/8;
constant minAddrBit : integer := byteBits;
constant WB_ACTIVE : integer := bool_to_integer(EVO_USE_WB_BUS); -- Set to 1 if the wishbone interface is active to divide the address space in two, lower = direct access, upper = wishbone.
constant maxAddrBit : integer := 24 + WB_ACTIVE; -- Maximum address limit in bits.
@@ -81,6 +84,9 @@ package zpu_pkg is
subtype ADDR_32BIT_RANGE is natural range maxAddrBit-1 downto minAddrBit; -- Full address range - 4 bytes (32bit) aligned
subtype ADDR_64BIT_RANGE is natural range maxAddrBit-1 downto minAddrBit+1; -- Full address range - 8 bytes (64bit) aligned
subtype ADDR_IOBIT_RANGE is natural range ioBit downto minAddrBit; -- Non-EVO: IO range.
subtype WORD_UPPER_64BIT_RANGE is natural range 63 downto 32; -- Bits for the higher word of a 64bit long word.
subtype WORD_LOWER_64BIT_RANGE is natural range 31 downto 0; -- Bits for the lower word of a 64bit long word.
subtype WORD_64BIT_RANGE is natural range longWordSize-1 downto 0; -- Number of bits in a long word (normally 64 for this CPU).
subtype WORD_32BIT_RANGE is natural range wordSize-1 downto 0; -- Number of bits in a word (normally 32 for this CPU).
subtype WORD_16BIT_RANGE is natural range (wordSize/2)-1 downto 0; -- Number of bits in a half-word (normally 16 for this CPU).
subtype WORD_UPPER_16BIT_RANGE is natural range (wordSize/2)-1 downto wordSize/4; -- Number of bits in a half-word (normally 16 for this CPU).
@@ -244,11 +250,12 @@ package zpu_pkg is
MAX_INSNRAM_SIZE : integer := 32768; -- Maximum size of the optional Instruction BRAM on the INSN Bus.
MAX_L1CACHE_BITS : integer := 4; -- Maximum size in bytes of the Level 1 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
MAX_L2CACHE_BITS : integer := 12; -- Maximum size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
MAX_STCACHE_BITS : integer := 8; -- Maximum size in 32bit words of the stack cache, governed by the number of bits, ie. 8 - 256 x 32bit cache.
MAX_MXCACHE_BITS : integer := 4; -- Maximum size of the memory transaction cache governed by the number of bits.
RESET_ADDR_CPU : integer := 0; -- Initial start address of the CPU.
START_ADDR_MEM : integer := 0; -- Start address of program memory.
STACK_ADDR : integer := 0; -- Initial stack address on CPU start.
CLK_FREQ : integer := 100000000 -- Frequency of the input clock.
CLK_FREQ : integer := 100000000 -- Frequency of the input clock.
);
port (
CLK : in std_logic;
@@ -263,9 +270,12 @@ package zpu_pkg is
MEM_READ_ENABLE : out std_logic;
MEM_WRITE_BYTE : out std_logic;
MEM_WRITE_HWORD : out std_logic;
MEM_BUSRQ : in std_logic; -- Bus request, when memory transaction processor goes to Idle, suspend and allow an external device to control the bus.
MEM_BUSACK : out std_logic; -- Bus acknowledge, set when MEM_BUSRQ goes active and the memory transaction processor completes a transaction and goes idle.
-- Instruction memory path
MEM_BUSY_INSN : in std_logic;
MEM_DATA_IN_INSN : in std_logic_vector(WORD_32BIT_RANGE);
MEM_DATA_IN_INSN : in std_logic_vector(WORD_64BIT_RANGE);
MEM_ADDR_INSN : out std_logic_vector(ADDR_BIT_RANGE);
MEM_READ_ENABLE_INSN : out std_logic;
-- Master Wishbone Memory/IO bus interface.