6594673ddfd437875ca7ded9f8a207096e06893a
5 from misoc
.integration
import cpu_interface
, soc_sdram
, sdram_init
8 __all__
= ["misoc_software_packages", "misoc_directory",
9 "Builder", "builder_args", "builder_argdict"]
12 # in build order (for dependencies)
13 misoc_software_packages
= [
23 misoc_directory
= os
.path
.abspath(os
.path
.join(os
.path
.dirname(__file__
), ".."))
26 def _makefile_escape(s
):
27 return s
.replace("\\", "\\\\")
31 def __init__(self
, soc
, output_dir
=None,
32 compile_software
=True, compile_gateware
=True,
33 gateware_toolchain_path
=None,
36 if output_dir
is None:
37 output_dir
= "misoc_{}_{}".format(
38 soc
.__class
__.__name
__.lower(),
40 # From Python doc: makedirs() will become confused if the path
41 # elements to create include '..'
42 self
.output_dir
= os
.path
.abspath(output_dir
)
43 self
.compile_software
= compile_software
44 self
.compile_gateware
= compile_gateware
45 self
.gateware_toolchain_path
= gateware_toolchain_path
46 self
.csr_csv
= csr_csv
48 self
.software_packages
= []
49 for name
in misoc_software_packages
:
50 self
.add_software_package(
51 name
, os
.path
.join(misoc_directory
, "software", name
))
53 def add_software_package(self
, name
, src_dir
):
54 self
.software_packages
.append((name
, src_dir
))
56 def _generate_includes(self
):
57 cpu_type
= self
.soc
.cpu_type
58 memory_regions
= self
.soc
.get_memory_regions()
59 flash_boot_address
= getattr(self
.soc
, "flash_boot_address", None)
60 csr_regions
= self
.soc
.get_csr_regions()
61 constants
= self
.soc
.get_constants()
62 if isinstance(self
.soc
, soc_sdram
.SoCSDRAM
) and self
.soc
._sdram
_phy
:
63 sdram_phy_settings
= self
.soc
._sdram
_phy
[0].settings
65 sdram_phy_settings
= None
67 buildinc_dir
= os
.path
.join(self
.output_dir
, "software", "include")
68 generated_dir
= os
.path
.join(buildinc_dir
, "generated")
69 os
.makedirs(generated_dir
, exist_ok
=True)
70 with
open(os
.path
.join(generated_dir
, "variables.mak"), "w") as f
:
72 f
.write("{}={}\n".format(k
, _makefile_escape(v
)))
73 for k
, v
in cpu_interface
.get_cpu_mak(cpu_type
):
75 define("MISOC_DIRECTORY", misoc_directory
)
76 define("BUILDINC_DIRECTORY", buildinc_dir
)
77 for name
, src_dir
in self
.software_packages
:
78 define(name
.upper() + "_DIRECTORY", src_dir
)
80 with
open(os
.path
.join(generated_dir
, "output_format.ld"), "w") as f
:
81 f
.write(cpu_interface
.get_linker_output_format(cpu_type
))
82 with
open(os
.path
.join(generated_dir
, "regions.ld"), "w") as f
:
83 f
.write(cpu_interface
.get_linker_regions(memory_regions
))
85 with
open(os
.path
.join(generated_dir
, "mem.h"), "w") as f
:
86 f
.write(cpu_interface
.get_mem_header(memory_regions
, flash_boot_address
))
87 with
open(os
.path
.join(generated_dir
, "csr.h"), "w") as f
:
88 f
.write(cpu_interface
.get_csr_header(csr_regions
, constants
))
90 if sdram_phy_settings
is not None:
91 with
open(os
.path
.join(generated_dir
, "sdram_phy.h"), "w") as f
:
92 f
.write(sdram_init
.get_sdram_phy_header(sdram_phy_settings
))
94 if self
.csr_csv
is not None:
95 with
open(self
.csr_csv
, "w") as f
:
96 f
.write(cpu_interface
.get_csr_csv(csr_regions
))
98 def _generate_software(self
):
99 for name
, src_dir
in self
.software_packages
:
100 dst_dir
= os
.path
.join(self
.output_dir
, "software", name
)
101 os
.makedirs(dst_dir
, exist_ok
=True)
102 src
= os
.path
.join(src_dir
, "Makefile")
103 dst
= os
.path
.join(dst_dir
, "Makefile")
106 except FileNotFoundError
:
109 if self
.compile_software
:
110 subprocess
.check_call(["make", "-C", dst_dir
])
112 def _initialize_rom(self
):
113 bios_file
= os
.path
.join(self
.output_dir
, "software", "bios",
115 if self
.soc
.integrated_rom_size
:
116 with
open(bios_file
, "rb") as boot_file
:
119 w
= boot_file
.read(4)
122 boot_data
.append(struct
.unpack(">I", w
)[0])
123 self
.soc
.initialize_rom(boot_data
)
128 if self
.soc
.integrated_rom_size
and not self
.compile_software
:
129 raise ValueError("Software must be compiled in order to "
130 "intitialize integrated ROM")
132 self
._generate
_includes
()
133 self
._generate
_software
()
134 self
._initialize
_rom
()
135 if self
.gateware_toolchain_path
is None:
138 kwargs
= {"toolchain_path": self
.gateware_toolchain_path
}
139 self
.soc
.build(build_dir
=os
.path
.join(self
.output_dir
, "gateware"),
140 run
=self
.compile_gateware
, **kwargs
)
143 def builder_args(parser
):
144 parser
.add_argument("--output-dir", default
=None,
145 help="output directory for generated "
146 "source files and binaries")
147 parser
.add_argument("--no-compile-software", action
="store_true",
148 help="do not compile the software, only generate "
149 "build infrastructure")
150 parser
.add_argument("--no-compile-gateware", action
="store_true",
151 help="do not compile the gateware, only generate "
152 "HDL source files and build scripts")
153 parser
.add_argument("--gateware-toolchain-path", default
=None,
154 help="set gateware toolchain (ISE, Quartus, etc.) "
156 parser
.add_argument("--csr-csv", default
=None,
157 help="store CSR map in CSV format into the "
161 def builder_argdict(args
):
163 "output_dir": args
.output_dir
,
164 "compile_software": not args
.no_compile_software
,
165 "compile_gateware": not args
.no_compile_gateware
,
166 "gateware_toolchain_path": args
.gateware_toolchain_path
,
167 "csr_csv": args
.csr_csv