from typing import List, Optional
from ipCorePackager.constants import DIRECTION
from hwtBuildsystem.common.tcl import CommonTcl
# http://www.xilinx.com/support/documentation/sw_manuals/xilinx2013_1/ug975-vivado-quick-reference.pdf
[docs]
class VivadoFSOpsTCL():
[docs]
@staticmethod
def ls():
return 'ls'
[docs]
@staticmethod
def cd(path: str):
return f'cd {path:s}'
[docs]
@staticmethod
def pwd():
return "pwd"
[docs]
class file():
# file system manipulator
[docs]
@staticmethod
def delete(files, force=True):
if force:
params = '-force'
else:
params = ""
return "file delete %s %s" % (params, ' '.join(files))
[docs]
class VivadoBDOpsTCL():
# [TODO]
# copy_bd_objs / [get_bd_cells {c_accum_0}]
# delete_bd_objs [get_bd_nets c_accum_0_Q] [get_bd_cells c_accum_0]
[docs]
@staticmethod
def open_bd_design(fileName):
return 'open_bd_design {%s}' % fileName
[docs]
@staticmethod
def get_bd_ports(names):
return 'get_bd_ports %s' % (' '.join(names))
[docs]
@staticmethod
def create_bd_port(name: str,
direction: DIRECTION,
typ: Optional[str]=None,
width:Optional[int]=None):
params = []
if direction == DIRECTION.IN:
d = "I"
elif direction == DIRECTION.OUT:
d = "O"
else:
raise Exception()
params.append(f"-dir {d:s}")
if width is not None:
params.append('-from %s -to %d' % ((width - 1), 0))
if typ != None:
params.append(f"-type {typ:s}")
return "create_bd_port %s %s" % (' '.join(params), name)
[docs]
@staticmethod
def make_bd_pins_external(names):
return 'make_bd_pins_external %s' % (' '.join(names))
[docs]
@staticmethod
def get_bd_intf_pins(names: List[str]):
return 'get_bd_intf_pins %s' % (' '.join(names))
[docs]
@staticmethod
def get_bd_intf_ports(names: List[str]):
raise NotImplementedError()
[docs]
@staticmethod
def get_bd_pins(names):
return 'get_bd_pins %s' % (' '.join(names))
[docs]
@staticmethod
def create_bd_design(name: str):
return f'create_bd_design "{name:s}"'
[docs]
@staticmethod
def create_bd_cell(ipId: str, name: str):
return f"create_bd_cell -type ip -vlnv {ipId:s} {name:s}"
[docs]
@staticmethod
def make_wrapper(bdFile: str):
# top has to be at end
return f"make_wrapper -files [get_files {bdFile:s}] -top "
[docs]
@staticmethod
def get_bd_cells(names: List[str]):
return "[get_bd_cells %s]" % ' '.join(names)
[docs]
@staticmethod
def connect_bd_net(src: str, dst: str):
# connect_bd_net [get_bd_pins /eth0/txp] [get_bd_ports txp]
return f"connect_bd_net [{src:s}] [{dst:s}]"
[docs]
@staticmethod
def connect_bd_intf_net(src: str, dst: str):
# connect_bd_intf_net [get_bd_intf_pins eth3a/m_axis_rx] [get_bd_intf_pins eth3a/s_axis_tx]
return f"connect_bd_intf_net [{src:s}] [{dst:s}]"
[docs]
@staticmethod
def regenerate_bd_layout():
return "regenerate_bd_layout"
[docs]
@staticmethod
def save_bd_design():
return "save_bd_design"
[docs]
@staticmethod
def write_bd_tcl(tclFileName, force=False):
"""save bd as independent tcl
bd has to be saved and opened"""
params = []
if force:
params.append('-force')
return "write_bd_tcl %s %s" % (' '.join(params), tclFileName)
[docs]
class VivadoProjectOpsTCL():
[docs]
@staticmethod
def add_files(files, fileSet=None, norecurse=True):
params = []
if norecurse:
params.append('-norecurse')
if fileSet is not None:
params.append(f"-fileset {fileSet:s}")
return 'add_files %s %s' % (' '.join(params), ' '.join(files))
[docs]
@staticmethod
def update_compile_order(fileSet):
return "update_compile_order -fileset %s" % (fileSet)
[docs]
@staticmethod
def generate_target(bdFile):
return 'generate_target all [get_files %s]' % (bdFile)
[docs]
class ip_repo_paths():
[docs]
@staticmethod
def add(repoPath):
"""Multiple add will not cause duplicates"""
return VivadoTCL.set_property("[current_project]", name="ip_repo_paths", value=repoPath)
[docs]
@staticmethod
def remove_files(files):
'''remove from project'''
return "remove_files %s" % (' '.join(files))
[docs]
@staticmethod
def update_ip_catalog(rebuild=True, scan_changes=True):
params = []
if rebuild:
params.append('-rebuild')
if scan_changes:
params.append('-scan_changes')
return "update_ip_catalog %s" % (' '.join(params))
[docs]
@staticmethod
def open_project(filename: str):
return f'open_project {filename:s}'
[docs]
@staticmethod
def close_project():
return 'close_project'
[docs]
@staticmethod
def reset_run(name: str):
return f"reset_run {name:s}"
[docs]
@staticmethod
def launch_runs(names: List[str], workerCnt=None, to_step=None, quiet=False):
assert names
params = []
if to_step is not None:
params.append(f"-to_step {to_step:s}")
if workerCnt is not None:
params.append(f"-jobs {workerCnt:d}")
if quiet:
params.append("-quiet")
if params:
return "launch_runs %s %s" % (' '.join(names), ' '.join(params))
else:
return "launch_runs %s" % (' '.join(names))
[docs]
@staticmethod
def run(jobName, workerCnt=None):
return VivadoTCL.reset_run(jobName) + '\n' + \
VivadoTCL.launch_runs(jobName, workerCnt=workerCnt)
[docs]
@staticmethod
def wait_on_run(run, timeout=None):
params = []
if timeout is not None:
params.append(f"-timeout {timeout:d}")
return "wait_on_run %s %s" % (" ".join(params), run)
[docs]
@staticmethod
def create_project(_dir, name, in_memory=False):
"""
:param in_memory: Create an in-memory project
:param name: Project name
:param _dir: Directory where the project file is saved
"""
params = [name, _dir]
if in_memory:
params.append('-in_memory')
return "create_project %s" % ' '.join(params)
[docs]
class VivadoHdlOps():
[docs]
@staticmethod
def get_ports(portNames):
return "get_ports %s" % (" ".join(portNames))
[docs]
class VivadoTCL(CommonTcl, VivadoFSOpsTCL, VivadoBDOpsTCL, VivadoProjectOpsTCL, VivadoHdlOps):
"""
python wraps for Vivado TCL commands
"""
[docs]
@staticmethod
def set_property(obj, name=None, value=None, valDict=None, valList=None):
if valDict != None:
valueStr = ' '.join(map(lambda kv: "%s {%s}" % (kv[0], str(kv[1])), valDict.items()))
params = f"-dict [list {valueStr:s}]"
elif value != None:
params = "%s %s" % (name, str(value))
elif valList != None:
params = "%s {%s}" % (name, " ".join(valList))
else:
raise Exception()
return f"set_property {params:s} {obj:s}"
[docs]
@staticmethod
def get_property(obj, name):
return f"get_property \"{name:s}\" {obj:s}"
[docs]
@staticmethod
def source(scriptPath, noTrace=True):
cmd = ["source", scriptPath]
if noTrace:
cmd.append('-notrace')
return " ".join(cmd)
[docs]
@staticmethod
def synth_design(top: str, part: str, quiet=False):
if quiet:
params = " -quiet"
else:
params = ""
return f"synth_design -top {top:s} -part {part:s}{params:s}"
[docs]
class group():
[docs]
@staticmethod
def start():
return 'startgroup'
[docs]
@staticmethod
def end():
return 'endgroup'
[docs]
@staticmethod
def start_gui():
return "start_gui"
[docs]
class sim():
# http://www.xilinx.com/support/answers/53351.html
# https://gist.github.com/imrickysu/ad8318229a603f8c7e79
# set_property top test_tb [get_filesets sim_1]
# set_property top_lib xil_defaultlib [get_filesets sim_1]
[docs]
@staticmethod
def launch():
return "launch_simulation"
[docs]
@staticmethod
def close():
return "close_sim"