Bug fix and start of stack cache being added
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
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.
|
||||
|
||||
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
12391
devices/sysbus/BRAM/IOCP_zOS_BootROM.vhd
Normal file
12391
devices/sysbus/BRAM/IOCP_zOS_BootROM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
34606
devices/sysbus/BRAM/IOCP_zOS_DualPortBootBRAM.vhd
Normal file
34606
devices/sysbus/BRAM/IOCP_zOS_DualPortBootBRAM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
34548
devices/sysbus/BRAM/IOCP_zOS_SinglePortBootBRAM.vhd
Normal file
34548
devices/sysbus/BRAM/IOCP_zOS_SinglePortBootBRAM.vhd
Normal file
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
11370
devices/sysbus/BRAM/zOS_BootROM.vhd
Normal file
11370
devices/sysbus/BRAM/zOS_BootROM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
66014
devices/sysbus/BRAM/zOS_DualPort32-64BootBRAM.vhd
Normal file
66014
devices/sysbus/BRAM/zOS_DualPort32-64BootBRAM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
45476
devices/sysbus/BRAM/zOS_DualPort3264BootBRAM.vhd
Normal file
45476
devices/sysbus/BRAM/zOS_DualPort3264BootBRAM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
45302
devices/sysbus/BRAM/zOS_DualPortBootBRAM.vhd
Normal file
45302
devices/sysbus/BRAM/zOS_DualPortBootBRAM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
160
devices/sysbus/BRAM/zOS_SinglePortBRAM.vhd
Normal file
160
devices/sysbus/BRAM/zOS_SinglePortBRAM.vhd
Normal 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;
|
||||
45244
devices/sysbus/BRAM/zOS_SinglePortBootBRAM.vhd
Normal file
45244
devices/sysbus/BRAM/zOS_SinglePortBootBRAM.vhd
Normal file
File diff suppressed because it is too large
Load Diff
33
zpu_soc.vhd
33
zpu_soc.vhd
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user