Skip to content
Snippets Groups Projects
Commit aa926d9f authored by Georg Streich's avatar Georg Streich
Browse files

Fix create stitched IP add start and stop steps

parent f28ea543
No related branches found
No related tags found
No related merge requests found
Subproject commit 914a8b520e62adbd4c02a8f50567928fe117d9c9
Subproject commit 8c7e26f98ba8275ca5294fb7186ee8e9666ac786
......@@ -58,10 +58,11 @@ cfg_splits = build.DataflowBuildConfig(
build_cfg.DataflowOutputType.STITCHED_IP,
],
stitched_ip_gen_dcp = True,
# verify_steps = [build_cfg.VerificationStepType.FOLDED_HLS_CPPSIM],
verify_steps = [build_cfg.VerificationStepType.FOLDED_HLS_CPPSIM],
shell_flow_type = build_cfg.ShellFlowType.VITIS_ALVEO,
board = "U55C",
num_boards = 2,
# start_step="step_create_stitched_ip",
save_intermediate_models = True,
)
......
......@@ -192,7 +192,7 @@ def build_dataflow_cfg(model_filename, cfg: DataflowBuildConfig):
def build_distributed_dataflow_cfg(model_filename, cfg: DataflowBuildConfig):
steps = resolve_build_steps(cfg)
steps = resolve_build_steps(cfg, partial=False)
step_names = list(map(lambda x: x.__name__, steps))
# TODO: Not sure if splitting up the config implicitly up is the best way to do this.
......@@ -207,20 +207,26 @@ def build_distributed_dataflow_cfg(model_filename, cfg: DataflowBuildConfig):
global_cfg = deepcopy(cfg)
global_cfg.steps = steps[:step_names.index(split_step) + 1]
local_cfg = deepcopy(cfg)
local_cfg.steps = steps[step_names.index(split_step) + 1:]
if not cfg.save_intermediate_models:
print("save_intermediate_models must be enabled for distributed build")
return -1
if build_dataflow_cfg(model_filename, global_cfg) != 0:
print("Global build failed")
return -1
if not cfg.start_step or cfg.start_step in global_cfg.steps:
if build_dataflow_cfg(model_filename, global_cfg) != 0:
print("Global build failed")
return -1
local_cfg.start_step = None
if cfg.stop_step and cfg.stop_step in global_cfg.steps:
return 0
intermediate_models_dir = cfg.output_dir + "/intermediate_models"
parent_model = ModelWrapper(f"{intermediate_models_dir}/{split_step}.onnx")
local_cfg = deepcopy(cfg)
local_cfg.steps = steps[step_names.index(split_step) + 1:]
sdp_nodes = parent_model.get_nodes_by_op_type("StreamingDataflowPartition")
for i, node in enumerate(sdp_nodes):
local_cfg.output_dir = f"{cfg.output_dir}/{i}"
......
......@@ -393,6 +393,7 @@ class ACCLIn(ACCLOp):
self.code_gen_dict["$PRAGMAS$"] = [
'#pragma HLS INTERFACE axis port=data_from_cclo',
'#pragma HLS INTERFACE axis port=out_{}'.format(self.hls_sname()),
"#pragma HLS INTERFACE s_axilite port=dummy bundle=control",
]
self.code_gen_dict["$PRAGMAS$"].append("#pragma HLS INTERFACE ap_ctrl_none port=return")
......@@ -501,7 +502,7 @@ class ACCLIn(ACCLOp):
def blackboxfunction(self):
self.code_gen_dict["$BLACKBOXFUNCTION$"] = [
'void {}(STREAM<stream_word> &data_from_cclo, hls::stream<ap_uint<{}>> &out_{})'
'void {}(STREAM<stream_word> &data_from_cclo, hls::stream<ap_uint<{}>> &out_{}, ap_uint<32> dummy)'
.format(
self.onnx_node.name,
self.get_outstream_width(),
......@@ -513,6 +514,7 @@ class ACCLIn(ACCLOp):
intf_names = super().get_verilog_top_module_intf_names()
intf_names["s_axis"] = [("data_from_cclo", accl_word_size)]
intf_names["axilite"] = ["s_axi_control"]
return intf_names
......@@ -16,7 +16,7 @@ class AssignPartitionIDs(Transformation):
self.target_platform,
self.ndevices,
# TODO: Remove this after testing
abs_anchors=[(0, [3]), (1, [7])]
abs_anchors=[(0, [1]), (1, [4])]
)
if floorplans is None:
......
......@@ -280,6 +280,8 @@ class CreateStitchedIP(Transformation):
self.connect_cmds.append("assign_bd_address")
def setup_accl_interface(self, model):
tcl = []
has_accl_in = any(node.op_type == "ACCLIn" for node in model.graph.node)
unused_src = None
......@@ -303,8 +305,8 @@ class CreateStitchedIP(Transformation):
tcl.append("set_property name data_to_cclo [get_bd_intf_ports m_axis_0]")
tcl.append("create_bd_intf_port -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 m_axis_0")
# TODO: In a case where we have multiple nodes that access this interface we
# need to add an arbiter for these and the data streams.
# TODO: In a case where we have multiple nodes that access the cmd interface
# we will need to add an arbiter for this.
tcl += [
"make_bd_intf_pins_external [get_bd_intf_pins {}/{}]".format(
accl_out_node.name,
......@@ -315,16 +317,42 @@ class CreateStitchedIP(Transformation):
tcl.append("create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 xlconstant_0")
tcl.append("connect_bd_net [get_bd_pins xlconstant_0/dout] [get_bd_pins {}/wait_for_ack]".format(accl_out_node.name))
unused_sink = "m_axis_0"
else:
tcl.append("create_bd_intf_port -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 cmd_to_cclo")
tcl.append("create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 sts_from_cclo")
tcl.append("create_bd_intf_port -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 data_to_cclo")
unused_sink = "data_to_cclo"
tie_off_cmd = accl_out_node is not None
def tie_off(a, b):
fifo_name = f"tie_off_{a}_{b}"
tcl.append(
f"create_bd_cell -type ip -vlnv xilinx.com:ip:axis_data_fifo:2.0 {fifo_name}"
)
tcl.append(
f"""
connect_bd_intf_net [get_bd_intf_pins {fifo_name}/S_AXIS]
[get_bd_intf_pins {a}]
"""
)
tcl.append(
f"""
connect_bd_intf_net [get_bd_intf_pins {fifo_name}/M_AXIS]
[get_bd_intf_pins {b}]
"""
)
# Tie off the unused ports with a fifo so that they will not get removed from the
# interface of the generated IP.
# tie_off(unused_src, unused_sink)
# if accl_out_node is None:
# tie_off("cmd_to_cclo", "sts_from_cclo")
return tcl
def apply(self, model):
# ensure non-relative readmemh .dat files
......@@ -401,12 +429,10 @@ class CreateStitchedIP(Transformation):
checksum_layers = model.get_nodes_by_op_type("checksum")
self.insert_signature(len(checksum_layers))
if self.accl_interface:
self.setup_accl_interface(model)
# create a temporary folder for the project
prjname = "finn_vivado_stitch_proj"
vivado_stitch_proj_dir = make_build_dir(prefix="vivado_stitch_proj_")
print(vivado_stitch_proj_dir)
model.set_metadata_prop("vivado_stitch_proj", vivado_stitch_proj_dir)
# start building the tcl script
tcl = []
......@@ -423,8 +449,13 @@ class CreateStitchedIP(Transformation):
# create block design and instantiate all layers
block_name = self.ip_name
tcl.append('create_bd_design "%s"' % block_name)
tcl.extend(self.create_cmds)
tcl.extend(self.connect_cmds)
if self.accl_interface:
tcl.extend(self.setup_accl_interface(model))
fclk_mhz = 1 / (self.clk_ns * 0.001)
fclk_hz = fclk_mhz * 1000000
model.set_metadata_prop("clk_ns", str(self.clk_ns))
......@@ -647,9 +678,11 @@ close $ofile
tcl_string = "\n".join(tcl) + "\n"
with open(vivado_stitch_proj_dir + "/make_project.tcl", "w") as f:
f.write(tcl_string)
# create a shell script and call Vivado
make_project_sh = vivado_stitch_proj_dir + "/make_project.sh"
working_dir = os.environ["PWD"]
with open(make_project_sh, "w") as f:
f.write("#!/bin/bash \n")
f.write("cd {}\n".format(vivado_stitch_proj_dir))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment