diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 45800d2e8..192f7b20c 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1245,9 +1245,7 @@ class LiteXSoC(SoC): self.add_csr(name) # Add SDCard ----------------------------------------------------------------------------------- - def add_sdcard(self, name="sdcard"): - assert self.platform.device[:3] == "xc7" # FIXME: Only supports 7-Series for now. - + def add_sdcard(self, name="sdcard", with_emulator=False): # Imports from litesdcard.phy import SDPHY from litesdcard.clocker import SDClockerS7 @@ -1255,11 +1253,26 @@ class LiteXSoC(SoC): from litesdcard.bist import BISTBlockGenerator, BISTBlockChecker from litesdcard.data import SDDataReader, SDDataWriter + # Emulator + if with_emulator: + from litesdcard.emulator import SDEmulator, _sdemulator_pads + sdcard_pads = _sdemulator_pads() + self.submodules.sdemulator = SDEmulator(self.platform, sdcard_pads) + self.add_csr("sdemulator") + else: + assert self.platform.device[:3] == "xc7" # FIXME: Only supports 7-Series for now. + sdcard_pads = self.platform.request(name) + # Core - sdcard_pads = self.platform.request(name) if hasattr(sdcard_pads, "rst"): self.comb += sdcard_pads.rst.eq(0) - self.submodules.sdclk = SDClockerS7(sys_clk_freq=self.sys_clk_freq) + if with_emulator: + self.clock_domains.cd_sd = ClockDomain("sd") + self.clock_domains.cd_sd_fb = ClockDomain("sd_fb") + self.comb += self.cd_sd.clk.eq(ClockSignal()) + self.comb += self.cd_sd_fb.clk.eq(ClockSignal()) + else: + 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, csr_data_width=self.csr_data_width) self.submodules.sdtimer = Timer() @@ -1293,9 +1306,10 @@ class LiteXSoC(SoC): self.comb += self.sddatawriter.source.connect(self.sdcore.sink), # Timing constraints - self.platform.add_period_constraint(self.sdclk.cd_sd.clk, 1e9/self.sys_clk_freq) - self.platform.add_period_constraint(self.sdclk.cd_sd_fb.clk, 1e9/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) + if not with_emulator: + self.platform.add_period_constraint(self.sdclk.cd_sd.clk, 1e9/self.sys_clk_freq) + self.platform.add_period_constraint(self.sdclk.cd_sd_fb.clk, 1e9/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) diff --git a/litex/tools/litex_sim.py b/litex/tools/litex_sim.py index 23fb6b71f..c1d986633 100755 --- a/litex/tools/litex_sim.py +++ b/litex/tools/litex_sim.py @@ -177,6 +177,7 @@ class SimSoC(SoCCore): sdram_spd_data = None, sdram_verbosity = 0, with_i2c = False, + with_sdcard = False, **kwargs): platform = Platform() sys_clk_freq = int(1e6) @@ -306,6 +307,10 @@ class SimSoC(SoCCore): self.submodules.i2c = I2CMasterSim(pads) self.add_csr("i2c") + # SDCard ----------------------------------------------------------------------------------- + if with_sdcard: + self.add_sdcard("sdcard", with_emulator=True) + # Build -------------------------------------------------------------------------------------------- def main(): @@ -327,6 +332,7 @@ def main(): parser.add_argument("--remote-ip", default="192.168.1.100", help="Remote IP address of TFTP server (default=192.168.1.100)") parser.add_argument("--with-analyzer", action="store_true", help="Enable Analyzer support") parser.add_argument("--with-i2c", action="store_true", help="Enable I2C support") + parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support") parser.add_argument("--trace", action="store_true", help="Enable Tracing") parser.add_argument("--trace-fst", action="store_true", help="Enable FST tracing (default=VCD)") parser.add_argument("--trace-start", default=0, help="Cycle to start tracing") @@ -376,6 +382,7 @@ def main(): with_etherbone = args.with_etherbone, with_analyzer = args.with_analyzer, with_i2c = args.with_i2c, + with_sdcard = args.with_sdcard, sdram_init = [] if args.sdram_init is None else get_mem_data(args.sdram_init, cpu_endianness), **soc_kwargs) if args.ram_init is not None: