def __init__(self, platform, **kwargs):
        VideoMixerSoC.__init__(self, platform, **kwargs)

        lasmim = self.sdram.crossbar.get_master()
        self.submodules.encoder_reader = EncoderDMAReader(lasmim)
        self.submodules.encoder_cdc = RenameClockDomains(AsyncFIFO([("data", 128)], 4),
                                          {"write": "sys", "read": "encoder"})
        self.submodules.encoder_buffer = RenameClockDomains(EncoderBuffer(), "encoder")
        self.submodules.encoder_fifo = RenameClockDomains(SyncFIFO(EndpointDescription([("data", 16)], packetized=True), 16), "encoder")
        self.submodules.encoder = Encoder(platform)
        self.submodules.usb_streamer = USBStreamer(platform, platform.request("fx2"))

        self.comb += [
            Record.connect(self.encoder_reader.source, self.encoder_cdc.sink),
            Record.connect(self.encoder_cdc.source, self.encoder_buffer.sink),
            Record.connect(self.encoder_buffer.source, self.encoder_fifo.sink),
            Record.connect(self.encoder_fifo.source, self.encoder.sink),
            Record.connect(self.encoder.source, self.usb_streamer.sink)
        ]
        self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), self.encoder.bus)
        self.add_memory_region("encoder", self.mem_map["encoder"]+self.shadow_base, 0x2000)

        platform.add_platform_command("""
NET "{usb_clk}" TNM_NET = "GRPusb_clk";
TIMESPEC "TSise_sucks11" = FROM "GRPusb_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks12" = FROM "GRPsys_clk" TO "GRPusb_clk" TIG;
""", usb_clk=platform.lookup_request("fx2").ifclk)
    def __init__(self, platform, **kwargs):
        EtherVideoMixerSoC.__init__(self, platform, **kwargs)

        lasmim = self.sdram.crossbar.get_master()
        self.submodules.encoder_reader = EncoderDMAReader(lasmim)
        self.submodules.encoder_cdc = RenameClockDomains(AsyncFIFO([("data", 128)], 4),
                                          {"write": "sys", "read": "encoder"})
        self.submodules.encoder_buffer = RenameClockDomains(EncoderBuffer(), "encoder")
        self.submodules.encoder_fifo = RenameClockDomains(SyncFIFO(EndpointDescription([("data", 16)], packetized=True), 16), "encoder")
        self.submodules.encoder = Encoder(platform)
        encoder_port = self.ethcore.udp.crossbar.get_port(8000, 8)
        self.submodules.encoder_streamer = UDPStreamer(convert_ip("192.168.1.15"), 8000)

        self.comb += [
            platform.request("user_led", 0).eq(self.encoder_reader.source.stb),
            platform.request("user_led", 1).eq(self.encoder_reader.source.ack),
            Record.connect(self.encoder_reader.source, self.encoder_cdc.sink),
            Record.connect(self.encoder_cdc.source, self.encoder_buffer.sink),
            Record.connect(self.encoder_buffer.source, self.encoder_fifo.sink),
            Record.connect(self.encoder_fifo.source, self.encoder.sink),
            Record.connect(self.encoder.source, self.encoder_streamer.sink),
            Record.connect(self.encoder_streamer.source, encoder_port.sink)
        ]
        self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), self.encoder.bus)
        self.add_memory_region("encoder", self.mem_map["encoder"]+self.shadow_base, 0x2000)
Esempio n. 3
0
    def __init__(self, platform, **kwargs):
        BaseSoC.__init__(self, platform, **kwargs)

        self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"), platform.request("eth"), clk_freq=self.clk_freq)
        self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
        self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
        self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
Esempio n. 4
0
    def add_rtio(self, rtio_channels):
        self.submodules.rtio_crg = _RTIOCRG(self.platform, self.crg.cd_sys.clk)
        self.submodules.rtio = rtio.RTIO(rtio_channels)
        self.add_constant("RTIO_FINE_TS_WIDTH", self.rtio.fine_ts_width)
        assert self.rtio.fine_ts_width <= 3
        self.add_constant("DDS_RTIO_CLK_RATIO", 8 >> self.rtio.fine_ts_width)
        self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)

        if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
            self.platform.add_platform_command("""
create_clock -name rsys_clk -period 8.0 [get_nets {rsys_clk}]
create_clock -name rio_clk -period 8.0 [get_nets {rio_clk}]
set_false_path -from [get_clocks rsys_clk] -to [get_clocks rio_clk]
set_false_path -from [get_clocks rio_clk] -to [get_clocks rsys_clk]
""", rsys_clk=self.rtio.cd_rsys.clk, rio_clk=self.rtio.cd_rio.clk)
        if isinstance(self.platform.toolchain, XilinxISEToolchain):
            self.platform.add_platform_command("""
NET "sys_clk" TNM_NET = "GRPrsys_clk";
NET "{rio_clk}" TNM_NET = "GRPrio_clk";
TIMESPEC "TSfix_cdc1" = FROM "GRPrsys_clk" TO "GRPrio_clk" TIG;
TIMESPEC "TSfix_cdc2" = FROM "GRPrio_clk" TO "GRPrsys_clk" TIG;
""", rio_clk=self.rtio_crg.cd_rtio.clk)

        rtio_csrs = self.rtio.get_csrs()
        self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
        self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
                                     self.rtiowb.bus)
        self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
                            rtio_csrs)
    def __init__(self, platform, **kwargs):
        BaseSoC.__init__(self, platform, **kwargs)

        self.submodules.ethphy = LiteEthPHYRGMII(platform.request("eth_clocks"), platform.request("eth"))
        self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
        self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
        self.add_memory_region("ethmac", self.mem_map["ethmac"]+self.shadow_base, 0x2000)

        self.specials += [
            Keep(self.ethphy.crg.cd_eth_rx.clk),
            Keep(self.ethphy.crg.cd_eth_tx.clk)
        ]
        platform.add_platform_command("""
# Separate TMNs for FROM:TO TIG constraints
NET "{eth_clocks_rx}" CLOCK_DEDICATED_ROUTE = FALSE;
NET "{eth_rx_clk}" TNM_NET = "TIGeth_rx_clk";
NET "{eth_tx_clk}" TNM_NET = "TIGeth_tx_clk";
TIMESPEC "TSeth_tx_to_sys" = FROM "TIGeth_tx_clk" TO "TIGsys_clk" TIG;
TIMESPEC "TSsys_to_eth_tx" = FROM "TIGsys_clk" TO "TIGeth_tx_clk" TIG;
TIMESPEC "TSeth_rx_to_sys" = FROM "TIGeth_rx_clk" TO "TIGsys_clk" TIG;
TIMESPEC "TSsys_to_eth_rx" = FROM "TIGsys_clk" TO "TIGeth_rx_clk" TIG;
# FIXME: What is this?
PIN "BUFG_4.O" CLOCK_DEDICATED_ROUTE = FALSE;
""", eth_clocks_rx=platform.lookup_request("eth_clocks").rx,
     eth_rx_clk=self.ethphy.crg.cd_eth_rx.clk,
     eth_tx_clk=self.ethphy.crg.cd_eth_tx.clk)
Esempio n. 6
0
    def __init__(self, platform, **kwargs):
        EtherVideoMixerSoC.__init__(self, platform, **kwargs)

        lasmim = self.sdram.crossbar.get_master()
        self.submodules.encoder_reader = EncoderDMAReader(lasmim)
        self.submodules.encoder_cdc = RenameClockDomains(
            AsyncFIFO([("data", 128)], 4), {
                "write": "sys",
                "read": "encoder"
            })
        self.submodules.encoder_buffer = RenameClockDomains(
            EncoderBuffer(), "encoder")
        self.submodules.encoder_fifo = RenameClockDomains(
            SyncFIFO(EndpointDescription([("data", 16)], packetized=True), 16),
            "encoder")
        self.submodules.encoder = Encoder(platform)
        encoder_port = self.ethcore.udp.crossbar.get_port(8000, 8)
        self.submodules.encoder_streamer = UDPStreamer(
            convert_ip("192.168.1.15"), 8000)

        self.comb += [
            platform.request("user_led", 0).eq(self.encoder_reader.source.stb),
            platform.request("user_led", 1).eq(self.encoder_reader.source.ack),
            Record.connect(self.encoder_reader.source, self.encoder_cdc.sink),
            Record.connect(self.encoder_cdc.source, self.encoder_buffer.sink),
            Record.connect(self.encoder_buffer.source, self.encoder_fifo.sink),
            Record.connect(self.encoder_fifo.source, self.encoder.sink),
            Record.connect(self.encoder.source, self.encoder_streamer.sink),
            Record.connect(self.encoder_streamer.source, encoder_port.sink)
        ]
        self.add_wb_slave(mem_decoder(self.mem_map["encoder"]),
                          self.encoder.bus)
        self.add_memory_region("encoder",
                               self.mem_map["encoder"] + self.shadow_base,
                               0x2000)
Esempio n. 7
0
    def __init__(self, platform, **kwargs):
        BaseSoC.__init__(self, platform, **kwargs)

        self.submodules.ethphy = LiteEthPHYMII(platform.request("eth_clocks"),
                                               platform.request("eth"))
        self.submodules.ethmac = LiteEthMAC(phy=self.ethphy,
                                            dw=32,
                                            interface="wishbone")
        self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
        self.add_memory_region("ethmac",
                               self.mem_map["ethmac"] + self.shadow_base,
                               0x2000)

        platform.add_platform_command(
            """
NET "{eth_clocks_rx}" CLOCK_DEDICATED_ROUTE = FALSE;
NET "{eth_clocks_rx}" TNM_NET = "GRPeth_rx_clk";
NET "{eth_clocks_tx}" TNM_NET = "GRPeth_tx_clk";
TIMESPEC "TSise_sucks1" = FROM "GRPeth_tx_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPeth_tx_clk" TIG;
TIMESPEC "TSise_sucks3" = FROM "GRPeth_rx_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks4" = FROM "GRPsys_clk" TO "GRPeth_rx_clk" TIG;
""",
            eth_clocks_rx=platform.lookup_request("eth_clocks").rx,
            eth_clocks_tx=platform.lookup_request("eth_clocks").tx)
Esempio n. 8
0
    def __init__(self, platform, **kwargs):
        BaseSoC.__init__(self, platform, **kwargs)

        self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"), platform.request("eth"))
        self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone", with_preamble_crc=False)
        self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
        self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
Esempio n. 9
0
File: soc.py Progetto: fallen/artiq
    def __init__(self):
        if not hasattr(self, "cpu_or_bridge"):
            raise ValueError("Platform SoC must be initialized first")
        if hasattr(self, "timer0"):
            raise ValueError("Timer already exists. "
                             "Initialize platform SoC using with_timer=False")

        self.submodules.timer0 = timer.Timer(width=64)

        self.submodules.kernel_cpu = amp.KernelCPU(self.platform)
        self.add_wb_sdram_if(self.kernel_cpu.wb_sdram)

        self.submodules.mailbox = amp.Mailbox()
        self.add_wb_slave(mem_decoder(self.mem_map["mailbox"]),
                          self.mailbox.i1)
        self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["mailbox"]),
                                     self.mailbox.i2)
        self.add_memory_region("mailbox",
                               self.mem_map["mailbox"] | 0x80000000, 4)
Esempio n. 10
0
    def __init__(self):
        if not hasattr(self, "cpu_or_bridge"):
            raise ValueError("Platform SoC must be initialized first")
        if hasattr(self, "timer0"):
            raise ValueError("Timer already exists. "
                             "Initialize platform SoC using with_timer=False")

        self.submodules.timer0 = timer.Timer(width=64)

        self.submodules.kernel_cpu = amp.KernelCPU(self.platform)
        self.add_wb_sdram_if(self.kernel_cpu.wb_sdram)

        self.submodules.mailbox = amp.Mailbox()
        self.add_wb_slave(mem_decoder(self.mem_map["mailbox"]),
                          self.mailbox.i1)
        self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["mailbox"]),
                                     self.mailbox.i2)
        self.add_memory_region("mailbox", self.mem_map["mailbox"] | 0x80000000,
                               4)
Esempio n. 11
0
    def __init__(self, platform, **kwargs):
        BaseSoC.__init__(self, platform, **kwargs)

        if platform.name == "mixxeo":
            self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
        if platform.name == "m1":
            self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0),
                                                      platform.request("user_btn", 2)))
            self.submodules.leds = gpio.GPIOOut(Cat(platform.request("user_led", i) for i in range(2)))

        self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"),
                                            platform.request("eth"))
        self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
        self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
        self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
    def __init__(self, platform, **kwargs):
        BaseSoC.__init__(self, platform, **kwargs)

        self.submodules.ethphy = LiteEthPHYMII(platform.request("eth_clocks"), platform.request("eth"))
        self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
        self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
        self.add_memory_region("ethmac", self.mem_map["ethmac"]+self.shadow_base, 0x2000)

        platform.add_platform_command("""
NET "{eth_clocks_rx}" CLOCK_DEDICATED_ROUTE = FALSE;
NET "{eth_clocks_rx}" TNM_NET = "GRPeth_rx_clk";
NET "{eth_clocks_tx}" TNM_NET = "GRPeth_tx_clk";
TIMESPEC "TSise_sucks1" = FROM "GRPeth_tx_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPeth_tx_clk" TIG;
TIMESPEC "TSise_sucks3" = FROM "GRPeth_rx_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks4" = FROM "GRPsys_clk" TO "GRPeth_rx_clk" TIG;
""", eth_clocks_rx=platform.lookup_request("eth_clocks").rx,
     eth_clocks_tx=platform.lookup_request("eth_clocks").tx)
Esempio n. 13
0
    def __init__(self, platform, **kwargs):
        VideoMixerSoC.__init__(self, platform, **kwargs)

        lasmim = self.sdram.crossbar.get_master()
        self.submodules.encoder_reader = EncoderDMAReader(lasmim)
        self.submodules.encoder_cdc = RenameClockDomains(
            AsyncFIFO([("data", 128)], 4), {
                "write": "sys",
                "read": "encoder"
            })
        self.submodules.encoder_buffer = RenameClockDomains(
            EncoderBuffer(), "encoder")
        self.submodules.encoder_fifo = RenameClockDomains(
            SyncFIFO(EndpointDescription([("data", 16)], packetized=True), 16),
            "encoder")
        self.submodules.encoder = Encoder(platform)
        self.submodules.usb_streamer = USBStreamer(platform,
                                                   platform.request("fx2"))

        self.comb += [
            platform.request("user_led", 0).eq(self.encoder_reader.source.stb),
            platform.request("user_led", 1).eq(self.encoder_reader.source.ack),
            Record.connect(self.encoder_reader.source, self.encoder_cdc.sink),
            Record.connect(self.encoder_cdc.source, self.encoder_buffer.sink),
            Record.connect(self.encoder_buffer.source, self.encoder_fifo.sink),
            Record.connect(self.encoder_fifo.source, self.encoder.sink),
            Record.connect(self.encoder.source, self.usb_streamer.sink)
        ]
        self.add_wb_slave(mem_decoder(self.mem_map["encoder"]),
                          self.encoder.bus)
        self.add_memory_region("encoder",
                               self.mem_map["encoder"] + self.shadow_base,
                               0x2000)

        platform.add_platform_command(
            """
NET "{usb_clk}" TNM_NET = "GRPusb_clk";
TIMESPEC "TSise_sucks11" = FROM "GRPusb_clk" TO "GRPsys_clk" TIG;
TIMESPEC "TSise_sucks12" = FROM "GRPsys_clk" TO "GRPusb_clk" TIG;
""",
            usb_clk=platform.lookup_request("fx2").ifclk)
Esempio n. 14
0
    def __init__(self, platform,
                 exec_address=0x40400000,
                 main_mem_origin=0x40000000,
                 l2_size=8192):
        self._reset = CSRStorage(reset=1)

        # # #

        self._wb_slaves = []

        # CPU core
        self.clock_domains.cd_sys_kernel = ClockDomain()
        self.comb += [
            self.cd_sys_kernel.clk.eq(ClockSignal()),
            self.cd_sys_kernel.rst.eq(self._reset.storage)
        ]
        self.submodules.cpu = RenameClockDomains(
            mor1kx.MOR1KX(platform, exec_address),
            "sys_kernel")

        # DRAM access
        self.wb_sdram = wishbone.Interface()
        self.add_wb_slave(mem_decoder(main_mem_origin), self.wb_sdram)
Esempio n. 15
0
    def __init__(self,
                 platform,
                 exec_address=0x40400000,
                 main_mem_origin=0x40000000,
                 l2_size=8192):
        self._reset = CSRStorage(reset=1)

        # # #

        self._wb_slaves = []

        # CPU core
        self.clock_domains.cd_sys_kernel = ClockDomain()
        self.comb += [
            self.cd_sys_kernel.clk.eq(ClockSignal()),
            self.cd_sys_kernel.rst.eq(self._reset.storage)
        ]
        self.submodules.cpu = RenameClockDomains(
            mor1kx.MOR1KX(platform, exec_address), "sys_kernel")

        # DRAM access
        self.wb_sdram = wishbone.Interface()
        self.add_wb_slave(mem_decoder(main_mem_origin), self.wb_sdram)
Esempio n. 16
0
    def __init__(self, platform, cpu_type="or1k", **kwargs):
        BaseSoC.__init__(self, platform,
                         cpu_type=cpu_type,
                         sdram_controller_settings=MiniconSettings(l2_size=64*1024),
                         with_timer=False, **kwargs)
        AMPSoC.__init__(self)
        platform.toolchain.ise_commands += """
trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf
"""
        platform.add_extension(nist_qc1.papilio_adapter_io)

        self.submodules.leds = gpio.GPIOOut(Cat(
            platform.request("user_led", 0),
            platform.request("user_led", 1),
            platform.request("user_led", 2),
            platform.request("user_led", 3),
        ))

        self.comb += [
            platform.request("ttl_l_tx_en").eq(1),
            platform.request("ttl_h_tx_en").eq(1)
        ]

        self.submodules.rtio_crg = _RTIOCRG(platform, self.clk_freq)

        # RTIO channels
        rtio_channels = []
        # pmt1 can run on a 8x serdes if pmt0 is not used
        for i in range(2):
            phy = ttl_serdes_spartan6.Inout_4X(platform.request("pmt", i),
                                               self.rtio_crg.rtiox4_stb)
            self.submodules += phy
            rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=512,
                                                       ofifo_depth=4))

        # ttl2 can run on a 8x serdes if xtrig is not used
        for i in range(15):
            if i in (0, 1):
                phy = ttl_serdes_spartan6.Output_4X(platform.request("ttl", i),
                                                    self.rtio_crg.rtiox4_stb)
            elif i in (2,):
                phy = ttl_serdes_spartan6.Output_8X(platform.request("ttl", i),
                                                    self.rtio_crg.rtiox8_stb)
            else:
                phy = ttl_simple.Output(platform.request("ttl", i))

            self.submodules += phy
            rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=256))

        phy = ttl_simple.Output(platform.request("ext_led", 0))
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))

        phy = ttl_simple.Output(platform.request("user_led", 4))
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))

        self.add_constant("RTIO_REGULAR_TTL_COUNT", len(rtio_channels))

        phy = ttl_simple.ClockGen(platform.request("ttl", 15))
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy))

        self.add_constant("RTIO_DDS_CHANNEL", len(rtio_channels))
        self.add_constant("DDS_CHANNEL_COUNT", 8)
        self.add_constant("DDS_AD9858")
        dds_pins = platform.request("dds")
        self.comb += dds_pins.p.eq(0)
        phy = dds.AD9858(dds_pins, 8)
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy,
                                                   ofifo_depth=512,
                                                   ififo_depth=4))

        # RTIO core
        self.submodules.rtio = rtio.RTIO(rtio_channels)
        self.add_constant("RTIO_FINE_TS_WIDTH", self.rtio.fine_ts_width)
        self.add_constant("DDS_RTIO_CLK_RATIO", 8 >> self.rtio.fine_ts_width)
        self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)

        # CPU connections
        rtio_csrs = self.rtio.get_csrs()
        self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
        self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
                                     self.rtiowb.bus)
        self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
                            rtio_csrs)
Esempio n. 17
0
    def __init__(self, platform, cpu_type="or1k", **kwargs):
        BaseSoC.__init__(self,
                         platform,
                         cpu_type=cpu_type,
                         sdram_controller_settings=MiniconSettings(l2_size=64 *
                                                                   1024),
                         with_timer=False,
                         **kwargs)
        AMPSoC.__init__(self)
        platform.toolchain.ise_commands += """
trce -v 12 -fastpaths -tsi {build_name}.tsi -o {build_name}.twr {build_name}.ncd {build_name}.pcf
"""
        platform.add_extension(nist_qc1.papilio_adapter_io)

        self.submodules.leds = gpio.GPIOOut(
            Cat(
                platform.request("user_led", 0),
                platform.request("user_led", 1),
                platform.request("user_led", 2),
                platform.request("user_led", 3),
            ))

        self.comb += [
            platform.request("ttl_l_tx_en").eq(1),
            platform.request("ttl_h_tx_en").eq(1)
        ]

        self.submodules.rtio_crg = _RTIOCRG(platform, self.clk_freq)

        # RTIO channels
        rtio_channels = []
        # pmt1 can run on a 8x serdes if pmt0 is not used
        for i in range(2):
            phy = ttl_serdes_spartan6.Inout_4X(platform.request("pmt", i),
                                               self.rtio_crg.rtiox4_stb)
            self.submodules += phy
            rtio_channels.append(
                rtio.Channel.from_phy(phy, ififo_depth=512, ofifo_depth=4))

        # ttl2 can run on a 8x serdes if xtrig is not used
        for i in range(15):
            if i in (0, 1):
                phy = ttl_serdes_spartan6.Output_4X(platform.request("ttl", i),
                                                    self.rtio_crg.rtiox4_stb)
            elif i in (2, ):
                phy = ttl_serdes_spartan6.Output_8X(platform.request("ttl", i),
                                                    self.rtio_crg.rtiox8_stb)
            else:
                phy = ttl_simple.Output(platform.request("ttl", i))

            self.submodules += phy
            rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=256))

        phy = ttl_simple.Output(platform.request("ext_led", 0))
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))

        phy = ttl_simple.Output(platform.request("user_led", 4))
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy, ofifo_depth=4))

        self.add_constant("RTIO_REGULAR_TTL_COUNT", len(rtio_channels))

        phy = ttl_simple.ClockGen(platform.request("ttl", 15))
        self.submodules += phy
        rtio_channels.append(rtio.Channel.from_phy(phy))

        self.add_constant("RTIO_DDS_CHANNEL", len(rtio_channels))
        self.add_constant("DDS_CHANNEL_COUNT", 8)
        self.add_constant("DDS_AD9858")
        dds_pins = platform.request("dds")
        self.comb += dds_pins.p.eq(0)
        phy = dds.AD9858(dds_pins, 8)
        self.submodules += phy
        rtio_channels.append(
            rtio.Channel.from_phy(phy, ofifo_depth=512, ififo_depth=4))

        # RTIO core
        self.submodules.rtio = rtio.RTIO(rtio_channels)
        self.add_constant("RTIO_FINE_TS_WIDTH", self.rtio.fine_ts_width)
        self.add_constant("DDS_RTIO_CLK_RATIO", 8 >> self.rtio.fine_ts_width)
        self.submodules.rtio_moninj = rtio.MonInj(rtio_channels)

        # CPU connections
        rtio_csrs = self.rtio.get_csrs()
        self.submodules.rtiowb = wbgen.Bank(rtio_csrs)
        self.kernel_cpu.add_wb_slave(mem_decoder(self.mem_map["rtio"]),
                                     self.rtiowb.bus)
        self.add_csr_region("rtio", self.mem_map["rtio"] | 0x80000000, 32,
                            rtio_csrs)