Merge pull request #1024 from antmicro/litespi_refactor
litex: adding litespi to simulation, making litespi compatible with new implementation
This commit is contained in:
commit
aff2aefa72
|
@ -159,9 +159,9 @@ class XilinxDDRTristateImpl(Module):
|
||||||
_o = Signal()
|
_o = Signal()
|
||||||
_oe_n = Signal()
|
_oe_n = Signal()
|
||||||
_i = Signal()
|
_i = Signal()
|
||||||
self.specials += DDROutput(i1, i2, _o)
|
self.specials += DDROutput(i1, i2, _o, clk)
|
||||||
self.specials += DDROutput(~oe1, ~oe2, _oe_n)
|
self.specials += DDROutput(~oe1, ~oe2, _oe_n, clk)
|
||||||
self.specials += DDRInput(_i, o1, o2)
|
self.specials += DDRInput(_i, o1, o2, clk)
|
||||||
self.specials += Instance("IOBUF",
|
self.specials += Instance("IOBUF",
|
||||||
io_IO = io,
|
io_IO = io,
|
||||||
o_O = _i,
|
o_O = _i,
|
||||||
|
|
|
@ -1491,7 +1491,7 @@ class LiteXSoC(SoC):
|
||||||
self.platform.add_false_path_constraints(self.crg.cd_sys.clk, eth_rx_clk, eth_tx_clk)
|
self.platform.add_false_path_constraints(self.crg.cd_sys.clk, eth_rx_clk, eth_tx_clk)
|
||||||
|
|
||||||
# Add SPI Flash --------------------------------------------------------------------------------
|
# Add SPI Flash --------------------------------------------------------------------------------
|
||||||
def add_spi_flash(self, name="spiflash", mode="4x", dummy_cycles=None, clk_freq=None, module=None, **kwargs):
|
def add_spi_flash(self, name="spiflash", mode="4x", dummy_cycles=None, clk_freq=None, module=None, init=None, clock_domain="sys", **kwargs):
|
||||||
if module is None:
|
if module is None:
|
||||||
# Use previous LiteX SPI Flash core with compat, will be deprecated at some point.
|
# Use previous LiteX SPI Flash core with compat, will be deprecated at some point.
|
||||||
from litex.compat.soc_add_spi_flash import add_spi_flash
|
from litex.compat.soc_add_spi_flash import add_spi_flash
|
||||||
|
@ -1499,7 +1499,6 @@ class LiteXSoC(SoC):
|
||||||
# LiteSPI.
|
# LiteSPI.
|
||||||
else:
|
else:
|
||||||
# Imports.
|
# Imports.
|
||||||
from litespi.phy.generic import LiteSPIPHY
|
|
||||||
from litespi import LiteSPI
|
from litespi import LiteSPI
|
||||||
from litespi.opcodes import SpiNorFlashOpCodes
|
from litespi.opcodes import SpiNorFlashOpCodes
|
||||||
|
|
||||||
|
@ -1511,14 +1510,24 @@ class LiteXSoC(SoC):
|
||||||
self.check_if_exists(name + "_phy")
|
self.check_if_exists(name + "_phy")
|
||||||
self.check_if_exists(name + "_mmap")
|
self.check_if_exists(name + "_mmap")
|
||||||
spiflash_pads = self.platform.request(name if mode == "1x" else name + mode)
|
spiflash_pads = self.platform.request(name if mode == "1x" else name + mode)
|
||||||
spiflash_phy = LiteSPIPHY(spiflash_pads, module, device=self.platform.device, default_divisor=int(self.sys_clk_freq/clk_freq))
|
if init is None:
|
||||||
spiflash_core = LiteSPI(spiflash_phy, clk_freq=clk_freq, mmap_endianness=self.cpu.endianness, **kwargs)
|
from litespi.phy.generic import LiteSPIPHY
|
||||||
|
if not hasattr(spiflash_pads, "clk") or self.platform.device.startswith("LFE5U") or self.platform.device.startswith("LAE5U"):
|
||||||
|
spiflash_phy = LiteSPIPHY(spiflash_pads, module, clock_domain=clock_domain, device=self.platform.device, default_divisor=int(self.sys_clk_freq/clk_freq), legacy=True)
|
||||||
|
self.add_constant("SPIFLASH_LEGACY")
|
||||||
|
else:
|
||||||
|
spiflash_phy = LiteSPIPHY(spiflash_pads, module, clock_domain=clock_domain, device=self.platform.device, legacy=False)
|
||||||
|
else:
|
||||||
|
from litespi.phy.model import LiteSPIPHYModel
|
||||||
|
spiflash_phy = LiteSPIPHYModel(module, init=init, clock_domain=clock_domain)
|
||||||
|
spiflash_core = LiteSPI(spiflash_phy, clock_domain=clock_domain, mmap_endianness=self.cpu.endianness, **kwargs)
|
||||||
setattr(self.submodules, name + "_phy", spiflash_phy)
|
setattr(self.submodules, name + "_phy", spiflash_phy)
|
||||||
setattr(self.submodules, name + "_core", spiflash_core)
|
setattr(self.submodules, name + "_core", spiflash_core)
|
||||||
spiflash_region = SoCRegion(origin=self.mem_map.get(name, None), size=module.total_size)
|
spiflash_region = SoCRegion(origin=self.mem_map.get(name, None), size=module.total_size)
|
||||||
self.bus.add_slave(name=name, slave=spiflash_core.bus, region=spiflash_region)
|
self.bus.add_slave(name=name, slave=spiflash_core.bus, region=spiflash_region)
|
||||||
|
|
||||||
# Constants.
|
# Constants.
|
||||||
|
self.add_constant("SPIFLASH_FREQUENCY", clk_freq)
|
||||||
self.add_constant("SPIFLASH_MODULE_NAME", module.name.upper())
|
self.add_constant("SPIFLASH_MODULE_NAME", module.name.upper())
|
||||||
self.add_constant("SPIFLASH_MODULE_TOTAL_SIZE", module.total_size)
|
self.add_constant("SPIFLASH_MODULE_TOTAL_SIZE", module.total_size)
|
||||||
self.add_constant("SPIFLASH_MODULE_PAGE_SIZE", module.page_size)
|
self.add_constant("SPIFLASH_MODULE_PAGE_SIZE", module.page_size)
|
||||||
|
|
|
@ -13,10 +13,9 @@
|
||||||
|
|
||||||
#include "spiflash.h"
|
#include "spiflash.h"
|
||||||
|
|
||||||
#if defined(CSR_SPIFLASH_PHY_BASE) && defined(CSR_SPIFLASH_CORE_BASE)
|
#if defined(CSR_SPIFLASH_CORE_BASE)
|
||||||
|
|
||||||
//#define SPIFLASH_DEBUG
|
#if defined(SPIFLASH_LEGACY)
|
||||||
//#define SPIFLASH_MODULE_DUMMY_BITS 8
|
|
||||||
|
|
||||||
int spiflash_freq_init(void)
|
int spiflash_freq_init(void)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +29,7 @@ int spiflash_freq_init(void)
|
||||||
|
|
||||||
/* Check if block is erased (filled with 0xFF) */
|
/* Check if block is erased (filled with 0xFF) */
|
||||||
if(crc == CRC32_ERASED_FLASH) {
|
if(crc == CRC32_ERASED_FLASH) {
|
||||||
printf("First SPI Flash block erased, unable to perform freq test.\n\r");
|
printf("Block of size %d, started on address 0x%lx is erased. Cannot proceed with SPI Flash frequency test.\n\r", SPI_FLASH_BLOCK_SIZE, SPIFLASH_BASE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,18 +41,41 @@ int spiflash_freq_init(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
lowest_div++;
|
lowest_div++;
|
||||||
printf("SPI Flash clk configured to %d MHz\n", (spiflash_core_sys_clk_freq_read()/(2*(1 + lowest_div)))/1000000);
|
printf("SPI Flash clk configured to %d MHz\n", (spiflash_frequency_read()/(2*(1 + lowest_div)))/1000000);
|
||||||
|
|
||||||
spiflash_phy_clk_divisor_write(lowest_div);
|
spiflash_phy_clk_divisor_write(lowest_div);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int spiflash_freq_init(void)
|
||||||
|
{
|
||||||
|
unsigned int crc = crc32((unsigned char *)SPIFLASH_BASE, SPI_FLASH_BLOCK_SIZE);
|
||||||
|
unsigned int crc_test = crc;
|
||||||
|
|
||||||
|
#if SPIFLASH_DEBUG
|
||||||
|
printf("Testing against CRC32: %08x\n\r", crc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Check if block is erased (filled with 0xFF) */
|
||||||
|
if(crc == CRC32_ERASED_FLASH) {
|
||||||
|
printf("First SPI Flash block erased, unable to perform freq test.\n\r");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("SPI Flash clk configured to %ld MHz\n", (unsigned long)(spiflash_frequency_read()/1e6));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SPIFLASH_LEGACY
|
||||||
|
|
||||||
void spiflash_dummy_bits_setup(unsigned int dummy_bits)
|
void spiflash_dummy_bits_setup(unsigned int dummy_bits)
|
||||||
{
|
{
|
||||||
spiflash_phy_dummy_bits_write((uint32_t)dummy_bits);
|
spiflash_core_mmap_dummy_bits_write((uint32_t)dummy_bits);
|
||||||
#if SPIFLASH_DEBUG
|
#if SPIFLASH_DEBUG
|
||||||
printf("Dummy bits set to: %d\n\r", spi_dummy_bits_read());
|
printf("Dummy bits set to: %d\n\r", spiflash_core_mmap_dummy_bits_read());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +133,6 @@ void spiflash_init(void)
|
||||||
#ifndef SPIFLASH_SKIP_FREQ_INIT
|
#ifndef SPIFLASH_SKIP_FREQ_INIT
|
||||||
/* Clk frequency auto-calibration. */
|
/* Clk frequency auto-calibration. */
|
||||||
spiflash_freq_init();
|
spiflash_freq_init();
|
||||||
#else
|
|
||||||
printf("Warning: SPI Flash frequency auto-calibration skipped, using the default divisor of %d\n", spiflash_phy_clk_divisor_read());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memspeed((unsigned int *) SPIFLASH_BASE, SPIFLASH_SIZE/16, 1, 0);
|
memspeed((unsigned int *) SPIFLASH_BASE, SPIFLASH_SIZE/16, 1, 0);
|
||||||
|
|
|
@ -74,6 +74,19 @@ _io = [
|
||||||
Subsignal("sda_out", Pins(1)),
|
Subsignal("sda_out", Pins(1)),
|
||||||
Subsignal("sda_in", Pins(1)),
|
Subsignal("sda_in", Pins(1)),
|
||||||
),
|
),
|
||||||
|
("spiflash", 0,
|
||||||
|
Subsignal("cs_n", Pins(1)),
|
||||||
|
Subsignal("clk", Pins(1)),
|
||||||
|
Subsignal("mosi", Pins(1)),
|
||||||
|
Subsignal("miso", Pins(1)),
|
||||||
|
Subsignal("wp", Pins(1)),
|
||||||
|
Subsignal("hold", Pins(1)),
|
||||||
|
),
|
||||||
|
("spiflash4x", 0,
|
||||||
|
Subsignal("cs_n", Pins(1)),
|
||||||
|
Subsignal("clk", Pins(1)),
|
||||||
|
Subsignal("dq", Pins(4)),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Platform -----------------------------------------------------------------------------------------
|
# Platform -----------------------------------------------------------------------------------------
|
||||||
|
@ -85,6 +98,9 @@ class Platform(SimPlatform):
|
||||||
# Simulation SoC -----------------------------------------------------------------------------------
|
# Simulation SoC -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
class SimSoC(SoCCore):
|
class SimSoC(SoCCore):
|
||||||
|
mem_map = {
|
||||||
|
"spiflash" : 0x80000000,
|
||||||
|
}
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
with_sdram = False,
|
with_sdram = False,
|
||||||
with_ethernet = False,
|
with_ethernet = False,
|
||||||
|
@ -99,6 +115,8 @@ class SimSoC(SoCCore):
|
||||||
sdram_verbosity = 0,
|
sdram_verbosity = 0,
|
||||||
with_i2c = False,
|
with_i2c = False,
|
||||||
with_sdcard = False,
|
with_sdcard = False,
|
||||||
|
with_spi_flash = False,
|
||||||
|
flash_init = [],
|
||||||
sim_debug = False,
|
sim_debug = False,
|
||||||
trace_reset_on = False,
|
trace_reset_on = False,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
|
@ -232,6 +250,15 @@ class SimSoC(SoCCore):
|
||||||
if with_sdcard:
|
if with_sdcard:
|
||||||
self.add_sdcard("sdcard", use_emulator=True)
|
self.add_sdcard("sdcard", use_emulator=True)
|
||||||
|
|
||||||
|
# SPI Flash --------------------------------------------------------------------------------
|
||||||
|
if with_spi_flash:
|
||||||
|
from litespi.modules import S25FL128L
|
||||||
|
from litespi.opcodes import SpiNorFlashOpCodes as Codes
|
||||||
|
if flash_init is None:
|
||||||
|
platform.add_sources(os.path.abspath(os.path.dirname(__file__)), "../build/sim/verilog/iddr_verilog.v")
|
||||||
|
platform.add_sources(os.path.abspath(os.path.dirname(__file__)), "../build/sim/verilog/oddr_verilog.v")
|
||||||
|
self.add_spi_flash(mode="4x", module=S25FL128L(Codes.READ_1_1_4), with_master=True, init=flash_init)
|
||||||
|
|
||||||
# Simulation debugging ----------------------------------------------------------------------
|
# Simulation debugging ----------------------------------------------------------------------
|
||||||
if sim_debug:
|
if sim_debug:
|
||||||
platform.add_debug(self, reset=1 if trace_reset_on else 0)
|
platform.add_debug(self, reset=1 if trace_reset_on else 0)
|
||||||
|
@ -295,6 +322,8 @@ def sim_args(parser):
|
||||||
parser.add_argument("--with-analyzer", action="store_true", help="Enable Analyzer support")
|
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-i2c", action="store_true", help="Enable I2C support")
|
||||||
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
|
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
|
||||||
|
parser.add_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed)")
|
||||||
|
parser.add_argument("--flash-init", default=None, help="Flash init file")
|
||||||
parser.add_argument("--trace", action="store_true", help="Enable Tracing")
|
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-fst", action="store_true", help="Enable FST tracing (default=VCD)")
|
||||||
parser.add_argument("--trace-start", default="0", help="Time to start tracing (ps)")
|
parser.add_argument("--trace-start", default="0", help="Time to start tracing (ps)")
|
||||||
|
@ -361,9 +390,11 @@ def main():
|
||||||
with_analyzer = args.with_analyzer,
|
with_analyzer = args.with_analyzer,
|
||||||
with_i2c = args.with_i2c,
|
with_i2c = args.with_i2c,
|
||||||
with_sdcard = args.with_sdcard,
|
with_sdcard = args.with_sdcard,
|
||||||
|
with_spi_flash = args.with_spi_flash,
|
||||||
sim_debug = args.sim_debug,
|
sim_debug = args.sim_debug,
|
||||||
trace_reset_on = trace_start > 0 or trace_end > 0,
|
trace_reset_on = trace_start > 0 or trace_end > 0,
|
||||||
sdram_init = [] if args.sdram_init is None else get_mem_data(args.sdram_init, cpu.endianness),
|
sdram_init = [] if args.sdram_init is None else get_mem_data(args.sdram_init, cpu.endianness),
|
||||||
|
flash_init = None if args.flash_init is None else get_mem_data(args.flash_init, "big"),
|
||||||
**soc_kwargs)
|
**soc_kwargs)
|
||||||
if args.ram_init is not None or args.sdram_init is not None:
|
if args.ram_init is not None or args.sdram_init is not None:
|
||||||
soc.add_constant("ROM_BOOT_ADDRESS", soc.mem_map["main_ram"])
|
soc.add_constant("ROM_BOOT_ADDRESS", soc.mem_map["main_ram"])
|
||||||
|
|
Loading…
Reference in New Issue