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

📄 usb_new_sie_rtl.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 3 页
字号:
	EvalCrc := TRUE;
	ReceiveWord;
	if SE0Detected then
	  SetError(ERROR_TR_EOP);
	end if;
	if Ready and (not Error) then
	  SIE_RxData <= DataWord;
	  -- Pass second Frame Number byte
	  if (MAX_DEVICE_SPEED = USB_FULL_SPEED) and PidType = PID_SOF then
	    SIE_SOFByte2 <= TRUE;
	  end if;
	  RxTxState  := EOP;
	end if;
	-- Endpoint Number is ready when the first 3 bits are received.
	-- There is no time enough to wait until the end of the byte before
	-- passing it to the MM
	if (Position = 3) and (not Error) then       -- Endpoint Complete
	  SIE_RxData <= "0000" & DataWord(2 downto 0) & SaveBit;
	  SIE_RxDataRdy <= TRUE;
	end if;
      when others => -- EOP
	if EndOfPacket then
	  RxTxState := SOP;
	  -- end RxSOF pulse
	  if (MAX_DEVICE_SPEED = USB_FULL_SPEED) then
	    SIE_RxSOF <= FALSE;
	  end if;
	  if (not CRC5ok) then
	    SetError(ERROR_TOKEN_CRC);
	  end if;
	else 
	  ReceiveWord;
	  -- 2 dribble bits allowed, at position 0 and 1
	  if Position >1 then
	    SetError(ERROR_TR_EOP);
	  end if;
	end if;
    end case;
  end ReceiveToken;

  -- DOC_END

  -- DOC_BEGIN: Procedure for receiving a handshake
  -- This procedure takes care of receiving a complete handshake. 
  -- 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. 
  -- If the sync pattern is not received within the allowed turn 
  -- around time, a timeout error is generated.
  -- In the EOP state, an end of packet should come in after at most
  -- 2 dribble bits. 

  procedure ReceiveHandshake is
  begin
    case RxTxState is
      when SOP =>
	if (TimeOut) then
	  -- Packet not received before timeout
	  StopTimeOut := TRUE;
	  SetError(ERROR_TIMEOUT);
	  TimeOut := FALSE;
	elsif SyncDetected then
	  StopTimeOut := TRUE;
	  Error := FALSE; -- clear possible previous error
	  BitstuffCnt := 0;
	  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_HANDSHAKE,
			 PidType, PacketType, Error, ErrorType);
	  end if;
	  if (not Error) then 
	    PidReady := TRUE;
	    RxTxState := EOP;
	  end if;
	end if;
      when others => -- EOP
	if EndOfPacket then
	  RxTxState := SOP;
	else 
	  ReceiveWord;
	  if Position >1 then
	    SetError(ERROR_TR_EOP);
	  end if;
	end if;
    end case; -- RxTxState
  end ReceiveHandshake;
  -- DOC_END


  -- DOC_BEGIN: Procedure for receiving a data packet
  -- This procedure takes care of receiving a complete data packet. 
  -- 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. 
  -- If the sync pattern is not received within the allowed token - data
  -- time, a timeout error is generated.
  -- After the PID, the DATA state is entered, until an SE0 is received.
  -- At that moment, the 16 bit CRC is evaluated, and the EOP state is
  -- entered.
  
  procedure ReceiveData is
  begin
    case RxTxState is
      when SOP =>
	if (TimeOut) then
	  -- Data Packet not received before timeout
	  StopTimeOut := TRUE;
	  SetError(ERROR_TIMEOUT);
	  TimeOut := FALSE;
	elsif SyncDetected then
	  StopTimeOut := TRUE;
	  Error := FALSE; -- clear possible previous error
	  BitstuffCnt := 0;
	  RxTxState := PID;
	  InitCrc := TRUE;
	end if;
      when PID =>
	ReceiveWord;
	if Ready then
	  if (not Error) then
	    CheckPidPacket(DataWord, PACKET_DATA,
			 PidType, PacketType, Error, ErrorType);
	  end if;
	  if (not Error) then 
	    PidReady := TRUE;
	    RxTxState := DATA;
	  end if;
	end if;
	if SE0Detected  then
	  SetError(ERROR_TR_EOP);
	end if;
      when DATA =>
	EvalCrc := TRUE;
	ReceiveWord;
	-- Receive data until an EOP is seen
	if Ready and (not Error) then
	  if SE0Detected then 
	    RxTxState := EOP;
	  else
	    SIE_RxData <= DataWord;
	    SIE_RxDataRdy <= TRUE;
	  end if;
	end if;
      when others => -- EOP
	if (not CRC16ok) then 
	  SetError(ERROR_DATA_CRC);
	end if;
	if EndOfPacket then
	  RxTxState := SOP;
	elsif not SE0Detected and Position >1 then
	  SetError(ERROR_TR_EOP);
	end if;
    end case;
  end ReceiveData;
  -- DOC_END


  -----------------------------------------------------------------------
  --                             Tx Procedures                         --
  -----------------------------------------------------------------------

  -- DOC_BEGIN: Procedure to send a data packet
  -- This procedure sends a data packet. After the sync pattern 
  -- and the PID, data are sent as long as available. When no data
  -- are available anymore, the CRC is added, followed by an EOP.

  procedure SendData is
  begin
    case RxTxState is
      when SOP =>
	DataWord := SYNC_PATTERN;
	SendWord;
	if Ready then
	  RxTxState := PID;
	  InitCrc := TRUE;
	end if;
      when PID =>
	if MM_TxData1Pid then
	  DataWord := EncodePid(PID_DATA1);
	else
	  DataWord := EncodePid(PID_DATA0);
	end if;
	SendWord;
	if Ready then 
	  -- if data are available, fetch them, otherwise
	  -- send CRC
	  if MM_TxDataRdy then
	    SIE_TxDataAck <= TRUE;
	    DataWord := MM_TxData;
	    RxTxState := DATA;
	  else
	    RxTxState := CRC1;
	  end if;
	end if;
      when DATA =>
	EvalCrc := TRUE;
	SendWord;
	if Ready then 
	  if MM_TxDataRdy then
	    SIE_TxDataAck <= TRUE;
	    DataWord := MM_TxData;
	  else
	    RxTxState := CRC1;
	  end if;
	end if;
      when CRC1 =>
      Crc16_tmp := Crc16(15 downto 8);
      DataWord := InsertWord(DataWord, not(Crc16_tmp),
	    Position => 0, RevIns => TRUE);
	SendWord;
	if Ready then 
	  RxTxState := CRC2;
	end if;
      when CRC2 =>
	DataWord := InsertWord(DataWord, not(Crc16(7 downto 0)),
	    Position => 0, RevIns => TRUE);
	SendWord;
	if Ready then 
	  RxTxState := EOP;
	end if;
      when others => -- EOP
        -- Reset the DataWord during EOP to avoid bitstuffing
        DataWord := (others => not BITSTUFF_VALUE);
        SendEOP;
	if Ready then
	  RxTxState := SOP;
	end if;
    end case; -- RxTxState
  end SendData;
  -- DOC_END


  -- DOC_BEGIN: Procedure for sending a handshake
  -- This procedure sends a handshake packet, consisting of 3 parts:
  -- a sync pattern, the PID and an EOP.
  procedure SendHandshake is
  begin
    case RxTxState is
      when SOP =>
	DataWord := SYNC_PATTERN;
	SendWord;
	if Ready then
	  RxTxState := PID;
	  InitCrc := TRUE;
	end if;
      when PID =>
	if MM_Stalled then
	  DataWord := EncodePid(PID_STALL);
	elsif MM_Accepted then
	  DataWord := EncodePid(PID_ACK);
	else
	  DataWord := EncodePid(PID_NAK);
	end if;
	SendWord;
	if Ready then
	  RxTxState := EOP;
	end if;
      when others => -- EOP
	-- Reset the dataword during EOP to avoid bitstuffing
	DataWord := (others => not BITSTUFF_VALUE);
	SendEOP;
	if Ready then
	  RxTxState := SOP;
	end if;
    end case; -- SHState
  end SendHandshake;
  -- DOC_END


begin

  if (Reset_N = ACTIVE_LOW) then
    
    PMState := PM_WAIT_FOR_REQUEST;
    TxUsbLogValue_Z <= USB_LOG_J;
    RxTxState := SOP;
    SIE_RxDataRdy <= FALSE;
    SIE_RxData <= (others => '0');
    ErrorType := ERROR_NO_ERROR;
    Error := FALSE;
    RxErrorType <= ERROR_NO_ERROR;
    RxError <= FALSE;
    SIE_RxPidRdy <= FALSE;
    RxPid <= PID_INVALID;
    SIE_TxDataAck <= FALSE;
    if MAX_DEVICE_SPEED = USB_FULL_SPEED then
      SIE_LowSpeedTransaction <= FALSE;
      SIE_SOFByte1 <= FALSE;
      SIE_SOFByte2 <= FALSE;
      SIE_RxSOF <= FALSE;
    end if;
    SIE_StartEndpSearch <= FALSE;
    SIE_RxEOP <= FALSE;
    PidType := PID_INVALID;
    SaveBit := LOW;
    TimeOutCnt := 0;
    TimeOutStarted := FALSE;
    TimeOut := FALSE;
    PidReady := FALSE;

    Position := 0;
    BitstuffCnt := 0;
    BitValue := '0';
    DataWord := (others => '0');
    Crc16 := (others => '0');
    Crc5 := (others => '0');
    Crc16ok := FALSE;
    Crc5ok := FALSE;
    TxUsbLogValue <= USB_LOG_J;
    TxUsbEnable <= FALSE;
    BitstuffError := FALSE;
    EndOFPacket := FALSE;

    SyncDetected := FALSE;
    SE0Detected := FALSE;
    PacketSent := FALSE;
    RxUsbLogValue    <= USB_LOG_J;
    RxUsbLogValue_Z1 <= USB_LOG_J;
    RxUsbLogValue_Z2 <= USB_LOG_J;
    RxUsbLogValue_Z3 <= USB_LOG_J;

  elsif (FsClk'event and FsClk='1') then

	   
    -- Convert the incoming bits to Logical value
    if TxUsbEnable then
      -- mask incoming bits during sending
      RxUsbLogValue <= USB_LOG_J;
    else
      RxUsbLogValue <= UsbDif2Log(CR_UsbLineBits, GetDeviceSpeed(ConfigArray));
    end if;
    RxUsbLogValue_Z1 <= RxUsbLogValue;
    RxUsbLogValue_Z2 <= RxUsbLogValue_Z1;
    RxUsbLogValue_Z3 <= RxUsbLogValue_Z2;
					    
    
    -- Prevents generation of different registers for variable and signal
    Error := RxError;
    ErrorType := RxErrorType;
    PidType := RxPid;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -