📄 usb_new_sie_rtl.vhdl
字号:
----------------------------------------------------------------------------------
---- File >>> usb_new_sie_rtl.vhdl
---- Iden >>> 960123-09:12:07
----
---- Project: USB Development
---- Customer: Philips_ITCL
----
---- Module: architecture RTL of entity SIE
---- Written by: Geert Verbruggen (e-mail: geert@easics.be)
---- Easics nv
---- Kapeldreef 60
---- B-3001 Leuven
---- Belgium
---- Tel +32-16-270.400
---- Fax +32-16-270.319
---- e-mail: vhdl@easics.be
----
---- Creation Date: Tue, 23 Jan 1996
----
---- Purpose:
----
---- Revision history:
----
----------------------------------------------------------------------------------
--
-- DESCRIPTION_BEGIN
-- The Serial Interface Engine is an interface that takes care of the
-- low level USB protocol. It monitors the traffic on the USB Bus and
-- presents data and requests to the Memory Manager using a simple
-- protocol.
-- DESCRIPTION_END
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
library work;
use work.PCK_GENERAL.all;
use work.PCK_USB.all;
use work.PCK_CONFIGURATION.all;
use work.PCK_SETUP.all;
architecture RTL of SIE is
signal RxUsbLogValue: T_UsbLog_enum;
signal RxUsbLogValue_Z1: T_UsbLog_enum; -- previous value
signal RxUsbLogValue_Z2: T_UsbLog_enum; -- previous value
signal RxUsbLogValue_Z3: T_UsbLog_enum; -- previous value
signal TxUsbLogValue: T_UsbLog_enum;
signal TxUsbLogValue_Z: T_UsbLog_enum;
signal TxUsbEnable: boolean;
signal DataReady: boolean;
signal Enable_1kHz: boolean;
signal RxError: boolean;
signal RxErrorType: T_PACKET_ERROR_enum;
signal RxPid: T_Pid_enum;
begin
-- Debug output
SIE_RxUsbLogValue <= RxUsbLogValue;
-- Convert the TX outgoing logic values to bits
SIE_TxLogValue <= TxUsbLogValue when TxUsbEnable else
TxUsbLogValue_Z;
-- Enables for upstream Tx and CLKREC
SIE_UsbEnable_N <= conv_active_low(TxUsbEnable);
SIE_CREnable <= not TxUsbEnable;
-- Connection between internal signals and ports
SIE_RxError <= RxError;
SIE_RxErrorType <= RxErrorType;
SIE_RxPid <= RxPid;
--------------------------------------------------------------
-- process MAIN (FsClk, Reset_N)
--------------------------------------------------------------
MAIN: process(FsClk , Reset_N)
type T_PMState_enum is (PM_WAIT_FOR_REQUEST,
PM_PROCESS_IN,
PM_PROCESS_OUT_SETUP,
PM_RECEIVE_HANDSHAKE,
PM_SEND_HANDSHAKE);
variable PMState: T_PMState_enum;
variable ErrorType: T_PACKET_ERROR_enum;
variable Error: boolean;
variable TimeOutCnt: integer range 0 to DEVICE_TIMEOUT +7;
variable TimeOut: boolean;
variable TimeOutStarted: boolean;
variable StartTimeOut: boolean;
variable StopTimeOut: boolean;
variable PidType: T_Pid_enum;
variable PacketType: T_Packet_enum;
variable Ready: boolean;
variable SaveBit: one_bit;
variable Position: S_USBWORD_WIDTH_range;
variable BitValue: one_bit; -- Bit to be processed
variable BitStuffCnt: S_BitStuff_range; -- length bitstuff sequence
variable StuffedBit: boolean; -- Flags stuffed bits
variable NewBitStuffCnt: S_BitStuff_range; -- New BitStuffCnt (de)stuffing
variable Crc5: five_bits; -- CRC5 for tokens
variable Crc16: sixteen_bits; -- CRC16 for data
variable Crc16_tmp : unsigned(7 downto 0);
variable Crc5ok: boolean; -- CRC5 of token was ok
variable Crc16ok: boolean; -- CRC16 of data was ok
variable InitCrc: boolean; -- Initialize the Crc5/Crc16.
variable EvalCrc: boolean; -- Evaluate the Crc5/Crc16
variable EndOfPacket: boolean;
variable SyncDetected: boolean;
variable SE0Detected: boolean;
variable BitstuffError: boolean;
variable DataWord: S_UsbWord_bits;
variable PidReady: boolean;
variable PacketSent: boolean;
-------------------------------------------------------------------------
-- Error Procedure --
-------------------------------------------------------------------------
procedure SetError(AnError: T_Packet_Error_enum) is
begin
Error := TRUE;
ErrorType := AnError;
end SetError;
-------------------------------------------------------------------------
-- Low Level Tx/Rx Procedures --
-------------------------------------------------------------------------
-- Procedure to send one byte
-- DOC_BEGIN: Procedure for sending one byte
-- This procedure is called by the main state machine every cycle
-- when the SIE is sending data. This procedure sends the data
-- provided in the DataWord variable. When this byte is sent
-- completely, this is reported to the main state machine by
-- setting the Ready flag. The procedure takes care of bit stuffing
-- and NRZI encoding.
procedure SendWord is
begin
BitValue := DataWord(Position);
Stuff(BitValue, BitStuffCnt,
BitStuffError, StuffedBit, NewBitStuffCnt);
BitStuffCnt := NewBitStuffCnt;
if (StuffedBit) then
TxUsbLogValue <= EncodeNRZI(TxUsbLogValue, (not BITSTUFF_VALUE));
TxUsbEnable <= TRUE;
-- A stuffed bit should never trigger CRC evaluation
EvalCrc := FALSE;
else
TxUsbLogValue <= EncodeNRZI(TxUsbLogValue, BitValue);
TxUsbEnable <= TRUE;
if (IsAtMaxValue(Position, USBWORD_WIDTH)) then
Position := 0;
Ready := TRUE;
else
Position := Position + 1;
end if;
end if;
end SendWord;
-- DOC_END
-- Procedure for sending an End of Packet
-- DOC_BEGIN: Procedure for sending End of Packet
-- This procedure is called by the main state machine every cycle
-- when the SIE is sending an End of Packet. When the End of Packet
-- is sent completely, this is reported to the main state machine by
-- setting the Ready flag. The procedure also takes care of bit stuffing
-- and NRZI encoding of the last data bit.
procedure SendEOP is
begin
-- Needed to stuff the last bit before the SE0
BitValue := DataWord(Position);
Stuff(BitValue, BitStuffCnt,
BitStuffError, StuffedBit, NewBitStuffCnt);
BitStuffCnt := 0; -- reset bit stuff count during SE0
if (StuffedBit) then
TxUsbLogValue <= EncodeNRZI(TxUsbLogValue, (not BITSTUFF_VALUE));
TxUsbEnable <= TRUE;
-- A stuffed bit should never trigger CRC evaluation
EvalCrc := FALSE;
else
-- Send SE0
if (Position < EOP_MAX_SE0) then
TxUsbLogValue <= USB_LOG_SE0;
TxUsbEnable <= TRUE;
Position := Position + 1;
else
-- Send J
TxUsbLogValue <= USB_LOG_J;
TxUsbEnable <= TRUE;
Position := 0;
Ready := TRUE;
PacketSent := TRUE;
end if;
end if;
end SendEOP;
-- DOC_END
-- Procedure for receiving one byte
-- DOC_BEGIN: Procedure to receive data
-- This procedure is called by the main state machine while the SIE
-- is receiving data. When a complete byte or an SE0 are received,
-- this is indicated to the main state machine by setting the Ready
-- flag. The received data are stored in the DataWord variable. This
-- procedure takes care of NRZI decoding and destuffing.
procedure ReceiveWord is
begin
BitValue := DecodeNRZI(RxUsbLogValue_Z1, RxUsbLogValue);
DeStuff(BitValue, BitStuffCnt, BitStuffError, StuffedBit, NewBitStuffCnt);
BitStuffCnt := NewBitStuffCnt;
if (StuffedBit) then
-- a stuffed bit should never be allowed to trigger
-- a CRC evaluation
EvalCrc := FALSE;
else
DataWord(Position) := BitValue;
if (BitStuffError) then
SetError(ERROR_BITSTUFF_ERROR);
Ready := TRUE;
elsif SE0Detected then
EvalCrc := FALSE;
-- 2 dribble bits are allowed: on position 0 and 1
if Position > 1 then
SetError(ERROR_TR_EOP);
end if;
Position := 1;
Ready := TRUE;
else
if (IsAtMaxValue(Position, USBWORD_WIDTH)) then
Position := 0;
Ready := TRUE;
else
Position := Position + 1;
end if;
end if;
end if;
end ReceiveWord;
-- DOC_END
-------------------------------------------------------------------------
-- Rx Procedures --
-------------------------------------------------------------------------
type T_RxTxState_enum is (SOP,
PID,
ADDR_ONE,
ADDR_TWO,
DATA,
CRC1,
CRC2,
EOP);
variable RxTxState: T_RxTxState_enum;
-- Procedure for Receiving a token
-- DOC_BEGIN: Procedure for receiving a token
-- This procedure takes care of receiving a complete token.
-- In the Start of Packet (SOF) state, it waits for the end of a
-- sync pattern. When this is received, the Packet Identifier (PID)
-- state is entered, where the packet PID is received using the
-- ReceiveWord procedure. This state also takes care of SOF's and
-- PRE PID's. When the PID is received, the device and endpoint
-- addresses are received in the ADDR_ONE and ADDR_TWO states.
-- In the EOP state, and end of packet should come in after at most
-- 2 dribble bits. At that moment the 5 bit CRC is evaluated.
procedure ReceiveToken is
begin
case RxTxState is
when SOP =>
if SyncDetected then
StopTimeOut := TRUE;
BitstuffCnt := 0;
Error := FALSE; -- clear possible previous error
RxTxState := PID;
InitCrc := TRUE;
end if;
when PID =>
ReceiveWord;
if SE0Detected then
SetError(ERROR_TR_EOP);
end if;
if Ready then
if (not Error) then
CheckPidPacket(DataWord, PACKET_TOKEN,
PidType, PacketType, Error, ErrorType);
end if;
if (not Error) then
if (MAX_DEVICE_SPEED = USB_FULL_SPEED) and PidType = PID_SOF then
-- SIE_RxSOF is reset in the EOP state -> long pulse
-- (needed to sample in the 12MHz reference domain)
SIE_RxSOF <= TRUE;
end if;
PidReady := TRUE;
RxTxState := ADDR_ONE;
if (MAX_DEVICE_SPEED = USB_FULL_SPEED) and PidType = PID_PRE then
-- Wait for next packet
RxTxState := SOP; -- otherwise bitstuff errors occur
end if;
end if;
end if;
when ADDR_ONE =>
EvalCrc := TRUE;
ReceiveWord;
if SE0Detected then
SetError(ERROR_TR_EOP);
end if;
if Ready and (not Error) then
SIE_RxData <= DataWord;
-- Last bit of first byte is the first bit of the endpoint number
SaveBit := DataWord(7); -- LSB of endpoint address
RxTxState := ADDR_TWO;
-- USB Address is ready -> start decoding
if PidType = PID_IN or PidType = PID_OUT or PidType = PID_SETUP then
SIE_StartEndpSearch <= TRUE;
-- Pass first Frame Number byte
elsif (MAX_DEVICE_SPEED = USB_FULL_SPEED) and PidType = PID_SOF then
SIE_SOFByte1 <= TRUE;
end if;
end if;
when ADDR_TWO =>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -