Line 14... |
Line 14... |
--
|
--
|
-- You should have received a copy of the GNU Lesser General Public License
|
-- You should have received a copy of the GNU Lesser General Public License
|
-- along with Experimental Unstable CPU System. If not, see
|
-- along with Experimental Unstable CPU System. If not, see
|
-- http://www.gnu.org/licenses/lgpl.txt.
|
-- http://www.gnu.org/licenses/lgpl.txt.
|
|
|
|
-- This package is the main interface to the memory. When defining
|
|
-- different sizes, this package generates the main component.
|
|
-- The components themselves are responsible for using the contents
|
|
-- of the passed file name to initialise the memory array.
|
|
|
LIBRARY ieee;
|
LIBRARY ieee;
|
USE ieee.std_logic_1164.ALL;
|
USE ieee.std_logic_1164.ALL;
|
USE ieee.numeric_std.ALL;
|
USE ieee.numeric_std.ALL;
|
|
|
PACKAGE ram_parts IS
|
PACKAGE RAM IS
|
|
|
COMPONENT generic_ram IS
|
COMPONENT memory IS
|
|
|
GENERIC (
|
GENERIC (
|
filename : STRING := "";
|
filename : STRING := "";
|
w_data : NATURAL RANGE 1 TO 32 := 16;
|
w_data : NATURAL RANGE 1 TO 32 := 16;
|
w_addr : NATURAL RANGE 8 TO 14 := 10);
|
w_addr : NATURAL RANGE 8 TO 14 := 10);
|
Line 36... |
Line 40... |
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
|
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
|
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
|
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
|
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
|
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
|
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
|
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
|
|
|
END COMPONENT generic_ram;
|
END COMPONENT memory;
|
|
|
COMPONENT RAM32K IS
|
END PACKAGE RAM;
|
|
|
GENERIC (
|
|
w_data : NATURAL RANGE 1 TO 32 := 16;
|
|
file_1 : STRING := "";
|
|
file_2 : STRING := "";
|
|
file_3 : STRING := "";
|
|
file_4 : STRING := "");
|
|
PORT (
|
|
clk : IN STD_LOGIC;
|
|
we : IN STD_LOGIC;
|
|
a1 : IN STD_LOGIC_VECTOR(14 DOWNTO 0); -- Data port address
|
|
a2 : IN STD_LOGIC_VECTOR(14 DOWNTO 0); -- Instruction port address
|
|
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
|
|
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
|
|
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
|
|
|
|
END COMPONENT RAM32K;
|
|
|
|
END PACKAGE ram_parts;
|
|
|
|
LIBRARY ieee;
|
LIBRARY ieee;
|
USE ieee.std_logic_1164.ALL;
|
USE ieee.std_logic_1164.ALL;
|
USE ieee.numeric_std.ALL;
|
USE ieee.numeric_std.ALL;
|
USE std.textio.ALL;
|
USE std.textio.ALL;
|
USE ieee.std_logic_textio.ALL;
|
USE ieee.std_logic_textio.ALL;
|
USE work.arrayio.ALL;
|
USE work.ram_parts.ALL;
|
|
|
ENTITY generic_ram IS
|
ENTITY memory IS
|
|
|
-- Memory component based upon Xilinx Spartan-6 block RAM
|
-- Memory component based upon Xilinx Spartan-6 block RAM
|
-- Maximum capacity is 16k words
|
-- Maximum capacity is 16k words
|
-- This component can be initialised by passing a file name as a generic
|
-- This component can be initialised by passing a file name as a generic
|
-- parameter.
|
-- parameter.
|
|
|
GENERIC (
|
GENERIC (
|
filename : STRING := "";
|
filename : STRING := "";
|
w_data : NATURAL RANGE 1 TO 32 := 16;
|
w_data : NATURAL RANGE 1 TO 32 := 16;
|
w_addr : NATURAL RANGE 8 TO 14 := 10);
|
w_addr : NATURAL RANGE 8 TO 15 := 10);
|
PORT (
|
PORT (
|
clk : IN STD_LOGIC;
|
clk : IN STD_LOGIC;
|
we : IN STD_LOGIC;
|
we : IN STD_LOGIC;
|
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address
|
a1 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Data port address
|
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
|
a2 : IN STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0); -- Instruction port address
|
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
|
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
|
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
|
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
|
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
|
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
|
|
|
END generic_ram;
|
END memory;
|
|
|
ARCHITECTURE Behavioral OF generic_ram IS
|
|
|
|
SIGNAL mem : cstr_array_type(0 TO (2**w_addr) - 1) := init_cstr(2**w_addr, filename);
|
|
|
|
SIGNAL address_reg_1 : STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0);
|
|
SIGNAL address_reg_2 : STD_LOGIC_VECTOR(w_addr - 1 DOWNTO 0);
|
|
|
|
BEGIN -- Behavioral
|
|
|
|
-- purpose: Try to describe a proper block ram without needing to instantiate a BRAM
|
|
-- type : sequential
|
|
-- inputs : clk, we, a1, a2, d1
|
|
-- outputs: q1, q2
|
|
MP1 : PROCESS (clk, address_reg_1, address_reg_2, mem)
|
|
BEGIN -- PROCESS MP1
|
|
|
|
-- Reading
|
|
q1 <= STD_LOGIC_VECTOR(to_unsigned(mem(to_integer(UNSIGNED(address_reg_1))), w_data));
|
|
q2 <= STD_LOGIC_VECTOR(to_unsigned(mem(to_integer(UNSIGNED(address_reg_2))), w_data));
|
|
|
|
IF rising_edge(clk) THEN -- rising clock edge
|
|
|
|
-- These work like the block RAM registers
|
|
address_reg_1 <= a1;
|
|
address_reg_2 <= a2;
|
|
|
|
-- Writing
|
|
IF we = '1' THEN
|
|
mem(to_integer(UNSIGNED(a1))) <= to_integer(UNSIGNED(d1));
|
|
END IF;
|
|
|
|
END IF;
|
|
|
|
END PROCESS MP1;
|
|
|
|
|
|
END Behavioral;
|
|
|
|
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.ALL;
|
|
USE ieee.numeric_std.ALL;
|
|
USE work.mux_parts.ALL;
|
|
USE work.ram_parts.ALL;
|
|
|
|
ENTITY RAM32K IS
|
ARCHITECTURE Structural OF memory IS
|
|
|
-- This component is based upon the above defined generic_ram
|
|
-- It is constructed using a 4-to-1 multiplexer and 4 8k word
|
|
-- generic_rams.
|
|
-- In order to initialise it, a filename can be passed, which is then
|
|
-- used to generate the names of four files which should have been
|
|
-- prepared previously: filename_{0|1|2|3}.txt
|
|
-- These will be used to initialise the four RAM components.
|
|
|
|
GENERIC (
|
|
w_data : NATURAL RANGE 1 TO 32 := 16;
|
|
file_1 : STRING := "";
|
|
file_2 : STRING := "";
|
|
file_3 : STRING := "";
|
|
file_4 : STRING := "");
|
|
PORT (
|
|
clk : IN STD_LOGIC;
|
|
we : IN STD_LOGIC;
|
|
a1 : IN STD_LOGIC_VECTOR(14 DOWNTO 0); -- Data port address
|
|
a2 : IN STD_LOGIC_VECTOR(14 DOWNTO 0); -- Instruction port address
|
|
d1 : IN STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port input
|
|
q1 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0); -- Data port output
|
|
q2 : OUT STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0)); -- Instruction port output
|
|
|
|
END RAM32K;
|
|
|
|
ARCHITECTURE Structural OF RAM32K IS
|
|
|
|
SIGNAL data_address : STD_LOGIC_VECTOR(12 DOWNTO 0);
|
|
SIGNAL data_select : STD_LOGIC_VECTOR(1 DOWNTO 0);
|
|
SIGNAL instr_address : STD_LOGIC_VECTOR(12 DOWNTO 0);
|
|
SIGNAL instr_select : STD_LOGIC_VECTOR(1 DOWNTO 0);
|
|
|
|
SIGNAL wr_sel : STD_LOGIC_VECTOR(3 DOWNTO 0);
|
|
|
|
TYPE bus_array_t IS ARRAY(0 TO 3) OF STD_LOGIC_VECTOR(w_data - 1 DOWNTO 0);
|
|
|
|
SIGNAL data : bus_array_t;
|
|
SIGNAL inst : bus_array_t;
|
|
|
|
TYPE file_array IS ARRAY(INTEGER RANGE <>) OF STRING(1 TO 100);
|
|
|
|
CONSTANT i_file : file_array(0 TO 3) := (file_1, file_2, file_3, file_4);
|
|
|
|
BEGIN -- Structural
|
BEGIN -- Structural
|
|
|
data_address <= a1(12 DOWNTO 0);
|
SMALL_MEM : IF w_data >= 8 AND w_data <= 14 GENERATE
|
data_select <= a1(14 DOWNTO 13);
|
MEM0 : RAM_GENERIC
|
|
|
instr_address <= a2(12 DOWNTO 0);
|
|
instr_select <= a2(14 DOWNTO 13);
|
|
|
|
wr_sel <= "0001" WHEN data_select = "00" AND we = '1' ELSE
|
|
"0010" WHEN data_select = "01" AND we = '1' ELSE
|
|
"0100" WHEN data_select = "10" AND we = '1' ELSE
|
|
"1000" WHEN data_select = "11" AND we = '1' ELSE
|
|
"0000";
|
|
|
|
M1 : mux4to1
|
|
PORT MAP (
|
|
SEL => data_select,
|
|
S0 => data(0),
|
|
S1 => data(1),
|
|
S2 => data(2),
|
|
S3 => data(3),
|
|
Y => q1);
|
|
|
|
M2 : mux4to1
|
|
PORT MAP (
|
|
SEL => instr_select,
|
|
S0 => inst(0),
|
|
S1 => inst(1),
|
|
S2 => inst(2),
|
|
S3 => inst(3),
|
|
Y => q2);
|
|
|
|
RAM : FOR i IN 0 TO 3 GENERATE
|
|
|
|
R0 : generic_ram
|
|
GENERIC MAP (
|
GENERIC MAP (
|
filename => i_file(i),
|
filename => filename,
|
w_data => w_data,
|
w_data => w_data,
|
w_addr => 13)
|
w_addr => w_addr)
|
PORT MAP (
|
PORT MAP (
|
clk => clk,
|
clk => clk,
|
we => wr_sel(i),
|
we => we,
|
a1 => data_address,
|
a1 => a1,
|
a2 => instr_address,
|
a2 => a2,
|
d1 => d1,
|
d1 => d1,
|
q1 => data(i),
|
q1 => q1,
|
q2 => inst(i));
|
q2 => q2);
|
|
END GENERATE SMALL_MEM;
|
|
|
END GENERATE RAM;
|
LARGE_MEM : IF w_data = 15 GENERATE
|
|
MEM1: RAM32K
|
|
GENERIC MAP (
|
|
filename => filename,
|
|
w_data => w_data)
|
|
PORT MAP (
|
|
clk => clk,
|
|
we => we,
|
|
a1 => a1,
|
|
a2 => a2,
|
|
d1 => d1,
|
|
q1 => q1,
|
|
q2 => q2);
|
|
END GENERATE LARGE_MEM;
|
|
|
END Structural;
|
END Structural;
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|