DRTIO port - gateware #140
|
@ -16,10 +16,15 @@ from artiq.coredevice import jsondesc
|
||||||
from artiq.gateware import rtio, eem_7series
|
from artiq.gateware import rtio, eem_7series
|
||||||
from artiq.gateware.rtio.phy import ttl_simple
|
from artiq.gateware.rtio.phy import ttl_simple
|
||||||
|
|
||||||
|
from artiq.gateware.drtio.transceiver import gtx_7series
|
||||||
|
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||||
|
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
||||||
|
from artiq.gateware.drtio import *
|
||||||
|
|
||||||
import dma
|
import dma
|
||||||
import analyzer
|
import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
|
import aux_controller
|
||||||
|
|
||||||
class RTIOCRG(Module, AutoCSR):
|
class RTIOCRG(Module, AutoCSR):
|
||||||
def __init__(self, platform):
|
def __init__(self, platform):
|
||||||
|
@ -71,6 +76,36 @@ class RTIOCRG(Module, AutoCSR):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class _RTIOClockMultiplier(Module, AutoCSR):
|
||||||
|
def __init__(self, rtio_clk_freq):
|
||||||
|
self.pll_reset = CSRStorage(reset=1)
|
||||||
|
self.pll_locked = CSRStatus()
|
||||||
|
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
|
# See "Global Clock Network Deskew Using Two BUFGs" in ug472.
|
||||||
|
clkfbout = Signal()
|
||||||
|
clkfbin = Signal()
|
||||||
|
rtiox4_clk = Signal()
|
||||||
|
pll_locked = Signal()
|
||||||
|
self.specials += [
|
||||||
|
Instance("MMCME2_BASE",
|
||||||
|
p_CLKIN1_PERIOD=1e9/rtio_clk_freq,
|
||||||
|
i_CLKIN1=ClockSignal("rtio"),
|
||||||
|
i_RST=self.pll_reset.storage,
|
||||||
|
o_LOCKED=pll_locked,
|
||||||
|
|
||||||
|
p_CLKFBOUT_MULT_F=8.0, p_DIVCLK_DIVIDE=1,
|
||||||
|
|
||||||
|
o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbin,
|
||||||
|
|
||||||
|
p_CLKOUT0_DIVIDE_F=2.0, o_CLKOUT0=rtiox4_clk,
|
||||||
|
),
|
||||||
|
Instance("BUFG", i_I=clkfbout, o_O=clkfbin),
|
||||||
|
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
||||||
|
|
||||||
|
MultiReg(pll_locked, self.pll_locked.status)
|
||||||
|
]
|
||||||
|
|
||||||
eem_iostandard_dict = {
|
eem_iostandard_dict = {
|
||||||
0: "LVDS_25",
|
0: "LVDS_25",
|
||||||
1: "LVDS_25",
|
1: "LVDS_25",
|
||||||
|
@ -173,13 +208,295 @@ class GenericStandalone(SoCCore):
|
||||||
|
|
||||||
|
|
||||||
class GenericMaster(SoCCore):
|
class GenericMaster(SoCCore):
|
||||||
def __init__(self, description, **kwargs):
|
def __init__(self, description, acpki=False):
|
||||||
raise NotImplementedError
|
sys_clk_freq = 125e6
|
||||||
|
|
||||||
|
self.acpki = acpki
|
||||||
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
|
platform = kasli_soc.Platform()
|
||||||
|
platform.toolchain.bitstream_commands.extend([
|
||||||
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
|
])
|
||||||
|
ident = self.__class__.__name__
|
||||||
|
if self.acpki:
|
||||||
|
ident = "acpki_" + ident
|
||||||
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
|
# kasli_soc has no SATA, but it has 4x SFP
|
||||||
|
# not sure yet why sfp0 is omitted in MasterMode
|
||||||
|
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||||
|
|
||||||
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
|
clock_pads=platform.request("clk125_gtp"),
|
||||||
|
pads=data_pads,
|
||||||
|
sys_clk_freq=sys_clk_freq)
|
||||||
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
|
self.submodules.rtio_crg = RTIOCRG(self.platform)
|
||||||
|
self.csr_devices.append("rtio_crg")
|
||||||
|
self.platform.add_period_constraint(self.rtio_crg.cd_rtio.clk, 8.)
|
||||||
|
self.platform.add_false_path_constraints(
|
||||||
|
self.ps7.cd_sys.clk,
|
||||||
|
self.rtio_crg.cd_rtio.clk)
|
||||||
|
|
||||||
|
self.rtio_channels = []
|
||||||
|
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
||||||
|
if has_grabber:
|
||||||
|
self.grabber_csr_group = []
|
||||||
|
eem_7series.add_peripherals(self, description["peripherals"], iostandard=eem_iostandard)
|
||||||
|
for i in (0, 1):
|
||||||
|
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
|
||||||
|
user_led = self.platform.request("user_led", i)
|
||||||
|
phy = ttl_simple.Output(user_led)
|
||||||
|
self.submodules += phy
|
||||||
|
self.rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
||||||
|
self.rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
|
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
||||||
|
|
||||||
|
drtio_csr_group = []
|
||||||
|
drtioaux_csr_group = []
|
||||||
|
drtioaux_memory_group = []
|
||||||
|
self.drtio_cri = []
|
||||||
|
for i in range(len(self.drtio_transceiver.channels)):
|
||||||
|
core_name = "drtio" + str(i)
|
||||||
|
coreaux_name = "drtioaux" + str(i)
|
||||||
|
memory_name = "drtioaux" + str(i) + "_mem"
|
||||||
|
drtio_csr_group.append(core_name)
|
||||||
|
drtioaux_csr_group.append(coreaux_name)
|
||||||
|
drtioaux_memory_group.append(memory_name)
|
||||||
|
|
||||||
|
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
|
||||||
|
|
||||||
|
core = cdr(DRTIOMaster(self.rtio_tsc, self.drtio_transceiver.channels[i]))
|
||||||
|
setattr(self.submodules, core_name, core)
|
||||||
|
self.drtio_cri.append(core.cri)
|
||||||
|
self.csr_devices.append(core_name)
|
||||||
|
|
||||||
|
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
|
size = coreaux.get_mem_size()
|
||||||
|
memory_address = self.axi2csr.register_port(coreaux.get_tx_port(), size)
|
||||||
|
self.axi2csr.register_port(coreaux.get_rx_port(), size)
|
||||||
|
self.add_memory_region(memory_name, self.mem_map["csr"] + memory_address, size * 2)
|
||||||
|
self.rustc_cfg["has_drtio"] = None
|
||||||
|
self.rustc_cfg["has_drtio_routing"] = None
|
||||||
|
self.add_csr_group("drtio", drtio_csr_group)
|
||||||
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
|
||||||
|
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, self.rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_core")
|
||||||
|
|
||||||
|
if self.acpki:
|
||||||
|
self.rustc_cfg["ki_impl"] = "acp"
|
||||||
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
|
bus=self.ps7.s_axi_acp,
|
||||||
|
user=self.ps7.s_axi_acp_user,
|
||||||
|
evento=self.ps7.event.o)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
else:
|
||||||
|
self.rustc_cfg["ki_impl"] = "csr"
|
||||||
|
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
|
||||||
|
self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0)
|
||||||
|
self.csr_devices.append("rtio_dma")
|
||||||
|
|
||||||
|
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||||
|
[self.rtio.cri, self.rtio_dma.cri],
|
||||||
|
[self.rtio_core.cri] + self.drtio_cri,
|
||||||
|
enable_routing=True)
|
||||||
|
self.csr_devices.append("cri_con")
|
||||||
|
|
||||||
|
self.submodules.rtio_moninj = rtio.MonInj(self.rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_moninj")
|
||||||
|
|
||||||
|
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||||
|
self.csr_devices.append("routing_table")
|
||||||
|
|
||||||
|
self.submodules.rtio_analyzer = analyzer.Analyzer(self.rtio_tsc, self.rtio_core.cri,
|
||||||
|
self.ps7.s_axi_hp1)
|
||||||
|
self.csr_devices.append("rtio_analyzer")
|
||||||
|
|
||||||
|
if has_grabber:
|
||||||
|
self.rustc_cfg["has_grabber"] = None
|
||||||
|
self.add_csr_group("grabber", self.grabber_csr_group)
|
||||||
|
for grabber in self.grabber_csr_group:
|
||||||
|
self.platform.add_false_path_constraints(
|
||||||
|
self.rtio_crg.cd_rtio.clk, getattr(self, grabber).deserializer.cd_cl.clk)
|
||||||
|
|
||||||
|
|
||||||
class GenericSatellite(SoCCore):
|
class GenericSatellite(SoCCore):
|
||||||
def __init__(self, description, **kwargs):
|
def __init__(self, description, acpki=False):
|
||||||
raise NotImplementedError
|
sys_clk_freq = 125e6
|
||||||
|
rtio_clk_freq = 125e6
|
||||||
|
|
||||||
|
self.acpki = acpki
|
||||||
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
|
platform = kasli_soc.Platform()
|
||||||
|
platform.toolchain.bitstream_commands.extend([
|
||||||
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
|
])
|
||||||
|
ident = self.__class__.__name__
|
||||||
|
if self.acpki:
|
||||||
|
ident = "acpki_" + ident
|
||||||
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
|
self.crg = self.ps7 # HACK for eem_7series to find the clock
|
||||||
|
self.submodules.rtio_crg = _RTIOClockMultiplier(rtio_clk_freq)
|
||||||
|
self.csr_devices.append("rtio_crg")
|
||||||
|
|
||||||
|
data_pads = [platform.request("sfp", i) for i in range(4)]
|
||||||
|
|
||||||
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
|
clock_pads=platform.request("clk125_gtp"),
|
||||||
|
pads=data_pads,
|
||||||
|
sys_clk_freq=sys_clk_freq)
|
||||||
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
|
self.rtio_channels = []
|
||||||
|
has_grabber = any(peripheral["type"] == "grabber" for peripheral in description["peripherals"])
|
||||||
|
if has_grabber:
|
||||||
|
self.grabber_csr_group = []
|
||||||
|
eem_7series.add_peripherals(self, description["peripherals"], iostandard=eem_iostandard)
|
||||||
|
for i in (0, 1):
|
||||||
|
print("USER LED at RTIO channel 0x{:06x}".format(len(self.rtio_channels)))
|
||||||
|
user_led = self.platform.request("user_led", i)
|
||||||
|
phy = ttl_simple.Output(user_led)
|
||||||
|
self.submodules += phy
|
||||||
|
self.rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
self.config["RTIO_LOG_CHANNEL"] = len(self.rtio_channels)
|
||||||
|
self.rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
|
self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3)
|
||||||
|
|
||||||
|
drtioaux_csr_group = []
|
||||||
|
drtioaux_memory_group = []
|
||||||
|
drtiorep_csr_group = []
|
||||||
|
self.drtio_cri = []
|
||||||
|
for i in range(len(self.drtio_transceiver.channels)):
|
||||||
|
coreaux_name = "drtioaux" + str(i)
|
||||||
|
memory_name = "drtioaux" + str(i) + "_mem"
|
||||||
|
drtioaux_csr_group.append(coreaux_name)
|
||||||
|
drtioaux_memory_group.append(memory_name)
|
||||||
|
|
||||||
|
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
self.submodules.rx_synchronizer = cdr(XilinxRXSynchronizer())
|
||||||
|
core = cdr(DRTIOSatellite(
|
||||||
|
self.rtio_tsc, self.drtio_transceiver.channels[i],
|
||||||
|
self.rx_synchronizer))
|
||||||
|
self.submodules.drtiosat = core
|
||||||
|
self.csr_devices.append("drtiosat")
|
||||||
|
else:
|
||||||
|
corerep_name = "drtiorep" + str(i-1)
|
||||||
|
drtiorep_csr_group.append(corerep_name)
|
||||||
|
|
||||||
|
core = cdr(DRTIORepeater(
|
||||||
|
self.rtio_tsc, self.drtio_transceiver.channels[i]))
|
||||||
|
setattr(self.submodules, corerep_name, core)
|
||||||
|
self.drtio_cri.append(core.cri)
|
||||||
|
self.csr_devices.append(corerep_name)
|
||||||
|
|
||||||
|
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
|
mem_size = coreaux.get_mem_size()
|
||||||
|
tx_port = coreaux.get_tx_port()
|
||||||
|
rx_port = coreaux.get_rx_port()
|
||||||
|
memory_address = self.axi2csr.register_port(tx_port, mem_size)
|
||||||
|
# rcv in upper half of the memory, thus added second
|
||||||
|
self.axi2csr.register_port(rx_port, mem_size)
|
||||||
|
# and registered in PS interface
|
||||||
|
# manually, because software refers to rx/tx by halves of entire memory block, not names
|
||||||
|
self.add_memory_region(memory_name, self.mem_map["csr"] + memory_address, mem_size * 2)
|
||||||
|
self.rustc_cfg["has_drtio"] = None
|
||||||
|
self.rustc_cfg["has_drtio_routing"] = None
|
||||||
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
self.add_csr_group("drtiorep", drtiorep_csr_group)
|
||||||
|
|
||||||
|
if self.acpki:
|
||||||
|
self.rustc_cfg["ki_impl"] = "acp"
|
||||||
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
|
bus=self.ps7.s_axi_acp,
|
||||||
|
user=self.ps7.s_axi_acp_user,
|
||||||
|
evento=self.ps7.event.o)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
else:
|
||||||
|
self.rustc_cfg["ki_impl"] = "csr"
|
||||||
|
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
|
||||||
|
self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0)
|
||||||
|
self.csr_devices.append("rtio_dma")
|
||||||
|
|
||||||
|
self.submodules.local_io = SyncRTIO(self.rtio_tsc, self.rtio_channels)
|
||||||
|
self.comb += self.drtiosat.async_errors.eq(self.local_io.async_errors)
|
||||||
|
|
||||||
|
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||||
|
[self.drtiosat.cri],
|
||||||
|
[self.local_io.cri] + self.drtio_cri,
|
||||||
|
mode="sync", enable_routing=True)
|
||||||
|
self.csr_devices.append("cri_con")
|
||||||
|
|
||||||
|
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||||
|
self.csr_devices.append("routing_table")
|
||||||
|
|
||||||
|
self.submodules.rtio_moninj = rtio.MonInj(self.rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_moninj")
|
||||||
|
|
||||||
|
rtio_clk_period = 1e9/rtio_clk_freq
|
||||||
|
self.rustc_cfg["rtio_frequency"] = str(rtio_clk_freq/1e6)
|
||||||
|
|
||||||
|
self.submodules.siphaser = SiPhaser7Series(
|
||||||
|
si5324_clkin=platform.request("cdr_clk"),
|
||||||
|
rx_synchronizer=self.rx_synchronizer,
|
||||||
|
ultrascale=False,
|
||||||
|
rtio_clk_freq=self.drtio_transceiver.rtio_clk_freq)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.crg.cd_sys.clk, self.siphaser.mmcm_freerun_output)
|
||||||
|
self.csr_devices.append("siphaser")
|
||||||
|
self.rustc_cfg["has_si5324"] = None
|
||||||
|
self.rustc_cfg["has_siphaser"] = None
|
||||||
|
self.rustc_cfg["si5324_soft_reset"] = None
|
||||||
|
|
||||||
|
gtx0 = self.drtio_transceiver.gtxs[0]
|
||||||
|
platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period)
|
||||||
|
platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.crg.cd_sys.clk,
|
||||||
|
gtx0.txoutclk, gtx0.rxoutclk)
|
||||||
|
for gtx in self.drtio_transceiver.gtxs[1:]:
|
||||||
|
platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.crg.cd_sys.clk, gtx.rxoutclk)
|
||||||
|
|
||||||
|
if has_grabber:
|
||||||
|
self.rustc_cfg["has_grabber"] = None
|
||||||
|
self.add_csr_group("grabber", self.grabber_csr_group)
|
||||||
|
# no RTIO CRG here
|
||||||
|
|
||||||
|
|
||||||
|
def write_mem_file(soc, filename):
|
||||||
|
with open(filename, "w") as f:
|
||||||
|
f.write(cpu_interface.get_mem_rust(
|
||||||
|
soc.get_memory_regions(), soc.get_memory_groups(), None))
|
||||||
|
|
||||||
|
|
||||||
def write_csr_file(soc, filename):
|
def write_csr_file(soc, filename):
|
||||||
|
@ -204,6 +521,8 @@ def main():
|
||||||
help="build Rust interface into the specified file")
|
help="build Rust interface into the specified file")
|
||||||
parser.add_argument("-c", default=None,
|
parser.add_argument("-c", default=None,
|
||||||
help="build Rust compiler configuration into the specified file")
|
help="build Rust compiler configuration into the specified file")
|
||||||
|
parser.add_argument("-m", default=None,
|
||||||
|
help="build Rust memory interface into the specified file")
|
||||||
parser.add_argument("-g", default=None,
|
parser.add_argument("-g", default=None,
|
||||||
help="build gateware into the specified directory")
|
help="build gateware into the specified directory")
|
||||||
parser.add_argument("--acpki", default=False, action="store_true",
|
parser.add_argument("--acpki", default=False, action="store_true",
|
||||||
|
@ -230,6 +549,8 @@ def main():
|
||||||
|
|
||||||
if args.r is not None:
|
if args.r is not None:
|
||||||
write_csr_file(soc, args.r)
|
write_csr_file(soc, args.r)
|
||||||
|
if args.m is not None:
|
||||||
|
write_mem_file(soc, args.m)
|
||||||
if args.c is not None:
|
if args.c is not None:
|
||||||
write_rustc_cfg_file(soc, args.c)
|
write_rustc_cfg_file(soc, args.c)
|
||||||
if args.g is not None:
|
if args.g is not None:
|
||||||
|
|
|
@ -11,14 +11,20 @@ from migen_axi.integration.soc_core import SoCCore
|
||||||
from migen_axi.platforms import zc706
|
from migen_axi.platforms import zc706
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
from misoc.integration import cpu_interface
|
from misoc.integration import cpu_interface
|
||||||
|
from misoc.cores import gpio
|
||||||
|
|
||||||
from artiq.gateware import rtio, nist_clock, nist_qc2
|
from artiq.gateware import rtio, nist_clock, nist_qc2
|
||||||
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2
|
from artiq.gateware.rtio.phy import ttl_simple, ttl_serdes_7series, dds, spi2
|
||||||
|
|
||||||
|
from artiq.gateware.drtio.transceiver import gtx_7series
|
||||||
|
from artiq.gateware.drtio.siphaser import SiPhaser7Series
|
||||||
|
from artiq.gateware.drtio.rx_synchronizer import XilinxRXSynchronizer
|
||||||
|
from artiq.gateware.drtio import *
|
||||||
|
|
||||||
import dma
|
import dma
|
||||||
import analyzer
|
import analyzer
|
||||||
import acpki
|
import acpki
|
||||||
|
import aux_controller
|
||||||
|
|
||||||
class RTIOCRG(Module, AutoCSR):
|
class RTIOCRG(Module, AutoCSR):
|
||||||
def __init__(self, platform, rtio_internal_clk):
|
def __init__(self, platform, rtio_internal_clk):
|
||||||
|
@ -64,23 +70,88 @@ class RTIOCRG(Module, AutoCSR):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class _RTIOClockMultiplier(Module, AutoCSR):
|
||||||
|
def __init__(self, rtio_clk_freq):
|
||||||
|
self.pll_reset = CSRStorage(reset=1)
|
||||||
|
self.pll_locked = CSRStatus()
|
||||||
|
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
|
# See "Global Clock Network Deskew Using Two BUFGs" in ug472.
|
||||||
|
clkfbout = Signal()
|
||||||
|
clkfbin = Signal()
|
||||||
|
rtiox4_clk = Signal()
|
||||||
|
pll_locked = Signal()
|
||||||
|
self.specials += [
|
||||||
|
Instance("MMCME2_BASE",
|
||||||
|
p_CLKIN1_PERIOD=1e9/rtio_clk_freq,
|
||||||
|
i_CLKIN1=ClockSignal("rtio"),
|
||||||
|
i_RST=self.pll_reset.storage,
|
||||||
|
o_LOCKED=pll_locked,
|
||||||
|
|
||||||
|
p_CLKFBOUT_MULT_F=8.0, p_DIVCLK_DIVIDE=1,
|
||||||
|
|
||||||
|
o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbin,
|
||||||
|
|
||||||
|
p_CLKOUT0_DIVIDE_F=2.0, o_CLKOUT0=rtiox4_clk,
|
||||||
|
),
|
||||||
|
Instance("BUFG", i_I=clkfbout, o_O=clkfbin),
|
||||||
|
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
||||||
|
|
||||||
|
MultiReg(pll_locked, self.pll_locked.status)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def fix_serdes_timing_path(platform):
|
||||||
|
# ignore timing of path from OSERDESE2 through the pad to ISERDESE2
|
||||||
|
platform.add_platform_command(
|
||||||
|
"set_false_path -quiet "
|
||||||
|
"-through [get_pins -filter {{REF_PIN_NAME == OQ || REF_PIN_NAME == TQ}} "
|
||||||
|
"-of [get_cells -filter {{REF_NAME == OSERDESE2}}]] "
|
||||||
|
"-to [get_pins -filter {{REF_PIN_NAME == D}} "
|
||||||
|
"-of [get_cells -filter {{REF_NAME == ISERDESE2}}]]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# The NIST backplanes require setting VADJ to 3.3V by reprogramming the power supply.
|
||||||
|
# This also changes the I/O standard for some on-board LEDs.
|
||||||
|
leds_fmc33 = [
|
||||||
|
("user_led_33", 0, Pins("Y21"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led_33", 1, Pins("G2"), IOStandard("LVCMOS15")),
|
||||||
|
("user_led_33", 2, Pins("W21"), IOStandard("LVCMOS33")),
|
||||||
|
("user_led_33", 3, Pins("A17"), IOStandard("LVCMOS15")),
|
||||||
|
]
|
||||||
|
|
||||||
|
# same deal as with LEDs - changed I/O standard.
|
||||||
|
si5324_fmc33 = [
|
||||||
|
("si5324_33", 0,
|
||||||
|
Subsignal("rst_n", Pins("W23"), IOStandard("LVCMOS33")),
|
||||||
|
Subsignal("int", Pins("AJ25"), IOStandard("LVCMOS33"))
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_zc706_platform(platform):
|
||||||
|
platform.toolchain.bitstream_commands.extend([
|
||||||
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
|
])
|
||||||
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
return platform
|
||||||
|
|
||||||
|
|
||||||
class ZC706(SoCCore):
|
class ZC706(SoCCore):
|
||||||
def __init__(self, acpki=False):
|
def __init__(self, acpki=False):
|
||||||
self.acpki = acpki
|
self.acpki = acpki
|
||||||
self.rustc_cfg = dict()
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
platform = zc706.Platform()
|
platform = zc706.Platform()
|
||||||
platform.toolchain.bitstream_commands.extend([
|
platform = prepare_zc706_platform(platform)
|
||||||
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
|
||||||
])
|
|
||||||
ident = self.__class__.__name__
|
ident = self.__class__.__name__
|
||||||
if self.acpki:
|
if self.acpki:
|
||||||
ident = "acpki_" + ident
|
ident = "acpki_" + ident
|
||||||
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
|
||||||
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
|
||||||
|
|
||||||
self.submodules.rtio_crg = RTIOCRG(self.platform, self.ps7.cd_sys.clk)
|
self.submodules.rtio_crg = RTIOCRG(self.platform, self.ps7.cd_sys.clk)
|
||||||
self.csr_devices.append("rtio_crg")
|
self.csr_devices.append("rtio_crg")
|
||||||
self.rustc_cfg["has_rtio_crg_clock_sel"] = None
|
self.rustc_cfg["has_rtio_crg_clock_sel"] = None
|
||||||
|
@ -122,10 +193,284 @@ class ZC706(SoCCore):
|
||||||
self.csr_devices.append("rtio_analyzer")
|
self.csr_devices.append("rtio_analyzer")
|
||||||
|
|
||||||
|
|
||||||
class Simple(ZC706):
|
class _MasterBase(SoCCore):
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, acpki=False, use_si5324_33=False):
|
||||||
ZC706.__init__(self, **kwargs)
|
self.acpki = acpki
|
||||||
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
|
platform = zc706.Platform()
|
||||||
|
platform = prepare_zc706_platform(platform)
|
||||||
|
ident = self.__class__.__name__
|
||||||
|
if self.acpki:
|
||||||
|
ident = "acpki_" + ident
|
||||||
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
platform.add_platform_command("create_clock -name clk_fpga_0 -period 8 [get_pins \"PS7/FCLKCLK[0]\"]")
|
||||||
|
platform.add_platform_command("set_input_jitter clk_fpga_0 0.24")
|
||||||
|
|
||||||
|
if use_si5324_33:
|
||||||
|
platform.add_extension(si5324_fmc33)
|
||||||
|
|
||||||
|
self.sys_clk_freq = 125e6
|
||||||
|
|
||||||
|
platform = self.platform
|
||||||
|
|
||||||
|
self.comb += platform.request("sfp_tx_disable_n").eq(1)
|
||||||
|
data_pads = [
|
||||||
|
platform.request("sfp")
|
||||||
|
]
|
||||||
|
|
||||||
|
# 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock
|
||||||
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
|
clock_pads=platform.request("si5324_clkout"),
|
||||||
|
pads=data_pads,
|
||||||
|
sys_clk_freq=self.sys_clk_freq)
|
||||||
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
|
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
||||||
|
|
||||||
|
drtio_csr_group = []
|
||||||
|
drtioaux_csr_group = []
|
||||||
|
drtioaux_memory_group = []
|
||||||
|
self.drtio_cri = []
|
||||||
|
for i in range(len(self.drtio_transceiver.channels)):
|
||||||
|
core_name = "drtio" + str(i)
|
||||||
|
coreaux_name = "drtioaux" + str(i)
|
||||||
|
memory_name = "drtioaux" + str(i) + "_mem"
|
||||||
|
drtio_csr_group.append(core_name)
|
||||||
|
drtioaux_csr_group.append(coreaux_name)
|
||||||
|
drtioaux_memory_group.append(memory_name)
|
||||||
|
|
||||||
|
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
|
||||||
|
|
||||||
|
core = cdr(DRTIOMaster(
|
||||||
|
self.rtio_tsc, self.drtio_transceiver.channels[i]))
|
||||||
|
setattr(self.submodules, core_name, core)
|
||||||
|
self.drtio_cri.append(core.cri)
|
||||||
|
self.csr_devices.append(core_name)
|
||||||
|
|
||||||
|
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
|
mem_size = coreaux.get_mem_size()
|
||||||
|
memory_address = self.axi2csr.register_port(coreaux.get_tx_port(), mem_size)
|
||||||
|
self.axi2csr.register_port(coreaux.get_rx_port(), mem_size)
|
||||||
|
self.add_memory_region(memory_name, self.mem_map["csr"] + memory_address, mem_size * 2)
|
||||||
|
self.rustc_cfg["has_drtio"] = None
|
||||||
|
self.rustc_cfg["has_drtio_routing"] = None
|
||||||
|
self.add_csr_group("drtio", drtio_csr_group)
|
||||||
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
|
||||||
|
self.rustc_cfg["RTIO_FREQUENCY"] = str(self.drtio_transceiver.rtio_clk_freq/1e6)
|
||||||
|
|
||||||
|
if use_si5324_33:
|
||||||
|
|||||||
|
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324_33").rst_n)
|
||||||
|
else:
|
||||||
|
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n)
|
||||||
|
self.csr_devices.append("si5324_rst_n")
|
||||||
|
self.rustc_cfg["has_si5324"] = None
|
||||||
|
self.rustc_cfg["si5324_as_synthesizer"] = None
|
||||||
|
|
||||||
|
rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq
|
||||||
|
# Constrain TX & RX timing for the first transceiver channel
|
||||||
|
# (First channel acts as master for phase alignment for all channels' TX)
|
||||||
|
gtx0 = self.drtio_transceiver.gtxs[0]
|
||||||
|
platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period)
|
||||||
|
platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.ps7.cd_sys.clk,
|
||||||
|
gtx0.txoutclk, gtx0.rxoutclk)
|
||||||
|
# Constrain RX timing for the each transceiver channel
|
||||||
|
# (Each channel performs single-lane phase alignment for RX)
|
||||||
|
for gtx in self.drtio_transceiver.gtxs[1:]:
|
||||||
|
platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.ps7.cd_sys.clk, gtx0.txoutclk, gtx.rxoutclk)
|
||||||
|
|
||||||
|
self.submodules.rtio_crg = _RTIOClockMultiplier(self.sys_clk_freq)
|
||||||
|
self.csr_devices.append("rtio_crg")
|
||||||
|
fix_serdes_timing_path(self.platform)
|
||||||
|
|
||||||
|
def add_rtio(self, rtio_channels):
|
||||||
|
self.submodules.rtio_tsc = rtio.TSC("async", glbl_fine_ts_width=3)
|
||||||
|
self.submodules.rtio_core = rtio.Core(self.rtio_tsc, rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_core")
|
||||||
|
|
||||||
|
if self.acpki:
|
||||||
|
self.rustc_cfg["ki_impl"] = "acp"
|
||||||
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
|
bus=self.ps7.s_axi_acp,
|
||||||
|
user=self.ps7.s_axi_acp_user,
|
||||||
|
evento=self.ps7.event.o)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
else:
|
||||||
|
self.rustc_cfg["ki_impl"] = "csr"
|
||||||
|
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
|
||||||
|
self.submodules.rtio_dma = dma.DMA(self.ps7.s_axi_hp0)
|
||||||
|
self.csr_devices.append("rtio_dma")
|
||||||
|
|
||||||
|
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels)
|
||||||
|
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||||
|
[self.rtio.cri, self.rtio_dma.cri],
|
||||||
|
[self.local_io.cri] + self.drtio_cri,
|
||||||
|
mode="sync", enable_routing=True)
|
||||||
|
self.csr_devices.append("cri_con")
|
||||||
|
|
||||||
|
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_moninj")
|
||||||
|
|
||||||
|
self.submodules.rtio_analyzer = analyzer.Analyzer(self.rtio_tsc, self.rtio_core.cri,
|
||||||
|
self.ps7.s_axi_hp1)
|
||||||
|
self.csr_devices.append("rtio_analyzer")
|
||||||
|
|
||||||
|
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||||
|
self.csr_devices.append("routing_table")
|
||||||
|
|
||||||
|
|
||||||
|
class _SatelliteBase(SoCCore):
|
||||||
|
def __init__(self, acpki=False, use_si5324_33=False):
|
||||||
|
self.acpki = acpki
|
||||||
|
self.rustc_cfg = dict()
|
||||||
|
|
||||||
|
platform = zc706.Platform()
|
||||||
|
platform = prepare_zc706_platform(platform)
|
||||||
|
ident = self.__class__.__name__
|
||||||
|
if self.acpki:
|
||||||
|
ident = "acpki_" + ident
|
||||||
|
SoCCore.__init__(self, platform=platform, csr_data_width=32, ident=ident)
|
||||||
|
|
||||||
|
if use_si5324_33:
|
||||||
|
platform.add_extension(si5324_fmc33)
|
||||||
|
|
||||||
|
self.sys_clk_freq = 125e6
|
||||||
|
platform = self.platform
|
||||||
|
|
||||||
|
# SFP
|
||||||
|
self.comb += platform.request("sfp_tx_disable_n").eq(0)
|
||||||
|
data_pads = [
|
||||||
|
platform.request("sfp")
|
||||||
|
]
|
||||||
|
|
||||||
|
self.submodules.rtio_tsc = rtio.TSC("sync", glbl_fine_ts_width=3)
|
||||||
|
|
||||||
|
# 1000BASE_BX10 Ethernet compatible, 125MHz RTIO clock
|
||||||
|
self.submodules.drtio_transceiver = gtx_7series.GTX(
|
||||||
|
clock_pads=platform.request("si5324_clkout"),
|
||||||
|
pads=data_pads,
|
||||||
|
sys_clk_freq=self.sys_clk_freq)
|
||||||
|
self.csr_devices.append("drtio_transceiver")
|
||||||
|
|
||||||
|
drtioaux_csr_group = []
|
||||||
|
drtioaux_memory_group = []
|
||||||
|
self.drtio_cri = []
|
||||||
|
for i in range(len(self.drtio_transceiver.channels)):
|
||||||
|
coreaux_name = "drtioaux" + str(i)
|
||||||
|
memory_name = "drtioaux" + str(i) + "_mem"
|
||||||
|
drtioaux_csr_group.append(coreaux_name)
|
||||||
|
drtioaux_memory_group.append(memory_name)
|
||||||
|
|
||||||
|
cdr = ClockDomainsRenamer({"rtio_rx": "rtio_rx" + str(i)})
|
||||||
|
|
||||||
|
# Satellite
|
||||||
|
if i == 0:
|
||||||
|
self.submodules.rx_synchronizer = cdr(XilinxRXSynchronizer())
|
||||||
|
core = cdr(DRTIOSatellite(
|
||||||
|
self.rtio_tsc, self.drtio_transceiver.channels[0], self.rx_synchronizer))
|
||||||
|
self.submodules.drtiosat = core
|
||||||
|
self.csr_devices.append("drtiosat")
|
||||||
|
# Repeaters - there would be for i != 0 - however zc706 only has one SFP
|
||||||
|
# and no other means to connect to
|
||||||
sb10q
commented
There's the link on the MGT SMAs but I doubt anyone needs this. @dhslichter ? There's the link on the MGT SMAs but I doubt anyone needs this. @dhslichter ?
|
|||||||
|
|
||||||
|
coreaux = cdr(aux_controller.DRTIOAuxControllerBare(core.link_layer))
|
||||||
|
setattr(self.submodules, coreaux_name, coreaux)
|
||||||
|
self.csr_devices.append(coreaux_name)
|
||||||
|
|
||||||
|
mem_size = coreaux.get_mem_size()
|
||||||
|
tx_port = coreaux.get_tx_port()
|
||||||
|
rx_port = coreaux.get_rx_port()
|
||||||
|
memory_address = self.axi2csr.register_port(tx_port, mem_size)
|
||||||
|
# rcv in upper half of the memory, thus added second
|
||||||
|
self.axi2csr.register_port(rx_port, mem_size)
|
||||||
|
# and registered in PS interface
|
||||||
|
# manually, because software refers to rx/tx by halves of entire memory block, not names
|
||||||
|
self.add_memory_region(memory_name, self.mem_map["csr"] + memory_address, mem_size * 2)
|
||||||
|
self.rustc_cfg["has_drtio"] = None
|
||||||
|
# no repeaters - it does not have drtio routing support
|
||||||
|
self.add_csr_group("drtioaux", drtioaux_csr_group)
|
||||||
|
self.add_memory_group("drtioaux_mem", drtioaux_memory_group)
|
||||||
|
|
||||||
|
self.rustc_cfg["rtio_frequency"] = str(self.drtio_transceiver.rtio_clk_freq/1e6)
|
||||||
|
|
||||||
|
# Si5324 Phaser
|
||||||
|
self.submodules.siphaser = SiPhaser7Series(
|
||||||
|
si5324_clkin=platform.request("si5324_clkin"),
|
||||||
|
rx_synchronizer=self.rx_synchronizer,
|
||||||
|
ultrascale=False,
|
||||||
|
rtio_clk_freq=self.drtio_transceiver.rtio_clk_freq)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.ps7.cd_sys.clk, self.siphaser.mmcm_freerun_output)
|
||||||
|
self.csr_devices.append("siphaser")
|
||||||
|
if use_si5324_33:
|
||||||
|
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324_33").rst_n)
|
||||||
|
else:
|
||||||
|
self.submodules.si5324_rst_n = gpio.GPIOOut(platform.request("si5324").rst_n)
|
||||||
|
self.csr_devices.append("si5324_rst_n")
|
||||||
|
self.rustc_cfg["has_si5324"] = None
|
||||||
|
self.rustc_cfg["has_siphaser"] = None
|
||||||
|
|
||||||
|
rtio_clk_period = 1e9/self.drtio_transceiver.rtio_clk_freq
|
||||||
|
# Constrain TX & RX timing for the first transceiver channel
|
||||||
|
# (First channel acts as master for phase alignment for all channels' TX)
|
||||||
|
gtx0 = self.drtio_transceiver.gtxs[0]
|
||||||
|
platform.add_period_constraint(gtx0.txoutclk, rtio_clk_period)
|
||||||
|
platform.add_period_constraint(gtx0.rxoutclk, rtio_clk_period)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.ps7.cd_sys.clk,
|
||||||
|
gtx0.txoutclk, gtx0.rxoutclk)
|
||||||
|
# Constrain RX timing for the each transceiver channel
|
||||||
|
# (Each channel performs single-lane phase alignment for RX)
|
||||||
|
for gtx in self.drtio_transceiver.gtxs[1:]:
|
||||||
|
platform.add_period_constraint(gtx.rxoutclk, rtio_clk_period)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.ps7.cd_sys.clk, gtx.rxoutclk)
|
||||||
|
|
||||||
|
self.submodules.rtio_crg = _RTIOClockMultiplier(self.sys_clk_freq)
|
||||||
|
self.csr_devices.append("rtio_crg")
|
||||||
|
fix_serdes_timing_path(self.platform)
|
||||||
|
|
||||||
|
def add_rtio(self, rtio_channels):
|
||||||
|
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_moninj")
|
||||||
|
|
||||||
|
if self.acpki:
|
||||||
|
self.rustc_cfg["ki_impl"] = "acp"
|
||||||
|
self.submodules.rtio = acpki.KernelInitiator(self.rtio_tsc,
|
||||||
|
bus=self.ps7.s_axi_acp,
|
||||||
|
user=self.ps7.s_axi_acp_user,
|
||||||
|
evento=self.ps7.event.o)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
else:
|
||||||
|
self.rustc_cfg["ki_impl"] = "csr"
|
||||||
|
self.submodules.rtio = rtio.KernelInitiator(self.rtio_tsc, now64=True)
|
||||||
|
self.csr_devices.append("rtio")
|
||||||
|
|
||||||
|
self.submodules.local_io = SyncRTIO(self.rtio_tsc, rtio_channels)
|
||||||
|
self.submodules.cri_con = rtio.CRIInterconnectShared(
|
||||||
|
[self.drtiosat.cri],
|
||||||
|
[self.local_io.cri] + self.drtio_cri,
|
||||||
|
mode="sync", enable_routing=True)
|
||||||
|
self.csr_devices.append("cri_con")
|
||||||
|
|
||||||
|
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||||
|
self.csr_devices.append("routing_table")
|
||||||
|
|
||||||
|
|
||||||
|
class _Simple_RTIO:
|
||||||
|
def __init__(self):
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
|
|
||||||
rtio_channels = []
|
rtio_channels = []
|
||||||
|
@ -140,23 +485,11 @@ class Simple(ZC706):
|
||||||
self.add_rtio(rtio_channels)
|
self.add_rtio(rtio_channels)
|
||||||
|
|
||||||
|
|
||||||
# The NIST backplanes require setting VADJ to 3.3V by reprogramming the power supply.
|
class _NIST_CLOCK_RTIO:
|
||||||
# This also changes the I/O standard for some on-board LEDs.
|
|
||||||
leds_fmc33 = [
|
|
||||||
("user_led_33", 0, Pins("Y21"), IOStandard("LVCMOS33")),
|
|
||||||
("user_led_33", 1, Pins("G2"), IOStandard("LVCMOS15")),
|
|
||||||
("user_led_33", 2, Pins("W21"), IOStandard("LVCMOS33")),
|
|
||||||
("user_led_33", 3, Pins("A17"), IOStandard("LVCMOS15")),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class NIST_CLOCK(ZC706):
|
|
||||||
"""
|
"""
|
||||||
NIST clock hardware, with old backplane and 11 DDS channels
|
NIST clock hardware, with old backplane and 11 DDS channels
|
||||||
"""
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self):
|
||||||
ZC706.__init__(self, **kwargs)
|
|
||||||
|
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
platform.add_extension(nist_clock.fmc_adapter_io)
|
platform.add_extension(nist_clock.fmc_adapter_io)
|
||||||
platform.add_extension(leds_fmc33)
|
platform.add_extension(leds_fmc33)
|
||||||
|
@ -203,14 +536,12 @@ class NIST_CLOCK(ZC706):
|
||||||
self.add_rtio(rtio_channels)
|
self.add_rtio(rtio_channels)
|
||||||
|
|
||||||
|
|
||||||
class NIST_QC2(ZC706):
|
class _NIST_QC2_RTIO:
|
||||||
"""
|
"""
|
||||||
NIST QC2 hardware, as used in Quantum I and Quantum II, with new backplane
|
NIST QC2 hardware, as used in Quantum I and Quantum II, with new backplane
|
||||||
and 24 DDS channels. Two backplanes are used.
|
and 24 DDS channels. Two backplanes are used.
|
||||||
"""
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self):
|
||||||
ZC706.__init__(self, **kwargs)
|
|
||||||
|
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
platform.add_extension(nist_qc2.fmc_adapter_io)
|
platform.add_extension(nist_qc2.fmc_adapter_io)
|
||||||
platform.add_extension(leds_fmc33)
|
platform.add_extension(leds_fmc33)
|
||||||
|
@ -253,7 +584,56 @@ class NIST_QC2(ZC706):
|
||||||
self.add_rtio(rtio_channels)
|
self.add_rtio(rtio_channels)
|
||||||
|
|
||||||
|
|
||||||
VARIANTS = {cls.__name__.lower(): cls for cls in [Simple, NIST_CLOCK, NIST_QC2]}
|
class Simple(ZC706, _Simple_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
ZC706.__init__(self, acpki)
|
||||||
|
_Simple_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class Master(_MasterBase, _Simple_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
_MasterBase.__init__(self, acpki, use_si5324_33=False)
|
||||||
|
_Simple_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class Satellite(_SatelliteBase, _Simple_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
_SatelliteBase.__init__(self, acpki, use_si5324_33=False)
|
||||||
|
_Simple_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class NIST_CLOCK(ZC706, _NIST_CLOCK_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
ZC706.__init__(self, acpki)
|
||||||
|
_NIST_CLOCK_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class NIST_CLOCK_Master(_MasterBase, _NIST_CLOCK_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
_MasterBase.__init__(self, acpki, use_si5324_33=True)
|
||||||
|
|
||||||
|
_NIST_CLOCK_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class NIST_CLOCK_Satellite(_SatelliteBase, _NIST_CLOCK_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
_SatelliteBase.__init__(self, acpki, use_si5324_33=True)
|
||||||
|
_NIST_CLOCK_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class NIST_QC2(ZC706, _NIST_QC2_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
ZC706.__init__(self, acpki)
|
||||||
|
_NIST_QC2_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class NIST_QC2_Master(_MasterBase, _NIST_QC2_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
_MasterBase.__init__(self, acpki, use_si5324_33=True)
|
||||||
|
_NIST_QC2_RTIO.__init__(self)
|
||||||
|
|
||||||
|
class NIST_QC2_Satellite(_SatelliteBase, _NIST_QC2_RTIO):
|
||||||
|
def __init__(self, acpki):
|
||||||
|
_SatelliteBase.__init__(self, acpki, use_si5324_33=True)
|
||||||
|
_NIST_QC2_RTIO.__init__(self)
|
||||||
|
|
||||||
|
|
||||||
|
VARIANTS = {cls.__name__.lower(): cls for cls in [Simple, Master, Satellite,
|
||||||
|
NIST_CLOCK, NIST_CLOCK_Master, NIST_CLOCK_Satellite,
|
||||||
|
NIST_QC2, NIST_QC2_Master, NIST_QC2_Satellite]}
|
||||||
|
|
||||||
|
|
||||||
def write_csr_file(soc, filename):
|
def write_csr_file(soc, filename):
|
||||||
|
@ -261,6 +641,11 @@ def write_csr_file(soc, filename):
|
||||||
f.write(cpu_interface.get_csr_rust(
|
f.write(cpu_interface.get_csr_rust(
|
||||||
soc.get_csr_regions(), soc.get_csr_groups(), soc.get_constants()))
|
soc.get_csr_regions(), soc.get_csr_groups(), soc.get_constants()))
|
||||||
|
|
||||||
|
def write_mem_file(soc, filename):
|
||||||
|
with open(filename, "w") as f:
|
||||||
|
f.write(cpu_interface.get_mem_rust(
|
||||||
|
soc.get_memory_regions(), soc.get_memory_groups(), None))
|
||||||
|
|
||||||
|
|
||||||
def write_rustc_cfg_file(soc, filename):
|
def write_rustc_cfg_file(soc, filename):
|
||||||
with open(filename, "w") as f:
|
with open(filename, "w") as f:
|
||||||
|
@ -276,6 +661,8 @@ def main():
|
||||||
description="ARTIQ port to the ZC706 Zynq development kit")
|
description="ARTIQ port to the ZC706 Zynq development kit")
|
||||||
parser.add_argument("-r", default=None,
|
parser.add_argument("-r", default=None,
|
||||||
help="build Rust interface into the specified file")
|
help="build Rust interface into the specified file")
|
||||||
|
parser.add_argument("-m", default=None,
|
||||||
|
help="build Rust memory interface into the specified file")
|
||||||
parser.add_argument("-c", default=None,
|
parser.add_argument("-c", default=None,
|
||||||
help="build Rust compiler configuration into the specified file")
|
help="build Rust compiler configuration into the specified file")
|
||||||
parser.add_argument("-g", default=None,
|
parser.add_argument("-g", default=None,
|
||||||
|
@ -300,11 +687,12 @@ def main():
|
||||||
|
|
||||||
if args.r is not None:
|
if args.r is not None:
|
||||||
write_csr_file(soc, args.r)
|
write_csr_file(soc, args.r)
|
||||||
|
if args.m is not None:
|
||||||
|
write_mem_file(soc, args.m)
|
||||||
if args.c is not None:
|
if args.c is not None:
|
||||||
write_rustc_cfg_file(soc, args.c)
|
write_rustc_cfg_file(soc, args.c)
|
||||||
if args.g is not None:
|
if args.g is not None:
|
||||||
soc.build(build_dir=args.g)
|
soc.build(build_dir=args.g)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue
You can use assume it is true at all times and simplify the code accordingly. Only NIST backplanes are supported on ZC706 and they need the 3.3V signals.
So there won't be "simple" master/satellite? What about the board I've been testing it on, is it with a backplane?
"Simple" targets were just for testing, on the same hardware that has the backplane installed (even if they don't use the backplane).
Also fine to remove these targets, they were only there for the initial development.
Okay, makes sense, I was somewhat worried about mismatched voltages for si5324. Although I don't think this is the place to be removing the simple targets, that should be done in another PR (not only unrelated functionally to drtio, it also touches gateware, nix scripts and readme).
Changing the IOSTANDARD here does not actually change the voltage produced by the FPGA I/O, and will not damage the Si5324. In fact it even works correctly in practice when the voltage in the CMOS/TTL IOSTANDARD is wrong.