160 lines
4.5 KiB
VHDL
160 lines
4.5 KiB
VHDL
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; |