Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 50 additions & 28 deletions litex/soc/integration/soc.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,21 +440,6 @@ def add_slave(self, name=None, slave=None, region=None):
colorer(name, color="underline"),
colorer("added", color="green")))

def get_address_width(self, standard):
standard_from = self.standard
standard_to = standard

# AXI or AXI-Lite SoC Bus and Wishbone requested:
if standard_from in ["axi", "axi-lite"] and standard_to in ["wishbone"]:
address_shift = log2_int(self.data_width//8)
return self.address_width - address_shift
# Wishbone SoC Bus and AXI, AXI-Lite requested:
if standard_from in ["wishbone"] and standard_to in ["axi", "axi-lite"]:
address_shift = log2_int(self.data_width//8)
return self.address_width + address_shift
# Else just return address_width:
return self.address_width

# Str ------------------------------------------------------------------------------------------
def __str__(self):
r = "{}-bit {} Bus, {}GiB Address Space.\n".format(
Expand Down Expand Up @@ -1053,7 +1038,7 @@ def add_cpu(self, name="vexriscv", variant="standard", reset_address=None, cfu=N
name = "SoCDMABusHandler",
standard = "wishbone",
data_width = self.bus.data_width,
address_width = self.bus.get_address_width(standard="wishbone"),
address_width = self.bus.address_width,
bursting = self.bus.bursting
)
dma_bus = wishbone.Interface(data_width=self.bus.data_width)
Expand Down Expand Up @@ -1412,8 +1397,9 @@ def add_jtagbone(self, name="jtagbone", chain=1):
self.bus.add_master(name=name, master=jtagbone.wishbone)

# Add SDRAM ------------------------------------------------------------------------------------
def add_sdram(self, name="sdram", phy=None, module=None, origin=None, size=None,
with_bist = False,
def add_sdram(self, name="sdram", phy=None, module=None, origin=None, size=None, software_debug=False,
with_bist = True,
with_ecc = False,
with_soc_interconnect = True,
l2_cache_size = 8192,
l2_cache_min_data_width = 128,
Expand All @@ -1427,6 +1413,7 @@ def add_sdram(self, name="sdram", phy=None, module=None, origin=None, size=None,
from litedram.frontend.wishbone import LiteDRAMWishbone2Native
from litedram.frontend.axi import LiteDRAMAXI2Native
from litedram.frontend.bist import LiteDRAMBISTGenerator, LiteDRAMBISTChecker
from litedram.frontend.ecc import LiteDRAMNativePortECC

# LiteDRAM core.
self.check_if_exists(name)
Expand Down Expand Up @@ -1460,10 +1447,41 @@ def add_sdram(self, name="sdram", phy=None, module=None, origin=None, size=None,

# LiteDRAM BIST.
if with_bist:
sdram_generator = LiteDRAMBISTGenerator(sdram.crossbar.get_port())
sdram_checker = LiteDRAMBISTChecker( sdram.crossbar.get_port())
if with_ecc:
ecc_port_w = sdram.crossbar.get_port()
user_port_w = LiteDRAMNativePort(
mode = ecc_port_w.mode,
address_width = ecc_port_w.address_width,
data_width = ecc_port_w.data_width//2
)
ecc_w = LiteDRAMNativePortECC(
user_port_w, ecc_port_w,
burst_cycles=user_port_w.data_width//8,
with_error_injection=True
)
setattr(self.submodules, f"{name}_eccw", ecc_w)

ecc_port_r = sdram.crossbar.get_port()
user_port_r = LiteDRAMNativePort(
mode = ecc_port_r.mode,
address_width = ecc_port_r.address_width,
data_width = ecc_port_r.data_width//2
)
ecc_r = LiteDRAMNativePortECC(
user_port_r, ecc_port_r,
burst_cycles=user_port_r.data_width//8,
with_error_injection=True
)
setattr(self.submodules, f"{name}_eccr", ecc_r)
else:
user_port_w = sdram.crossbar.get_port()
user_port_r = sdram.crossbar.get_port()

sdram_generator = LiteDRAMBISTGenerator(user_port_w)
sdram_checker = LiteDRAMBISTChecker(user_port_r)
setattr(self.submodules, f"{name}_generator", sdram_generator)
setattr(self.submodules, f"{name}_checker", sdram_checker)
self.add_config("BIST_DATA_WIDTH", user_port_r.data_width)

if not with_soc_interconnect: return

Expand Down Expand Up @@ -1563,7 +1581,7 @@ def add_sdram(self, name="sdram", phy=None, module=None, origin=None, size=None,

# L2 Cache
if l2_cache_size != 0:
# Insert L2 cache inbetween Wishbone bus and LiteDRAM
# Insert L2 cache in between Wishbone bus and LiteDRAM
l2_cache_size = max(l2_cache_size, int(2*port.data_width/8)) # Use minimal size if lower
l2_cache_size = 2**int(log2(l2_cache_size)) # Round to nearest power of 2
l2_cache_data_width = max(port.data_width, l2_cache_min_data_width)
Expand All @@ -1588,6 +1606,10 @@ def add_sdram(self, name="sdram", phy=None, module=None, origin=None, size=None,
base_address = self.bus.regions["main_ram"].origin
)

# Debug.
if software_debug:
self.add_constant("SDRAM_DEBUG")

# Add Ethernet ---------------------------------------------------------------------------------
def add_ethernet(self, name="ethmac", phy=None, phy_cd="eth", dynamic_ip=False, software_debug=False,
data_width = 8,
Expand Down Expand Up @@ -1804,28 +1826,28 @@ def add_sdcard(self, name="sdcard", mode="read+write", use_emulator=False, softw

# Block2Mem DMA.
if "read" in mode:
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.get_address_width(standard="wishbone"))
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width)
self.submodules.sdblock2mem = SDBlock2MemDMA(bus=bus, endianness=self.cpu.endianness)
self.comb += self.sdcore.source.connect(self.sdblock2mem.sink)
dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
dma_bus.add_master("sdblock2mem", master=bus)

# Mem2Block DMA.
if "write" in mode:
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.get_address_width(standard="wishbone"))
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width)
self.submodules.sdmem2block = SDMem2BlockDMA(bus=bus, endianness=self.cpu.endianness)
self.comb += self.sdmem2block.source.connect(self.sdcore.sink)
dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus
dma_bus.add_master("sdmem2block", master=bus)

# Interrupts.
self.submodules.sdirq = EventManager()
self.sdirq.card_detect = EventSourcePulse(description="SDCard has been ejected/inserted.")
self.submodules.sdirq = EventManager()
self.sdirq.card_detect = EventSourcePulse(description="SDCard has been ejected/inserted.")
if "read" in mode:
self.sdirq.block2mem_dma = EventSourcePulse(description="Block2Mem DMA terminated.")
if "write" in mode:
self.sdirq.mem2block_dma = EventSourcePulse(description="Mem2Block DMA terminated.")
self.sdirq.cmd_done = EventSourceLevel(description="Command completed.")
self.sdirq.cmd_done = EventSourceLevel(description="Command completed.")
self.sdirq.finalize()
if "read" in mode:
self.comb += self.sdirq.block2mem_dma.trigger.eq(self.sdblock2mem.irq)
Expand Down Expand Up @@ -1876,7 +1898,7 @@ def add_sata(self, name="sata", phy=None, mode="read+write", with_identify=True)

# Sector2Mem DMA.
if "read" in mode:
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.get_address_width(standard="wishbone"))
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width)
self.submodules.sata_sector2mem = LiteSATASector2MemDMA(
port = self.sata_crossbar.get_port(),
bus = bus,
Expand All @@ -1886,7 +1908,7 @@ def add_sata(self, name="sata", phy=None, mode="read+write", with_identify=True)

# Mem2Sector DMA.
if "write" in mode:
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.get_address_width(standard="wishbone"))
bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width)
self.submodules.sata_mem2sector = LiteSATAMem2SectorDMA(
bus = bus,
port = self.sata_crossbar.get_port(),
Expand Down
162 changes: 146 additions & 16 deletions litex/soc/software/bios/cmds/cmd_litedram.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <libbase/memtest.h>

#include <generated/soc.h>
#include <generated/csr.h>
#include <generated/mem.h>
#include <generated/soc.h>

#include <libbase/i2c.h>
#include <libbase/memtest.h>

#include <liblitedram/sdram.h>
#include <liblitedram/bist.h>
Expand Down Expand Up @@ -52,41 +53,170 @@ define_command(sdram_cal, sdram_cal_handler, "Calibrate SDRAM", LITEDRAM_CMDS);
#if defined(CSR_SDRAM_BASE)
static void sdram_test_handler(int nb_params, char **params)
{
memtest((unsigned int *)MAIN_RAM_BASE, MAIN_RAM_SIZE/32);
memtest((unsigned int *)MAIN_RAM_BASE, MAIN_RAM_SIZE);
}
define_command(sdram_test, sdram_test_handler, "Test SDRAM", LITEDRAM_CMDS);
#endif

#if defined(CSR_SDRAM_GENERATOR_BASE) && defined(CSR_SDRAM_CHECKER_BASE)
/**
* Command "sdram_bist"
* Command "sdram_bist_pat"
*
* Run SDRAM Build-In Self-Test
* Set SDRAM Build-In Self-Test (BIST) Pattern
*
*/
#if defined(CSR_SDRAM_GENERATOR_BASE) && defined(CSR_SDRAM_CHECKER_BASE)
static void sdram_bist_handler(int nb_params, char **params)
static void sdram_pat_handler(int nb_params, char **params)
{
char *c;
int burst_length;
int random;
if (nb_params < 2) {
printf("sdram_bist <burst_length> <random>");
uint32_t value;

if (nb_params < 1) {
printf("sdram_bist_pat <value>");
return;
}
burst_length = strtoul(params[0], &c, 0);
value = strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Incorrect burst_length");
return;
}
random = strtoul(params[1], &c, 0);
sdram_bist_pattern(value);
}
define_command(sdram_bist_pat, sdram_pat_handler, "Set SDRAM Build-In Self-Test Pattern", LITEDRAM_CMDS);

/**
* Command "sdram_bist_gen"
*
* Run SDRAM Build-In Self-Test (BIST) Generator
*
*/
static void sdram_gen_handler(int nb_params, char **params)
{
char *c;
uint32_t base;
uint32_t length;
int dmode = 2; /* default: random data*/

if (nb_params < 2) {
printf("sdram_bist_gen <base> <length> [<data_mode>]\n");
printf("base : base address (starts at zero)\n");
printf("length : DMA block size in bytes\n");
printf("data_mode: 0=pattern, 1=inc, 2=random");
return;
}
base = strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Incorrect base");
return;
}
length = strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Incorrect length");
return;
}
if (nb_params > 2) {
dmode = strtoul(params[2], &c, 0);
if (*c != 0) {
printf("Incorrect data_mode");
return;
}
}
sdram_bist_gen(base, length, dmode);
}
define_command(sdram_bist_gen, sdram_gen_handler, "Run SDRAM Build-In Self-Test Generator", LITEDRAM_CMDS);

/**
* Command "sdram_bist_chk"
*
* Run SDRAM Build-In Self-Test (BIST) Checker
*
*/
static void sdram_chk_handler(int nb_params, char **params)
{
char *c;
uint32_t base;
uint32_t length;
int dmode = 2; /* default: random data*/

if (nb_params < 2) {
printf("sdram_bist_chk <base> <length> [<data_mode>]\n");
printf("base : base address (starts at zero)\n");
printf("length : DMA block size in bytes\n");
printf("data_mode: 0=pattern, 1=inc, 2=random");
return;
}
base = strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Incorrect base");
return;
}
length = strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Incorrect length");
return;
}
if (nb_params > 2) {
dmode = strtoul(params[2], &c, 0);
if (*c != 0) {
printf("Incorrect data_mode");
return;
}
}
sdram_bist_chk(base, length, dmode);
}
define_command(sdram_bist_chk, sdram_chk_handler, "Run SDRAM Build-In Self-Test Checker", LITEDRAM_CMDS);

/**
* Command "sdram_bist"
*
* Run SDRAM Build-In Self-Test (BIST)
*
*/
static void sdram_bist_handler(int nb_params, char **params)
{
char *c;
uint32_t length;
int amode = 1; /* default: increment */
int dmode = 2; /* default: random data*/
int wmode = 2; /* default: write before each read */

if (nb_params < 1) {
printf("sdram_bist <length> [<addr_mode>] [<data_mode>] [<write_mode>]\n");
printf("length : DMA block size in bytes\n");
printf("addr_mode : 0=fixed (starts at zero), 1=inc, 2=random\n");
printf("data_mode : 0=pattern, 1=inc, 2=random\n");
printf("write_mode: 0=no_write, 1=write_once, 2=write_and_read");
return;
}
length = strtoul(params[0], &c, 0);
if (*c != 0) {
printf("Incorrect random");
printf("Incorrect length");
return;
}
sdram_bist(burst_length, random);
if (nb_params > 1) {
amode = strtoul(params[1], &c, 0);
if (*c != 0) {
printf("Incorrect addr_mode");
return;
}
}
if (nb_params > 2) {
dmode = strtoul(params[2], &c, 0);
if (*c != 0) {
printf("Incorrect data_mode");
return;
}
}
if (nb_params > 3) {
wmode = strtoul(params[3], &c, 0);
if (*c != 0) {
printf("Incorrect write_once");
return;
}
}
sdram_bist(length, amode, dmode, wmode);
}
define_command(sdram_bist, sdram_bist_handler, "Run SDRAM Build-In Self-Test", LITEDRAM_CMDS);
#endif
#endif /* defined(CSR_SDRAM_GENERATOR_BASE) && defined(CSR_SDRAM_CHECKER_BASE) */

#ifdef CSR_DDRPHY_RDPHASE_ADDR
/**
Expand Down
Loading