2024-04-02 18:08:20 +03:00
|
|
|
|
library ieee;
|
|
|
|
|
use ieee.std_logic_1164.all;
|
|
|
|
|
use ieee.std_logic_arith.all;
|
|
|
|
|
use ieee.std_logic_unsigned.all;
|
|
|
|
|
|
|
|
|
|
entity RAM9X8_LedController is
|
|
|
|
|
generic(
|
2024-04-08 12:29:11 +03:00
|
|
|
|
REG_ADDR_ACTIVE_DEVICE_LOWER_BYTE : integer := 38;
|
|
|
|
|
REG_ADDR_ACTIVE_DEVICE_UPPER_BYTE : integer := 39;
|
|
|
|
|
REG_ADDR_TEST_LOWER_BYTE : integer := 40;
|
|
|
|
|
REG_ADDR_TEST_UPPER_BYTE : integer := 41;
|
|
|
|
|
REG_ADDR_VERSION_LOWER_BYTE : integer := 42;
|
|
|
|
|
REG_ADDR_VERSION_UPPER_BYTE : integer := 43;
|
2024-04-02 18:08:20 +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;
|
|
|
|
|
|
|
|
|
|
asyncline : out std_logic := '1';
|
|
|
|
|
divclk : out std_logic := '1';
|
|
|
|
|
error : in std_logic;
|
|
|
|
|
init : out std_logic := '0'
|
|
|
|
|
);
|
|
|
|
|
end entity;
|
|
|
|
|
|
|
|
|
|
architecture behavorial of RAM9X8_LedController is
|
|
|
|
|
|
|
|
|
|
signal activeDeviceBuf : std_logic_vector(15 downto 0) := (others => '0');
|
|
|
|
|
signal testBuf : std_logic_vector(15 downto 0) := (others => '0');
|
2024-04-04 16:27:31 +03:00
|
|
|
|
signal versionBuf : std_logic_vector(15 downto 0) := x"0004";
|
2024-04-02 18:08:20 +03:00
|
|
|
|
|
|
|
|
|
signal initBuf : std_logic := '0';
|
|
|
|
|
signal divClkBuf : std_logic := '0';
|
|
|
|
|
signal divClkBufPWM : std_logic := '0';
|
|
|
|
|
|
|
|
|
|
signal addrBuf : std_logic_vector(3 downto 0) := (others => '0');
|
|
|
|
|
signal ledBuf : std_logic := '0';
|
|
|
|
|
|
|
|
|
|
signal LedState : std_logic_vector(1 downto 0) := (others => '0');
|
|
|
|
|
|
|
|
|
|
type BusSt is (Waiting, A3, A2, A1, A0, Dt, Finish);
|
|
|
|
|
signal BusState : BusSt := Waiting;
|
|
|
|
|
|
|
|
|
|
signal countBuf : std_logic_vector(3 downto 0) := (others => '0');
|
|
|
|
|
signal countBufPWM : std_logic_vector(3 downto 0) := (others => '0');
|
|
|
|
|
|
|
|
|
|
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_ACTIVE_DEVICE_UPPER_BYTE or addr = REG_ADDR_ACTIVE_DEVICE_LOWER_BYTE
|
2024-04-08 12:29:11 +03:00
|
|
|
|
or addr = REG_ADDR_TEST_UPPER_BYTE or addr = REG_ADDR_TEST_LOWER_BYTE
|
|
|
|
|
or addr = REG_ADDR_VERSION_UPPER_BYTE or addr = REG_ADDR_VERSION_LOWER_BYTE) then
|
2024-04-02 18:08:20 +03:00
|
|
|
|
if (oe = '0' and we = '1') then -- Если сигнал чтения активен, а записи нет
|
|
|
|
|
case addr is
|
|
|
|
|
when REG_ADDR_ACTIVE_DEVICE_UPPER_BYTE =>
|
|
|
|
|
data <= activeDeviceBuf(15 downto 8);
|
|
|
|
|
when REG_ADDR_ACTIVE_DEVICE_LOWER_BYTE =>
|
|
|
|
|
data <= activeDeviceBuf(7 downto 0);
|
|
|
|
|
when REG_ADDR_TEST_UPPER_BYTE =>
|
|
|
|
|
data <= not testBuf(15 downto 8);
|
|
|
|
|
when REG_ADDR_TEST_LOWER_BYTE =>
|
|
|
|
|
data <= not testBuf(7 downto 0);
|
2024-04-04 16:27:31 +03:00
|
|
|
|
when REG_ADDR_VERSION_UPPER_BYTE =>
|
|
|
|
|
data <= versionBuf(15 downto 8);
|
|
|
|
|
when REG_ADDR_VERSION_LOWER_BYTE =>
|
|
|
|
|
data <= versionBuf(7 downto 0);
|
2024-04-02 18:08:20 +03:00
|
|
|
|
when others =>
|
|
|
|
|
data <= (others => 'Z'); -- Запретить запись на шину
|
|
|
|
|
end case;
|
|
|
|
|
elsif (oe = '1' and we = '0') then -- Если сигнал записи активен, а чтения нет
|
|
|
|
|
case addr is
|
|
|
|
|
when REG_ADDR_ACTIVE_DEVICE_UPPER_BYTE =>
|
|
|
|
|
activeDeviceBuf(15 downto 8) <= data;
|
|
|
|
|
when REG_ADDR_ACTIVE_DEVICE_LOWER_BYTE =>
|
|
|
|
|
activeDeviceBuf(7 downto 0) <= data;
|
|
|
|
|
when REG_ADDR_TEST_UPPER_BYTE =>
|
|
|
|
|
testBuf(15 downto 8) <= data;
|
|
|
|
|
when REG_ADDR_TEST_LOWER_BYTE =>
|
|
|
|
|
testBuf(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
|
|
|
|
|
begin
|
|
|
|
|
if rising_edge(clk) then
|
|
|
|
|
if testBuf = x"5AA5" then
|
|
|
|
|
initBuf <= '1';
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
init <= initBuf;
|
|
|
|
|
|
|
|
|
|
process(clk) is
|
|
|
|
|
variable count50000 : integer range 0 to 50000 := 0;
|
|
|
|
|
variable count50 : integer range 0 to 50 := 0;
|
|
|
|
|
begin
|
|
|
|
|
if rising_edge(clk) then
|
|
|
|
|
if count50000 < 50000 then
|
|
|
|
|
count50000 := count50000 + 1;
|
|
|
|
|
else
|
|
|
|
|
divClkBufPWM <= not divClkBufPWM;
|
|
|
|
|
count50000 := 0;
|
|
|
|
|
if count50 < 50 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
divClkBuf <= not divClkBuf;
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
process(divClkBufPWM) is
|
|
|
|
|
begin
|
|
|
|
|
if conv_integer(countBufPWM) < 15 then
|
|
|
|
|
countBufPWM <= conv_std_logic_vector(conv_integer(countBufPWM) + 1, 4);
|
|
|
|
|
else
|
|
|
|
|
countBufPWM <= (others => '0');
|
|
|
|
|
end if;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
process(divClkBuf) is
|
|
|
|
|
variable direction : integer range 0 to 1 := 0;
|
|
|
|
|
begin
|
|
|
|
|
if direction = 0 then
|
|
|
|
|
if conv_integer(countBuf) < 15 then
|
|
|
|
|
countBuf <= conv_std_logic_vector(conv_integer(countBuf) + 1, 4);
|
|
|
|
|
else
|
|
|
|
|
direction := 1;
|
|
|
|
|
end if;
|
|
|
|
|
else
|
|
|
|
|
if conv_integer(countBuf) > 0 then
|
|
|
|
|
countBuf <= conv_std_logic_vector(conv_integer(countBuf) - 1, 4);
|
|
|
|
|
else
|
|
|
|
|
direction := 0;
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
process(divClkBuf) is
|
|
|
|
|
variable count15 : integer range 0 to 15 := 0;
|
|
|
|
|
begin
|
|
|
|
|
case LedState is
|
|
|
|
|
when b"00" =>
|
|
|
|
|
if count15 < 15 then
|
|
|
|
|
count15 := count15 + 1;
|
|
|
|
|
else
|
|
|
|
|
count15 := 0;
|
|
|
|
|
LedState <= b"01";
|
|
|
|
|
end if;
|
|
|
|
|
divclk <= '0';
|
|
|
|
|
when b"01" =>
|
|
|
|
|
if count15 < 7 then
|
|
|
|
|
count15 := count15 + 1;
|
|
|
|
|
else
|
|
|
|
|
count15 := 0;
|
|
|
|
|
LedState <= b"10";
|
|
|
|
|
end if;
|
|
|
|
|
divclk <= '1';
|
|
|
|
|
when b"10" =>
|
|
|
|
|
if count15 < 15 then
|
|
|
|
|
count15 := count15 + 1;
|
|
|
|
|
else
|
|
|
|
|
count15 := 0;
|
|
|
|
|
LedState <= b"11";
|
|
|
|
|
end if;
|
|
|
|
|
divclk <= '0';
|
|
|
|
|
when b"11" =>
|
|
|
|
|
if count15 < 4 then
|
|
|
|
|
count15 := count15 + 1;
|
|
|
|
|
else
|
|
|
|
|
count15 := 0;
|
|
|
|
|
LedState <= b"00";
|
|
|
|
|
end if;
|
|
|
|
|
divclk <= '1';
|
|
|
|
|
when others =>
|
|
|
|
|
LedState <= b"00";
|
|
|
|
|
end case;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
process(clk) is
|
|
|
|
|
variable count50 : integer range 0 to 50 := 0;
|
|
|
|
|
variable count15 : integer range 0 to 15 := 15;
|
|
|
|
|
begin
|
|
|
|
|
if rising_edge(clk) then
|
|
|
|
|
if initBuf = '0' then
|
|
|
|
|
case BusState is
|
|
|
|
|
when Waiting =>
|
|
|
|
|
if count50 < 38 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
if count15 < 15 then
|
|
|
|
|
count15 := count15 + 1;
|
|
|
|
|
else
|
|
|
|
|
count15 := 0;
|
|
|
|
|
end if;
|
|
|
|
|
if activeDeviceBuf(count15) = '1' then
|
|
|
|
|
addrBuf <= conv_std_logic_vector(count15, 4);
|
|
|
|
|
asyncline <= '0';
|
|
|
|
|
count50 := 0;
|
|
|
|
|
BusState <= A3;
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
when A3 =>
|
|
|
|
|
if count50 < 18 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
asyncline <= addrBuf(3);
|
|
|
|
|
BusState <= A2;
|
|
|
|
|
end if;
|
|
|
|
|
when A2 =>
|
|
|
|
|
if count50 < 38 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
asyncline <= addrBuf(2);
|
|
|
|
|
BusState <= A1;
|
|
|
|
|
end if;
|
|
|
|
|
when A1 =>
|
|
|
|
|
if count50 < 38 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
asyncline <= addrBuf(1);
|
|
|
|
|
BusState <= A0;
|
|
|
|
|
end if;
|
|
|
|
|
when A0 =>
|
|
|
|
|
if count50 < 38 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
asyncline <= addrBuf(0);
|
|
|
|
|
BusState <= Dt;
|
|
|
|
|
end if;
|
|
|
|
|
when Dt =>
|
|
|
|
|
if count50 < 38 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
asyncline <= divClkBuf;
|
|
|
|
|
BusState <= Finish;
|
|
|
|
|
end if;
|
|
|
|
|
when Finish =>
|
|
|
|
|
if count50 < 38 then
|
|
|
|
|
count50 := count50 + 1;
|
|
|
|
|
else
|
|
|
|
|
count50 := 0;
|
|
|
|
|
asyncline <= '1';
|
|
|
|
|
BusState <= Finish;
|
|
|
|
|
end if;
|
|
|
|
|
when others =>
|
|
|
|
|
BusState <= Waiting;
|
|
|
|
|
count50 := 0;
|
|
|
|
|
count15 :=15;
|
|
|
|
|
end case;
|
|
|
|
|
else
|
|
|
|
|
BusState <= Waiting;
|
|
|
|
|
count50 := 0;
|
|
|
|
|
count15 := 15;
|
|
|
|
|
if error = '0' then
|
|
|
|
|
if countBuf < countBufPWM then
|
|
|
|
|
asyncline <= '1';
|
|
|
|
|
else
|
|
|
|
|
asyncline <= '0';
|
|
|
|
|
end if;
|
|
|
|
|
else
|
|
|
|
|
asyncline <= '1';
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
end if;
|
|
|
|
|
end process;
|
|
|
|
|
|
|
|
|
|
end behavorial;
|