⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_new_sie_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 3 页
字号:
----------------------------------------------------------------------------------
---- 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 + -