From a9c7e5e46d5682a1ebcebb3d0bb26e13ea19678a Mon Sep 17 00:00:00 2001 From: auphelia <jakobapk@web.de> Date: Tue, 28 Apr 2020 18:02:16 +0100 Subject: [PATCH] [StreamingFIFO] Change functions to fit new rtlsim flow --- .../custom_op/fpgadataflow/streamingfifo.py | 83 ++++++++++--------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/src/finn/custom_op/fpgadataflow/streamingfifo.py b/src/finn/custom_op/fpgadataflow/streamingfifo.py index 8fcb1fe43..9a68bd817 100644 --- a/src/finn/custom_op/fpgadataflow/streamingfifo.py +++ b/src/finn/custom_op/fpgadataflow/streamingfifo.py @@ -30,7 +30,6 @@ import numpy as np from shutil import copy import subprocess -from pyverilator import PyVerilator from finn.custom_op.fpgadataflow import HLSCustomOp from finn.core.datatype import DataType from onnx import TensorProto, helper @@ -88,10 +87,14 @@ class StreamingFIFO(HLSCustomOp): def code_generation_ipgen(self, model, fpgapart, clk): code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen") - # copy Q_srl.v from finn-rtllib to code gen directory + verilog_dir = "{}/project_{}/sol1/impl/verilog".format( + code_gen_dir, self.onnx_node.name + ) + os.makedirs(verilog_dir) + # copy Q_srl.v from finn-rtllib to verilog directory memstream_dir = "/workspace/finn/finn-rtllib/memstream/hdl/" Q_file = os.path.join(memstream_dir, "Q_srl.v") - copy(Q_file, code_gen_dir) + copy(Q_file, verilog_dir) # empty code gen dictionary for new entries self.code_gen_dict.clear() @@ -112,39 +115,47 @@ class StreamingFIFO(HLSCustomOp): # transform list into long string separated by '\n' code_gen_line = "\n".join(self.code_gen_dict[key]) template = template.replace(key, code_gen_line) - f = open(os.path.join(code_gen_dir, "{}.v".format(self.onnx_node.name)), "w",) + f = open( + os.path.join( + verilog_dir, "{}_{}.v".format(self.onnx_node.name, self.onnx_node.name,) + ), + "w", + ) f.write(template) f.close() self.code_gen_dict.clear() def ipgen_singlenode_code(self): code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen") + verilog_dir = "{}/project_{}/sol1/impl/verilog".format( + code_gen_dir, self.onnx_node.name + ) # prepare the IP packaging tcl template template = templates.ip_package_tcl self.code_gen_dict.clear() self.code_gen_dict["$TOPNAME$"] = ["{}".format(self.onnx_node.name)] - self.code_gen_dict["$VERILOG_DIR$"] = [code_gen_dir] + self.code_gen_dict["$VERILOG_DIR$"] = [verilog_dir] for key in self.code_gen_dict: # transform list into long string separated by '\n' code_gen_line = "\n".join(self.code_gen_dict[key]) template = template.replace(key, code_gen_line) - f = open(os.path.join(code_gen_dir, "package_ip.tcl"), "w") + f = open(os.path.join(verilog_dir, "package_ip.tcl"), "w") f.write(template) f.close() # create a shell script and call Vivado to invoke the IP pkg script - make_project_sh = code_gen_dir + "/make_ip.sh" + make_project_sh = verilog_dir + "/make_ip.sh" working_dir = os.environ["PWD"] with open(make_project_sh, "w") as f: f.write("#!/bin/bash \n") - f.write("cd {}\n".format(code_gen_dir)) + f.write("cd {}\n".format(verilog_dir)) f.write("vivado -mode batch -source package_ip.tcl\n") f.write("cd {}\n".format(working_dir)) bash_command = ["bash", make_project_sh] process_compile = subprocess.Popen(bash_command, stdout=subprocess.PIPE) process_compile.communicate() # set ipgen_path and ip_path to point to the new packaged IP - self.set_nodeattr("ipgen_path", code_gen_dir) - self.set_nodeattr("ip_path", code_gen_dir) + self.set_nodeattr("ipgen_path", verilog_dir) + self.set_nodeattr("ip_path", verilog_dir) vlnv = "xilinx.com:hls:%s:1.0" % (self.onnx_node.name) self.set_nodeattr("ip_vlnv", vlnv) self.code_gen_dict.clear() @@ -224,38 +235,30 @@ class StreamingFIFO(HLSCustomOp): np.save( os.path.join(code_gen_dir, "input_0.npy"), reshaped_input, ) - verilog_file = os.path.join( - code_gen_dir, "{}.v".format(self.onnx_node.name) + sim = self.get_rtlsim() + nbits = self.get_instream_width() + inp = npy_to_rtlsim_input( + "{}/input_0.npy".format(code_gen_dir), export_idt, nbits ) - if os.path.isfile(verilog_file): - nbits = self.get_instream_width(axi_strm_padding=True) - inp = npy_to_rtlsim_input( - "{}/input_0.npy".format(code_gen_dir), export_idt, nbits - ) - sim = PyVerilator.build(verilog_file, verilog_path=[code_gen_dir],) - super().reset_rtlsim(sim) - super().toggle_clk(sim) - output = self.rtlsim(sim, inp) - odt = DataType[self.get_nodeattr("dataType")] - target_bits = odt.bitwidth() - packed_bits = self.get_outstream_width(axi_strm_padding=True) - out_npy_path = "{}/output.npy".format(code_gen_dir) - out_shape = self.get_folded_output_shape() - rtlsim_output_to_npy( - output, out_npy_path, odt, out_shape, packed_bits, target_bits - ) - - # load and reshape output - output = np.load(out_npy_path) - oshape = self.get_normal_output_shape() - output = np.asarray([output], dtype=np.float32).reshape(*oshape) - context[node.output[0]] = output + super().reset_rtlsim(sim) + super().toggle_clk(sim) + output = self.rtlsim(sim, inp) + odt = DataType[self.get_nodeattr("dataType")] + target_bits = odt.bitwidth() + packed_bits = self.get_outstream_width() + out_npy_path = "{}/output.npy".format(code_gen_dir) + out_shape = self.get_folded_output_shape() + rtlsim_output_to_npy( + output, out_npy_path, odt, out_shape, packed_bits, target_bits + ) + # load and reshape output + output = np.load(out_npy_path) + oshape = self.get_normal_output_shape() + output = np.asarray([output], dtype=np.float32).reshape(*oshape) + context[node.output[0]] = output - else: - raise Exception( - """Found no verilog files for this node, - did you run the codegen_ipgen transformation?""" - ) + else: + raise Exception("Test") def get_number_output_values(self): folded_oshape = self.get_folded_output_shape() -- GitLab