📄 usb_new_pck_usb.vhdl
字号:
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 + -