URL
https://opencores.org/ocsvn/usb11_sim_model/usb11_sim_model/trunk
Subversion Repositories usb11_sim_model
Compare Revisions
- This comparison shows the changes necessary to convert path
/usb11_sim_model/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/USB_Stimuli.vhd
0,0 → 1,153
--==========================================================================================================-- |
-- -- |
-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de -- |
-- -- |
-- This source file may be used and distributed without restriction provided that this copyright statement -- |
-- is not removed from the file and that any derivative work contains the original copyright notice and -- |
-- the associated disclaimer. -- |
-- -- |
-- This software is provided ''as is'' and without any express or implied warranties, including, but not -- |
-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event -- |
-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or -- |
-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss -- |
-- of use, data, or profits; or business interruption) however caused and on any theory of liability, -- |
-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way -- |
-- out of the use of this software, even if advised of the possibility of such damage. -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- File name : USB_tc_02.vhd -- |
-- Author : Martin Neumann martin@neumanns-mail.de -- |
-- Description : Copy and rename this file to usb_stimuli.vhd before running a new simulation! -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- Change history -- |
-- -- |
-- Version / date Description -- |
-- -- |
-- 01 05 Mar 2011 MN Initial version -- |
-- -- |
-- End change history -- |
--==========================================================================================================-- |
|
LIBRARY work, IEEE; |
USE IEEE.std_logic_1164.ALL; |
USE IEEE.std_logic_arith.ALL; |
USE work.usb_commands.ALL; |
|
ENTITY USB_Stimuli IS PORT( |
-- Test Control Interface -- |
USB : OUT usb_action; |
t_no : OUT NATURAL; |
-- Application Interface |
clk : IN STD_LOGIC; |
rst_neg_ext : OUT STD_LOGIC; |
RXval : IN STD_LOGIC; -- RX bytes available |
RXdat : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Received data bytes |
RXrdy : OUT STD_LOGIC := '0'; -- Application ready for data |
RXlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Number of bytes available |
TXval : OUT STD_LOGIC := '0'; -- Application has valid data |
TXdat : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data byte to send |
TXrdy : IN STD_LOGIC; -- Entity is ready for data |
TXroom : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- No of free bytes in TX |
TXcork : OUT STD_LOGIC := '1'); -- Hold TX transmission |
END USB_Stimuli; |
|
ARCHITECTURE sim OF usb_stimuli IS |
|
SIGNAL rd_data : byte_array(0 TO 7); |
SIGNAL TX_load : STD_LOGIC := '0'; |
|
BEGIN |
|
p_stimuli_data : PROCESS |
BEGIN |
list("*****************************"); |
list("* Results of tc_02.vhd *"); |
list("*****************************"); |
list(" "); |
list(T_No, 10); |
rst_neg_ext <= '0'; |
WAIT FOR 301 ns; |
rst_neg_ext <= '1'; |
WAIT FOR 40 ns; |
list("Reset completed, initializing"); |
TX_load <= '1'; |
list(T_No, 20); |
setup(usb, X"00", X"0"); --Send Setup to addr 0, endp 0 .. |
send_D0(usb,(X"80",X"06",X"00",X"01",X"00",X"00",X"40",X"00")); -- .. 'Get Device descriptor' |
wait_slv(usb); --Recv ACK |
in_token(usb, X"00", X"0"); --Send IN-Token |
wait_slv(usb); --Recv Data1 Device Discriptor |
send_ack(usb); --Send ACK |
out_token(usb, X"00", X"0"); |
send_D0(usb); --Send Zero Data |
wait_slv(usb); |
|
list(T_No, 30); |
setup(usb, X"00", X"0"); --Setup to addr 0, endp 0 .. |
send_D0(usb,(X"00",X"05",X"03",X"00",X"00",X"00",X"00",X"00")); -- .. 'Set Address' |
wait_slv(usb); --Recv ACK |
in_token(usb, X"00", X"0"); --Send IN-Token |
wait_slv(usb); --Recv Data0 zero Length |
send_ack(usb); --Send ACK |
|
--Now we may use the new address : |
list(T_No, 50); |
out_token(usb, X"03", X"1"); --Send Out-Token to Endpoint 1 |
send_D0(usb, (X"11",X"22",X"33",X"44",X"55",X"66",X"77",X"88")); |
wait_slv(usb); |
list(T_No, 51); |
out_token(usb, X"03", X"1"); --Send Out-Token to Endpoint 1 |
send_D0(usb, (X"11",X"12",X"13",X"14",X"15",X"16",X"17",X"18")); |
wait_slv(usb); |
TXcork <= '0'; --Release TX buffer |
FOR i IN 0 TO 5 LOOP |
list(T_No, 60+i); |
in_token(usb, X"03", X"1"); --Send IN-Token to Endpoint 1 |
wait_slv(usb); --Recv Data ? |
send_ack(usb); --Send ACK |
END LOOP; |
-- list(T_No, 70); |
-- in_token(usb, X"03", X"1"); --Send IN-Token to Endpoint 1 |
-- wait_slv(usb); --Recv Data ? |
-- send_ack(usb); --Send ACK |
IF usb_busy THEN --is a usb_monitor signal |
WAIT UNTIL NOT usb_busy; |
END IF; |
WAIT FOR 300 ns; |
send_RES(usb); |
WAIT FOR 1 us; |
ASSERT FALSE REPORT"End of Test" SEVERITY FAILURE; |
END PROCESS; |
|
p_rd_data : PROCESS |
VARIABLE i : NATURAL := 0; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
RXrdy <= '1'; |
IF i < 8 THEN |
RXrdy <= '1'; |
IF RXval ='1' THEN |
rd_data(i) <= RXdat; |
END IF; |
ELSE |
RXrdy <= '0'; |
END IF; |
END PROCESS; |
|
p_wr_data : PROCESS |
VARIABLE i : NATURAL := 0; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
IF i < 333 AND TXrdy ='1' and TX_load ='1' THEN |
TXval <= '1'; |
TXdat <= CONV_STD_LOGIC_VECTOR(i,8); |
i := i +1; |
ELSE |
TXval <= '0'; |
END IF; |
END PROCESS; |
|
END sim; |
/usb_tc_02.vhd
0,0 → 1,153
--==========================================================================================================-- |
-- -- |
-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de -- |
-- -- |
-- This source file may be used and distributed without restriction provided that this copyright statement -- |
-- is not removed from the file and that any derivative work contains the original copyright notice and -- |
-- the associated disclaimer. -- |
-- -- |
-- This software is provided ''as is'' and without any express or implied warranties, including, but not -- |
-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event -- |
-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or -- |
-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss -- |
-- of use, data, or profits; or business interruption) however caused and on any theory of liability, -- |
-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way -- |
-- out of the use of this software, even if advised of the possibility of such damage. -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- File name : USB_tc_02.vhd -- |
-- Author : Martin Neumann martin@neumanns-mail.de -- |
-- Description : Copy and rename this file to usb_stimuli.vhd before running a new simulation! -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- Change history -- |
-- -- |
-- Version / date Description -- |
-- -- |
-- 01 05 Mar 2011 MN Initial version -- |
-- -- |
-- End change history -- |
--==========================================================================================================-- |
|
LIBRARY work, IEEE; |
USE IEEE.std_logic_1164.ALL; |
USE IEEE.std_logic_arith.ALL; |
USE work.usb_commands.ALL; |
|
ENTITY USB_Stimuli IS PORT( |
-- Test Control Interface -- |
USB : OUT usb_action; |
t_no : OUT NATURAL; |
-- Application Interface |
clk : IN STD_LOGIC; |
rst_neg_ext : OUT STD_LOGIC; |
RXval : IN STD_LOGIC; -- RX bytes available |
RXdat : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Received data bytes |
RXrdy : OUT STD_LOGIC := '0'; -- Application ready for data |
RXlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Number of bytes available |
TXval : OUT STD_LOGIC := '0'; -- Application has valid data |
TXdat : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data byte to send |
TXrdy : IN STD_LOGIC; -- Entity is ready for data |
TXroom : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- No of free bytes in TX |
TXcork : OUT STD_LOGIC := '1'); -- Hold TX transmission |
END USB_Stimuli; |
|
ARCHITECTURE sim OF usb_stimuli IS |
|
SIGNAL rd_data : byte_array(0 TO 7); |
SIGNAL TX_load : STD_LOGIC := '0'; |
|
BEGIN |
|
p_stimuli_data : PROCESS |
BEGIN |
list("*****************************"); |
list("* Results of tc_02.vhd *"); |
list("*****************************"); |
list(" "); |
list(T_No, 10); |
rst_neg_ext <= '0'; |
WAIT FOR 301 ns; |
rst_neg_ext <= '1'; |
WAIT FOR 40 ns; |
list("Reset completed, initializing"); |
TX_load <= '1'; |
list(T_No, 20); |
setup(usb, X"00", X"0"); --Send Setup to addr 0, endp 0 .. |
send_D0(usb,(X"80",X"06",X"00",X"01",X"00",X"00",X"40",X"00")); -- .. 'Get Device descriptor' |
wait_slv(usb); --Recv ACK |
in_token(usb, X"00", X"0"); --Send IN-Token |
wait_slv(usb); --Recv Data1 Device Discriptor |
send_ack(usb); --Send ACK |
out_token(usb, X"00", X"0"); |
send_D0(usb); --Send Zero Data |
wait_slv(usb); |
|
list(T_No, 30); |
setup(usb, X"00", X"0"); --Setup to addr 0, endp 0 .. |
send_D0(usb,(X"00",X"05",X"03",X"00",X"00",X"00",X"00",X"00")); -- .. 'Set Address' |
wait_slv(usb); --Recv ACK |
in_token(usb, X"00", X"0"); --Send IN-Token |
wait_slv(usb); --Recv Data0 zero Length |
send_ack(usb); --Send ACK |
|
--Now we may use the new address : |
list(T_No, 50); |
out_token(usb, X"03", X"1"); --Send Out-Token to Endpoint 1 |
send_D0(usb, (X"11",X"22",X"33",X"44",X"55",X"66",X"77",X"88")); |
wait_slv(usb); |
list(T_No, 51); |
out_token(usb, X"03", X"1"); --Send Out-Token to Endpoint 1 |
send_D0(usb, (X"11",X"12",X"13",X"14",X"15",X"16",X"17",X"18")); |
wait_slv(usb); |
TXcork <= '0'; --Release TX buffer |
FOR i IN 0 TO 5 LOOP |
list(T_No, 60+i); |
in_token(usb, X"03", X"1"); --Send IN-Token to Endpoint 1 |
wait_slv(usb); --Recv Data ? |
send_ack(usb); --Send ACK |
END LOOP; |
-- list(T_No, 70); |
-- in_token(usb, X"03", X"1"); --Send IN-Token to Endpoint 1 |
-- wait_slv(usb); --Recv Data ? |
-- send_ack(usb); --Send ACK |
IF usb_busy THEN --is a usb_monitor signal |
WAIT UNTIL NOT usb_busy; |
END IF; |
WAIT FOR 300 ns; |
send_RES(usb); |
WAIT FOR 1 us; |
ASSERT FALSE REPORT"End of Test" SEVERITY FAILURE; |
END PROCESS; |
|
p_rd_data : PROCESS |
VARIABLE i : NATURAL := 0; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
RXrdy <= '1'; |
IF i < 8 THEN |
RXrdy <= '1'; |
IF RXval ='1' THEN |
rd_data(i) <= RXdat; |
END IF; |
ELSE |
RXrdy <= '0'; |
END IF; |
END PROCESS; |
|
p_wr_data : PROCESS |
VARIABLE i : NATURAL := 0; |
BEGIN |
WAIT UNTIL rising_edge(clk); |
IF i < 333 AND TXrdy ='1' and TX_load ='1' THEN |
TXval <= '1'; |
TXdat <= CONV_STD_LOGIC_VECTOR(i,8); |
i := i +1; |
ELSE |
TXval <= '0'; |
END IF; |
END PROCESS; |
|
END sim; |
/TC_Copy.bat
0,0 → 1,5
@ECHO Off |
if exist USB_Stimuli.old erase USB_Stimuli.old |
if exist USB_Stimuli.vhd rename USB_Stimuli.vhd USB_Stimuli.old |
copy %1 USB_Stimuli.vhd |
|
/usb_tc_02.out
0,0 → 1,77
***************************** |
* Results of tc_02.vhd * |
***************************** |
|
Test_No 10 |
Reset completed, initializing |
Test_No 20 |
1862.409 ns Send Setup: Address 0x00, Endpoint 0x0, CRC5 0x02 |
4862.328 ns Send Data0 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 0xDD 0x94 |
13599.797 ns Recv ACK |
15452.206 ns Send IN-Token: Address 0x00, Endpoint 0x0, CRC5 0x02 |
18845.557 ns Recv Data1 0x12 0x01 0x10 0x01 0x02 0x00 0x00 0x40 0x9A 0xFB 0x9A 0xFB 0x20 0x00 0x00 0x00 |
29992.797 ns ..... 0x00 0x01 0xB4 0x2C |
33861.545 ns Send ACK |
35533.631 ns Send OUT-Token: Address 0x00, Endpoint 0x0, CRC5 0x02 |
38533.55 ns Send Data0 0x00 0x00 |
41926.901 ns Recv ACK |
Test_No 30 |
43779.31 ns Send Setup: Address 0x00, Endpoint 0x0, CRC5 0x02 |
46779.229 ns Send Data0 0x00 0x05 0x03 0x00 0x00 0x00 0x00 0x00 0xEA 0xC7 |
55598.663 ns Recv ACK |
57451.072 ns Send IN-Token: Address 0x00, Endpoint 0x0, CRC5 0x02 |
60844.423 ns Recv Data1 0x00 0x00 |
64024.665 ns Send ACK |
Test_No 50 |
65696.751 ns Send OUT-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
68696.67 ns Send Data0 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x5E 0xBF |
77516.104 ns Recv ACK |
Test_No 51 |
79352.12 ns Send OUT-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
82352.039 ns Send Data0 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x95 0xA7 |
91089.508 ns Recv ACK |
Test_No 60 |
92941.917 ns Send IN-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
96351.661 ns Recv Data0 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F |
107498.901 ns ..... 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F |
117990.421 ns ..... 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F |
128481.941 ns ..... 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3A 0x3B 0x3C 0x3D 0x3E 0x3F |
139055.426 ns ..... 0x26 0xF7 |
141612.734 ns Send ACK |
Test_No 61 |
143268.427 ns Send IN-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
146678.171 ns Recv Data1 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4A 0x4B 0x4C 0x4D 0x4E 0x4F |
157825.411 ns ..... 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5A 0x5B 0x5C 0x5D 0x5E 0x5F |
168316.931 ns ..... 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x69 0x6A 0x6B 0x6C 0x6D 0x6E 0x6F |
178808.451 ns ..... 0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7A 0x7B 0x7C 0x7D 0x7E 0x7F |
189463.901 ns ..... 0x9B 0xBA |
192021.209 ns Send ACK |
Test_No 62 |
193693.295 ns Send IN-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
197103.039 ns Recv Data0 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8A 0x8B 0x8C 0x8D 0x8E 0x8F |
208250.279 ns ..... 0x90 0x91 0x92 0x93 0x94 0x95 0x96 0x97 0x98 0x99 0x9A 0x9B 0x9C 0x9D 0x9E 0x9F |
218823.764 ns ..... 0xA0 0xA1 0xA2 0xA3 0xA4 0xA5 0xA6 0xA7 0xA8 0xA9 0xAA 0xAB 0xAC 0xAD 0xAE 0xAF |
229315.284 ns ..... 0xB0 0xB1 0xB2 0xB3 0xB4 0xB5 0xB6 0xB7 0xB8 0xB9 0xBA 0xBB 0xBC 0xBD 0xBE 0xBF |
239888.769 ns ..... 0x5C 0x6C |
242446.077 ns Send ACK |
Test_No 63 |
244101.77 ns Send IN-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
247511.514 ns Recv Data1 0xC0 0xC1 0xC2 0xC3 0xC4 0xC5 0xC6 0xC7 0xC8 0xC9 0xCA 0xCB 0xCC 0xCD 0xCE 0xCF |
258740.719 ns ..... 0xD0 0xD1 0xD2 0xD3 0xD4 0xD5 0xD6 0xD7 0xD8 0xD9 0xDA 0xDB 0xDC 0xDD 0xDE 0xDF |
269314.204 ns ..... 0xE0 0xE1 0xE2 0xE3 0xE4 0xE5 0xE6 0xE7 0xE8 0xE9 0xEA 0xEB 0xEC 0xED 0xEE 0xEF |
279969.654 ns ..... 0xF0 0xF1 0xF2 0xF3 0xF4 0xF5 0xF6 0xF7 0xF8 0xF9 0xFA 0xFB 0xFC 0xFD 0xFE 0x00 |
291034.929 ns ..... 0xA1 0x61 |
293526.665 ns Send ACK |
Test_No 64 |
295198.751 ns Send IN-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
298592.102 ns Recv Data0 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 |
309739.342 ns ..... 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1A 0x1B 0x1C 0x1D 0x1E 0x1F 0x20 |
320230.862 ns ..... 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2A 0x2B 0x2C 0x2D 0x2E 0x2F 0x30 |
330722.382 ns ..... 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3A 0x3B 0x3C 0x3D 0x3E 0x3F 0x41 |
341295.867 ns ..... 0x98 0x8A |
343853.175 ns Send ACK |
Test_No 65 |
345525.261 ns Send IN-Token: Address 0x03, Endpoint 0x1, CRC5 0x1C |
348935.005 ns Recv Data1 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4A 0x4B 0x4C 0x5A 0x87 |
359360.953 ns Send ACK |
364950.966 ns USB Reset detected for 5098.223 ns |
/usb_fs_slave.vhdl
0,0 → 1,181
|
--==========================================================================================================-- |
-- -- |
-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de -- |
-- -- |
-- This source file may be used and distributed without restriction provided that this copyright statement -- |
-- is not removed from the file and that any derivative work contains the original copyright notice and -- |
-- the associated disclaimer. -- |
-- -- |
-- This software is provided ''as is'' and without any express or implied warranties, including, but not -- |
-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event -- |
-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or -- |
-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss -- |
-- of use, data, or profits; or business interruption) however caused and on any theory of liability, -- |
-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way -- |
-- out of the use of this software, even if advised of the possibility of such damage. -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- File name : usb_fs_slave.vhdl -- |
-- Author : Martin Neumann martin@neumanns-mail.de -- |
-- Description : Wrapper for a USB full speed slave operating at 60MHz clock frequency -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- Change history -- |
-- -- |
-- Version / date Description -- |
-- -- |
-- 01 05 Mar 2011 MN Initial version -- |
-- -- |
-- End change history -- |
--==========================================================================================================-- |
|
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
|
ENTITY usb_fs_slave IS |
GENERIC ( |
VENDORID : STD_LOGIC_VECTOR(15 DOWNTO 0); |
PRODUCTID : STD_LOGIC_VECTOR(15 DOWNTO 0); |
VERSIONBCD : STD_LOGIC_VECTOR(15 DOWNTO 0); |
SELFPOWERED : BOOLEAN := FALSE; |
BUFSIZE_BITS : INTEGER RANGE 7 to 12 := 10); |
PORT ( |
clk : IN STD_LOGIC; |
rst_neg_ext : IN STD_LOGIC; |
rst_neg_syc : OUT STD_LOGIC; |
d_pos : INOUT STD_LOGIC; |
d_neg : INOUT STD_LOGIC; |
USB_rst : OUT STD_LOGIC; -- USB reset detected (SE0 > 2.5 us) |
online : OUT STD_LOGIC; -- High when the device is in Config state. |
RXval : OUT STD_LOGIC; -- High if a received byte available on RXDAT. |
RXdat : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Received data byte, valid if RXVAL is high. |
RXrdy : IN STD_LOGIC; -- High if application is ready to receive. |
RXlen : OUT STD_LOGIC_VECTOR(BUFSIZE_BITS-1 DOWNTO 0); -- No of bytes available in receive buffer. |
TXval : IN STD_LOGIC; -- High if the application has data to send. |
TXdat : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data byte to send, must be valid if TXVAL is high. |
TXrdy : OUT STD_LOGIC; -- High if the entity is ready to accept the next byte. |
TXroom : OUT STD_LOGIC_VECTOR(BUFSIZE_BITS-1 DOWNTO 0); -- No of free bytes in transmit buffer. |
TXcork : IN STD_LOGIC; -- Temp. suppress transmissions at the outgoing endpoint. |
FPGA_ready : OUT STD_LOGIC); -- connect FPGA_ready to the pullup resistor logic |
END usb_fs_slave; |
|
ARCHITECTURE rtl OF usb_fs_slave IS |
|
CONSTANT DriverMode : STD_LOGIC := '1'; -- HIGH level for differential io mode (else single-ended) |
CONSTANT tx_wait : STD_LOGIC := '0'; -- Don't suppress temporarily transmissions at the outgoing endpoint. |
|
SIGNAL Phy_DataIn : STD_LOGIC_VECTOR(7 DOWNTO 0); |
SIGNAL Phy_DataOut : STD_LOGIC_VECTOR(7 DOWNTO 0); |
SIGNAL Phy_Linestate : STD_LOGIC_VECTOR(1 DOWNTO 0); |
SIGNAL Phy_Opmode : STD_LOGIC_VECTOR(1 DOWNTO 0); |
SIGNAL Phy_RxActive : STD_LOGIC; |
SIGNAL Phy_RxError : STD_LOGIC; |
SIGNAL Phy_RxValid : STD_LOGIC; |
SIGNAL Phy_Termselect : STD_LOGIC := 'L'; |
SIGNAL Phy_TxReady : STD_LOGIC; |
SIGNAL Phy_TxValid : STD_LOGIC; |
SIGNAL Phy_XcvrSelect : STD_LOGIC := 'L'; |
SIGNAL usb_rst_phy : STD_LOGIC; |
SIGNAL usb_rst_slv : STD_LOGIC; |
SIGNAL rst_neg_int : STD_LOGIC; |
SIGNAL rst_neg_tmp : STD_LOGIC; |
SIGNAL rxd : STD_LOGIC; |
SIGNAL txdn : STD_LOGIC; |
SIGNAL txdp : STD_LOGIC; |
SIGNAL txoe : STD_LOGIC; |
|
FUNCTION neg(value : STD_LOGIC) RETURN STD_LOGIC IS |
BEGIN |
RETURN NOT value; |
END neg; |
|
BEGIN |
|
p_rst_neg : PROCESS(rst_neg_ext, clk) |
BEGIN |
IF rst_neg_ext ='0' THEN |
rst_neg_tmp <= '0'; |
rst_neg_int <= '0'; |
ELSIF clk'EVENT AND clk ='1' THEN |
rst_neg_tmp <= rst_neg_ext; |
rst_neg_int <= rst_neg_tmp; |
END IF; |
END PROCESS; |
|
rst_neg_syc <= rst_neg_int; |
|
rxd <= d_pos AND NOT d_neg; |
usb_rst <= usb_rst_phy OR usb_rst_slv; |
|
d_pos <= txdp WHEN txoe = '0' ELSE 'Z'; |
d_neg <= txdn WHEN txoe = '0' ELSE 'Z'; |
|
usb_phy_1 : ENTITY work.usb_phy --Open Cores USB Phy, designed by Rudolf Usselmanns |
GENERIC MAP ( |
usb_rst_det => TRUE |
) |
PORT MAP ( |
clk => clk, -- i |
rst => rst_neg_int, -- i |
phy_tx_mode => DriverMode, -- i |
usb_rst => usb_rst_phy, -- o |
txdp => txdp, -- o |
txdn => txdn, -- o |
txoe => txoe, -- o |
rxd => rxd, -- i |
rxdp => d_pos, -- i |
rxdn => d_neg, -- i |
DataOut_i => Phy_DataOut, -- i (7 downto 0); |
TxValid_i => Phy_TxValid, -- i |
TxReady_o => Phy_TxReady, -- o |
DataIn_o => Phy_DataIn, -- o (7 downto 0); |
RxValid_o => Phy_RxValid, -- o |
RxActive_o => Phy_RxActive, -- o |
RxError_o => Phy_RxError, -- o |
LineState_o => Phy_LineState -- o (1 downto 0) |
); |
|
usb_serial_1 : ENTITY work.usb_serial --Open Cores USB Serial, designed by Joris van Rantwijk |
GENERIC MAP ( |
VENDORID => VENDORID, |
PRODUCTID => PRODUCTID, |
VERSIONBCD => VERSIONBCD, |
HSSUPPORT => FALSE, |
SELFPOWERED => SELFPOWERED, |
RXBUFSIZE_BITS => BUFSIZE_BITS, |
TXBUFSIZE_BITS => BUFSIZE_BITS) |
PORT MAP ( |
clk => clk, -- i 60 MHz UTMI clock. |
reset => neg(rst_neg_int), -- i Synchronous reset; clear buffers and re-attach to the bus. |
usbrst => usb_rst_slv, -- o High for one clock when a reset signal is detected on the USB bus. |
highspeed => OPEN, -- o High when the device is operating (or suspended) in high speed mode. |
suspend => OPEN, -- o High if device suspended, drive asynchronously the UTMI SuspendM pin. |
online => online, -- o High when the device is in the Configured state. |
RXval => RXval, -- o High if a received byte is available on RXDAT. |
RXdat => RXdat, -- o (7 downto 0) - Received data byte, valid if RXVAL is high. |
RXrdy => RXrdy, -- i High if the application is ready to receive the next byte. |
RXlen => RXlen, -- o (RXBUFSIZE_BITS-1 downto 0) - No of bytes available in receive buffer. |
TXval => TXval, -- i High if the application has data to send. |
TXdat => TXdat, -- i (7 downto 0) - Data byte to send, must be valid if TXVAL is high. |
TXrdy => TXrdy, -- o High if the entity is ready to accept the next byte. |
TXroom => TXroom, -- o (TXBUFSIZE_BITS-1 downto 0) - No of free bytes in transmit buffer. |
TXcork => TXcork, -- i Temporarily suppress transmissions at the outgoing endpoint. |
Phy_DataIn => Phy_DataIn, -- i (7 downto 0) |
Phy_DataOut => Phy_DataOut, -- o (7 downto 0) |
Phy_TxValid => Phy_TxValid, -- o |
Phy_TxReady => Phy_TxReady, -- i |
Phy_RxActive => Phy_RxActive, -- i |
Phy_RxValid => Phy_RxValid, -- i |
Phy_RxError => Phy_RxError, -- i |
Phy_LineState => Phy_LineState, -- i (1 downto 0) |
Phy_OPmode => Phy_OPmode, -- o (1 downto 0) Phy_OPmode "01" -> non-driving |
Phy_xcvrselect => OPEN, -- o Phy_OPmode "00" -> normal |
Phy_termselect => FPGA_ready, -- o Phy_OPmode "10" -> disable bit stuffing |
Phy_reset => OPEN -- o ); |
); |
|
END rtl; |
|
/usb_FS_monitor.vhd
0,0 → 1,325
--==========================================================================================================-- |
-- -- |
-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de -- |
-- -- |
-- This source file may be used and distributed without restriction provided that this copyright statement -- |
-- is not removed from the file and that any derivative work contains the original copyright notice and -- |
-- the associated disclaimer. -- |
-- -- |
-- This software is provided ''as is'' and without any express or implied warranties, including, but not -- |
-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event -- |
-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or -- |
-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss -- |
-- of use, data, or profits; or business interruption) however caused and on any theory of liability, -- |
-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way -- |
-- out of the use of this software, even if advised of the possibility of such damage. -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- File name : usb_fs_monitor.vhd -- |
-- Author : Martin Neumann martin@neumanns-mail.de -- |
-- Description : USB bus monitor, logs all USB activities in result.out file. -- |
-- -- |
--==========================================================================================================-- |
-- -- |
-- Change history -- |
-- -- |
-- Version / date Description -- |
-- -- |
-- 01 05 Mar 2011 MN Initial version -- |
-- -- |
-- End change history -- |
--==========================================================================================================-- |
|
LIBRARY IEEE; |
USE IEEE.std_logic_1164.all; |
USE IEEE.std_logic_textio.all; |
USE std.textio.all; |
LIBRARY work; |
USE work.usb_commands.all; |
|
ENTITY usb_fs_monitor IS PORT( |
clk_60MHz : IN STD_LOGIC; |
master_oe : IN STD_LOGIC; |
usb_Dp : IN STD_LOGIC; |
usb_Dn : IN STD_LOGIC); |
END usb_fs_monitor; |
|
ARCHITECTURE SIM OF usb_fs_monitor IS |
TYPE state_mode IS(idle, pid, addr, frame, data, spec, eop); |
SIGNAL usb_state : state_mode; |
SIGNAL usb_dp_sync : STD_LOGIC; |
SIGNAL usb_dn_sync : STD_LOGIC; |
SIGNAL clk_en : STD_LOGIC; |
SIGNAL usb_byte : STD_LOGIC_VECTOR(7 DOWNTO 0); |
SIGNAL byte_valid : STD_LOGIC; |
SIGNAL xfer_busy : STD_LOGIC; |
SIGNAL bit_cntr : NATURAL; |
SIGNAL dll_cntr : NATURAL; |
SIGNAL next_state : state_mode; |
SIGNAL edge_detect : STD_LOGIC; |
SIGNAL usb_dp_s0 : STD_LOGIC; |
SIGNAL usb_dp_s1 : STD_LOGIC; |
SIGNAL usb_dn_s0 : STD_LOGIC; |
SIGNAL usb_dn_s1 : STD_LOGIC; |
SIGNAL usb_dp_last : STD_LOGIC; |
|
BEGIN |
|
--==========================================================================================================-- |
-- Synchronize Inputs -- |
--==========================================================================================================-- |
|
p_usb_dp_sync: process (clk_60MHz) |
begin |
if rising_edge(clk_60MHz) then |
usb_dp_s0 <= usb_dp; |
usb_dp_s1 <= usb_dp_s0; |
if (usb_dp_s0 and usb_dp_s1) ='1' then |
usb_dp_sync <= '1'; |
elsif (usb_dp_s0 OR usb_dp_s1) ='0' then |
usb_dp_sync <= '0'; |
end if; |
end if; |
end process; |
|
p_usb_dn_sync: process (clk_60MHz) |
begin |
if rising_edge(clk_60MHz) then |
usb_dn_s0 <= usb_Dn; |
usb_dn_s1 <= usb_dn_s0; |
if (usb_dn_s0 and usb_dn_s1) ='1' then |
usb_dn_sync <= '1'; |
elsif (usb_dn_s0 OR usb_dn_s1) ='0' then |
usb_dn_sync <= '0'; |
end if; |
end if; |
end process; |
|
p_usb_d_last: process (clk_60MHz) |
begin |
if rising_edge(clk_60MHz) THEN |
usb_dp_last <= usb_dp_sync; |
end if; |
end process; |
|
edge_detect <= usb_dp_last XOR usb_dp_sync; |
|
p_dll_cntr: process (clk_60MHz) |
begin |
if rising_edge(clk_60MHz) then |
if edge_detect ='1' then |
if dll_cntr >= 8 then |
dll_cntr <= 2; -- clk_en detected, now centered in following cycle |
else |
dll_cntr <= 7; -- adjust clk_en to center cycle |
end if; |
elsif dll_cntr >= 8 then -- normal count sequence is 8->4->5->6->7->8->4... |
dll_cntr <= 4; |
else |
dll_cntr <= dll_cntr +1; |
end if; |
end if; |
end process; |
|
clk_en <= '1' WHEN dll_cntr >= 8 ELSE '0'; |
|
--==========================================================================================================-- |
-- Analyse USB Inputs -- |
--==========================================================================================================-- |
|
|
p_xfer_busy : PROCESS |
VARIABLE sync_pattern : STD_LOGIC_VECTOR(7 DOWNTO 0); |
BEGIN |
WAIT UNTIL rising_edge(clk_60MHz) AND clk_en ='1'; |
sync_pattern := sync_pattern(6 DOWNTO 0) & usb_Dp_sync; |
IF sync_pattern = "01010100" THEN |
xfer_busy <= '1'; |
WAIT UNTIL rising_edge(clk_60MHz) AND usb_Dp_sync ='0' AND usb_Dn_sync ='0' AND clk_en ='1'; |
END IF; |
xfer_busy <= '0'; |
END PROCESS; |
|
p_se0_det : PROCESS |
VARIABLE sync_pattern : STD_LOGIC_VECTOR(7 DOWNTO 0); |
VARIABLE se0_lev : BOOLEAN; |
VARIABLE se0_time : Time := 0 ns; |
VARIABLE v_LineWr : line := NULL; |
BEGIN |
WAIT UNTIL rising_edge(clk_60MHz) AND clk_en ='1'; |
IF usb_Dp_sync ='0' AND usb_Dn_sync ='0' THEN |
IF NOT se0_lev THEN |
se0_lev := TRUE; |
se0_time := now; |
END IF; |
ELSE |
IF se0_lev THEN |
se0_time := now - se0_time; |
IF se0_time >= 200 ns THEN |
write (v_LineWr, now, right,15); |
IF se0_time >= 2500 ns THEN |
write (v_LineWr, STRING'(" USB Reset detected for ")); |
ELSE |
write (v_LineWr, STRING'(" USB lines at SE0 for ")); |
END IF; |
write (v_LineWr, se0_time, right,15); |
PrintLine(v_LineWr); |
END IF; |
END IF; |
se0_lev := FALSE; |
END IF; |
END PROCESS; |
|
p_usb_byte : PROCESS(xfer_busy, clk_60MHz, clk_en) |
VARIABLE hold, usb_last : STD_LOGIC; |
VARIABLE ones_cnt : NATURAL; |
BEGIN |
IF xfer_busy ='0' THEN |
usb_last := usb_Dp_sync; |
bit_cntr <= 0; |
ones_cnt := 0; |
byte_valid <= '0'; |
usb_byte <= (OTHERS => 'H'); |
ELSIF rising_edge(clk_60MHz) AND clk_en ='1' THEN |
IF usb_Dp_sync = usb_last THEN |
usb_byte <= '1' & usb_byte(7 DOWNTO 1); |
bit_cntr <= (bit_cntr +1) MOD 8; |
ones_cnt := (ones_cnt +1); |
IF ones_cnt > 6 THEN |
ASSERT FALSE REPORT"Stuffing error" SEVERITY ERROR; |
END IF; |
hold := '0'; |
ELSE |
IF ones_cnt /= 6 THEN |
usb_byte <= '0' & usb_byte(7 DOWNTO 1); |
bit_cntr <= (bit_cntr +1) MOD 8; |
hold := '0'; |
ELSE |
hold := '1'; |
END IF; |
ones_cnt := 0; |
END IF; |
IF bit_cntr=7 THEN |
byte_valid <= NOT hold; |
ELSE |
byte_valid <= '0'; |
END IF; |
usb_last := usb_Dp_sync; |
END IF; |
END PROCESS; |
|
p_usb_state : PROCESS |
BEGIN |
WAIT UNTIL rising_edge(clk_60MHz) AND clk_en ='1'; |
IF xfer_busy ='0' THEN |
usb_state <= idle; |
ELSIF usb_Dp_sync ='0' AND usb_Dn_sync ='0' THEN |
usb_state <= eop; |
ELSE |
usb_state <= next_state; |
END IF; |
END PROCESS; |
|
p_next_state : PROCESS |
VARIABLE address : STD_LOGIC_VECTOR(6 DOWNTO 0); |
VARIABLE endpoint : STD_LOGIC_VECTOR(3 DOWNTO 0); |
VARIABLE frame_no : STD_LOGIC_VECTOR(10 DOWNTO 0); |
VARIABLE byte_cnt : NATURAL; |
VARIABLE v_LineWr : line := NULL; |
BEGIN |
WAIT UNTIL rising_edge(clk_60MHz) AND clk_en ='1'; |
CASE usb_state IS |
WHEN idle => next_state <= pid; |
WHEN pid => IF byte_valid ='1' THEN |
IF usb_byte(3 DOWNTO 0) /= NOT usb_byte(7 DOWNTO 4) THEN |
ASSERT FALSE REPORT"PID error" SEVERITY ERROR; |
END IF; |
write (v_LineWr, now, right,15); |
IF master_oe ='1' THEN |
write (v_LineWr, STRING'(" Send ")); |
ELSE |
write (v_LineWr, STRING'(" Recv ")); |
END IF; |
byte_cnt := 0; |
CASE usb_byte(3 DOWNTO 0) IS |
WHEN x"1" => next_state <= addr; |
write (v_LineWr, STRING'("OUT-Token")); |
WHEN x"9" => next_state <= addr; |
write (v_LineWr, STRING'("IN-Token")); |
WHEN x"5" => next_state <= frame; |
write (v_LineWr, STRING'("SOF-Token")); |
WHEN x"D" => next_state <= addr; |
write (v_LineWr, STRING'("Setup")); |
WHEN x"3" => next_state <= data; |
write (v_LineWr, STRING'("Data0")); |
WHEN x"B" => next_state <= data; |
write (v_LineWr, STRING'("Data1")); |
WHEN x"7" => next_state <= data; |
write (v_LineWr, STRING'("Data2")); |
WHEN x"F" => next_state <= data; |
write (v_LineWr, STRING'("MData")); |
WHEN x"2" => next_state <= idle; |
write (v_LineWr, STRING'("ACK")); |
WHEN x"A" => next_state <= idle; |
write (v_LineWr, STRING'("NAK")); |
WHEN x"E" => next_state <= idle; |
write (v_LineWr, STRING'("STALL")); |
WHEN x"6" => next_state <= idle; |
write (v_LineWr, STRING'("NYET")); |
-- WHEN x"C" => next_state <= spec; |
-- write (v_LineWr, STRING'("Preamble")); |
WHEN x"C" => next_state <= spec; |
write (v_LineWr, STRING'("ERR")); |
WHEN x"8" => next_state <= spec; |
write (v_LineWr, STRING'("Split")); |
WHEN x"4" => next_state <= spec; |
write (v_LineWr, STRING'("Ping")); |
WHEN OTHERS => next_state <= idle; |
ASSERT FALSE REPORT"PID is zero" SEVERITY ERROR; |
END CASE; |
END IF; |
WHEN addr => IF byte_valid ='1' THEN |
address := usb_byte(6 DOWNTO 0); |
endpoint(0) := usb_byte(7); |
WAIT UNTIL rising_edge(clk_60MHz) AND byte_valid ='1' AND clk_en ='1'; |
endpoint(3 DOWNTO 1) := usb_byte(2 DOWNTO 0); |
write (v_LineWr, STRING'(": Address 0x")); |
HexWrite (v_LineWr, address); |
write (v_LineWr, STRING'(", Endpoint 0x")); |
HexWrite (v_LineWr, endpoint); |
write (v_LineWr, STRING'(", CRC5 0x")); |
HexWrite (v_LineWr, usb_byte(7 DOWNTO 3)); |
next_state <= idle; |
END IF; |
WHEN frame =>IF byte_valid ='1' THEN |
frame_no(7 DOWNTO 0) := usb_byte; |
WAIT UNTIL rising_edge(clk_60MHz) AND byte_valid ='1' AND clk_en ='1'; |
frame_no(10 DOWNTO 8) := usb_byte(2 DOWNTO 0); |
write (v_LineWr, STRING'(": Frame No 0x")); |
HexWrite (v_LineWr, frame_no); |
write (v_LineWr, STRING'(", CRC5 0x")); |
HexWrite (v_LineWr, usb_byte(7 DOWNTO 3)); |
next_state <= idle; |
END IF; |
WHEN data => WAIT UNTIL rising_edge(clk_60MHz) AND byte_valid ='1' AND clk_en ='1'; |
byte_cnt := byte_cnt +1; |
IF byte_cnt = 17 THEN |
PrintLine(v_LineWr); |
write (v_LineWr, now, right,15); |
write (v_LineWr, STRING'(" .....")); |
byte_cnt := 1; |
END IF; |
write (v_LineWr, STRING'(" 0x")); |
HexWrite (v_LineWr, usb_byte); |
WHEN eop => next_state <= idle; |
PrintLine(v_LineWr); |
WHEN OTHERS => next_state <= idle; |
END CASE; |
END PROCESS; |
|
usb_busy <= usb_state /= idle; -- global signal, used in usb_commands -- |
|
END SIM; |
|
--======================================== END OF usb_fs_monitor.vhd =======================================-- |
/usb_test.do
0,0 → 1,80
################################################################################################ |
# This tcl-file is for usage with Model Sim, adopt this information to your simulator needs MN # |
################################################################################################ |
|
echo "===>" |
echo "===> Recompiling Sources" |
echo "===>" |
|
if {[file exists work]} { vdel -lib work -all } |
vlib work |
vmap work D:/Design/My_USB_Controller/work |
|
# Open Cores USB Phy, designed by Rudolf Usselmanns and translated to VHDL by Martin Neumann |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_phy/usb_rx_phy_60MHz.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_phy/usb_tx_phy.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_phy/usb_phy.vhdl |
|
# Open Cores USB Serial, designed by Joris van Rantwijk |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_serial/usb_pkg.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_serial/usb_init.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_serial/usb_control.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_serial/usb_transact.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_serial/usb_packet.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_serial/usb_serial.vhdl |
vcom -93 -work work D:/Design/My_USB_Controller/Source/usb_fs_slave.vhdl |
|
# The USB FS test bench files |
vcom -93 -work work D:/Design/My_USB_Controller/Testbench/usb_commands.vhd |
vcom -93 -work work D:/Design/My_USB_Controller/Testbench/usb_stimuli.vhd |
vcom -93 -work work D:/Design/My_usb_Controller/Testbench/usb_fs_monitor.vhd |
vcom -93 -work work D:/Design/My_usb_Controller/Testbench/usb_fs_master.vhd |
vcom -93 -work work D:/Design/My_USB_Controller/Testbench/usb_tb.vhd |
|
echo "===>" |
echo "===> Start Simulation" |
echo "===>" |
vsim -quiet usb_tb |
|
#view source |
view wave |
configure wave -signalnamewidth 1 |
|
add wave -noupdate -divider {USB_Monitor} |
add wave -noupdate -format Literal -radix decimal /usb_tb/usb_fs_master/test_case/t_no |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_master/usb_fs_monitor/* |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_master/stimuli_bit |
|
add wave -noupdate -divider {USB_MASTER} |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_master/* |
|
add wave -noupdate -divider {USB_STIMULI} |
add wave -noupdate -format Literal -radix decimal /usb_tb/usb_fs_master/test_case/t_no |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_master/test_case/* |
|
add wave -noupdate -divider {USB_PHY} |
add wave -noupdate -format Literal -radix decimal /usb_tb/usb_fs_master/test_case/t_no |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_phy_1/* |
|
# add wave -noupdate -divider {USB_RX_PHY} |
# add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_phy_1/i_rx_phy/* |
# |
# add wave -noupdate -divider |
# add wave -noupdate -divider {USB_TX_PHY} |
# add wave -noupdate -format Literal -radix decimal /usb_tb/usb_fs_master/test_case/t_no |
# add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_phy_1/i_tx_phy/* |
add wave -noupdate -divider {USB_SERIAL} |
add wave -noupdate -format Literal -radix decimal /usb_tb/usb_fs_master/test_case/t_no |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_serial_1/* |
add wave -noupdate -divider {USB_S-INIT} |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_serial_1/usb_init_inst/* |
add wave -noupdate -divider {USB_S-PACKET} |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_serial_1/usb_packet_inst/* |
add wave -noupdate -divider {USB_S-TRANSACT} |
add wave -noupdate -format Literal -radix decimal /usb_tb/usb_fs_master/test_case/t_no |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_serial_1/usb_transact_inst/* |
add wave -noupdate -divider {USB_S-CONTROL} |
add wave -noupdate -format Logic -radix hexadecimal /usb_tb/usb_fs_slave_1/usb_serial_1/usb_control_inst/* |
|
onbreak {resume} |
run -all |
/USB FS TestBench.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
USB FS TestBench.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: USB_Commands.vhd
===================================================================
--- USB_Commands.vhd (nonexistent)
+++ USB_Commands.vhd (revision 2)
@@ -0,0 +1,509 @@
+--==========================================================================================================--
+-- --
+-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de --
+-- --
+-- This source file may be used and distributed without restriction provided that this copyright statement --
+-- is not removed from the file and that any derivative work contains the original copyright notice and --
+-- the associated disclaimer. --
+-- --
+-- This software is provided ''as is'' and without any express or implied warranties, including, but not --
+-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event --
+-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or --
+-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss --
+-- of use, data, or profits; or business interruption) however caused and on any theory of liability, --
+-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way --
+-- out of the use of this software, even if advised of the possibility of such damage. --
+-- --
+--==========================================================================================================--
+-- --
+-- File name : usb_commands.vhd --
+-- Author : Martin Neumann martin@neumanns-mail.de --
+-- Description : Defines, functions and procedures for the usb_Stimuli.vhd file - the USB data source for --
+-- the test bench file. --
+-- --
+--==========================================================================================================--
+-- --
+-- Change history --
+-- --
+-- Version / date Description --
+-- --
+-- 01 05 Mar 2011 MN Initial version --
+-- --
+-- End change history --
+--==========================================================================================================--
+-- --
+-- USB control concept --
+-- ------------------- --
+-- The usb signal controls the usb command execution and its proper timing : --
+-- --
+-- Each command in the test case file 'usb_stimuli.vhd' is a procedure call with an output signal 'usb'. -- --
+-- Its states (of type usb_action) control the correct timing sequence of the process 'p_stimuli_bit' in --
+-- the file'usb_master'. This procedure sets the signal usb first to any one of the active states, then --
+-- after completion to inactive (idle). --
+-- --
+--==========================================================================================================--
+-- --
+-- Syntax Examples --
+-- --
+-- Procedure Function, Parameters --
+-- --
+-- list (T_No, 30); Test No listed in transcript and report file --
+-- List ("Any Text Message "); Message any text --
+-- Setup (usb, X"00", X"0"); usb setup: device address, endp address (+CRC5) --
+-- send_D0 (usb, (X"10",X"46",X"11",X"47", --
+-- X"12",X"48",X"13",X"49")); usb write data0 : byte string (+CRC16) --
+-- send_D1 (usb, (X"20",X"36",X"21",X"37", --
+-- X"22",X"38",X"23",X"39")); usb write data1 : byte string (+CRC16) --
+-- send_ACK (usb); usb ACK Handshake --
+-- send_NAK (usb); usb NAK Handshake --
+-- send_STALL(usb); usb Stall Handshake --
+-- send_NYET (usb); usb NYET (No Response Yet) Handshake --
+-- wait_slv (usb); wait until transfer of USB-slave completed --
+-- --
+--==========================================================================================================--
+
+LIBRARY IEEE;
+ USE IEEE.std_logic_1164.all;
+ USE IEEE.std_logic_textio.all;
+ USE IEEE.std_logic_arith.all;
+ USE IEEE.std_logic_unsigned.all;
+ USE std.textio.all;
+
+PACKAGE usb_commands IS
+
+--==========================================================================================================--
+
+ TYPE usb_action IS (idle, sync, pid, addr, rd, wr_odd, wr_even, wr_crc5, wr_crc16, reset, send_eop, recv_eop);
+ TYPE byte_array IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
+
+ SIGNAL usb_status : usb_action;
+ SIGNAL usb_busy : BOOLEAN := FALSE;
+ SHARED VARIABLE ok : BOOLEAN;
+ SHARED VARIABLE sv_usb_byte : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SHARED VARIABLE sv_usb_addr : STD_LOGIC_VECTOR(10 DOWNTO 0);
+ SHARED VARIABLE sv_read_loop : BOOLEAN := FALSE;
+ FILE screen : TEXT OPEN WRITE_MODE IS "STD_OUTPUT";
+ FILE outpdata : TEXT OPEN WRITE_MODE IS "Result.out";
+
+
+ PROCEDURE list(message : IN STRING);
+ PROCEDURE list(SIGNAL no_out : OUT NATURAL; no_in : IN NATURAL);
+
+ PROCEDURE end_of_test(stop : IN BOOLEAN := TRUE);
+
+--==========================================================================================================--
+
+ PROCEDURE send_ACK (SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_NAK (SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_STALL(SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_NYET (SIGNAL usb : OUT usb_action);
+
+ PROCEDURE handshake(SIGNAL usb : OUT usb_action; CONSTANT pid_val : IN std_logic_vector(3 DOWNTO 0));
+
+ PROCEDURE setup(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT device_addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ CONSTANT endp_addr : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ );
+
+ PROCEDURE in_token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT device_addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ CONSTANT endp_addr : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ );
+
+ PROCEDURE out_token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT device_addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ CONSTANT endp_addr : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ );
+
+ PROCEDURE sof_token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT frame_no : IN STD_LOGIC_VECTOR(11 DOWNTO 0)
+ );
+
+ PROCEDURE token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT pid_val : IN std_logic_vector(3 DOWNTO 0);
+ CONSTANT token_val : IN STD_LOGIC_VECTOR(10 DOWNTO 0)
+ );
+
+ PROCEDURE send_d0(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array);
+ PROCEDURE send_D0(SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_d1(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array);
+ PROCEDURE send_D1(SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_d2(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array);
+ PROCEDURE send_D2(SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_dm(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array);
+ PROCEDURE send_Dm(SIGNAL usb : OUT usb_action);
+
+ PROCEDURE send_dx(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT pid_val : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
+ CONSTANT wr_data : IN byte_array
+ );
+ PROCEDURE send_dx(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT pid_val : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ );
+
+ PROCEDURE send_RES(SIGNAL usb : OUT usb_action);
+
+ PROCEDURE wait_slv(SIGNAL usb : OUT usb_action);
+
+--==========================================================================================================--
+ -- internal functions and procedures --
+
+ FUNCTION to_01x(d : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
+
+ FUNCTION hex_to_string(D: STD_LOGIC_VECTOR) RETURN STRING;
+
+ PROCEDURE HexWrite( VARIABLE L : INOUT LINE;
+ CONSTANT VALUE : IN STD_LOGIC_VECTOR;
+ CONSTANT JUSTIFIED: IN SIDE := right;
+ CONSTANT FIELD : IN WIDTH := 0);
+
+ PROCEDURE PrintLine (VARIABLE v_Line : INOUT Line);
+
+ END usb_commands;
+
+--==========================================================================================================--
+
+ PACKAGE BODY usb_commands IS
+
+ FUNCTION to_01x(d : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE result : STD_LOGIC_VECTOR (d'RANGE);
+ BEGIN
+ FOR i IN d'RANGE LOOP
+ IF d(i) ='0' OR d(i) ='L' THEN --reduce data to 0, 1 or X
+ result(i) := '0';
+ ELSIF d(i) ='1' OR d(i) ='H' THEN
+ result(i) := '1';
+ ELSE
+ result(i) := 'X';
+ END IF;
+ END LOOP;
+ RETURN result;
+ END to_01x;
+
+--==========================================================================================================--
+
+ FUNCTION hex_to_string(d: STD_LOGIC_VECTOR) RETURN STRING is
+ -- vector is padded with leadin '0's if not modula 4 --
+ VARIABLE j, k, p : INTEGER;
+ VARIABLE d_ext : STD_LOGIC_VECTOR(1 to ((d'LENGTH +3)/4)*4);
+ VARIABLE nibble : STD_LOGIC_VECTOR(1 to 4);
+ VARIABLE result : STRING(1 TO (d'HIGH +4 - d'LOW)/4);
+ VARIABLE hex_val : STRING(1 TO 16) := "0123456789ABCDEF";
+ TYPE hex_type IS ARRAY (1 TO 16) OF STD_LOGIC_VECTOR(0 to 3);
+ CONSTANT hex_tbl : hex_type :=
+ ("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111");
+ BEGIN
+ j := d_ext'LENGTH - d'LENGTH;
+ IF j = 0 THEN
+ d_ext := to_01x(d);
+ ELSE
+ d_ext(1 TO j) := (OTHERS =>'0');
+ d_ext(j +1 TO d_ext'LENGTH) := to_01x(d);
+ END IF;
+ j := 1;
+ k := 1;
+ FOR i IN d_ext'RANGE LOOP
+ nibble(j) := d_ext(i);
+ IF j = 4 THEN --data nibble is ...
+ result(k) := 'X'; -- ... default X ...
+ HEX_CHAR: for h in 1 to 16 LOOP
+ IF nibble = hex_tbl(h) THEN
+ result(k) := hex_val(h); -- ... or 1 to F
+ EXIT HEX_CHAR;
+ END IF;
+ END LOOP;
+ k := k+1;
+ END IF;
+ j := (j MOD 4) +1;
+ END LOOP;
+ RETURN result;
+ END;
+
+ PROCEDURE HexWrite( VARIABLE L : INOUT LINE;
+ CONSTANT VALUE : IN STD_LOGIC_VECTOR;
+ CONSTANT JUSTIFIED: IN SIDE := right;
+ CONSTANT FIELD : IN WIDTH := 0) IS
+ BEGIN
+ write (L, STRING'(hex_to_string(VALUE)), JUSTIFIED, FIELD);
+ END;
+
+--==========================================================================================================--
+
+ PROCEDURE list(message : IN STRING) IS
+ VARIABLE v_Line : line := NULL;
+ BEGIN
+ WAIT FOR 0 ns;
+ write(v_Line, " " & Message);
+ write(Screen, v_Line.all & LF);
+ writeline(OutpData, v_Line);
+ END list;
+
+ PROCEDURE list(SIGNAL no_out : OUT NATURAL; no_in : IN NATURAL) IS
+ VARIABLE v_Line : line := NULL;
+ BEGIN
+ IF usb_busy THEN -- set in usb_monitor
+ WAIT UNTIL NOT usb_busy;
+ END IF;
+ write(v_Line, STRING'("Test_No "), right, 25);
+ write(v_Line, no_in);
+ PrintLine(v_Line);
+ no_out <= no_in;
+ END list;
+
+--==========================================================================================================--
+
+ PROCEDURE end_of_test(stop : IN BOOLEAN := TRUE) IS
+ BEGIN
+ IF usb_busy THEN -- set in usb_monitor
+ WAIT UNTIL NOT usb_busy;
+ END IF;
+ ASSERT stop = FALSE REPORT"End of Test" SEVERITY FAILURE;
+ END end_of_test;
+
+--==========================================================================================================--
+
+ PROCEDURE PrintLine(VARIABLE v_Line : INOUT Line) IS
+ BEGIN
+ IF v_Line /= NULL THEN
+ write(Screen, v_Line.all & LF);
+ END IF;
+ writeline(OutpData, v_Line);
+ END PrintLine;
+
+--==========================================================================================================--
+
+ PROCEDURE send_ACK(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ handshake(usb, X"2");
+ END send_ACK;
+
+ PROCEDURE send_NAK(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ handshake(usb, X"A");
+ END send_NAK;
+
+ PROCEDURE send_STALL(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ handshake(usb, X"E");
+ END send_STALL;
+
+ PROCEDURE send_NYET(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ handshake(usb, X"6");
+ END send_NYET;
+
+ PROCEDURE handshake(SIGNAL usb : OUT usb_action; CONSTANT pid_val : IN std_logic_vector(3 DOWNTO 0)) IS
+ BEGIN
+ usb <= sync;
+ WAIT UNTIL usb_status = sync;
+ WAIT UNTIL usb_status = idle;
+ sv_usb_byte := NOT pid_val & pid_val;
+ usb <= pid;
+ WAIT UNTIL usb_status = pid;
+ WAIT UNTIL usb_status = idle;
+ usb <= send_eop;
+ WAIT UNTIL usb_status = send_eop;
+ WAIT UNTIL usb_status = idle;
+ usb <= idle;
+ END handshake;
+
+--==========================================================================================================--
+
+ PROCEDURE setup(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT device_addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ CONSTANT endp_addr : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ )IS
+ BEGIN
+ ASSERT device_addr(7) = '0' REPORT" Token device address out of range 0 to 127" SEVERITY FAILURE;
+ token(usb, X"D", endp_addr & device_addr(6 DOWNTO 0));
+ END setup;
+
+ PROCEDURE in_token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT device_addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ CONSTANT endp_addr : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ )IS
+ BEGIN
+ ASSERT device_addr(7) = '0' REPORT" Token device address out of range 0 to 127" SEVERITY FAILURE;
+ token(usb, X"9", endp_addr & device_addr(6 DOWNTO 0));
+ END in_token;
+
+ PROCEDURE out_token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT device_addr : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
+ CONSTANT endp_addr : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ )IS
+ BEGIN
+ ASSERT device_addr(7) = '0' REPORT" Token device address out of range 0 to 127" SEVERITY FAILURE;
+ token(usb, X"1", endp_addr & device_addr(6 DOWNTO 0));
+ END out_token;
+
+ PROCEDURE sof_token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT frame_no : IN STD_LOGIC_VECTOR(11 DOWNTO 0)
+ )IS
+ BEGIN
+ token(usb, X"5", frame_no(10 DOWNTO 0));
+ END sof_token;
+
+ PROCEDURE token(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT pid_val : IN std_logic_vector(3 DOWNTO 0);
+ CONSTANT token_val : IN STD_LOGIC_VECTOR(10 DOWNTO 0)
+ )IS
+ BEGIN
+ usb <= sync;
+ WAIT UNTIL usb_status = sync;
+ WAIT UNTIL usb_status = idle;
+ sv_usb_byte := NOT pid_val & pid_val;
+ usb <= pid;
+ WAIT UNTIL usb_status = pid;
+ WAIT UNTIL usb_status = idle;
+ sv_usb_addr := token_val;
+ usb <= addr;
+ WAIT UNTIL usb_status = addr;
+ WAIT UNTIL usb_status = idle;
+ usb <= wr_crc5;
+ WAIT UNTIL usb_status = wr_crc5;
+ WAIT UNTIL usb_status = idle;
+ usb <= send_eop;
+ WAIT UNTIL usb_status = send_eop;
+ WAIT UNTIL usb_status = idle;
+ usb <= idle;
+ END token;
+
+----==========================================================================================================--
+
+ PROCEDURE send_D0(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array) IS
+ BEGIN
+ send_dx(usb, X"3", wr_data);
+ END send_D0;
+
+ PROCEDURE send_D1(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array) IS
+ BEGIN
+ send_dx(usb, X"B", wr_data);
+ END send_D1;
+
+ PROCEDURE send_D2(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array) IS
+ BEGIN
+ send_dx(usb, X"7", wr_data);
+ END send_D2;
+
+ PROCEDURE send_Dm(SIGNAL usb : OUT usb_action; CONSTANT wr_data : IN byte_array) IS
+ BEGIN
+ send_dx(usb, X"F", wr_data);
+ END send_Dm;
+
+ PROCEDURE send_dx(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT pid_val : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
+ CONSTANT wr_data : IN byte_array
+ )IS
+ BEGIN
+ usb <= sync;
+ WAIT UNTIL usb_status = sync;
+ WAIT UNTIL usb_status = idle;
+ sv_usb_byte := NOT pid_val & pid_val;
+ usb <= pid;
+ WAIT UNTIL usb_status = pid;
+ WAIT UNTIL usb_status = idle;
+ FOR i in 0 TO wr_data'LENGTH -1 LOOP
+ sv_usb_byte := wr_data(i);
+ IF i MOD 2 = 0 THEN
+ usb <= wr_even;
+ WAIT UNTIL usb_status = wr_even;
+ ELSE
+ usb <= wr_odd;
+ WAIT UNTIL usb_status = wr_odd;
+ END IF;
+ WAIT UNTIL usb_status = idle;
+ END LOOP;
+ usb <= wr_crc16;
+ WAIT UNTIL usb_status = wr_crc16;
+ WAIT UNTIL usb_status = idle;
+ usb <= send_eop;
+ WAIT UNTIL usb_status = send_eop;
+ WAIT UNTIL usb_status = idle;
+ usb <= idle;
+ END send_dx;
+
+----==========================================================================================================--
+
+ PROCEDURE send_D0(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ send_dx(usb, X"3");
+ END send_D0;
+
+ PROCEDURE send_D1(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ send_dx(usb, X"B");
+ END send_D1;
+
+ PROCEDURE send_D2(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ send_dx(usb, X"7");
+ END send_D2;
+
+ PROCEDURE send_Dm(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ send_dx(usb, X"F");
+ END send_Dm;
+
+ PROCEDURE send_dx(
+ SIGNAL usb : OUT usb_action;
+ CONSTANT pid_val : IN STD_LOGIC_VECTOR(3 DOWNTO 0)
+ )IS
+ BEGIN
+ usb <= sync;
+ WAIT UNTIL usb_status = sync;
+ WAIT UNTIL usb_status = idle;
+ sv_usb_byte := NOT pid_val & pid_val;
+ usb <= pid;
+ WAIT UNTIL usb_status = pid;
+ WAIT UNTIL usb_status = idle;
+ usb <= wr_crc16;
+ WAIT UNTIL usb_status = wr_crc16;
+ WAIT UNTIL usb_status = idle;
+ usb <= send_eop;
+ WAIT UNTIL usb_status = send_eop;
+ WAIT UNTIL usb_status = idle;
+ usb <= idle;
+ END send_dx;
+
+----==========================================================================================================--
+
+ PROCEDURE send_RES(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ usb <= reset;
+ WAIT UNTIL usb_status = reset;
+ WAIT UNTIL usb_status = idle;
+ usb <= idle;
+ END send_RES;
+
+----==========================================================================================================--
+
+ PROCEDURE wait_slv(SIGNAL usb : OUT usb_action) IS
+ BEGIN
+ usb <= recv_eop;
+ WAIT UNTIL usb_status = recv_eop;
+ WAIT UNTIL usb_status = idle;
+ usb <= idle;
+ END wait_slv;
+
+----==========================================================================================================--
+END usb_commands;
Index: usb_tc_01.vhdl
===================================================================
--- usb_tc_01.vhdl (nonexistent)
+++ usb_tc_01.vhdl (revision 2)
@@ -0,0 +1,185 @@
+--==========================================================================================================--
+-- --
+-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de --
+-- --
+-- This source file may be used and distributed without restriction provided that this copyright statement --
+-- is not removed from the file and that any derivative work contains the original copyright notice and --
+-- the associated disclaimer. --
+-- --
+-- This software is provided ''as is'' and without any express or implied warranties, including, but not --
+-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event --
+-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or --
+-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss --
+-- of use, data, or profits; or business interruption) however caused and on any theory of liability, --
+-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way --
+-- out of the use of this software, even if advised of the possibility of such damage. --
+-- --
+--==========================================================================================================--
+-- --
+-- File name : USB_tc_01.vhd --
+-- Author : Martin Neumann martin@neumanns-mail.de --
+-- Description : Copy and rename this file to usb_stimuli.vhd before running a new simulation! --
+-- --
+--==========================================================================================================--
+-- --
+-- Change history --
+-- --
+-- Version / date Description --
+-- --
+-- 01 05 Mar 2011 MN Initial version --
+-- --
+-- End change history --
+--==========================================================================================================--
+
+LIBRARY work, IEEE;
+ USE IEEE.std_logic_1164.ALL;
+ USE work.usb_commands.ALL;
+
+ENTITY USB_Stimuli IS PORT(
+ -- Test Control Interface --
+ USB : OUT usb_action;
+ t_no : OUT NATURAL;
+ -- Application Interface
+ clk : IN STD_LOGIC;
+ rst_neg_ext : OUT STD_LOGIC;
+ RXval : IN STD_LOGIC; -- RX bytes available
+ RXdat : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Received data bytes
+ RXrdy : OUT STD_LOGIC := '0'; -- Application ready for data
+ RXlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Number of bytes available
+ TXval : OUT STD_LOGIC := '0'; -- Application has valid data
+ TXdat : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data byte to send
+ TXrdy : IN STD_LOGIC; -- Entity is ready for data
+ TXroom : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- No of free bytes in TX
+ TXcork : OUT STD_LOGIC := '1'); -- Hold TX transmission
+END USB_Stimuli;
+
+ARCHITECTURE sim OF usb_stimuli IS
+
+--==========================================================================================================--
+
+ -- Get discritor (control transfer to endp 0) is a Setup transaction of 8 data0 bytes:
+ -- **************************************************************************
+ -- |Setup Packet |Bytes | Value | Details | CRC5 : Init to "11111"
+ -- +-----------------+------+-------+---------------------------------------+ Ignor Sync
+ -- |Setup-PID | 1 | 2Dh | | Ignor PIP
+ -- +-----------------+------+-------+---------------------------------------+ Process Byte 1 + 2
+ -- |Addr EndP CRC-5 | 2 | 1000h | | Send inverted CRC with MSB first
+ -- | | | | .........00000000 Address (7bit) | CRC-checker expects "01100"
+ -- | | | | .....0000........ EndP Ar (4bit) |
+ -- | | | | 00010............ CRC (5bit) |
+ -- **************************************************************************
+ -- **************************************************************************
+ -- |Data0 Packet |Bytes | Value | Details | CRC16 : Init to "1111111111111111"
+ -- +-----------------+------+-------+---------------------------------------+ Ignor Sync
+ -- |Data0-PID | 1 | C3h | | Process all Bytes
+ -- +-----------------+------+-------+---------------------------------------+ Send inverted CRC with MSB first
+ -- |bmRequestType | 1 | 81h | | CRC-checker expects "1000000000001101";
+ -- | | | |Recipient ...00001 Interface |
+ -- | | | |Type .00..... Standard |
+ -- | | | |Direction 1....... Device to Host |
+ -- +-----------------+------+-------+---------------------------------------+
+ -- |bRequest | 1 | 06h | Get Descriptor |
+ -- +-----------------+------+-------+---------------------------------------+
+ -- |wValue LowByte | 1 | 00h | |
+ -- +-----------------+------+-------+ Report Descriptor |
+ -- |wValue HiByte | 1 | 22h | |
+ -- +-----------------+------+-------+---------------------------------------+
+ -- |wIndex | 2 | 0003h | Interface |
+ -- +-----------------+------+-------+---------------------------------------+
+ -- |wLength | 2 | 0072h | Descriptor Length |
+ -- +-----------------+------+-------+---------------------------------------+
+ -- |CRC-16 | 2 | BBCCh | CRC-Check |
+ -- **************************************************************************
+
+BEGIN
+
+ p_stimuli_data : PROCESS
+ BEGIN
+ list(T_No, 10);
+ rst_neg_ext <= '0';
+ WAIT FOR 301 ns;
+ rst_neg_ext <= '1';
+ WAIT FOR 40 ns;
+ list("Reset completed");
+ list(T_No, 20);
+ setup(usb, X"00", X"0"); --Send Setup to addr 0, endp 0
+ -- send_D0(usb,(X"01",X"FF",X"FF",X"80",X"FE",X"00",X"02",X"00")); --Stuffing test pattern
+ -- send_D0(usb,(X"80",X"06",X"00",X"01",X"00",X"00",X"40",X"00")); --Mouse in Example No4
+ send_D0(usb,(X"80",X"06",X"00",X"01",X"00",X"00",X"12",X"00")); --Send 'Get Device descriptor'
+ --=========================================--
+ -- Send 'Get Device descriptor' Data Field --
+ --=========================================--
+ -- Byte 0-1 0x80, 0x06 Get Discriptor --
+ -- 2 0x00 Descr.Index=0 --
+ -- 3 0x01 Descr.Type=Device --
+ -- 4-5 0x00, 0x00 Zero --
+ -- 6-7 0x12, 0x00 Byte Cnt (18 byte) --
+ --=========================================--
+ wait_slv(usb); --Recv ACK
+ list(T_No, 30);
+ in_token(usb, X"00", X"0"); --Send IN-Token
+ wait_slv(usb); --Recv discriptor data
+ --Recv 12 01 00 02 00 00 00 40 FE 13 00 1E 00 00 00 00 00 01 Mouse in Example No4
+ --===========================================================--
+ --Recv 12 01 10 01 02 00 00 40 9A FB 9A FB 20 00 00 00 00 01 --
+ --======+==============+========+============================--
+ -- 0 | bLength | 18 | Valid Length --
+ -- 1 | bDiscType | 1 | Device --
+ -- 2-3 | bcd USB | 0x0110 | Spec Version --
+ -- 4 | bDeviceClass | 0x02 | Communications --
+ -- 5 | bDevSubClass | 0x00 | none --
+ -- 6 | bDevProtocol | 0x00 | none --
+ -- 7 | bMaxPacket | 0x40 | 64 byte --
+ -- 8-9 | idVendor | 0xFB9A | ? --
+ -- A-B | idProduct | 0xFB9A | ? --
+ -- C-D | bcdDevice | 0x0020 | ? --
+ -- E | iManufact. | 0x00 | Index to Manufact. (none) --
+ -- F | iProduct | 0x00 | Index to ProdString (none) --
+ -- 10 | iSerialNo | 0x00 | Index to SerNo (none) --
+ -- 11 | bNumConfig | 0x01 | 1 Configuration --
+ --===========================================================--
+ send_ack(usb); --Send ACK
+ --Once the device descriptor is sent, a status transaction follows.
+ list(T_No, 35);
+ setup(usb, X"00", X"0"); --Send Setup to addr 0, endp 0
+ send_D0(usb,(X"80",X"00",X"00",X"00",X"00",X"00",X"02",X"00")); --Send 'Get Status' (Device, 2 byte)
+ wait_slv(usb);
+ in_token(usb, X"00", X"0");
+ wait_slv(usb); --get 2 bytes
+ send_ACK(usb); --Send ACK
+
+ --If the transactions were successful, the host will send a zero length packet indicating the overall
+ --transaction was successful. The function then replies to this zero length packet indicating its status:
+ list(T_No, 40);
+ out_token(usb, X"00", X"0");
+ send_D0(usb); --Send Zero Data
+ wait_slv(usb); --Recv ACK
+
+ --Set Address is used during enumeration to assign a unique address to the USB device. The address is
+ --specified in wValue and can only be a maximum of 127. This request is unique in that the device does
+ --not set its address until after the completion of the status stage (send an IN Token, expect zero data).
+ list(T_No, 50);
+ setup(usb, X"00", X"0"); --Send Setup to addr 0, endp 0
+ send_D0(usb,(X"00",X"05",X"03",X"00",X"00",X"00",X"00",X"00")); --Send 'Set Address' to 0x0003
+ wait_slv(usb); --Recv ACK
+ in_token(usb, X"00", X"0"); --Send IN packet
+ wait_slv(usb); --Recv Data0 zero Length
+ send_ack(usb); --Send ACK
+
+ --Now we may use the new address :
+ list(T_No, 60);
+ setup(usb, X"03", X"0"); --Send Setup to addr 3, endp 0
+ send_D0(usb,(X"80",X"06",X"00",X"01",X"00",X"00",X"12",X"00")); --Send 'Get Device descriptor'
+ wait_slv(usb); --Recv ACK
+ list(T_No, 70);
+ in_token(usb, X"03", X"0"); --Send IN-Token
+ wait_slv(usb);
+ send_ack(usb); --Send ACK
+ IF usb_busy THEN -- usb_usy is set in usb_monitor
+ WAIT UNTIL NOT usb_busy;
+ END IF;
+ ASSERT FALSE REPORT"End of Test" SEVERITY FAILURE;
+ END PROCESS;
+
+END sim;
+
Index: USB_FS_master.vhd
===================================================================
--- USB_FS_master.vhd (nonexistent)
+++ USB_FS_master.vhd (revision 2)
@@ -0,0 +1,280 @@
+--==========================================================================================================--
+-- --
+-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de --
+-- --
+-- This source file may be used and distributed without restriction provided that this copyright statement --
+-- is not removed from the file and that any derivative work contains the original copyright notice and --
+-- the associated disclaimer. --
+-- --
+-- This software is provided ''as is'' and without any express or implied warranties, including, but not --
+-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event --
+-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or --
+-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss --
+-- of use, data, or profits; or business interruption) however caused and on any theory of liability, --
+-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way --
+-- out of the use of this software, even if advised of the possibility of such damage. --
+-- --
+--==========================================================================================================--
+-- --
+-- File name : usb_fs_master.vhd --
+-- Author : Martin Neumann martin@neumanns-mail.de --
+-- Description : USB FS Master, used with usb_Stimuli.vhd data source and usb_fs_monitor.vhd. --
+-- --
+--==========================================================================================================--
+-- --
+-- Change history --
+-- --
+-- Version / date Description --
+-- --
+-- 01 05 Mar 2011 MN Initial version --
+-- --
+-- End change history --
+--==========================================================================================================--
+-- --
+-- http://en.wikipedia.org/wiki/Universal_Serial_Bus --
+-- USB data is transmitted by toggling the data lines between the J state and the opposite K state. USB --
+-- encodes data using the NRZI convention; a 0 bit is transmitted by toggling the data lines from J to K --
+-- or vice-versa, while a 1 bit is transmitted by leaving the data lines as-is. --
+-- To ensure a minimum density of signal transitions, USB uses bit stuffing - an extra 0 bit is inserted --
+-- into the data stream after any appearance of six consecutive 1 bits. Seven consecutive '1's are always --
+-- an error. --
+-- A USB packet begins with an 8-bit synchronization sequence '00000001'. That is, after the initial idle --
+-- state J, the data lines toggle KJKJKJKK. The final 1 bit (repeated K state) marks the end of the sync --
+-- pattern and the beginning of the USB frame. For high bandwidth USB, the packet begins with a 32-bit --
+-- synchronization sequence. --
+-- A USB packet's end, called EOP (end-of-packet), is indicated by the transmitter driving 2 bit times of --
+-- SE0 (D+ and D- both below max) and 1 bit time of J state. After this, the transmitter ceases to drive --
+-- the D+/D- lines and the aforementioned pull up resistors hold it in the J (idle) state. Sometimes skew --
+-- due to hubs can add as much as one bit time before the SE0 of the end of packet. --
+-- This extra bit can result in a "bit stuff violation" if the six bits before it in the CRC are '1's. --
+-- This bit should be ignored by receiver. --
+-- A USB bus is reset using a prolonged (10 to 20 milliseconds) SE0 signal. --
+-- --
+--==========================================================================================================--
+
+LIBRARY IEEE;
+ USE IEEE.std_logic_1164.all;
+ USE IEEE.std_logic_textio.all;
+ USE std.textio.all;
+
+LIBRARY work;
+ USE work.usb_commands.all;
+
+ENTITY usb_fs_master IS PORT(
+ -- USB Interface --
+ usb_clk : IN STD_LOGIC;
+ int_clk : IN STD_LOGIC;
+ rst_neg_ext : OUT STD_LOGIC;
+ usb_Dp : INOUT STD_LOGIC;
+ usb_Dn : INOUT STD_LOGIC;
+ -- Application Interface
+ RXval : IN STD_LOGIC; -- RX bytes available
+ RXdat : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Received data bytes
+ RXrdy : OUT STD_LOGIC := '0'; -- Application ready for data
+ RXlen : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Number of bytes available
+ TXval : OUT STD_LOGIC := '0'; -- Application has valid data
+ TXdat : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- Data byte to send
+ TXrdy : IN STD_LOGIC; -- Entity is ready for data
+ TXroom : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- No of free bytes in TX
+ TXcork : OUT STD_LOGIC := '1'); -- Hold TX transmission
+END usb_fs_master;
+
+ARCHITECTURE SIM OF usb_fs_master IS
+
+ SIGNAL T_No : NATURAL;
+ SIGNAL crc_16 : STD_LOGIC_VECTOR(15 DOWNTO 0);
+ SIGNAL crc_5 : STD_LOGIC_VECTOR( 4 DOWNTO 0);
+ SIGNAL master_oe : STD_LOGIC;
+ SIGNAL stimuli_bit : STD_LOGIC := 'Z';
+ SIGNAL stop_sim : BOOLEAN := false;
+ SIGNAL stuffing_requ : BOOLEAN;
+ SIGNAL usb_request : usb_action;
+
+ function next_CRC_5 (Data: std_logic; crc: std_logic_vector(4 downto 0)) return std_logic_vector is
+ -- Copyright (C) 1999-2008 Easics NV. http://www.easics.com/webtools/crctool
+ variable d: std_logic;
+ variable c: std_logic_vector(4 downto 0);
+ variable new_crc: std_logic_vector(4 downto 0);
+ begin
+ d := Data;
+ c := crc;
+ new_crc(0) := d xor c(4);
+ new_crc(1) := c(0);
+ new_crc(2) := d xor c(1) xor c(4);
+ new_crc(3) := c(2);
+ new_crc(4) := c(3);
+ return new_crc;
+ end next_CRC_5;
+
+ function next_CRC_16 (Data: std_logic; crc: std_logic_vector(15 downto 0)) return std_logic_vector is
+ -- Copyright (C) 1999-2008 Easics NV. http://www.easics.com/webtools/crctool
+ variable d: std_logic;
+ variable c: std_logic_vector(15 downto 0);
+ variable new_crc: std_logic_vector(15 downto 0);
+ begin
+ d := Data;
+ c := crc;
+ new_crc(0) := d xor c(15);
+ new_crc(1) := c(0);
+ new_crc(2) := d xor c(1) xor c(15);
+ new_crc(14 DOWNTO 3) := c(13 DOWNTO 2);
+ new_crc(15) := d xor c(14) xor c(15);
+ return new_crc;
+ end next_CRC_16;
+
+ FUNCTION nrzi(data_bit, last_level : std_logic) RETURN STD_LOGIC IS
+ BEGIN
+ IF data_bit = '0' THEN
+ RETURN not last_level;
+ ELSE
+ RETURN last_level;
+ END IF;
+ END nrzi;
+
+--==========================================================================================================--
+
+begin
+
+ test_case : ENTITY work.usb_stimuli
+ PORT MAP(
+ -- Test Control Interface --
+ usb => usb_request,
+ T_No => T_No,
+ -- Application Interface
+ clk => int_clk,
+ rst_neg_ext => rst_neg_ext,
+ RXval => RXval,
+ RXdat => RXdat,
+ RXrdy => RXrdy,
+ RXlen => RXlen,
+ TXval => TXval,
+ TXdat => TXdat,
+ TXrdy => TXrdy,
+ TXroom => TXroom,
+ TXcork => TXcork
+ );
+
+ usb_fs_monitor : ENTITY work.usb_fs_monitor
+ port map (
+ clk_60MHz => int_clk,
+ master_oe => master_oe,
+ usb_Dp => usb_dp,
+ usb_Dn => usb_dn
+ );
+
+ master_oe <= '0' WHEN usb_request = idle OR usb_request = recv_eop ELSE '1';
+
+ p_usb_data : PROCESS
+ VARIABLE d_new : STD_LOGIC;
+ VARIABLE ones_cnt : NATURAL;
+ BEGIN
+ WAIT UNTIL rising_edge(usb_clk);
+ stuffing_requ <= FALSE;
+ IF stimuli_bit = 'L' THEN
+ usb_Dp <= '0';
+ usb_Dn <= '0';
+ ELSIF stimuli_bit = 'Z' THEN
+ usb_Dp <= 'Z';
+ usb_Dn <= 'L';
+ ELSIF stimuli_bit = '1' THEN
+ ones_cnt := ones_cnt +1;
+ d_new := nrzi('1', usb_Dp);
+ usb_Dp <= d_new;
+ usb_Dn <= not d_new;
+ IF ones_cnt = 6 THEN -- add stuffing bit
+ stuffing_requ <= TRUE;
+ ones_cnt := 0;
+ WAIT UNTIL rising_edge(usb_clk);
+ stuffing_requ <= FALSE;
+ d_new := nrzi('0', usb_Dp);
+ usb_Dp <= d_new;
+ usb_Dn <= not d_new;
+ END IF;
+ ELSE
+ ones_cnt := 0;
+ d_new := nrzi('0', usb_Dp);
+ usb_Dp <= d_new;
+ usb_Dn <= not d_new;
+ END IF;
+ END PROCESS;
+
+ p_stimuli_bit : PROCESS --always transfer LSB first (exception crc)
+ CONSTANT sync_data : std_logic_vector(7 DOWNTO 0) := X"80"; --USB FS : sync patter is KJKJKJKK
+ CONSTANT eop_data : std_logic_vector(3 DOWNTO 0) := "Z0LL"; --'L' forces both usb_up, usb_dn low !!
+ BEGIN
+ WAIT ON usb_request;
+ IF usb_request = reset THEN
+ usb_status <= usb_request;
+ stimuli_bit <= 'L';
+ WAIT FOR 5 us;
+ WAIT UNTIL rising_edge(usb_clk);
+ stimuli_bit <= 'Z';
+ usb_status <= idle;
+ ELSIF usb_request = sync THEN
+ usb_status <= usb_request;
+ FOR i IN 0 TO 7 LOOP -- Sync pattern
+ WAIT UNTIL rising_edge(usb_clk);
+ stimuli_bit <= sync_data(i);
+ END LOOP;
+ usb_status <= idle;
+ ELSIF usb_request = pid THEN
+ usb_status <= usb_request;
+ FOR i IN 0 TO 7 LOOP
+ WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
+ stimuli_bit <= sv_usb_byte(i);
+ END LOOP;
+ crc_5 <= (others =>'1');
+ crc_16 <= (others =>'1');
+ usb_status <= idle;
+ ELSIF usb_request = addr THEN
+ usb_status <= usb_request;
+ FOR i IN 0 TO 10 LOOP
+ WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
+ stimuli_bit <= sv_usb_addr(i);
+ crc_5 <= next_crc_5(sv_usb_addr(i),crc_5);
+ END LOOP;
+ usb_status <= idle;
+ ELSIF usb_request = wr_odd OR usb_request = wr_even THEN
+ usb_status <= usb_request;
+ FOR i IN 0 TO 7 LOOP
+ WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
+ stimuli_bit <= sv_usb_byte(i);
+ crc_16 <= next_crc_16(sv_usb_byte(i),crc_16);
+ END LOOP;
+ usb_status <= idle;
+ -- WAIT for 1 ns;
+ ELSIF usb_request = wr_crc5 THEN
+ usb_status <= usb_request;
+ FOR i IN 4 DOWNTO 0 LOOP -- Token crc5, LSB last
+ WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
+ stimuli_bit <= NOT crc_5(i);
+ END LOOP;
+ usb_status <= idle;
+ ELSIF usb_request = wr_crc16 THEN
+ usb_status <= usb_request;
+ FOR i IN 15 DOWNTO 0 LOOP -- Data crc16, LSB last
+ WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
+ stimuli_bit <= NOT crc_16(i);
+ END LOOP;
+ usb_status <= idle;
+ ELSIF usb_request = send_eop THEN
+ usb_status <= usb_request;
+ FOR i IN 0 TO 3 LOOP
+ WAIT UNTIL rising_edge(usb_clk) AND NOT stuffing_requ;
+ stimuli_bit <= eop_data(i);
+ END LOOP;
+ usb_status <= idle;
+ ELSIF usb_request = Recv_eop THEN
+ usb_status <= usb_request;
+ WAIT UNTIL rising_edge(usb_clk) AND usb_Dp ='0' AND usb_Dn ='0';
+ WAIT FOR 400 ns;
+ usb_status <= idle;
+ ELSE
+ stimuli_bit <= 'Z';
+ usb_status <= idle;
+ END IF;
+ END PROCESS;
+
+END SIM;
+
+--======================================== END OF usb_fs_master.vhd ========================================--
Index: USB_tb.vhd
===================================================================
--- USB_tb.vhd (nonexistent)
+++ USB_tb.vhd (revision 2)
@@ -0,0 +1,148 @@
+
+--==========================================================================================================--
+-- --
+-- Copyright (C) 2011 by Martin Neumann martin@neumanns-mail.de --
+-- --
+-- This source file may be used and distributed without restriction provided that this copyright statement --
+-- is not removed from the file and that any derivative work contains the original copyright notice and --
+-- the associated disclaimer. --
+-- --
+-- This software is provided ''as is'' and without any express or implied warranties, including, but not --
+-- limited to, the implied warranties of merchantability and fitness for a particular purpose. in no event --
+-- shall the author or contributors be liable for any direct, indirect, incidental, special, exemplary, or --
+-- consequential damages (including, but not limited to, procurement of substitute goods or services; loss --
+-- of use, data, or profits; or business interruption) however caused and on any theory of liability, --
+-- whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way --
+-- out of the use of this software, even if advised of the possibility of such damage. --
+-- --
+--==========================================================================================================--
+-- --
+-- File name : USB_tb.vhd --
+-- Author : Martin Neumann martin@neumanns-mail.de --
+-- Description : USB test bench used with usb_mster.vhd, usb_Stimuli.vhd and usb_fs_monitor.vhd. --
+-- --
+--==========================================================================================================--
+-- --
+-- Change history --
+-- --
+-- Version / date Description --
+-- --
+-- 01 05 Mar 2011 MN Initial version --
+-- --
+-- End change history --
+--==========================================================================================================--
+
+LIBRARY work, IEEE;
+ USE IEEE.std_logic_1164.ALL;
+ USE work.usb_commands.ALL;
+
+ENTITY usb_tb IS
+END usb_tb;
+
+ARCHITECTURE sim OF usb_tb IS
+
+ CONSTANT BUFSIZE_BITS : POSITIVE := 8;
+
+ SIGNAL FPGA_ready : STD_LOGIC;
+ SIGNAL RXdat : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL RXlen : STD_LOGIC_VECTOR(BUFSIZE_BITS-1 DOWNTO 0);
+ SIGNAL RXrdy : STD_LOGIC;
+ SIGNAL RXval : STD_LOGIC;
+ SIGNAL TXcork : STD_LOGIC;
+ SIGNAL TXdat : STD_LOGIC_VECTOR(7 DOWNTO 0);
+ SIGNAL TXrdy : STD_LOGIC;
+ SIGNAL TXroom : STD_LOGIC_VECTOR(BUFSIZE_BITS-1 DOWNTO 0);
+ SIGNAL TXval : STD_LOGIC;
+ SIGNAL USB_rst : STD_LOGIC;
+ SIGNAL online : STD_LOGIC;
+ SIGNAL clk_12MHz : STD_LOGIC;
+ SIGNAL clk_60MHz : STD_LOGIC;
+ SIGNAL rst_neg_ext : STD_LOGIC;
+ SIGNAL rst_neg_syc : STD_LOGIC;
+ SIGNAL usb_Dn : STD_LOGIC := 'L';
+ SIGNAL usb_Dp : STD_LOGIC := 'Z'; -- allow forcing 'H', avoid 'X'
+
+BEGIN
+
+ p_clk_60MHz : PROCESS
+ BEGIN
+ clk_60MHz <= '0';
+ WAIT FOR 2 ns;
+ While true loop
+ clk_60MHz <= '0';
+ WAIT FOR 8000 ps;
+ clk_60MHz <= '1';
+ -- WAIT FOR 8667 ps; -- 60 MHz
+ WAIT FOR 8393 ps; -- 61 MHz
+ -- WAIT FOR 8949 ps; -- 59 MHz
+ end loop;
+ END PROCESS;
+
+ p_clk_12MHz : PROCESS
+ BEGIN
+ clk_12MHz <= '0';
+ WAIT FOR 20866 ps;
+ clk_12MHz <= '1';
+ WAIT FOR 41600 ps;
+ clk_12MHz <= '0';
+ WAIT FOR 20867 ps;
+ END PROCESS;
+
+ p_rst_neg_ext : PROCESS
+ BEGIN
+ rst_neg_ext <= '0';
+ WAIT FOR 301 ns;
+ rst_neg_ext <= '1';
+ WAIT;
+ END PROCESS;
+
+ usb_fs_master : ENTITY work.usb_fs_master
+ port map (
+ usb_clk => clk_12MHz,
+ int_clk => clk_60MHz,
+ rst_neg_ext => rst_neg_ext,
+ usb_Dp => usb_dp,
+ usb_Dn => usb_dn,
+ RXval => RXval,
+ RXdat => RXdat,
+ RXrdy => RXrdy,
+ RXlen => RXlen,
+ TXval => TXval,
+ TXdat => TXdat,
+ TXrdy => TXrdy,
+ TXroom => TXroom,
+ TXcork => TXcork
+ );
+
+ usb_dp <= 'H' WHEN FPGA_ready ='1' ELSE 'L'; -- connect FPGA_ready to the pullup resistor logic, ....
+ usb_dn <= 'L'; -- ... keeping usb_dp='L' during FPGA initialization.
+
+ usb_fs_slave_1 : ENTITY work.usb_fs_slave
+ GENERIC MAP(
+ VENDORID => X"FB9A",
+ PRODUCTID => X"FB9A",
+ VERSIONBCD => X"0020",
+ SELFPOWERED => FALSE,
+ BUFSIZE_BITS => BUFSIZE_BITS)
+ PORT MAP(
+ clk => clk_60MHz, -- i
+ rst_neg_ext => rst_neg_ext, -- i
+ rst_neg_syc => rst_neg_syc, -- o RST_NEG_EXT streched to next clock
+ d_pos => usb_dp, -- io Pos USB data line
+ d_neg => usb_dn, -- io Neg USB data line
+ USB_rst => USB_rst, -- o USB reset detected (SE0 > 2.5 us)
+ online => online, -- o High when the device is in Config state.
+ RXval => RXval, -- o High if a received byte available on RXDAT.
+ RXdat => RXdat, -- o Received data byte, valid if RXVAL is high.
+ RXrdy => RXrdy, -- i High if application is ready to receive.
+ RXlen => RXlen, -- o No of bytes available in receive buffer.
+ TXval => TXval, -- i High if the application has data to send.
+ TXdat => TXdat, -- i Data byte to send, must be valid if TXVAL is high.
+ TXrdy => TXrdy, -- o High if the entity is ready to accept the next byte.
+ TXroom => TXroom, -- o No of free bytes in transmit buffer.
+ TXcork => TXcork, -- i Temp. suppress transmissions at the outgoing endpoint.
+ FPGA_ready => FPGA_ready -- o Connect FPGA_ready to the pullup resistor logic
+ );
+
+END sim;
+