altera/MainController/RAM.vhd

179 lines
5.8 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;
-- Блок памяти (8х32) способен принимать данные с двух устройств одновременно;
-- Со стороны контроллера - постфикс "0" - данные грузятся в ячейку памяти четырьмя транзакциями, поскольку шина данных здесь всего 8 бит;
-- Со стороны ПЛИС - постфикс "1" - данные грузятся за одну транзакцию (шина данных 32х разрядная);
-- Для работы с контроллером дополнительно введены два бита BL для определения с какой частью ячейки памяти работаем;
-- Когда в комментариях говорю "со стороны ПЛИС" - это значит, что есть IP блок диспетчеризации,
-- который получает свежайшие данные от остальных IP блоков на ПЛИС, создает приоритетную очередь и грузит эти данные в ячейки памяти;
entity RAM is
generic(
REG_ADDR_FIRST : integer := 0;
REG_ADDR_LAST : integer := 16;
TEST : integer := 5
);
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;
bl0 : in std_logic_vector(1 downto 0);
data1 : inout std_logic_vector(31 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(31 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 addr0 : integer range 0 to 255 := 0;
variable part0 : integer range 0 to 3 := 0;
variable addr1 : integer range 0 to 255 := 0;
begin
if rising_edge(clk) then
case stateMM0 is
when Waiting =>
if ce0 = '0' and ce0Prev = '1' then
addr0 := conv_integer(address0);
part0 := conv_integer(bl0);
if oe0 = '0' then -- этот if можно перенести на следующий такт, чтобы успела установиться ножка output enable
stateMM0 <= Reading;
else
stateMM0 <= Writing;
end if;
else
data0 <= (others => 'Z');
end if;
when Reading =>
data0 <= memory(addr0)(7 + part0*8 downto part0*8);
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(addr0)(7 + part0*8 downto part0*8) <= data0;
stateMM0 <= Waiting;
elsif ce0 = '1' then
stateMM0 <= Waiting;
end if;
when others =>
end case;
oe0Prev <= oe0;
ce0Prev <= ce0;
we0Prev <= we0;
case stateMM1 is
when Waiting =>
if ce1 = '0' and ce1Prev = '1' then
addr1 := conv_integer(address1);
if oe1 = '0' then -- этот if можно перенести на следующий такт, чтобы успела установиться ножка output enable
stateMM1 <= Reading;
else
stateMM1 <= Writing;
end if;
else
data1 <= (others => 'Z');
end if;
when Reading =>
data1 <= memory(addr1);
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(addr1) <= data1;
stateMM1 <= Waiting;
elsif ce0 = '1' then
stateMM1 <= Waiting;
end if;
when others =>
end case;
oe1Prev <= oe1;
ce1Prev <= ce1;
we1Prev <= we1;
memory(0) <= x"AABBCCDD";
memory(1) <= x"EEFF0011";
memory(2) <= x"22334455";
memory(3) <= x"66778899";
memory(4) <= x"EEFF0011";
memory(5) <= x"AAAAAAAA";
memory(6) <= x"55555555";
memory(7) <= x"BBBBBBBB";
memory(8) <= x"66666666";
memory(9) <= memory(9) + 1;
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;