Exemple #1
0
    def add_sdcard(self):
        sdcard_pads = self.platform.request("sdcard")
        if hasattr(sdcard_pads, "rst"):
            self.comb += sdcard_pads.rst.eq(0)
        self.submodules.sdclk = SDClockerS7(sys_clk_freq=self.sys_clk_freq)
        self.submodules.sdphy = SDPHY(sdcard_pads, self.platform.device)
        self.submodules.sdcore = SDCore(self.sdphy)
        self.submodules.sdtimer = Timer()
        self.add_csr("sdclk")
        self.add_csr("sdphy")
        self.add_csr("sdcore")
        self.add_csr("sdtimer")

        self.submodules.bist_generator = BISTBlockGenerator(random=True)
        self.submodules.bist_checker = BISTBlockChecker(random=True)
        self.add_csr("bist_generator")
        self.add_csr("bist_checker")
        self.comb += [
            self.sdcore.source.connect(self.bist_checker.sink),
            self.bist_generator.source.connect(self.sdcore.sink)
        ]
        self.platform.add_period_constraint(self.sdclk.cd_sd.clk,
                                            period_ns(self.sys_clk_freq))
        self.platform.add_period_constraint(self.sdclk.cd_sd_fb.clk,
                                            period_ns(self.sys_clk_freq))
        self.platform.add_false_path_constraints(self.crg.cd_sys.clk,
                                                 self.sdclk.cd_sd.clk,
                                                 self.sdclk.cd_sd_fb.clk)
Exemple #2
0
    def __init__(self):
        platform = trellisboard.Platform()

        # BenchPHY ---------------------------------------------------------------------------------
        BaseSoC.__init__(self,
                         sys_clk_freq=int(100e6),
                         cpu_type=None,
                         integrated_main_ram_size=0x100)

        # SDCard on PMODA with Digilent's Pmod TPH2 +  Pmod MicroSD --------------------------------
        _sdcard_pmod_ios = [(
            "sdcard_pmoda",
            0,
            Subsignal("clk", Pins("pmoda:3")),
            Subsignal("cmd", Pins("pmoda:1"), Misc("PULLMODE=UP")),
            Subsignal("data", Pins("pmoda:2 pmoda:4 pmoda:5 pmoda:0"),
                      Misc("PULLMODE=UP")),
            Misc("SLEWRATE=FAST"),
            IOStandard("LVCMOS33"),
        )]
        self.platform.add_extension(_sdcard_pmod_ios)
        from litesdcard.phy import SDPHY
        self.submodules.sd_phy = SDPHY(self.platform.request("sdcard_pmoda"),
                                       platform.device, self.clk_freq)
        self.add_csr("sd_phy")

        # Send a command with button to verify timings ---------------------------------------------
        self.comb += [
            If(
                self.platform.request("user_btn", 3),
                self.sd_phy.cmdw.sink.valid.eq(1),
                self.sd_phy.cmdw.sink.data.eq(0x5a),
            )
        ]
Exemple #3
0
    def __init__(self, platform):
        self.submodules.crg = _CRG(platform, int(50e6))

        # SRAM
        self.submodules.sram = wishbone.SRAM(1024)

        # SD Emulator
        sdcard_pads = _sdemulator_pads()
        self.submodules.sdemulator = ClockDomainsRenamer("sd")(
            SDEmulator(platform, sdcard_pads))

        # SD Core
        self.submodules.sdphy = SDPHY(sdcard_pads, platform.device)
        self.submodules.sdcore = SDCore(self.sdphy)

        self.submodules.bist_generator = BISTBlockGenerator(random=False)
        self.submodules.bist_checker = BISTBlockChecker(random=False)

        self.comb += [
            self.sdcore.source.connect(self.bist_checker.sink),
            self.bist_generator.source.connect(self.sdcore.sink)
        ]

        # Wishbone
        self.bus = wishbone.Interface()
        wb_masters = [
            self.bus
        ]
        wb_slaves = [
            (mem_decoder(sram_base), self.sram.bus),
            (mem_decoder(sdemulator_base), self.sdemulator.bus)
        ]
        self.submodules.wb_decoder = wishbone.InterconnectShared(wb_masters, wb_slaves, register=True)

        # Tester
        self.submodules.sdtester = SDTester(self.sdcore, self.sdemulator, self.bist_generator, self.bist_checker, self.bus)
Exemple #4
0
    def __init__(self, **kwargs):
        platform = arty.Platform()

        # BenchPHY ---------------------------------------------------------------------------------
        BaseSoC.__init__(self,
                         sys_clk_freq=int(100e6),
                         cpu_type=None,
                         integrated_main_ram_size=0x100)

        # SDCard on PMODD with Digilent's Pmod MicroSD ---------------------------------------------
        self.platform.add_extension(arty._sdcard_pmod_io)
        from litesdcard.phy import SDPHY
        self.submodules.sd_phy = SDPHY(self.platform.request("sdcard"),
                                       platform.device, self.clk_freq)
        self.add_csr("sd_phy")

        # Send a command with button to verify timings ---------------------------------------------
        self.comb += [
            If(
                self.platform.request("user_btn", 0),
                self.sd_phy.cmdw.sink.valid.eq(1),
                self.sd_phy.cmdw.sink.data.eq(0x5a),
            )
        ]
    def __init__(self, with_cpu, with_emulator, with_analyzer):
        platform = minispartan6.Platform(device="xc6slx25")
        platform.add_extension(_sd_io)
        clk_freq = int(50e6)
        sd_freq = int(140e6)
        SoCCore.__init__(self,
                         platform,
                         clk_freq=clk_freq,
                         cpu_type="lm32" if with_cpu else None,
                         csr_data_width=32,
                         with_uart=with_cpu,
                         with_timer=with_cpu,
                         ident="SDCard Test SoC",
                         ident_version=True,
                         integrated_rom_size=0x8000 if with_cpu else 0,
                         integrated_main_ram_size=0x8000 if with_cpu else 0)

        self.submodules.crg = _CRG(platform, clk_freq)

        # bridge
        if not with_cpu:
            self.add_cpu_or_bridge(
                UARTWishboneBridge(platform.request("serial"),
                                   clk_freq,
                                   baudrate=115200))
            self.add_wb_master(self.cpu_or_bridge.wishbone)

        # emulator
        if with_emulator:
            sdcard_pads = _sdemulator_pads()
            self.submodules.sdemulator = SDEmulator(platform, sdcard_pads)
        else:
            sdcard_pads = platform.request('sdcard')

        # sd
        self.submodules.sdclk = SDClockerS6()
        self.submodules.sdphy = SDPHY(sdcard_pads, platform.device)
        self.submodules.sdcore = SDCore(self.sdphy)
        self.submodules.sdtimer = Timer()

        self.submodules.bist_generator = BISTBlockGenerator(random=True)
        self.submodules.bist_checker = BISTBlockChecker(random=True)

        self.comb += [
            self.sdcore.source.connect(self.bist_checker.sink),
            self.bist_generator.source.connect(self.sdcore.sink)
        ]

        self.platform.add_period_constraint(self.crg.cd_sys.clk,
                                            1e9 / clk_freq)
        self.platform.add_period_constraint(self.sdclk.cd_sd.clk,
                                            1e9 / sd_freq)

        self.crg.cd_sys.clk.attr.add("keep")
        self.sdclk.cd_sd.clk.attr.add("keep")
        self.platform.add_false_path_constraints(self.crg.cd_sys.clk,
                                                 self.sdclk.cd_sd.clk)

        # led
        led_counter = Signal(32)
        self.sync.sd += led_counter.eq(led_counter + 1)
        self.comb += platform.request("user_led", 0).eq(led_counter[26])

        # analyzer
        if with_analyzer:
            analyzer_signals = [
                self.sdphy.sdpads, self.sdphy.cmdw.sink, self.sdphy.cmdr.sink,
                self.sdphy.cmdr.source, self.sdphy.dataw.sink,
                self.sdphy.datar.sink, self.sdphy.datar.source
            ]
            self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals,
                                                         2048,
                                                         cd="sd",
                                                         cd_ratio=4)
Exemple #6
0
    def __init__(self, platform,
        with_sdram=True,
        with_ethernet=False,
        with_etherbone=True,
        with_sdcard=True,
        with_pcie=False,
        with_hdmi_in0=False, with_hdmi_out0=False,
        with_hdmi_in1=False, with_hdmi_out1=False,
        with_interboard_communication=False):
        assert not (with_pcie and with_interboard_communication)
        sys_clk_freq = int(100e6)
        sd_freq = int(100e6)
        SoCSDRAM.__init__(self, platform, sys_clk_freq,
            #cpu_type="vexriscv", l2_size=32,
            cpu_type=None, l2_size=32,
            #csr_data_width=8, csr_address_width=14,
            csr_data_width=32, csr_address_width=14,
            integrated_rom_size=0x8000,
            integrated_sram_size=0x4000,
            integrated_main_ram_size=0x8000 if not with_sdram else 0,
            ident="NeTV2 LiteX Test SoC", ident_version=True,
            reserve_nmi_interrupt=False)

        # crg
        self.submodules.crg = CRG(platform, sys_clk_freq)

        # dnax
        self.submodules.dna = dna.DNA()

        # xadc
        self.submodules.xadc = xadc.XADC()

        # icap
        self.submodules.icap = ICAP(platform)

        # flash
        self.submodules.flash = Flash(platform.request("flash"), div=math.ceil(sys_clk_freq/25e6))

        # sdram
        if with_sdram:
            self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram"),
                sys_clk_freq=sys_clk_freq, iodelay_clk_freq=200e6)
            sdram_module = MT41J128M16(sys_clk_freq, "1:4")
            self.register_sdram(self.ddrphy,
                                sdram_module.geom_settings,
                                sdram_module.timing_settings,
                                controller_settings=ControllerSettings(with_bandwidth=True,
                                                                       cmd_buffer_depth=8,
                                                                       with_refresh=True))
        # ethernet
        if with_ethernet:
            self.submodules.ethphy = LiteEthPHYRMII(self.platform.request("eth_clocks"),
                                                    self.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.crg.cd_eth.clk.attr.add("keep")
            self.platform.add_false_path_constraints(
                self.crg.cd_sys.clk,
                self.crg.cd_eth.clk)

        # etherbone
        if with_etherbone:
            self.submodules.ethphy = LiteEthPHYRMII(self.platform.request("eth_clocks"), self.platform.request("eth"))
            self.submodules.ethcore = LiteEthUDPIPCore(self.ethphy, 0x10e2d5000000, convert_ip("192.168.1.50"), sys_clk_freq)
            self.add_cpu(LiteEthEtherbone(self.ethcore.udp, 1234, mode="master"))
            self.add_wb_master(self.cpu.wishbone.bus)
            #self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, 1234, mode="master")
            #self.add_wb_master(self.etherbone.wishbone.bus)

            self.crg.cd_eth.clk.attr.add("keep")
            self.platform.add_false_path_constraints(
                self.crg.cd_sys.clk,
                self.crg.cd_eth.clk)

        # sdcard
        self.submodules.sdclk = SDClockerS7()
        self.submodules.sdphy = SDPHY(platform.request("sdcard"), platform.device)
        self.submodules.sdcore = SDCore(self.sdphy)
        self.submodules.sdtimer = Timer()

        self.submodules.bist_generator = BISTBlockGenerator(random=True)
        self.submodules.bist_checker = BISTBlockChecker(random=True)

        self.comb += [
            self.sdcore.source.connect(self.bist_checker.sink),
            self.bist_generator.source.connect(self.sdcore.sink)
        ]

        self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq)
        self.platform.add_period_constraint(self.sdclk.cd_sd.clk, 1e9/sd_freq)
        self.platform.add_period_constraint(self.sdclk.cd_sd_fb.clk, 1e9/sd_freq)

        self.crg.cd_sys.clk.attr.add("keep")
        self.sdclk.cd_sd.clk.attr.add("keep")
        self.sdclk.cd_sd_fb.clk.attr.add("keep")
        self.platform.add_false_path_constraints(
            self.crg.cd_sys.clk,
            self.sdclk.cd_sd.clk,
            self.sdclk.cd_sd_fb.clk)

        # pcie
        if with_pcie:
            # pcie phy
            self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x2"))
            platform.add_false_path_constraints(
                self.crg.cd_sys.clk,
                self.pcie_phy.cd_pcie.clk)

            # pcie endpoint
            self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy, with_reordering=True)

            # pcie wishbone bridge
            self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint, lambda a: 1, shadow_base=0x80000000)
            self.add_wb_master(self.pcie_bridge.wishbone)

            # pcie dma
            self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True)

            # pcie msi
            self.submodules.pcie_msi = LitePCIeMSI()
            self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi)
            self.interrupts = {
                "PCIE_DMA0_WRITER":    self.pcie_dma0.writer.irq,
                "PCIE_DMA0_READER":    self.pcie_dma0.reader.irq
            }
            for i, (k, v) in enumerate(sorted(self.interrupts.items())):
                self.comb += self.pcie_msi.irqs[i].eq(v)
                self.add_constant(k + "_INTERRUPT", i)

        # interboard communication
        if with_interboard_communication:
            self.clock_domains.cd_refclk = ClockDomain()
            self.submodules.refclk_pll = refclk_pll = S7PLL()
            refclk_pll.register_clkin(platform.lookup_request("clk50"), 50e6)
            refclk_pll.create_clkout(self.cd_refclk, 125e6)

            platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-49]")

            # qpll
            qpll = GTPQuadPLL(ClockSignal("refclk"), 125e6, 1.25e9)
            print(qpll)
            self.submodules += qpll

            # gtp
            gtp = GTP(qpll,
                platform.request("interboard_comm_tx"),
                platform.request("interboard_comm_rx"),
                sys_clk_freq,
                clock_aligner=True, internal_loopback=False)
            self.submodules += gtp

            counter = Signal(32)
            self.sync.tx += counter.eq(counter + 1)

            # send counter to other-board
            self.comb += [
                gtp.encoder.k[0].eq(1),
                gtp.encoder.d[0].eq((5 << 5) | 28),
                gtp.encoder.k[1].eq(0),
                gtp.encoder.d[1].eq(counter[26:])
            ]

            # receive counter and display it on leds
            self.comb += [
                platform.request("user_led", 3).eq(gtp.rx_ready),
                platform.request("user_led", 4).eq(gtp.decoders[1].d[0]),
                platform.request("user_led", 5).eq(gtp.decoders[1].d[1])
            ]

            gtp.cd_tx.clk.attr.add("keep")
            gtp.cd_rx.clk.attr.add("keep")
            platform.add_period_constraint(gtp.cd_tx.clk, 1e9/gtp.tx_clk_freq)
            platform.add_period_constraint(gtp.cd_rx.clk, 1e9/gtp.tx_clk_freq)
            self.platform.add_false_path_constraints(
                self.crg.cd_sys.clk,
                gtp.cd_tx.clk,
                gtp.cd_rx.clk)

        # hdmi in 0
        if with_hdmi_in0:
            hdmi_in0_pads = platform.request("hdmi_in", 0)
            self.submodules.hdmi_in0_freq = FreqMeter(period=sys_clk_freq)
            self.submodules.hdmi_in0 = HDMIIn(
                hdmi_in0_pads,
                self.sdram.crossbar.get_port(mode="write"),
                fifo_depth=512,
                device="xc7",
                split_mmcm=True)
            self.comb += self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk),
            for clk in [self.hdmi_in0.clocking.cd_pix.clk,
                        self.hdmi_in0.clocking.cd_pix1p25x.clk,
                        self.hdmi_in0.clocking.cd_pix5x.clk]:
                self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk)
            self.platform.add_period_constraint(platform.lookup_request("hdmi_in", 0).clk_p, period_ns(148.5e6))

        # hdmi out 0
        if with_hdmi_out0:
            hdmi_out0_dram_port = self.sdram.crossbar.get_port(mode="read", dw=16, cd="hdmi_out0_pix", reverse=True)
            self.submodules.hdmi_out0 = VideoOut(
                platform.device,
                platform.request("hdmi_out", 0),
                hdmi_out0_dram_port,
                "ycbcr422",
                fifo_depth=4096)
            for clk in [self.hdmi_out0.driver.clocking.cd_pix.clk,
                        self.hdmi_out0.driver.clocking.cd_pix5x.clk]:
                self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk)

        # hdmi in 1
        if with_hdmi_in1:
            hdmi_in1_pads = platform.request("hdmi_in", 1)
            self.submodules.hdmi_in1_freq = FreqMeter(period=sys_clk_freq)
            self.submodules.hdmi_in1 = HDMIIn(
                hdmi_in1_pads,
                self.sdram.crossbar.get_port(mode="write"),
                fifo_depth=512,
                device="xc7",
                split_mmcm=True)
            self.comb += self.hdmi_in1_freq.clk.eq(self.hdmi_in1.clocking.cd_pix.clk),
            for clk in [self.hdmi_in1.clocking.cd_pix.clk,
                        self.hdmi_in1.clocking.cd_pix1p25x.clk,
                        self.hdmi_in1.clocking.cd_pix5x.clk]:
                self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk)
            self.platform.add_period_constraint(platform.lookup_request("hdmi_in", 1).clk_p, period_ns(148.5e6))

        # hdmi out 1
        if with_hdmi_out1:
            hdmi_out1_dram_port = self.sdram.crossbar.get_port(mode="read", dw=16, cd="hdmi_out1_pix", reverse=True)
            self.submodules.hdmi_out1 = VideoOut(
                platform.device,
                platform.request("hdmi_out", 1),
                hdmi_out1_dram_port,
                "ycbcr422",
                fifo_depth=4096)
            for clk in [self.hdmi_out1.driver.clocking.cd_pix.clk,
                        self.hdmi_out1.driver.clocking.cd_pix5x.clk]:
                self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk)

        # led blinking (sys)
        sys_counter = Signal(32)
        self.sync.sys += sys_counter.eq(sys_counter + 1)
        self.comb += platform.request("user_led", 0).eq(sys_counter[26])


        # led blinking (pcie)
        if with_pcie:
            pcie_counter = Signal(32)
            self.sync.pcie += pcie_counter.eq(pcie_counter + 1)
            self.comb += platform.request("user_led", 1).eq(pcie_counter[26])

        # led blinking (sdcard)
        if with_sdcard:
            sd_counter = Signal(32)
            self.sync.sd += sd_counter.eq(sd_counter + 1)
            self.comb += platform.request("user_led", 1).eq(sd_counter[26])
Exemple #7
0
    def __init__(self, with_cpu, with_emulator, with_analyzer):
        platform = nexys4ddr.Platform()
        sys_clk_freq = int(100e6)
        sd_clk_freq = int(100e6)

        # SoCCore ----------------------------------------------------------------------------------
        SoCCore.__init__(self,
                         platform,
                         clk_freq=sys_clk_freq,
                         cpu_type="vexriscv" if with_cpu else None,
                         csr_data_width=32,
                         with_uart=with_cpu,
                         with_timer=with_cpu,
                         ident="SDCard Test SoC",
                         ident_version=True,
                         integrated_rom_size=0x8000 if with_cpu else 0,
                         integrated_main_ram_size=0x8000 if with_cpu else 0)

        # CRG --------------------------------------------------------------------------------------
        self.submodules.crg = _CRG(platform, sys_clk_freq)

        # Serial bridge (optional) -----------------------------------------------------------------
        if not with_cpu:
            self.submodules.bridge = UARTWishboneBridge(
                platform.request("serial"), sys_clk_freq)
            self.add_wb_master(self.bridge.wishbone)

        # SDCard Emulator (optional) ---------------------------------------------------------------
        if with_emulator:
            from litesdcard.emulator import SDEmulator, _sdemulator_pads
            sdcard_pads = _sdemulator_pads()
            self.submodules.sdemulator = SDEmulator(platform, sdcard_pads)
            self.add_csr("sdemulator")
        else:
            sdcard_pads = platform.request('sdcard')

        # SDCard -----------------------------------------------------------------------------------
        self.comb += sdcard_pads.rst.eq(0)
        self.submodules.sdclk = SDClockerS7()
        self.submodules.sdphy = SDPHY(sdcard_pads, platform.device)
        self.submodules.sdcore = SDCore(self.sdphy)
        self.submodules.sdtimer = Timer()
        self.add_csr("sdclk")
        self.add_csr("sdphy")
        self.add_csr("sdcore")
        self.add_csr("sdtimer")

        self.submodules.bist_generator = BISTBlockGenerator(random=True)
        self.submodules.bist_checker = BISTBlockChecker(random=True)
        self.add_csr("bist_generator")
        self.add_csr("bist_checker")
        self.comb += [
            self.sdcore.source.connect(self.bist_checker.sink),
            self.bist_generator.source.connect(self.sdcore.sink)
        ]
        self.platform.add_period_constraint(self.sdclk.cd_sd.clk,
                                            1e9 / sd_clk_freq)
        self.platform.add_period_constraint(self.sdclk.cd_sd_fb.clk,
                                            1e9 / sd_clk_freq)
        self.platform.add_false_path_constraints(self.crg.cd_sys.clk,
                                                 self.sdclk.cd_sd.clk,
                                                 self.sdclk.cd_sd_fb.clk)

        # Led --------------------------------------------------------------------------------------
        led_counter = Signal(32)
        self.sync.sd += led_counter.eq(led_counter + 1)
        self.comb += platform.request("user_led", 0).eq(led_counter[26])

        # Analyzer (optional) ----------------------------------------------------------------------
        if with_analyzer:
            from litescope import LiteScopeAnalyzer
            analyzer_signals = [
                self.sdphy.sdpads, self.sdphy.cmdw.sink, self.sdphy.cmdr.sink,
                self.sdphy.cmdr.source, self.sdphy.dataw.sink,
                self.sdphy.datar.sink, self.sdphy.datar.source
            ]
            self.submodules.analyzer = LiteScopeAnalyzer(
                analyzer_signals,
                2048,
                clock_domain="sd",
                csr_csv="../test/analyzer.csv")
            self.add_csr("analyzer")
Exemple #8
0
        def add_a7_sdcard(self,
                          sd_card_freq,
                          memory_size=512,
                          memory_width=32):
            sdcard_pads = self.platform.request("sdcard")

            self.cd_mmcm_clkout[0].name = "sd"
            self.mmcm.clock_domains.cd_sd_fb = self.cd_sd_fb = ClockDomain()

            self.submodules.sdphy = SDPHY(sdcard_pads, self.platform.device)
            self.add_csr("sdphy")
            self.submodules.sdcore = SDCore(self.sdphy)
            self.add_csr("sdcore")
            self.submodules.sdtimer = Timer()
            self.add_csr("sdtimer")

            # SD Card data reader

            sdread_mem = Memory(memory_width, memory_size // 4)
            sdread_sram = FullMemoryWE()(wishbone.SRAM(sdread_mem,
                                                       read_only=True))
            self.submodules += sdread_sram

            self.add_wb_slave(self.mem_map["sdread"], sdread_sram.bus,
                              memory_size)
            self.add_memory_region("sdread", self.mem_map["sdread"],
                                   memory_size)

            sdread_port = sdread_sram.mem.get_port(write_capable=True)
            self.specials += sdread_port
            self.submodules.sddatareader = SDDataReader(
                port=sdread_port, endianness=self.cpu.endianness)
            self.add_csr("sddatareader")
            self.comb += self.sdcore.source.connect(self.sddatareader.sink),

            # SD Card data writer

            sdwrite_mem = Memory(memory_width, memory_size // 4)
            sdwrite_sram = FullMemoryWE()(wishbone.SRAM(sdwrite_mem,
                                                        read_only=False))
            self.submodules += sdwrite_sram

            self.add_wb_slave(self.mem_map["sdwrite"], sdwrite_sram.bus,
                              memory_size)
            self.add_memory_region("sdwrite", self.mem_map["sdwrite"],
                                   memory_size)

            sdwrite_port = sdwrite_sram.mem.get_port(write_capable=False,
                                                     async_read=True,
                                                     mode=READ_FIRST)
            self.specials += sdwrite_port
            self.submodules.sddatawriter = SDDataWriter(
                port=sdwrite_port, endianness=self.cpu.endianness)
            self.add_csr("sddatawriter")
            self.comb += self.sddatawriter.source.connect(self.sdcore.sink),

            self.platform.add_period_constraint(self.cd_mmcm_clkout[0].clk,
                                                1e9 / sd_card_freq)
            self.cd_mmcm_clkout[0].clk.attr.add("keep")
            self.platform.add_false_path_constraints(
                self.cd_mmcm_clkout[0].clk)