Bug fix and start of stack cache being added
This commit is contained in:
4594
cpu/zpu_core_evo.vhd
4594
cpu/zpu_core_evo.vhd
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
448
cpu/zpu_core_evo_STcache.vhd
Normal file
448
cpu/zpu_core_evo_STcache.vhd
Normal 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;
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user