From 1f30c3fbfbb0fcbbd6964d5c9b186ea26d2131ea Mon Sep 17 00:00:00 2001
From: auphelia <jakobapk@web.de>
Date: Thu, 9 Apr 2020 17:21:19 +0100
Subject: [PATCH] [StreamingFIFO] Remove functions that would overwrite
 functions for npysim code generation

---
 .../custom_op/fpgadataflow/streamingfifo.py   |  16 +-
 .../fpgadataflow/insert_fifo.py               | 149 ++++++++++++++++++
 2 files changed, 153 insertions(+), 12 deletions(-)
 create mode 100644 src/finn/transformation/fpgadataflow/insert_fifo.py

diff --git a/src/finn/custom_op/fpgadataflow/streamingfifo.py b/src/finn/custom_op/fpgadataflow/streamingfifo.py
index 75f668c71..8fcb1fe43 100644
--- a/src/finn/custom_op/fpgadataflow/streamingfifo.py
+++ b/src/finn/custom_op/fpgadataflow/streamingfifo.py
@@ -95,7 +95,7 @@ class StreamingFIFO(HLSCustomOp):
 
         # empty code gen dictionary for new entries
         self.code_gen_dict.clear()
-        self.code_gen_dict["$TOPNAME$"] = ["top_{}".format(self.onnx_node.name)]
+        self.code_gen_dict["$TOPNAME$"] = ["{}".format(self.onnx_node.name)]
         self.code_gen_dict["$LAYER_NAME$"] = [
             "{}_{}".format(self.onnx_node.name, self.onnx_node.name)
         ]
@@ -112,9 +112,7 @@ 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, "top_{}.v".format(self.onnx_node.name)), "w",
-        )
+        f = open(os.path.join(code_gen_dir, "{}.v".format(self.onnx_node.name)), "w",)
         f.write(template)
         f.close()
         self.code_gen_dict.clear()
@@ -124,7 +122,7 @@ class StreamingFIFO(HLSCustomOp):
         # prepare the IP packaging tcl template
         template = templates.ip_package_tcl
         self.code_gen_dict.clear()
-        self.code_gen_dict["$TOPNAME$"] = ["top_{}".format(self.onnx_node.name)]
+        self.code_gen_dict["$TOPNAME$"] = ["{}".format(self.onnx_node.name)]
         self.code_gen_dict["$VERILOG_DIR$"] = [code_gen_dir]
         for key in self.code_gen_dict:
             # transform list into long string separated by '\n'
@@ -151,12 +149,6 @@ class StreamingFIFO(HLSCustomOp):
         self.set_nodeattr("ip_vlnv", vlnv)
         self.code_gen_dict.clear()
 
-    def code_generation_npysim(self, model):
-        pass
-
-    def compile_singlenode_code(self):
-        pass
-
     def get_normal_input_shape(self):
         depth = self.get_nodeattr("depth")
         assert (
@@ -233,7 +225,7 @@ class StreamingFIFO(HLSCustomOp):
                 os.path.join(code_gen_dir, "input_0.npy"), reshaped_input,
             )
             verilog_file = os.path.join(
-                code_gen_dir, "top_{}.v".format(self.onnx_node.name)
+                code_gen_dir, "{}.v".format(self.onnx_node.name)
             )
             if os.path.isfile(verilog_file):
                 nbits = self.get_instream_width(axi_strm_padding=True)
diff --git a/src/finn/transformation/fpgadataflow/insert_fifo.py b/src/finn/transformation/fpgadataflow/insert_fifo.py
new file mode 100644
index 000000000..c7efb95c8
--- /dev/null
+++ b/src/finn/transformation/fpgadataflow/insert_fifo.py
@@ -0,0 +1,149 @@
+from onnx import TensorProto
+from onnx import helper as oh
+
+from finn.custom_op.registry import getCustomOp
+from finn.transformation import Transformation
+from finn.util.fpgadataflow import is_fpgadataflow_node
+
+
+def _is_fifo_node(node):
+    if node.op_type == "StreamingFIFO":
+        return True
+    else:
+        return False
+
+
+def _suitable_node(node):
+    if node is not None:
+        if is_fpgadataflow_node(node) is True:
+            if _is_fifo_node(node) is False:
+                return True
+            else:
+                return False
+        else:
+            return False
+    else:
+        return False
+
+
+class InsertFIFO(Transformation):
+    """Ensure that the graph is terminated with a TLastMarker node, inserting
+    one if necessary."""
+
+    def __init__(self):
+        super().__init__()
+
+    def apply(self, model):
+        # default depth for FIFOs
+        default_depth = 2
+        graph = model.graph
+        node_ind = -1
+        graph_modified = False
+        for n in graph.node:
+            node_ind += 1
+            if _suitable_node(n):
+                n_output = n.output[0]
+                consumer = model.find_consumer(n_output)
+                if _suitable_node(consumer) is True:
+                    graph_modified = True
+                    n0 = getCustomOp(n)
+                    # determine fifo node attributes
+                    fld_shape = n0.get_folded_output_shape()
+                    dtype = n0.get_output_datatype()
+
+                    # create fifo node
+                    fifo_output_tensor = oh.make_tensor_value_info(
+                        model.make_new_valueinfo_name(),
+                        TensorProto.FLOAT,
+                        n0.get_normal_output_shape(),
+                    )
+                    graph.value_info.append(fifo_output_tensor)
+
+                    fifo_node = oh.make_node(
+                        "StreamingFIFO",
+                        [n_output],
+                        [fifo_output_tensor.name],
+                        domain="finn",
+                        backend="fpgadataflow",
+                        depth=default_depth,
+                        folded_shape=fld_shape,
+                        dataType=str(dtype.name),
+                    )
+                    # insert fifo
+                    graph.node.insert(node_ind + 1, fifo_node)
+
+                    # set fifo output tensor as new input tensor of second node
+                    consumer.input[0] = fifo_output_tensor.name
+
+        if graph_modified is False:
+            # insert FIFO as first node
+            if graph.node[0].op_type != "StreamingFIFO":
+                n = graph.node[0]
+                n_input = n.input[0]
+                n0 = getCustomOp(n)
+                # determine fifo node attributes
+                fld_shape = n0.get_folded_input_shape()
+                dtype = n0.get_input_datatype()
+
+                # create fifo node
+                fifo_output_tensor = oh.make_tensor_value_info(
+                    model.make_new_valueinfo_name(),
+                    TensorProto.FLOAT,
+                    n0.get_normal_input_shape(),
+                )
+                graph.value_info.append(fifo_output_tensor)
+
+                fifo_node = oh.make_node(
+                    "StreamingFIFO",
+                    [n_input],
+                    [fifo_output_tensor.name],
+                    domain="finn",
+                    backend="fpgadataflow",
+                    depth=default_depth,
+                    folded_shape=fld_shape,
+                    dataType=str(dtype.name),
+                )
+                # insert fifo
+                graph.node.insert(0, fifo_node)
+
+                # set fifo output tensor as new input tensor of second node
+                n.input[0] = fifo_output_tensor.name
+
+            # insert FIFO as first node
+            if graph.node[-1].op_type != "StreamingFIFO":
+                n = graph.node[-1]
+                assert (
+                    n.op_type != "TLastMarker"
+                ), """Insert tlast marker should be done
+                    after inserting the FIFOs"""
+                graph_out_name = graph.output[0].name
+                n0 = getCustomOp(n)
+                # determine fifo node attributes
+                fld_shape = n0.get_folded_output_shape()
+                dtype = n0.get_output_datatype()
+
+                # create fifo node
+                fifo_input_tensor = oh.make_tensor_value_info(
+                    model.make_new_valueinfo_name(),
+                    TensorProto.FLOAT,
+                    n0.get_normal_output_shape(),
+                )
+                graph.value_info.append(fifo_input_tensor)
+
+                fifo_node = oh.make_node(
+                    "StreamingFIFO",
+                    [fifo_input_tensor.name],
+                    [graph_out_name],
+                    domain="finn",
+                    backend="fpgadataflow",
+                    depth=default_depth,
+                    folded_shape=fld_shape,
+                    dataType=str(dtype.name),
+                )
+                # insert fifo
+                graph.node.append(fifo_node)
+
+                # set fifo output tensor as new input tensor of second node
+                n.output[0] = fifo_input_tensor.name
+
+        return (model, graph_modified)
-- 
GitLab