Line 1... |
Line 1... |
--RAM module
|
--Memory management component
|
--4096*8 bit file
|
--By having this separate, it should be fairly easy to add RAMs or ROMs later
|
--simultaneous write/read support
|
--This basically lets the CPU not have to worry about how memory "Really" works
|
--16 bit or 8 bit data bus
|
--currently just one RAM. 1024 byte blockram.vhd mapped as 0 - 1023
|
--16 bit address bus
|
|
--On Reset, will load a "default" RAM image
|
|
|
|
library IEEE;
|
library IEEE;
|
use IEEE.STD_LOGIC_1164.ALL;
|
use IEEE.STD_LOGIC_1164.ALL;
|
use ieee.std_logic_arith.all;
|
|
use IEEE.NUMERIC_STD.ALL;
|
use IEEE.NUMERIC_STD.ALL;
|
use ieee.std_logic_unsigned.all;
|
|
|
|
|
|
|
|
entity memory is
|
entity memory is
|
port(
|
port(
|
Address: in std_logic_vector(15 downto 0); --memory address
|
Address: in std_logic_vector(15 downto 0); --memory address (in bytes)
|
Write: in std_logic; --write or read
|
WriteWord: in std_logic; --if set, will write a full 16-bit word instead of a byte. Address must be aligned to 16-bit address. (bottom bit must be 0)
|
UseTopBits: in std_logic; --if 1, top 8 bits of data is ignored and not written to memory
|
WriteEnable: in std_logic;
|
Clock: in std_logic;
|
Clock: in std_logic;
|
DataIn: in std_logic_vector(15 downto 0);
|
DataIn: in std_logic_vector(15 downto 0);
|
DataOut: out std_logic_vector(15 downto 0);
|
DataOut: out std_logic_vector(15 downto 0)
|
Reset: in std_logic
|
-- Reset: in std_logic
|
|
|
|
--RAM/ROM interface (RAMA is built in to here
|
|
--RAMBDataIn: out std_logic_vector(15 downto 0);
|
|
--RAMBDataOut: in std_logic_vector(15 downto 0);
|
|
--RAMBAddress: out std_logic_vector(15 downto 0);
|
|
--RAMBWriteEnable: out std_logic_vector(1 downto 0);
|
);
|
);
|
end memory;
|
end memory;
|
|
|
architecture Behavioral of memory is
|
architecture Behavioral of memory is
|
constant BUSSIZE : integer := 8;
|
|
type memorytype is array(0 to integer((2**BUSSIZE))) of std_logic_vector(7 downto 0);
|
|
signal mem: memorytype;
|
|
begin
|
|
|
|
writemem: process(Reset,Write, Address, UseTopBits, Clock)
|
component blockram
|
variable addr: integer range 0 to (2**BUSSIZE)-1 := 0;
|
port(
|
|
Address: in std_logic_vector(7 downto 0); --memory address
|
|
WriteEnable: in std_logic_vector(1 downto 0); --write or read
|
|
Enable: in std_logic;
|
|
Clock: in std_logic;
|
|
DataIn: in std_logic_vector(15 downto 0);
|
|
DataOut: out std_logic_vector(15 downto 0)
|
|
);
|
|
end component;
|
|
|
|
constant R1START: integer := 0;
|
|
constant R1END: integer := 1023;
|
|
signal addr: std_logic_vector(15 downto 0) := (others => '0');
|
|
signal R1addr: std_logic_vector(7 downto 0);
|
|
signal we: std_logic_vector(1 downto 0);
|
|
signal datawrite: std_logic_vector(15 downto 0);
|
|
signal dataread: std_logic_vector(15 downto 0);
|
|
--signal en: std_logic;
|
|
signal R1we: std_logic_vector(1 downto 0);
|
|
signal R1en: std_logic;
|
|
signal R1in: std_logic_vector(15 downto 0);
|
|
signal R1out: std_logic_vector(15 downto 0);
|
begin
|
begin
|
addr := conv_integer(Address(BUSSIZE-1 downto 0));
|
R1: blockram port map (R1addr, R1we, R1en, Clock, R1in, R1out);
|
if(rising_edge(Clock)) then
|
addrwe: process(Address, WriteWord, WriteEnable, DataIn)
|
if(Reset ='1') then
|
begin
|
--mem <= (others => "00000000");
|
addr <= Address(15 downto 1) & '0';
|
elsif( Write='1') then
|
if WriteEnable='1' then
|
mem(addr) <= DataIn(7 downto 0);
|
if WriteWord='1' then
|
if(UseTopBits='1') then
|
we <= "11";
|
mem(addr+1) <= DataIn(15 downto 8);
|
datawrite <= DataIn;
|
|
else
|
|
if Address(0)='0' then
|
|
we <= "01";
|
|
datawrite <= x"00" & DataIn(7 downto 0); --not really necessary
|
|
else
|
|
we <= "10";
|
|
datawrite <= DataIn(7 downto 0) & x"00";
|
end if;
|
end if;
|
end if;
|
end if;
|
|
else
|
|
we <= "00";
|
end if;
|
end if;
|
end process;
|
end process;
|
readmem: process(Reset,Address,Write,Clock)
|
|
variable addr: integer range 0 to (2**BUSSIZE)-1 := 0;
|
assignram: process (we, datawrite, addr, r1out)
|
variable addr2: integer range 0 to (2**BUSSIZE)-1 := 0; -- for second part
|
variable tmp: integer;
|
|
variable found: boolean := false;
|
begin
|
begin
|
addr := conv_integer(Address(BUSSIZE-1 downto 0));
|
tmp := to_integer(unsigned(addr));
|
addr2 := conv_integer(Address(BUSSIZE-1 downto 0));
|
if tmp >= R1START and tmp <= R1END then
|
if(Reset='1') then
|
--map all to R1
|
DataOut <= (others => '0');
|
found := true;
|
elsif(Write='0') then
|
R1en <= '1';
|
DataOut <= mem(addr+1) & mem(addr);
|
R1we <= we;
|
|
R1in <= datawrite;
|
|
dataread <= R1out;
|
|
R1addr <= addr(8 downto 1);
|
else
|
else
|
DataOut <= (others => '0');
|
R1en <= '0';
|
|
R1we <= "00";
|
|
R1in <= x"0000";
|
|
R1addr <= x"00";
|
|
dataread <= x"0000";
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
readdata: process(Address, dataread)
|
|
begin
|
|
if Address(0) = '0' then
|
|
DataOut <= dataread;
|
|
else
|
|
DataOut <= x"00" & dataread(15 downto 8);
|
|
end if;
|
|
end process;
|
|
|
end Behavioral;
|
end Behavioral;
|
No newline at end of file
|
No newline at end of file
|