cores/cpu/zynq7000: improve methods to pass provide/pass configuration to PS7.

User can now only use set_ps7 and provides the .xci file, preset file or/and additional configuration:

To use a .xci file, in the design do:
self.cpu.set_ps7(xci="ps7.xci")

To use a preset:
self.cpu.set_ps7(preset="preset_name")

To use a config dict:
self.cpu.set_ps7(name="ps7_name", config={"param0": "0", "param1": "1"})

It's also possible to use preset and then pass and additionnal config dict:
self.cpu.set_ps7(preset="preset_name")
self.cpu.add_ps7_config({"param0": "0", "param1": "1"})
or all at once:
self.cpu.set_ps7(preset="preset_name", config={"param0": "0", "param1": "1"})
This commit is contained in:
Florent Kermarrec 2020-11-30 11:30:48 +01:00
parent 30e8773819
commit 18f66a79f2
1 changed files with 50 additions and 28 deletions

View File

@ -47,8 +47,10 @@ class Zynq7000(CPU):
self.clock_domains.cd_ps7 = ClockDomain() self.clock_domains.cd_ps7 = ClockDomain()
# PS7 (Minimal) ---------------------------------------------------------------------------- # PS7 (Minimal) ----------------------------------------------------------------------------
ps7_rst_n = Signal() self.ps7_name = None
ps7_ddram_pads = platform.request("ps7_ddram") self.ps7_tcl = []
ps7_rst_n = Signal()
ps7_ddram_pads = platform.request("ps7_ddram")
self.cpu_params = dict( self.cpu_params = dict(
# Clk/Rst # Clk/Rst
io_PS_CLK = platform.request("ps7_clk"), io_PS_CLK = platform.request("ps7_clk"),
@ -139,30 +141,46 @@ class Zynq7000(CPU):
if ps7_sdio0_wp_pads is not None: if ps7_sdio0_wp_pads is not None:
self.cpu_params.update(i_SDIO0_WP = ps7_sdio0_wp_pads.wp) self.cpu_params.update(i_SDIO0_WP = ps7_sdio0_wp_pads.wp)
def set_ps7_xci(self, ps7_xci): def set_ps7_xci(self, xci):
self.ps7_xci = ps7_xci # Add .xci as Vivado IP and set ps7_name from .xci filename.
self.platform.add_ip(ps7_xci) self.ps7_xci = xci
self.ps7_name = os.path.splitext(os.path.basename(xci))[0]
self.platform.add_ip(xci)
def set_ps7_config(self): def add_ps7_config(self, config):
ps7_name = f"{self.platform.name}_ps7" # Check that PS7 has been set.
tcl = [] if self.ps7_name is None:
tcl.append(f"set ps7 [create_ip -vendor xilinx.com -name processing_system7 -module_name {ps7_name}]") raise Exception("Please set PS7 with set_ps7 method first.")
# Config must be provided as a config, value dict.
assert isinstance(config, dict)
# Add configs to PS7.
self.ps7_tcl.append("set_property -dict [list \\")
for config, value in config.items():
self.ps7_tcl.append("CONFIG.{} {} \\".format(config, '{{' + value + '}}'))
self.ps7_tcl.append(f"] [get_ips {self.ps7_name}]")
if hasattr(self.platform, "ps7_preset") and self.platform.ps7_preset: def set_ps7(self, name=None, xci=None, preset=None, config=None):
tcl.append("set_property -dict [list CONFIG.preset {}] [get_ips {}]".format( # Check that PS7 has not already been set.
'{{' + self.platform.ps7_preset + '}}', ps7_name)) if self.ps7_name is not None:
raise Exception(f"PS7 has already been set to {self.ps7_name}.")
self.ps7_name = preset if name is None else name
if hasattr(self.platform, "ps7_config") and self.platform.ps7_config: # User should provide an .xci file, preset_name or config dict but not all at once.
tcl.append("set_property -dict [list \\") if (xci is not None) and (preset is not None):
for config, value in self.platform.ps7_config.items(): raise Exception("PS7 .xci and preset specified, please only provide one.")
tcl.append("CONFIG.{} {} \\".format(config, '{{' + value + '}}'))
tcl.append(f"] [get_ips {ps7_name}]")
tcl += [f"upgrade_ip [get_ips {ps7_name}]", # User provides an .xci file...
f"generate_target all [get_ips {ps7_name}]", if xci is not None:
f"synth_ip [get_ips {ps7_name}]" self.set_ps7_xci(xci)
]
self.platform.toolchain.pre_synthesis_commands += tcl # User provides a preset or/and config
else:
self.ps7_tcl.append(f"set ps7 [create_ip -vendor xilinx.com -name processing_system7 -module_name {self.ps7_name}]")
if preset is not None:
assert isinstance(preset, str)
self.ps7_tcl.append("set_property -dict [list CONFIG.preset {}] [get_ips {}]".format("{{" + preset + "}}", self.ps7_name))
if config is not None:
self.add_ps7_config(config)
# AXI GP Master -------------------------------------------------------------------------------- # AXI GP Master --------------------------------------------------------------------------------
@ -296,9 +314,13 @@ class Zynq7000(CPU):
platform.add_ip(os.path.join("ip", self.ps7)) platform.add_ip(os.path.join("ip", self.ps7))
def do_finalize(self): def do_finalize(self):
if hasattr(self, "ps7_xci"): if self.ps7_name is None:
ps7_name = os.path.splitext(os.path.basename(self.ps7_xci))[0] raise Exception("PS7 must be set with set_ps7 or set_ps7_xci methods.")
else: if len(self.ps7_tcl):
self.set_ps7_config() self.ps7_tcl += [
ps7_name = self.platform.name + "_ps7" f"upgrade_ip [get_ips {self.ps7_name}]",
self.specials += Instance(ps7_name, **self.cpu_params) f"generate_target all [get_ips {self.ps7_name}]",
f"synth_ip [get_ips {self.ps7_name}]"
]
self.platform.toolchain.pre_synthesis_commands += self.ps7_tcl
self.specials += Instance(self.ps7_name, **self.cpu_params)