From c591f1a74d2242f52fa16ee588da4ac70b39089c Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 1 Dec 2014 18:53:29 +0800 Subject: [PATCH] targets/ARTIQMiniSoC: support dynamic switching of RTIO clock to XTRIG --- doc/manual/fpga_board_ports.rst | 2 ++ soc/targets/artiq.py | 33 +++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/doc/manual/fpga_board_ports.rst b/doc/manual/fpga_board_ports.rst index eff4e3ac9..d8f3d31f6 100644 --- a/doc/manual/fpga_board_ports.rst +++ b/doc/manual/fpga_board_ports.rst @@ -36,3 +36,5 @@ When plugged to a QC-DAQ LVDS adapter, the AD9858 DDS hardware can be used in ad +--------------+----------+-----------------+ The input only limitation on channels 0 and 1 comes from the QC-DAQ adapter. When the adapter is not used (and physically unplugged from the Papilio Pro board), the corresponding pins on the Papilio Pro can be used as outputs. Do not configure these channels as outputs when the adapter is plugged, as this would cause electrical contention. + +The board can accept an external RTIO clock connected to XTRIG. diff --git a/soc/targets/artiq.py b/soc/targets/artiq.py index 2e1676a4a..c7539e2c2 100644 --- a/soc/targets/artiq.py +++ b/soc/targets/artiq.py @@ -1,4 +1,5 @@ from migen.fhdl.std import * +from migen.bank.description import * from migen.bank import wbgen from mibuild.generic_platform import * @@ -13,6 +14,7 @@ _tester_io = [ ("pmt", 0, Pins("C:13"), IOStandard("LVTTL")), ("pmt", 1, Pins("C:14"), IOStandard("LVTTL")), + ("xtrig", 0, Pins("C:12"), IOStandard("LVTTL")), # used for DDS clock ("ttl", 0, Pins("C:11"), IOStandard("LVTTL")), ("ttl", 1, Pins("C:10"), IOStandard("LVTTL")), @@ -51,27 +53,42 @@ class _TestGen(Module): self.comb += pad.eq(sr[0]) -class _RTIOMiniCRG(Module): +class _RTIOMiniCRG(Module, AutoCSR): def __init__(self, platform): + self._r_clock_sel = CSRStorage() self.clock_domains.cd_rtio = ClockDomain() - # 80MHz -> 125MHz - self.specials += Instance("DCM_CLKGEN", - p_CLKFXDV_DIVIDE=2, p_CLKFX_DIVIDE=16, p_CLKFX_MD_MAX=1.6, p_CLKFX_MULTIPLY=25, - p_CLKIN_PERIOD=12.5, p_SPREAD_SPECTRUM="NONE", p_STARTUP_WAIT="FALSE", - i_CLKIN=ClockSignal(), o_CLKFX=self.cd_rtio.clk, + # 80MHz -> 125MHz + rtio_internal_clk = Signal() + self.specials += Instance("DCM_CLKGEN", + p_CLKFXDV_DIVIDE=2, + p_CLKFX_DIVIDE=16, p_CLKFX_MD_MAX=1.6, p_CLKFX_MULTIPLY=25, + p_CLKIN_PERIOD=12.5, p_SPREAD_SPECTRUM="NONE", + p_STARTUP_WAIT="FALSE", + + i_CLKIN=ClockSignal(), o_CLKFX=rtio_internal_clk, i_FREEZEDCM=0, i_RST=ResetSignal()) + + rtio_external_clk = platform.request("xtrig") + platform.add_period_constraint(rtio_external_clk, 8.0) + self.specials += Instance("BUFGMUX", + i_I0=rtio_internal_clk, + i_I1=rtio_external_clk, + i_S=self._r_clock_sel.storage, + o_O=self.cd_rtio.clk) + platform.add_platform_command(""" NET "{rtio_clk}" TNM_NET = "GRPrtio_clk"; NET "sys_clk" TNM_NET = "GRPsys_clk"; TIMESPEC "TSfix_ise1" = FROM "GRPrtio_clk" TO "GRPsys_clk" TIG; TIMESPEC "TSfix_ise2" = FROM "GRPsys_clk" TO "GRPrtio_clk" TIG; -""", rtio_clk=self.cd_rtio.clk) +""", rtio_clk=rtio_internal_clk) class ARTIQMiniSoC(BaseSoC): csr_map = { - "rtio": None # mapped on Wishbone instead + "rtio": None, # mapped on Wishbone instead + "rtiocrg": 13 } csr_map.update(BaseSoC.csr_map)