2024-04-03 18:51:31 +03:00
|
|
|
|
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(
|
2024-04-08 12:29:11 +03:00
|
|
|
|
REG_ADDR_CMD_2_LOWER_BYTE : integer := 46;
|
|
|
|
|
REG_ADDR_CMD_2_UPPER_BYTE : integer := 47;
|
|
|
|
|
REG_ADDR_CMD_1_LOWER_BYTE : integer := 48;
|
|
|
|
|
REG_ADDR_CMD_1_UPPER_BYTE : integer := 49;
|
|
|
|
|
REG_ADDR_DATA_2_LOWER_BYTE : integer := 50;
|
|
|
|
|
REG_ADDR_DATA_2_UPPER_BYTE : integer := 51;
|
|
|
|
|
REG_ADDR_DATA_1_LOWER_BYTE : integer := 52;
|
|
|
|
|
REG_ADDR_DATA_1_UPPER_BYTE : integer := 53;
|
2024-04-03 18:51:31 +03:00
|
|
|
|
|
|
|
|
|
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 = REG_ADDR_CMD_2_UPPER_BYTE or addr = REG_ADDR_CMD_2_LOWER_BYTE or addr = REG_ADDR_CMD_1_UPPER_BYTE or addr = REG_ADDR_CMD_1_LOWER_BYTE
|
|
|
|
|
or addr = REG_ADDR_DATA_2_UPPER_BYTE or addr = REG_ADDR_DATA_2_LOWER_BYTE or addr = REG_ADDR_DATA_1_UPPER_BYTE or addr = REG_ADDR_DATA_1_LOWER_BYTE) then
|
|
|
|
|
if (oe = '0' and we = '1') then -- Если сигнал чтения активен, а записи нет
|
|
|
|
|
case addr is
|
|
|
|
|
when REG_ADDR_CMD_2_UPPER_BYTE =>
|
|
|
|
|
data <= cmdBuf(31 downto 24);
|
|
|
|
|
when REG_ADDR_CMD_2_LOWER_BYTE =>
|
|
|
|
|
data <= cmdBuf(23 downto 16);
|
|
|
|
|
when REG_ADDR_CMD_1_UPPER_BYTE =>
|
|
|
|
|
data <= cmdBuf(15 downto 8);
|
|
|
|
|
when REG_ADDR_CMD_1_LOWER_BYTE =>
|
|
|
|
|
data(7 downto 1) <= cmdBuf(7 downto 1);
|
|
|
|
|
data(0) <= done;
|
|
|
|
|
when REG_ADDR_DATA_2_UPPER_BYTE =>
|
|
|
|
|
data <= tempBuf(29 downto 22);
|
|
|
|
|
when REG_ADDR_DATA_2_LOWER_BYTE =>
|
|
|
|
|
data <= tempBuf(21 downto 14);
|
|
|
|
|
when REG_ADDR_DATA_1_UPPER_BYTE =>
|
|
|
|
|
data <= tempBuf(13 downto 6);
|
|
|
|
|
when REG_ADDR_DATA_1_LOWER_BYTE =>
|
|
|
|
|
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 REG_ADDR_CMD_2_UPPER_BYTE =>
|
|
|
|
|
cmdBuf(31 downto 24) <= data;
|
|
|
|
|
when REG_ADDR_CMD_2_LOWER_BYTE =>
|
|
|
|
|
cmdBuf(23 downto 16) <= data;
|
|
|
|
|
when REG_ADDR_CMD_1_UPPER_BYTE =>
|
|
|
|
|
cmdBuf(15 downto 8) <= data;
|
|
|
|
|
when REG_ADDR_CMD_1_LOWER_BYTE =>
|
|
|
|
|
cmdBuf(7 downto 0) <= data;
|
|
|
|
|
when REG_ADDR_DATA_2_UPPER_BYTE =>
|
|
|
|
|
dataBuf(31 downto 24) <= data;
|
|
|
|
|
when REG_ADDR_DATA_2_LOWER_BYTE =>
|
|
|
|
|
dataBuf(23 downto 16) <= data;
|
|
|
|
|
when REG_ADDR_DATA_1_UPPER_BYTE =>
|
|
|
|
|
dataBuf(15 downto 8) <= data;
|
|
|
|
|
when REG_ADDR_DATA_1_LOWER_BYTE =>
|
|
|
|
|
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;
|