altera/MainController/RAM9X8_HWPBusMaster.vhd

207 lines
6.3 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_arith.all;
use ieee.std_logic_unsigned.all;
entity RAM9X8_HWPBusMaster is
generic(
HWP_CMD_2_LOWER : integer := 46;
HWP_CMD_2_UPPER : integer := 47;
HWP_CMD_1_LOWER : integer := 48;
HWP_CMD_1_UPPER : integer := 49;
HWP_DATA_2_LOWER : integer := 50;
HWP_DATA_2_UPPER : integer := 51;
HWP_DATA_1_LOWER : integer := 52;
HWP_DATA_1_UPPER : integer := 53;
DATA_BUS_WIDTH : integer := 8;
ADDRESS_BUS_WIDTH : integer := 9
);
port(
clk : in std_logic;
data : inout std_logic_vector(DATA_BUS_WIDTH - 1 downto 0);
address : in std_logic_vector(ADDRESS_BUS_WIDTH - 1 downto 0);
we : in std_logic;
oe : in std_logic;
ce : in std_logic;
hwpdataout : out std_logic;
hwpclk : out std_logic;
hwpdatain : in std_logic_vector(1 downto 0)
);
end entity;
architecture behavorial of RAM9X8_HWPBusMaster is
signal cmdBuf : std_logic_vector(31 downto 0) := (others => '0');
signal dataBuf : std_logic_vector(31 downto 0) := (others => '0');
signal tempBuf : std_logic_vector(31 downto 0) := (others => '0');
signal dataToSend : std_logic_vector(33 downto 0) := (others => '0');
signal cmdBuf_0_prev : std_logic := '0';
signal done : std_logic := '1';
type HWPSt is (Waiting, SendingData, ReceivingData, Checking);
signal HWPState : HWPSt := Waiting;
begin
process (we, oe, ce)
variable addr : integer range 0 to 2**ADDRESS_BUS_WIDTH - 1 := 0;
begin
if (ce = '0') then -- Если микросхема выбрана
addr := conv_integer(address);
if (addr = HWP_CMD_2_UPPER or addr = HWP_CMD_2_LOWER or addr = HWP_CMD_1_UPPER or addr = HWP_CMD_1_LOWER
or addr = HWP_DATA_2_UPPER or addr = HWP_DATA_2_LOWER or addr = HWP_DATA_1_UPPER or addr = HWP_DATA_1_LOWER) then
if (oe = '0' and we = '1') then -- Если сигнал чтения активен, а записи нет
case addr is
when HWP_CMD_2_UPPER =>
data <= cmdBuf(31 downto 24);
when HWP_CMD_2_LOWER =>
data <= cmdBuf(23 downto 16);
when HWP_CMD_1_UPPER =>
data <= cmdBuf(15 downto 8);
when HWP_CMD_1_LOWER =>
data(7 downto 1) <= cmdBuf(7 downto 1);
data(0) <= done;
when HWP_DATA_2_UPPER =>
data <= tempBuf(29 downto 22);
when HWP_DATA_2_LOWER =>
data <= tempBuf(21 downto 14);
when HWP_DATA_1_UPPER =>
data <= tempBuf(13 downto 6);
when HWP_DATA_1_LOWER =>
data(7 downto 2) <= tempBuf(5 downto 0);
data(1 downto 0) <= (others => '0');
when others =>
data <= (others => 'Z'); -- Запретить запись на шину
end case;
elsif (oe = '1' and we = '0') then -- Если сигнал записи активен, а чтения нет
case addr is
when HWP_CMD_2_UPPER =>
cmdBuf(31 downto 24) <= data;
when HWP_CMD_2_LOWER =>
cmdBuf(23 downto 16) <= data;
when HWP_CMD_1_UPPER =>
cmdBuf(15 downto 8) <= data;
when HWP_CMD_1_LOWER =>
cmdBuf(7 downto 0) <= data;
when HWP_DATA_2_UPPER =>
dataBuf(31 downto 24) <= data;
when HWP_DATA_2_LOWER =>
dataBuf(23 downto 16) <= data;
when HWP_DATA_1_UPPER =>
dataBuf(15 downto 8) <= data;
when HWP_DATA_1_LOWER =>
dataBuf(7 downto 0) <= data;
when others =>
data <= (others => 'Z'); -- Запретить запись на шину
end case;
else
data <= (others => 'Z'); -- Запретить запись на шину
end if;
else
data <= (others => 'Z'); -- Запретить запись на шину
end if;
else
data <= (others => 'Z'); -- Запретить запись на шину
end if;
end process;
process(clk) is
variable count : integer range 0 to 511 := 0;
variable state : integer range 0 to 1 := 0;
variable countBit : integer range 0 to 32 := 0;
begin
if rising_edge(clk) then
case HWPState is
when Waiting =>
if cmdBuf(0) = '1' and cmdBuf_0_prev = '0' then
done <= '1';
if cmdBuf(14) = '0' then
if cmdBuf(13) = '0' then
dataToSend(33 downto 22) <= (others => '0');
dataToSend(21 downto 16) <= cmdBuf(15 downto 10);
dataToSend(15 downto 0) <= cmdBuf(31 downto 16);
countBit := 21;
else
dataToSend(33) <= '0';
dataToSend(32 downto 30) <= cmdBuf(15 downto 13);
dataToSend(29 downto 0) <= dataBuf(31 downto 2);
countBit := 32;
end if;
else
dataToSend(33) <= '1';
dataToSend(32 downto 2) <= (others => '0');
dataToSend(1 downto 0) <= cmdBuf(15 downto 14);
countBit := 1;
end if;
HWPState <= SendingData;
count := 0;
state := 0;
end if;
when SendingData =>
if count < 511 and state = 0 then
if count = 0 then
hwpdataout <= dataToSend(countBit);
end if;
count := count + 1;
elsif count = 511 and state = 0 then
hwpclk <= '0';
count := 0;
state := 1;
elsif count < 511 and state = 1 then
count := count + 1;
elsif count = 511 and state = 1 then
hwpclk <= '1';
count := 0;
state := 0;
if countBit > 0 then
countBit := countBit - 1;
else
if dataToSend(33) = '1' then
HWPState <= ReceivingData;
countBit := 29;
else
HWPState <= Checking;
end if;
end if;
end if;
when ReceivingData =>
if count < 511 and state = 0 then
count := count + 1;
elsif count = 511 and state = 0 then
hwpclk <= '0';
count := 0;
state := 1;
if dataToSend(1) = '0' then
tempBuf(countBit) <= hwpdatain(0);
hwpdataout <= hwpdatain(0);
else
tempBuf(countBit) <= hwpdatain(1);
hwpdataout <= hwpdatain(1);
end if;
elsif count < 511 and state = 1 then
count := count + 1;
elsif count = 511 and state = 1 then
hwpclk <= '1';
count := 0;
state := 0;
if countBit > 0 then
countBit := countBit - 1;
else
HWPState <= Checking;
end if;
end if;
when Checking =>
done <= '0';
HWPState <= Waiting;
when others =>
HWPState <= Waiting;
end case;
cmdBuf_0_prev <= cmdBuf(0);
end if;
end process;
end behavorial;