From f04720071bbc68c79e4fc0e60069ea6d98dca8bb Mon Sep 17 00:00:00 2001 From: sokolovstanislav Date: Tue, 26 Mar 2024 18:54:15 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D1=83=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BE=D0=B3=D0=BE=20=D0=B1=D0=BB=D0=BE=D0=BA=D0=B0=20Par?= =?UTF-8?q?allelBus.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MainController/RAM9X8_ParallelBusMaster.vhd | 244 ++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 MainController/RAM9X8_ParallelBusMaster.vhd diff --git a/MainController/RAM9X8_ParallelBusMaster.vhd b/MainController/RAM9X8_ParallelBusMaster.vhd new file mode 100644 index 0000000..70377af --- /dev/null +++ b/MainController/RAM9X8_ParallelBusMaster.vhd @@ -0,0 +1,244 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity RAM9X8_ParallelBusMaster is + generic( + REG_ADDR_FIRST_FREE_UPPER_BYTE : integer := 6; + REG_ADDR_FIRST_FREE_LOWER_BYTE : integer := 7; + REG_ADDR_CMD_UPPER_BYTE : integer := 8; + REG_ADDR_CMD_LOWER_BYTE : integer := 9; + REG_ADDR_FILL_ADDRESS_SPACE_UPPER_BYTE : integer := 10; + REG_ADDR_FILL_ADDRESS_SPACE_LOWER_BYTE : integer := 11; + REG_ADDR_CONTROL_UPPER_BYTE : integer := 12; + REG_ADDR_CONTROL_LOWER_BYTE : integer := 13; + + ARRAY_LENGTH : integer := 128; + 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; + + pbclk : out std_logic := '1'; + pbce : out std_logic := '1'; + pbdir : out std_logic_vector(1 downto 0) := (others => '1'); + pbdata : inout std_logic_vector(15 downto 0) := (others => 'Z'); + pback : in std_logic + ); +end entity; + +architecture behavorial of RAM9X8_ParallelBusMaster is + +type mem is array (ARRAY_LENGTH - 1 downto 0) of std_logic_vector(7 downto 0); +signal memoryAddress : mem; +signal memoryData : mem; + +signal firstFreeBuf : std_logic_vector(15 downto 0) := (others => '0'); +signal cmdBuf : std_logic_vector(15 downto 0) := (others => '0'); +signal fasBuf : std_logic_vector(15 downto 0) := (others => '0'); +signal controlBuf : std_logic_vector(15 downto 0) := (others => '0'); + +signal direction : std_logic := '0'; +signal addressToTransmit : std_logic_vector(7 downto 0) := x"00"; +signal dataToTransmit : std_logic_vector(15 downto 0) := x"0000"; +signal dataFromDevices : std_logic_vector(15 downto 0) := x"0000"; + +type CommunicationState_start is (Waiting, TransmiteAddress, TransmiteCheck, PreparingToReceiveData, ReceiveData, ReceiveCheck, Timeout, ReceiveCheckTimeout); +signal CommunicationState : CommunicationState_start := Waiting ; + +signal lineBusy : std_logic := '1'; +signal start : std_logic := '0'; +signal startPrev : std_logic := '0'; + +begin + + process (we, oe, ce) + variable addr : integer range 0 to 2**ADDRESS_BUS_WIDTH - 1 := 0; + variable position : integer range 0 to ARRAY_LENGTH - 1 := 0; + begin + if (ce = '0') then -- Если микросхема выбрана + addr := conv_integer(address); + if (addr = REG_ADDR_FIRST_FREE_UPPER_BYTE or addr = REG_ADDR_FIRST_FREE_LOWER_BYTE or addr = REG_ADDR_CMD_UPPER_BYTE or addr = REG_ADDR_CMD_LOWER_BYTE + or addr = REG_ADDR_FILL_ADDRESS_SPACE_UPPER_BYTE or addr = REG_ADDR_FILL_ADDRESS_SPACE_LOWER_BYTE or addr = ) then + if (oe = '0') then -- Если сигнал чтения активен + case addr is + when REG_ADDR_FIRST_FREE_UPPER_BYTE => + data <= firstFreeBuf(15 downto 8); + when REG_ADDR_FIRST_FREE_LOWER_BYTE => + data <= firstFreeBuf(7 downto 0); + when REG_ADDR_CMD_UPPER_BYTE => + data <= cmdBuf(15 downto 8); + when REG_ADDR_CMD_LOWER_BYTE => + data <= cmdBuf(7 downto 0); + when REG_ADDR_FILL_ADDRESS_SPACE_UPPER_BYTE => + data <= fasBuf(15 downto 8); + when REG_ADDR_FILL_ADDRESS_SPACE_LOWER_BYTE => + data <= fasBuf(7 downto 0); + when REG_ADDR_CONTROL_UPPER_BYTE => + data <= errorBuf; + when REG_ADDR_CONTROL_LOWER_BYTE => + data <= controlBuf(7 downto 0); + when others => + data <= (others => 'Z'); -- Запретить запись на шину + end case; + elsif (we = '0') then -- Если сигнал записи активен + case addr is + when REG_ADDR_FIRST_FREE_UPPER_BYTE => + firstFreeBuf(15 downto 8) <= data; + when REG_ADDR_FIRST_FREE_LOWER_BYTE => + firstFreeBuf(7 downto 0) <= data; + when REG_ADDR_CMD_UPPER_BYTE => + cmdBuf(15 downto 8) <= data; + when REG_ADDR_CMD_LOWER_BYTE => + cmdBuf(7 downto 0) <= data; + when REG_ADDR_FILL_ADDRESS_SPACE_UPPER_BYTE => + fasBuf(15 downto 8) <= data; + when REG_ADDR_FILL_ADDRESS_SPACE_LOWER_BYTE => + fasBuf(7 downto 0) <= data; + position := data; + memoryAddress(position) <= fasBuf(15 downto 8); + when others => + data <= (others => 'Z'); -- Запретить запись на шину + end case; + else + data <= (others => 'Z'); -- Запретить запись на шину + end if; + elsif (addr >= firstFree and addr <= firstFree + cmdBuf(7 downto 0)) then + if (oe = '0') then -- Если сигнал чтения активен + data <= memoryData(addr - firstFree); + 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 255 := 0; + variable countValue : integer range 0 to 255 := 63; + variable errorCount : integer range 0 to 15 := 0; + variable position : integer range 0 to ARRAY_LENGTH - 1 := 0; + begin + if(rising_edge (clk)) then + if cmdBuf(15) = '1' then + case CommunicationState is + when Waiting => + if errorCount < cmdBuf(11 downto 8) then + addrTemp <= memoryAddress(position); + CommunicationState <= TransmiteAddress; + else + errorBuf(7 downto 4) <= cmdBuf(11 downto 8); ----------------- заменить на правильный пересчет + end if; + pbclk <= '1'; + pbce <= '1'; + pbdata <= (others =>'Z'); + pbdir <= '1'; + countValue <= 6; + count <= 0; + when TransmiteAddress => + if count < countValue then + count <= count + 1; + pbdata(15 downto 8) <= addrTemp; + pbdata(7 downto 0) <= not addrTemp; + else + pbce <= '0'; + CommunicationState <= TransmiteCheck; + count <= 0; + countValue <= 10; + end if; + when TransmiteCheck => + if count < countValue then + count <= count + 1; + if pback = '0' then + count <= 0; + countValue <= 15; + pbdata <= (others => 'Z'); + CommunicationState <= PreparingToReceiveData; + end if; + else + CommunicationState <= Waiting; + errorBuf(0) <= '1'; + end if; + when PreparingToReceiveData => + if count < countValue then + count <= count + 1; + else + pbclk <= '0'; + count <= 0; + countValue <= 12; + CommunicationState <= ReceiveData; + end if;; + when ReceiveData => + if count < countValue then + if pback = '1' then + pbclk <= '1'; + dataTemp <= pbdata; + CommunicationState <= ReceiveCheck; + count <= 0; + countValue <= 12; + else + count <= count + 1; + end if; + else + CommunicationState <= Waiting; + errorBuf(1) <= '1'; + end if; + when ReceiveCheck => + if count < countValue then + if pback = '0' then + if pbdata = not dataTemp then + memoryData(position) <= dataTemp(15 downto 8); + memoryData(position + 1) <= dataTemp(7 downto 0); + CommunicationState <= Timeout; + count <= 0; + countValue <= 12; + if position + 1 < cmdBuf(7 downto 0) then + updatedAddress <= position; + position <= position + 2; + else + position <= 0; + end if; + else + CommunicationState <= Waiting; + errorBuf(2) <= '1'; + end if; + else + count <= count + 1; + end if; + else + CommunicationState <= Waiting; + errorBuf(3) <= '1'; + end if; + when Timeout => + if count < countValue then + count <= count + 1; + else + CommunicationState <= Waiting; + end if; + when others => CommunicationState <= Waiting; + end case; + else + pbclk <= '1'; + pbce <= '1'; + pbdata <= (others =>'Z'); + pbdir <= '1'; + position <= 0; + errorCount <= 0; + errorBuf <= (others => '0'); + end if; + end if; + end process; + +end behavorial; \ No newline at end of file