gateware/serwb: SERWBPLL, SERWBPHY, SERWBCore and add checks in delay finding to verify the sampling window

This commit is contained in:
Florent Kermarrec 2017-08-30 14:31:44 +02:00
parent 9ba50098a8
commit 41d57d64f6
6 changed files with 182 additions and 161 deletions

View File

@ -1 +1 @@
from artiq.gateware.serwb import s7phy, kusphy, phy, packet, etherbone from artiq.gateware.serwb import s7phy, kusphy, phy, core, packet, etherbone

View File

@ -0,0 +1,37 @@
from migen import *
from misoc.interconnect import stream
from artiq.gateware.serwb.packet import Depacketizer, Packetizer
from artiq.gateware.serwb.etherbone import Etherbone
class SERWBCore(Module):
def __init__(self, phy, clk_freq, mode):
self.submodules.etherbone = etherbone = Etherbone(mode)
depacketizer = Depacketizer(clk_freq)
packetizer = Packetizer()
self.submodules += depacketizer, packetizer
tx_cdc = stream.AsyncFIFO([("data", 32)], 8)
tx_cdc = ClockDomainsRenamer({"write": "sys", "read": "serdes"})(tx_cdc)
self.submodules += tx_cdc
rx_cdc = stream.AsyncFIFO([("data", 32)], 8)
rx_cdc = ClockDomainsRenamer({"write": "serdes", "read": "sys"})(rx_cdc)
self.submodules += rx_cdc
self.comb += [
# core <--> etherbone
depacketizer.source.connect(etherbone.sink),
etherbone.source.connect(packetizer.sink),
# core --> serdes
packetizer.source.connect(tx_cdc.sink),
If(tx_cdc.source.stb & phy.init.ready,
phy.serdes.tx_data.eq(tx_cdc.source.data)
),
tx_cdc.source.ack.eq(phy.init.ready),
# serdes --> core
rx_cdc.sink.stb.eq(phy.init.ready),
rx_cdc.sink.data.eq(phy.serdes.rx_data),
rx_cdc.source.connect(depacketizer.sink),
]

View File

@ -18,7 +18,7 @@ from misoc.interconnect import wishbone
from artiq.gateware.serwb.packet import * from artiq.gateware.serwb.packet import *
class Packetizer(Module): class _Packetizer(Module):
def __init__(self, sink_description, source_description, header): def __init__(self, sink_description, source_description, header):
self.sink = sink = stream.Endpoint(sink_description) self.sink = sink = stream.Endpoint(sink_description)
self.source = source = stream.Endpoint(source_description) self.source = source = stream.Endpoint(source_description)
@ -108,7 +108,7 @@ class Packetizer(Module):
) )
class Depacketizer(Module): class _Depacketizer(Module):
def __init__(self, sink_description, source_description, header): def __init__(self, sink_description, source_description, header):
self.sink = sink = stream.Endpoint(sink_description) self.sink = sink = stream.Endpoint(sink_description)
self.source = source = stream.Endpoint(source_description) self.source = source = stream.Endpoint(source_description)
@ -275,22 +275,22 @@ def etherbone_mmap_description(dw):
# etherbone packet # etherbone packet
class EtherbonePacketPacketizer(Packetizer): class _EtherbonePacketPacketizer(_Packetizer):
def __init__(self): def __init__(self):
Packetizer.__init__(self, _Packetizer.__init__(self,
etherbone_packet_description(32), etherbone_packet_description(32),
user_description(32), user_description(32),
etherbone_packet_header) etherbone_packet_header)
class EtherbonePacketTX(Module): class _EtherbonePacketTX(Module):
def __init__(self): def __init__(self):
self.sink = sink = stream.Endpoint(etherbone_packet_user_description(32)) self.sink = sink = stream.Endpoint(etherbone_packet_user_description(32))
self.source = source = stream.Endpoint(user_description(32)) self.source = source = stream.Endpoint(user_description(32))
# # # # # #
self.submodules.packetizer = packetizer = EtherbonePacketPacketizer() self.submodules.packetizer = packetizer = _EtherbonePacketPacketizer()
self.comb += [ self.comb += [
packetizer.sink.stb.eq(sink.stb), packetizer.sink.stb.eq(sink.stb),
packetizer.sink.eop.eq(sink.eop), packetizer.sink.eop.eq(sink.eop),
@ -321,22 +321,22 @@ class EtherbonePacketTX(Module):
) )
class EtherbonePacketDepacketizer(Depacketizer): class _EtherbonePacketDepacketizer(_Depacketizer):
def __init__(self): def __init__(self):
Depacketizer.__init__(self, _Depacketizer.__init__(self,
user_description(32), user_description(32),
etherbone_packet_description(32), etherbone_packet_description(32),
etherbone_packet_header) etherbone_packet_header)
class EtherbonePacketRX(Module): class _EtherbonePacketRX(Module):
def __init__(self): def __init__(self):
self.sink = sink = stream.Endpoint(user_description(32)) self.sink = sink = stream.Endpoint(user_description(32))
self.source = source = stream.Endpoint(etherbone_packet_user_description(32)) self.source = source = stream.Endpoint(etherbone_packet_user_description(32))
# # # # # #
self.submodules.depacketizer = depacketizer = EtherbonePacketDepacketizer() self.submodules.depacketizer = depacketizer = _EtherbonePacketDepacketizer()
self.comb += sink.connect(depacketizer.sink) self.comb += sink.connect(depacketizer.sink)
self.submodules.fsm = fsm = FSM(reset_state="IDLE") self.submodules.fsm = fsm = FSM(reset_state="IDLE")
@ -385,10 +385,10 @@ class EtherbonePacketRX(Module):
) )
class EtherbonePacket(Module): class _EtherbonePacket(Module):
def __init__(self, port_sink, port_source): def __init__(self, port_sink, port_source):
self.submodules.tx = tx = EtherbonePacketTX() self.submodules.tx = tx = _EtherbonePacketTX()
self.submodules.rx = rx = EtherbonePacketRX() self.submodules.rx = rx = _EtherbonePacketRX()
self.comb += [ self.comb += [
tx.source.connect(port_sink), tx.source.connect(port_sink),
port_source.connect(rx.sink) port_source.connect(rx.sink)
@ -397,23 +397,23 @@ class EtherbonePacket(Module):
# etherbone record # etherbone record
class EtherboneRecordPacketizer(Packetizer): class _EtherboneRecordPacketizer(_Packetizer):
def __init__(self): def __init__(self):
Packetizer.__init__(self, _Packetizer.__init__(self,
etherbone_record_description(32), etherbone_record_description(32),
etherbone_packet_user_description(32), etherbone_packet_user_description(32),
etherbone_record_header) etherbone_record_header)
class EtherboneRecordDepacketizer(Depacketizer): class _EtherboneRecordDepacketizer(_Depacketizer):
def __init__(self): def __init__(self):
Depacketizer.__init__(self, _Depacketizer.__init__(self,
etherbone_packet_user_description(32), etherbone_packet_user_description(32),
etherbone_record_description(32), etherbone_record_description(32),
etherbone_record_header) etherbone_record_header)
class EtherboneRecordReceiver(Module): class _EtherboneRecordReceiver(Module):
def __init__(self, buffer_depth=256): def __init__(self, buffer_depth=256):
self.sink = sink = stream.Endpoint(etherbone_record_description(32)) self.sink = sink = stream.Endpoint(etherbone_record_description(32))
self.source = source = stream.Endpoint(etherbone_mmap_description(32)) self.source = source = stream.Endpoint(etherbone_mmap_description(32))
@ -496,7 +496,7 @@ class EtherboneRecordReceiver(Module):
) )
class EtherboneRecordSender(Module): class _EtherboneRecordSender(Module):
def __init__(self, buffer_depth=256): def __init__(self, buffer_depth=256):
self.sink = sink = stream.Endpoint(etherbone_mmap_description(32)) self.sink = sink = stream.Endpoint(etherbone_mmap_description(32))
self.source = source = stream.Endpoint(etherbone_record_description(32)) self.source = source = stream.Endpoint(etherbone_record_description(32))
@ -545,7 +545,7 @@ class EtherboneRecordSender(Module):
) )
class EtherboneRecord(Module): class _EtherboneRecord(Module):
def __init__(self): def __init__(self):
self.sink = sink = stream.Endpoint(etherbone_packet_user_description(32)) self.sink = sink = stream.Endpoint(etherbone_packet_user_description(32))
self.source = source = stream.Endpoint(etherbone_packet_user_description(32)) self.source = source = stream.Endpoint(etherbone_packet_user_description(32))
@ -553,16 +553,16 @@ class EtherboneRecord(Module):
# # # # # #
# receive record, decode it and generate mmap stream # receive record, decode it and generate mmap stream
self.submodules.depacketizer = depacketizer = EtherboneRecordDepacketizer() self.submodules.depacketizer = depacketizer = _EtherboneRecordDepacketizer()
self.submodules.receiver = receiver = EtherboneRecordReceiver() self.submodules.receiver = receiver = _EtherboneRecordReceiver()
self.comb += [ self.comb += [
sink.connect(depacketizer.sink), sink.connect(depacketizer.sink),
depacketizer.source.connect(receiver.sink) depacketizer.source.connect(receiver.sink)
] ]
# receive mmap stream, encode it and send records # receive mmap stream, encode it and send records
self.submodules.sender = sender = EtherboneRecordSender() self.submodules.sender = sender = _EtherboneRecordSender()
self.submodules.packetizer = packetizer = EtherboneRecordPacketizer() self.submodules.packetizer = packetizer = _EtherboneRecordPacketizer()
self.comb += [ self.comb += [
sender.source.connect(packetizer.sink), sender.source.connect(packetizer.sink),
packetizer.source.connect(source), packetizer.source.connect(source),
@ -574,7 +574,7 @@ class EtherboneRecord(Module):
# etherbone wishbone # etherbone wishbone
class EtherboneWishboneMaster(Module): class _EtherboneWishboneMaster(Module):
def __init__(self): def __init__(self):
self.sink = sink = stream.Endpoint(etherbone_mmap_description(32)) self.sink = sink = stream.Endpoint(etherbone_mmap_description(32))
self.source = source = stream.Endpoint(etherbone_mmap_description(32)) self.source = source = stream.Endpoint(etherbone_mmap_description(32))
@ -642,7 +642,7 @@ class EtherboneWishboneMaster(Module):
) )
class EtherboneWishboneSlave(Module): class _EtherboneWishboneSlave(Module):
def __init__(self): def __init__(self):
self.bus = bus = wishbone.Interface() self.bus = bus = wishbone.Interface()
self.ready = Signal(reset=1) self.ready = Signal(reset=1)
@ -723,12 +723,12 @@ class Etherbone(Module):
# # # # # #
self.submodules.packet = EtherbonePacket(source, sink) self.submodules.packet = _EtherbonePacket(source, sink)
self.submodules.record = EtherboneRecord() self.submodules.record = _EtherboneRecord()
if mode == "master": if mode == "master":
self.submodules.wishbone = EtherboneWishboneMaster() self.submodules.wishbone = _EtherboneWishboneMaster()
elif mode == "slave": elif mode == "slave":
self.submodules.wishbone = EtherboneWishboneSlave() self.submodules.wishbone = _EtherboneWishboneSlave()
else: else:
raise ValueError raise ValueError

View File

@ -6,63 +6,6 @@ from migen.genlib.misc import BitSlip
from misoc.cores.code_8b10b import Encoder, Decoder from misoc.cores.code_8b10b import Encoder, Decoder
class KUSSerdesPLL(Module):
def __init__(self, refclk_freq, linerate, vco_div=1):
assert refclk_freq == 125e6
assert linerate == 1.25e9
self.lock = Signal()
self.refclk = Signal()
self.serdes_clk = Signal()
self.serdes_20x_clk = Signal()
self.serdes_5x_clk = Signal()
# # #
#----------------------
# refclk: 125MHz
# vco: 1250MHz
#----------------------
# serdes: 31.25MHz
# serdes_20x: 625MHz
# serdes_5x: 156.25MHz
#----------------------
self.linerate = linerate
pll_locked = Signal()
pll_fb = Signal()
pll_serdes_clk = Signal()
pll_serdes_20x_clk = Signal()
pll_serdes_5x_clk = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
# VCO @ 1.25GHz / vco_div
p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=8.0,
p_CLKFBOUT_MULT=10, p_DIVCLK_DIVIDE=vco_div,
i_CLKIN1=self.refclk, i_CLKFBIN=pll_fb,
o_CLKFBOUT=pll_fb,
# 31.25MHz: serdes
p_CLKOUT0_DIVIDE=40//vco_div, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=pll_serdes_clk,
# 625MHz: serdes_20x
p_CLKOUT1_DIVIDE=2//vco_div, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_serdes_20x_clk,
# 156.25MHz: serdes_5x
p_CLKOUT2_DIVIDE=8//vco_div, p_CLKOUT2_PHASE=0.0,
o_CLKOUT2=pll_serdes_5x_clk
),
Instance("BUFG", i_I=pll_serdes_clk, o_O=self.serdes_clk),
Instance("BUFG", i_I=pll_serdes_20x_clk, o_O=self.serdes_20x_clk),
Instance("BUFG", i_I=pll_serdes_5x_clk, o_O=self.serdes_5x_clk)
]
self.specials += MultiReg(pll_locked, self.lock)
class KUSSerdes(Module): class KUSSerdes(Module):
def __init__(self, pll, pads, mode="master"): def __init__(self, pll, pads, mode="master"):
self.tx_data = Signal(32) self.tx_data = Signal(32)

View File

@ -4,6 +4,9 @@ from migen.genlib.misc import WaitTimer
from misoc.interconnect.csr import * from misoc.interconnect.csr import *
from artiq.gateware.serwb.kusphy import KUSSerdes
from artiq.gateware.serwb.s7phy import S7Serdes
# Master <--> Slave synchronization: # Master <--> Slave synchronization:
# 1) Master sends idle pattern (zeroes) to reset Slave. # 1) Master sends idle pattern (zeroes) to reset Slave.
@ -13,11 +16,11 @@ from misoc.interconnect.csr import *
# 5) Slave stops sending K25.5 commas. # 5) Slave stops sending K25.5 commas.
# 6) Link is ready. # 6) Link is ready.
class SerdesMasterInit(Module): class _SerdesMasterInit(Module):
def __init__(self, serdes, taps): def __init__(self, serdes, taps):
self.reset = Signal() self.reset = Signal()
self.error = Signal()
self.ready = Signal() self.ready = Signal()
self.error = Signal()
# # # # # #
@ -72,6 +75,7 @@ class SerdesMasterInit(Module):
If(serdes.rx_comma, If(serdes.rx_comma,
timer.wait.eq(1), timer.wait.eq(1),
If(timer.done, If(timer.done,
timer.wait.eq(0),
NextValue(delay_min, delay), NextValue(delay_min, delay),
NextValue(delay_min_found, 1) NextValue(delay_min_found, 1)
) )
@ -82,7 +86,7 @@ class SerdesMasterInit(Module):
If(~serdes.rx_comma, If(~serdes.rx_comma,
NextValue(delay_max, delay), NextValue(delay_max, delay),
NextValue(delay_max_found, 1), NextValue(delay_max_found, 1),
NextState("RESET_SAMPLING_WINDOW") NextState("CHECK_SAMPLING_WINDOW")
).Else( ).Else(
NextState("INC_DELAY_BITSLIP") NextState("INC_DELAY_BITSLIP")
) )
@ -93,12 +97,10 @@ class SerdesMasterInit(Module):
fsm.act("INC_DELAY_BITSLIP", fsm.act("INC_DELAY_BITSLIP",
NextState("WAIT_STABLE"), NextState("WAIT_STABLE"),
If(delay == (taps - 1), If(delay == (taps - 1),
If(delay_min_found,
NextState("ERROR")
),
If(bitslip == (40 - 1), If(bitslip == (40 - 1),
NextValue(bitslip, 0) NextState("ERROR")
).Else( ).Else(
NextValue(delay_min_found, 0),
NextValue(bitslip, bitslip + 1) NextValue(bitslip, bitslip + 1)
), ),
NextValue(delay, 0), NextValue(delay, 0),
@ -110,6 +112,17 @@ class SerdesMasterInit(Module):
), ),
serdes.tx_comma.eq(1) serdes.tx_comma.eq(1)
) )
fsm.act("CHECK_SAMPLING_WINDOW",
If((delay_min == 0) |
(delay_max == (taps - 1)) |
((delay_max - delay_min) < taps//16),
NextValue(delay_min_found, 0),
NextValue(delay_max_found, 0),
NextState("WAIT_STABLE")
).Else(
NextState("RESET_SAMPLING_WINDOW")
)
)
fsm.act("RESET_SAMPLING_WINDOW", fsm.act("RESET_SAMPLING_WINDOW",
NextValue(delay, 0), NextValue(delay, 0),
serdes.rx_delay_rst.eq(1), serdes.rx_delay_rst.eq(1),
@ -143,7 +156,7 @@ class SerdesMasterInit(Module):
) )
class SerdesSlaveInit(Module, AutoCSR): class _SerdesSlaveInit(Module, AutoCSR):
def __init__(self, serdes, taps): def __init__(self, serdes, taps):
self.reset = Signal() self.reset = Signal()
self.ready = Signal() self.ready = Signal()
@ -199,7 +212,7 @@ class SerdesSlaveInit(Module, AutoCSR):
If(~serdes.rx_comma, If(~serdes.rx_comma,
NextValue(delay_max, delay), NextValue(delay_max, delay),
NextValue(delay_max_found, 1), NextValue(delay_max_found, 1),
NextState("RESET_SAMPLING_WINDOW") NextState("CHECK_SAMPLING_WINDOW")
).Else( ).Else(
NextState("INC_DELAY_BITSLIP") NextState("INC_DELAY_BITSLIP")
) )
@ -210,12 +223,10 @@ class SerdesSlaveInit(Module, AutoCSR):
fsm.act("INC_DELAY_BITSLIP", fsm.act("INC_DELAY_BITSLIP",
NextState("WAIT_STABLE"), NextState("WAIT_STABLE"),
If(delay == (taps - 1), If(delay == (taps - 1),
If(delay_min_found,
NextState("ERROR")
),
If(bitslip == (40 - 1), If(bitslip == (40 - 1),
NextValue(bitslip, 0) NextState("ERROR")
).Else( ).Else(
NextValue(delay_min_found, 0),
NextValue(bitslip, bitslip + 1) NextValue(bitslip, bitslip + 1)
), ),
NextValue(delay, 0), NextValue(delay, 0),
@ -227,6 +238,17 @@ class SerdesSlaveInit(Module, AutoCSR):
), ),
serdes.tx_idle.eq(1) serdes.tx_idle.eq(1)
) )
fsm.act("CHECK_SAMPLING_WINDOW",
If((delay_min == 0) |
(delay_max == (taps - 1)) |
((delay_max - delay_min) < taps//16),
NextValue(delay_min_found, 0),
NextValue(delay_max_found, 0),
NextState("WAIT_STABLE")
).Else(
NextState("RESET_SAMPLING_WINDOW")
)
)
fsm.act("RESET_SAMPLING_WINDOW", fsm.act("RESET_SAMPLING_WINDOW",
NextValue(delay, 0), NextValue(delay, 0),
serdes.rx_delay_rst.eq(1), serdes.rx_delay_rst.eq(1),
@ -266,7 +288,7 @@ class SerdesSlaveInit(Module, AutoCSR):
) )
class SerdesControl(Module, AutoCSR): class _SerdesControl(Module, AutoCSR):
def __init__(self, init, mode="master"): def __init__(self, init, mode="master"):
if mode == "master": if mode == "master":
self.reset = CSR() self.reset = CSR()
@ -294,3 +316,79 @@ class SerdesControl(Module, AutoCSR):
self.delay_max.status.eq(init.delay_max), self.delay_max.status.eq(init.delay_max),
self.bitslip.status.eq(init.bitslip) self.bitslip.status.eq(init.bitslip)
] ]
class SERWBPLL(Module):
def __init__(self, refclk_freq, linerate, vco_div=1):
assert refclk_freq == 125e6
assert linerate == 1.25e9
self.lock = Signal()
self.refclk = Signal()
self.serdes_clk = Signal()
self.serdes_20x_clk = Signal()
self.serdes_5x_clk = Signal()
# # #
#----------------------
# refclk: 125MHz
# vco: 1250MHz
#----------------------
# serdes: 31.25MHz
# serdes_20x: 625MHz
# serdes_5x: 156.25MHz
#----------------------
self.linerate = linerate
pll_locked = Signal()
pll_fb = Signal()
pll_serdes_clk = Signal()
pll_serdes_20x_clk = Signal()
pll_serdes_5x_clk = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
# VCO @ 1.25GHz / vco_div
p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=8.0,
p_CLKFBOUT_MULT=10, p_DIVCLK_DIVIDE=vco_div,
i_CLKIN1=self.refclk, i_CLKFBIN=pll_fb,
o_CLKFBOUT=pll_fb,
# 31.25MHz: serdes
p_CLKOUT0_DIVIDE=40//vco_div, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=pll_serdes_clk,
# 625MHz: serdes_20x
p_CLKOUT1_DIVIDE=2//vco_div, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_serdes_20x_clk,
# 156.25MHz: serdes_5x
p_CLKOUT2_DIVIDE=8//vco_div, p_CLKOUT2_PHASE=0.0,
o_CLKOUT2=pll_serdes_5x_clk
),
Instance("BUFG", i_I=pll_serdes_clk, o_O=self.serdes_clk),
Instance("BUFG", i_I=pll_serdes_20x_clk, o_O=self.serdes_20x_clk),
Instance("BUFG", i_I=pll_serdes_5x_clk, o_O=self.serdes_5x_clk)
]
self.specials += MultiReg(pll_locked, self.lock)
class SERWBPHY(Module, AutoCSR):
def __init__(self, device, pll, pads, mode="master"):
assert mode in ["master", "slave"]
if device[:4] == "xcku":
taps = 512
self.submodules.serdes = KUSSerdes(pll, pads, mode)
elif device[:4] == "xc7a":
taps = 32
self.submodules.serdes = S7Serdes(pll, pads, mode)
else:
raise NotImplementedError
if mode == "master":
self.submodules.init = _SerdesMasterInit(self.serdes, taps)
else:
self.submodules.init = _SerdesSlaveInit(self.serdes, taps)
self.submodules.control = _SerdesControl(self.init, mode)

View File

@ -6,63 +6,6 @@ from migen.genlib.misc import BitSlip
from misoc.cores.code_8b10b import Encoder, Decoder from misoc.cores.code_8b10b import Encoder, Decoder
class S7SerdesPLL(Module):
def __init__(self, refclk_freq, linerate, vco_div=1):
assert refclk_freq == 125e6
assert linerate == 1.25e9
self.lock = Signal()
self.refclk = Signal()
self.serdes_clk = Signal()
self.serdes_20x_clk = Signal()
self.serdes_5x_clk = Signal()
# # #
#----------------------
# refclk: 125MHz
# vco: 1250MHz
#----------------------
# serdes: 31.25MHz
# serdes_20x: 625MHz
# serdes_5x: 156.25MHz
#----------------------
self.linerate = linerate
pll_locked = Signal()
pll_fb = Signal()
pll_serdes_clk = Signal()
pll_serdes_20x_clk = Signal()
pll_serdes_5x_clk = Signal()
self.specials += [
Instance("PLLE2_BASE",
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
# VCO @ 1.25GHz / vco_div
p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=8.0,
p_CLKFBOUT_MULT=10, p_DIVCLK_DIVIDE=vco_div,
i_CLKIN1=self.refclk, i_CLKFBIN=pll_fb,
o_CLKFBOUT=pll_fb,
# 31.25MHz: serdes
p_CLKOUT0_DIVIDE=40//vco_div, p_CLKOUT0_PHASE=0.0,
o_CLKOUT0=pll_serdes_clk,
# 625MHz: serdes_20x
p_CLKOUT1_DIVIDE=2//vco_div, p_CLKOUT1_PHASE=0.0,
o_CLKOUT1=pll_serdes_20x_clk,
# 156.25MHz: serdes_5x
p_CLKOUT2_DIVIDE=8//vco_div, p_CLKOUT2_PHASE=0.0,
o_CLKOUT2=pll_serdes_5x_clk
),
Instance("BUFG", i_I=pll_serdes_clk, o_O=self.serdes_clk),
Instance("BUFG", i_I=pll_serdes_20x_clk, o_O=self.serdes_20x_clk),
Instance("BUFG", i_I=pll_serdes_5x_clk, o_O=self.serdes_5x_clk)
]
self.specials += MultiReg(pll_locked, self.lock)
class S7Serdes(Module): class S7Serdes(Module):
def __init__(self, pll, pads, mode="master"): def __init__(self, pll, pads, mode="master"):
self.tx_data = Signal(32) self.tx_data = Signal(32)