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

6
.gitignore vendored
View File

@@ -74,4 +74,8 @@ docker/QuartusPrime/local/
docker/QuartusPrime/quartus_docker.sh
docker/QuartusPrime/unison/
docker/QuartusPrime/x/
zpu_core_evo.vhd.bakPreZ80
zpu_core_evo.vhd.new
zpu_core_evo.vhd.preZ80_2
zpu_core_evo.vhd.workingpre64bitL1
zpu_core_evo_L2.vhd.workingpre64bitL1

View File

@@ -148,7 +148,7 @@ BEGIN
GENERIC MAP (
clk0_divide_by => 1,
clk0_duty_cycle => 50,
clk0_multiply_by => 4,
clk0_multiply_by => 3,
clk0_phase_shift => "0",
clk1_divide_by => 1,
clk1_duty_cycle => 50,

View File

@@ -254,6 +254,7 @@ set_global_assignment -name VHDL_FILE ../cpu/zpu_core_small.vhd
set_global_assignment -name VHDL_FILE ../cpu/zpu_core_medium.vhd
set_global_assignment -name VHDL_FILE ../cpu/zpu_core_evo.vhd
set_global_assignment -name VHDL_FILE ../cpu/zpu_core_evo_L2.vhd
set_global_assignment -name VHDL_FILE ../cpu/zpu_core_evo_STcache.vhd
set_global_assignment -name VHDL_FILE ../cpu/zpu_uart_debug.vhd
set_global_assignment -name VHDL_FILE ../zpu_soc_pkg.vhd
set_global_assignment -name VHDL_FILE ../zpu_soc.vhd
@@ -264,20 +265,21 @@ set_global_assignment -name VHDL_FILE ../devices/sysbus/spi/spi.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/SDMMC/SDCard.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/ps2/io_ps2_com.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/timer/timer_controller.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/BootROM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/DualPortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/SinglePortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/SinglePortBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_BootROM.vhd
#set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_DualPortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_DualPort3264BootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_SinglePortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_SinglePortBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/ioctl/ioctl.vhd
#set_global_assignment -name VHDL_FILE ../devices/sysbus/TCPU/tcpu.vhd
#set_global_assignment -name QIP_FILE ../devices/sysbus/SDRAM/48LC16M16.qip
set_global_assignment -name QIP_FILE ../devices/sysbus/SDRAM/48LC16M16.qip
#set_global_assignment -name QIP_FILE ../devices/sysbus/SDRAM/48LC16M16_cached.qip
#set_global_assignment -name QIP_FILE ../devices/sysbus/SDRAM/W9864G6.qip
#set_global_assignment -name QIP_FILE ../devices/sysbus/SDRAM/W9864G6_cached.qip
set_global_assignment -name VHDL_FILE ../devices/WishBone/I2C/i2c_master_top.vhd
set_global_assignment -name VHDL_FILE ../devices/WishBone/I2C/i2c_master_byte_ctrl.vhd
set_global_assignment -name VHDL_FILE ../devices/WishBone/I2C/i2c_master_bit_ctrl.vhd
#set_global_assignment -name QIP_FILE ../devices/WishBone/SDRAM/48LC16M16.qip
set_global_assignment -name QIP_FILE ../devices/WishBone/SDRAM/48LC16M16.qip
#set_global_assignment -name QIP_FILE ../devices/WishBone/SDRAM/48LC16M16_cached.qip
#set_global_assignment -name QIP_FILE ../devices/WishBone/SDRAM/W9864G6.qip
#set_global_assignment -name QIP_FILE ../devices/WishBone/SDRAM/W9864G6_cached.qip
@@ -299,4 +301,12 @@ set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -435,10 +435,10 @@ set_global_assignment -name VHDL_FILE ../devices/sysbus/spi/spi.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/SDMMC/SDCard.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/ps2/io_ps2_com.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/timer/timer_controller.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/BootROM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/DualPortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/SinglePortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/SinglePortBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_BootROM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_DualPortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_SinglePortBootBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/BRAM/zOS_SinglePortBRAM.vhd
set_global_assignment -name VHDL_FILE ../devices/sysbus/ioctl/ioctl.vhd
#set_global_assignment -name VHDL_FILE ../devices/sysbus/TCPU/tcpu.vhd
set_global_assignment -name QIP_FILE ../devices/sysbus/SDRAM/48LC16M16.qip
@@ -470,4 +470,5 @@ set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
-- 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;
entity SinglePortBRAM 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)
);
end SinglePortBRAM;
architecture arch of SinglePortBRAM is
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
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;
end arch;

File diff suppressed because it is too large Load Diff

View File

@@ -275,7 +275,7 @@ architecture rtl of zpu_soc is
signal MEM_WRITE_HWORD_ENABLE : std_logic;
signal MEM_READ_ENABLE : std_logic;
signal MEM_READ_ENABLE_LAST : std_logic;
signal MEM_DATA_READ_INSN : std_logic_vector(WORD_32BIT_RANGE);
signal MEM_DATA_READ_INSN : std_logic_vector(WORD_64BIT_RANGE);
signal MEM_ADDR_INSN : std_logic_vector(ADDR_BIT_RANGE);
signal MEM_READ_ENABLE_INSN : std_logic;
signal IO_DATA_READ : std_logic_vector(WORD_32BIT_RANGE);
@@ -516,6 +516,7 @@ begin
MAX_INSNRAM_SIZE => (2**(SOC_MAX_ADDR_INSN_BRAM_BIT)), -- Maximum size of the optional instruction BRAM on the INSN Bus.
MAX_L1CACHE_BITS => MAX_EVO_L1CACHE_BITS, -- Maximum size in instructions of the Level 0 instruction cache governed by the number of bits, ie. 8 = 256 instruction cache.
MAX_L2CACHE_BITS => MAX_EVO_L2CACHE_BITS, -- Maximum bit size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
MAX_STCACHE_BITS => MAX_EVO_STCACHE_BITS, -- Maximum size in 32bit words of the stack cache, governed by the number of bits, ie. 8 - 256 x 32bit cache.
MAX_MXCACHE_BITS => MAX_EVO_MXCACHE_BITS, -- Maximum size of the memory transaction cache governed by the number of bits.
RESET_ADDR_CPU => SOC_RESET_ADDR_CPU, -- Initial start address of the CPU.
START_ADDR_MEM => SOC_START_ADDR_MEM, -- Start address of program memory.
@@ -534,6 +535,8 @@ begin
MEM_READ_ENABLE => MEM_READ_ENABLE,
MEM_WRITE_BYTE => MEM_WRITE_BYTE_ENABLE,
MEM_WRITE_HWORD => MEM_WRITE_HWORD_ENABLE,
MEM_BUSRQ => '0',
MEM_BUSACK => open,
-- Instruction memory path.
MEM_BUSY_INSN => '0',
MEM_DATA_IN_INSN => MEM_DATA_READ_INSN,
@@ -600,6 +603,7 @@ begin
MAX_INSNRAM_SIZE => (2**(SOC_MAX_ADDR_INSN_BRAM_BIT)), -- Maximum size of the optional instruction BRAM on the INSN Bus.
MAX_L1CACHE_BITS => MAX_EVO_MIN_L1CACHE_BITS, -- Maximum size in instructions of the Level 0 instruction cache governed by the number of bits, ie. 8 = 256 instruction cache.
MAX_L2CACHE_BITS => MAX_EVO_MIN_L2CACHE_BITS, -- Maximum size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
MAX_STCACHE_BITS => MAX_EVO_MIN_STCACHE_BITS, -- Maximum size in 32bit words of the stack cache, governed by the number of bits, ie. 8 - 256 x 32bit cache.
MAX_MXCACHE_BITS => MAX_EVO_MIN_MXCACHE_BITS, -- Maximum size of the memory transaction cache governed by the number of bits.
RESET_ADDR_CPU => SOC_RESET_ADDR_CPU, -- Initial start address of the CPU.
START_ADDR_MEM => SOC_START_ADDR_MEM, -- Start address of program memory.
@@ -618,6 +622,8 @@ begin
MEM_READ_ENABLE => MEM_READ_ENABLE,
MEM_WRITE_BYTE => MEM_WRITE_BYTE_ENABLE,
MEM_WRITE_HWORD => MEM_WRITE_HWORD_ENABLE,
MEM_BUSRQ => '0',
MEM_BUSACK => open,
-- Instruction memory path.
MEM_BUSY_INSN => '0',
MEM_DATA_IN_INSN => MEM_DATA_READ_INSN,
@@ -704,7 +710,7 @@ begin
-- Evo system BRAM, dual port to allow for seperate instruction bus read.
ZPUDPBRAMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_INSN_BRAM = true and SOC_IMPL_BRAM = true generate
ZPUBRAM : entity work.DualPortBootBRAM
ZPUBRAM : entity work.DualPort3264BootBRAM
generic map (
addrbits => SOC_MAX_ADDR_BRAM_BIT
)
@@ -717,7 +723,7 @@ begin
memAWrite => MEM_DATA_WRITE,
memARead => BRAM_DATA_READ,
memBAddr => MEM_ADDR_INSN(ADDR_32BIT_BRAM_RANGE),
memBAddr => MEM_ADDR_INSN(ADDR_64BIT_BRAM_RANGE),
memBWrite => (others => '0'),
memBWriteEnable => '0',
memBRead => MEM_DATA_READ_INSN
@@ -804,18 +810,23 @@ begin
WRITE_BYTE => MEM_WRITE_BYTE_ENABLE, -- Write a single byte.
WRITE_HWORD => MEM_WRITE_HWORD_ENABLE, -- Write a 16 bit word.
CS => SDRAM_SELECT, -- Chip Select.
WREN => MEM_WRITE_ENABLE, --SDRAM_WREN, -- Write enable.
RDEN => MEM_READ_ENABLE, --SDRAM_RDEN, -- Read enable.
WREN => SDRAM_WREN, -- Write enable.
RDEN => SDRAM_RDEN, -- Read enable.
BUSY => SDRAM_MEM_BUSY
);
-- SDRAM clock based on system clock.
SDRAM_CLK <= MEMCLK;
SDRAM_CLK <= MEMCLK;
-- RAM Range SOC_ADDR_SDRAM_START) -> SOC_ADDR_SDRAM_END
SDRAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1 or ZPU_MEDIUM = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_SDRAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_SDRAM_END, MEM_ADDR'LENGTH)))
--SDRAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_RAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_RAM_END, MEM_ADDR'LENGTH)))
else '0';
SDRAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1 or ZPU_MEDIUM = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_SDRAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_SDRAM_END, MEM_ADDR'LENGTH)))
--SDRAM_SELECT <= '1' when (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and (MEM_ADDR >= std_logic_vector(to_unsigned(SOC_ADDR_RAM_START, MEM_ADDR'LENGTH)) and MEM_ADDR < std_logic_vector(to_unsigned(SOC_ADDR_RAM_END, MEM_ADDR'LENGTH)))
else '0';
-- Enable write to RAM when selected and CPU in write state.
SDRAM_WREN <= MEM_WRITE_ENABLE when SDRAM_SELECT = '1'
else '0';
SDRAM_RDEN <= MEM_READ_ENABLE when SDRAM_SELECT = '1'
else '0';
end generate;
-- Force the CPU to wait when slower memory/IO is accessed and it cant deliver an immediate result.
@@ -2051,7 +2062,9 @@ begin
-----------------------
elsif rising_edge(SYSCLK) then
MEM_READ_ENABLE_LAST <= MEM_READ_ENABLE;
-- Edge detection for read signal. Most I/O operations need a read signal longer than 1 clock so BUSY needs to be asserted in order to prolong the read cycle.
--
MEM_READ_ENABLE_LAST <= MEM_READ_ENABLE;
-- If the RX receives a break signal, count down to ensure it is held low for correct period, when the count reaches
-- zero, start a reset.

View File

@@ -62,16 +62,16 @@ package zpu_soc_pkg is
-- Target board declaration.
--
constant BOARD_E115 : boolean := false; -- E115 FPGA Board
constant BOARD_QMV : boolean := true; -- QMTECH Cyclone V FPGA Board
constant BOARD_E115 : boolean := true; -- E115 FPGA Board
constant BOARD_QMV : boolean := false; -- QMTECH Cyclone V FPGA Board
constant BOARD_DE0 : boolean := false; -- DE0-Nano FPGA Board
constant BOARD_DE10 : boolean := false; -- DE10-Nano FPGA Board
constant BOARD_CYC1000 : boolean := false; -- Trenz CYC1000 FPGA Board
-- Frequencies for the various boards.
--
constant SYSCLK_E115_FREQ : integer := 100000000; -- E115 FPGA Board
constant SYSCLK_QMV_FREQ : integer := 100000000; -- QMTECH Cyclone V FPGA Board
constant SYSCLK_E115_FREQ : integer := 75000000; -- E115 FPGA Board
constant SYSCLK_QMV_FREQ : integer := 75000000; -- QMTECH Cyclone V FPGA Board
constant SYSCLK_DE0_FREQ : integer := 100000000; -- DE0-Nano FPGA Board
constant SYSCLK_DE10_FREQ : integer := 100000000; -- DE10-Nano FPGA Board
constant SYSCLK_CYC1000_FREQ : integer := 100000000; -- Trenz CYC1000 FPGA Board
@@ -80,15 +80,17 @@ package zpu_soc_pkg is
constant ZPU_ID_SMALL : integer := 16#0101#; -- ID for the ZPU Small in this package.
constant ZPU_ID_MEDIUM : integer := 16#0201#; -- ID for the ZPU Medium in this package.
constant ZPU_ID_FLEX : integer := 16#0301#; -- ID for the ZPU Flex in this package.
constant ZPU_ID_EVO : integer := 16#0401#; -- ID for the ZPU Evo in this package.
constant ZPU_ID_EVO_MINIMAL : integer := 16#0501#; -- ID for the ZPU Evo Minimal in this package.
constant ZPU_ID_EVO : integer := 16#0402#; -- ID for the ZPU Evo in this package.
constant ZPU_ID_EVO_MINIMAL : integer := 16#0502#; -- ID for the ZPU Evo Minimal in this package.
-- EVO CPU specific configuration.
constant MAX_EVO_L1CACHE_BITS : integer := 5; -- Maximum size in instructions of the Level 0 instruction cache governed by the number of bits, ie. 8 = 256 instruction cache.
constant MAX_EVO_L2CACHE_BITS : integer := 12; -- Maximum bit size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
constant MAX_EVO_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.
constant MAX_EVO_MXCACHE_BITS : integer := 3; -- Maximum size of the memory transaction cache governed by the number of bits.
constant MAX_EVO_MIN_L1CACHE_BITS : integer := 4; -- Maximum size in instructions of the Level 0 instruction cache governed by the number of bits, ie. 8 = 256 instruction cache.
constant MAX_EVO_MIN_L2CACHE_BITS : integer := 12; -- Maximum bit size in bytes of the Level 2 instruction cache governed by the number of bits, ie. 8 = 256 byte cache.
constant MAX_EVO_MIN_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.
constant MAX_EVO_MIN_MXCACHE_BITS : integer := 3; -- Maximum size of the memory transaction cache governed by the number of bits.
-- Settings for various IO devices.
@@ -96,7 +98,7 @@ package zpu_soc_pkg is
constant MAX_RX_FIFO_BITS : integer := 8; -- Size of UART RX Fifo.
constant MAX_TX_FIFO_BITS : integer := 8; -- Size of UART TX Fifo.
constant MAX_UART_DIVISOR_BITS : integer := 16; -- Maximum number of bits for the UART clock rate generator divisor.
constant SYSTEM_FREQUENCY : integer := 100000000; -- Default system clock frequency if not overriden in top level.
constant SYSTEM_FREQUENCY : integer := 75000000; -- Default system clock frequency if not overriden in top level.
-- SoC specific options.
--
@@ -115,16 +117,16 @@ package zpu_soc_pkg is
-- Main Boot BRAM on sysbus, contains startup firmware.
constant SOC_IMPL_BRAM : boolean := true; -- Implement BRAM for the BIOS and initial Stack.
constant SOC_IMPL_INSN_BRAM : boolean := EVO_USE_INSN_BUS; -- Implement dedicated instruction BRAM for the EVO CPU. Any addr access beyond the BRAM size goes to normal memory.
constant SOC_MAX_ADDR_BRAM_BIT : integer := 16; -- Max address bit of the System BRAM ROM/Stack in bytes, ie. 15 = 32KB or 8K 32bit words. NB. For non evo CPUS you must adjust the maxMemBit parameter in zpu_pkg.vhd to be the same.
constant SOC_MAX_ADDR_BRAM_BIT : integer := 17; -- Max address bit of the System BRAM ROM/Stack in bytes, ie. 15 = 32KB or 8K 32bit words. NB. For non evo CPUS you must adjust the maxMemBit parameter in zpu_pkg.vhd to be the same.
constant SOC_ADDR_BRAM_START : integer := 0; -- Start address of BRAM.
constant SOC_ADDR_BRAM_END : integer := SOC_ADDR_BRAM_START+(2**SOC_MAX_ADDR_BRAM_BIT); -- End address of BRAM = START + 2^SOC_MAX_ADDR_INSN_BRAM_BIT.
-- Secondary block of sysbus RAM, typically implemented in BRAM.
constant SOC_IMPL_RAM : boolean := false; -- Implement RAM using BRAM, typically for Application programs seperate to BIOS.
constant SOC_MAX_ADDR_RAM_BIT : integer := 15; -- Max address bit of the System RAM.
constant SOC_MAX_ADDR_RAM_BIT : integer := 16; -- Max address bit of the System RAM.
constant SOC_ADDR_RAM_START : integer := 65536; -- Start address of RAM.
constant SOC_ADDR_RAM_END : integer := SOC_ADDR_RAM_START+(2**SOC_MAX_ADDR_RAM_BIT); -- End address of RAM = START + 2^SOC_MAX_ADDR_INSN_BRAM_BIT.
-- SDRAM on sysbus.
constant SOC_IMPL_SDRAM : boolean := true; -- Implement Dynamic RAM and controller.
constant SOC_IMPL_SDRAM : boolean := false; -- Implement Dynamic RAM and controller.
constant SOC_SDRAM_ROWS : integer := 4096; -- Number of Rows within the SDRAM.
constant SOC_SDRAM_COLUMNS : integer := 256; -- Number of Columns within the SDRAM.
constant SOC_SDRAM_BANKS : integer := 4; -- Number of Banks within the SDRAM.
@@ -228,6 +230,7 @@ package zpu_soc_pkg is
subtype ADDR_BIT_BRAM_RANGE is natural range SOC_MAX_ADDR_BRAM_BIT-1 downto 0; -- Address range of the onboard B(lock)RAM - 1 byte aligned
subtype ADDR_16BIT_BRAM_RANGE is natural range SOC_MAX_ADDR_BRAM_BIT-1 downto 1; -- Address range of the onboard B(lock)RAM - 2 bytes aligned
subtype ADDR_32BIT_BRAM_RANGE is natural range SOC_MAX_ADDR_BRAM_BIT-1 downto minAddrBit; -- Address range of the onboard B(lock)RAM - 4 bytes aligned
subtype ADDR_64BIT_BRAM_RANGE is natural range SOC_MAX_ADDR_BRAM_BIT-1 downto minAddrBit+1; -- Address range of the onboard B(lock)RAM - 8 bytes aligned
subtype ADDR_BIT_RAM_RANGE is natural range SOC_MAX_ADDR_RAM_BIT-1 downto 0; -- Address range of external RAM (BRAM, Dynamic, Static etc) - 1 byte aligned
subtype ADDR_16BIT_RAM_RANGE is natural range SOC_MAX_ADDR_RAM_BIT-1 downto 1; -- Address range of external RAM (BRAM, Dynamic, Static etc) - 2 bytes aligned
subtype ADDR_32BIT_RAM_RANGE is natural range SOC_MAX_ADDR_RAM_BIT-1 downto minAddrBit; -- Address range of external RAM (BRAM, Dynamic, Static etc) - 4 bytes aligned