altera/MainController/RAM.vhd

160 lines
4.5 KiB
VHDL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- Блок памяти способен асинхронно принимать данные с двух устройств одновременно
entity RAM is
port(
clk : in std_logic;
data0 : inout std_logic_vector(7 downto 0);
address0 : in std_logic_vector(7 downto 0);
we0 : in std_logic;
oe0 : in std_logic;
ce0 : in std_logic;
data1 : inout std_logic_vector(7 downto 0);
address1 : in std_logic_vector(7 downto 0);
we1 : in std_logic;
oe1 : in std_logic;
ce1 : in std_logic
);
end entity;
architecture behavorial of RAM is
type mem is array (255 downto 0) of std_logic_vector(7 downto 0);
signal memory : mem;
signal we0Prev : std_logic := '0';
signal oe0Prev : std_logic := '0';
signal ce0Prev : std_logic := '0';
signal we1Prev : std_logic := '0';
signal oe1Prev : std_logic := '0';
signal ce1Prev : std_logic := '0';
type MemoryMachine is (Waiting, Writing, Reading);
signal stateMM0 : MemoryMachine := Waiting;
signal stateMM1 : MemoryMachine := Waiting;
begin
-- автомат для работы с памятью со стороны контроллера
process(clk)
variable addr : integer range 0 to 255 := 0;
begin
if rising_edge(clk) then
case stateMM0 is
when Waiting =>
if ce0 = '0' and ce0Prev = '1' then
addr := conv_integer(address0);
if oe0 = '0' then -- этот if можно перенести на следующий такт, чтобы успела установиться ножка output enable
stateMM0 <= Reading;
else
stateMM0 <= Writing;
end if;
else
addr := 0;
data0 <= (others => 'Z');
end if;
when Reading =>
data0 <= memory(addr);
if oe0 = '1' and oe0Prev = '0' then
stateMM0 <= Waiting;
elsif ce0 = '1' then
stateMM0 <= Waiting;
end if;
when Writing =>
if we0 = '0' and we0Prev = '1' then
memory(addr) <= data0;
stateMM0 <= Waiting;
elsif ce0 = '1' then
stateMM0 <= Waiting;
end if;
when others =>
end case;
oe0Prev <= oe0;
ce0Prev <= ce0;
we0Prev <= we0;
end if;
end process;
-- автомат для работы с памятью со стороны контроллера
process(clk)
variable addr : integer range 0 to 255 := 0;
begin
if rising_edge(clk) then
case stateMM1 is
when Waiting =>
if ce1 = '0' and ce1Prev = '1' then
addr := conv_integer(address1);
if oe1 = '0' then -- этот if можно перенести на следующий такт, чтобы успела установиться ножка output enable
stateMM1 <= Reading;
else
stateMM1 <= Writing;
end if;
else
addr := 0;
data1 <= (others => 'Z');
end if;
when Reading =>
data1 <= memory(addr);
if oe1 = '1' and oe1Prev = '0' then
stateMM1 <= Waiting;
elsif ce0 = '1' then
stateMM1 <= Waiting;
end if;
when Writing =>
if we1 = '0' and we1Prev = '1' then
memory(addr) <= data1;
stateMM1 <= Waiting;
elsif ce0 = '1' then
stateMM1 <= Waiting;
end if;
when others =>
end case;
oe1Prev <= oe1;
ce1Prev <= ce1;
we1Prev <= we1;
end if;
end process;
-- process(clk)
-- variable addr : integer range 0 to 255;
-- begin
-- if rising_edge(clk) then
-- if clk = '1' and clkPrev = '0' then
-- addr := conv_integer(address1); -- переменной addr1 присваивается новое значение сразу. Удобно для преобразования типов.
-- if (wr1 = '0') then
-- memory(addr1) <= data1; -- тут уже новое значение переменной addr1
-- else
-- data1 <= memory(addr1);
-- end if;
-- end if;
-- if clk1 = '0' and clk1Prev = '1' then
-- data1 <= (others => 'Z');
-- end if;
--
-- clk1Prev <= clk1;
--
-- if clk0 = '1' and clk0Prev = '0' then
-- addr0 := conv_integer(address0); -- переменной addr0 присваивается новое значение сразу. Удобно для преобразования типов.
-- if (wr0 = '0') then
-- memory(addr0) <= data0; -- тут уже новое значение переменной addr0
-- else
-- data0 <= memory(addr0);
-- end if;
-- end if;
-- if clk0 = '0' and clk0Prev = '1' then
-- data0 <= (others => 'Z');
-- end if;
--
-- clk0Prev <= clk0;
--
-- end if;
-- end process;
end behavorial;