soc_core: add csr_alignment to allow 64-bit alignment with 64-bit CPUs

This commit is contained in:
Florent Kermarrec 2019-07-08 09:53:52 +02:00
parent 927b7c13a2
commit f4770219fa
4 changed files with 46 additions and 23 deletions

View File

@ -21,6 +21,13 @@ from litex.soc.interconnect.csr import CSRStatus
from litex.build.tools import generated_banner
# FIXME: use OrderedDict for constants?
def get_constant(name, constants):
for n, v in constants:
if n == name:
return v
return None
def get_cpu_mak(cpu):
# select between clang and gcc
clang = os.getenv("CLANG", "")
@ -97,7 +104,7 @@ def get_mem_header(regions, flash_boot_address, shadow_base):
return r
def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only, with_access_functions):
def _get_rw_functions_c(reg_name, reg_base, nwords, busword, alignment, read_only, with_access_functions):
r = ""
r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"L\n"
@ -120,7 +127,7 @@ def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only, with_acc
if size > 1:
r += "\t"+ctype+" r = csr_readl("+hex(reg_base)+"L);\n"
for byte in range(1, nwords):
r += "\tr <<= "+str(busword)+";\n\tr |= csr_readl("+hex(reg_base+4*byte)+"L);\n"
r += "\tr <<= "+str(busword)+";\n\tr |= csr_readl("+hex(reg_base+alignment//8*byte)+"L);\n"
r += "\treturn r;\n}\n"
else:
r += "\treturn csr_readl("+hex(reg_base)+"L);\n}\n"
@ -133,12 +140,13 @@ def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only, with_acc
value_shifted = "value >> "+str(shift)
else:
value_shifted = "value"
r += "\tcsr_writel("+value_shifted+", "+hex(reg_base+4*word)+"L);\n"
r += "\tcsr_writel("+value_shifted+", "+hex(reg_base+alignment//8*word)+"L);\n"
r += "}\n"
return r
def get_csr_header(regions, constants, with_access_functions=True, with_shadow_base=True, shadow_base=0x80000000):
alignment = get_constant("CONFIG_CSR_ALIGNMENT", constants)
r = generated_banner("//")
r += "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n"
if with_access_functions:
@ -161,8 +169,9 @@ def get_csr_header(regions, constants, with_access_functions=True, with_shadow_b
if not isinstance(obj, Memory):
for csr in obj:
nr = (csr.size + busword - 1)//busword
r += _get_rw_functions_c(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus), with_access_functions)
origin += 4*nr
r += _get_rw_functions_c(name + "_" + csr.name, origin, nr, busword, alignment,
isinstance(csr, CSRStatus), with_access_functions)
origin += alignment//8*nr
r += "\n/* constants */\n"
for name, value in constants:
@ -185,6 +194,7 @@ def get_csr_header(regions, constants, with_access_functions=True, with_shadow_b
def get_csr_csv(csr_regions=None, constants=None, memory_regions=None):
alignment = 32 if constants is None else get_constant("CONFIG_CSR_ALIGNMENT", constants)
r = generated_banner("#")
if csr_regions is not None:
@ -196,7 +206,7 @@ def get_csr_csv(csr_regions=None, constants=None, memory_regions=None):
for csr in obj:
nr = (csr.size + busword - 1)//busword
r += "csr_register,{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
origin += 4*nr
origin += alignment//8*nr
if constants is not None:
for name, value in constants:

View File

@ -150,7 +150,7 @@ class SoCCore(Module):
# MAIN_RAM parameters
integrated_main_ram_size=0, integrated_main_ram_init=[],
# CSR parameters
csr_data_width=8, csr_address_width=14,
csr_data_width=8, csr_alignment=32, csr_address_width=14,
# Identifier parameters
ident="", ident_version=False,
# UART parameters
@ -210,7 +210,10 @@ class SoCCore(Module):
self.integrated_sram_size = integrated_sram_size
self.integrated_main_ram_size = integrated_main_ram_size
assert csr_data_width in [8, 32, 64]
assert csr_alignment in [32, 64]
self.csr_data_width = csr_data_width
self.csr_alignment = csr_alignment
self.csr_address_width = csr_address_width
self.with_ctrl = with_ctrl
@ -291,6 +294,7 @@ class SoCCore(Module):
bus_csr=csr_bus.Interface(csr_data_width, csr_address_width))
self.add_csr_master(self.wishbone2csr.csr)
self.config["CSR_DATA_WIDTH"] = csr_data_width
self.config["CSR_ALIGNMENT"] = csr_alignment
self.register_mem("csr", self.soc_mem_map["csr"], self.wishbone2csr.wishbone)
# Add UART
@ -495,7 +499,9 @@ class SoCCore(Module):
# Collect and create CSRs
self.submodules.csrbankarray = csr_bus.CSRBankArray(self,
self.get_csr_dev_address,
data_width=self.csr_data_width, address_width=self.csr_address_width)
data_width=self.csr_data_width,
address_width=self.csr_address_width,
alignment=self.csr_alignment)
# Add CSRs interconnect
self.submodules.csrcon = csr_bus.InterconnectShared(

View File

@ -32,7 +32,8 @@ _layout = [
class Interface(Record):
def __init__(self, data_width=8, address_width=14):
def __init__(self, data_width=8, address_width=14, alignment=32):
self.alignment = alignment
Record.__init__(self, set_layout_parameters(_layout,
data_width=data_width, address_width=address_width))
@ -160,19 +161,23 @@ class CSRBank(csr.GenericBank):
sel = Signal()
self.comb += sel.eq(self.bus.adr[9:] == address)
if bus.alignment == 64:
self.comb += If(self.bus.adr[0], sel.eq(0))
adr_shift = log2_int(bus.alignment//32)
for i, c in enumerate(self.simple_csrs):
self.comb += [
c.r.eq(self.bus.dat_w[:c.size]),
c.re.eq(sel & \
self.bus.we & \
(self.bus.adr[:self.decode_bits] == i))
(self.bus.adr[adr_shift:adr_shift+self.decode_bits] == i))
]
brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
self.sync += [
self.bus.dat_r.eq(0),
If(sel, Case(self.bus.adr[:self.decode_bits], brcases))
If(sel, Case(self.bus.adr[adr_shift:adr_shift+self.decode_bits], brcases))
]

View File

@ -51,6 +51,8 @@ __attribute__((unused)) static void cdelay(int i)
#ifdef CSR_SDRAM_BASE
#define DFII_ADDR_SHIFT CONFIG_CSR_ALIGNMENT/8
void sdrsw(void)
{
sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
@ -103,7 +105,7 @@ void sdrrdbuf(int dq)
for(p=0;p<DFII_NPHASES;p++)
for(i=first_byte;i<DFII_PIX_DATA_SIZE;i+=step)
printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i));
printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*i));
printf("\n");
}
@ -167,7 +169,7 @@ void sdrrderr(char *count)
cdelay(15);
for(p=0;p<DFII_NPHASES;p++)
for(i=0;i<DFII_PIX_DATA_SIZE;i++)
prev_data[p*DFII_PIX_DATA_SIZE+i] = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i);
prev_data[p*DFII_PIX_DATA_SIZE+i] = MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*i);
for(j=0;j<_count;j++) {
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
@ -176,7 +178,7 @@ void sdrrderr(char *count)
for(i=0;i<DFII_PIX_DATA_SIZE;i++) {
unsigned char new_data;
new_data = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i);
new_data = MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*i);
errs[p*DFII_PIX_DATA_SIZE+i] |= prev_data[p*DFII_PIX_DATA_SIZE+i] ^ new_data;
prev_data[p*DFII_PIX_DATA_SIZE+i] = new_data;
}
@ -211,7 +213,7 @@ void sdrwr(char *startaddr)
for(p=0;p<DFII_NPHASES;p++)
for(i=0;i<DFII_PIX_DATA_SIZE;i++)
MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = 0x10*p + i;
MMPTR(sdram_dfii_pix_wrdata_addr[p]+DFII_ADDR_SHIFT*i) = 0x10*p + i;
sdram_dfii_piwr_address_write(addr);
sdram_dfii_piwr_baddress_write(0);
@ -309,7 +311,7 @@ int write_level(void)
cdelay(100);
for(i=0;i<NBMODULES;i++) {
printf("m%d: |", i);
dq_address = sdram_dfii_pix_rddata_addr[0]+4*(NBMODULES-1-i);
dq_address = sdram_dfii_pix_rddata_addr[0]+DFII_ADDR_SHIFT*(NBMODULES-1-i);
/* rst delay */
write_delay_rst(i);
@ -458,7 +460,7 @@ static int read_level_scan(int module, int bitslip)
/* Write test pattern */
for(p=0;p<DFII_NPHASES;p++)
for(i=0;i<DFII_PIX_DATA_SIZE;i++)
MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = prs[DFII_PIX_DATA_SIZE*p+i];
MMPTR(sdram_dfii_pix_wrdata_addr[p]+DFII_ADDR_SHIFT*i) = prs[DFII_PIX_DATA_SIZE*p+i];
sdram_dfii_piwr_address_write(0);
sdram_dfii_piwr_baddress_write(0);
command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
@ -483,9 +485,9 @@ static int read_level_scan(int module, int bitslip)
cdelay(15);
working = 1;
for(p=0;p<DFII_NPHASES;p++) {
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
working = 0;
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
working = 0;
}
#ifdef ECP5DDRPHY
@ -554,9 +556,9 @@ static void read_level(int module)
cdelay(15);
working = 1;
for(p=0;p<DFII_NPHASES;p++) {
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
working = 0;
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
working = 0;
}
#ifdef ECP5DDRPHY
@ -592,9 +594,9 @@ static void read_level(int module)
cdelay(15);
working = 1;
for(p=0;p<DFII_NPHASES;p++) {
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+(NBMODULES-module-1)])
working = 0;
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
if(MMPTR(sdram_dfii_pix_rddata_addr[p]+DFII_ADDR_SHIFT*(2*NBMODULES-module-1)) != prs[DFII_PIX_DATA_SIZE*p+2*NBMODULES-module-1])
working = 0;
}
#ifdef ECP5DDRPHY