mirror of https://github.com/m-labs/artiq.git
phaser: extract target
This commit is contained in:
parent
1c84d1ee59
commit
617650f3b2
|
@ -74,7 +74,7 @@ Setup
|
||||||
|
|
||||||
* Compile the ARTIQ Phaser bitstream, bios, and runtime (c.f. ARTIQ manual): ::
|
* Compile the ARTIQ Phaser bitstream, bios, and runtime (c.f. ARTIQ manual): ::
|
||||||
|
|
||||||
python -m artiq.gateware.targets.kc705 -H phaser --toolchain vivado
|
python -m artiq.gateware.targets.phaser --toolchain vivado
|
||||||
|
|
||||||
* Run the following OpenOCD command to flash the ARTIQ phaser design: ::
|
* Run the following OpenOCD command to flash the ARTIQ phaser design: ::
|
||||||
|
|
||||||
|
|
|
@ -8,28 +8,16 @@ from migen.genlib.cdc import MultiReg
|
||||||
from migen.build.generic_platform import *
|
from migen.build.generic_platform import *
|
||||||
from migen.build.xilinx.vivado import XilinxVivadoToolchain
|
from migen.build.xilinx.vivado import XilinxVivadoToolchain
|
||||||
from migen.build.xilinx.ise import XilinxISEToolchain
|
from migen.build.xilinx.ise import XilinxISEToolchain
|
||||||
from migen.genlib.io import DifferentialInput
|
|
||||||
|
|
||||||
from jesd204b.common import (JESD204BTransportSettings,
|
|
||||||
JESD204BPhysicalSettings,
|
|
||||||
JESD204BSettings)
|
|
||||||
from jesd204b.phy.gtx import GTXQuadPLL
|
|
||||||
from jesd204b.phy import JESD204BPhyTX
|
|
||||||
from jesd204b.core import JESD204BCoreTX
|
|
||||||
from jesd204b.core import JESD204BCoreTXControl
|
|
||||||
|
|
||||||
from misoc.interconnect.csr import *
|
from misoc.interconnect.csr import *
|
||||||
from misoc.interconnect import wishbone
|
|
||||||
from misoc.cores import gpio
|
from misoc.cores import gpio
|
||||||
from misoc.cores import spi as spi_csr
|
|
||||||
from misoc.integration.soc_core import mem_decoder
|
|
||||||
from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict
|
from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict
|
||||||
from misoc.integration.builder import builder_args, builder_argdict
|
from misoc.integration.builder import builder_args, builder_argdict
|
||||||
|
|
||||||
from artiq.gateware.soc import AMPSoC, build_artiq_soc
|
from artiq.gateware.soc import AMPSoC, build_artiq_soc
|
||||||
from artiq.gateware import rtio, nist_clock, nist_qc2, phaser
|
from artiq.gateware import rtio, nist_clock, nist_qc2
|
||||||
from artiq.gateware.rtio.phy import (ttl_simple, ttl_serdes_7series,
|
from artiq.gateware.rtio.phy import (ttl_simple, ttl_serdes_7series,
|
||||||
dds, spi, sawg)
|
dds, spi)
|
||||||
from artiq import __version__ as artiq_version
|
from artiq import __version__ as artiq_version
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,228 +310,6 @@ class NIST_QC2(_NIST_Ions):
|
||||||
self.add_rtio(rtio_channels)
|
self.add_rtio(rtio_channels)
|
||||||
|
|
||||||
|
|
||||||
class _PhaserCRG(Module, AutoCSR):
|
|
||||||
def __init__(self, platform, refclk):
|
|
||||||
self._clock_sel = CSRStorage()
|
|
||||||
self._pll_reset = CSRStorage(reset=1)
|
|
||||||
self._pll_locked = CSRStatus()
|
|
||||||
self.clock_domains.cd_rtio = ClockDomain()
|
|
||||||
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
|
||||||
|
|
||||||
pll_locked = Signal()
|
|
||||||
rtio_clk = Signal()
|
|
||||||
rtiox4_clk = Signal()
|
|
||||||
self.specials += [
|
|
||||||
Instance("PLLE2_ADV",
|
|
||||||
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
|
|
||||||
|
|
||||||
p_REF_JITTER1=0.01, p_REF_JITTER2=0.01,
|
|
||||||
p_CLKIN1_PERIOD=20/3, p_CLKIN2_PERIOD=20/3,
|
|
||||||
i_CLKIN1=0, i_CLKIN2=refclk,
|
|
||||||
# Warning: CLKINSEL=0 means CLKIN2 is selected
|
|
||||||
i_CLKINSEL=~self._clock_sel.storage,
|
|
||||||
|
|
||||||
# VCO @ 1.2GHz when using 150MHz input
|
|
||||||
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
|
|
||||||
i_CLKFBIN=self.cd_rtio.clk,
|
|
||||||
i_RST=self._pll_reset.storage,
|
|
||||||
|
|
||||||
o_CLKFBOUT=rtio_clk,
|
|
||||||
|
|
||||||
p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0,
|
|
||||||
o_CLKOUT0=rtiox4_clk,
|
|
||||||
),
|
|
||||||
Instance("BUFG", i_I=rtio_clk, o_O=self.cd_rtio.clk),
|
|
||||||
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
|
||||||
AsyncResetSynchronizer(self.cd_rtio, ~pll_locked),
|
|
||||||
MultiReg(pll_locked | ~self._clock_sel.storage,
|
|
||||||
self._pll_locked.status)
|
|
||||||
]
|
|
||||||
self.cd_rtio.clk.attr.add("keep")
|
|
||||||
platform.add_period_constraint(self.cd_rtio.clk, 20/3)
|
|
||||||
|
|
||||||
|
|
||||||
class AD9154JESD(Module, AutoCSR):
|
|
||||||
def __init__(self, platform):
|
|
||||||
ps = JESD204BPhysicalSettings(l=4, m=4, n=16, np=16)
|
|
||||||
ts = JESD204BTransportSettings(f=2, s=1, k=16, cs=1)
|
|
||||||
settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
|
||||||
linerate = 6e9
|
|
||||||
refclk_freq = 150e6
|
|
||||||
fabric_freq = 150*1000*1000
|
|
||||||
|
|
||||||
sync_pads = platform.request("ad9154_sync")
|
|
||||||
self.jsync = Signal()
|
|
||||||
self.specials += DifferentialInput(
|
|
||||||
sync_pads.p, sync_pads.n, self.jsync)
|
|
||||||
|
|
||||||
refclk = Signal()
|
|
||||||
self.clock_domains.cd_jesd = ClockDomain()
|
|
||||||
refclk_pads = platform.request("ad9154_refclk")
|
|
||||||
|
|
||||||
self.specials += [
|
|
||||||
Instance("IBUFDS_GTE2", i_CEB=0,
|
|
||||||
i_I=refclk_pads.p, i_IB=refclk_pads.n, o_O=refclk),
|
|
||||||
Instance("BUFG", i_I=refclk, o_O=self.cd_jesd.clk),
|
|
||||||
AsyncResetSynchronizer(self.cd_jesd, ResetSignal("rio_phy")),
|
|
||||||
]
|
|
||||||
self.cd_jesd.clk.attr.add("keep")
|
|
||||||
platform.add_period_constraint(self.cd_jesd.clk, 1e9/refclk_freq)
|
|
||||||
|
|
||||||
qpll = GTXQuadPLL(refclk, refclk_freq, linerate)
|
|
||||||
self.submodules += qpll
|
|
||||||
self.phys = []
|
|
||||||
for i in range(4):
|
|
||||||
phy = JESD204BPhyTX(
|
|
||||||
qpll, platform.request("ad9154_jesd", i), fabric_freq)
|
|
||||||
phy.gtx.cd_tx.clk.attr.add("keep")
|
|
||||||
platform.add_period_constraint(phy.gtx.cd_tx.clk, 40*1e9/linerate)
|
|
||||||
platform.add_false_path_constraints(self.cd_jesd.clk,
|
|
||||||
phy.gtx.cd_tx.clk)
|
|
||||||
self.phys.append(phy)
|
|
||||||
to_jesd = ClockDomainsRenamer("jesd")
|
|
||||||
self.submodules.core = to_jesd(JESD204BCoreTX(self.phys, settings,
|
|
||||||
converter_data_width=32))
|
|
||||||
self.submodules.control = to_jesd(JESD204BCoreTXControl(self.core))
|
|
||||||
|
|
||||||
self.comb += [
|
|
||||||
platform.request("ad9154_txen", 0).eq(1),
|
|
||||||
platform.request("ad9154_txen", 1).eq(1),
|
|
||||||
self.core.start.eq(self.jsync),
|
|
||||||
platform.request("user_led", 3).eq(self.jsync),
|
|
||||||
]
|
|
||||||
|
|
||||||
# blinking leds for transceiver reset status
|
|
||||||
for i in range(4):
|
|
||||||
counter = Signal(max=fabric_freq)
|
|
||||||
self.comb += platform.request("user_led", 4 + i).eq(counter[-1])
|
|
||||||
sync = getattr(self.sync, "phy{}_tx".format(i))
|
|
||||||
sync += [
|
|
||||||
counter.eq(counter - 1),
|
|
||||||
If(counter == 0,
|
|
||||||
counter.eq(fabric_freq - 1)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class AD9154(Module, AutoCSR):
|
|
||||||
def __init__(self, platform):
|
|
||||||
ad9154_spi = platform.request("ad9154_spi")
|
|
||||||
self.comb += ad9154_spi.en.eq(1)
|
|
||||||
|
|
||||||
self.submodules.spi = spi_csr.SPIMaster(ad9154_spi)
|
|
||||||
|
|
||||||
self.submodules.jesd = AD9154JESD(platform)
|
|
||||||
|
|
||||||
self.sawgs = [sawg.Channel(width=16, parallelism=2) for i in range(4)]
|
|
||||||
self.submodules += self.sawgs
|
|
||||||
|
|
||||||
for conv, ch in zip(self.jesd.core.sink.flatten(), self.sawgs):
|
|
||||||
self.sync.jesd += conv.eq(Cat(ch.o))
|
|
||||||
|
|
||||||
|
|
||||||
class Phaser(MiniSoC, AMPSoC):
|
|
||||||
mem_map = {
|
|
||||||
"timer_kernel": 0x10000000, # (shadow @0x90000000)
|
|
||||||
"rtio": 0x20000000, # (shadow @0xa0000000)
|
|
||||||
"i2c": 0x30000000, # (shadow @0xb0000000)
|
|
||||||
"mailbox": 0x70000000, # (shadow @0xf0000000)
|
|
||||||
"ad9154": 0x50000000,
|
|
||||||
}
|
|
||||||
mem_map.update(MiniSoC.mem_map)
|
|
||||||
|
|
||||||
def __init__(self, cpu_type="or1k", **kwargs):
|
|
||||||
MiniSoC.__init__(self,
|
|
||||||
cpu_type=cpu_type,
|
|
||||||
sdram_controller_type="minicon",
|
|
||||||
l2_size=128*1024,
|
|
||||||
with_timer=False,
|
|
||||||
ident=artiq_version,
|
|
||||||
**kwargs)
|
|
||||||
AMPSoC.__init__(self)
|
|
||||||
self.platform.toolchain.bitstream_commands.extend([
|
|
||||||
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
|
||||||
])
|
|
||||||
|
|
||||||
platform = self.platform
|
|
||||||
platform.add_extension(_ams101_dac)
|
|
||||||
platform.add_extension(phaser.fmc_adapter_io)
|
|
||||||
|
|
||||||
self.submodules.leds = gpio.GPIOOut(Cat(
|
|
||||||
platform.request("user_led", 0),
|
|
||||||
platform.request("user_led", 1)))
|
|
||||||
self.csr_devices.append("leds")
|
|
||||||
|
|
||||||
i2c = platform.request("i2c")
|
|
||||||
self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda])
|
|
||||||
self.register_kernel_cpu_csrdevice("i2c")
|
|
||||||
self.config["I2C_BUS_COUNT"] = 1
|
|
||||||
|
|
||||||
self.submodules.ad9154 = AD9154(platform)
|
|
||||||
self.register_kernel_cpu_csrdevice("ad9154")
|
|
||||||
self.config["AD9154_DAC_CS"] = 1 << 0
|
|
||||||
self.config["AD9154_CLK_CS"] = 1 << 1
|
|
||||||
|
|
||||||
rtio_channels = []
|
|
||||||
|
|
||||||
phy = ttl_serdes_7series.Inout_8X(
|
|
||||||
platform.request("user_sma_gpio_n"))
|
|
||||||
self.submodules += phy
|
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=128))
|
|
||||||
|
|
||||||
phy = ttl_simple.Output(platform.request("user_led", 2))
|
|
||||||
self.submodules += phy
|
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy))
|
|
||||||
|
|
||||||
sysref_pads = platform.request("ad9154_sysref")
|
|
||||||
phy = ttl_serdes_7series.Input_8X(sysref_pads.p, sysref_pads.n)
|
|
||||||
self.submodules += phy
|
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=32,
|
|
||||||
ofifo_depth=2))
|
|
||||||
|
|
||||||
phy = ttl_simple.Input(self.ad9154.jesd.jsync)
|
|
||||||
self.submodules += phy
|
|
||||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=32,
|
|
||||||
ofifo_depth=2))
|
|
||||||
|
|
||||||
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)
|
|
||||||
|
|
||||||
self.config["RTIO_FIRST_SAWG_CHANNEL"] = len(rtio_channels)
|
|
||||||
rtio_channels.extend(rtio.Channel.from_phy(phy)
|
|
||||||
for sawg in self.ad9154.sawgs
|
|
||||||
for phy in sawg.phys)
|
|
||||||
|
|
||||||
self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels)
|
|
||||||
rtio_channels.append(rtio.LogChannel())
|
|
||||||
|
|
||||||
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
|
||||||
self.config["RTIO_DDS_COUNT"] = 1
|
|
||||||
self.config["DDS_CHANNELS_PER_BUS"] = 1
|
|
||||||
self.config["DDS_AD9914"] = None
|
|
||||||
self.config["DDS_ONEHOT_SEL"] = None
|
|
||||||
self.config["DDS_RTIO_CLK_RATIO"] = 8
|
|
||||||
|
|
||||||
self.submodules.rtio_crg = _PhaserCRG(
|
|
||||||
platform, self.ad9154.jesd.cd_jesd.clk)
|
|
||||||
self.csr_devices.append("rtio_crg")
|
|
||||||
self.submodules.rtio = rtio.RTIO(rtio_channels)
|
|
||||||
self.register_kernel_cpu_csrdevice("rtio")
|
|
||||||
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
|
||||||
self.csr_devices.append("rtio_moninj")
|
|
||||||
self.submodules.rtio_analyzer = rtio.Analyzer(
|
|
||||||
self.rtio, self.get_native_sdram_if())
|
|
||||||
self.csr_devices.append("rtio_analyzer")
|
|
||||||
|
|
||||||
self.config["RTIO_FINE_TS_WIDTH"] = self.rtio.fine_ts_width
|
|
||||||
platform.add_false_path_constraints(
|
|
||||||
self.crg.cd_sys.clk, self.rtio_crg.cd_rtio.clk)
|
|
||||||
platform.add_false_path_constraints(
|
|
||||||
self.crg.cd_sys.clk, self.ad9154.jesd.cd_jesd.clk)
|
|
||||||
for phy in self.ad9154.jesd.phys:
|
|
||||||
platform.add_false_path_constraints(
|
|
||||||
self.crg.cd_sys.clk, phy.gtx.cd_tx.clk)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="ARTIQ core device builder / KC705 "
|
description="ARTIQ core device builder / KC705 "
|
||||||
|
@ -552,7 +318,7 @@ def main():
|
||||||
soc_kc705_args(parser)
|
soc_kc705_args(parser)
|
||||||
parser.add_argument("-H", "--hw-adapter", default="nist_clock",
|
parser.add_argument("-H", "--hw-adapter", default="nist_clock",
|
||||||
help="hardware adapter type: "
|
help="hardware adapter type: "
|
||||||
"nist_clock/nist_qc2/phaser "
|
"nist_clock/nist_qc2 "
|
||||||
"(default: %(default)s)")
|
"(default: %(default)s)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -561,8 +327,6 @@ def main():
|
||||||
cls = NIST_CLOCK
|
cls = NIST_CLOCK
|
||||||
elif hw_adapter == "nist_qc2":
|
elif hw_adapter == "nist_qc2":
|
||||||
cls = NIST_QC2
|
cls = NIST_QC2
|
||||||
elif hw_adapter == "phaser":
|
|
||||||
cls = Phaser
|
|
||||||
else:
|
else:
|
||||||
raise SystemExit("Invalid hardware adapter string (-H/--hw-adapter)")
|
raise SystemExit("Invalid hardware adapter string (-H/--hw-adapter)")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
#!/usr/bin/env python3.5
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from migen import *
|
||||||
|
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||||
|
from migen.genlib.cdc import MultiReg
|
||||||
|
from migen.genlib.io import DifferentialInput
|
||||||
|
|
||||||
|
from jesd204b.common import (JESD204BTransportSettings,
|
||||||
|
JESD204BPhysicalSettings,
|
||||||
|
JESD204BSettings)
|
||||||
|
from jesd204b.phy.gtx import GTXQuadPLL
|
||||||
|
from jesd204b.phy import JESD204BPhyTX
|
||||||
|
from jesd204b.core import JESD204BCoreTX
|
||||||
|
from jesd204b.core import JESD204BCoreTXControl
|
||||||
|
|
||||||
|
from misoc.interconnect.csr import *
|
||||||
|
from misoc.cores import gpio
|
||||||
|
from misoc.cores import spi as spi_csr
|
||||||
|
from misoc.targets.kc705 import MiniSoC, soc_kc705_args, soc_kc705_argdict
|
||||||
|
from misoc.integration.builder import builder_args, builder_argdict
|
||||||
|
|
||||||
|
from artiq.gateware.soc import AMPSoC, build_artiq_soc
|
||||||
|
from artiq.gateware import rtio, phaser
|
||||||
|
from artiq.gateware.rtio.phy import (ttl_simple, ttl_serdes_7series,
|
||||||
|
sawg)
|
||||||
|
from artiq import __version__ as artiq_version
|
||||||
|
|
||||||
|
|
||||||
|
class _PhaserCRG(Module, AutoCSR):
|
||||||
|
def __init__(self, platform, refclk):
|
||||||
|
self._clock_sel = CSRStorage()
|
||||||
|
self._pll_reset = CSRStorage(reset=1)
|
||||||
|
self._pll_locked = CSRStatus()
|
||||||
|
self.clock_domains.cd_rtio = ClockDomain()
|
||||||
|
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
||||||
|
|
||||||
|
pll_locked = Signal()
|
||||||
|
rtio_clk = Signal()
|
||||||
|
rtiox4_clk = Signal()
|
||||||
|
self.specials += [
|
||||||
|
Instance("PLLE2_ADV",
|
||||||
|
p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
|
||||||
|
|
||||||
|
p_REF_JITTER1=0.01, p_REF_JITTER2=0.01,
|
||||||
|
p_CLKIN1_PERIOD=20/3, p_CLKIN2_PERIOD=20/3,
|
||||||
|
i_CLKIN1=0, i_CLKIN2=refclk,
|
||||||
|
# Warning: CLKINSEL=0 means CLKIN2 is selected
|
||||||
|
i_CLKINSEL=~self._clock_sel.storage,
|
||||||
|
|
||||||
|
# VCO @ 1.2GHz when using 150MHz input
|
||||||
|
p_CLKFBOUT_MULT=8, p_DIVCLK_DIVIDE=1,
|
||||||
|
i_CLKFBIN=self.cd_rtio.clk,
|
||||||
|
i_RST=self._pll_reset.storage,
|
||||||
|
|
||||||
|
o_CLKFBOUT=rtio_clk,
|
||||||
|
|
||||||
|
p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0,
|
||||||
|
o_CLKOUT0=rtiox4_clk,
|
||||||
|
),
|
||||||
|
Instance("BUFG", i_I=rtio_clk, o_O=self.cd_rtio.clk),
|
||||||
|
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
||||||
|
AsyncResetSynchronizer(self.cd_rtio, ~pll_locked),
|
||||||
|
MultiReg(pll_locked | ~self._clock_sel.storage,
|
||||||
|
self._pll_locked.status)
|
||||||
|
]
|
||||||
|
self.cd_rtio.clk.attr.add("keep")
|
||||||
|
platform.add_period_constraint(self.cd_rtio.clk, 20/3)
|
||||||
|
|
||||||
|
|
||||||
|
class AD9154JESD(Module, AutoCSR):
|
||||||
|
def __init__(self, platform):
|
||||||
|
ps = JESD204BPhysicalSettings(l=4, m=4, n=16, np=16)
|
||||||
|
ts = JESD204BTransportSettings(f=2, s=1, k=16, cs=1)
|
||||||
|
settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||||
|
linerate = 6e9
|
||||||
|
refclk_freq = 150e6
|
||||||
|
fabric_freq = 150*1000*1000
|
||||||
|
|
||||||
|
sync_pads = platform.request("ad9154_sync")
|
||||||
|
self.jsync = Signal()
|
||||||
|
self.specials += DifferentialInput(
|
||||||
|
sync_pads.p, sync_pads.n, self.jsync)
|
||||||
|
|
||||||
|
refclk = Signal()
|
||||||
|
self.clock_domains.cd_jesd = ClockDomain()
|
||||||
|
refclk_pads = platform.request("ad9154_refclk")
|
||||||
|
|
||||||
|
self.specials += [
|
||||||
|
Instance("IBUFDS_GTE2", i_CEB=0,
|
||||||
|
i_I=refclk_pads.p, i_IB=refclk_pads.n, o_O=refclk),
|
||||||
|
Instance("BUFG", i_I=refclk, o_O=self.cd_jesd.clk),
|
||||||
|
AsyncResetSynchronizer(self.cd_jesd, ResetSignal("rio_phy")),
|
||||||
|
]
|
||||||
|
self.cd_jesd.clk.attr.add("keep")
|
||||||
|
platform.add_period_constraint(self.cd_jesd.clk, 1e9/refclk_freq)
|
||||||
|
|
||||||
|
qpll = GTXQuadPLL(refclk, refclk_freq, linerate)
|
||||||
|
self.submodules += qpll
|
||||||
|
self.phys = []
|
||||||
|
for i in range(4):
|
||||||
|
phy = JESD204BPhyTX(
|
||||||
|
qpll, platform.request("ad9154_jesd", i), fabric_freq)
|
||||||
|
phy.gtx.cd_tx.clk.attr.add("keep")
|
||||||
|
platform.add_period_constraint(phy.gtx.cd_tx.clk, 40*1e9/linerate)
|
||||||
|
platform.add_false_path_constraints(self.cd_jesd.clk,
|
||||||
|
phy.gtx.cd_tx.clk)
|
||||||
|
self.phys.append(phy)
|
||||||
|
to_jesd = ClockDomainsRenamer("jesd")
|
||||||
|
self.submodules.core = to_jesd(JESD204BCoreTX(self.phys, settings,
|
||||||
|
converter_data_width=32))
|
||||||
|
self.submodules.control = to_jesd(JESD204BCoreTXControl(self.core))
|
||||||
|
|
||||||
|
self.comb += [
|
||||||
|
platform.request("ad9154_txen", 0).eq(1),
|
||||||
|
platform.request("ad9154_txen", 1).eq(1),
|
||||||
|
self.core.start.eq(self.jsync),
|
||||||
|
platform.request("user_led", 3).eq(self.jsync),
|
||||||
|
]
|
||||||
|
|
||||||
|
# blinking leds for transceiver reset status
|
||||||
|
for i in range(4):
|
||||||
|
counter = Signal(max=fabric_freq)
|
||||||
|
self.comb += platform.request("user_led", 4 + i).eq(counter[-1])
|
||||||
|
sync = getattr(self.sync, "phy{}_tx".format(i))
|
||||||
|
sync += [
|
||||||
|
counter.eq(counter - 1),
|
||||||
|
If(counter == 0,
|
||||||
|
counter.eq(fabric_freq - 1)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class AD9154(Module, AutoCSR):
|
||||||
|
def __init__(self, platform):
|
||||||
|
ad9154_spi = platform.request("ad9154_spi")
|
||||||
|
self.comb += ad9154_spi.en.eq(1)
|
||||||
|
|
||||||
|
self.submodules.spi = spi_csr.SPIMaster(ad9154_spi)
|
||||||
|
|
||||||
|
self.submodules.jesd = AD9154JESD(platform)
|
||||||
|
|
||||||
|
self.sawgs = [sawg.Channel(width=16, parallelism=2) for i in range(4)]
|
||||||
|
self.submodules += self.sawgs
|
||||||
|
|
||||||
|
for conv, ch in zip(self.jesd.core.sink.flatten(), self.sawgs):
|
||||||
|
self.sync.jesd += conv.eq(Cat(ch.o))
|
||||||
|
|
||||||
|
|
||||||
|
class Phaser(MiniSoC, AMPSoC):
|
||||||
|
mem_map = {
|
||||||
|
"timer_kernel": 0x10000000, # (shadow @0x90000000)
|
||||||
|
"rtio": 0x20000000, # (shadow @0xa0000000)
|
||||||
|
"i2c": 0x30000000, # (shadow @0xb0000000)
|
||||||
|
"mailbox": 0x70000000, # (shadow @0xf0000000)
|
||||||
|
"ad9154": 0x50000000,
|
||||||
|
}
|
||||||
|
mem_map.update(MiniSoC.mem_map)
|
||||||
|
|
||||||
|
def __init__(self, cpu_type="or1k", **kwargs):
|
||||||
|
MiniSoC.__init__(self,
|
||||||
|
cpu_type=cpu_type,
|
||||||
|
sdram_controller_type="minicon",
|
||||||
|
l2_size=128*1024,
|
||||||
|
with_timer=False,
|
||||||
|
ident=artiq_version,
|
||||||
|
**kwargs)
|
||||||
|
AMPSoC.__init__(self)
|
||||||
|
self.platform.toolchain.bitstream_commands.extend([
|
||||||
|
"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
|
||||||
|
])
|
||||||
|
|
||||||
|
platform = self.platform
|
||||||
|
platform.add_extension(phaser.fmc_adapter_io)
|
||||||
|
|
||||||
|
self.submodules.leds = gpio.GPIOOut(Cat(
|
||||||
|
platform.request("user_led", 0),
|
||||||
|
platform.request("user_led", 1)))
|
||||||
|
self.csr_devices.append("leds")
|
||||||
|
|
||||||
|
i2c = platform.request("i2c")
|
||||||
|
self.submodules.i2c = gpio.GPIOTristate([i2c.scl, i2c.sda])
|
||||||
|
self.register_kernel_cpu_csrdevice("i2c")
|
||||||
|
self.config["I2C_BUS_COUNT"] = 1
|
||||||
|
|
||||||
|
self.submodules.ad9154 = AD9154(platform)
|
||||||
|
self.register_kernel_cpu_csrdevice("ad9154")
|
||||||
|
self.config["AD9154_DAC_CS"] = 1 << 0
|
||||||
|
self.config["AD9154_CLK_CS"] = 1 << 1
|
||||||
|
|
||||||
|
rtio_channels = []
|
||||||
|
|
||||||
|
phy = ttl_serdes_7series.Inout_8X(
|
||||||
|
platform.request("user_sma_gpio_n"))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=128))
|
||||||
|
|
||||||
|
phy = ttl_simple.Output(platform.request("user_led", 2))
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy))
|
||||||
|
|
||||||
|
sysref_pads = platform.request("ad9154_sysref")
|
||||||
|
phy = ttl_serdes_7series.Input_8X(sysref_pads.p, sysref_pads.n)
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=32,
|
||||||
|
ofifo_depth=2))
|
||||||
|
|
||||||
|
phy = ttl_simple.Input(self.ad9154.jesd.jsync)
|
||||||
|
self.submodules += phy
|
||||||
|
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=32,
|
||||||
|
ofifo_depth=2))
|
||||||
|
|
||||||
|
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)
|
||||||
|
|
||||||
|
self.config["RTIO_FIRST_SAWG_CHANNEL"] = len(rtio_channels)
|
||||||
|
rtio_channels.extend(rtio.Channel.from_phy(phy)
|
||||||
|
for sawg in self.ad9154.sawgs
|
||||||
|
for phy in sawg.phys)
|
||||||
|
|
||||||
|
self.config["RTIO_LOG_CHANNEL"] = len(rtio_channels)
|
||||||
|
rtio_channels.append(rtio.LogChannel())
|
||||||
|
|
||||||
|
self.config["RTIO_FIRST_DDS_CHANNEL"] = len(rtio_channels)
|
||||||
|
self.config["RTIO_DDS_COUNT"] = 1
|
||||||
|
self.config["DDS_CHANNELS_PER_BUS"] = 1
|
||||||
|
self.config["DDS_AD9914"] = None
|
||||||
|
self.config["DDS_ONEHOT_SEL"] = None
|
||||||
|
self.config["DDS_RTIO_CLK_RATIO"] = 8
|
||||||
|
|
||||||
|
self.submodules.rtio_crg = _PhaserCRG(
|
||||||
|
platform, self.ad9154.jesd.cd_jesd.clk)
|
||||||
|
self.csr_devices.append("rtio_crg")
|
||||||
|
self.submodules.rtio = rtio.RTIO(rtio_channels)
|
||||||
|
self.register_kernel_cpu_csrdevice("rtio")
|
||||||
|
self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)
|
||||||
|
self.csr_devices.append("rtio_moninj")
|
||||||
|
self.submodules.rtio_analyzer = rtio.Analyzer(
|
||||||
|
self.rtio, self.get_native_sdram_if())
|
||||||
|
self.csr_devices.append("rtio_analyzer")
|
||||||
|
|
||||||
|
self.config["RTIO_FINE_TS_WIDTH"] = self.rtio.fine_ts_width
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.crg.cd_sys.clk, self.rtio_crg.cd_rtio.clk)
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.crg.cd_sys.clk, self.ad9154.jesd.cd_jesd.clk)
|
||||||
|
for phy in self.ad9154.jesd.phys:
|
||||||
|
platform.add_false_path_constraints(
|
||||||
|
self.crg.cd_sys.clk, phy.gtx.cd_tx.clk)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="ARTIQ core device builder for "
|
||||||
|
"KC705+AD9154 hardware")
|
||||||
|
builder_args(parser)
|
||||||
|
soc_kc705_args(parser)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
soc = Phaser(**soc_kc705_argdict(args))
|
||||||
|
build_artiq_soc(soc, builder_argdict(args))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Reference in New Issue