예제 #1
0
class KernelCPU(Module):
    def __init__(self,
                 platform,
                 exec_address=0x45000000,
                 main_mem_origin=0x40000000,
                 l2_size=8192):
        self._reset = CSRStorage(reset=1)

        # # #

        # 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)
        ]
        kasli_v1 = isinstance(
            platform, kasli.Platform) and platform.hw_rev in ("v1.0", "v1.1")
        self.submodules.cpu = ClockDomainsRenamer("sys_kernel")(
            vexriscv.VexRiscv(
                platform,
                exec_address,
                variant="VexRiscv_IMA" if kasli_v1 else "VexRiscv_G"))

        self.cpu_dw = len(self.cpu.dbus.dat_w)
        self._wb_slaves = WishboneSlaveManager(0x80000000, dw=self.cpu_dw)

        # DRAM access
        self.wb_sdram = wishbone.Interface(data_width=self.cpu_dw,
                                           adr_width=32 -
                                           log2_int(self.cpu_dw // 8))
        self.add_wb_slave(main_mem_origin, 0x10000000, self.wb_sdram)

    def get_csrs(self):
        return [self._reset]

    def do_finalize(self):
        self.submodules.wishbonecon = wishbone.InterconnectShared(
            [self.cpu.ibus, self.cpu.dbus],
            self._wb_slaves.get_interconnect_slaves(),
            register=True,
            dw=self.cpu_dw)

    def add_wb_slave(self, origin, length, interface):
        if self.finalized:
            raise FinalizeError
        self._wb_slaves.add(origin, length, interface)
예제 #2
0
class KernelCPU(Module):
    def __init__(self, platform,
                 exec_address=0x40800000,
                 main_mem_origin=0x40000000,
                 l2_size=8192):
        self._reset = CSRStorage(reset=1)

        # # #

        self._wb_slaves = WishboneSlaveManager(0x80000000)

        # 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 = ClockDomainsRenamer("sys_kernel")(
            mor1kx.MOR1KX(
                platform,
                OPTION_RESET_PC=exec_address,
                FEATURE_PERFCOUNTERS="ENABLED",
                OPTION_PERFCOUNTERS_NUM=7))

        # DRAM access
        self.wb_sdram = wishbone.Interface()
        self.add_wb_slave(main_mem_origin, 0x10000000, self.wb_sdram)

    def get_csrs(self):
        return [self._reset]

    def do_finalize(self):
        self.submodules.wishbonecon = wishbone.InterconnectShared(
            [self.cpu.ibus, self.cpu.dbus],
            self._wb_slaves.get_interconnect_slaves(), register=True)

    def add_wb_slave(self, origin, length, interface):
        if self.finalized:
            raise FinalizeError
        self._wb_slaves.add(origin, length, interface)
예제 #3
0
    def __init__(self, platform):
        platform.toolchain.bitstream_commands.extend([
            "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
            "set_property CFGBVS VCCO [current_design]",
            "set_property CONFIG_VOLTAGE 3.3 [current_design]",
            ])

        csr_devices = []

        self.submodules.crg = CRG(platform)
        clk_freq = 125e6

        self.submodules.rtm_identifier = RTMIdentifier()
        csr_devices.append("rtm_identifier")

        # clock mux: 100MHz ext SMA clock to HMC830 input
        self.submodules.clock_mux = gpio.GPIOOut(Cat(
            platform.request("clk_src_ext_sel"),
            platform.request("ref_clk_src_sel"),
            platform.request("dac_clk_src_sel")))
        csr_devices.append("clock_mux")

        # UART loopback
        serial = platform.request("serial")
        self.comb += serial.tx.eq(serial.rx)

        # Allaki: enable RF output, GPIO access to attenuator
        self.comb += [
            platform.request("allaki0_rfsw0").eq(1),
            platform.request("allaki0_rfsw1").eq(1),
            platform.request("allaki1_rfsw0").eq(1),
            platform.request("allaki1_rfsw1").eq(1),
            platform.request("allaki2_rfsw0").eq(1),
            platform.request("allaki2_rfsw1").eq(1),
            platform.request("allaki3_rfsw0").eq(1),
            platform.request("allaki3_rfsw1").eq(1),
        ]
        allaki_atts = [
            platform.request("allaki0_att0"),
            platform.request("allaki0_att1"),
            platform.request("allaki1_att0"),
            platform.request("allaki1_att1"),
            platform.request("allaki2_att0"),
            platform.request("allaki2_att1"),
            platform.request("allaki3_att0"),
            platform.request("allaki3_att1"),
        ]
        allaki_att_gpio = []
        for allaki_att in allaki_atts:
            allaki_att_gpio += [
                allaki_att.le,
                allaki_att.sin,
                allaki_att.clk,
                allaki_att.rst_n,
            ]
        self.submodules.allaki_atts = gpio.GPIOOut(Cat(*allaki_att_gpio))
        csr_devices.append("allaki_atts")

        # HMC clock chip and DAC control
        self.comb += [
            platform.request("ad9154_rst_n").eq(1),
            platform.request("ad9154_txen", 0).eq(0b11),
            platform.request("ad9154_txen", 1).eq(0b11)
        ]

        self.submodules.converter_spi = spi.SPIMaster([
            platform.request("hmc_spi"),
            platform.request("ad9154_spi", 0),
            platform.request("ad9154_spi", 1)])
        csr_devices.append("converter_spi")
        self.comb += platform.request("hmc7043_reset").eq(0)

        # AMC/RTM serwb
        serwb_pll = serwb.phy.SERWBPLL(62.5e6, 625e6, vco_div=1)
        self.submodules += serwb_pll

        serwb_pads = platform.request("amc_rtm_serwb")
        platform.add_period_constraint(serwb_pads.clk_p, 16.)
        serwb_phy_rtm = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="slave")
        self.submodules.serwb_phy_rtm = serwb_phy_rtm
        self.comb += self.crg.reset.eq(serwb_phy_rtm.init.reset)
        csr_devices.append("serwb_phy_rtm")

        serwb_phy_rtm.serdes.cd_serwb_serdes.clk.attr.add("keep")
        serwb_phy_rtm.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
        serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
        platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes.clk, 40*1e9/serwb_pll.linerate),
        platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes_20x.clk, 2*1e9/serwb_pll.linerate),
        platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk, 8*1e9/serwb_pll.linerate)
        platform.add_false_path_constraints(
            self.crg.cd_sys.clk,
            serwb_phy_rtm.serdes.cd_serwb_serdes.clk,
            serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk)

        serwb_core = serwb.core.SERWBCore(serwb_phy_rtm, int(clk_freq), mode="master", with_scrambling=True)
        self.submodules += serwb_core

        # process CSR devices and connect them to serwb
        self.csr_regions = []
        wb_slaves = WishboneSlaveManager(0x10000000)
        for i, name in enumerate(csr_devices):
            origin = i*CSR_RANGE_SIZE
            module = getattr(self, name)
            csrs = module.get_csrs()

            bank = wishbone.CSRBank(csrs)
            self.submodules += bank

            wb_slaves.add(origin, CSR_RANGE_SIZE, bank.bus)
            self.csr_regions.append((name, origin, 32, csrs))

        self.submodules += wishbone.Decoder(serwb_core.etherbone.wishbone.bus,
                                            wb_slaves.get_interconnect_slaves(),
                                            register=True)
예제 #4
0
class SoCCore(Module):
    mem_map = {
        "rom": 0x00000000,
        "sram": 0x10000000,
        "main_ram": 0x40000000,
        "csr": 0x60000000,
    }

    def __init__(self,
                 platform,
                 clk_freq,
                 cpu_type="lm32",
                 cpu_reset_address=0x00000000,
                 integrated_rom_size=0,
                 integrated_sram_size=4096,
                 integrated_main_ram_size=16 * 1024,
                 shadow_base=0x80000000,
                 csr_data_width=8,
                 csr_address_width=14,
                 with_uart=True,
                 uart_baudrate=115200,
                 ident="",
                 with_timer=True):
        self.platform = platform
        self.clk_freq = clk_freq

        self.cpu_type = cpu_type
        if integrated_rom_size:
            cpu_reset_address = 0
        self.cpu_reset_address = cpu_reset_address

        self.integrated_rom_size = integrated_rom_size
        self.integrated_sram_size = integrated_sram_size
        self.integrated_main_ram_size = integrated_main_ram_size

        self.with_uart = with_uart
        self.uart_baudrate = uart_baudrate

        self.shadow_base = shadow_base

        self.csr_data_width = csr_data_width
        self.csr_address_width = csr_address_width

        self._memory_regions = []  # list of (name, origin, length)
        self._csr_regions = [
        ]  # list of (name, origin, busword, csr_list/Memory)
        self._constants = []  # list of (name, value)

        self._wb_masters = []
        self._wb_slaves = WishboneSlaveManager(self.shadow_base)

        self.config = dict()

        self.csr_devices = [
            "uart_phy", "uart", "identifier_mem", "timer0", "tmpu"
        ]
        self._memory_groups = [
        ]  # list of (group_name, (group_member0, group_member1, ...))
        self._csr_groups = [
        ]  # list of (group_name, (group_member0, group_member1, ...))
        self.interrupt_devices = []

        if cpu_type == "lm32":
            self.submodules.cpu = lm32.LM32(platform, self.cpu_reset_address)
        elif cpu_type == "or1k":
            self.submodules.cpu = mor1kx.MOR1KX(
                platform, OPTION_RESET_PC=self.cpu_reset_address)
        else:
            raise ValueError("Unsupported CPU type: {}".format(cpu_type))
        self.submodules.tmpu = tmpu.TMPU(self.cpu.dbus)
        self.add_wb_master(self.cpu.ibus)
        self.add_wb_master(self.tmpu.output_bus)

        if integrated_rom_size:
            self.submodules.rom = wishbone.SRAM(integrated_rom_size,
                                                read_only=True)
            self.register_rom(self.rom.bus, integrated_rom_size)

        if integrated_sram_size:
            self.submodules.sram = wishbone.SRAM(integrated_sram_size)
            self.register_mem("sram", self.mem_map["sram"],
                              integrated_sram_size, self.sram.bus)

        # Main Ram can be used when no external SDRAM is present, and use SDRAM mapping.
        if integrated_main_ram_size:
            self.submodules.main_ram = wishbone.SRAM(integrated_main_ram_size)

        self.submodules.wishbone2csr = wishbone2csr.WB2CSR(
            bus_csr=csr_bus.Interface(csr_data_width, csr_address_width))
        self.register_mem("csr", self.mem_map["csr"], 4 * 2**csr_address_width,
                          self.wishbone2csr.wishbone)

        if with_uart:
            self.submodules.uart_phy = uart.RS232PHY(
                platform.request("serial"), clk_freq, uart_baudrate)
            self.submodules.uart = uart.UART(self.uart_phy)
            self.interrupt_devices.append("uart")

        if ident:
            self.submodules.identifier = identifier.Identifier(ident)
        self.config["CLOCK_FREQUENCY"] = int(clk_freq)
        self.config["SOC_PLATFORM"] = platform.name

        if with_timer:
            self.submodules.timer0 = timer.Timer()
            self.interrupt_devices.append("timer0")

    def initialize_rom(self, data):
        self.rom.mem.init = data

    def add_wb_master(self, wbm):
        if self.finalized:
            raise FinalizeError
        self._wb_masters.append(wbm)

    def add_wb_slave(self, origin, length, interface):
        if self.finalized:
            raise FinalizeError
        self._wb_slaves.add(origin, length, interface)

    # This function simply registers the memory region for firmware purposes
    # (linker script, generated headers)
    def add_memory_region(self, name, origin, length):
        self._memory_regions.append((name, origin, length))

    def add_memory_group(self, group_name, members):
        self._memory_groups.append((group_name, members))

    def register_mem(self, name, origin, length, interface):
        self.add_wb_slave(origin, length, interface)
        self.add_memory_region(name, origin, length)

    def register_rom(self, interface, rom_size=0xa000):
        self.add_wb_slave(self.mem_map["rom"], rom_size, interface)
        assert self.cpu_reset_address < rom_size
        self.add_memory_region("rom", self.cpu_reset_address,
                               rom_size - self.cpu_reset_address)

    def get_memory_regions(self):
        return self._memory_regions

    def get_memory_groups(self):
        return self._memory_groups

    def check_csr_region(self, name, origin):
        for n, o, l, obj in self._csr_regions:
            if n == name or o == origin:
                raise ValueError(
                    "CSR region conflict between {} and {}".format(n, name))

    def add_csr_region(self, name, origin, busword, obj):
        self.check_csr_region(name, origin)
        self._csr_regions.append((name, origin, busword, obj))

    def add_csr_group(self, group_name, members):
        self._csr_groups.append((group_name, members))

    def get_csr_regions(self):
        return self._csr_regions

    def get_csr_groups(self):
        return self._csr_groups

    def get_constants(self):
        r = []
        for nr, name in enumerate(self.interrupt_devices):
            r.append((name.upper() + "_INTERRUPT", nr))
        r += self._constants
        return r

    def get_csr_dev_address(self, name, memory):
        if memory is not None:
            name = name + "_" + memory.name_override
        try:
            return self.csr_devices.index(name)
        except ValueError:
            return None

    def do_finalize(self):
        registered_mems = {regions[0] for regions in self._memory_regions}
        for mem in "rom", "sram":
            if mem not in registered_mems:
                raise FinalizeError(
                    "CPU needs a {} to be registered with register_mem()".
                    format(mem))

        # Wishbone
        self.submodules.wishbonecon = wishbone.InterconnectShared(
            self._wb_masters,
            self._wb_slaves.get_interconnect_slaves(),
            register=True)

        # CSR
        self.submodules.csrbankarray = csr_bus.CSRBankArray(
            self,
            self.get_csr_dev_address,
            data_width=self.csr_data_width,
            address_width=self.csr_address_width)
        self.submodules.csrcon = csr_bus.Interconnect(
            self.wishbone2csr.csr, self.csrbankarray.get_buses())
        for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
            self.add_csr_region(name, (self.mem_map["csr"] + 0x800 * mapaddr)
                                | self.shadow_base, self.csr_data_width, csrs)
        for name, memory, mapaddr, mmap in self.csrbankarray.srams:
            self.add_csr_region(name + "_" + memory.name_override,
                                (self.mem_map["csr"] + 0x800 * mapaddr)
                                | self.shadow_base, self.csr_data_width,
                                memory)
        for name, constant in self.csrbankarray.constants:
            self._constants.append(
                ((name + "_" + constant.name).upper(), constant.value.value))
        for name, value in sorted(self.config.items(), key=itemgetter(0)):
            self._constants.append(("CONFIG_" + name.upper(), value))

        # Interrupts
        for nr, name in enumerate(self.interrupt_devices):
            self.comb += self.cpu.interrupt[nr].eq(getattr(self, name).ev.irq)

    def build(self, *args, **kwargs):
        self.platform.build(self, *args, **kwargs)
예제 #5
0
파일: soc_core.py 프로젝트: m-labs/misoc
class SoCCore(Module):
    mem_map = {
        "rom":      0x00000000,
        "sram":     0x10000000,
        "main_ram": 0x40000000,
        "csr":      0x60000000,
    }
    def __init__(self, platform, clk_freq,
                cpu_type="lm32", cpu_reset_address=0x00000000,
                integrated_rom_size=0,
                integrated_sram_size=4096,
                integrated_main_ram_size=16*1024,
                shadow_base=0x80000000,
                csr_data_width=8, csr_address_width=14,
                with_uart=True, uart_baudrate=115200,
                ident="",
                with_timer=True):
        self.platform = platform
        self.clk_freq = clk_freq

        self.cpu_type = cpu_type
        if integrated_rom_size:
            cpu_reset_address = 0
        self.cpu_reset_address = cpu_reset_address

        self.integrated_rom_size = integrated_rom_size
        self.integrated_sram_size = integrated_sram_size
        self.integrated_main_ram_size = integrated_main_ram_size

        self.with_uart = with_uart
        self.uart_baudrate = uart_baudrate

        self.shadow_base = shadow_base

        self.csr_data_width = csr_data_width
        self.csr_address_width = csr_address_width

        self._memory_regions = []  # list of (name, origin, length)
        self._csr_regions = []  # list of (name, origin, busword, csr_list/Memory)
        self._constants = []  # list of (name, value)

        self._wb_masters = []
        self._wb_slaves = WishboneSlaveManager(self.shadow_base)

        self.config = dict()

        self.csr_devices = [
            "uart_phy",
            "uart",
            "identifier",
            "timer0",
            "tmpu"
        ]
        self._memory_groups = []  # list of (group_name, (group_member0, group_member1, ...))
        self._csr_groups = []  # list of (group_name, (group_member0, group_member1, ...))
        self.interrupt_devices = []

        if cpu_type == "lm32":
            self.submodules.cpu = lm32.LM32(platform, self.cpu_reset_address)
        elif cpu_type == "or1k":
            self.submodules.cpu = mor1kx.MOR1KX(platform,
                    OPTION_RESET_PC=self.cpu_reset_address)
        elif cpu_type == "vexriscv":
            self.submodules.cpu = vexriscv.VexRiscv(platform, self.cpu_reset_address)
        else:
            raise ValueError("Unsupported CPU type: {}".format(cpu_type))
        self.submodules.tmpu = tmpu.TMPU(self.cpu.dbus)
        self.add_wb_master(self.cpu.ibus)
        self.add_wb_master(self.tmpu.output_bus)

        if integrated_rom_size:
            self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True)
            self.register_rom(self.rom.bus, integrated_rom_size)

        if integrated_sram_size:
            self.submodules.sram = wishbone.SRAM(integrated_sram_size)
            self.register_mem("sram", self.mem_map["sram"], integrated_sram_size, self.sram.bus)

        # Main Ram can be used when no external SDRAM is present, and use SDRAM mapping.
        if integrated_main_ram_size:
            self.submodules.main_ram = wishbone.SRAM(integrated_main_ram_size)
            self.register_mem("main_ram", self.mem_map["main_ram"], integrated_main_ram_size, self.main_ram.bus)

        self.submodules.wishbone2csr = wishbone2csr.WB2CSR(
            bus_csr=csr_bus.Interface(csr_data_width, csr_address_width))
        self.register_mem("csr", self.mem_map["csr"], 4*2**csr_address_width, self.wishbone2csr.wishbone)

        if with_uart:
            self.submodules.uart_phy = uart.RS232PHY(platform.request("serial"), clk_freq, uart_baudrate)
            self.submodules.uart = uart.UART(self.uart_phy)
            self.interrupt_devices.append("uart")

        if ident:
            self.submodules.identifier = identifier.Identifier(ident)
        self.config["CLOCK_FREQUENCY"] = int(clk_freq)
        self.config["SOC_PLATFORM"] = platform.name

        if with_timer:
            self.submodules.timer0 = timer.Timer()
            self.interrupt_devices.append("timer0")

    def add_wb_master(self, wbm):
        if self.finalized:
            raise FinalizeError
        self._wb_masters.append(wbm)

    def add_wb_slave(self, origin, length, interface):
        if self.finalized:
            raise FinalizeError
        self._wb_slaves.add(origin, length, interface)

    # This function simply registers the memory region for firmware purposes
    # (linker script, generated headers)
    def add_memory_region(self, name, origin, length):
        self._memory_regions.append((name, origin, length))

    def add_memory_group(self, group_name, members):
        self._memory_groups.append((group_name, members))

    def register_mem(self, name, origin, length, interface):
        self.add_wb_slave(origin, length, interface)
        self.add_memory_region(name, origin, length)

    def register_rom(self, interface, rom_size=0xa000):
        self.add_wb_slave(self.mem_map["rom"], rom_size, interface)
        assert self.cpu_reset_address < rom_size
        self.add_memory_region("rom", self.cpu_reset_address,
                               rom_size-self.cpu_reset_address)

    def get_memory_regions(self):
        return self._memory_regions

    def get_memory_groups(self):
        return self._memory_groups

    def check_csr_region(self, name, origin):
        for n, o, l, obj in self._csr_regions:
            if n == name or o == origin:
                raise ValueError("CSR region conflict between {} and {}".format(n, name))

    def add_csr_region(self, name, origin, busword, obj):
        self.check_csr_region(name, origin)
        self._csr_regions.append((name, origin, busword, obj))

    def add_csr_group(self, group_name, members):
        self._csr_groups.append((group_name, members))

    def get_csr_regions(self):
        return self._csr_regions

    def get_csr_groups(self):
        return self._csr_groups

    def get_constants(self):
        r = []
        for nr, name in enumerate(self.interrupt_devices):
            r.append((name.upper() + "_INTERRUPT", nr))
        r += self._constants
        return r

    def get_csr_dev_address(self, name, memory):
        if memory is not None:
            name = name + "_" + memory.name_override
        try:
            return self.csr_devices.index(name)
        except ValueError:
            return None

    def do_finalize(self):
        registered_mems = {regions[0] for regions in self._memory_regions}

        # Wishbone
        self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters,
            self._wb_slaves.get_interconnect_slaves(), register=True)

        # CSR
        self.submodules.csrbankarray = csr_bus.CSRBankArray(self,
            self.get_csr_dev_address,
            data_width=self.csr_data_width, address_width=self.csr_address_width)
        self.submodules.csrcon = csr_bus.Interconnect(
            self.wishbone2csr.csr, self.csrbankarray.get_buses())
        for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
            self.add_csr_region(name, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, csrs)
        for name, memory, mapaddr, mmap in self.csrbankarray.srams:
            self.add_csr_region(name + "_" + memory.name_override, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, memory)
        for name, constant in self.csrbankarray.constants:
            self._constants.append(((name + "_" + constant.name).upper(), constant.value.value))
        for name, value in sorted(self.config.items(), key=itemgetter(0)):
            self._constants.append(("CONFIG_" + name.upper(), value))

        # Interrupts
        for nr, name in enumerate(self.interrupt_devices):
            self.comb += self.cpu.interrupt[nr].eq(getattr(self, name).ev.irq)

    def build(self, *args, **kwargs):
        self.platform.build(self, *args, **kwargs)
예제 #6
0
파일: sayma_rtm.py 프로젝트: kaolpr/artiq
    def __init__(self, platform):
        csr_devices = []

        self.submodules.crg = CRG(platform)
        clk_freq = 125e6

        self.submodules.rtm_magic = RTMMagic()
        csr_devices.append("rtm_magic")
        self.submodules.rtm_identifier = identifier.Identifier(artiq_version)
        csr_devices.append("rtm_identifier")

        # clock mux: 100MHz ext SMA clock to HMC830 input
        self.submodules.clock_mux = gpio.GPIOOut(
            Cat(platform.request("clk_src_ext_sel"),
                platform.request("ref_clk_src_sel"),
                platform.request("dac_clk_src_sel")))
        csr_devices.append("clock_mux")

        # UART loopback
        serial = platform.request("serial")
        self.comb += serial.tx.eq(serial.rx)

        # Allaki: enable RF output, GPIO access to attenuator
        self.comb += [
            platform.request("allaki0_rfsw0").eq(1),
            platform.request("allaki0_rfsw1").eq(1),
            platform.request("allaki1_rfsw0").eq(1),
            platform.request("allaki1_rfsw1").eq(1),
            platform.request("allaki2_rfsw0").eq(1),
            platform.request("allaki2_rfsw1").eq(1),
            platform.request("allaki3_rfsw0").eq(1),
            platform.request("allaki3_rfsw1").eq(1),
        ]
        allaki_atts = [
            platform.request("allaki0_att0"),
            platform.request("allaki0_att1"),
            platform.request("allaki1_att0"),
            platform.request("allaki1_att1"),
            platform.request("allaki2_att0"),
            platform.request("allaki2_att1"),
            platform.request("allaki3_att0"),
            platform.request("allaki3_att1"),
        ]
        allaki_att_gpio = []
        for allaki_att in allaki_atts:
            allaki_att_gpio += [
                allaki_att.le,
                allaki_att.sin,
                allaki_att.clk,
                allaki_att.rst_n,
            ]
        self.submodules.allaki_atts = gpio.GPIOOut(Cat(*allaki_att_gpio))
        csr_devices.append("allaki_atts")

        # HMC clock chip and DAC control
        self.comb += [
            platform.request("ad9154_rst_n").eq(1),
            platform.request("ad9154_txen", 0).eq(0b11),
            platform.request("ad9154_txen", 1).eq(0b11)
        ]

        self.submodules.converter_spi = spi2.SPIMaster(
            spi2.SPIInterface(platform.request("hmc_spi"),
                              platform.request("ad9154_spi", 0),
                              platform.request("ad9154_spi", 1)))
        csr_devices.append("converter_spi")
        self.comb += platform.request("hmc7043_reset").eq(0)

        # AMC/RTM serwb
        serwb_pads = platform.request("amc_rtm_serwb")
        platform.add_period_constraint(serwb_pads.clk_p, 8.)
        serwb_phy_rtm = serwb.genphy.SERWBPHY(platform.device,
                                              serwb_pads,
                                              mode="slave")
        self.submodules.serwb_phy_rtm = serwb_phy_rtm
        self.comb += [
            self.crg.serwb_refclk.eq(serwb_phy_rtm.serdes.clocking.refclk),
            self.crg.serwb_reset.eq(serwb_phy_rtm.serdes.reset)
        ]
        csr_devices.append("serwb_phy_rtm")

        serwb_core = serwb.core.SERWBCore(serwb_phy_rtm,
                                          int(clk_freq),
                                          mode="master")
        self.submodules += serwb_core

        # process CSR devices and connect them to serwb
        self.csr_regions = []
        wb_slaves = WishboneSlaveManager(0x10000000)
        for i, name in enumerate(csr_devices):
            origin = i * CSR_RANGE_SIZE
            module = getattr(self, name)
            csrs = module.get_csrs()

            bank = wishbone.CSRBank(csrs)
            self.submodules += bank

            wb_slaves.add(origin, CSR_RANGE_SIZE, bank.bus)
            self.csr_regions.append((name, origin, 32, csrs))

        self.submodules += wishbone.Decoder(
            serwb_core.etherbone.wishbone.bus,
            wb_slaves.get_interconnect_slaves(),
            register=True)
예제 #7
0
class SoCCore(Module):
    mem_map = dict(
        axi=0x40000000,  # m_axi_gp0
        csr=0x80000000,  # m_axi_gp1
    )

    def __init__(self,
                 platform,
                 csr_data_width=8,
                 csr_address_width=14,
                 max_addr=0xc0000000,
                 ident="SoCCore"):
        self.platform = platform
        # self.clk_freq = clk_freq

        self.csr_data_width = csr_data_width
        self.csr_address_width = csr_address_width

        self._memory_regions = []  # seq of (name, origin, length)
        self._csr_regions = [
        ]  # seq of (name, origin, busword, csr_list|Memory)  # noqa
        self._constants = []  # seq of (name, value)

        self._axi_slaves = SlaveManager(max_addr)

        self.csr_devices = [
            "identifier_mem",
        ]
        self.interrupt_devices = []

        self.submodules.ps7 = ps7.PS7(
            SimpleNamespace(
                ps=platform.request("ps"),
                ddr=platform.request("ddr"),
            ))

        self.submodules.axi2csr = axi2csr.AXI2CSR(
            bus_csr=csr_bus.Interface(csr_data_width, csr_address_width),
            bus_axi=axi.Interface.like(self.ps7.m_axi_gp1))

        self.register_mem("csr", self.mem_map["csr"], 4 * 2**csr_address_width,
                          self.axi2csr.bus)

        self.submodules.identifier = identifier.Identifier(ident)

    def add_axi_slave(self, origin, length, interface):
        if self.finalized:
            raise RuntimeError("{} already finalised")
        self._axi_slaves.add(origin, length, interface)

    # This function simply registers the memory region for firmware purposes
    # (linker script, generated headers)
    def add_memory_region(self, name, origin, length):
        self._memory_regions.append((name, origin, length))

    def check_csr_region(self, name, origin):
        for n, o, l, obj in self._csr_regions:
            if n == name or o == origin:
                raise ValueError(
                    "CSR region conflict between {} and {}".format(n, name))

    def add_csr_region(self, name, origin, busword, obj):
        self.check_csr_region(name, origin)
        self._csr_regions.append((name, origin, busword, obj))

    def register_mem(self, name, origin, length, interface):
        self.add_axi_slave(origin, length, interface)
        self.add_memory_region(name, origin, length)

    @property
    def memory_regions(self):
        return self._memory_regions

    @property
    def csr_regions(self):
        return self._csr_regions

    @property
    def constants(self):
        return self._constants

    def get_csr_dev_address(self, name, memory):
        if memory is not None:
            name = "_".join([name, memory.name_override])
        try:
            return self.csr_devices.index(name)
        except ValueError:
            return None

    def do_finalize(self):
        # CSR
        self.submodules.csrbankarray = csr_bus.CSRBankArray(
            self,
            self.get_csr_dev_address,
            data_width=self.csr_data_width,
            address_width=self.csr_address_width)

        self.submodules.csrcon = csr_bus.Interconnect(
            self.axi2csr.csr, self.csrbankarray.get_buses())

        for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
            self.add_csr_region(name, (self.mem_map["csr"] + 0x800 * mapaddr),
                                self.csr_data_width, csrs)
        for name, memory, mapaddr, mmap in self.csrbankarray.srams:
            self.add_csr_region("{}_{}".format(name, memory.name_override),
                                (self.mem_map["csr"] + 0x800 * mapaddr),
                                self.csr_data_width, memory)
        for name, constant in self.csrbankarray.constants:
            self._constants.append(
                (("_".join([name,
                            constant.name]).uppper(), constant.value.value)))

        # Interrupts
        for n, name in enumerate(self.interrupt_devices):
            self.comb += self.ps7.interrupt[n].eq(getattr(self, name).ev.irq)

        # AXI: FIXME: add InterconnectShared support
        slaves = self._axi_slaves.get_interconnect_slaves()
        if len(slaves) > 2:
            raise NotImplementedError("only P2P is supported")
        self.submodules += axi.InterconnectPointToPoint(
            self.ps7.m_axi_gp1, slaves[0][1])
        if len(slaves) == 2:
            self.submodules += axi.InterconnectPointToPoint(
                self.ps7.m_axi_gp0, slaves[1][1])

    def build(self, *args, **kwargs):
        self.platform.build(self, *args, **kwargs)
예제 #8
0
    def __init__(self, platform):
        csr_devices = []

        self.submodules.crg = CRG(platform)

        clk_freq = 125e6

        self.submodules.rtm_magic = RTMMagic()
        csr_devices.append("rtm_magic")
        self.submodules.rtm_identifier = identifier.Identifier(artiq_version)
        csr_devices.append("rtm_identifier")
        self.submodules.rtm_scratch = RTMScratch()
        csr_devices.append("rtm_scratch")

        # clock mux: 100MHz ext SMA clock to HMC830 input
        self.submodules.clock_mux = gpio.GPIOOut(Cat(
            platform.request("clk_src_ext_sel"),
            platform.request("ref_clk_src_sel"),
            platform.request("dac_clk_src_sel"),
            platform.request("ref_lo_clk_sel")),
            reset_out=0b0111)
        csr_devices.append("clock_mux")

        # Allaki: enable RF output, GPIO access to attenuator
        self.comb += [
            platform.request("allaki0_rfsw0").eq(1),
            platform.request("allaki0_rfsw1").eq(1),
            platform.request("allaki1_rfsw0").eq(1),
            platform.request("allaki1_rfsw1").eq(1),
            platform.request("allaki2_rfsw0").eq(1),
            platform.request("allaki2_rfsw1").eq(1),
            platform.request("allaki3_rfsw0").eq(1),
            platform.request("allaki3_rfsw1").eq(1),
        ]
        allaki_atts = [
            platform.request("allaki0_att0"),
            platform.request("allaki0_att1"),
            platform.request("allaki1_att0"),
            platform.request("allaki1_att1"),
            platform.request("allaki2_att0"),
            platform.request("allaki2_att1"),
            platform.request("allaki3_att0"),
            platform.request("allaki3_att1"),
        ]
        allaki_att_gpio = []
        for allaki_att in allaki_atts:
            allaki_att_gpio += [
                allaki_att.le,
                allaki_att.sin,
                allaki_att.clk,
                allaki_att.rst_n,
            ]
        self.submodules.allaki_atts = gpio.GPIOOut(Cat(*allaki_att_gpio))
        csr_devices.append("allaki_atts")

        # HMC clock chip and DAC control
        self.comb += platform.request("ad9154_rst_n").eq(1)
        self.submodules.converter_spi = spi2.SPIMaster(spi2.SPIInterface(
            platform.request("hmc_spi"),
            platform.request("ad9154_spi", 0),
            platform.request("ad9154_spi", 1)))
        csr_devices.append("converter_spi")
        self.submodules.hmc7043_reset = gpio.GPIOOut(
            platform.request("hmc7043_reset"), reset_out=1)
        csr_devices.append("hmc7043_reset")
        self.submodules.hmc7043_gpo = gpio.GPIOIn(
            platform.request("hmc7043_gpo"))
        csr_devices.append("hmc7043_gpo")

        # DDMTD
        self.clock_domains.cd_rtio = ClockDomain(reset_less=True)
        rtio_clock_pads = platform.request("si5324_clkout_fabric")
        self.specials += Instance("IBUFGDS", i_I=rtio_clock_pads.p, i_IB=rtio_clock_pads.n,
            o_O=self.cd_rtio.clk)
        self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(
            platform.request("rtm_master_aux_clk"), 150e6)
        csr_devices.append("sysref_ddmtd")

        # AMC/RTM serwb
        serwb_pads = platform.request("amc_rtm_serwb")
        platform.add_period_constraint(serwb_pads.clk, 8.)
        serwb_phy_rtm = serwb.genphy.SERWBPHY(platform.device, serwb_pads, mode="slave")
        self.submodules.serwb_phy_rtm = serwb_phy_rtm
        self.comb += [
            self.crg.serwb_refclk.eq(serwb_phy_rtm.serdes.clocking.refclk),
            self.crg.serwb_reset.eq(serwb_phy_rtm.serdes.reset)
        ]
        csr_devices.append("serwb_phy_rtm")

        serwb_core = serwb.core.SERWBCore(serwb_phy_rtm, int(clk_freq), mode="master")
        self.submodules += serwb_core

        # process CSR devices and connect them to serwb
        self.csr_regions = []
        wb_slaves = WishboneSlaveManager(0x10000000)
        for i, name in enumerate(csr_devices):
            origin = i*CSR_RANGE_SIZE
            module = getattr(self, name)
            csrs = module.get_csrs()

            bank = wishbone.CSRBank(csrs)
            self.submodules += bank

            wb_slaves.add(origin, CSR_RANGE_SIZE, bank.bus)
            self.csr_regions.append((name, origin, 32, csrs))

        self.submodules += wishbone.Decoder(serwb_core.etherbone.wishbone.bus,
                                            wb_slaves.get_interconnect_slaves(),
                                            register=True)
예제 #9
0
파일: sayma_rtm.py 프로젝트: mntng/artiq
    def __init__(self, platform):
        csr_devices = []

        self.submodules.crg = CRG(platform)
        self.crg.cd_sys.clk.attr.add("keep")
        clk_freq = 125e6
        platform.add_period_constraint(self.crg.cd_sys.clk, 8.0)

        self.submodules.rtm_identifier = RTMIdentifier()
        csr_devices.append("rtm_identifier")

        # clock mux: 125MHz ext SMA clock to HMC830 input
        self.comb += [
            platform.request("clk_src_ext_sel").eq(1), # use ext clk from sma
            platform.request("ref_clk_src_sel").eq(1),
            platform.request("dac_clk_src_sel").eq(0), # use clk from dac_clk
        ]

        self.comb += [
            platform.request("ad9154_rst_n").eq(1),
            platform.request("ad9154_txen", 0).eq(0b11),
            platform.request("ad9154_txen", 1).eq(0b11)
        ]

        self.submodules.converter_spi = spi.SPIMaster([
            platform.request("hmc_spi"),
            platform.request("ad9154_spi", 0),
            platform.request("ad9154_spi", 1)])
        csr_devices.append("converter_spi")
        self.comb += platform.request("hmc7043_reset").eq(0)

        # AMC/RTM serwb
        serwb_pll = serwb.phy.SERWBPLL(125e6, 1.25e9, vco_div=1)
        self.submodules += serwb_pll

        serwb_pads = platform.request("amc_rtm_serwb")
        serwb_phy = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="slave")
        self.submodules.serwb_phy = serwb_phy
        self.comb += self.crg.reset.eq(serwb_phy.init.reset)

        serwb_phy.serdes.cd_serwb_serdes.clk.attr.add("keep")
        serwb_phy.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
        serwb_phy.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
        platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes.clk, 32.0),
        platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes_20x.clk, 1.6),
        platform.add_period_constraint(serwb_phy.serdes.cd_serwb_serdes_5x.clk, 6.4)
        platform.add_false_path_constraints(
            self.crg.cd_sys.clk,
            serwb_phy.serdes.cd_serwb_serdes.clk,
            serwb_phy.serdes.cd_serwb_serdes_5x.clk)

        serwb_core = serwb.core.SERWBCore(serwb_phy, int(clk_freq), mode="master")
        self.submodules += serwb_core

        # process CSR devices and connect them to serwb
        self.csr_regions = []
        wb_slaves = WishboneSlaveManager(0x10000000)
        for i, name in enumerate(csr_devices):
            origin = i*CSR_RANGE_SIZE
            module = getattr(self, name)
            csrs = module.get_csrs()

            bank = wishbone.CSRBank(csrs)
            self.submodules += bank

            wb_slaves.add(origin, CSR_RANGE_SIZE, bank.bus)
            self.csr_regions.append((name, origin, 32, csrs))

        self.submodules += wishbone.Decoder(serwb_core.etherbone.wishbone.bus,
                                            wb_slaves.get_interconnect_slaves(),
                                            register=True)
예제 #10
0
파일: sayma_rtm.py 프로젝트: m-labs/artiq
    def __init__(self, platform, hw_rev):
        csr_devices = []

        self.submodules.crg = CRG(platform)

        clk_freq = 125e6

        self.submodules.rtm_magic = RTMMagic()
        csr_devices.append("rtm_magic")
        self.submodules.rtm_identifier = identifier.Identifier(artiq_version)
        csr_devices.append("rtm_identifier")
        self.submodules.rtm_scratch = RTMScratch()
        csr_devices.append("rtm_scratch")

        if hw_rev == "v1.0":
            # clock mux: 100MHz ext SMA clock to HMC830 input
            self.submodules.clock_mux = gpio.GPIOOut(Cat(
                platform.request("clk_src_ext_sel"),
                platform.request("ref_clk_src_sel"),
                platform.request("dac_clk_src_sel"),
                platform.request("ref_lo_clk_sel")),
                reset_out=0b0111)
            csr_devices.append("clock_mux")
        elif hw_rev == "v2.0":
            # TODO
            self.submodules.clock_mux = gpio.GPIOOut(
                platform.request("clk_src_ext_sel"))
            csr_devices.append("clock_mux")
        else:
            raise NotImplementedError

        if hw_rev == "v1.0":
            # Allaki: enable RF output, GPIO access to attenuator
            self.comb += [
                platform.request("allaki0_rfsw0").eq(1),
                platform.request("allaki0_rfsw1").eq(1),
                platform.request("allaki1_rfsw0").eq(1),
                platform.request("allaki1_rfsw1").eq(1),
                platform.request("allaki2_rfsw0").eq(1),
                platform.request("allaki2_rfsw1").eq(1),
                platform.request("allaki3_rfsw0").eq(1),
                platform.request("allaki3_rfsw1").eq(1),
            ]
            allaki_atts = [
                platform.request("allaki0_att0"),
                platform.request("allaki0_att1"),
                platform.request("allaki1_att0"),
                platform.request("allaki1_att1"),
                platform.request("allaki2_att0"),
                platform.request("allaki2_att1"),
                platform.request("allaki3_att0"),
                platform.request("allaki3_att1"),
            ]
            allaki_att_gpio = []
            for allaki_att in allaki_atts:
                allaki_att_gpio += [
                    allaki_att.le,
                    allaki_att.sin,
                    allaki_att.clk,
                    allaki_att.rst_n,
                ]
            self.submodules.allaki_atts = gpio.GPIOOut(Cat(*allaki_att_gpio))
            csr_devices.append("allaki_atts")

        # HMC clock chip and DAC control
        self.comb += platform.request("ad9154_rst_n").eq(1)
        self.submodules.converter_spi = spi2.SPIMaster(spi2.SPIInterface(
            platform.request("hmc_spi"),
            platform.request("ad9154_spi", 0),
            platform.request("ad9154_spi", 1)))
        csr_devices.append("converter_spi")
        self.submodules.hmc7043_reset = gpio.GPIOOut(
            platform.request("hmc7043_reset"), reset_out=1)
        csr_devices.append("hmc7043_reset")
        self.submodules.hmc7043_gpo = gpio.GPIOIn(
            platform.request("hmc7043_gpo"))
        csr_devices.append("hmc7043_gpo")

        # DDMTD
        self.clock_domains.cd_rtio = ClockDomain(reset_less=True)
        if hw_rev == "v1.0":
            # HACK - Si5324 needs to be put into bypass mode first.
            # See: https://github.com/m-labs/artiq/issues/1260
            rtio_clock_pads = platform.request("si5324_clkout_fabric")
            sysref_pads = platform.request("rtm_master_aux_clk")
        elif hw_rev == "v2.0":
            # https://github.com/sinara-hw/Sayma_RTM/issues/68
            rtio_clock_pads = platform.request("cdr_clk_clean_fabric")
            sysref_pads = platform.request("rtm_fpga_sysref", 1)  # use odd-numbered 7043 output
        else:
            raise NotImplementedError
        self.specials += Instance("IBUFGDS", i_I=rtio_clock_pads.p, i_IB=rtio_clock_pads.n,
            o_O=self.cd_rtio.clk)
        self.submodules.sysref_ddmtd = jesd204_tools.DDMTD(sysref_pads, 150e6)
        csr_devices.append("sysref_ddmtd")

        # AMC/RTM serwb
        serwb_pads = platform.request("amc_rtm_serwb")
        if hw_rev == "v1.0":
            platform.add_period_constraint(serwb_pads.clk, 8.)
        elif hw_rev == "v2.0":
            platform.add_period_constraint(serwb_pads.clk_p, 8.)
        else:
            raise NotImplementedError
        serwb_phy_rtm = serwb.genphy.SERWBPHY(platform.device, serwb_pads, mode="slave")
        self.submodules.serwb_phy_rtm = serwb_phy_rtm
        self.comb += [
            self.crg.serwb_refclk.eq(serwb_phy_rtm.serdes.clocking.refclk),
            self.crg.serwb_reset.eq(serwb_phy_rtm.serdes.reset)
        ]
        csr_devices.append("serwb_phy_rtm")

        serwb_core = serwb.core.SERWBCore(serwb_phy_rtm, int(clk_freq), mode="master")
        self.submodules += serwb_core

        # process CSR devices and connect them to serwb
        self.csr_regions = []
        wb_slaves = WishboneSlaveManager(0x10000000)
        for i, name in enumerate(csr_devices):
            origin = i*CSR_RANGE_SIZE
            module = getattr(self, name)
            csrs = module.get_csrs()

            bank = wishbone.CSRBank(csrs)
            self.submodules += bank

            wb_slaves.add(origin, CSR_RANGE_SIZE, bank.bus)
            self.csr_regions.append((name, origin, 32, csrs))

        self.submodules += wishbone.Decoder(serwb_core.etherbone.wishbone.bus,
                                            wb_slaves.get_interconnect_slaves(),
                                            register=True)
예제 #11
0
    def __init__(self, platform):
        platform.toolchain.bitstream_commands.extend([
            "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
            "set_property CFGBVS VCCO [current_design]",
            "set_property CONFIG_VOLTAGE 3.3 [current_design]",
            ])

        csr_devices = []

        self.submodules.crg = CRG(platform)
        clk_freq = 125e6

        self.submodules.rtm_magic = RTMMagic()
        csr_devices.append("rtm_magic")
        self.submodules.rtm_identifier = identifier.Identifier(artiq_version)
        csr_devices.append("rtm_identifier")

        # clock mux: 100MHz ext SMA clock to HMC830 input
        self.submodules.clock_mux = gpio.GPIOOut(Cat(
            platform.request("clk_src_ext_sel"),
            platform.request("ref_clk_src_sel"),
            platform.request("dac_clk_src_sel")))
        csr_devices.append("clock_mux")

        # UART loopback
        serial = platform.request("serial")
        self.comb += serial.tx.eq(serial.rx)

        # Allaki: enable RF output, GPIO access to attenuator
        self.comb += [
            platform.request("allaki0_rfsw0").eq(1),
            platform.request("allaki0_rfsw1").eq(1),
            platform.request("allaki1_rfsw0").eq(1),
            platform.request("allaki1_rfsw1").eq(1),
            platform.request("allaki2_rfsw0").eq(1),
            platform.request("allaki2_rfsw1").eq(1),
            platform.request("allaki3_rfsw0").eq(1),
            platform.request("allaki3_rfsw1").eq(1),
        ]
        allaki_atts = [
            platform.request("allaki0_att0"),
            platform.request("allaki0_att1"),
            platform.request("allaki1_att0"),
            platform.request("allaki1_att1"),
            platform.request("allaki2_att0"),
            platform.request("allaki2_att1"),
            platform.request("allaki3_att0"),
            platform.request("allaki3_att1"),
        ]
        allaki_att_gpio = []
        for allaki_att in allaki_atts:
            allaki_att_gpio += [
                allaki_att.le,
                allaki_att.sin,
                allaki_att.clk,
                allaki_att.rst_n,
            ]
        self.submodules.allaki_atts = gpio.GPIOOut(Cat(*allaki_att_gpio))
        csr_devices.append("allaki_atts")

        # HMC clock chip and DAC control
        self.comb += [
            platform.request("ad9154_rst_n").eq(1),
            platform.request("ad9154_txen", 0).eq(0b11),
            platform.request("ad9154_txen", 1).eq(0b11)
        ]

        self.submodules.converter_spi = spi2.SPIMaster(spi2.SPIInterface(
            platform.request("hmc_spi"),
            platform.request("ad9154_spi", 0),
            platform.request("ad9154_spi", 1)))
        csr_devices.append("converter_spi")
        self.comb += platform.request("hmc7043_reset").eq(0)

        # AMC/RTM serwb
        serwb_pll = serwb.phy.SERWBPLL(62.5e6, 625e6, vco_div=1)
        self.submodules += serwb_pll

        serwb_pads = platform.request("amc_rtm_serwb")
        platform.add_period_constraint(serwb_pads.clk_p, 16.)
        serwb_phy_rtm = serwb.phy.SERWBPHY(platform.device, serwb_pll, serwb_pads, mode="slave")
        self.submodules.serwb_phy_rtm = serwb_phy_rtm
        self.comb += self.crg.reset.eq(serwb_phy_rtm.init.reset)
        csr_devices.append("serwb_phy_rtm")

        serwb_phy_rtm.serdes.cd_serwb_serdes.clk.attr.add("keep")
        serwb_phy_rtm.serdes.cd_serwb_serdes_20x.clk.attr.add("keep")
        serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk.attr.add("keep")
        platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes.clk, 40*1e9/serwb_pll.linerate),
        platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes_20x.clk, 2*1e9/serwb_pll.linerate),
        platform.add_period_constraint(serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk, 8*1e9/serwb_pll.linerate)
        platform.add_false_path_constraints(
            self.crg.cd_sys.clk,
            serwb_phy_rtm.serdes.cd_serwb_serdes.clk,
            serwb_phy_rtm.serdes.cd_serwb_serdes_5x.clk)

        serwb_core = serwb.core.SERWBCore(serwb_phy_rtm, int(clk_freq), mode="master", with_scrambling=True)
        self.submodules += serwb_core

        # process CSR devices and connect them to serwb
        self.csr_regions = []
        wb_slaves = WishboneSlaveManager(0x10000000)
        for i, name in enumerate(csr_devices):
            origin = i*CSR_RANGE_SIZE
            module = getattr(self, name)
            csrs = module.get_csrs()

            bank = wishbone.CSRBank(csrs)
            self.submodules += bank

            wb_slaves.add(origin, CSR_RANGE_SIZE, bank.bus)
            self.csr_regions.append((name, origin, 32, csrs))

        self.submodules += wishbone.Decoder(serwb_core.etherbone.wishbone.bus,
                                            wb_slaves.get_interconnect_slaves(),
                                            register=True)