1 # This file is Copyright (c) 2015 Sebastien Bourdeauducq <sb@m-labs.hk>
2 # This file is Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # This file is Copyright (c) 2018-2019 Antmicro <www.antmicro.com>
4 # This file is Copyright (c) 2018 Sergiusz Bazanski <q3k@q3k.org>
5 # This file is Copyright (c) 2016-2017 Tim 'mithro' Ansell <mithro@mithis.com>
6 # This file is Copyright (c) 2018 William D. Jones <thor0505@comcast.net>
7 # This file is Copyright (c) 2020 Xiretza <xiretza@xiretza.xyz>
8 # This file is Copyright (c) 2020 Piotr Esden-Tempski <piotr@esden.net>
17 from litex
import get_data_mod
18 from litex
.build
.tools
import write_to_file
19 from litex
.soc
.integration
import export
, soc_core
21 __all__
= ["soc_software_packages", "soc_directory",
22 "Builder", "builder_args", "builder_argdict"]
25 soc_software_packages
= [
35 soc_directory
= os
.path
.abspath(os
.path
.join(os
.path
.dirname(__file__
), ".."))
38 def _makefile_escape(s
):
39 return s
.replace("\\", "\\\\")
43 def __init__(self
, soc
,
49 compile_software
= True,
50 compile_gateware
= True,
58 # From Python doc: makedirs() will become confused if the path
59 # elements to create include '..'
60 self
.output_dir
= os
.path
.abspath(output_dir
or "soc_{}_{}".format(soc
.__class
__.__name
__.lower(), soc
.platform
.name
))
61 self
.gateware_dir
= os
.path
.abspath(gateware_dir
or os
.path
.join(self
.output_dir
, "gateware"))
62 self
.software_dir
= os
.path
.abspath(software_dir
or os
.path
.join(self
.output_dir
, "software"))
63 self
.include_dir
= os
.path
.abspath(include_dir
or os
.path
.join(self
.software_dir
, "include"))
64 self
.generated_dir
= os
.path
.abspath(generated_dir
or os
.path
.join(self
.include_dir
, "generated"))
66 self
.compile_software
= compile_software
67 self
.compile_gateware
= compile_gateware
68 self
.csr_csv
= csr_csv
69 self
.csr_json
= csr_json
70 self
.csr_svd
= csr_svd
71 self
.memory_x
= memory_x
72 self
.bios_options
= bios_options
74 self
.software_packages
= []
75 for name
in soc_software_packages
:
76 self
.add_software_package(name
)
78 def add_software_package(self
, name
, src_dir
=None):
80 src_dir
= os
.path
.join(soc_directory
, "software", name
)
81 self
.software_packages
.append((name
, src_dir
))
83 def _generate_includes(self
):
84 os
.makedirs(self
.include_dir
, exist_ok
=True)
85 os
.makedirs(self
.generated_dir
, exist_ok
=True)
87 if self
.soc
.cpu_type
is not None:
88 variables_contents
= []
90 variables_contents
.append("{}={}\n".format(k
, _makefile_escape(v
)))
92 for k
, v
in export
.get_cpu_mak(self
.soc
.cpu
, self
.compile_software
):
94 # Distinguish between LiteX and MiSoC.
96 # Distinguish between applications running from main RAM and
97 # flash for user-provided software packages.
99 "COPY_TO_MAIN_RAM" : "0",
100 "EXECUTE_IN_PLACE" : "0"
102 if "main_ram" in self
.soc
.mem_regions
.keys():
103 exec_profiles
["COPY_TO_MAIN_RAM"] = "1"
105 exec_profiles
["EXECUTE_IN_PLACE"] = "1"
106 for k
, v
in exec_profiles
.items():
109 "COMPILER_RT_DIRECTORY",
110 get_data_mod("software", "compiler_rt").data_location
)
111 define("SOC_DIRECTORY", soc_directory
)
112 variables_contents
.append("export BUILDINC_DIRECTORY\n")
113 define("BUILDINC_DIRECTORY", self
.include_dir
)
114 for name
, src_dir
in self
.software_packages
:
115 define(name
.upper() + "_DIRECTORY", src_dir
)
117 if self
.bios_options
is not None:
118 for option
in self
.bios_options
:
122 os
.path
.join(self
.generated_dir
, "variables.mak"),
123 "".join(variables_contents
))
125 os
.path
.join(self
.generated_dir
, "output_format.ld"),
126 export
.get_linker_output_format(self
.soc
.cpu
))
128 os
.path
.join(self
.generated_dir
, "regions.ld"),
129 export
.get_linker_regions(self
.soc
.mem_regions
))
132 os
.path
.join(self
.generated_dir
, "mem.h"),
133 export
.get_mem_header(self
.soc
.mem_regions
))
135 os
.path
.join(self
.generated_dir
, "soc.h"),
136 export
.get_soc_header(self
.soc
.constants
))
138 os
.path
.join(self
.generated_dir
, "csr.h"),
139 export
.get_csr_header(self
.soc
.csr_regions
,
143 os
.path
.join(self
.generated_dir
, "git.h"),
144 export
.get_git_header()
147 if hasattr(self
.soc
, "sdram"):
148 from litedram
.init
import get_sdram_phy_c_header
149 write_to_file(os
.path
.join(self
.generated_dir
, "sdram_phy.h"),
150 get_sdram_phy_c_header(
151 self
.soc
.sdram
.controller
.settings
.phy
,
152 self
.soc
.sdram
.controller
.settings
.timing
))
154 def _generate_csr_map(self
):
155 if self
.csr_json
is not None:
156 csr_dir
= os
.path
.dirname(os
.path
.realpath(self
.csr_json
))
157 os
.makedirs(csr_dir
, exist_ok
=True)
158 write_to_file(self
.csr_json
, export
.get_csr_json(self
.soc
.csr_regions
, self
.soc
.constants
, self
.soc
.mem_regions
))
160 if self
.csr_csv
is not None:
161 csr_dir
= os
.path
.dirname(os
.path
.realpath(self
.csr_csv
))
162 os
.makedirs(csr_dir
, exist_ok
=True)
163 write_to_file(self
.csr_csv
, export
.get_csr_csv(self
.soc
.csr_regions
, self
.soc
.constants
, self
.soc
.mem_regions
))
165 if self
.csr_svd
is not None:
166 svd_dir
= os
.path
.dirname(os
.path
.realpath(self
.csr_svd
))
167 os
.makedirs(svd_dir
, exist_ok
=True)
168 write_to_file(self
.csr_svd
, export
.get_csr_svd(self
.soc
))
170 def _generate_mem_region_map(self
):
171 if self
.memory_x
is not None:
172 memory_x_dir
= os
.path
.dirname(os
.path
.realpath(self
.memory_x
))
173 os
.makedirs(memory_x_dir
, exist_ok
=True)
174 write_to_file(self
.memory_x
, export
.get_memory_x(self
.soc
))
176 def _prepare_rom_software(self
):
177 for name
, src_dir
in self
.software_packages
:
178 dst_dir
= os
.path
.join(self
.software_dir
, name
)
179 os
.makedirs(dst_dir
, exist_ok
=True)
181 def _generate_rom_software(self
, compile_bios
=True):
182 for name
, src_dir
in self
.software_packages
:
183 if name
== "bios" and not compile_bios
:
186 dst_dir
= os
.path
.join(self
.software_dir
, name
)
187 makefile
= os
.path
.join(src_dir
, "Makefile")
188 if self
.compile_software
:
189 subprocess
.check_call(["make", "-C", dst_dir
, "-f", makefile
])
191 def _initialize_rom_software(self
):
192 bios_file
= os
.path
.join(self
.software_dir
, "bios", "bios.bin")
193 bios_data
= soc_core
.get_mem_data(bios_file
, self
.soc
.cpu
.endianness
)
194 self
.soc
.initialize_rom(bios_data
)
196 def build(self
, **kwargs
):
197 self
.soc
.platform
.output_dir
= self
.output_dir
198 os
.makedirs(self
.gateware_dir
, exist_ok
=True)
199 os
.makedirs(self
.software_dir
, exist_ok
=True)
203 self
._generate
_includes
()
204 self
._generate
_csr
_map
()
205 self
._generate
_mem
_region
_map
()
206 if self
.soc
.cpu_type
is not None:
207 if self
.soc
.cpu
.use_rom
:
208 self
._prepare
_rom
_software
()
209 self
._generate
_rom
_software
(not self
.soc
.integrated_rom_initialized
)
210 if self
.soc
.integrated_rom_size
and self
.compile_software
:
211 if not self
.soc
.integrated_rom_initialized
:
212 self
._initialize
_rom
_software
()
214 if "run" not in kwargs
:
215 kwargs
["run"] = self
.compile_gateware
216 vns
= self
.soc
.build(build_dir
=self
.gateware_dir
, **kwargs
)
217 self
.soc
.do_exit(vns
=vns
)
221 def builder_args(parser
):
222 parser
.add_argument("--output-dir", default
=None,
223 help="base output directory for generated "
224 "source files and binaries (customizable "
225 "with --{gateware,software,include,generated}-dir)")
226 parser
.add_argument("--gateware-dir", default
=None,
227 help="output directory for gateware files")
228 parser
.add_argument("--software-dir", default
=None,
229 help="base output directory for software files")
230 parser
.add_argument("--include-dir", default
=None,
231 help="output directory for header files")
232 parser
.add_argument("--generated-dir", default
=None,
233 help="output directory for various generated files")
234 parser
.add_argument("--no-compile-software", action
="store_true",
235 help="do not compile the software, only generate "
236 "build infrastructure")
237 parser
.add_argument("--no-compile-gateware", action
="store_true",
238 help="do not compile the gateware, only generate "
239 "HDL source files and build scripts")
240 parser
.add_argument("--csr-csv", default
=None,
241 help="store CSR map in CSV format into the "
243 parser
.add_argument("--csr-json", default
=None,
244 help="store CSR map in JSON format into the "
246 parser
.add_argument("--csr-svd", default
=None,
247 help="store CSR map in SVD format into the "
249 parser
.add_argument("--memory-x", default
=None,
250 help="store Mem regions in memory-x format into the "
254 def builder_argdict(args
):
256 "output_dir": args
.output_dir
,
257 "gateware_dir": args
.gateware_dir
,
258 "software_dir": args
.software_dir
,
259 "include_dir": args
.include_dir
,
260 "generated_dir": args
.generated_dir
,
261 "compile_software": not args
.no_compile_software
,
262 "compile_gateware": not args
.no_compile_gateware
,
263 "csr_csv": args
.csr_csv
,
264 "csr_json": args
.csr_json
,
265 "csr_svd": args
.csr_svd
,
266 "memory_x": args
.memory_x
,