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
= [
36 soc_directory
= os
.path
.abspath(os
.path
.join(os
.path
.dirname(__file__
), ".."))
39 def _makefile_escape(s
):
40 return s
.replace("\\", "\\\\")
44 def __init__(self
, soc
,
50 compile_software
= True,
51 compile_gateware
= True,
59 # From Python doc: makedirs() will become confused if the path elements to create include '..'
60 self
.output_dir
= os
.path
.abspath(output_dir
or os
.path
.join("build", 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
):
95 "COMPILER_RT_DIRECTORY",
96 get_data_mod("software", "compiler_rt").data_location
)
97 define("SOC_DIRECTORY", soc_directory
)
98 variables_contents
.append("export BUILDINC_DIRECTORY\n")
99 define("BUILDINC_DIRECTORY", self
.include_dir
)
100 for name
, src_dir
in self
.software_packages
:
101 define(name
.upper() + "_DIRECTORY", src_dir
)
103 if self
.bios_options
is not None:
104 for option
in self
.bios_options
:
108 os
.path
.join(self
.generated_dir
, "variables.mak"),
109 "".join(variables_contents
))
111 os
.path
.join(self
.generated_dir
, "output_format.ld"),
112 export
.get_linker_output_format(self
.soc
.cpu
))
114 os
.path
.join(self
.generated_dir
, "regions.ld"),
115 export
.get_linker_regions(self
.soc
.mem_regions
))
118 os
.path
.join(self
.generated_dir
, "mem.h"),
119 export
.get_mem_header(self
.soc
.mem_regions
))
121 os
.path
.join(self
.generated_dir
, "soc.h"),
122 export
.get_soc_header(self
.soc
.constants
))
124 os
.path
.join(self
.generated_dir
, "csr.h"),
125 export
.get_csr_header(
126 regions
= self
.soc
.csr_regions
,
127 constants
= self
.soc
.constants
,
128 csr_base
= self
.soc
.mem_regions
['csr'].origin
132 os
.path
.join(self
.generated_dir
, "git.h"),
133 export
.get_git_header()
136 if hasattr(self
.soc
, "sdram"):
137 from litedram
.init
import get_sdram_phy_c_header
138 write_to_file(os
.path
.join(self
.generated_dir
, "sdram_phy.h"),
139 get_sdram_phy_c_header(
140 self
.soc
.sdram
.controller
.settings
.phy
,
141 self
.soc
.sdram
.controller
.settings
.timing
))
143 def _generate_csr_map(self
):
144 if self
.csr_json
is not None:
145 csr_dir
= os
.path
.dirname(os
.path
.realpath(self
.csr_json
))
146 os
.makedirs(csr_dir
, exist_ok
=True)
147 write_to_file(self
.csr_json
, export
.get_csr_json(self
.soc
.csr_regions
, self
.soc
.constants
, self
.soc
.mem_regions
))
149 if self
.csr_csv
is not None:
150 csr_dir
= os
.path
.dirname(os
.path
.realpath(self
.csr_csv
))
151 os
.makedirs(csr_dir
, exist_ok
=True)
152 write_to_file(self
.csr_csv
, export
.get_csr_csv(self
.soc
.csr_regions
, self
.soc
.constants
, self
.soc
.mem_regions
))
154 if self
.csr_svd
is not None:
155 svd_dir
= os
.path
.dirname(os
.path
.realpath(self
.csr_svd
))
156 os
.makedirs(svd_dir
, exist_ok
=True)
157 write_to_file(self
.csr_svd
, export
.get_csr_svd(self
.soc
))
159 def _generate_mem_region_map(self
):
160 if self
.memory_x
is not None:
161 memory_x_dir
= os
.path
.dirname(os
.path
.realpath(self
.memory_x
))
162 os
.makedirs(memory_x_dir
, exist_ok
=True)
163 write_to_file(self
.memory_x
, export
.get_memory_x(self
.soc
))
165 def _prepare_rom_software(self
):
166 for name
, src_dir
in self
.software_packages
:
167 dst_dir
= os
.path
.join(self
.software_dir
, name
)
168 os
.makedirs(dst_dir
, exist_ok
=True)
170 def _generate_rom_software(self
, compile_bios
=True):
171 for name
, src_dir
in self
.software_packages
:
172 if name
== "bios" and not compile_bios
:
175 dst_dir
= os
.path
.join(self
.software_dir
, name
)
176 makefile
= os
.path
.join(src_dir
, "Makefile")
177 if self
.compile_software
:
178 subprocess
.check_call(["make", "-C", dst_dir
, "-f", makefile
])
180 def _initialize_rom_software(self
):
181 bios_file
= os
.path
.join(self
.software_dir
, "bios", "bios.bin")
182 bios_data
= soc_core
.get_mem_data(bios_file
, self
.soc
.cpu
.endianness
)
183 self
.soc
.initialize_rom(bios_data
)
185 def build(self
, **kwargs
):
186 self
.soc
.platform
.output_dir
= self
.output_dir
187 os
.makedirs(self
.gateware_dir
, exist_ok
=True)
188 os
.makedirs(self
.software_dir
, exist_ok
=True)
192 self
._generate
_includes
()
193 self
._generate
_csr
_map
()
194 self
._generate
_mem
_region
_map
()
195 if self
.soc
.cpu_type
is not None:
196 if self
.soc
.cpu
.use_rom
:
197 self
._prepare
_rom
_software
()
198 self
._generate
_rom
_software
(not self
.soc
.integrated_rom_initialized
)
199 if self
.soc
.integrated_rom_size
and self
.compile_software
:
200 if not self
.soc
.integrated_rom_initialized
:
201 self
._initialize
_rom
_software
()
203 if "run" not in kwargs
:
204 kwargs
["run"] = self
.compile_gateware
205 vns
= self
.soc
.build(build_dir
=self
.gateware_dir
, **kwargs
)
206 self
.soc
.do_exit(vns
=vns
)
210 def builder_args(parser
):
211 parser
.add_argument("--output-dir", default
=None,
212 help="base output directory for generated "
213 "source files and binaries (customizable "
214 "with --{gateware,software,include,generated}-dir)")
215 parser
.add_argument("--gateware-dir", default
=None,
216 help="output directory for gateware files")
217 parser
.add_argument("--software-dir", default
=None,
218 help="base output directory for software files")
219 parser
.add_argument("--include-dir", default
=None,
220 help="output directory for header files")
221 parser
.add_argument("--generated-dir", default
=None,
222 help="output directory for various generated files")
223 parser
.add_argument("--no-compile-software", action
="store_true",
224 help="do not compile the software, only generate "
225 "build infrastructure")
226 parser
.add_argument("--no-compile-gateware", action
="store_true",
227 help="do not compile the gateware, only generate "
228 "HDL source files and build scripts")
229 parser
.add_argument("--csr-csv", default
=None,
230 help="store CSR map in CSV format into the "
232 parser
.add_argument("--csr-json", default
=None,
233 help="store CSR map in JSON format into the "
235 parser
.add_argument("--csr-svd", default
=None,
236 help="store CSR map in SVD format into the "
238 parser
.add_argument("--memory-x", default
=None,
239 help="store Mem regions in memory-x format into the "
243 def builder_argdict(args
):
245 "output_dir": args
.output_dir
,
246 "gateware_dir": args
.gateware_dir
,
247 "software_dir": args
.software_dir
,
248 "include_dir": args
.include_dir
,
249 "generated_dir": args
.generated_dir
,
250 "compile_software": not args
.no_compile_software
,
251 "compile_gateware": not args
.no_compile_gateware
,
252 "csr_csv": args
.csr_csv
,
253 "csr_json": args
.csr_json
,
254 "csr_svd": args
.csr_svd
,
255 "memory_x": args
.memory_x
,