def elaborate(self, platform): m = Module() # Received symbols are aligned and processed by the PCIePhyRX # The PCIePhyTX sends symbols to the SERDES #m.submodules.serdes = serdes = LatticeECP5PCIeSERDESx2() # Declare SERDES module with 1:2 gearing m.submodules.serdes = serdes = LatticeECP5PCIeSERDES( 2) # Declare SERDES module with 1:2 gearing m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), serdes.lane.rx_align.eq(1), ] uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart m.submodules.debug = UARTDebugger(uart, 9, CAPTURE_DEPTH, Cat(serdes.lane.rx_symbol, serdes.lane.tx_symbol, Signal(9 * 8 - 18 * 2)), "rx", timeout=100 * 1000 * 1000) return m
def elaborate(self, platform): m = Module() m.submodules.phy = ecp5_phy = LatticeECP5PCIePhy() phy = ecp5_phy.phy ltssm = phy.ltssm lane = phy.descrambled_lane # Temperature sensor, the chip gets kinda hot refclkcounter = Signal(32) m.d.sync += refclkcounter.eq(refclkcounter + 1) sample = Signal() m.d.sync += sample.eq(refclkcounter[25]) m.submodules.dtr = dtr = DTR(start=refclkcounter[25] & ~sample) leds_alnum = Cat(platform.request("alnum_led", 0)) m.d.comb += leds_alnum.eq(ltssm.debug_state) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor = int(100), pins = uart_pins) m.submodules += uart if NO_DEBUG: pass else: # 64t 9R 9R 9T 9T 2v 4- 6D # t = Ticks since state was entered # R = RX symbol # T = TX symbol # v = RX valid # D = DTR Temperature, does not correspond to real temperature besides the range of 21-29 °C. After that in 10 °C steps (30 = 40 °C, 31 = 50 °C etc...), see TN1266 time_since_state = Signal(64) with m.If(ltssm.debug_state != State.L0): m.d.rx += time_since_state.eq(0) with m.Else(): m.d.rx += time_since_state.eq(time_since_state + 1) m.submodules += UARTDebugger(uart, 14, CAPTURE_DEPTH, Cat( time_since_state, lane.rx_symbol, lane.tx_symbol, lane.rx_locked & lane.rx_present & lane.rx_aligned, lane.rx_locked & lane.rx_present & lane.rx_aligned, Signal(4), Signal(4), phy.dll.tx.started_sending, phy.dll.tx.started_sending#dtr.temperature ), "rx") return m
def elaborate(self, platform): m = Module() m.submodules.serdes = serdes = LatticeECP5PCIeSERDES(2) m.submodules.aligner = lane = DomainRenamer("rx")(PCIeSERDESAligner( serdes.lane)) #m.submodules.phy_rx = phy_rx = PCIePhyRX(lane) #lane = serdes.lane m.d.comb += [ # serdes.txd.eq(K(28,5)), #lane.rx.eq(1), Crucial? lane.rx_invert.eq(0), lane.rx_align.eq(1), ] #m.domains.sync = ClockDomain() m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ #ClockSignal("sync").eq(serdes.refclk), ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] cntr = Signal(5) #with m.If(cntr == 0): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.COM) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) #with m.Elif(cntr == 1): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) #with m.Elif(cntr == 2): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.EIE) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.EDB) #with m.Elif(cntr == 3): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.STP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SDP) #with m.Elif(cntr == 4): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.IDL) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.EIE) #with m.Elif(cntr == 5): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.EDB) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.EDB) #with m.Elif(cntr == 6): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.EIE) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.EIE) #with m.Elif(cntr == 7): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.END) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.END) #with m.Elif(cntr == 8): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.IDL) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.IDL) #with m.Else(): # m.d.tx += lane.tx_symbol.eq(cntr) with m.If(cntr == 0): m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.COM) m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) with m.Elif(cntr == 1): m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) #with m.Elif(cntr == 6): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.COM) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) #with m.Elif(cntr == 7): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) # #with m.Elif(cntr == 12): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.IDL) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.COM) #with m.Elif(cntr == 13): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) #with m.Elif(cntr == 14): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.IDL) # #with m.Elif(cntr == 20): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.IDL) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.COM) #with m.Elif(cntr == 21): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) #with m.Elif(cntr == 22): # m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.SKP) # m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.IDL) with m.Else(): m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.IDL) m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.IDL) #m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.COM) #m.d.tx += lane.tx_symbol[9:18].eq(cntr) m.d.tx += cntr.eq(cntr + 1) #with m.FSM(domain="tx"): # with m.State("1"): # m.d.tx += lane.tx_symbol.eq(Ctrl.COM) # m.next = "2" # with m.State("2"): # m.d.tx += lane.tx_symbol.eq(Ctrl.SKP) # m.d.tx += cntr.eq(cntr + 1) # with m.If(cntr == 3): # m.d.tx += cntr.eq(0) # m.next = "1" platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) m.d.comb += platform.request("test", 1).o.eq(ClockSignal("tx")) refclkcounter = Signal(32) m.d.sync += refclkcounter.eq(refclkcounter + 1) rxclkcounter = Signal(32) m.d.rx += rxclkcounter.eq(rxclkcounter + 1) txclkcounter = Signal(32) m.d.tx += txclkcounter.eq(txclkcounter + 1) led_att1 = platform.request("led", 0) led_att2 = platform.request("led", 1) led_sta1 = platform.request("led", 2) led_sta2 = platform.request("led", 3) led_err1 = platform.request("led", 4) led_err2 = platform.request("led", 5) led_err3 = platform.request("led", 6) led_err4 = platform.request("led", 7) m.d.rx += lane.det_enable.eq(1) m.d.comb += [ led_att1.eq(~(refclkcounter[25])), led_att2.eq(~(serdes.lane.rx_aligned)), led_sta1.eq(~(rxclkcounter[25])), led_sta2.eq(~(txclkcounter[25])), led_err1.eq(~(serdes.lane.rx_present)), led_err2.eq(~(serdes.lane.rx_locked | serdes.lane.tx_locked)), led_err3.eq(~(lane.det_valid)), #serdes.rxde0)), led_err4.eq(~(lane.det_status)), #serdes.rxce0)), ] triggered = Const(1) #m.d.tx += triggered.eq((triggered ^ ((lane.rx_symbol[0:9] == Ctrl.EIE) | (lane.rx_symbol[9:18] == Ctrl.EIE)))) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart #m.d.rx += lane.tx_e_idle.eq(1) debug = UARTDebugger(uart, 4, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_valid[0], Signal(6), lane.rx_symbol[9:18], lane.rx_valid[1], Signal(6)), "rx", triggered) # lane.rx_present & lane.rx_locked) # You need to add the SERDES within the SERDES as a self. attribute for this to work #debug = UARTDebugger(uart, 4, CAPTURE_DEPTH, Cat(serdes.serdes.lane.rx_symbol[0:9], cntr == 0, Signal(6), Signal(9), lane.rx_valid[0] | lane.rx_valid[1], Signal(6)), "rxf", triggered) # lane.rx_present & lane.rx_locked) m.submodules += debug return m
def elaborate(self, platform): m = Module() m.submodules.serdes = serdes = LatticeECP5PCIeSERDES(1) m.submodules.lane = lane = serdes.lane #lane = serdes.lane m.d.comb += [ # serdes.txd.eq(K(28,5)), #lane.rx.eq(1), Crucial? lane.rx_invert.eq(0), lane.rx_align.eq(1), ] #m.domains.sync = ClockDomain() m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ #ClockSignal("sync").eq(serdes.refclk), ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] cntr = Signal(5) with m.If(cntr == 0): m.d.tx += lane.tx_symbol.eq(Ctrl.COM) with m.Elif(cntr == 1): m.d.tx += lane.tx_symbol.eq(Ctrl.SKP) with m.Elif(cntr == 2): m.d.tx += lane.tx_symbol.eq(Ctrl.SKP) with m.Elif(cntr == 3): m.d.tx += lane.tx_symbol.eq(Ctrl.SKP) with m.Elif(cntr == 4): m.d.tx += lane.tx_symbol.eq(Ctrl.STP) with m.Elif(cntr[2:] == 2): m.d.tx += lane.tx_symbol.eq(Ctrl.EDB) with m.Elif(cntr[2:] == 3): m.d.tx += lane.tx_symbol.eq(Ctrl.EIE) with m.Elif(cntr[2:] == 4): m.d.tx += lane.tx_symbol.eq(Ctrl.END) with m.Elif(cntr[2:] == 5): m.d.tx += lane.tx_symbol.eq(Ctrl.IDL) with m.Else(): m.d.tx += lane.tx_symbol.eq(cntr) m.d.tx += cntr.eq(cntr + 1) #with m.FSM(domain="tx"): # with m.State("1"): # m.d.tx += lane.tx_symbol.eq(Ctrl.COM) # m.next = "2" # with m.State("2"): # m.d.tx += lane.tx_symbol.eq(Ctrl.SKP) # m.d.tx += cntr.eq(cntr + 1) # with m.If(cntr == 3): # m.d.tx += cntr.eq(0) # m.next = "1" platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) m.d.comb += platform.request("test", 1).o.eq(ClockSignal("tx")) #refclkcounter = Signal(32) #m.d.sync += refclkcounter.eq(refclkcounter + 1) #rxclkcounter = Signal(32) #m.d.rx += rxclkcounter.eq(rxclkcounter + 1) #txclkcounter = Signal(32) #m.d.tx += txclkcounter.eq(txclkcounter + 1) led_att1 = platform.request("led", 0) led_att2 = platform.request("led", 1) led_sta1 = platform.request("led", 2) led_sta2 = platform.request("led", 3) led_err1 = platform.request("led", 4) led_err2 = platform.request("led", 5) led_err3 = platform.request("led", 6) led_err4 = platform.request("led", 7) m.d.rx += lane.det_enable.eq(1) m.d.comb += [ led_att2.eq(~(serdes.lane.rx_aligned)), led_err1.eq(~(serdes.lane.rx_present)), led_err2.eq(~(serdes.lane.rx_locked | serdes.lane.tx_locked)), led_err3.eq(~(lane.det_valid)), #serdes.rxde0)), led_err4.eq(~(lane.det_status)), #serdes.rxce0)), ] triggered = Signal(reset=1) #m.d.tx += triggered.eq((triggered ^ ((lane.rx_symbol[0:9] == Ctrl.EIE) | (lane.rx_symbol[9:18] == Ctrl.EIE)))) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart #m.d.rx += lane.tx_e_idle.eq(1) debug = UARTDebugger(uart, 2, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6)), "rx", triggered) # lane.rx_present & lane.rx_locked) m.submodules += debug return m
def elaborate(self, platform): m = Module() gearing = 1 m.submodules.serdes = serdes = LatticeECP5PCIeSERDES( gearing) # Declare SERDES module with 1:2 gearing lane = serdes.lane m.d.comb += lane.tx_e_idle.eq(0) m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] # Clock outputs for the RX and TX clock domain platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) m.d.comb += platform.request("test", 1).o.eq(ClockSignal("tx")) # Counters for the LEDs refclkcounter = Signal(32) m.d.sync += refclkcounter.eq(refclkcounter + 1) rxclkcounter = Signal(32) m.d.rx += rxclkcounter.eq(rxclkcounter + 1) txclkcounter = Signal(32) m.d.tx += txclkcounter.eq(txclkcounter + 1) old_rx = Signal(8) m.d.sync += old_rx.eq(Cat(lane.rx_symbol[0:8])) tx_symbol = Signal(9, reset=56) timer = Signal(32) fftest_a = Signal(32) fftest_b = Signal(32) fftest_a_last = Signal(32) slipcnt = Signal(5) lastslip = Signal() m.d.rx += serdes.slip.eq(rxclkcounter[2]) m.d.sync += lastslip.eq(serdes.slip) with m.If(serdes.slip & ~lastslip): with m.If(slipcnt < (10 * gearing - 1)): m.d.sync += slipcnt.eq(slipcnt + 1) with m.Else(): m.d.sync += slipcnt.eq(0) leds = Cat(platform.request("led", i) for i in range(8)) m.d.comb += leds[0].eq(~serdes.lane.rx_locked) m.d.comb += leds[1].eq(~serdes.lane.rx_present) #m.submodules += FFSynchronizer(fftest_a, fftest_b, o_domain="tx") with m.FSM(): #with m.State("Align"): # m.d.rx += fftest_a.eq(~fftest_a) # m.d.rx += timer.eq(timer + 1) # m.d.rx += fftest_a_last.eq(fftest_a) # m.d.tx += fftest_b.eq(fftest_a) # # with m.If(fftest_b != fftest_a_last): # m.d.rx += timer.eq(0) # # m.d.rx += serdes.slip.eq(rxclkcounter[10]) # # with m.If(timer == 128): # m.next = "BERTest" # # # m.next = "BERTest" with m.State("Align2"): last_rxclkcounter = Signal(32) m.d.rx += last_rxclkcounter.eq(rxclkcounter) m.d.rx += timer.eq(timer + 1) m.d.rx += tx_symbol.eq(Ctrl.STP) cond = (Cat(lane.rx_symbol[0:9]) == Ctrl.STP) & (Cat( lane.rx_symbol[9:18]) == Ctrl.COM) with m.If( rxclkcounter[8] & ~last_rxclkcounter[8] ): #~((Cat(lane.rx_symbol[0:9]) - old_rx == 0) | (Cat(lane.rx_symbol[0:9]) - old_rx == -2))) with m.If(cond): m.d.rx += timer.eq(0) m.next = "BERTest" with m.Else(): pass #m.d.rx += serdes.slip.eq(~serdes.slip) # Invert Lane if too long errored m.d.rx += lane.rx_invert.eq(timer[16]) with m.State("BERTest"): m.d.rx += lane.tx_disp.eq(0) #m.d.rx += lane.tx_set_disp.eq(1) m.d.rx += timer.eq(timer + 1) m.d.rx += tx_symbol.eq(Cat(timer[0:8], 0)) m.d.rx += lane.rx_invert.eq(1) #m.d.rx += tx_symbol.eq(tx_symbol + 1) commacnt = Signal(3) #m.d.sync += commacnt.eq(commacnt + 1) with m.If(commacnt == 6): m.d.sync += commacnt.eq(0) #m.d.comb += Cat(serdes.lane.tx_symbol[0:9]).eq(Mux(commacnt == 2, Ctrl.COM, Ctrl.STP))#(tx_symbol) m.d.comb += Cat(serdes.lane.tx_symbol[0:9]).eq(0b101010101) m.d.comb += Cat(serdes.lane.tx_symbol[9:18]).eq(Ctrl.COM) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart m.d.sync += lane.rx_align.eq(1) #debug = UARTDebugger(uart, 8, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6), lane.rx_symbol[9:18], lane.rx_valid[0] | lane.rx_valid[1], Signal(6), # lane.tx_symbol[0:9], Signal(7), lane.tx_symbol[9:18], Signal(7)), "rx") #debug = UARTDebugger(uart, 8, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6), lane.rx_symbol[9:18], lane.rx_valid[0] | lane.rx_valid[1], Signal(6), # serdes.tx_bus_s_2[0:9], Signal(7), serdes.tx_bus_s_2[12:21], Signal(7)), "rx") #debug = UARTDebugger(uart, 8, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6+9), lane.rx_valid[0], Signal(6), # serdes.tx_bus_s_2[0:9], Signal(7+9), Signal(7)), "rx") #debug = UARTDebugger(uart, 9, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6+9), lane.rx_valid[0], Signal(6), # serdes.tx_bus[0:9], Signal(7+9), Signal(7), Cat(slipcnt, lane.rx_present, lane.rx_locked, lane.rx_valid)), "rx") debug = UARTDebugger( uart, 9, CAPTURE_DEPTH, Cat(serdes.rx_bus[0:10], lane.rx_aligned, Signal(5 + 9), lane.rx_valid[0], Signal(6), serdes.tx_bus[0:10], Signal(6 + 9), Signal(7), Cat(slipcnt, lane.rx_present, lane.rx_locked, lane.rx_valid)), "rx") m.submodules += debug return m
def elaborate(self, platform): platform.add_resources([ Resource( "pcie_x1", 0, Subsignal("perst", Pins("A6"), Attrs(IO_TYPE="LVCMOS33")), ) ]) m = Module() uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) cd_serdes = ClockDomain() m.domains += cd_serdes m.domains.gearout = ClockDomain() serdes = LatticeECP5PCIeSERDES() #aligner = DomainRenamer("rx")(PCIeSERDESAligner(serdes.lane)) # The lane dout = Signal(4 * 4 * 12) m.submodules += DomainRenamer("rx")( Resizer( Cat( #Signal(9, reset=0xFE), Signal(6, reset=0), Signal(1, reset=1), Signal(8,reset=0), #Signal(9, reset=0xDC), Signal(6, reset=0), Signal(1, reset=1), Signal(8,reset=2), serdes.lane.rx_symbol.word_select(0, 9), Signal(6, reset=0), serdes.lane.rx_valid[0], serdes.lane.det_valid, serdes.lane.det_status, serdes.lane.rx_present, serdes.lane.rx_locked, serdes.lane.rx_aligned, Signal(3), serdes.lane.rx_symbol.word_select(1, 9), Signal(6, reset=0), serdes.lane.rx_valid[1], Signal(8, reset=0x11), ), dout, ClockSignal("gearout"))) platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) # Arduino tx m.d.comb += platform.request("test").o.eq(ClockSignal("gearout")) debug = UARTDebugger( uart, 24, 1000, dout, "gearout") # serdes.lane.rx_present & serdes.lane.rx_locked) m.submodules += [ uart, serdes, # aligner, debug, ] m.d.comb += [ cd_serdes.clk.eq(serdes.rx_clk_o), serdes.rx_clk_i.eq(cd_serdes.clk), serdes.tx_clk_i.eq(cd_serdes.clk), serdes.lane.rx_align.eq(1), serdes.lane.tx_symbol.eq(K(28, 3)), serdes.lane.rx_invert.eq(0), #aligner.rx_align.eq(1), serdes.lane.det_enable.eq(0), ] m.d.sync += platform.request("led", 0).o.eq(~serdes.lane.det_valid) m.d.sync += platform.request("led", 1).o.eq(~serdes.lane.det_status) m.d.sync += platform.request("led", 2).o.eq(~serdes.lane.rx_present) m.d.sync += platform.request("led", 3).o.eq(~serdes.lane.rx_locked) m.d.sync += platform.request("led", 4).o.eq(~serdes.lane.rx_aligned) m.d.sync += platform.request("led", 5).o.eq(~(serdes.lane.rx_locked)) m.d.sync += platform.request("led", 6).o.eq(~(serdes.lane.tx_locked)) m.d.sync += platform.request("led", 7).o.eq(~1) #with m.FSM(): # with m.State("start"): # m.next = "a" # with m.State("a"): # m.d.sync += serdes.lane.det_enable.eq(0) return m
def elaborate(self, platform): m = Module() # Received symbols are aligned and processed by the PCIePhyRX # The PCIePhyTX sends symbols to the SERDES m.submodules.serdes = serdes = LatticeECP5PCIeSERDESx4(speed_5GTps=True) # Declare SERDES module with 1:2 gearing m.submodules.aligner = aligner = DomainRenamer("rx")(PCIeSERDESAligner(serdes.lane)) # Aligner for aligning COM symbols m.submodules.phy = phy = PCIePhy(aligner) lane = phy.descrambled_lane phy_rx = phy.rx phy_tx = phy.tx ltssm = phy.ltssm m.d.comb += lane.speed.eq(LinkSpeed.S2_5) #m.submodules.scrambler = lane = PCIeScrambler(aligner) # Aligner for aligning COM symbols #lane = serdes.lane # Aligner for aligning COM symbols #m.submodules.phy_rx = phy_rx = PCIePhyRX(aligner, lane) #m.submodules.phy_tx = phy_tx = PCIePhyTX(lane) #m.submodules.lfsr = lfsr = PCIeLFSR(0, 1) #m.submodules.phy_txfake = phy_txfake = PCIePhyTX(PCIeSERDESInterface(ratio = 2)) # Link Status Machine to test #m.submodules.ltssm = ltssm = PCIeLTSSM(lane, phy_tx, phy_rx) #m.submodules.ltssm = ltssm = PCIeLTSSM(lane, phy_tx, phy_rx) #m.d.comb += [ # phy_tx.ts.eq(0), # phy_tx.ts.valid.eq(1), # phy_tx.ts.rate.eq(1), # phy_tx.ts.ctrl.eq(0) #] #TODO m.d.rx += lane.enable.eq(ltssm.status.link.scrambling & ~phy_tx.sending_ts) m.d.comb += [ #lane.rx_invert.eq(0), #serdes.lane.rx_align.eq(1), ] m.d.comb += [ #lane.rx_invert.eq(0), #lane.rx_align.eq(1), ] # Declare the RX and TX clock domain, most of the logic happens in the RX domain m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] # Clock outputs for the RX and TX clock domain #platform.add_resources([Resource("test", 0, Pins("B17", dir="o"))]) # X4 33 platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) # X3 4 m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) # X4 39 m.d.comb += platform.request("test", 1).o.eq(ClockSignal("rxf")) # Counters for the LEDs refclkcounter = Signal(32) m.d.sync += refclkcounter.eq(refclkcounter + 1) rxclkcounter = Signal(32) m.d.rx += rxclkcounter.eq(rxclkcounter + 1) txclkcounter = Signal(32) m.d.tx += txclkcounter.eq(txclkcounter + 1) #m.d.rx += serdes.slip.eq(rxclkcounter[25]) ## Sample temperature once a second #m.d.sync += dtr.start.eq(refclkcounter[25]) # Temperature sensor, the chip gets kinda hot sample = Signal() m.d.sync += sample.eq(refclkcounter[25]) m.submodules.dtr = dtr = DTR(start=refclkcounter[25] & ~sample) # Can be used to count how many cycles det_status is on, currently unused detstatuscounter = Signal(7) with m.If(lane.det_valid & lane.det_status): m.d.tx += detstatuscounter.eq(detstatuscounter + 1) leds = Cat(platform.request("led", i) for i in range(8)) leds_alnum = Cat(platform.request("alnum_led", 0)) # Information LEDs, first three output the clock frequency of the clock domains divided by 2^26 #m.d.comb += [ # leds[0].eq(~(refclkcounter[25])), # leds[2].eq(~(rxclkcounter[25])), # leds[3].eq(~(txclkcounter[25])), # leds[1].eq(~(serdes.lane.rx_aligned)), # leds[4].eq(~(serdes.lane.rx_present)), # leds[5].eq(~(serdes.lane.rx_locked | serdes.lane.tx_locked)), # leds[6].eq(~(0)),#serdes.rxde0)), # leds[7].eq(~(ltssm.status.link.up)),#serdes.rxce0)), #] m.d.comb += leds_alnum.eq(ltssm.debug_state) #m.d.comb += leds.eq(~Cat(serdes.serdes.lane.rx_locked, serdes.serdes.lane.tx_locked, serdes.serdes.lane.reset, serdes.serdes.lane.reset_done, Const(0, 5))) div = Signal(32) m.d.rx += div.eq(div + 1) m.d.comb += leds.eq(div[24:]) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor = int(100), pins = uart_pins) m.submodules += uart # In the default mode, there are some extra words for debugging data debug1 = Signal(16) debug2 = Signal(16) debug3 = Signal(16) debug4 = Signal(16) # For example data from the LTSSM m.d.comb += debug1.eq(ltssm.tx_ts_count) m.d.comb += debug2.eq(ltssm.rx_ts_count) # Or data about TSs m.d.comb += debug3.eq(Cat(phy_rx.ts.valid, phy_rx.ts.lane.valid, phy_rx.ts.link.valid, phy_rx.ts.ts_id)) m.d.comb += debug4.eq(1234) if NO_DEBUG: pass if self.tstest: # l = Link Number, L = Lane Number, v = Link Valid, V = Lane Valid, t = TS Valid, T = TS ID, n = FTS count, r = TS.rate, c = TS.ctrl, d = lane.det_status, D = lane.det_valid # DdTcccccrrrrrrrrnnnnnnnnLLLLLtVvllllllll debug = UARTDebugger(uart, 5, CAPTURE_DEPTH, Cat(phy_rx.ts.link.number, phy_rx.ts.link.valid, phy_rx.ts.lane.valid, phy_rx.ts.valid, phy_rx.ts.lane.number, phy_rx.ts.n_fts, phy_rx.ts.rate, phy_rx.ts.ctrl, phy_rx.ts.ts_id, lane.det_status, lane.det_valid), "rx") # lane.rx_present & lane.rx_locked) #debug = UARTDebugger(uart, 5, CAPTURE_DEPTH, Cat(ts.link.number, ts.link.valid, ts.lane.valid, ts.valid, ts.lane.number, ts.n_fts, ts.rate, ts.ctrl, ts.ts_id, Signal(2)), "rx") # lane.rx_present & lane.rx_locked) #debug = UARTDebugger(uart, 5, CAPTURE_DEPTH, Cat(Signal(8, reset=123), Signal(4 * 8)), "rx") # lane.rx_present & lane.rx_locked) elif STATE_TEST: # 32t 9R 9R 9T 9T 2v 2- # t = Ticks since state was entered # R = RX symbol # T = TX symbol # v = RX valid time_since_state = Signal(32) with m.If(ltssm.debug_state != TESTING_STATE): m.d.rx += time_since_state.eq(0) with m.Else(): m.d.rx += time_since_state.eq(time_since_state + 1) #m.d.rx += time_since_state.eq(ltssm.time_since_last_skp_or_idle) #m.d.rx += time_since_state.eq(ltssm.status.link.scrambling) #m.d.rx += time_since_state.eq(ltssm.rx_idl_count_total) #m.d.rx += time_since_state.eq(Cat(phy_rx.inverted, lane.rx_invert)) debug = UARTDebugger(uart, 14, CAPTURE_DEPTH, Cat( time_since_state, lane.rx_symbol, lane.tx_symbol, lane.rx_locked & lane.rx_present & lane.rx_aligned, lane.rx_locked & lane.rx_present & lane.rx_aligned, Signal(6) ), "rx", (ltssm.debug_state == TESTING_STATE), timeout=100 * 1000 * 1000)# & (time_since_state < CAPTURE_DEPTH), timeout=100 * 1000 * 1000) elif FSM_LOG: # Keep track of time in 8 nanosecond increments time = Signal(64) m.d.rx += time.eq(time + 1) #with m.If(serdes.serdes.lane.reset): # m.d.rx += time.eq(time + 1) # Real time in 10 ns ticks, doesnt drift or change in frequency as compared to the RX clock domain. realtime = Signal(64) m.d.sync += realtime.eq(realtime + 1) # Real time FF sync realtime_rx = Signal(64) #m.submodules += FFSynchronizer(realtime, realtime_rx, o_domain="rx") #with m.If((serdes.lane.rx_symbol[0:9] == Ctrl.STP) | (serdes.lane.rx_symbol[27:36] == Ctrl.STP)): # m.d.rx += realtime_rx.eq(realtime_rx + 1) m.d.rx += realtime_rx.eq(phy.dll_tlp_rx.buffer.slots_occupied) #errors = Signal(64) #with m.If(): # m.d.rx += errors.eq(errors + 1) #m.d.rx += realtime_rx.eq(ltssm.time_since_last_skp_or_idle) last_state = Signal(8) m.d.rx += last_state.eq(ltssm.debug_state) # 8o 8c 64t 64r 32i 6T 1v 1- 8l 5L o O 1- # o = old state, c = current state, t = time, r = realtime, i = idle count, T = temperature, v = temperature valid, - = empty, l = link, L = lane, o = link valid, O = lane valid # preceding number is number of bits #debug = UARTDebugger2(uart, 25, CAPTURE_DEPTH, Cat( # last_state, ltssm.debug_state, time, realtime_rx, Signal(32), dtr.temperature, Signal(1), dtr.valid, # phy_rx.ts.link.number, phy_rx.ts.lane.number, phy_rx.ts.link.valid, phy_rx.ts.lane.valid, Signal(1) # ), "rx", ltssm.debug_state != last_state, timeout=100 * 1000 * 1000) debug = UARTDebugger2(uart, 25, CAPTURE_DEPTH, Cat( last_state, ltssm.debug_state, time, realtime_rx, serdes.debug.dco_status, Signal(24), dtr.temperature, Signal(1), dtr.valid, phy_rx.ts.link.number, phy_rx.ts.lane.number, phy_rx.ts.link.valid, phy_rx.ts.lane.valid, Signal(1) ), "rx", ltssm.debug_state != last_state, timeout=100 * 1000 * 1000) else: # ssssssss sa000000 ssssssss sb000000 llllllll SSSSSSSS S0000000 SSSSSSSS S0000000 dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd dddddddd s = rx_symbol, S = tx_symbol, a = aligned, b = valid, l = ltssm state, d = debug debug = UARTDebugger(uart, 17, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6), lane.rx_symbol[9:18], lane.rx_valid[0] | lane.rx_valid[1], Signal(6), ltssm.debug_state, lane.tx_symbol[0:9], Signal(7), lane.tx_symbol[9:18], Signal(7), debug1, debug2, debug3, debug4), "rx") # lane.rx_present & lane.rx_locked) m.submodules += debug return m
def elaborate(self, platform): m = Module() m.submodules.serdes = serdes = LatticeECP5PCIeSERDESx4( speed_5GTps=False, CH=0) m.submodules.aligner = lane = DomainRenamer("rx")(PCIeSERDESAligner( serdes.lane)) m.d.comb += [ lane.rx_invert.eq(0), lane.rx_align.eq(1), ] #m.domains.sync = ClockDomain() m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ #ClockSignal("sync").eq(serdes.refclk), ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] cntr = Signal(1) with m.If(cntr[0]): m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.COM) m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.SKP) m.d.tx += lane.tx_symbol[18:27].eq(Ctrl.SKP) m.d.tx += lane.tx_symbol[27:36].eq(Ctrl.SKP) with m.Else(): m.d.tx += lane.tx_symbol[0:9].eq(Ctrl.IDL) m.d.tx += lane.tx_symbol[9:18].eq(Ctrl.IDL) m.d.tx += lane.tx_symbol[18:27].eq(Ctrl.IDL) m.d.tx += lane.tx_symbol[27:36].eq(Ctrl.IDL) m.d.tx += cntr.eq(cntr + 1) platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) m.d.comb += platform.request("test", 1).o.eq(ClockSignal("tx")) leds = [] for i in range(8): leds.append(platform.request("led", i)) m.d.rx += Cat(leds).eq(lane.rx_symbol[0:8] ^ lane.rx_symbol[8:16] ^ lane.rx_symbol[16:24] ^ lane.rx_symbol[24:32] ^ Cat(lane.rx_symbol[32:36], Signal(4))) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart #m.d.rx += lane.tx_e_idle.eq(1) debug = UARTDebugger( uart, 8, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_valid[0], Signal(6), lane.rx_symbol[9:18], lane.rx_valid[1], Signal(6), lane.rx_symbol[18:27], lane.rx_valid[2], Signal(6), lane.rx_symbol[27:36], lane.rx_valid[3], Signal(6)), "rx") m.submodules += debug return m
def elaborate(self, platform): m = Module() m.submodules.serdes = serdes = LatticeECP5PCIeSERDES(2) m.submodules.aligner = lane = DomainRenamer("rx")(PCIeSERDESAligner( serdes.lane)) m.d.comb += [ lane.rx_invert.eq(0), lane.rx_align.eq(1), ] m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) m.d.comb += platform.request("test", 1).o.eq(ClockSignal("tx")) led_att1 = platform.request("led", 0) led_att2 = platform.request("led", 1) led_sta1 = platform.request("led", 2) led_sta2 = platform.request("led", 3) led_err1 = platform.request("led", 4) led_err2 = platform.request("led", 5) led_err3 = platform.request("led", 6) led_err4 = platform.request("led", 7) #m.d.comb += [ # led_att1.eq(~(ClockSignal("rx") ^ ClockSignal("tx"))), #] count = Signal() refclkcounter = Signal(64) txclkcounter = Signal(64) rxclkcounter = Signal(64) with m.If(count): m.d.sync += refclkcounter.eq(refclkcounter + 1) m.d.tx += txclkcounter.eq(txclkcounter + 1) m.d.rx += rxclkcounter.eq(rxclkcounter + 1) counter = Signal(16) sample = Signal() with m.FSM(): with m.State("Wait"): m.d.sync += count.eq(1) m.d.sync += counter.eq(counter + 1) with m.If(counter == 0xFFFF): m.d.sync += count.eq(0) m.d.sync += counter.eq(0) m.next = "Sample Delay" with m.State("Sample Delay"): m.d.sync += counter.eq(counter + 1) with m.If(counter == 0xF): m.d.sync += counter.eq(0) m.next = "Sample" with m.State("Sample"): m.d.sync += sample.eq(1) m.next = "Sample After Delay" with m.State("Sample After Delay"): m.d.sync += sample.eq(0) m.d.sync += counter.eq(counter + 1) with m.If(counter == 0xF): m.d.sync += counter.eq(0) m.next = "Wait" uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart debug = UARTDebugger(uart, 8 * 3, CAPTURE_DEPTH, Cat(refclkcounter, txclkcounter, rxclkcounter), "sync", sample) # lane.rx_present & lane.rx_locked) m.submodules += debug return m
def elaborate(self, platform): m = Module() m.submodules.serdes = serdes = LatticeECP5PCIeSERDES(2) m.submodules.aligner = lane = DomainRenamer("rx")(PCIeSERDESAligner( serdes.lane)) m.submodules.phy_rx = phy_rx = PCIePhyRX(lane) #lane = serdes.lane m.d.comb += [ # serdes.txd.eq(K(28,5)), #lane.rx.eq(1), Crucial? lane.rx_invert.eq(0), lane.rx_align.eq(1), ] #m.domains.sync = ClockDomain() m.domains.rx = ClockDomain() m.domains.tx = ClockDomain() m.d.comb += [ #ClockSignal("sync").eq(serdes.refclk), ClockSignal("rx").eq(serdes.rx_clk), ClockSignal("tx").eq(serdes.tx_clk), ] cntr = Signal(8) #m.d.tx += lane.tx_symbol.eq(Ctrl.IDL) with m.FSM(domain="tx"): with m.State("1"): m.d.tx += lane.tx_symbol.eq(Ctrl.COM) m.next = "2" with m.State("2"): m.d.tx += lane.tx_symbol.eq(Ctrl.SKP) m.d.tx += cntr.eq(cntr + 1) with m.If(cntr == 3): m.d.tx += cntr.eq(0) m.next = "1" platform.add_resources([Resource("test", 0, Pins("B19", dir="o"))]) m.d.comb += platform.request("test", 0).o.eq(ClockSignal("rx")) platform.add_resources([Resource("test", 1, Pins("A18", dir="o"))]) m.d.comb += platform.request("test", 1).o.eq(ClockSignal("tx")) refclkcounter = Signal(32) m.d.sync += refclkcounter.eq(refclkcounter + 1) rxclkcounter = Signal(32) m.d.rx += rxclkcounter.eq(rxclkcounter + 1) txclkcounter = Signal(32) m.d.tx += txclkcounter.eq(txclkcounter + 1) led_att1 = platform.request("led", 0) led_att2 = platform.request("led", 1) led_sta1 = platform.request("led", 2) led_sta2 = platform.request("led", 3) led_err1 = platform.request("led", 4) led_err2 = platform.request("led", 5) led_err3 = platform.request("led", 6) led_err4 = platform.request("led", 7) m.d.rx += lane.det_enable.eq(1) m.d.comb += [ led_att1.eq(~(refclkcounter[25])), led_att2.eq(~(serdes.lane.rx_aligned)), led_sta1.eq(~(rxclkcounter[25])), led_sta2.eq(~(txclkcounter[25])), led_err1.eq(~(serdes.lane.rx_present)), led_err2.eq(~(serdes.lane.rx_locked | serdes.lane.tx_locked)), led_err3.eq(~(lane.det_valid)), #serdes.rxde0)), led_err4.eq(~(lane.det_status)), #serdes.rxce0)), ] triggered = Signal(reset=1) #m.d.tx += triggered.eq((triggered ^ ((lane.rx_symbol[0:9] == Ctrl.EIE) | (lane.rx_symbol[9:18] == Ctrl.EIE)))) uart_pins = platform.request("uart", 0) uart = AsyncSerial(divisor=int(100), pins=uart_pins) m.submodules += uart m.d.rx += lane.tx_e_idle.eq(1) if self.tstest: # l = Link Number, L = Lane Number, v = Link Valid, V = Lane Valid, t = TS Valid, T = TS ID, n = FTS count, r = TS.rate, c = TS.ctrl, d = lane.det_status, D = lane.det_valid # DdTcccccrrrrrrrrnnnnnnnnLLLLLtVvllllllll debug = UARTDebugger( uart, 5, CAPTURE_DEPTH, Cat(phy_rx.ts.link.number, phy_rx.ts.link.valid, phy_rx.ts.lane.valid, phy_rx.ts.valid, phy_rx.ts.lane.number, phy_rx.ts.n_fts, phy_rx.ts.rate, phy_rx.ts.ctrl, phy_rx.ts.ts_id, lane.det_status, lane.det_valid), "rx") # lane.rx_present & lane.rx_locked) #debug = UARTDebugger(uart, 5, CAPTURE_DEPTH, Cat(ts.link.number, ts.link.valid, ts.lane.valid, ts.valid, ts.lane.number, ts.n_fts, ts.rate, ts.ctrl, ts.ts_id, Signal(2)), "rx") # lane.rx_present & lane.rx_locked) #debug = UARTDebugger(uart, 5, CAPTURE_DEPTH, Cat(Signal(8, reset=123), Signal(4 * 8)), "rx") # lane.rx_present & lane.rx_locked) else: debug = UARTDebugger( uart, 4, CAPTURE_DEPTH, Cat(lane.rx_symbol[0:9], lane.rx_aligned, Signal(6), lane.rx_symbol[9:18], lane.rx_valid[0] | lane.rx_valid[1], Signal(6)), "rx", triggered) # lane.rx_present & lane.rx_locked) m.submodules += debug return m