soc_core: add csr_alignment to allow 64-bit alignment with 64-bit CPUs
This commit is contained in:
parent
927b7c13a2
commit
f4770219fa
|
@ -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:
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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))
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue