soc/integration/cpu_interface: generate name for Memories in get_csr_header
[litex.git] / litex / soc / integration / cpu_interface.py
1 import os
2 from shutil import which
3
4 from migen import *
5
6 from litex.soc.interconnect.csr import CSRStatus
7
8 def get_cpu_mak(cpu):
9 # select between clang and gcc
10 clang = os.getenv("CLANG", "")
11 if clang != "":
12 clang = bool(int(clang))
13 else:
14 clang = None
15 if not hasattr(cpu, "clang_triple"):
16 if clang:
17 raise ValueError(cpu.name + "not supported with clang.")
18 else:
19 clang = False
20 else:
21 # Default to clang unless told otherwise
22 if clang is None:
23 clang = True
24 assert isinstance(clang, bool)
25 if clang:
26 triple = cpu.clang_triple
27 flags = cpu.clang_flags
28 else:
29 triple = cpu.gcc_triple
30 flags = cpu.gcc_flags
31
32 # select triple when more than one
33 def select_triple(triple):
34 r = None
35 if not isinstance(triple, tuple):
36 triple = (triple,)
37 for i in range(len(triple)):
38 t = triple[i]
39 if which(t+"-gcc"):
40 r = t
41 break
42 if r is None:
43 msg = "Unable to find any of the cross compilation toolchains:\n"
44 for i in range(len(triple)):
45 msg += "- " + triple[i] + "\n"
46 raise OSError(msg)
47 return r
48
49 # return informations
50 return [
51 ("TRIPLE", select_triple(triple)),
52 ("CPU", cpu.name),
53 ("CPUFLAGS", flags),
54 ("CPUENDIANNESS", cpu.endianness),
55 ("CLANG", str(int(clang)))
56 ]
57
58
59 def get_linker_output_format(cpu):
60 return "OUTPUT_FORMAT(\"" + cpu.linker_output_format + "\")\n"
61
62
63 def get_linker_regions(regions):
64 r = "MEMORY {\n"
65 for name, origin, length in regions:
66 r += "\t{} : ORIGIN = 0x{:08x}, LENGTH = 0x{:08x}\n".format(name, origin, length)
67 r += "}\n"
68 return r
69
70
71 def get_mem_header(regions, flash_boot_address):
72 r = "#ifndef __GENERATED_MEM_H\n#define __GENERATED_MEM_H\n\n"
73 for name, base, size in regions:
74 r += "#define {name}_BASE 0x{base:08x}\n#define {name}_SIZE 0x{size:08x}\n\n".format(name=name.upper(), base=base, size=size)
75 if flash_boot_address is not None:
76 r += "#define FLASH_BOOT_ADDRESS 0x{:08x}\n\n".format(flash_boot_address)
77 r += "#endif\n"
78 return r
79
80
81 def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only, with_access_functions):
82 r = ""
83
84 r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n"
85 r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(nwords)+"\n"
86
87 size = nwords*busword
88 if size > 64:
89 return r
90 elif size > 32:
91 ctype = "unsigned long long int"
92 elif size > 16:
93 ctype = "unsigned int"
94 elif size > 8:
95 ctype = "unsigned short int"
96 else:
97 ctype = "unsigned char"
98
99 if with_access_functions:
100 r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
101 if size > 1:
102 r += "\t"+ctype+" r = csr_readl("+hex(reg_base)+");\n"
103 for byte in range(1, nwords):
104 r += "\tr <<= "+str(busword)+";\n\tr |= csr_readl("+hex(reg_base+4*byte)+");\n"
105 r += "\treturn r;\n}\n"
106 else:
107 r += "\treturn csr_readl("+hex(reg_base)+");\n}\n"
108
109 if not read_only:
110 r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
111 for word in range(nwords):
112 shift = (nwords-word-1)*busword
113 if shift:
114 value_shifted = "value >> "+str(shift)
115 else:
116 value_shifted = "value"
117 r += "\tcsr_writel("+value_shifted+", "+hex(reg_base+4*word)+");\n"
118 r += "}\n"
119 return r
120
121
122 def get_csr_header(regions, constants, with_access_functions=True, with_shadow_base=True, shadow_base=0x80000000):
123 r = "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n"
124 if with_access_functions:
125 r += "#include <stdint.h>\n"
126 r += "#ifdef CSR_ACCESSORS_DEFINED\n"
127 r += "extern void csr_writeb(uint8_t value, uint32_t addr);\n"
128 r += "extern uint8_t csr_readb(uint32_t addr);\n"
129 r += "extern void csr_writew(uint16_t value, uint32_t addr);\n"
130 r += "extern uint16_t csr_readw(uint32_t addr);\n"
131 r += "extern void csr_writel(uint32_t value, uint32_t addr);\n"
132 r += "extern uint32_t csr_readl(uint32_t addr);\n"
133 r += "#else /* ! CSR_ACCESSORS_DEFINED */\n"
134 r += "#include <hw/common.h>\n"
135 r += "#endif /* ! CSR_ACCESSORS_DEFINED */\n"
136 for name, origin, busword, obj in regions:
137 if not with_shadow_base:
138 origin &= (~shadow_base)
139 if isinstance(obj, Memory):
140 r += "\n/* "+name+" */\n"
141 r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
142 else:
143 r += "\n/* "+name+" */\n"
144 r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
145 for csr in obj:
146 nr = (csr.size + busword - 1)//busword
147 r += _get_rw_functions_c(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus), with_access_functions)
148 origin += 4*nr
149
150 r += "\n/* constants */\n"
151 for name, value in constants:
152 if value is None:
153 r += "#define "+name+"\n"
154 continue
155 if isinstance(value, str):
156 value = "\"" + value + "\""
157 ctype = "const char *"
158 else:
159 value = str(value)
160 ctype = "int"
161 r += "#define "+name+" "+value+"\n"
162 if with_access_functions:
163 r += "static inline "+ctype+" "+name.lower()+"_read(void) {\n"
164 r += "\treturn "+value+";\n}\n"
165
166 r += "\n#endif\n"
167 return r
168
169
170 def get_csr_csv(csr_regions=None, constants=None, memory_regions=None):
171 r = ""
172
173 if csr_regions is not None:
174 for name, origin, busword, obj in csr_regions:
175 r += "csr_base,{},0x{:08x},,\n".format(name, origin)
176
177 for name, origin, busword, obj in csr_regions:
178 if not isinstance(obj, Memory):
179 for csr in obj:
180 nr = (csr.size + busword - 1)//busword
181 r += "csr_register,{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
182 origin += 4*nr
183
184 if constants is not None:
185 for name, value in constants:
186 r += "constant,{},{},,\n".format(name.lower(), value)
187
188 if memory_regions is not None:
189 for name, origin, length in memory_regions:
190 r += "memory_region,{},0x{:08x},{:d},\n".format(name.lower(), origin, length)
191
192 return r