Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: whitequark/Yumewatari
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7c0df16f5b83
Choose a base ref
...
head repository: whitequark/Yumewatari
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: df22333aad95
Choose a head ref
  • 1 commit
  • 8 files changed
  • 1 contributor

Commits on Nov 12, 2018

  1. Copy the full SHA
    df22333 View commit details
180 changes: 114 additions & 66 deletions yumewatari/gateware/phy.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
from migen.genlib.fsm import *

from .serdes import K, D
from .parser import *
from .protocol import *


__all__ = ["PCIeRXPHY", "PCIeTXPHY"]
@@ -49,15 +49,22 @@ def __init__(self, lane):
ts_id = Signal(9)
ts_inv = Signal()

self.submodules.parser = Parser(symbol_size=9, word_size=lane.ratio, reset_rule="COMMA")
self.submodules.parser = Parser(
symbol_size=9,
word_size=lane.ratio,
reset_rule="COMMA",
layout=[
("data", 8),
("ctrl", 1),
])
self.comb += [
self.parser.reset.eq(~lane.rx_valid),
self.parser.i.eq(lane.rx_symbol),
self.error.eq(self.parser.error)
]
self.parser.rule(
name="COMMA",
cond=lambda symbol: symbol == K(28,5),
cond=lambda symbol: symbol.raw_bits() == K(28,5),
succ="TSn-LINK/SKP-0",
action=lambda symbol: [
NextValue(self._tsZ.valid, 1),
@@ -66,120 +73,120 @@ def __init__(self, lane):
)
self.parser.rule(
name="TSn-LINK/SKP-0",
cond=lambda symbol: symbol == K(28,0),
cond=lambda symbol: symbol.raw_bits() == K(28,0),
succ="SKP-1"
)
self.parser.rule(
name="TSn-LINK/SKP-0",
cond=lambda symbol: symbol == K(23,7),
cond=lambda symbol: symbol.raw_bits() == K(23,7),
succ="TSn-LANE",
action=lambda symbol: [
NextValue(self._tsZ.link.valid, 0)
]
)
self.parser.rule(
name="TSn-LINK/SKP-0",
cond=lambda symbol: ~symbol[8],
cond=lambda symbol: ~symbol.ctrl,
succ="TSn-LANE",
action=lambda symbol: [
NextValue(self._tsZ.link.number, symbol),
NextValue(self._tsZ.link.number, symbol.data),
NextValue(self._tsZ.link.valid, 1)
]
)
for n in range(1, 3):
self.parser.rule(
name="SKP-%d" % n,
cond=lambda symbol: symbol == K(28,0),
cond=lambda symbol: symbol.raw_bits() == K(28,0),
succ="COMMA" if n == 2 else "SKP-%d" % (n + 1),
)
self.parser.rule(
name="TSn-LANE",
cond=lambda symbol: symbol == K(23,7),
cond=lambda symbol: symbol.raw_bits() == K(23,7),
succ="TSn-FTS",
action=lambda symbol: [
NextValue(self._tsZ.lane.valid, 0)
]
)
self.parser.rule(
name="TSn-LANE",
cond=lambda symbol: ~symbol[8],
cond=lambda symbol: ~symbol.ctrl,
succ="TSn-FTS",
action=lambda symbol: [
NextValue(self._tsZ.lane.number, symbol),
NextValue(self._tsZ.lane.number, symbol.data),
NextValue(self._tsZ.lane.valid, 1)
]
)
self.parser.rule(
name="TSn-FTS",
cond=lambda symbol: ~symbol[8],
cond=lambda symbol: ~symbol.ctrl,
succ="TSn-RATE",
action=lambda symbol: [
NextValue(self._tsZ.n_fts, symbol)
NextValue(self._tsZ.n_fts, symbol.data)
]
)
self.parser.rule(
name="TSn-RATE",
cond=lambda symbol: ~symbol[8],
cond=lambda symbol: ~symbol.ctrl,
succ="TSn-CTRL",
action=lambda symbol: [
NextValue(self._tsZ.rate.raw_bits(), symbol)
NextValue(self._tsZ.rate.raw_bits(), symbol.data)
]
)
self.parser.rule(
name="TSn-CTRL",
cond=lambda symbol: ~symbol[8],
cond=lambda symbol: ~symbol.ctrl,
succ="TSn-ID0",
action=lambda symbol: [
NextValue(self._tsZ.ctrl.raw_bits(), symbol)
NextValue(self._tsZ.ctrl.raw_bits(), symbol.data)
]
)
self.parser.rule(
name="TSn-ID0",
cond=lambda symbol: symbol == D(10,2),
cond=lambda symbol: symbol.raw_bits() == D(10,2),
succ="TSn-ID1",
action=lambda symbol: [
NextMemory(ts_id, symbol),
NextMemory(ts_id, symbol.raw_bits()),
NextValue(ts_inv, 0),
NextValue(self._tsZ.ts_id, 0),
]
)
self.parser.rule(
name="TSn-ID0",
cond=lambda symbol: symbol == D(5,2),
cond=lambda symbol: symbol.raw_bits() == D(5,2),
succ="TSn-ID1",
action=lambda symbol: [
NextMemory(ts_id, symbol),
NextMemory(ts_id, symbol.raw_bits()),
NextValue(ts_inv, 0),
NextValue(self._tsZ.ts_id, 1),
]
)
self.parser.rule(
name="TSn-ID0",
cond=lambda symbol: symbol == D(21,5),
cond=lambda symbol: symbol.raw_bits() == D(21,5),
succ="TSn-ID1",
action=lambda symbol: [
NextMemory(ts_id, symbol),
NextMemory(ts_id, symbol.raw_bits()),
NextValue(ts_inv, 1),
]
)
self.parser.rule(
name="TSn-ID0",
cond=lambda symbol: symbol == D(26,5),
cond=lambda symbol: symbol.raw_bits() == D(26,5),
succ="TSn-ID1",
action=lambda symbol: [
NextMemory(ts_id, symbol),
NextMemory(ts_id, symbol.raw_bits()),
NextValue(ts_inv, 1),
]
)
for n in range(1, 9):
self.parser.rule(
name="TSn-ID%d" % n,
cond=lambda symbol: symbol == Memory(ts_id),
cond=lambda symbol: symbol.raw_bits() == Memory(ts_id),
succ="TSn-ID%d" % (n + 1)
)
self.parser.rule(
name="TSn-ID9",
cond=lambda symbol: symbol == Memory(ts_id),
cond=lambda symbol: symbol.raw_bits() == Memory(ts_id),
succ="COMMA",
action=lambda symbol: [
NextValue(self.ts.valid, 0),
@@ -199,46 +206,87 @@ def __init__(self, lane):

###

self.submodules.fsm = ResetInserter()(FSM(reset_state="IDLE"))
self.fsm.act("IDLE",
lane.tx_set_disp.eq(1),
lane.tx_symbol.eq(K(28,5)),
NextState("TSn-LINK")
)
self.fsm.act("TSn-LINK",
If(self.ts.link.valid,
lane.tx_symbol.eq(self.ts.link.number)
).Else(
lane.tx_symbol.eq(K(23,7))
),
NextState("TSn-LANE")
)
self.fsm.act("TSn-LANE",
If(self.ts.lane.valid,
lane.tx_symbol.eq(self.ts.lane.number)
).Else(
lane.tx_symbol.eq(K(23,7))
),
NextState("TSn-FTS")
)
self.fsm.act("TSn-FTS",
lane.tx_symbol.eq(self.ts.n_fts),
NextState("TSn-RATE")
)
self.fsm.act("TSn-RATE",
lane.tx_symbol.eq(self.ts.rate.raw_bits()),
NextState("TSn-CTRL")
)
self.fsm.act("TSn-CTRL",
lane.tx_symbol.eq(self.ts.ctrl.raw_bits()),
NextState("TSn-ID0")
self.submodules.emitter = Emitter(
symbol_size=12,
word_size=lane.ratio,
reset_rule="IDLE",
layout=[
("data", 8),
("ctrl", 1),
("set_disp", 1),
("disp", 1),
("e_idle", 1),
])
self.comb += [
lane.tx_symbol.eq(Cat(
(self.emitter._o[n].data, self.emitter._o[n].ctrl)
for n in range(lane.ratio)
)),
lane.tx_set_disp.eq(Cat(self.emitter._o[n].set_disp for n in range(lane.ratio))),
lane.tx_disp .eq(Cat(self.emitter._o[n].disp for n in range(lane.ratio))),
lane.tx_e_idle .eq(Cat(self.emitter._o[n].e_idle for n in range(lane.ratio))),
]
self.emitter.rule(
name="IDLE",
succ="TSn-LINK",
action=lambda symbol: [
symbol.raw_bits().eq(K(28,5)),
symbol.set_disp.eq(1),
symbol.disp.eq(0)
]
)
for n in range(0, 10):
self.fsm.act("TSn-ID%d" % n,
If(self.ts.ts_id == 0,
lane.tx_symbol.eq(D(10,2))
self.emitter.rule(
name="TSn-LINK",
succ="TSn-LANE",
action=lambda symbol: [
If(self.ts.link.valid,
symbol.data.eq(self.ts.link.number)
).Else(
lane.tx_symbol.eq(D(5,2))
symbol.raw_bits().eq(K(23,7))
),
NextState("IDLE" if n == 9 else "TSn-ID%d" % (n + 1))
]
)
self.emitter.rule(
name="TSn-LANE",
succ="TSn-FTS",
action=lambda symbol: [
If(self.ts.lane.valid,
symbol.data.eq(self.ts.lane.number)
).Else(
symbol.raw_bits().eq(K(23,7))
),
]
)
self.emitter.rule(
name="TSn-FTS",
succ="TSn-RATE",
action=lambda symbol: [
symbol.data.eq(self.ts.n_fts),
]
)
self.emitter.rule(
name="TSn-RATE",
succ="TSn-CTRL",
action=lambda symbol: [
symbol.data.eq(self.ts.rate.raw_bits()),
]
)
self.emitter.rule(
name="TSn-CTRL",
succ="TSn-ID0",
action=lambda symbol: [
symbol.data.eq(self.ts.ctrl.raw_bits()),
]
)
for n in range(0, 10):
self.emitter.rule(
name="TSn-ID%d" % n,
succ="IDLE" if n == 9 else "TSn-ID%d" % (n + 1),
action=lambda symbol: [
If(self.ts.ts_id == 0,
symbol.raw_bits().eq(D(10,2))
).Else(
symbol.raw_bits().eq(D(5,2))
)
]
)
3 changes: 3 additions & 0 deletions yumewatari/gateware/protocol/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .engine import Memory, NextMemory
from .parser import Parser
from .emitter import Emitter
65 changes: 65 additions & 0 deletions yumewatari/gateware/protocol/emitter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import os
from migen import *

from .engine import _ProtocolFSM, _ProtocolEngine


_DEBUG = os.getenv("DEBUG_EMITTER")


class Emitter(_ProtocolEngine):
def __init__(self, symbol_size, word_size, reset_rule, layout=None):
super().__init__(symbol_size, word_size, reset_rule)

self.o = Signal(symbol_size * word_size)

###

self._o = [Signal(symbol_size) for n in range(word_size)]
self.comb += self.o.eq(Cat(self._o))
if layout is not None:
for n in range(word_size):
irec = Record(layout)
self.comb += self._o[n].eq(irec.raw_bits())
self._o[n] = irec

def do_finalize(self):
self.submodules.fsm = _ProtocolFSM()

if _DEBUG:
print("Emitter layout:")
worklist = {self._reset_rule}
processed = set()
while worklist:
rule_name = worklist.pop()
processed.add(rule_name)

if _DEBUG:
print(" State %s" % rule_name)

rule_tuples = set()
self._get_rule_tuples(rule_name, rule_tuples)

conds = []
actions = []
for i, rule_tuple in enumerate(rule_tuples):
if _DEBUG:
print(" Output #%d %s -> %s" %
(i, rule_name, " -> ".join(rule.succ for rule in rule_tuple)))

succ = rule_tuple[-1].succ
action = [NextState(succ)]
for j, rule in enumerate(reversed(rule_tuple)):
symbol = self._o[self._word_size - j - 1]
action = [
If(rule.cond(),
rule.action(symbol),
*action
),
]

actions.append(action)
if succ not in processed:
worklist.add(succ)

self.fsm.act(rule_name, actions)
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import os
from collections import defaultdict, namedtuple
from collections import namedtuple, defaultdict
from migen import *
from migen.fhdl.structure import _Value, _Statement
from migen.genlib.fsm import _LowerNext, FSM


__all__ = ["Parser", "Memory", "NextMemory"]


_DEBUG = os.getenv("DEBUG_PARSER")


class Memory(_Value):
def __init__(self, target):
self.target = target
@@ -49,7 +42,7 @@ def visit_unknown(self, node):
return super().visit_unknown(node)


class _ParserFSM(FSM):
class _ProtocolFSM(FSM):
def _lower_controls(self):
return _LowerMemory(self.next_state, self.encoding, self.state_aliases)

@@ -62,21 +55,15 @@ def _finalize_sync(self, ls):
_Rule = namedtuple("_Rule", ("name", "cond", "succ", "action"))


class Parser(Module):
class _ProtocolEngine(Module):
def __init__(self, symbol_size, word_size, reset_rule):
self.reset = Signal()
self.error = Signal()
self.i = Signal(symbol_size * word_size)

###

self._symbol_size = symbol_size
self._word_size = word_size
self._reset_rule = reset_rule
# name -> [(cond, succ, action)]
self._grammar = defaultdict(lambda: [])

def rule(self, name, cond, succ, action=lambda symbol: []):
def rule(self, name, succ, cond=lambda *_: True, action=lambda symbol: []):
self._grammar[name].append(_Rule(name, cond, succ, action))

def _get_rule_tuples(self, rule_name, rule_tuples, rule_path=()):
@@ -86,54 +73,3 @@ def _get_rule_tuples(self, rule_name, rule_tuples, rule_path=()):

for rule in self._grammar[rule_name]:
self._get_rule_tuples(rule.succ, rule_tuples, rule_path + (rule,))

def do_finalize(self):
self.submodules.fsm = ResetInserter()(_ParserFSM())
self.comb += self.fsm.reset.eq(self.reset | self.error)

if _DEBUG:
print("Parser layout:")
worklist = {self._reset_rule}
processed = set()
while worklist:
rule_name = worklist.pop()
processed.add(rule_name)

if _DEBUG:
print(" State %s" % rule_name)

rule_tuples = set()
self._get_rule_tuples(rule_name, rule_tuples)

conds = []
actions = []
for i, rule_tuple in enumerate(rule_tuples):
if _DEBUG:
print(" Input #%d %s -> %s" %
(i, rule_name, " -> ".join(rule.succ for rule in rule_tuple)))

succ = rule_tuple[-1].succ
cond = 1
action = [
self.error.eq(0),
NextState(succ)
]
for j, rule in enumerate(reversed(rule_tuple)):
symbol = self.i.part((self._word_size - j - 1) * self._symbol_size,
self._symbol_size)
action = [
If(rule.cond(symbol),
rule.action(symbol),
*action
),
]

conds.append(cond)
actions.append(action)
if succ not in processed:
worklist.add(succ)

self.fsm.act(rule_name, [
self.error.eq(1),
*actions
])
72 changes: 72 additions & 0 deletions yumewatari/gateware/protocol/parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os
from migen import *

from .engine import _ProtocolFSM, _ProtocolEngine


_DEBUG = os.getenv("DEBUG_PARSER")


class Parser(_ProtocolEngine):
def __init__(self, symbol_size, word_size, reset_rule, layout=None):
super().__init__(symbol_size, word_size, reset_rule)

self.reset = Signal()
self.error = Signal()
self.i = Signal(symbol_size * word_size)

###

self._i = [self.i.part(n * symbol_size, symbol_size) for n in range(word_size)]
if layout is not None:
for n in range(word_size):
irec = Record(layout)
self.comb += irec.raw_bits().eq(self._i[n])
self._i[n] = irec

def do_finalize(self):
self.submodules.fsm = ResetInserter()(_ProtocolFSM())
self.comb += self.fsm.reset.eq(self.reset | self.error)

if _DEBUG:
print("Parser layout:")
worklist = {self._reset_rule}
processed = set()
while worklist:
rule_name = worklist.pop()
processed.add(rule_name)

if _DEBUG:
print(" State %s" % rule_name)

rule_tuples = set()
self._get_rule_tuples(rule_name, rule_tuples)

actions = []
for i, rule_tuple in enumerate(rule_tuples):
if _DEBUG:
print(" Input #%d %s -> %s" %
(i, rule_name, " -> ".join(rule.succ for rule in rule_tuple)))

succ = rule_tuple[-1].succ
action = [
self.error.eq(0),
NextState(succ)
]
for j, rule in enumerate(reversed(rule_tuple)):
symbol = self._i[self._word_size - j - 1]
action = [
If(rule.cond(symbol),
rule.action(symbol),
*action
),
]

actions.append(action)
if succ not in processed:
worklist.add(succ)

self.fsm.act(rule_name, [
self.error.eq(1),
*actions
])
62 changes: 46 additions & 16 deletions yumewatari/test/phy.py
Original file line number Diff line number Diff line change
@@ -6,14 +6,6 @@
from . import simulation_test


class _PHYTestCase(unittest.TestCase):
def assertState(self, tb, state):
self.assertEqual((yield from tb.phy_state()), state)

def assertSignal(self, signal, value):
self.assertEqual((yield signal), value)


class PCIeRXPHYTestbench(Module):
def __init__(self, ratio=1):
self.submodules.lane = PCIeSERDESInterface(ratio)
@@ -37,7 +29,15 @@ def transmit(self, symbols):
yield


class PCIeRXPHYTestCase(_PHYTestCase):
class _PCIeRXPHYTestCase(unittest.TestCase):
def assertState(self, tb, state):
self.assertEqual((yield from tb.phy_state()), state)

def assertSignal(self, signal, value):
self.assertEqual((yield signal), value)


class PCIeRXPHYGear1xTestCase(_PCIeRXPHYTestCase):
def setUp(self):
self.tb = PCIeRXPHYTestbench()

@@ -299,7 +299,7 @@ def test_rx_ts1_skp_ts1_valid(self, tb):
yield from self.assertSignal(tb.phy.ts.valid, 1)


class PCIeRXPHYGear2xTestCase(_PHYTestCase):
class PCIeRXPHYGear2xTestCase(_PCIeRXPHYTestCase):
def setUp(self):
self.tb = PCIeRXPHYTestbench(ratio=2)

@@ -319,25 +319,35 @@ def test_rx_ts1_2x_same_valid(self, tb):


class PCIeTXPHYTestbench(Module):
def __init__(self):
self.submodules.lane = PCIeSERDESInterface()
def __init__(self, ratio=1):
self.submodules.lane = PCIeSERDESInterface(ratio)
self.submodules.phy = PCIeTXPHY(self.lane)

def do_finalize(self):
self.states = {v: k for k, v in self.phy.fsm.encoding.items()}
self.states = {v: k for k, v in self.phy.emitter.fsm.encoding.items()}

def phy_state(self):
return self.states[(yield self.phy.fsm.state)]
return self.states[(yield self.phy.emitter.fsm.state)]

def receive(self, count):
symbols = []
for _ in range(count):
symbols.append((yield self.lane.tx_symbol))
word = yield self.lane.tx_symbol
if self.lane.ratio == 1:
symbols.append(word)
else:
symbols.append(tuple((word >> (9 * n)) & 0x1ff
for n in range(self.lane.ratio)))
yield
return symbols


class PCIeTXPHYTestCase(_PHYTestCase):
class _PCIeTXPHYTestCase(unittest.TestCase):
def assertReceive(self, tb, symbols):
self.assertEqual((yield from tb.receive(len(symbols))), symbols)


class PCIeTXPHYGear1xTestCase(_PCIeTXPHYTestCase):
def setUp(self):
self.tb = PCIeTXPHYTestbench()

@@ -396,3 +406,23 @@ def test_tx_ts2(self, tb):
K(28,5), K(23,7), K(23,7), 0xff, 0b0010, 0b0000, *[D(5,2) for _ in range(10)],
K(28,5)
])


class PCIeTXPHYGear2xTestCase(_PCIeTXPHYTestCase):
def setUp(self):
self.tb = PCIeTXPHYTestbench(ratio=2)

@simulation_test
def test_tx_ts1_link_lane(self, tb):
yield tb.phy.ts.link.valid.eq(1)
yield tb.phy.ts.link.number.eq(0xaa)
yield tb.phy.ts.lane.valid.eq(1)
yield tb.phy.ts.lane.number.eq(0x01)
yield tb.phy.ts.n_fts.eq(0xff)
yield tb.phy.ts.rate.gen1.eq(1)
yield from self.assertReceive(tb, [
(K(28,5), K(23,7)), (0x01, 0xff), (0b0010, 0b0000),
*[(D(10,2), D(10,2)) for _ in range(5)],
(K(28,5), 0xaa), (0x01, 0xff), (0b0010, 0b0000),
*[(D(10,2), D(10,2)) for _ in range(5)],
])
15 changes: 7 additions & 8 deletions yumewatari/testbench/phy.py
Original file line number Diff line number Diff line change
@@ -32,7 +32,6 @@ def __init__(self, **kwargs):
f.write("define_clock -name {n:serdes_ref_clk} -freq 100.000\n")
f.write("define_clock -name {n:serdes_rx_clk_o} -freq 150.000\n")
self.platform.add_source("top.sdc")

self.platform.add_platform_command("""FREQUENCY NET "serdes_ref_clk" 100 MHz;""")
self.platform.add_platform_command("""FREQUENCY NET "serdes_rx_clk_o" 125 MHz;""")

@@ -41,7 +40,6 @@ def __init__(self, **kwargs):
self.comb += [
self.tx_phy.ts.n_fts.eq(0xff),
self.tx_phy.ts.rate.gen1.eq(1),
# self.tx_phy.ts.ctrl.unscramble.eq(1),
]

led_att1 = self.platform.request("user_led")
@@ -53,8 +51,8 @@ def __init__(self, **kwargs):
led_err3 = self.platform.request("user_led")
led_err4 = self.platform.request("user_led")
self.comb += [
led_att1.eq(~(0)),
led_att2.eq(~(0)),
led_att1.eq(~(self.rx_phy.ts.link.valid)),
led_att2.eq(~(self.rx_phy.ts.lane.valid)),
led_sta1.eq(~(self.rx_phy.ts.valid)),
led_sta2.eq(~(0)),
led_err1.eq(~(~serdes.lane.rx_present)),
@@ -64,11 +62,12 @@ def __init__(self, **kwargs):
]

tp0 = self.platform.request("tp0")
self.comb += tp0.eq(self.rx_phy.ts.valid)
self.comb += tp0.eq(self.rx_phy.ts.link.valid)

self.submodules += CRG(serdes.ref_clk)
self.submodules += add_probe_record("lane0.rx", "ts", self.rx_phy.ts, clock_domain="rx")
self.submodules += Microscope(self.platform.request("serial"), 99.8e6)
# self.submodules += CRG(serdes.ref_clk)
# self.submodules += add_probe_single("lane0.rx", "ts",
# self.rx_phy.ts.raw_bits(), clock_domain="rx")
# self.submodules += Microscope(self.platform.request("serial"), 99.8e6)

# -------------------------------------------------------------------------------------------------

30 changes: 19 additions & 11 deletions yumewatari/testbench/serdes.py
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
from migen.genlib.fsm import FSM

from ..gateware.serdes import *
from ..gateware.phy import K
from ..gateware.phy import K, PCIeTXPHY
from ..gateware.align import *
from ..gateware.platform.lattice_ecp5 import *
from ..vendor.pads import *
@@ -26,23 +26,31 @@ def __init__(self, capture_depth, **kwargs):

self.submodules.serdes = serdes = \
LatticeECP5PCIeSERDES(self.platform.request("pcie_x1"))
self.submodules.aligner = aligner = \
ClockDomainsRenamer("rx")(PCIeSERDESAligner(serdes.lane))
self.comb += [
self.cd_ref.clk.eq(serdes.ref_clk),
serdes.rx_clk_i.eq(serdes.rx_clk_o),
self.cd_rx.clk.eq(serdes.rx_clk_i),
serdes.tx_clk_i.eq(serdes.tx_clk_o),
self.cd_tx.clk.eq(serdes.tx_clk_i),

serdes.lane.tx_symbol.eq(0x17C),
serdes.lane.rx_align.eq(1),
]

self.submodules.aligner = aligner = \
ClockDomainsRenamer("rx")(PCIeSERDESAligner(serdes.lane))
self.submodules.tx_phy = ClockDomainsRenamer("tx")(PCIeTXPHY(aligner))
self.comb += [
self.aligner.rx_align.eq(1),
self.tx_phy.ts.n_fts.eq(0xff),
self.tx_phy.ts.rate.gen1.eq(1),
]

self.platform.add_platform_command("""FREQUENCY NET "ref_clk" 100 MHz;""")
self.platform.add_platform_command("""FREQUENCY NET "rx_clk" 250 MHz;""")
self.platform.add_platform_command("""FREQUENCY NET "tx_clk" 250 MHz;""")
with open("top.sdc", "w") as f:
f.write("define_clock -name {n:serdes_ref_clk} -freq 100.000\n")
f.write("define_clock -name {n:serdes_tx_clk_o} -freq 150.000\n")
f.write("define_clock -name {n:serdes_rx_clk_o} -freq 150.000\n")
self.platform.add_source("top.sdc")
self.platform.add_platform_command("""FREQUENCY NET "serdes_ref_clk" 100 MHz;""")
self.platform.add_platform_command("""FREQUENCY NET "serdes_rx_clk_o" 125 MHz;""")
self.platform.add_platform_command("""FREQUENCY NET "serdes_tx_clk_o" 125 MHz;""")

refclkcounter = Signal(32)
self.sync.ref += refclkcounter.eq(refclkcounter + 1)
@@ -149,7 +157,7 @@ def __init__(self, capture_depth, **kwargs):
)

tp0 = self.platform.request("tp0")
self.comb += tp0.eq(serdes.rx_clk_o)
# self.comb += tp0.eq(serdes.rx_clk_o)

# -------------------------------------------------------------------------------------------------

@@ -164,7 +172,7 @@ def __init__(self, capture_depth, **kwargs):
if __name__ == "__main__":
for arg in sys.argv[1:]:
if arg == "run":
toolchain = "trellis"
toolchain = "diamond"
if toolchain == "trellis":
toolchain_path = "/usr/local/share/trellis"
elif toolchain == "diamond":