OpenCores
URL https://opencores.org/ocsvn/xucpu/xucpu/trunk

Subversion Repositories xucpu

[/] [xucpu/] [trunk/] [src/] [components/] [BRAM/] [RAM.vhdl] - Diff between revs 5 and 15

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 5 Rev 15
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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.