From b01a8a0980d15102cdeab397aab69631c5170816 Mon Sep 17 00:00:00 2001 From: sokolovstanislav Date: Tue, 11 Feb 2025 18:07:02 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=20=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D0=B0=D1=82=D1=8C=20SerialBusSlave=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D0=BE=D0=B1=D0=BC=D0=B5=D0=BD=D0=B0=20=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D0=BC=D0=B8=20=D0=BF=D0=BE=20=D1=88=D0=B8=D0=BD?= =?UTF-8?q?=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MainController/MainController.qsf | 3 +- MainController/TestLedsController.vhd | 2 +- MainController/TestSerialBusSlave.vhd | 247 ++++++++++++++++++++++++++ 3 files changed, 250 insertions(+), 2 deletions(-) create mode 100644 MainController/TestSerialBusSlave.vhd diff --git a/MainController/MainController.qsf b/MainController/MainController.qsf index 86edd76..f5a95c7 100644 --- a/MainController/MainController.qsf +++ b/MainController/MainController.qsf @@ -323,4 +323,5 @@ set_global_assignment -name VHDL_FILE RAM9X8_Service.vhd set_location_assignment PIN_43 -to S_RES set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to S_RES set_global_assignment -name VHDL_FILE TestLedsController.vhd -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top +set_global_assignment -name VHDL_FILE TestSerialBusSlave.vhd \ No newline at end of file diff --git a/MainController/TestLedsController.vhd b/MainController/TestLedsController.vhd index ab98ca5..1c9cb6f 100644 --- a/MainController/TestLedsController.vhd +++ b/MainController/TestLedsController.vhd @@ -5,7 +5,7 @@ use ieee.std_logic_unsigned.all; entity TestLedsController is generic( - ADDRESS_DEVICE_BUS_WIDTH : integer := 5; + ADDRESS_DEVICE_BUS_WIDTH : integer := 4; COUNT_ASYNCLINE : integer := 15 ); diff --git a/MainController/TestSerialBusSlave.vhd b/MainController/TestSerialBusSlave.vhd new file mode 100644 index 0000000..b893608 --- /dev/null +++ b/MainController/TestSerialBusSlave.vhd @@ -0,0 +1,247 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity TestSerialBusSlave is + generic( + ADDRESS_DEVICE_BUS_WIDTH : integer := 4; + ADDRESS_REG_BUS_WIDTH : integer := 4; + DATA_BUS_WIDTH : integer := 16; + + COUNT_RESET : integer := 180 + ); + + port( + clk : in std_logic; + + addressdevice : in std_logic_vector(ADDRESS_DEVICE_BUS_WIDTH - 1 downto 0); + + sbclk : in std_logic; + sbdatain : in std_logic; + sbdataout : out std_logic := '0'; + + addressregister : out std_logic_vector(ADDRESS_REG_BUS_WIDTH - 1 downto 0); + dataout : out std_logic_vector(DATA_BUS_WIDTH - 1 downto 0); + datain : in std_logic_vector(DATA_BUS_WIDTH - 1 downto 0); + + rw : out std_logic; + dataready : out std_logic + ); +end entity; + +architecture behavorial of TestSerialBusSlave is + +signal address_received : std_logic_vector(ADDRESS_DEVICE_BUS_WIDTH - 1 downto 0) := (others => '0'); + +signal sbclkPrev : std_logic := '0'; +signal sbReset : std_logic := '0'; +signal sbResetPrev : std_logic := '0'; +signal sbDataOutBuf : std_logic := '0'; + +signal direction : std_logic := '0'; +signal addressDevBuf : std_logic_vector(ADDRESS_DEVICE_BUS_WIDTH - 1 downto 0) := (others => '0'); +signal addressRegBuf : std_logic_vector(ADDRESS_REG_BUS_WIDTH - 1 downto 0) := (others => '0'); + +type CommunicationStateType is (Waiting, ReceiveAddress, ReceiveData, ReceiveCRC, ReceiveCheck, TransmitData, TransmitCRC, TransmitCheck, Timeout); +signal CommunicationState : CommunicationStateType := Waiting; + +signal resetCRC : std_logic := '1'; +signal CRC : std_logic_vector(3 downto 0) := x"0"; +signal bufCRC : std_logic_vector(3 downto 0) := x"0"; +signal dataCRC : std_logic_vector(31 downto 0) := x"00000000"; -- переключает +signal readyCRC : std_logic := '0'; + +begin + + process(clk) is + variable count : integer range 0 to COUNT_RESET := 0; + begin + if rising_edge(clk) then + sbclkPrev <= sbclk; + if sbclk = '0' then + if count < COUNT_RESET then + count := count + 1; + else + sbReset <= '1'; + end if; + else + count := 0; + sbReset <= '0'; + end if; + end if; + end process; + + sbdataout <= sbDataOutBuf; + + process(clk) + variable bitCnt : integer range -1 to ADDRESS_DEVICE_BUS_WIDTH + ADDRESS_REG_BUS_WIDTH + DATA_BUS_WIDTH - 1 := ADDRESS_DEVICE_BUS_WIDTH; + begin + if rising_edge(clk) then + if sbReset = '1' and sbResetPrev = '0' then + CommunicationState <= Waiting; + resetCRC <= '1'; + else + resetCRC <= '0'; + end if; + sbResetPrev <= sbReset; + + case CommunicationState is + when Waiting => + CRCData <= sbdatain; + if sbclk = '1' and sbclkPrev = '0' then + rw <= sbdatain; + direction <= sbdatain; + dataready <= '0'; + bitCnt := ADDRESS_DEVICE_BUS_WIDTH; -- на один больше из-за условия в ReceiveAddress, срабатывающего по спаду сигнала + + -- удалил обновление адреса в этом месте, но добавил сохранение направления передачи, по нему будем работать дальше + + CommunicationState <= ReceiveAddress; + else + if sbDataOutBuf = '0' then + sbDataOutBuf <= '1'; --pull up + else + sbDataOutBuf <= 'Z'; + end if; + end if; + + + when ReceiveAddress => + CRCData <= sbdatain; + if sbclk = '1' and sbclkPrev = '0' then + address_register(bitCnt) <= sbdatain; + if bitCnt = 0 then + + -- условие ниже пересмотреть и добавить буффер на адрес + if bufAddr(7 downto 4) = AddrSlave then + AddrUpdated <= '1'; + else + CommunicationState <= Timeout; + end if; + end if; + end if; + + if sbclk = '0' and sbclkPrev = '1' then + BitCnt <= BitCnt -1; + end if; + + + if BitCnt = -1 then + if Direction = '0' then + BitCnt <= 15; + Data_out_sig <= DataFromSlave(15); + CommunicationState <= SData; + else + BitCnt <= 19; + CommunicationState <= RData; --- 16 data + 4ñrc (19 to 0) + end if; + end if; + + + + when SData => -- îòïðàâêà ïî ñèíõðîêëîêó ïîä ñ÷åò + CRCData <= Data_out_sig; + if sclk = '0' and sclk_prev = '1' then + Data_out_sig <= DataFromSlave (BitCnt); + end if; + + if sclk = '1' and sclk_prev = '0' then + if BitCnt > 0 then + BitCnt <= BitCnt -1; + else + BitCnt <= 3; + CommunicationState <= SCRC; + end if; + end if; + + + when SCRC => -- îòïðàâêà ïî ñèíõðîêëîêó ïîä ñ÷åò + if sclk = '0' and sclk_prev = '1' then + Data_out_sig <= CRC_sign (BitCnt); + end if; + + if sclk = '1' and sclk_prev = '0' then + if BitCnt > 0 then + BitCnt <= BitCnt -1; + else + CommunicationState <= Timeout; + end if; + end if; + + + + when RData => + CRCData <= BusIn; + if sclk= '1' and sclk_prev = '0' then + bufData(BitCnt) <= BusIn; + end if; + + if sclk = '0' and sclk_prev = '1' then + if BitCnt > 0 then + BitCnt <= BitCnt -1; + else + if bufData(3 downto 0) = CRC_sign then + DataUpdated_sig <= '1'; + Data_out_sig <= '0'; + led <= '0'; + else + Data_out_sig <= '1'; + led <= '1'; + end if; + CommunicationState <= Timeout; + end if; + end if; + + when Timeout => + -- CRCReset_sig <= '1'; + + when others => + + end case; + + end if; + end process; + + process(clk) + variable lacth : integer range 0 to 1 := 0; + variable bitCnt : integer range -1 to 24 := 0; + begin + if rising_edge(clk) then + if resetCRC = '1' then + bitCnt := 24; + CRC <= x"0"; + lacth := 0; + readyCRC <= '0'; + else + if readyCRC = '0' then + if lacth = 0 then + if bitCnt /= -1 then + CRC(3) <= CRC(2) xor CRC(3); + CRC(2) <= CRC(1) xor CRC(0); + CRC(1) <= CRC(0); + CRC(0) <= dataCRC(bitCnt) xor CRC(1); + bitCnt := bitCnt - 1; + else + bitCnt := 3; + lacth := 1; + end if; + else + if bitCnt /= -1 then + CRC(3) <= CRC(2) xor CRC(3); + CRC(2) <= CRC(1) xor CRC(0); + CRC(1) <= CRC(0); + CRC(0) <= '1' xor CRC(1); + bitCnt := bitCnt - 1; + else + readyCRC <= '1'; + --countreadyCRC <= countreadyCRC + 1; + end if; + end if; + end if; + end if; + end if; + end process; + + +end behavorial; \ No newline at end of file