Начал писать SerialBusSlave для обмена данными по шине.
This commit is contained in:
parent
f663f42d3b
commit
b01a8a0980
@ -324,3 +324,4 @@ 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_global_assignment -name VHDL_FILE TestSerialBusSlave.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
|
||||
);
|
||||
|
||||
|
247
MainController/TestSerialBusSlave.vhd
Normal file
247
MainController/TestSerialBusSlave.vhd
Normal 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;
|
Loading…
Reference in New Issue
Block a user