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

📄 usb_new_pck_usb.vhdl

📁 实现USB接口功能的VHDL和verilog完整源代码
💻 VHDL
📖 第 1 页 / 共 4 页
字号:
  end DecodePacket;

  function EncodePacket (PacketType: T_Packet_enum)
	   return S_Packet_bits is
  begin
    case PacketType is
      when PACKET_SPECIAL =>
	return "00";
      when PACKET_TOKEN =>
	return "01";
      when PACKET_HANDSHAKE =>
	return "10";
      when PACKET_DATA =>
	return "11";
    end case; -- PacketType
  end EncodePacket;

  function PidToPacket (Pid: T_Pid_enum)
	   return T_Packet_enum is
  begin
    case Pid is
      when PID_IN | PID_OUT | PID_SOF | PID_SETUP =>
	return PACKET_TOKEN;
      when PID_DATA0 | PID_DATA1 =>
	return PACKET_DATA;
      when PID_PRE =>
	return PACKET_SPECIAL;
      when PID_ACK | PID_NAK | PID_STALL =>
	return PACKET_HANDSHAKE;
      when PID_INVALID | PID_RESERVED_1 | PID_RESERVED_2 |
	   PID_RESERVED_3 | PID_RESERVED_4 | PID_ERR =>
	assert FALSE
	  report "Calling PidToPacket for invalid Pid"
	  severity note;
	return PACKET_HANDSHAKE;
    end case; -- Pid
  end PidToPacket;

  procedure CheckPidPacket (DataWord:    in S_UsbWord_bits;
			    ExpPacket:   in T_Packet_enum;
			    PidType:    out T_Pid_enum;
			    PacketType: out T_Packet_enum;
			    Error:      out boolean;
			    ErrorType:  out T_PACKET_ERROR_enum) is
    variable IntError: boolean;
    variable IntPidType: T_Pid_enum;
    variable IntPacketType: T_Packet_enum;
  begin
    CheckPid(DataWord, IntPidType, IntError, ErrorType);
    if (IntError) then
      Error      := TRUE;
      PacketType := PACKET_HANDSHAKE; -- value is in fact don't care
    else
      IntPacketType := PidToPacket(IntPidType);
      if (ExpPacket /= IntPacketType) and 
	not (ExpPacket = PACKET_TOKEN and IntPacketType = PACKET_SPECIAL) then
	Error      := TRUE;
	ErrorType  := ERROR_PACKET_UNEXPECTED;
      else
	Error      := FALSE;
      end if;
      PacketType := IntPacketType;
    end if;
    PidType := IntPidType;
  end CheckPidPacket;

  function IsTokenPid (PidType: T_Pid_enum)
	   return boolean is
  begin
    if (IsValidPid(PidType) = FALSE) then
      return FALSE;
    elsif (PidToPacket(PidType) = PACKET_TOKEN) then
      return TRUE;
    else
      return FALSE;
    end if;
  end IsTokenPid;

  function IsDataPid (PidType: T_Pid_enum)
	   return boolean is
  begin
    if (IsValidPid(PidType) = FALSE) then
      return FALSE;
    elsif (PidToPacket(PidType) = PACKET_DATA) then
      return TRUE;
    else
      return FALSE;
    end if;
  end IsDataPid;

  function IsHandshakePid (PidType: T_Pid_enum)
	   return boolean is
  begin
    if (IsValidPid(PidType) = FALSE) then
      return FALSE;
    elsif (PidToPacket(PidType) = PACKET_HANDSHAKE) then
      return TRUE;
    else
      return FALSE;
    end if;
  end IsHandshakePid;

  function IsSpecialPid (PidType: T_Pid_enum)
	   return boolean is
  begin
    if (IsValidPid(PidType) = FALSE) then
      return FALSE;
    elsif (PidToPacket(PidType) = PACKET_SPECIAL) then
      return TRUE;
    else
      return FALSE;
    end if;
  end IsSpecialPid;

  function EncodeTransaction (TrType: T_Transaction_enum)
           return S_Transaction_bits is
  begin
    case TrType is
      when TR_BULK =>
	return "00";
      when TR_SETUP =>
	return "01";
      when TR_IRQ =>
	return "10";
      when TR_ISO =>
	return "11";
    end case; -- TrType
  end EncodeTransaction;

  function DecodeTransaction (TrType: S_Transaction_bits)
	   return T_Transaction_enum is
  begin
    case TrType is
      when "00" =>
	return TR_BULK;
      when "01" =>
	return TR_SETUP;
      when "10" =>
	return TR_IRQ;
      when "11" =>
	return TR_ISO;
      when others =>
	return TR_BULK;
    end case; -- TrType
  end DecodeTransaction;

  function EncodeUsbCrc (CrcType: T_UsbCrc_enum)
	   return S_UsbCrc_bits is
  begin
    case CrcType is
      when USBCRC_TOKEN =>
	return LOW;
      when USBCRC_DATA =>
	return HIGH;
    end case;
  end EncodeUsbCrc;

  function DecodeUsbCrc (CrcType: S_UsbCrc_bits)
	   return T_UsbCrc_enum is
  begin
    case CrcType is
      when LOW =>
	return USBCRC_TOKEN;
      when others =>
	return USBCRC_DATA;
    end case;
  end DecodeUsbCrc;

  -- function for general CRC calculation one bit at a time
  function OneBitCRC (Data: one_bit;
		      CRC: unsigned;
		      Polynomial: bit_vector) return unsigned is
    constant CRC_DEGREE: integer := CRC'length;
    variable NewCRC: unsigned(CRC_DEGREE-1 downto 0);
  begin
    assert Polynomial'high = CRC_DEGREE
	   report "Polynomial'high doesn't match CRC degree"
	   severity error;
    assert Polynomial'low = 0
           report "Polynomial'low should be 0"
	   severity error;
    assert Polynomial(Polynomial'high) = '1'
	   report "Polynomial'high should be a '1'"
	   severity error;
    assert Polynomial(Polynomial'low) = '1'
	   report "Polynomial'low should be a '1'"
	   severity error;
    NewCRC(0) := CRC(CRC'high) xor Data;
    for i in CRC_DEGREE - 1 downto 1 loop
      if Polynomial(i) = '1' then
	NewCRC(i) := CRC(i-1) xor NewCRC(0);
      else
	NewCRC(i) := CRC(i-1);
      end if;
    end loop;
    return NewCRC;
  end OneBitCrc;

  -- function for general CRC calculation for several bits
  function MultiBitCRC (Data: unsigned;
		        CRC: unsigned;
		        Polynomial: bit_vector) return unsigned is
    constant CRC_DEGREE: integer := CRC'length;
    variable NewCRC: unsigned(CRC_DEGREE-1 downto 0);
    variable NewCRC_Zero: one_bit;
  begin
    assert Polynomial'high = CRC_DEGREE
	   report "Polynomial'high doesn't match CRC degree"
	   severity error;
    assert Polynomial'low = 0
           report "Polynomial'low should be 0"
	   severity error;
    assert Polynomial(Polynomial'high) = '1'
	   report "Polynomial'high should be a '1'"
	   severity error;
    assert Polynomial(Polynomial'low) = '1'
	   report "Polynomial'low should be a '1'"
	   severity error;
    NewCRC := CRC;
    for j in Data'range loop
      NewCRC_Zero := NewCRC(NewCRC'high) xor Data(j);
      for i in CRC_DEGREE - 1 downto 1 loop
	if Polynomial(i) = '1' then
	  NewCRC(i) := NewCRC(i-1) xor NewCRC_Zero;
	else
	  NewCRC(i) := NewCRC(i-1);
	end if;
      end loop;
      NewCRC(0) := NewCRC_Zero;
    end loop;
    return NewCRC;
  end MultiBitCrc;

  function CalcSyndrome (CodeWord: unsigned;
			 CRC_Matrix: unsigned;
			 CRC_Degree: natural;
		         Coset: unsigned) return unsigned is
    variable CodeWordWithCoset: unsigned(CodeWord'range);
    variable Syndrome: unsigned(CRC_Degree-1 downto 0);
  begin
    assert (Coset'length <= CodeWord'length)
	   report "Coset too long for data word"
	   severity error;
    assert (CodeWord'length * CRC_Degree = CRC_Matrix'length)
	   report "CRC_Matrix does not match data length * CRC_Degree"
	   severity error;
    CodeWordWithCoset := CodeWord;
    CodeWordWithCoset(Coset'length - 1 downto 0) :=
	    CodeWord(Coset'length - 1 downto 0) xor Coset;
    Syndrome := (others => '0');
    for i in 0 to CRC_Degree-1 loop
      for j in 0 to CodeWord'high loop
	Syndrome(i) := Syndrome(i) xor
	  (CodeWordWithCoset(j) and CRC_Matrix(CodeWord'length*i+j));
      end loop; -- Data loop
    end loop; -- CRC loop
    return Syndrome;
  end CalcSyndrome;

  function SyndromePosition(Syndrome: unsigned;
			    CRC_Matrix: unsigned) return integer is
    constant X_DIM: integer := CRC_Matrix'length / Syndrome'length;
    constant Y_DIM: integer := Syndrome'length;
    variable ErrorPosition: integer range 0 to X_DIM;
    variable MatrixRow: unsigned(Y_DIM-1 downto 0);
  begin
    ErrorPosition := X_DIM; -- syndrome not found in CRC_Matrix
    for j in 0 to X_DIM - 1 loop
      MatrixRow := (others => '0');
      for i in 0 to Y_DIM - 1 loop
	MatrixRow(i) := CRC_Matrix(i*X_DIM + j);
      end loop;
      if (Syndrome = MatrixRow) then
	return j;
      end if;
    end loop;
    return ErrorPosition;
  end SyndromePosition;

  -- Multiple CRC5 with message length 1 bits
  function MultipleCRC5_D1 (D: one_bit;
                            CRC: five_bits) return five_bits is
    variable NewCRC: five_bits;
  begin
    NewCRC(0) := CRC(4) xor D;
    NewCRC(1) := CRC(0);
    NewCRC(2) := CRC(1) xor CRC(4) xor D;
    NewCRC(3) := CRC(2);
    NewCRC(4) := CRC(3);
    return NewCRC;
  end MultipleCRC5_D1;

  -- Multiple CRC5 with message length 11 bits
  function MultipleCRC5_D11 (D: eleven_bits;
                            CRC: five_bits) return five_bits is
    variable NewCRC: five_bits;
  begin
    NewCRC(0) := CRC(4) xor D(10) xor D(5) xor CRC(0) xor CRC(3)
                   xor D(9) xor D(6) xor D(3) xor D(0);
    NewCRC(1) := CRC(0) xor D(6) xor CRC(1) xor CRC(4) xor D(10)
                   xor D(7) xor D(4) xor D(1);
    NewCRC(2) := CRC(1) xor D(7) xor CRC(2) xor D(8) xor D(2)
                   xor CRC(4) xor D(10) xor CRC(0) xor CRC(3) xor D(9)
                   xor D(6) xor D(3) xor D(0);
    NewCRC(3) := CRC(2) xor D(8) xor CRC(3) xor D(9) xor D(3)
                   xor CRC(1) xor CRC(4) xor D(10) xor D(7) xor D(4)
                   xor D(1);
    NewCRC(4) := CRC(3) xor D(9) xor CRC(4) xor D(10) xor D(4)
                   xor CRC(2) xor D(8) xor D(5) xor D(2);
    return NewCRC;
  end MultipleCRC5_D11;

  -- Single CRC5 with message length 11 bits
  function SingleCRC5_D11 (D: eleven_bits)
           return five_bits is
    variable NewCRC: five_bits;
  begin
    NewCRC(0) := D(10) xor D(5) xor D(9) xor D(6) xor D(3) xor D(0);
    NewCRC(1) := D(6) xor D(10) xor D(7) xor D(4) xor D(1);
    NewCRC(2) := D(7) xor D(8) xor D(2) xor D(10) xor D(9)
		   xor D(6) xor D(3) xor D(0);
    NewCRC(3) := D(8) xor D(9) xor D(3) xor D(10) xor D(7)
		   xor D(4) xor D(1);
    NewCRC(4) := D(9) xor D(10) xor D(4) xor D(8) xor D(5) xor D(2);
    return NewCRC;
  end SingleCRC5_D11;

  -- Multiple CRC16 with message length 1 bits
  function MultipleCRC16_D1 (D: one_bit;
                            CRC: two_bytes) return two_bytes is
    variable NewCRC: two_bytes;
  begin
    NewCRC(0) := CRC(15) xor D;
    NewCRC(1) := CRC(0);
    NewCRC(2) := CRC(1) xor CRC(15) xor D;
    NewCRC(3) := CRC(2);
    NewCRC(4) := CRC(3);
    NewCRC(5) := CRC(4);
    NewCRC(6) := CRC(5);
    NewCRC(7) := CRC(6);
    NewCRC(8) := CRC(7);
    NewCRC(9) := CRC(8);
    NewCRC(10) := CRC(9);
    NewCRC(11) := CRC(10);
    NewCRC(12) := CRC(11);
    NewCRC(13) := CRC(12);
    NewCRC(14) := CRC(13);
    NewCRC(15) := CRC(14) xor CRC(15) xor D;
    return NewCRC;
  end MultipleCRC16_D1;

  -- Multiple CRC16 with message length 8 bits
  function MultipleCRC16_D8 (D: byte;
                            CRC: two_bytes) return two_bytes is
    variable NewCRC: two_bytes;
  begin
    NewCRC(0) := CRC(8) xor CRC(9) xor CRC(10) xor CRC(11) xor CRC(12)
                   xor CRC(13) xor CRC(14) xor CRC(15) xor D(7) xor D(6)
                   xor D(5) xor D(4) xor D(3) xor D(2) xor D(1)
                   xor D(0);
    NewCRC(1) := CRC(9) xor CRC(10) xor CRC(11) xor CRC(12) xor CRC(13)
                   xor CRC(14) xor CRC(15) xor D(7) xor D(6) xor D(5)
                   xor D(4) xor D(3) xor D(2) xor D(1);
    NewCRC(2) := CRC(8) xor CRC(9) xor D(1) xor D(0);
    NewCRC(3) := CRC(9) xor CRC(10) xor D(2) xor D(1);
    NewCRC(4) := CRC(10) xor CRC(11) xor D(3) xor D(2);
    NewCRC(5) := CRC(11) xor CRC(12) xor D(4) xor D(3);
    NewCRC(6) := CRC(12) xor CRC(13) xor D(5) xor D(4);
    NewCRC(7) := CRC(13) xor CRC(14) xor D(6) xor D(5);
    NewCRC(8) := CRC(0) xor CRC(14) xor CRC(15) xor D(7) xor D(6)
                  ;
    NewCRC(9) := CRC(1) xor CRC(15) xor D(7);
    NewCRC(10) := CRC(2);
    NewCRC(11) := CRC(3);
    NewCRC(12) := CRC(4);
    NewCRC(13) := CRC(5);
    NewCRC(14) := CRC(6);
    NewCRC(15) := CRC(7) xor CRC(8) xor CRC(9) xor CRC(10) xor CRC(11)
                   xor CRC(12) xor CRC(13) xor CRC(14) xor CRC(15) xor D(7)
                   xor D(6) xor D(5) xor D(4) xor D(3) xor D(2)
                   xor D(1) xor D(0);
    return NewCRC;
  end MultipleCRC16_D8;

end PCK_USB;

⌨️ 快捷键说明

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