Начал писать SerialBusSlave для обмена данными по шине.

This commit is contained in:
sokolovstanislav 2025-02-11 18:07:02 +03:00
parent f663f42d3b
commit b01a8a0980
3 changed files with 250 additions and 2 deletions

View File

@ -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
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_global_assignment -name VHDL_FILE TestSerialBusSlave.vhd

View File

@ -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
);

View File

@ -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;