📄 usbtstpak.vhd
字号:
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
data: in STD_LOGIC_VECTOR(7 downto 0)) is
begin
bit01(clk, xd, x0, data(0)); fieldComputeCRC16(data(0));
bit01(clk, xd, x0, data(1)); fieldComputeCRC16(data(1));
bit01(clk, xd, x0, data(2)); fieldComputeCRC16(data(2));
bit01(clk, xd, x0, data(3)); fieldComputeCRC16(data(3));
bit01(clk, xd, x0, data(4)); fieldComputeCRC16(data(4));
bit01(clk, xd, x0, data(5)); fieldComputeCRC16(data(5));
bit01(clk, xd, x0, data(6)); fieldComputeCRC16(data(6));
bit01(clk, xd, x0, data(7)); fieldComputeCRC16(data(7));
end procedure;
--------------------
procedure fieldCRC5(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
begin
-- When the last bit of the checked field is sent, the CRC in the
-- generator is inverted and sent to the checker MSb first. When
-- the last bit of the CRC is received by the checker and no
-- errors have occurred, the remainder will be equal to the
-- polynomial residual.
bit01(clk, xd, x0, not(crc5(4)));
bit01(clk, xd, x0, not(crc5(3)));
bit01(clk, xd, x0, not(crc5(2)));
bit01(clk, xd, x0, not(crc5(1)));
bit01(clk, xd, x0, not(crc5(0)));
end procedure;
--------------------
procedure fieldCRC16(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
begin
bit01(clk, xd, x0, not(crc16(15)));
bit01(clk, xd, x0, not(crc16(14)));
bit01(clk, xd, x0, not(crc16(13)));
bit01(clk, xd, x0, not(crc16(12)));
bit01(clk, xd, x0, not(crc16(11)));
bit01(clk, xd, x0, not(crc16(10)));
bit01(clk, xd, x0, not(crc16(9)));
bit01(clk, xd, x0, not(crc16(8)));
bit01(clk, xd, x0, not(crc16(7)));
bit01(clk, xd, x0, not(crc16(6)));
bit01(clk, xd, x0, not(crc16(5)));
bit01(clk, xd, x0, not(crc16(4)));
bit01(clk, xd, x0, not(crc16(3)));
bit01(clk, xd, x0, not(crc16(2)));
bit01(clk, xd, x0, not(crc16(1)));
bit01(clk, xd, x0, not(crc16(0)));
end procedure;
----------------------------------------
-- part #4: packets
procedure packetOUT(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
addr: in STD_LOGIC_VECTOR(6 downto 0);
ep: in STD_LOGIC_VECTOR(3 downto 0)) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldOUTpid);
fieldADDR (clk, xd, x0, addr);
fieldEP (clk, xd, x0, ep);
fieldCRC5 (clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetIN(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
addr: in STD_LOGIC_VECTOR(6 downto 0);
ep: in STD_LOGIC_VECTOR(3 downto 0)) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldINpid);
fieldADDR (clk, xd, x0, addr);
fieldEP (clk, xd, x0, ep);
fieldCRC5 (clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetSOF(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
frame: in STD_LOGIC_VECTOR(10 downto 0)) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldSOFpid);
fieldFRAME(clk, xd, x0, frame);
fieldCRC5 (clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetSETUP(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
addr: in STD_LOGIC_VECTOR(6 downto 0);
ep: in STD_LOGIC_VECTOR(3 downto 0)) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldSETUPpid);
fieldADDR (clk, xd, x0, addr);
fieldEP (clk, xd, x0, ep);
fieldCRC5 (clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetDATA0(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
data: in packetBUF) is
variable i: INTEGER;
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldDATA0pid);
for i in data'range loop
fieldBYTE(clk, xd, x0, data(i));
end loop;
fieldCRC16(clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetDATA0(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
data: in packetCHR) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldDATA0pid);
fieldBYTE(clk, xd, x0, data);
fieldCRC16(clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetDATA0(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
variable i: INTEGER;
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldDATA0pid);
fieldCRC16(clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetDATA1(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
data: in packetBUF) is
variable i: INTEGER;
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldDATA1pid);
for i in data'range loop
fieldBYTE(clk, xd, x0, data(i));
end loop;
fieldCRC16(clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetDATA1(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
data: in packetCHR) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldDATA1pid);
fieldBYTE(clk, xd, x0, data);
fieldCRC16(clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetDATA1(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
variable i: INTEGER;
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldDATA1pid);
fieldCRC16(clk, xd, x0);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetACK(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldACKpid);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetNAK(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldNAKpid);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetSTALL(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
begin
fieldSYNC (clk, xd, x0);
fieldPID (clk, xd, x0, fieldSTALLpid);
fieldEOP (clk, xd, x0);
end procedure;
--------------------
procedure packetIDLE(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC;
cycles: in INTEGER) is
variable i: INTEGER;
begin
i:= 0;
while i< cycles loop
fieldIDLE(clk, xd, x0);
i:= i+1;
end loop;
end procedure;
--------------------
procedure packetRESET(
signal clk: in STD_LOGIC;
signal xd: out STD_LOGIC;
signal x0: out STD_LOGIC) is
begin
fieldSE0(clk, xd, x0);
-- Reference: USB Spec 1.1
-- * The reset signaling must be driven for a minimum of 10ms (TDRST).
-- * Resets from root ports should be nominally 50ms (TDRSTR).
-- * A device seeing an SE0 on its upstream port for more than
-- 2.5us (TDETRST) may treat that signal as a reset.
--wait for 50ms;
--wait for 10ms;
wait for 5us;
end procedure;
end package body usbTSTPAK;
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use work.usbTSTPAK.all;
entity usbTSTctrl is
port(
signal sim: in STD_LOGIC; -- TRUE while simulating
signal stim: in STD_LOGIC; -- TRUE to stimulate UUT
--
signal clk48: out STD_LOGIC; -- 48MHz clock
signal rst: out STD_LOGIC; -- async reset
--
signal uut_rxd: out STD_LOGIC; -- UUT rxd pin
signal uut_rx0: out STD_LOGIC; -- UUT rx0 pin
signal uut_txd: in STD_LOGIC; -- UUT txd pin
signal uut_tx0: in STD_LOGIC; -- UUT tx0 pin
--
signal tb_xd: in STD_LOGIC; -- testbench xd signal
signal tb_x0: in STD_LOGIC; -- testbench x0 signal
signal tb_clk: out STD_LOGIC -- testbench clock
);
end usbTSTctrl;
architecture Test of usbTSTctrl is
signal pll: STD_LOGIC;
signal osc: STD_LOGIC;
constant Tusb1: TIME:= 84ns;
constant Tusb2: TIME:= 21ns;
begin
--------------------
-- UUT clock & reset
process
begin
if sim= '0' then
wait;
else
clk48<= '0', '1' after 10ns;
wait for Tusb2;
end if;
end process;
rst<= '1', '0' after 5ns;
--------------------
-- stimuli clock oscillator
process(osc, stim)
begin
if stim= '1' then
if osc= 'U' then
osc<= '0';
else
osc<= not(osc) after Tusb1/2;
end if;
end if;
end process;
--------------------
-- response clock recovery
process(uut_txd, uut_tx0, stim)
type Tstate is (Soff, Sx1, Sx, Sse0);
variable state: Tstate;
begin
if stim= '0' then
-- clock recovery state machine
case state is
when Soff=>
if uut_txd'event and uut_txd= '0' then
state:= Sx1;
end if;
when Sx1=>
if uut_txd'event then
state:= Sx;
end if;
when Sx=>
if uut_tx0= '1' then
state:= Sse0;
end if;
when Sse0=>
if uut_txd= '1' then
state:= Soff;
end if;
end case;
-- clock recovery
if (uut_txd'event and (uut_txd= '1' or uut_txd= '0'))
or (uut_tx0'event) then
case state is
when Sx1=> -- sync pattern at start of packet
pll<= '0', '1' after (1*Tusb1)/2;
when Sx=> -- normal bits
pll<=
'0', '1' after (1*Tusb1)/2, -- 1
'0' after (2*Tusb1)/2, '1' after (3*Tusb1)/2, -- 2
'0' after (4*Tusb1)/2, '1' after (5*Tusb1)/2, -- 3
'0' after (6*Tusb1)/2, '1' after (7*Tusb1)/2, -- 4
'0' after (8*Tusb1)/2, '1' after (9*Tusb1)/2, -- 5
'0' after (10*Tusb1)/2, '1' after (11*Tusb1)/2, -- 6
'0' after (12*Tusb1)/2, '1' after (13*Tusb1)/2; -- 7
when Sse0=> -- se0 at end of packet
pll<=
'0', '1' after (1*Tusb1)/2, -- 1
'0' after (2*Tusb1)/2, '1' after (3*Tusb1)/2; -- 2
--'0' after (4*Tusb1)/2, '1' after (5*Tusb1)/2; -- 3
when others=> -- J at end of packet or bus idle
pll<= '0', '1' after (1*Tusb1)/2;
end case;
end if;
else
state:= Soff;
end if;
end process;
tb_clk <= osc when stim= '1' else pll;
uut_rxd<= tb_xd when stim= '1' else '1';
uut_rx0<= tb_x0 when stim= '1' else '0';
--------------------
process
begin
wait until rising_edge(pll);
wait for 1ns;
assert(tb_xd= '-' or uut_txd= tb_xd) report "xd mismatch" severity FAILURE;
assert(tb_x0= '-' or uut_tx0= tb_x0) report "x0 mismatch" severity FAILURE;
end process;
end Test;
--------------------------------------------------------------------------------
-- end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -