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: 8afe8ead7ad2
Choose a base ref
...
head repository: whitequark/Yumewatari
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7e0cf330e1de
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Nov 12, 2018

  1. Copy the full SHA
    c0b6169 View commit details
  2. Copy the full SHA
    7e0cf33 View commit details
Showing with 95 additions and 86 deletions.
  1. +62 −73 yumewatari/gateware/phy.py
  2. +33 −13 yumewatari/test/phy.py
135 changes: 62 additions & 73 deletions yumewatari/gateware/phy.py
Original file line number Diff line number Diff line change
@@ -36,130 +36,119 @@ def D(x, y): return (0 << 8) | (y << 5) | x

class PCIeRXPHY(Module):
def __init__(self, lane):
self.ts = Record(_ts_layout)
self.ts_error = Signal()
self.ts = Record(_ts_layout)
self.error = Signal()

###

self.comb += lane.rx_align.eq(1)

self._tsZ = Record(_ts_layout) # TS being received
self._tsY = Record(_ts_layout) # previous TS received
self._tsY = Record(_ts_layout) # previous TS received
self._tsZ = Record(_ts_layout) # TS being received
self.sync += If(self.error, self._tsZ.valid.eq(0))

id_ctr = Signal(max=10)
ts_idx = Signal(2) # bit 0: TS1/TS2, bit 1: noninverted/inverted
ts_id = Signal(9)

self.submodules.fsm = ResetInserter()(FSM(reset_state="IDLE"))
self.comb += self.fsm.reset.eq(~lane.rx_valid)
self.fsm.act("IDLE",
self.submodules.fsm = ResetInserter()(FSM())
self.comb += self.fsm.reset.eq(~lane.rx_valid | self.error)
self.fsm.act("COMMA",
If(lane.rx_symbol == K(28,5),
NextValue(self._tsZ.valid, 1),
NextValue(self._tsY.raw_bits(), self._tsZ.raw_bits()),
NextState("TSn-LINK")
NextState("TSn-LINK/SKP-0")
)
)
self.fsm.act("TSn-LINK",
NextValue(self._tsZ.link.number, lane.rx_symbol),
If(lane.rx_symbol == K(23,7),
NextValue(self._tsZ.link.valid, 0),
NextState("TSn-LANE")
).Elif(~lane.rx_symbol[8],
NextValue(self._tsZ.link.valid, 1),
NextState("TSn-LANE")
self.fsm.act("TSn-LINK/SKP-0",
If(lane.rx_symbol == K(28,0),
NextState("SKP-1")
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
If(lane.rx_symbol == K(23,7),
NextValue(self._tsZ.link.valid, 0),
).Elif(~lane.rx_symbol[8],
NextValue(self._tsZ.link.valid, 1),
).Else(
self.error.eq(1)
),
NextValue(self._tsZ.link.number, lane.rx_symbol),
NextState("TSn-LANE")
)
)
for n in range(1, 3):
self.fsm.act("SKP-%d" % n,
If(lane.rx_symbol != K(28,0),
self.error.eq(1)
),
NextState("SKP-%d" % (n + 1) if n < 2 else "COMMA")
)
self.fsm.act("TSn-LANE",
NextValue(self._tsZ.lane.number, lane.rx_symbol),
If(lane.rx_symbol == K(23,7),
NextValue(self._tsZ.lane.valid, 0),
NextState("TSn-FTS")
).Elif(~lane.rx_symbol[8],
NextValue(self._tsZ.lane.valid, 1),
NextState("TSn-FTS")
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
)
self.error.eq(1)
),
NextValue(self._tsZ.lane.number, lane.rx_symbol),
NextState("TSn-FTS")
)
self.fsm.act("TSn-FTS",
If(lane.rx_symbol[8],
self.error.eq(1)
),
NextValue(self._tsZ.n_fts, lane.rx_symbol),
If(~lane.rx_symbol[8],
NextState("TSn-RATE")
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
)
NextState("TSn-RATE")
)
self.fsm.act("TSn-RATE",
If(lane.rx_symbol[8],
self.error.eq(1)
),
NextValue(self._tsZ.rate.raw_bits(), lane.rx_symbol),
If(~lane.rx_symbol[8],
NextState("TSn-CTRL")
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
)
NextState("TSn-CTRL")
)
self.fsm.act("TSn-CTRL",
If(lane.rx_symbol[8],
self.error.eq(1)
),
NextValue(self._tsZ.ctrl.raw_bits(), lane.rx_symbol),
If(~lane.rx_symbol[8],
NextState("TSn-ID0")
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
)
NextState("TSn-ID0")
)
self.fsm.act("TSn-ID0",
NextValue(id_ctr, 1),
NextValue(ts_id, lane.rx_symbol),
If(lane.rx_symbol == D(10,2),
NextValue(ts_idx, 0),
NextValue(self._tsZ.ts_id, 0),
NextState("TSn-IDn")
).Elif(lane.rx_symbol == D(5,2),
NextValue(ts_idx, 1),
NextValue(self._tsZ.ts_id, 1),
NextState("TSn-IDn")
).Elif(lane.rx_symbol == D(21,5),
NextValue(ts_idx, 2),
NextValue(self._tsZ.valid, 0),
NextState("TSn-IDn")
).Elif(lane.rx_symbol == D(26,5),
NextValue(ts_idx, 3),
NextValue(self._tsZ.valid, 0),
NextState("TSn-IDn")
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
)
self.error.eq(1)
),
NextValue(id_ctr, 1),
NextValue(ts_id, lane.rx_symbol),
NextState("TSn-IDn")
)
self.fsm.act("TSn-IDn",
If(lane.rx_symbol != ts_id,
self.error.eq(1)
),
NextValue(id_ctr, id_ctr + 1),
If(lane.rx_symbol == ts_id,
If(id_ctr == 9,
If(self._tsZ.raw_bits() == self._tsY.raw_bits(),
NextValue(self.ts.raw_bits(), self._tsY.raw_bits())
).Else(
NextValue(self.ts.valid, 0)
),
If(ts_idx[1],
NextValue(lane.rx_invert, ~lane.rx_invert)
),
NextState("IDLE")
)
).Else(
self.ts_error.eq(1),
NextValue(self._tsZ.valid, 0),
NextState("IDLE")
If(id_ctr == 9,
If(self._tsZ.raw_bits() == self._tsY.raw_bits(),
NextValue(self.ts.raw_bits(), self._tsY.raw_bits())
).Else(
NextValue(self.ts.valid, 0)
),
If(ts_idx[1],
NextValue(lane.rx_invert, ~lane.rx_invert)
),
NextState("COMMA")
)
)

46 changes: 33 additions & 13 deletions yumewatari/test/phy.py
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ def phy_state(self):

def transmit(self, symbols):
for symbol in symbols:
assert (yield self.phy.ts_error) == 0
assert (yield self.phy.error) == 0
yield self.lane.rx_symbol.eq(symbol)
yield

@@ -41,10 +41,10 @@ def assertSignal(self, signal, value):
def test_rx_tsn_cycle_by_cycle(self, tb):
yield tb.lane.rx_symbol.eq(K(28,5))
yield
yield from self.assertState(tb, "IDLE")
yield from self.assertState(tb, "COMMA")
yield tb.lane.rx_symbol.eq(D(1,0))
yield
yield from self.assertState(tb, "TSn-LINK")
yield from self.assertState(tb, "TSn-LINK/SKP-0")
yield tb.lane.rx_symbol.eq(D(2,0))
yield
yield from self.assertSignal(tb.phy._tsZ.link.valid, 1)
@@ -81,7 +81,7 @@ def test_rx_tsn_cycle_by_cycle(self, tb):
yield tb.lane.rx_symbol.eq(K(28,5))
yield
yield from self.assertSignal(tb.phy._tsZ.valid, 1)
yield from self.assertState(tb, "IDLE")
yield from self.assertState(tb, "COMMA")

def assertTSnState(self, tsN, valid=1, link_valid=0, link_number=0,
lane_valid=0, lane_number=0, n_fts=0, rate_gen1=0,
@@ -98,11 +98,11 @@ def assertTSnState(self, tsN, valid=1, link_valid=0, link_number=0,
yield from self.assertSignal(tsN.ctrl.unscramble, ctrl_unscramble)
yield from self.assertSignal(tsN.ts_id, ts_id)

def assertTSError(self, tb):
yield from self.assertSignal(tb.phy.ts_error, 1)
def assertError(self, tb):
yield from self.assertSignal(tb.phy.error, 1)
yield
yield from self.assertSignal(tb.phy._tsZ.valid, 0)
yield from self.assertState(tb, "IDLE")
yield from self.assertState(tb, "COMMA")

@simulation_test
def test_rx_ts1_empty_valid(self, tb):
@@ -152,7 +152,7 @@ def test_rx_ts1_link_invalid(self, tb):
yield from self.tb.transmit([
K(28,5), 0x1ee,
])
yield from self.assertTSError(tb)
yield from self.assertError(tb)

@simulation_test
def test_rx_ts1_lane_valid(self, tb):
@@ -169,7 +169,7 @@ def test_rx_ts1_lane_invalid(self, tb):
yield from self.tb.transmit([
K(28,5), K(23,7), 0x1ee,
])
yield from self.assertTSError(tb)
yield from self.assertError(tb)

@simulation_test
def test_rx_ts1_n_fts_valid(self, tb):
@@ -187,7 +187,7 @@ def test_rx_ts1_n_fts_invalid(self, tb):
yield from self.tb.transmit([
K(28,5), K(23,7), K(23,7), 0x1ee
])
yield from self.assertTSError(tb)
yield from self.assertError(tb)

@simulation_test
def test_rx_ts1_n_rate_valid(self, tb):
@@ -206,7 +206,7 @@ def test_rx_ts1_n_rate_invalid(self, tb):
yield from self.tb.transmit([
K(28,5), K(23,7), K(23,7), 0xff, 0x1ee
])
yield from self.assertTSError(tb)
yield from self.assertError(tb)

@simulation_test
def test_rx_ts1_ctrl_valid(self, tb):
@@ -232,15 +232,15 @@ def test_rx_ts1_ctrl_invalid(self, tb):
yield from self.tb.transmit([
K(28,5), K(23,7), K(23,7), 0xff, 0b0010, 0x1ee
])
yield from self.assertTSError(tb)
yield from self.assertError(tb)

@simulation_test
def test_rx_ts1_idN_invalid(self, tb):
for n in range(10):
yield from self.tb.transmit([
K(28,5), 0xaa, 0x1a, 0xff, 0b0010, 0b0001, *[D(10,2) for _ in range(n)], 0x1ee
])
yield from self.assertTSError(tb)
yield from self.assertError(tb)

@simulation_test
def test_rx_ts1_2x_same_valid(self, tb):
@@ -270,6 +270,26 @@ def test_rx_ts1_3x_same_different_invalid(self, tb):
])
yield from self.assertSignal(tb.phy.ts.valid, 0)

@simulation_test
def test_rx_ts1_3x_same_different_invalid(self, tb):
yield from self.tb.transmit([
K(28,5), 0xaa, 0x1a, 0xff, 0b0010, 0b0000, *[D(10,2) for _ in range(10)],
K(28,5), 0xaa, 0x1a, 0xff, 0b0010, 0b0000, *[D(10,2) for _ in range(10)],
K(28,5), 0xaa, 0x1a, 0xff, 0b0010, 0b0001, *[D(10,2) for _ in range(10)],
K(28,5)
])
yield from self.assertSignal(tb.phy.ts.valid, 0)

@simulation_test
def test_rx_ts1_skp_ts1_valid(self, tb):
yield from self.tb.transmit([
K(28,5), 0xaa, 0x1a, 0xff, 0b0010, 0b0000, *[D(10,2) for _ in range(10)],
K(28,5), K(28,0), K(28,0), K(28,0),
K(28,5), 0xaa, 0x1a, 0xff, 0b0010, 0b0000, *[D(10,2) for _ in range(10)],
K(28,5)
])
yield from self.assertSignal(tb.phy.ts.valid, 1)


class PCIeTXPHYTestbench(Module):
def __init__(self):