📄 usb_new_pck_usb.vhdl
字号:
constant Pid_InvVal_OFFSET: integer := 4;
constant Pid_InvVal_LENGTH: integer := 4;
subtype S_Pid_InvVal_busrange is
integer range Pid_InvVal_OFFSET +
Pid_InvVal_LENGTH - 1 downto
Pid_InvVal_OFFSET;
subtype S_Pid_InvVal_bitrange is
integer range Pid_InvVal_LENGTH - 1 downto 0;
subtype S_Pid_InvVal_bits is
unsigned (S_Pid_InvVal_bitrange);
function GetPidInvVal (BusData: S_Pid_DATAWIDTH_bits)
return S_Pid_InvVal_bits;
function PutPidInvVal (BusData: S_Pid_DATAWIDTH_bits;
InvVal: S_Pid_InvVal_bits)
return S_Pid_DATAWIDTH_bits;
constant Pid_Val_OFFSET: integer := 0;
constant Pid_Val_LENGTH: integer := 4;
subtype S_Pid_Val_busrange is
integer range Pid_Val_OFFSET +
Pid_Val_LENGTH - 1 downto
Pid_Val_OFFSET;
subtype S_Pid_Val_bitrange is
integer range Pid_Val_LENGTH - 1 downto 0;
subtype S_Pid_Val_bits is
unsigned (S_Pid_Val_bitrange);
function GetPidVal (BusData: S_Pid_DATAWIDTH_bits)
return S_Pid_Val_bits;
function PutPidVal (BusData: S_Pid_DATAWIDTH_bits;
Val: S_Pid_Val_bits)
return S_Pid_DATAWIDTH_bits;
-- End of Pid.def.vhd ------------------------------------------
function DecodePidVal (Pid: S_Pid_Val_bits)
return T_Pid_enum;
function EncodePidVal (Pid: T_Pid_enum)
return S_Pid_Val_bits;
function DecodePid (Pid: S_Pid_DATAWIDTH_bits)
return T_Pid_enum;
function EncodePid (Pid: T_Pid_enum)
return S_Pid_DATAWIDTH_bits;
-- Function PidOk checks whether the encoding of the Pid is ok
-- ie. the Val field is the one's complement of the InvVal field
function PidOk (Pid: S_Pid_DATAWIDTH_bits)
return boolean;
-- Procedure CheckPid first checks whether the DataWord
-- given is a valid PID encoded word, ie. the Val field should
-- be equal to the one's complement of the InvVal (PidOk).
-- If it is not, the Error is set TRUE, the PidType is
-- set to PID_INVALID and ErrorType is set ERROR_PID_ENCODING.
-- If the encoding is correct and the pid decoding returns
-- an undefined or invalid pid, PidType is set to PID_INVALID
-- Error is set TRUE, and ErrorType is set ERROR_PID_UNKNOWN.
-- Otherwise, the correct PidType is returned with Error FALSE
-- and ErrorType is not set.
procedure CheckPid (DataWord: in S_UsbWord_bits;
PidType: out T_Pid_enum;
Error: out boolean;
ErrorType: out T_PACKET_ERROR_enum);
-- function IsValidPid return TRUE if the PidType is one
-- of the defined PIDs of T_Pid_enum (not PID_UNKNOWN,
-- PID_RESERVED_? or PID_ERR).
function IsValidPid (PidType: T_Pid_enum)
return boolean;
-----------------------------------------------------------------
-- Packet types: token, data, handshake, special
-- token packets: IN, OUT, SOF, SETUP (pid ending in "01")
-- data packets: DATA0, DATA1 (pid ending in "11")
-- handshake packets: ACK, NAK, STALL (pid ending in "10")
-- special packets: PRE (pid ending in "00")
-----------------------------------------------------------------
type T_Packet_enum is (PACKET_SPECIAL, -- "00"
PACKET_TOKEN, -- "01"
PACKET_HANDSHAKE, -- "10"
PACKET_DATA); -- "11"
subtype S_Packet_bits is two_bits;
function DecodePacket (PacketType: S_Packet_bits)
return T_Packet_enum;
function EncodePacket (PacketType: T_Packet_enum)
return S_Packet_bits;
function PidToPacket (Pid: T_Pid_enum)
return T_Packet_enum;
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);
-----------------------------------------------------------------
-- Return TRUE is PidType is of a given Packet class
-----------------------------------------------------------------
function IsTokenPid (PidType: T_Pid_enum)
return boolean;
function IsDataPid (PidType: T_Pid_enum)
return boolean;
function IsHandshakePid (PidType: T_Pid_enum)
return boolean;
function IsSpecialPid (PidType: T_Pid_enum)
return boolean;
-----------------------------------------------------------------
-- Transaction types are: bulk, control, interrupt and isochronous
-- TR_BULK bulk transactions use IN/OUT PIDs
-- TR_SETUP control transactions use SETUP/[IN-OUT]*/OUT-IN PIDs
-- TR_IRQ interrupt transactions use IN PIDs
-- TR_ISO isochronous transactions use IN/OUT PIDs
-----------------------------------------------------------------
type T_Transaction_enum is (TR_BULK,
TR_SETUP,
TR_IRQ,
TR_ISO);
subtype S_Transaction_bits is two_bits;
function EncodeTransaction (TrType: T_Transaction_enum)
return S_Transaction_bits;
function DecodeTransaction (TrType: S_Transaction_bits)
return T_Transaction_enum;
-----------------------------------------------------------------
-- CRC type encoding (token = CRC5, data = CRC16)
-----------------------------------------------------------------
type T_UsbCrc_enum is (USBCRC_TOKEN,
USBCRC_DATA);
subtype S_UsbCrc_bits is one_bit;
function EncodeUsbCrc (CrcType: T_UsbCrc_enum)
return S_UsbCrc_bits;
function DecodeUsbCrc (CrcType: S_UsbCrc_bits)
return T_UsbCrc_enum;
-----------------------------------------------------------------
-- General CRC functions
-----------------------------------------------------------------
function OneBitCRC (Data: one_bit;
CRC: unsigned;
Polynomial: bit_vector) return unsigned;
function MultiBitCRC (Data: unsigned;
CRC: unsigned;
Polynomial: bit_vector) return unsigned;
function CalcSyndrome (CodeWord: unsigned;
CRC_Matrix: unsigned;
CRC_Degree: natural;
Coset: unsigned) return unsigned;
function SyndromePosition(Syndrome: unsigned;
CRC_Matrix: unsigned) return integer;
-----------------------------------------------------------------
-- USB specific CRC functions
-- The CRCs are given for bit-serial and byte-parallel operation
-- to allow the designer to select where the CRC calculation
-- will take place (low-level interface bit-serial, protocol
-- manager byte-parallel).
-----------------------------------------------------------------
-- Token CRC5 is G(x) = x^5 + x^2 + 1
-- Functions are given for calculating the CRC5 in a
-- bit-serial fashion (function MultipleCRC5_D1) and
-- for calculating the CRC5 on the full 11 bit at once.
-- (7 bit device address and 4 bit end-point address)
-- Function SingleCRC5_D11 calculates the CRC5 over the
-- 11 data bits, MultipleCRC5_D11 allows to initialize the
-- CRC5 to a specific value and then to calculate the
-- CRC5 starting from that value.
-----------------------------------------------------------------
-- Residual for CRC5
constant CRC5_RESIDUAL: unsigned(4 downto 0) := "01100";
-- CRC5 with message length equal 1
constant CRC5_D1_MATRIX: unsigned(29 downto 0) :=
"010000" &
"001000" &
"100100" &
"000010" &
"100001";
-- CRC5 with message length equal 11
constant CRC5_D11_MATRIX: unsigned(79 downto 0) :=
"1110011010010000" &
"1111001101001000" &
"1111100110100100" &
"1001101001000010" &
"1100110100100001";
-- Multiple CRC5 with message length 1 bits
function MultipleCRC5_D1 (D: one_bit;
CRC: five_bits) return five_bits;
-- Multiple CRC5 with message length 11 bits
function MultipleCRC5_D11 (D: eleven_bits;
CRC: five_bits) return five_bits;
-- Single CRC5 with message length 11 bits
function SingleCRC5_D11 (D: eleven_bits)
return five_bits;
-----------------------------------------------------------------
-- Data packet CRC16 is G(x) = x^16 + x^15 + x^2 + 1
-- Functions are given for calculating the CRC16 in a
-- bit-serial fashion (function MultipleCRC16_D1) and
-- for calculating the CRC16 on the consecutive bytes
-- (function MultipleCRC16_D8).
-----------------------------------------------------------------
-- Residual for CRC16
constant CRC16_RESIDUAL: unsigned(15 downto 0) := "1000000000001101";
-- CRC16 with message length equal 1
constant CRC16_D1_MATRIX: unsigned(271 downto 0) :=
"11000000000000000" &
"00100000000000000" &
"00010000000000000" &
"00001000000000000" &
"00000100000000000" &
"00000010000000000" &
"00000001000000000" &
"00000000100000000" &
"00000000010000000" &
"00000000001000000" &
"00000000000100000" &
"00000000000010000" &
"00000000000001000" &
"10000000000000100" &
"00000000000000010" &
"10000000000000001";
-- CRC16 with message length equal 8
constant CRC16_D8_MATRIX: unsigned(383 downto 0) :=
"111111111000000000000000" &
"000000000100000000000000" &
"000000000010000000000000" &
"000000000001000000000000" &
"000000000000100000000000" &
"000000000000010000000000" &
"100000000000001000000000" &
"110000000000000100000000" &
"011000000000000010000000" &
"001100000000000001000000" &
"000110000000000000100000" &
"000011000000000000010000" &
"000001100000000000001000" &
"000000110000000000000100" &
"111111100000000000000010" &
"111111110000000000000001";
-- Multiple CRC16 with message length 1 bits
function MultipleCRC16_D1 (D: one_bit;
CRC: two_bytes) return two_bytes;
-- Multiple CRC16 with message length 8 bits
function MultipleCRC16_D8 (D: byte;
CRC: two_bytes) return two_bytes;
end PCK_USB;
package body PCK_USB is
function IsDevAddr (DevAddr: S_DevAddr_range;
EndpAddr: S_EndpAddr_range;
ThisDevAddr: S_DevAddr_range;
ActiveEndps: S_EndpAddr_booleans;
DevConf: boolean)
return boolean is
begin
if (not DevConf) then
if (DevAddr = DEFAULT_DEVICE_ADDRESS) then
return TRUE;
else
return FALSE;
end if;
else
if (DevAddr /= ThisDevAddr) then
return FALSE;
else
if (ActiveEndps(EndpAddr)) then
return TRUE;
else
return FALSE;
end if;
end if;
end if;
end IsDevAddr;
function ConvertAddrToTime (DevAddr: S_DevAddr_range;
EndpAddr: S_EndpAddr_range)
return S_FRAME_TIME_range is
begin
assert (MAX_DEVICE_ADDRESS * MAX_ENDPOINT_ADDRESS > FRAME_TIME)
report "ConvertAddrToTime problem"
severity note;
assert (DevAddr_ADDRWIDTH + EndpAddr_ADDRWIDTH /= FRAME_TIME_WIDTH)
report "ConvertAddrToTime not possible"
severity note;
return (DevAddr * (2**EndpAddr_ADDRWIDTH)) + EndpAddr;
end ConvertAddrToTime;
function DecodeUsbSpeed (SpeedType: one_bit)
return T_UsbSpeed_enum is
begin
case SpeedType is
when LOW =>
return USB_FULL_SPEED;
when HIGH =>
return USB_LOW_SPEED;
when others =>
return USB_FULL_SPEED;
end case; -- SpeedType
end DecodeUsbSpeed;
function EncodeUsbSpeed (SpeedType: T_UsbSpeed_enum)
return one_bit is
begin
case SpeedType is
when USB_FULL_SPEED =>
return LOW;
when USB_LOW_SPEED =>
return HIGH;
end case; -- SpeedType
end EncodeUsbSpeed;
function GetFrameLength(Speed: T_UsbSpeed_enum)
return integer is
begin
case Speed is
when USB_FULL_SPEED =>
return FRAMELENGTH_FS;
when USB_LOW_SPEED =>
return FRAMELENGTH_LS;
end case;
end GetFrameLength;
function UsbDif2Log (DifInput: two_bits;
SpeedType: T_UsbSpeed_enum)
return T_UsbLog_enum is
begin
case DifInput is
when "00" =>
return USB_LOG_SE0;
when "01" =>
case SpeedType is
when USB_FULL_SPEED =>
return USB_LOG_K;
when USB_LOW_SPEED =>
return USB_LOG_J;
end case; -- SpeedType
when "10" =>
case SpeedType is
when USB_FULL_SPEED =>
return USB_LOG_J;
when USB_LOW_SPEED =>
return USB_LOG_K;
end case; -- SpeedType
when others =>
return USB_LOG_SE1_OR_Z;
end case; -- DifInput
end UsbDif2Log;
function UsbBus2Log (DifInput: one_bit;
LineInput: two_bits;
SpeedType: T_UsbSpeed_enum)
return T_UsbLog_enum is
begin
if LineInput = two_bits'("00") then
return USB_LOG_SE0;
elsif DifInput ='1' then
case SpeedType is
when USB_FULL_SPEED =>
return USB_LOG_J;
when USB_LOW_SPEED =>
return USB_LOG_K;
end case; -- SpeedType
else
case SpeedType is
when USB_FULL_SPEED =>
return USB_LOG_K;
when USB_LOW_SPEED =>
return USB_LOG_J;
end case; -- SpeedType
end if;
end UsbBus2Log;
function UsbLog2Dif (LogInput: T_UsbLog_enum;
SpeedType: T_UsbSpeed_enum)
return two_bits is
begin
case LogInput is
when USB_LOG_SE0 =>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -