472 lines
9.9 KiB
VHDL
472 lines
9.9 KiB
VHDL
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.all;
|
|
USE ieee.std_logic_arith.all;
|
|
|
|
ENTITY Command_Unit IS
|
|
PORT(
|
|
H: IN std_logic;
|
|
nRST: IN std_logic;
|
|
LinSynchro: IN std_logic;
|
|
|
|
octetRecu_EN: OUT std_logic;
|
|
|
|
n_SELECT: OUT std_logic;
|
|
n_LOAD: OUT std_logic;
|
|
n_EN: OUT std_logic;
|
|
|
|
BitNb_SELECT: OUT std_logic;
|
|
BitNb_LOAD: OUT std_logic;
|
|
BitNb_EN: OUT std_logic;
|
|
|
|
IdentifierField_EN: OUT std_logic;
|
|
|
|
nbData_LOAD: OUT std_logic;
|
|
nbData_EN: OUT std_logic;
|
|
|
|
n_0: IN std_logic;
|
|
BitNb_0: IN std_logic;
|
|
DataNb_0: IN std_logic;
|
|
|
|
RecByte_WR: OUT std_logic;
|
|
RecByte_RST: OUT std_logic := '0';
|
|
|
|
ErrorSet: OUT std_logic_vector(3 downto 1);
|
|
MsgRcv_SET: OUT std_logic
|
|
);
|
|
END Command_Unit;
|
|
|
|
ARCHITECTURE arch of Command_Unit IS
|
|
TYPE state IS (waiting, syncBreak0, syncBreak1, syncFieldWait, syncFieldStart, syncFieldData, syncFieldStop, idFieldWait, idFieldStart, idFieldData, idFieldStop, dataFieldWait, dataFieldStart, dataFieldData, dataFieldStop, checksumFieldWait, checksumFieldStart, checksumFieldData, checksumFieldStop);
|
|
SIGNAL cState, nState : state;
|
|
|
|
type errors is record
|
|
ErrorStartBit: std_logic;
|
|
ErrorStopBit: std_logic;
|
|
ErrorSync: std_logic;
|
|
end record errors;
|
|
SIGNAL errs: errors;
|
|
|
|
BEGIN
|
|
|
|
ErrorSet(1) <= errs.ErrorStartBit;
|
|
ErrorSet(2) <= errs.ErrorStopBit;
|
|
ErrorSet(3) <= errs.ErrorSync;
|
|
|
|
stateUpd : PROCESS(H, nRST)
|
|
BEGIN
|
|
IF(nRST = '0') THEN
|
|
cState <= waiting;
|
|
ELSIF(rising_edge(H)) THEN
|
|
cState <= nState;
|
|
END IF;
|
|
END process stateUpd;
|
|
|
|
nStateUpd : PROCESS(LinSynchro, cState, n_0, BitNb_0)
|
|
BEGIN
|
|
nState <= cState;
|
|
CASE cState IS
|
|
WHEN waiting =>
|
|
if(LinSynchro = '0') THEN
|
|
nState <= syncBreak0;
|
|
END IF;
|
|
|
|
WHEN syncBreak0 =>
|
|
if(LinSynchro = '1') THEN
|
|
if(BitNb_0 = '1') THEN
|
|
nState <= syncBreak1;
|
|
else
|
|
nState <= waiting;
|
|
END IF;
|
|
END IF;
|
|
|
|
WHEN syncBreak1 =>
|
|
if(n_0 = '1') THEN
|
|
if(LinSynchro = '1') THEN
|
|
nState <= syncFieldWait;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
END IF;
|
|
|
|
WHEN syncFieldWAit =>
|
|
if(LinSynchro = '0') THEN
|
|
nState <= syncFieldStart;
|
|
END IF;
|
|
|
|
WHEN syncFieldStart =>
|
|
if(n_0 = '1') THEN
|
|
IF(LinSynchro = '0') THEN
|
|
nState <= syncFieldData;
|
|
else
|
|
nState <= waiting;
|
|
END IF;
|
|
end if;
|
|
|
|
WHEN syncFieldData =>
|
|
if(BitNb_0 = '1') THEN
|
|
nState <= syncFieldStop;
|
|
END IF;
|
|
|
|
WHEN syncFieldStop =>
|
|
if(n_0 = '1') THEN
|
|
if(LinSynchro = '1') THEN
|
|
nState <= idFieldWait;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
end if;
|
|
|
|
WHEN idFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
nState <= idFieldStart;
|
|
end if;
|
|
|
|
WHEN idFieldStart =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '0') then
|
|
nState <= idFieldData;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
end if;
|
|
|
|
WHEN idFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
nState <= idFieldStop;
|
|
end if;
|
|
|
|
WHEN idFieldStop =>
|
|
if(n_0 = '1') then
|
|
if(LinSYnchro = '1') then
|
|
nState <= dataFieldWait;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
end if;
|
|
|
|
WHEN dataFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
nState <= dataFieldStart;
|
|
end if;
|
|
|
|
WHEN dataFieldStart =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '0') then
|
|
nState <= dataFieldData;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
end if;
|
|
|
|
WHEN dataFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
nState <= dataFieldStop;
|
|
end if;
|
|
|
|
WHEN dataFieldStop =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '1') then
|
|
if(DataNb_0 = '1') then
|
|
nState <= checksumFieldWait;
|
|
else
|
|
nState <= dataFieldWait;
|
|
end if;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
end if;
|
|
|
|
WHEN checksumFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
nState <= checksumFieldStart;
|
|
end if;
|
|
|
|
WHEN checksumFieldStart =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '0') then
|
|
nState <= checksumFieldData;
|
|
else
|
|
nState <= waiting;
|
|
end if;
|
|
end if;
|
|
|
|
WHEN checksumFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
nState <= checksumFieldStop;
|
|
end if;
|
|
|
|
WHEN checksumFieldStop =>
|
|
if(n_0 = '1') then
|
|
nState <= waiting;
|
|
end if;
|
|
|
|
end CASE;
|
|
END PROCESS nStateUpd;
|
|
|
|
RCS : PROCESS(cState, LinSynchro, n_0)
|
|
BEGIN
|
|
BitNb_EN <= '0';
|
|
nbData_EN <= '0';
|
|
RecByte_WR <= '0';
|
|
MsgRcv_SET <= '0';
|
|
errs <= (others => '0');
|
|
|
|
CASE cState IS
|
|
WHEN waiting =>
|
|
if(LinSynchro = '0') THEN
|
|
n_LOAD <= '1';
|
|
BitNb_EN <= '1';
|
|
n_SELECT <= '1';
|
|
BitNb_LOAD <= '1';
|
|
BitNb_SELECT <= '0';
|
|
end IF;
|
|
|
|
WHEN syncBreak0 =>
|
|
if(LinSynchro = '1') then
|
|
if(BitNb_0 = '1') then
|
|
n_LOAD <= '1';
|
|
n_SELECT <= '0';
|
|
else
|
|
errs.ErrorSync <= '1';
|
|
end if;
|
|
else
|
|
if(n_0 = '1' AND BitNb_0 = '0') then
|
|
n_select <= '0';
|
|
n_LOAD <= '1';
|
|
BitNb_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
BitNb_EN <= '0';
|
|
end if;
|
|
n_EN <= '1';
|
|
BitNb_LOAD <= '0';
|
|
end if;
|
|
|
|
WHEN syncBreak1 =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '0') then
|
|
errs.ErrorStopBit <= '1';
|
|
end if;
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN syncFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
n_LOAD <= '1';
|
|
n_SELECT <= '1';
|
|
end if;
|
|
|
|
WHEN syncFieldStart =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '0') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
BitNb_SELECT <= '1';
|
|
BitNb_LOAD <= '1';
|
|
BitNb_EN <= '1';
|
|
else
|
|
errs.ErrorStartBit <= '1';
|
|
end if;
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN syncFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
octetRecu_EN <= '0';
|
|
else
|
|
if(n_0 = '1') then
|
|
n_LOAD <= '1';
|
|
n_SELECT <= '0';
|
|
BitNb_EN <= '1';
|
|
octetRecu_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
BitNb_EN <= '0';
|
|
octetRecu_EN <= '0';
|
|
end if;
|
|
BitNb_LOAD <= '0';
|
|
end if;
|
|
|
|
WHEN syncFieldStop =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '1') then
|
|
RecByte_WR <= '1';
|
|
else
|
|
errs.ErrorStopBit <= '1';
|
|
end if;
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN idFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
n_SELECT <= '1';
|
|
n_LOAD <= '1';
|
|
end if;
|
|
|
|
WHEN idFieldStart =>
|
|
if(n_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
BitNb_SELECT <= '1';
|
|
BitNb_LOAD <= '1';
|
|
BitNb_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN idFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
octetRecu_EN <= '0';
|
|
else
|
|
if(n_0 = '1') then
|
|
n_LOAD <= '1';
|
|
n_SELECT <= '0';
|
|
BitNb_EN <= '1';
|
|
octetRecu_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
BitNb_EN <= '0';
|
|
octetRecu_EN <= '0';
|
|
end if;
|
|
BitNb_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN idFieldStop =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '1') then
|
|
nbData_LOAD <= '1';
|
|
nbData_EN <= '1';
|
|
IdentifierField_EN <= '1';
|
|
RecByte_WR <= '1';
|
|
else
|
|
errs.ErrorStopBit <= '1';
|
|
end if;
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN dataFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
n_SELECT <= '1';
|
|
n_LOAD <= '1';
|
|
else
|
|
nbData_EN <= '0';
|
|
nbData_LOAD <= '0';
|
|
IdentifierField_EN <= '0';
|
|
end if;
|
|
|
|
WHEN dataFieldStart =>
|
|
if(n_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
BitNb_SELECT <= '1';
|
|
BitNb_LOAD <= '1';
|
|
BitNb_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN dataFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
octetRecu_EN <= '0';
|
|
else
|
|
if(n_0 = '1') then
|
|
n_LOAD <= '1';
|
|
n_SELECT <= '0';
|
|
BitNb_EN <= '1';
|
|
octetRecu_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
BitNb_EN <= '0';
|
|
octetRecu_EN <= '0';
|
|
end if;
|
|
BitNb_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN dataFieldStop =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '1') then
|
|
nbData_EN <= '1';
|
|
RecByte_WR <= '1';
|
|
else
|
|
errs.ErrorStopBit <= '1';
|
|
end if;
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN checksumFieldWait =>
|
|
if(LinSynchro = '0') then
|
|
n_SELECT <= '1';
|
|
n_LOAD <= '1';
|
|
end if;
|
|
|
|
WHEN checksumFieldStart =>
|
|
if(n_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
BitNb_SELECT <= '1';
|
|
BitNb_LOAD <= '1';
|
|
BitNb_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN checksumFieldData =>
|
|
if(BitNb_0 = '1') then
|
|
n_SELECT <= '0';
|
|
n_LOAD <= '1';
|
|
octetRecu_EN <= '0';
|
|
else
|
|
if(n_0 = '1') then
|
|
n_LOAD <= '1';
|
|
n_SELECT <= '0';
|
|
BitNb_EN <= '1';
|
|
octetRecu_EN <= '1';
|
|
else
|
|
n_LOAD <= '0';
|
|
BitNb_EN <= '0';
|
|
octetRecu_EN <= '0';
|
|
end if;
|
|
BitNb_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
WHEN checksumFieldStop =>
|
|
if(n_0 = '1') then
|
|
if(LinSynchro = '1') then
|
|
RecByte_WR <= '1';
|
|
MsgRcv_SET <= '1';
|
|
else
|
|
errs.ErrorStopBit <= '1';
|
|
end if;
|
|
else
|
|
n_LOAD <= '0';
|
|
n_EN <= '1';
|
|
end if;
|
|
|
|
|
|
end CASE;
|
|
END PROCESS RCS;
|
|
|
|
END ARCHITECTURE arch;
|