diff --git a/notebooks/FCLayer_graph.onnx b/notebooks/FCLayer_graph.onnx
index 3599cecaf638c601662035441185576d4889c5f2..629359ee754d15a4a6358f3dbd61f01f9b9d04e2 100644
Binary files a/notebooks/FCLayer_graph.onnx and b/notebooks/FCLayer_graph.onnx differ
diff --git a/notebooks/FINN-CodeGenerationAndCompilation.ipynb b/notebooks/FINN-CodeGenerationAndCompilation.ipynb
index b7283da9d4880f56ac9482fb273cf6f70b3855e3..b65eecffb0b1f72f4ac06505a38cedeeacee5947 100644
--- a/notebooks/FINN-CodeGenerationAndCompilation.ipynb
+++ b/notebooks/FINN-CodeGenerationAndCompilation.ipynb
@@ -13,7 +13,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 2,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -244,7 +244,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 12,
    "metadata": {},
    "outputs": [
     {
@@ -282,7 +282,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 13,
    "metadata": {},
    "outputs": [
     {
@@ -322,14 +322,104 @@
    "source": [
     "<font size=\"3\">An instance of the node is created and checked for the attribute `code_gen_dir`. If the attribute is not set, a temporary directory is created and the attribute is set accordingly. \n",
     "\n",
-    "Then the `code_generation()` function of the instance is called. If an error occurs during this process, this is probably due to the fact that the selected CustomOp is not yet supported.</font>"
+    "Then the `code_generation()` function of the instance is called. If an error occurs during this process, this is probably due to the fact that the selected CustomOp is not yet supported. The following description of the code generation within the CustomOp instance may lead to overlaps with the Jupyter notebook [FINN-CustomOps](FINN-CustomOps.ipynb).\n",
+    "\n",
+    "In order to clarify the individual components involved in code generation, an instance of the node is first created, as in the `_codegen_single_node` function. This is done by looking up the op_type in the [registry](https://github.com/Xilinx/finn/blob/dev/src/finn/custom_op/registry.py) of CustomOps. The instance contains a template for code generation which is shown below.</font>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "        #include \"cnpy.h\"\n",
+      "        #include \"npy2apintstream.hpp\"\n",
+      "        #include <vector>\n",
+      "        #include \"bnn-library.h\"\n",
+      "\n",
+      "        // includes for network parameters\n",
+      "        $GLOBALS$\n",
+      "\n",
+      "        // defines for network parameters\n",
+      "        $DEFINES$\n",
+      "\n",
+      "        int main(){\n",
+      "\n",
+      "        $STREAMDECLARATIONS$\n",
+      "\n",
+      "        $READNPYDATA$\n",
+      "\n",
+      "        $DOCOMPUTE$\n",
+      "\n",
+      "        $DATAOUTSTREAM$\n",
+      "\n",
+      "        $SAVEASCNPY$\n",
+      "\n",
+      "        }\n",
+      "\n",
+      "        \n"
+     ]
+    }
+   ],
+   "source": [
+    "import finn.custom_op.registry as registry\n",
+    "node = FCLayer_node\n",
+    "op_type = FCLayer_node.op_type\n",
+    "inst = registry.custom_op[op_type](node)\n",
+    "print(inst.docompute_template)"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "<font size=\"3\">The following description of the code generation within the CustomOp instance may lead to overlaps with the Jupyter notebook [FINN-CustomOps](FINN-CustomOps.ipynb). </font>"
+    "<font size=\"3\">The template has some general constructs, like the inclusion of bnn-library.h, which contains the references to the finn-hls library, and of cnpy.h and npy2apintstream.hpp, which support the transfer of python numpy arrays in c++. The idea of this template is to replace the variables marked with `$ $` with c++ calls during code generation. Then the template can be written into a .cpp file and be compiled. \n",
+    "\n",
+    "The sub-functions that are called during code generation are shown below.</font>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "    def code_generation(self, model):\n",
+      "        node = self.onnx_node\n",
+      "        self.generate_params(model)\n",
+      "        self.global_includes()\n",
+      "        self.defines()\n",
+      "        self.read_npy_data()\n",
+      "        self.strm_decl()\n",
+      "        self.docompute()\n",
+      "        self.dataoutstrm()\n",
+      "        self.save_as_npy()\n",
+      "\n",
+      "        template = self.docompute_template\n",
+      "\n",
+      "        for key in self.code_gen_dict:\n",
+      "            # transform list into long string separated by '\\n'\n",
+      "            code_gen_line = \"\\n\".join(self.code_gen_dict[key])\n",
+      "            template = template.replace(key, code_gen_line)\n",
+      "        code_gen_dir = self.get_nodeattr(\"code_gen_dir\")\n",
+      "        f = open(os.path.join(code_gen_dir, \"execute_{}.cpp\".format(node.op_type)), \"w\")\n",
+      "        f.write(template)\n",
+      "        f.close()\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "from finn.custom_op.fpgadataflow.streamingfclayer_batch import StreamingFCLayer_Batch\n",
+    "showSrc(StreamingFCLayer_Batch.code_generation)"
    ]
   },
   {