library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity RAM9X8_Peripheral is generic( PER_BASE_ADDRESS : integer := 40; 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 : in std_logic ); end entity; architecture behavorial of RAM9X8_Peripheral is signal PER_ACTIVE_DEVICE_LOWER : integer := PER_BASE_ADDRESS; signal PER_ACTIVE_DEVICE_UPPER : integer := PER_BASE_ADDRESS + 1; signal PER_REZERVED_1_LOWER : integer := PER_BASE_ADDRESS + 2; signal PER_REZERVED_1_UPPER : integer := PER_BASE_ADDRESS + 3; signal PER_REZERVED_2_LOWER : integer := PER_BASE_ADDRESS + 4; signal PER_REZERVED_2_UPPER : integer := PER_BASE_ADDRESS + 5; signal activeDeviceBuf : std_logic_vector(15 downto 0) := (others => '0'); signal rezerved1Buf : std_logic_vector(15 downto 0) := (others => '0'); signal rezerved2Buf : std_logic_vector(15 downto 0) := (others => '0'); signal divClkBuf : std_logic := '0'; signal divClkBufPWM : std_logic := '0'; signal addrBuf : std_logic_vector(3 downto 0) := (others => '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 = PER_ACTIVE_DEVICE_UPPER or addr = PER_ACTIVE_DEVICE_LOWER or addr = PER_REZERVED_1_UPPER or addr = PER_REZERVED_1_LOWER or addr = PER_REZERVED_2_UPPER or addr = PER_REZERVED_2_LOWER) then if (oe = '0' and we = '1') then -- Если сигнал чтения активен, а записи нет case addr is when PER_ACTIVE_DEVICE_UPPER => data <= activeDeviceBuf(15 downto 8); when PER_ACTIVE_DEVICE_LOWER => data <= activeDeviceBuf(7 downto 0); when PER_REZERVED_1_UPPER => data <= rezerved1Buf(15 downto 8); when PER_REZERVED_1_LOWER => data <= rezerved1Buf(7 downto 0); when PER_REZERVED_2_UPPER => data <= rezerved2Buf(15 downto 8); when PER_REZERVED_2_LOWER => data <= rezerved2Buf(7 downto 0); when others => data <= (others => 'Z'); -- Запретить запись на шину end case; elsif (oe = '1' and we = '0') then -- Если сигнал записи активен, а чтения нет case addr is when PER_ACTIVE_DEVICE_UPPER => activeDeviceBuf(15 downto 8) <= data; when PER_ACTIVE_DEVICE_LOWER => activeDeviceBuf(7 downto 0) <= data; when PER_REZERVED_1_UPPER => rezerved1Buf(15 downto 8) <= data; when PER_REZERVED_1_LOWER => rezerved1Buf(7 downto 0) <= data; when PER_REZERVED_2_UPPER => rezerved2Buf(15 downto 8) <= data; when PER_REZERVED_2_LOWER => rezerved2Buf(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 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 init = '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;