URL
https://opencores.org/ocsvn/xucpu/xucpu/trunk
Subversion Repositories xucpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 14 to Rev 15
- ↔ Reverse comparison
Rev 14 → Rev 15
/xucpu/trunk/src/components/BRAM/ram_parts.vhdl
0,0 → 1,221
|
-- |
-- This file is part of the Experimental Unstable CPU System. |
-- |
-- The Experimental Unstable CPU System Is free software: you can redistribute |
-- it and/or modify it under the terms of the GNU Lesser General Public License |
-- as published by the Free Software Foundation, either version 3 of the |
-- License, or (at your option) any later version. |
-- |
-- The Experimental Unstable CPU System is distributed in the hope that it will |
-- be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser |
-- General Public License for more details. |
-- |
-- You should have received a copy of the GNU Lesser General Public License |
-- along with Experimental Unstable CPU System. If not, see |
-- http://www.gnu.org/licenses/lgpl.txt. |
|
|
LIBRARY ieee; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
|
PACKAGE ram_parts IS |
|
COMPONENT RAM_GENERIC IS |
GENERIC ( |
filename : STRING := ""; |
w_data : NATURAL RANGE 1 TO 32 := 16; |
w_addr : NATURAL RANGE 8 TO 14 := 10); |
PORT ( |
clk : IN STD_LOGIC; |
we : IN STD_LOGIC; |
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 |
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 RAM_GENERIC; |
|
COMPONENT RAM32K IS |
|
GENERIC ( |
filename : STRING := ""; |
w_data : NATURAL RANGE 1 TO 32 := 16); |
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; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
USE std.textio.ALL; |
USE ieee.std_logic_textio.ALL; |
USE work.arrayio.ALL; |
|
ENTITY RAM_GENERIC IS |
|
-- Memory component based upon Xilinx Spartan-6 block RAM |
-- Maximum capacity is 16k words |
-- This component can be initialised by passing a file name as a generic |
-- parameter. |
|
GENERIC ( |
filename : STRING := ""; |
w_data : NATURAL RANGE 1 TO 32 := 16; |
w_addr : NATURAL RANGE 8 TO 14 := 10); |
PORT ( |
clk : IN STD_LOGIC; |
we : IN STD_LOGIC; |
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 |
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 RAM_GENERIC; |
|
ARCHITECTURE Behavioral OF RAM_GENERIC 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 |
|
-- This component is based upon the above defined memory |
-- It is constructed using a 4-to-1 multiplexer and 4 8k word |
-- memories. |
|
GENERIC ( |
w_data : NATURAL RANGE 1 TO 32 := 16; |
filename : 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 |
|
data_address <= a1(12 DOWNTO 0); |
data_select <= a1(14 DOWNTO 13); |
|
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 : memory |
GENERIC MAP ( |
filename => i_file(i), |
w_data => w_data, |
w_addr => 13) |
PORT MAP ( |
clk => clk, |
we => wr_sel(i), |
a1 => data_address, |
a2 => instr_address, |
d1 => d1, |
q1 => data(i), |
q2 => inst(i)); |
|
END GENERATE RAM; |
|
END Structural; |
|
/xucpu/trunk/src/components/BRAM/RAM.vhdl
16,14 → 16,18
-- along with Experimental Unstable CPU System. If not, see |
-- 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; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
|
PACKAGE ram_parts IS |
PACKAGE RAM IS |
|
COMPONENT generic_ram IS |
COMPONENT memory IS |
|
GENERIC ( |
filename : STRING := ""; |
38,37 → 42,18
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 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; |
USE ieee.std_logic_1164.ALL; |
USE ieee.numeric_std.ALL; |
USE std.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 |
-- Maximum capacity is 16k words |
78,7 → 63,7
GENERIC ( |
filename : STRING := ""; |
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 ( |
clk : IN STD_LOGIC; |
we : IN STD_LOGIC; |
88,146 → 73,42
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 generic_ram; |
END memory; |
|
ARCHITECTURE Behavioral OF generic_ram IS |
ARCHITECTURE Structural OF memory 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 |
|
-- 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 |
|
data_address <= a1(12 DOWNTO 0); |
data_select <= a1(14 DOWNTO 13); |
|
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 |
SMALL_MEM : IF w_data >= 8 AND w_data <= 14 GENERATE |
MEM0 : RAM_GENERIC |
GENERIC MAP ( |
filename => i_file(i), |
filename => filename, |
w_data => w_data, |
w_addr => 13) |
w_addr => w_addr) |
PORT MAP ( |
clk => clk, |
we => wr_sel(i), |
a1 => data_address, |
a2 => instr_address, |
we => we, |
a1 => a1, |
a2 => a2, |
d1 => d1, |
q1 => data(i), |
q2 => inst(i)); |
q1 => q1, |
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; |
|