mirror of
https://github.com/enjoy-digital/usb3_pipe.git
synced 2025-01-04 10:18:41 +08:00
usb3_pipe/ordered_set: add OrderedSetTransmitter
This commit is contained in:
parent
cef3189280
commit
43f089281d
@ -6,7 +6,7 @@ import unittest
|
||||
from migen import *
|
||||
|
||||
from usb3_pipe.common import TSEQ, TS1
|
||||
from usb3_pipe.ordered_set import OrderedSetReceiver
|
||||
from usb3_pipe.ordered_set import OrderedSetReceiver, OrderedSetTransmitter
|
||||
|
||||
|
||||
class TestOrderedSet(unittest.TestCase):
|
||||
@ -38,7 +38,7 @@ class TestOrderedSet(unittest.TestCase):
|
||||
generator(dut, n_loops=32),
|
||||
checker(dut, n_loops=32, n_ordered_sets=4),
|
||||
]
|
||||
run_simulation(dut, generators, vcd_name="tseq.vcd")
|
||||
run_simulation(dut, generators)
|
||||
|
||||
|
||||
def test_ts1_receiver(self):
|
||||
@ -72,4 +72,75 @@ class TestOrderedSet(unittest.TestCase):
|
||||
generator(dut, n_loops=32),
|
||||
checker(dut, n_loops=32, n_ordered_sets=4),
|
||||
]
|
||||
run_simulation(dut, generators, vcd_name="ts1.vcd")
|
||||
run_simulation(dut, generators)
|
||||
|
||||
def test_tseq_transmitter(self):
|
||||
tseq_length = len(TSEQ.to_bytes())//4
|
||||
tseq_words = [int.from_bytes(TSEQ.to_bytes()[4*i:4*(i+1)], "little") for i in range(tseq_length)]
|
||||
def generator(dut, n_loops):
|
||||
for i in range(n_loops):
|
||||
yield dut.send.eq(1)
|
||||
yield
|
||||
yield dut.send.eq(0)
|
||||
yield
|
||||
while not (yield dut.done):
|
||||
yield
|
||||
yield
|
||||
for i in range(128):
|
||||
yield
|
||||
dut.run = False
|
||||
|
||||
def checker(dut, n_loops, n_ordered_sets):
|
||||
words = []
|
||||
yield dut.source.ready.eq(1)
|
||||
yield
|
||||
while dut.run:
|
||||
if (yield dut.source.valid):
|
||||
words.append((yield dut.source.data))
|
||||
yield
|
||||
self.assertEqual(words, tseq_words*n_loops*n_ordered_sets)
|
||||
|
||||
dut = OrderedSetTransmitter(ordered_set=TSEQ, n_ordered_sets=4, data_width=32)
|
||||
dut.run = True
|
||||
generators = [
|
||||
generator(dut, n_loops=32),
|
||||
checker(dut, n_loops=32, n_ordered_sets=4),
|
||||
]
|
||||
run_simulation(dut, generators)
|
||||
|
||||
def test_ts1_transmitter(self):
|
||||
ts1_length = len(TS1.to_bytes())//4
|
||||
ts1_words = [int.from_bytes(TS1.to_bytes()[4*i:4*(i+1)], "little") for i in range(ts1_length)]
|
||||
def generator(dut, n_loops):
|
||||
for i in range(n_loops):
|
||||
yield dut.send.eq(1)
|
||||
yield dut.reset.eq(0)
|
||||
yield dut.loopback.eq(0)
|
||||
yield dut.scrambling.eq(1)
|
||||
yield
|
||||
yield dut.send.eq(0)
|
||||
yield
|
||||
while not (yield dut.done):
|
||||
yield
|
||||
yield
|
||||
for i in range(128):
|
||||
yield
|
||||
dut.run = False
|
||||
|
||||
def checker(dut, n_loops, n_ordered_sets):
|
||||
words = []
|
||||
yield dut.source.ready.eq(1)
|
||||
yield
|
||||
while dut.run:
|
||||
if (yield dut.source.valid):
|
||||
words.append((yield dut.source.data))
|
||||
yield
|
||||
self.assertEqual(words, ts1_words*n_loops*n_ordered_sets)
|
||||
|
||||
dut = OrderedSetTransmitter(ordered_set=TS1, n_ordered_sets=4, data_width=32)
|
||||
dut.run = True
|
||||
generators = [
|
||||
generator(dut, n_loops=32),
|
||||
checker(dut, n_loops=32, n_ordered_sets=4),
|
||||
]
|
||||
run_simulation(dut, generators)
|
||||
|
@ -28,7 +28,7 @@ class OrderedSetReceiver(Module):
|
||||
port = mem.get_port(async_read=True)
|
||||
self.specials += mem, port
|
||||
|
||||
# Error detection --------------------------------------------------------------------------
|
||||
# Data check -------------------------------------------------------------------------------
|
||||
error = Signal()
|
||||
error_mask = Signal(data_width, reset=2**data_width-1)
|
||||
if ordered_set.name in ["TS1", "TS2"]:
|
||||
@ -101,3 +101,86 @@ class OrderedSetReceiver(Module):
|
||||
|
||||
# Result -----------------------------------------------------------------------------------
|
||||
self.comb += self.detected.eq(count == (mem_depth*n_ordered_sets - 1))
|
||||
|
||||
# Ordered Set Transmitter --------------------------------------------------------------------------
|
||||
|
||||
class OrderedSetTransmitter(Module):
|
||||
def __init__(self, ordered_set, n_ordered_sets, data_width):
|
||||
assert data_width in [16, 32]
|
||||
self.send = Signal() # i
|
||||
self.done = Signal() # i
|
||||
self.source = stream.Endpoint([("data", data_width), ("ctrl", data_width//8)])
|
||||
|
||||
if ordered_set.name in ["TS1", "TS2"]:
|
||||
self.reset = Signal() # i
|
||||
self.loopback = Signal() # i
|
||||
self.scrambling = Signal() # i
|
||||
|
||||
# # #
|
||||
|
||||
run = Signal()
|
||||
|
||||
# Memory --------------------------------------------------------------------------------
|
||||
mem_depth = len(ordered_set.to_bytes())//(data_width//8)
|
||||
mem_init = [int.from_bytes(ordered_set.to_bytes()[4*i:4*(i+1)], "little") for i in range(mem_depth)]
|
||||
mem = Memory(data_width, mem_depth, mem_init)
|
||||
port = mem.get_port(async_read=True)
|
||||
self.specials += mem, port
|
||||
|
||||
# Memory address generation ----------------------------------------------------------------
|
||||
self.sync += [
|
||||
If(self.source.valid & self.source.ready,
|
||||
If(port.adr == (mem_depth - 1),
|
||||
port.adr.eq(0)
|
||||
).Else(
|
||||
port.adr.eq(port.adr + 1)
|
||||
)
|
||||
).Else(
|
||||
port.adr.eq(0)
|
||||
)
|
||||
]
|
||||
|
||||
# Link Config ------------------------------------------------------------------------------
|
||||
link_config = Signal(8)
|
||||
if ordered_set.name in ["TS1", "TS2"]:
|
||||
self.comb += [
|
||||
link_config[0].eq(self.reset),
|
||||
link_config[1].eq(self.loopback),
|
||||
link_config[2].eq(~self.scrambling)
|
||||
]
|
||||
|
||||
# Data generation --------------------------------------------------------------------------
|
||||
if ordered_set.name in ["TS1", "TS2"]:
|
||||
first_ctrl = 2**(data_width//8) - 1
|
||||
else:
|
||||
first_ctrl = 1
|
||||
self.comb += [
|
||||
self.source.valid.eq(self.send | ~self.done),
|
||||
If(port.adr == 0,
|
||||
self.source.ctrl.eq(first_ctrl),
|
||||
).Else(
|
||||
self.source.ctrl.eq(0)
|
||||
),
|
||||
self.source.data.eq(port.dat_r)
|
||||
]
|
||||
if ordered_set.name in ["TS1", "TS2"]:
|
||||
if data_width == 32:
|
||||
self.comb += If(port.adr == 1, self.source.data[8:16].eq(link_config))
|
||||
else:
|
||||
self.comb += If(port.adr == 2, self.source.data[8:16].eq(link_config))
|
||||
|
||||
# Count ------------------------------------------------------------------------------------
|
||||
count = Signal(max=mem_depth*n_ordered_sets)
|
||||
self.sync += [
|
||||
If(self.send,
|
||||
run.eq(1),
|
||||
count.eq(0),
|
||||
).Elif(self.done,
|
||||
run.eq(0),
|
||||
).Else(
|
||||
count.eq(count + 1)
|
||||
)
|
||||
]
|
||||
|
||||
# Result -----------------------------------------------------------------------------------
|
||||
self.comb += self.done.eq(count == (mem_depth*n_ordered_sets - 1))
|
||||
|
Loading…
x
Reference in New Issue
Block a user