#!/usr/bin/env python3
from migen import *
import unittest
from ..utils.packet import b, nrzi, diff
from ..test.common import BaseUsbTestCase
from .pipeline import TxPipeline
[docs]class TestTxPipeline(BaseUsbTestCase):
maxDiff=None
[docs] def pkt_decode_test(self, vector, name):
PAD=8
def send(data, oe):
oe = oe.replace(' ', '')
clk12 = ClockSignal("usb_12")
clk48 = ClockSignal("usb_48")
def clk12_edge():
data_strobe = yield dut.o_data_strobe
if data_strobe:
if data:
yield dut.i_data_payload.eq(data.pop(0))
else:
yield dut.i_data_payload.eq(0xff)
usb = {
'p': "",
'n': "",
}
def clk48_edge(clk48=[0]):
j = clk48[0]
u = int(j/4)
if u < len(oe):
yield dut.i_oe.eq(int(oe[u]))
if j % 4 == 0:
yield dut.i_bit_strobe.eq(1)
else:
yield dut.i_bit_strobe.eq(0)
usb['p'] += str((yield dut.o_usbp))
usb['n'] += str((yield dut.o_usbn))
clk48[0] += 1
def tick(last={'clk12': None, 'clk48':None}):
current_clk12 = yield clk12
if current_clk12 and not last['clk12']:
yield from clk12_edge()
last['clk12'] = current_clk12
current_clk48 = yield clk48
if current_clk48 and not last['clk48']:
yield from clk48_edge()
last['clk48'] = current_clk48
yield
yield dut.i_data_payload.eq(0)
i = 0
N = 4*8
while usb['p'][PAD:][-N:] != '1'*(N) and i < 10000:
yield from tick()
i += 1
#assert usbn[20:] == 'J'*20
return usb['p'][2:], usb['n'][2:]
def stim(value, data, oe):
# expected_usbp, expected_usbn = diff('J'*(2*4)+nrzi(value)+'J'*(4*4))
expected_usbp, expected_usbn = diff('J'*(1*4)+nrzi(value)+'J'*(5*4))
assert len(expected_usbp) == len(expected_usbn)
actual_usbp, actual_usbn = yield from send(data, oe)
self.assertSequenceEqual(expected_usbp, actual_usbp[PAD:len(expected_usbp)+PAD])
self.assertSequenceEqual(expected_usbn, actual_usbn[PAD:len(expected_usbn)+PAD])
with self.subTest(name=name):
fname = name.replace(" ","_")
dut = TxPipeline()
run_simulation(dut, stim(**vector),
vcd_name=self.make_vcd_name(testsuffix=fname),
clocks={"sys": 10, "usb_48": 40, "usb_12": 160})
[docs] def test_usb2_sof_token(self):
self.pkt_decode_test(
# Passed
dict(
#data = [b("10000001"), b("10100101"), b("10000110"), b("11000010")],
data = [b("10100101"), b("10000110"), b("11000010")],
oe = "00 11111111 11111111 11111111 11111111 000000",
#se0 = "00 00000000 00000000 00000000 00000000 110000",
# SSSSSSSS PPPPPPPP AAAAAAAE EEECCCCC 00
value = "00000001 10100101 10000110 11000010 __",
), "USB2 SOF token")
#"USB2 SOF token - eop dribble 1": dict(
# data = [b("00000001"), b("10100101"), b("10000110"), b("11000010")],
# oe = "00 11111111 11111111 11111111 11111111 1000000",
# #se0 = "00 00000000 00000000 00000000 00000000 0110000",
# # SSSSSSSS PPPPPPPP AAAAAAAE EEECCCCC 00
# value = "00000001 10100101 10000110 11000010 1__",
#),
#"USB2 SOF token - eop dribble 6": dict(
# data = [b("00000001"), b("10100101"), b("10000110"), b("11000010")],
# oe = "00 11111111 11111111 11111111 11111111 111111000000",
# #se0 = "00 00000000 00000000 00000000 00000000 000000110000",
# # SSSSSSSS PPPPPPPP AAAAAAAE EEECCCCC 00
# value = "00000001 10100101 10000110 11000010 111111__",
#),
[docs] def test_usb2_sof_token_bad_pid(self):
self.pkt_decode_test(
# Passed
dict(
#data = [b("00000001"), b("10100100"), b("10000110"), b("11000010")],
data = [b("10100100"), b("10000110"), b("11000010")],
oe = "00 11111111 11111111 11111111 11111111 000000",
#se0 = "00 00000000 00000000 00000000 00000000 110000",
# SSSSSSSS PPPPPPPP AAAAAAAE EEECCCCC 00
value = "00000001 10100100 10000110 11000010 __",
), "USB2 SOF token - bad pid")
[docs] def test_usb2_sof_token_bad_crc5(self):
self.pkt_decode_test(
dict(
#data = [b("00000001"), b("10100101"), b("10000110"), b("11000011")],
data = [b("10100101"), b("10000110"), b("11000011")],
oe = "00 11111111 11111111 11111111 11111111 000000",
#se0 = "00 00000000 00000000 00000000 00000000 110000",
# SSSSSSSS PPPPPPPP AAAAAAAE EEECCCCC 00
value = "00000001 10100101 10000110 11000011 __",
), "USB2 SOF token - bad crc5")
[docs] def test_usb2_ack_handshake(self):
self.pkt_decode_test(
dict(
#data = [b("00000001"), b("01001011")],
data = [b("01001011")],
oe = "00 11111111 11111111 000000",
#se0 = "00 00000000 00000000 110000",
# SSSSSSSS PPPPPPPP 00
value = "00000001 01001011 __",
), "USB2 ACK handshake")
[docs] def test_usb2_ack_handshake_pid_error(self):
self.pkt_decode_test(
dict(
#data = [b("00000001"), b("01001111")],
data = [b("01001111")],
oe = "00 11111111 11111111 000000",
#se0 = "00 00000000 00000000 110000",
# SSSSSSSS PPPPPPPP 00
value = "00000001 01001111 __",
), "USB2 ACK handshake - pid error")
#"USB2 ACK handshake - EOP dribble 1": dict(
# data = [b("00000001"), b("01001011")],
# oe = "00 11111111 11111111 1000000",
# #se0 = "00 00000000 00000000 0110000",
# # SSSSSSSS PPPPPPPP 00
# value = "00000001 01001011 1__",
#),
#"USB2 ACK handshake - EOP dribble 6": dict(
# data = [b("00000001"), b("01001011")],
# oe = "00 11111111 11111111 111111000000",
# #se0 = "00 00000000 00000000 000000110000",
# # SSSSSSSS PPPPPPPP 00
# value = "00000001 01001011 111111__",
#),
[docs] def test_usb2_data_with_good_crc16(self):
self.pkt_decode_test(
dict(
data = [
#b("00000001"), # Sync
b("11000011"), # PID
0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, # Data payload
0xdd, 0x94, # CRC16
],
oe = "00 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 000000",
#se0 = "00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 110000",
value = "00000001 11000011 00000001 01100000 00000000 10000000 00000000 00000000 00000010 00000000 10111011 00101001 __",
), "USB2 data with good CRC16")
#"USB2 data with good CRC16 - 1 eop dribble": dict(
# data = [
# b("00000001"), # Sync
# b("11000011"), # PID
# 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, # Data payload
# 0xdd, 0x94, # CRC16
# ],
# oe = "00 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 1110000",
# #se0 = "00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0110000",
# value = "00000001 11000011 00000001 01100000 00000000 10000000 00000000 00000000 00000010 00000000 10111011 00101001 1__",
#),
#"USB2 data with good CRC16 - 6 eop dribble": dict(
# data = [
# b("00000001"), # Sync
# b("11000011"), # PID
# 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, # Data payload
# 0xdd, 0x94, # CRC16
# ],
# oe = "00 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 111111000000",
# #se0 = "00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000000110000",
# value = "00000001 11000011 00000001 01100000 00000000 10000000 00000000 00000000 00000010 00000000 10111011 00101001 111111__",
#),
[docs] def test_usb2_data_with_bad_crc16(self):
self.pkt_decode_test(
dict(
data = [
#b("00000001"), # Sync
b("11000011"), # PID
0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, # Data payload
0xdd, 0xd4, # CRC16
],
oe = "00 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 000000",
#se0 = "00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 110000",
value = "00000001 11000011 00000001 01100000 00000000 10000000 00000000 00000000 00000010 00000000 10111011 00101011 __",
), "USB2 data with bad CRC16")
if __name__ == "__main__":
unittest.main()