From 3e1979bfcac084a198d31a04a2075554989e46a7 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 07:21:15 +0200 Subject: [PATCH 01/32] tutorial notebook --- documentation/tutorial_ics_2021/README.md | 1 + documentation/tutorial_ics_2021/bambu.ipynb | 168 ++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 documentation/tutorial_ics_2021/README.md create mode 100644 documentation/tutorial_ics_2021/bambu.ipynb diff --git a/documentation/tutorial_ics_2021/README.md b/documentation/tutorial_ics_2021/README.md new file mode 100644 index 000000000..6ba3a512e --- /dev/null +++ b/documentation/tutorial_ics_2021/README.md @@ -0,0 +1 @@ +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ferrandi/PandA-bambu/blob/tutorial-2021/documentation/tutorial_ics_2021/bambu.ipynb) \ No newline at end of file diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb new file mode 100644 index 000000000..c6de8e1f0 --- /dev/null +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -0,0 +1,168 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "bambu.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "c97blcSRzP24" + }, + "source": [ + "installation of the required packages" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "LCIFdCihzM6S" + }, + "source": [ + "!echo pip install gdown\n", + "!gdown --id 1TRRbCaOeKFK83DtxQfOuGNA_ZP0RLYSG\n", + "!tar xvf dist.tar.xz -C /\n", + "!apt install verilator\n", + "!apt install iverilog\n", + "!apt install clang-6.0\n", + "!apt install libclang-6.0-dev\n", + "!apt install gcc-7-multilib\n", + "!apt install libbdd-dev" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "qFPREPl2IFbo" + }, + "source": [ + "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "rT_5LDK7IkZQ" + }, + "source": [ + "%%writefile arf.c\n", + "/*\n", + "\n", + " ARF: digital implementation of an auto-regressive lattice filter. The benchmark consists of 16 multiplication and 12 addition operations. The ARF benchmark operates in a loop. This feature is exploited by exercising the simulation as closed loop system.\n", + " \n", + " from:\n", + " N. Mukherjee:\n", + " \"Built-in in Self-Test for Functional Blocks in Data-Path Architectures\", PhD thesis, McGill University, Montreal, 1996.\n", + "\n", + " where it is referred to:\n", + " R. Jain:\n", + " \"High-Level Area-Delay Prediction with Application to Behavioral Synthesis\", PhD thesis, University of Southern California, Los Angeles, Usa, 1989.\n", + " \n", + "\n", + "*/\n", + "\n", + "void arf(int i1,int i2,int i3,int i4,int i5,int i6,\n", + " int *o1,int *o2,int *o3,int *o4,int G1,int G2, int G3, int G4, int GG1, int GG2){\n", + "\n", + " int op1,op2,op3,op4,op5,op6,op7,op8; \n", + " int op9,op10,op11,op12,op13,op14,op15,op16;\n", + " int op17,op18,op19,op20,op21,op22,op23,op24;\n", + " int op25,op26,op27,op28;\n", + " \n", + " op1 = GG1 * i1;\n", + " op2 = GG2 * i2;\n", + " op3 = G1 * i2;\n", + " op4 = G2 * i1;\n", + " op5 = G1 * i3;\n", + " op6 = G2 * i4;\n", + " op7 = G1 * i4;\n", + " op8 = G2 * i3;\n", + " \n", + " op9 = op1 + op2;\n", + " op10 = op3 + op4;\n", + " op11 = op5 + op6;\n", + " op12 = op7 + op8;\n", + "\n", + " op13 = op11 + i5;\n", + " *o1 = op13;\n", + " op14 = i6 + op12;\n", + " *o2 = op14;\n", + " op15 = G1 * op14;\n", + " op16 = op13 * G2;\n", + " op17 = op13 * G1;\n", + " op18 = op14 * G2;\n", + " op19 = op15 * op16;\n", + " op20 = op17 + op18;\n", + " op21 = G1 * op20;\n", + " op22 = op19 * G2;\n", + " op23 = op19 * G1; \n", + " op24 = op20 * G2;\n", + " op25 = op21 + op22;\n", + " op26 = op23 + op24;\n", + " op27 = op9 + op25;\n", + " *o3 = op27;\n", + " op28 = op10 + op26;\n", + " *o4 = op28;\n", + "\n", + "}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "TQ--5UHHCkED" + }, + "source": [ + "%%writefile test.xml\n", + "\n", + "\n", + " \n", + " \n", + "\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "EK66jeKOVcRL" + }, + "source": [ + "!bambu -v2 --print-dot arf.c --simulate --compiler=I386_GCC7" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pjUguz8lZr_2" + }, + "source": [ + "!bambu -v2 --print-dot arf.c --simulate --compiler=I386_CLANG6" + ], + "execution_count": null, + "outputs": [] + } + ] +} From e5586c021fcd30106dd99711956e5491cc1e50ae Mon Sep 17 00:00:00 2001 From: Serena Curzel <48477065+SerenaC94@users.noreply.github.com> Date: Fri, 11 Jun 2021 07:24:00 +0200 Subject: [PATCH 02/32] Update README.md --- documentation/tutorial_ics_2021/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/tutorial_ics_2021/README.md b/documentation/tutorial_ics_2021/README.md index 6ba3a512e..6d942b30b 100644 --- a/documentation/tutorial_ics_2021/README.md +++ b/documentation/tutorial_ics_2021/README.md @@ -1 +1 @@ -[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ferrandi/PandA-bambu/blob/tutorial-2021/documentation/tutorial_ics_2021/bambu.ipynb) \ No newline at end of file +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ferrandi/PandA-bambu/blob/tutorial_2021/documentation/tutorial_ics_2021/bambu.ipynb) From 48629c9d0c3848f1dfc894d1502b1a45c65fab21 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 08:00:58 +0200 Subject: [PATCH 03/32] modified notebook --- documentation/tutorial_ics_2021/bambu.ipynb | 117 ++++++-------------- 1 file changed, 33 insertions(+), 84 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index c6de8e1f0..2eacf8084 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -3,7 +3,7 @@ "nbformat_minor": 0, "metadata": { "colab": { - "name": "bambu.ipynb", + "name": "Copy of bambu.ipynb", "provenance": [], "collapsed_sections": [] }, @@ -13,8 +13,7 @@ }, "language_info": { "name": "python" - }, - "accelerator": "GPU" + } }, "cells": [ { @@ -23,7 +22,9 @@ "id": "c97blcSRzP24" }, "source": [ - "installation of the required packages" + "# **Initial setup**\n", + "\n", + "Install Bambu and required packages:" ] }, { @@ -45,6 +46,15 @@ "execution_count": null, "outputs": [] }, + { + "cell_type": "markdown", + "metadata": { + "id": "FfqJ_WhOiB-A" + }, + "source": [ + "Edit PATH variable:" + ] + }, { "cell_type": "code", "metadata": { @@ -57,101 +67,39 @@ "outputs": [] }, { - "cell_type": "code", + "cell_type": "markdown", "metadata": { - "id": "rT_5LDK7IkZQ" + "id": "St4YkjZRjLWN" }, "source": [ - "%%writefile arf.c\n", - "/*\n", - "\n", - " ARF: digital implementation of an auto-regressive lattice filter. The benchmark consists of 16 multiplication and 12 addition operations. The ARF benchmark operates in a loop. This feature is exploited by exercising the simulation as closed loop system.\n", - " \n", - " from:\n", - " N. Mukherjee:\n", - " \"Built-in in Self-Test for Functional Blocks in Data-Path Architectures\", PhD thesis, McGill University, Montreal, 1996.\n", - "\n", - " where it is referred to:\n", - " R. Jain:\n", - " \"High-Level Area-Delay Prediction with Application to Behavioral Synthesis\", PhD thesis, University of Southern California, Los Angeles, Usa, 1989.\n", - " \n", - "\n", - "*/\n", - "\n", - "void arf(int i1,int i2,int i3,int i4,int i5,int i6,\n", - " int *o1,int *o2,int *o3,int *o4,int G1,int G2, int G3, int G4, int GG1, int GG2){\n", - "\n", - " int op1,op2,op3,op4,op5,op6,op7,op8; \n", - " int op9,op10,op11,op12,op13,op14,op15,op16;\n", - " int op17,op18,op19,op20,op21,op22,op23,op24;\n", - " int op25,op26,op27,op28;\n", - " \n", - " op1 = GG1 * i1;\n", - " op2 = GG2 * i2;\n", - " op3 = G1 * i2;\n", - " op4 = G2 * i1;\n", - " op5 = G1 * i3;\n", - " op6 = G2 * i4;\n", - " op7 = G1 * i4;\n", - " op8 = G2 * i3;\n", - " \n", - " op9 = op1 + op2;\n", - " op10 = op3 + op4;\n", - " op11 = op5 + op6;\n", - " op12 = op7 + op8;\n", - "\n", - " op13 = op11 + i5;\n", - " *o1 = op13;\n", - " op14 = i6 + op12;\n", - " *o2 = op14;\n", - " op15 = G1 * op14;\n", - " op16 = op13 * G2;\n", - " op17 = op13 * G1;\n", - " op18 = op14 * G2;\n", - " op19 = op15 * op16;\n", - " op20 = op17 + op18;\n", - " op21 = G1 * op20;\n", - " op22 = op19 * G2;\n", - " op23 = op19 * G1; \n", - " op24 = op20 * G2;\n", - " op25 = op21 + op22;\n", - " op26 = op23 + op24;\n", - " op27 = op9 + op25;\n", - " *o3 = op27;\n", - " op28 = op10 + op26;\n", - " *o4 = op28;\n", - "\n", - "}" - ], - "execution_count": null, - "outputs": [] + "Clone exercises repository:" + ] }, { "cell_type": "code", "metadata": { - "id": "TQ--5UHHCkED" + "id": "rGIIMMugjEim" }, "source": [ - "%%writefile test.xml\n", - "\n", - "\n", - " \n", - " \n", - "\n" + "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", + "%cd bambu-tutorial\n", + "!ls" ], "execution_count": null, "outputs": [] }, { - "cell_type": "code", + "cell_type": "markdown", "metadata": { - "id": "EK66jeKOVcRL" + "id": "la-zNHdckW4f" }, "source": [ - "!bambu -v2 --print-dot arf.c --simulate --compiler=I386_GCC7" - ], - "execution_count": null, - "outputs": [] + "# **Introduction**\n", + "\n", + "Have a look at the C code for Exercise 1: /content/bambu-tutorial/01-introduction/Exercise1/module.c\n", + "\n", + "Launch bambu:" + ] }, { "cell_type": "code", @@ -159,10 +107,11 @@ "id": "pjUguz8lZr_2" }, "source": [ - "!bambu -v2 --print-dot arf.c --simulate --compiler=I386_CLANG6" + "% cd 01-introduction/Exercise1\n", + "!bambu module.c --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c 2>&1 | tee icrc1.log" ], "execution_count": null, "outputs": [] } ] -} +} \ No newline at end of file From b446eec4eb00bdad3793e9a277e4103dd17af0e7 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 09:09:29 +0200 Subject: [PATCH 04/32] add graphviz to visualize fsm --- documentation/tutorial_ics_2021/README.md | 2 ++ documentation/tutorial_ics_2021/bambu.ipynb | 38 ++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/documentation/tutorial_ics_2021/README.md b/documentation/tutorial_ics_2021/README.md index 6d942b30b..ac89be1a2 100644 --- a/documentation/tutorial_ics_2021/README.md +++ b/documentation/tutorial_ics_2021/README.md @@ -1 +1,3 @@ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ferrandi/PandA-bambu/blob/tutorial_2021/documentation/tutorial_ics_2021/bambu.ipynb) + +Code for the exercises is available at: https://github.com/SerenaC94/bambu-tutorial \ No newline at end of file diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 2eacf8084..75bd87bfa 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -3,7 +3,7 @@ "nbformat_minor": 0, "metadata": { "colab": { - "name": "Copy of bambu.ipynb", + "name": "bambu.ipynb", "provenance": [], "collapsed_sections": [] }, @@ -33,7 +33,7 @@ "id": "LCIFdCihzM6S" }, "source": [ - "!echo pip install gdown\n", + "% pip install gdown\n", "!gdown --id 1TRRbCaOeKFK83DtxQfOuGNA_ZP0RLYSG\n", "!tar xvf dist.tar.xz -C /\n", "!apt install verilator\n", @@ -83,7 +83,7 @@ "source": [ "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", "%cd bambu-tutorial\n", - "!ls" + "%ls" ], "execution_count": null, "outputs": [] @@ -112,6 +112,36 @@ ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "zXTGPFLA1Dmj" + }, + "source": [ + "Inspect the generated files in the explorer tab on the left:\n", + "\n", + "* icrc1.v\n", + "* test_icrc1.xml\n", + "* simulate_icrc1.sh\n", + "* synthesize_Synthesis_icrc1.sh\n", + "\n", + "\n", + "\n", + "Visualize the FSM:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IYUayuTqzb2I" + }, + "source": [ + "from graphviz import Source\n", + "Source.from_file('HLS_output/dot/icrc1/HLS_STGraph.dot')" + ], + "execution_count": null, + "outputs": [] } ] -} \ No newline at end of file +} From b006986fa988bd1b0e4c3baf1362c66ca5d0f7d4 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 09:34:26 +0200 Subject: [PATCH 05/32] introduction section ok --- documentation/tutorial_ics_2021/bambu.ipynb | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 75bd87bfa..11ea4f22d 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -143,5 +143,28 @@ "execution_count": null, "outputs": [] } + ], + { + "cell_type": "markdown", + "metadata": { + "id": "1vnkBTJD-lzY" + }, + "source": [ + "Navigate through the explorer to see the code for other exercises, **edit** this box to execute them:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "IoMlPfH7-wMD" + }, + "source": [ + "% cd ..\n", + "% cd Exercise2\n", + "! ./bambu.sh" + ], + "execution_count": null, + "outputs": [] + } ] } From b65ff050e11cdfb4d0c3446e288856f988a0e8c3 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 12:30:15 +0200 Subject: [PATCH 06/32] all exercises in introduction work, started second section --- documentation/tutorial_ics_2021/bambu.ipynb | 81 +++++++++++++++++++-- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 11ea4f22d..95222e048 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -41,7 +41,11 @@ "!apt install clang-6.0\n", "!apt install libclang-6.0-dev\n", "!apt install gcc-7-multilib\n", - "!apt install libbdd-dev" + "!apt install libbdd-dev\n", + "!apt install autoconf\n", + "!apt install autoconf-archive\n", + "!apt install automake\n", + "!apt install libtool" ], "execution_count": null, "outputs": [] @@ -107,7 +111,7 @@ "id": "pjUguz8lZr_2" }, "source": [ - "% cd 01-introduction/Exercise1\n", + "% cd /content/bambu-tutorial/01-introduction/Exercise1\n", "!bambu module.c --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c 2>&1 | tee icrc1.log" ], "execution_count": null, @@ -142,8 +146,7 @@ ], "execution_count": null, "outputs": [] - } - ], + }, { "cell_type": "markdown", "metadata": { @@ -165,6 +168,74 @@ ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "BZdmA4VKfyzL" + }, + "source": [ + "# **Target selection and tool integration**\n", + "\n", + "Exercise 1: synthesize a module that returns the minimum and maximum value in an array.\n", + "\n", + "Start by modifying the code below:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "paTFkaqqiQBk" + }, + "source": [ + "%cd /content/bambu-tutorial/02-target_customization/Exercise1/" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qk6YNsG6hFS8" + }, + "source": [ + "%%writefile array.c\n", + "void max(int input[10], int * max)\n", + "{\n", + " int local_max = input[0];\n", + " int i = 0;\n", + " for(i = 0; i < 10; i++)\n", + " {\n", + " if(input[i] > local_max)\n", + " {\n", + " local_max = input[i];\n", + " }\n", + " }\n", + " *max = local_max;\n", + "}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "l2LzyiJbhMIs" + }, + "source": [ + "Synthesize with bambu:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ghLrn4d0hOH_" + }, + "source": [ + "! bambu array.c" + ], + "execution_count": null, + "outputs": [] } ] -} +} \ No newline at end of file From 58e0e0cee9ba0b085e548667ecf204dbbe04c0bb Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 14:43:38 +0200 Subject: [PATCH 07/32] second section updated --- documentation/tutorial_ics_2021/bambu.ipynb | 89 +++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 95222e048..81dc91e19 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -236,6 +236,95 @@ ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mJgyQoCPBfAz" + }, + "source": [ + "Exercise 2: write a testbench to test arrays with different elemets and different sizes.\n", + "\n", + "Start by modifying the code below:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_0i7aZLxBwwl" + }, + "source": [ + "%cd ../Exercise2" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "5oOodjt2Bz9P" + }, + "source": [ + "%%writefile test.xml\n", + "\n", + "\n", + " \n", + "" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_n8JLBQYCzIA" + }, + "source": [ + "! bambu module.c --generate-tb=test.xml --simulate -v4" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "cbLOvR1FEFoP" + }, + "source": [ + "Exercise 3: compare simulations across different target platforms and frequencies.\n", + "\n", + "Start from the given command and modify the options appropriately to test the following combinations:\n", + "\n", + "\n", + "* xc4vlx100-10ff1513 – 66MHz\n", + "* 5SGXEA7N2F45C1 – 200MHz\n", + "* xc7vx690t-3ffg1930-VVD – 100MHz\n", + "* xc7vx690t-3ffg1930-VVD – 333MHz\n", + "* xc7vx690t-3ffg1930-VVD – 400MHz\n", + "\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "094IYzP9EVsm" + }, + "source": [ + "%cd ../Exercise3" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "FryYdWLmEh81" + }, + "source": [ + "! bambu module.c --device-name=xc4vlx100-10ff1513 --clock-period=15 --simulate" + ], + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file From 30ab9af6bcb6347bd0b57e3fd49c79786a40f645 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 14:59:52 +0200 Subject: [PATCH 08/32] first three optimization exercises --- documentation/tutorial_ics_2021/bambu.ipynb | 69 +++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 81dc91e19..90f28721c 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -325,6 +325,75 @@ ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IlQDB6nqHqz0" + }, + "source": [ + "# **Optimizations**\n", + "\n", + "Exercise 1: modify Bambu options to evaluate the effect of:\n", + "\n", + "\n", + "* different levels of optimization\n", + "* vectorization\n", + "* inlining\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "YOXiFqzSIDR9" + }, + "source": [ + "%cd /content/bambu-tutorial/03-optimizations/Exercise1/\n", + "! bambu adpcm.c -O0 --simulate" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mJOV50V4IiE2" + }, + "source": [ + "Exercise 2: use the command that yielded the best result in Exercise 1 and verify if SDC scheduling can introduce further improvement" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Qi_ZpIr1IzZ7" + }, + "source": [ + "! bambu adpcm.c -O0 --simulate" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "StGBkKaJJEfr" + }, + "source": [ + "Exercise 3: modify Bambu options to evaluate the effect of different integer division implementations" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "bnEJ4nwuJLfo" + }, + "source": [ + "%cd ../Exercise3\n", + "!bambu dfdiv.c --simulate --clock-period=15 --hls-div=none" + ], + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file From 5df1fe2c96e77035a624ba91385f6da0b9f2191c Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 18:41:21 +0200 Subject: [PATCH 09/32] various fixes, optimization ok --- documentation/tutorial_ics_2021/bambu.ipynb | 158 +++++++++++--------- 1 file changed, 86 insertions(+), 72 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 90f28721c..c56d73406 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -30,42 +30,23 @@ { "cell_type": "code", "metadata": { - "id": "LCIFdCihzM6S" + "id": "rGIIMMugjEim" }, "source": [ - "% pip install gdown\n", - "!gdown --id 1TRRbCaOeKFK83DtxQfOuGNA_ZP0RLYSG\n", - "!tar xvf dist.tar.xz -C /\n", - "!apt install verilator\n", - "!apt install iverilog\n", - "!apt install clang-6.0\n", - "!apt install libclang-6.0-dev\n", - "!apt install gcc-7-multilib\n", - "!apt install libbdd-dev\n", - "!apt install autoconf\n", - "!apt install autoconf-archive\n", - "!apt install automake\n", - "!apt install libtool" + "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", + "%cd bambu-tutorial\n", + "!tar xvf dist.tar.xz -C /" ], "execution_count": null, "outputs": [] }, - { - "cell_type": "markdown", - "metadata": { - "id": "FfqJ_WhOiB-A" - }, - "source": [ - "Edit PATH variable:" - ] - }, { "cell_type": "code", "metadata": { - "id": "qFPREPl2IFbo" + "id": "LCIFdCihzM6S" }, "source": [ - "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" + "!apt install verilator iverilog clang-6.0 libclang-6.0-dev gcc-7-multilib libbdd-dev autoconf autoconf-archive automake libtool" ], "execution_count": null, "outputs": [] @@ -73,21 +54,19 @@ { "cell_type": "markdown", "metadata": { - "id": "St4YkjZRjLWN" + "id": "FfqJ_WhOiB-A" }, "source": [ - "Clone exercises repository:" + "Edit PATH variable:" ] }, { "cell_type": "code", "metadata": { - "id": "rGIIMMugjEim" + "id": "qFPREPl2IFbo" }, "source": [ - "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", - "%cd bambu-tutorial\n", - "%ls" + "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" ], "execution_count": null, "outputs": [] @@ -100,7 +79,7 @@ "source": [ "# **Introduction**\n", "\n", - "Have a look at the C code for Exercise 1: /content/bambu-tutorial/01-introduction/Exercise1/module.c\n", + "Have a look at the C code for **Exercise 1**: /content/bambu-tutorial/01-introduction/Exercise1/module.c\n", "\n", "Launch bambu:" ] @@ -112,7 +91,7 @@ }, "source": [ "% cd /content/bambu-tutorial/01-introduction/Exercise1\n", - "!bambu module.c --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c 2>&1 | tee icrc1.log" + "!bambu icrc.c --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c 2>&1 | tee icrc1.log" ], "execution_count": null, "outputs": [] @@ -162,9 +141,8 @@ "id": "IoMlPfH7-wMD" }, "source": [ - "% cd ..\n", - "% cd Exercise2\n", - "! ./bambu.sh" + "% cd /content/bambu-tutorial/01-introduction/Exercise2\n", + "!./bambu.sh" ], "execution_count": null, "outputs": [] @@ -177,7 +155,7 @@ "source": [ "# **Target selection and tool integration**\n", "\n", - "Exercise 1: synthesize a module that returns the minimum and maximum value in an array.\n", + "**Exercise 1**: synthesize a module that returns the minimum and maximum value in an array.\n", "\n", "Start by modifying the code below:" ] @@ -199,7 +177,7 @@ "id": "Qk6YNsG6hFS8" }, "source": [ - "%%writefile array.c\n", + "%%writefile minmax.c\n", "void max(int input[10], int * max)\n", "{\n", " int local_max = input[0];\n", @@ -232,7 +210,7 @@ "id": "ghLrn4d0hOH_" }, "source": [ - "! bambu array.c" + "!bambu minmax.c" ], "execution_count": null, "outputs": [] @@ -243,22 +221,11 @@ "id": "mJgyQoCPBfAz" }, "source": [ - "Exercise 2: write a testbench to test arrays with different elemets and different sizes.\n", + "**Exercise 2**: write a testbench to test arrays with different elemets and different sizes.\n", "\n", - "Start by modifying the code below:" + "Start by modifying the code below **(change parameter names so that they correspond to function arguments in your code)**:" ] }, - { - "cell_type": "code", - "metadata": { - "id": "_0i7aZLxBwwl" - }, - "source": [ - "%cd ../Exercise2" - ], - "execution_count": null, - "outputs": [] - }, { "cell_type": "code", "metadata": { @@ -280,7 +247,7 @@ "id": "_n8JLBQYCzIA" }, "source": [ - "! bambu module.c --generate-tb=test.xml --simulate -v4" + "!bambu minmax.c --generate-tb=test.xml --simulate" ], "execution_count": null, "outputs": [] @@ -291,7 +258,7 @@ "id": "cbLOvR1FEFoP" }, "source": [ - "Exercise 3: compare simulations across different target platforms and frequencies.\n", + "**Exercise 3**: compare simulations across different target platforms and frequencies.\n", "\n", "Start from the given command and modify the options appropriately to test the following combinations:\n", "\n", @@ -304,24 +271,13 @@ "\n" ] }, - { - "cell_type": "code", - "metadata": { - "id": "094IYzP9EVsm" - }, - "source": [ - "%cd ../Exercise3" - ], - "execution_count": null, - "outputs": [] - }, { "cell_type": "code", "metadata": { "id": "FryYdWLmEh81" }, "source": [ - "! bambu module.c --device-name=xc4vlx100-10ff1513 --clock-period=15 --simulate" + "!bambu minmax.c --device-name=xc4vlx100-10ff1513 --clock-period=15 --simulate" ], "execution_count": null, "outputs": [] @@ -334,7 +290,7 @@ "source": [ "# **Optimizations**\n", "\n", - "Exercise 1: modify Bambu options to evaluate the effect of:\n", + "**Exercise 1**: modify Bambu options to evaluate the effect of:\n", "\n", "\n", "* different levels of optimization\n", @@ -349,7 +305,7 @@ }, "source": [ "%cd /content/bambu-tutorial/03-optimizations/Exercise1/\n", - "! bambu adpcm.c -O0 --simulate" + "!bambu adpcm.c -O0 --simulate" ], "execution_count": null, "outputs": [] @@ -360,7 +316,7 @@ "id": "mJOV50V4IiE2" }, "source": [ - "Exercise 2: use the command that yielded the best result in Exercise 1 and verify if SDC scheduling can introduce further improvement" + "**Exercise 2**: use the command that yielded the best result in Exercise 1 and verify if SDC scheduling can introduce further improvements." ] }, { @@ -369,7 +325,7 @@ "id": "Qi_ZpIr1IzZ7" }, "source": [ - "! bambu adpcm.c -O0 --simulate" + "!bambu adpcm.c -O0 --simulate" ], "execution_count": null, "outputs": [] @@ -380,7 +336,7 @@ "id": "StGBkKaJJEfr" }, "source": [ - "Exercise 3: modify Bambu options to evaluate the effect of different integer division implementations" + "**Exercise 3**: modify Bambu options to evaluate the effect of different integer division implementations." ] }, { @@ -389,11 +345,69 @@ "id": "bnEJ4nwuJLfo" }, "source": [ - "%cd ../Exercise3\n", + "%cd /content/bambu-tutorial/03-optimizations/Exercise3/\n", "!bambu dfdiv.c --simulate --clock-period=15 --hls-div=none" ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "YSRwNv1o2Jqx" + }, + "source": [ + "**Exercise 4**: write C functions that compute the following formula with single precision and double precision data types, experimenting with softfloat and libm implementations.\n", + "\n", + "![formula.png](data:image/png;base64,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)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "mGggAqUu6SJv" + }, + "source": [ + "Start by editing this code and then try different bambu options:" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "C5tEypGc7B0A" + }, + "source": [ + "%cd /content/bambu-tutorial/03-optimizations/Exercise4/" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "LuhiArbj6XnA" + }, + "source": [ + "%%writefile module.c\n", + "#include \n", + "float formula_pow(float a, float b, float c)\n", + "{\n", + " return acosf((powf(a,2) + powf(b,2) - powf(c,2))/(2*a*b));\n", + "}" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "_Rg4Gthy2vDm" + }, + "source": [ + "!bambu module.c -O3 -lm --simulate --top-fname=formula_pow --generate-tb=\"a=3.0,b=4.0,c=5.0\" --speculative-sdc-scheduling --libm-std-rounding --hls-div=none --soft-float" + ], + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file From 202c317b87558ffea3581e2dba4ddb3991421fa4 Mon Sep 17 00:00:00 2001 From: curzel Date: Fri, 11 Jun 2021 18:48:22 +0200 Subject: [PATCH 10/32] revert to old download method --- documentation/tutorial_ics_2021/bambu.ipynb | 40 +++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index c56d73406..e339f5e46 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -30,11 +30,11 @@ { "cell_type": "code", "metadata": { - "id": "rGIIMMugjEim" + "id": "ZoxqLkfA9zqM" }, "source": [ - "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", - "%cd bambu-tutorial\n", + "% pip install gdown\n", + "!gdown --id 1TRRbCaOeKFK83DtxQfOuGNA_ZP0RLYSG\n", "!tar xvf dist.tar.xz -C /" ], "execution_count": null, @@ -51,6 +51,18 @@ "execution_count": null, "outputs": [] }, + { + "cell_type": "code", + "metadata": { + "id": "XHBLNA5L-LGj" + }, + "source": [ + "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", + "%cd bambu-tutorial" + ], + "execution_count": null, + "outputs": [] + }, { "cell_type": "markdown", "metadata": { @@ -408,6 +420,28 @@ ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xbsgMK4D-EYq" + }, + "source": [ + "**USE THIS LATER**" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rGIIMMugjEim" + }, + "source": [ + "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", + "%cd bambu-tutorial\n", + "!tar xvf dist.tar.xz -C /" + ], + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file From 3faa8c75f0d5558714506294389332ed7075f4c1 Mon Sep 17 00:00:00 2001 From: Michele Fiorito Date: Sun, 13 Jun 2021 23:51:10 +0200 Subject: [PATCH 11/32] Installation update Section 4 updated --- documentation/tutorial_ics_2021/bambu.ipynb | 641 +++++++++++++++++--- 1 file changed, 540 insertions(+), 101 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index e339f5e46..123464ffa 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -9,10 +9,8 @@ }, "kernelspec": { "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" + "display_name": "Python 3", + "language": "python" } }, "cells": [ @@ -30,58 +28,380 @@ { "cell_type": "code", "metadata": { - "id": "ZoxqLkfA9zqM" - }, - "source": [ - "% pip install gdown\n", - "!gdown --id 1TRRbCaOeKFK83DtxQfOuGNA_ZP0RLYSG\n", - "!tar xvf dist.tar.xz -C /" - ], - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "LCIFdCihzM6S" - }, - "source": [ - "!apt install verilator iverilog clang-6.0 libclang-6.0-dev gcc-7-multilib libbdd-dev autoconf autoconf-archive automake libtool" - ], - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "code", - "metadata": { - "id": "XHBLNA5L-LGj" + "id": "ZoxqLkfA9zqM", + "tags": [ + "outputPrepend" + ] }, "source": [ + "!echo \"deb http://dk.archive.ubuntu.com/ubuntu/ xenial main universe\" >> /etc/apt/sources.list\n", + "!echo \"deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main\" >> /etc/apt/sources.list\n", + "!apt-get -o Acquire::AllowInsecureRepositories=true update\n", + "!apt-get -o Acquire::AllowInsecureRepositories=true --allow-unauthenticated install -y --no-install-recommends ca-certificates git libbdd-dev iverilog verilator gcc-4.9 gcc-4.9-plugin-dev gcc-4.9-multilib g++-4.9 g++-multilib gcc-multilib gcc-7-plugin-dev g++-multilib clang-6.0 libclang-6.0-dev clang-11 libclang-11-dev\n", "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", - "%cd bambu-tutorial" - ], - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "FfqJ_WhOiB-A" - }, - "source": [ - "Edit PATH variable:" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "qFPREPl2IFbo" - }, - "source": [ + "!tar xf bambu-tutorial/panda-dist.tar.gz -C /\n", "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" ], - "execution_count": null, - "outputs": [] + "execution_count": 1, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "packing liblsan0:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", + "Preparing to unpack .../2-libtsan0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libtsan0:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", + "Preparing to unpack .../3-libcc1-0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libcc1-0:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", + "Preparing to unpack .../4-libatomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libatomic1:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", + "Preparing to unpack .../5-libgomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libgomp1:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", + "Preparing to unpack .../6-libgcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libgcc1:amd64 (1:8.4.0-1ubuntu1~18.04) over (1:8.3.0-26ubuntu1~18.04) ...\n", + "Setting up libgcc1:amd64 (1:8.4.0-1ubuntu1~18.04) ...\n", + "(Reading database ... 15001 files and directories currently installed.)\n", + "Preparing to unpack .../libc6_2.27-3ubuntu1.4_amd64.deb ...\n", + "debconf: unable to initialize frontend: Dialog\n", + "debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)\n", + "debconf: falling back to frontend: Readline\n", + "Unpacking libc6:amd64 (2.27-3ubuntu1.4) over (2.27-3ubuntu1) ...\n", + "Setting up libc6:amd64 (2.27-3ubuntu1.4) ...\n", + "debconf: unable to initialize frontend: Dialog\n", + "debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)\n", + "debconf: falling back to frontend: Readline\n", + "(Reading database ... 15001 files and directories currently installed.)\n", + "Preparing to unpack .../00-ca-certificates_20210119~18.04.1_all.deb ...\n", + "Unpacking ca-certificates (20210119~18.04.1) over (20180409) ...\n", + "Selecting previously unselected package libedit2:amd64.\n", + "Preparing to unpack .../01-libedit2_3.1-20170329-1_amd64.deb ...\n", + "Unpacking libedit2:amd64 (3.1-20170329-1) ...\n", + "Selecting previously unselected package libkrb5support0:amd64.\n", + "Preparing to unpack .../02-libkrb5support0_1.16-2ubuntu0.2_amd64.deb ...\n", + "Unpacking libkrb5support0:amd64 (1.16-2ubuntu0.2) ...\n", + "Selecting previously unselected package libk5crypto3:amd64.\n", + "Preparing to unpack .../03-libk5crypto3_1.16-2ubuntu0.2_amd64.deb ...\n", + "Unpacking libk5crypto3:amd64 (1.16-2ubuntu0.2) ...\n", + "Selecting previously unselected package libkeyutils1:amd64.\n", + "Preparing to unpack .../04-libkeyutils1_1.5.9-9.2ubuntu2_amd64.deb ...\n", + "Unpacking libkeyutils1:amd64 (1.5.9-9.2ubuntu2) ...\n", + "Selecting previously unselected package libkrb5-3:amd64.\n", + "Preparing to unpack .../05-libkrb5-3_1.16-2ubuntu0.2_amd64.deb ...\n", + "Unpacking libkrb5-3:amd64 (1.16-2ubuntu0.2) ...\n", + "Selecting previously unselected package libgssapi-krb5-2:amd64.\n", + "Preparing to unpack .../06-libgssapi-krb5-2_1.16-2ubuntu0.2_amd64.deb ...\n", + "Unpacking libgssapi-krb5-2:amd64 (1.16-2ubuntu0.2) ...\n", + "Selecting previously unselected package libpipeline1:amd64.\n", + "Preparing to unpack .../07-libpipeline1_1.5.0-1_amd64.deb ...\n", + "Unpacking libpipeline1:amd64 (1.5.0-1) ...\n", + "Selecting previously unselected package libpsl5:amd64.\n", + "Preparing to unpack .../08-libpsl5_0.19.1-5build1_amd64.deb ...\n", + "Unpacking libpsl5:amd64 (0.19.1-5build1) ...\n", + "Selecting previously unselected package binfmt-support.\n", + "Preparing to unpack .../09-binfmt-support_2.1.8-2_amd64.deb ...\n", + "Unpacking binfmt-support (2.1.8-2) ...\n", + "Selecting previously unselected package libjsoncpp1:amd64.\n", + "Preparing to unpack .../10-libjsoncpp1_1.7.4-3_amd64.deb ...\n", + "Unpacking libjsoncpp1:amd64 (1.7.4-3) ...\n", + "Selecting previously unselected package libllvm4.0:amd64.\n", + "Preparing to unpack .../11-libllvm4.0_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking libllvm4.0:amd64 (1:4.0.1-10) ...\n", + "Selecting previously unselected package libgc1c2:amd64.\n", + "Preparing to unpack .../12-libgc1c2_1%3a7.4.2-8ubuntu1_amd64.deb ...\n", + "Unpacking libgc1c2:amd64 (1:7.4.2-8ubuntu1) ...\n", + "Selecting previously unselected package libobjc4:amd64.\n", + "Preparing to unpack .../13-libobjc4_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libobjc4:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libobjc-7-dev:amd64.\n", + "Preparing to unpack .../14-libobjc-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libobjc-7-dev:amd64 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package libclang-common-4.0-dev.\n", + "Preparing to unpack .../15-libclang-common-4.0-dev_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking libclang-common-4.0-dev (1:4.0.1-10) ...\n", + "Selecting previously unselected package libclang1-4.0:amd64.\n", + "Preparing to unpack .../16-libclang1-4.0_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking libclang1-4.0:amd64 (1:4.0.1-10) ...\n", + "Selecting previously unselected package clang-4.0.\n", + "Preparing to unpack .../17-clang-4.0_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking clang-4.0 (1:4.0.1-10) ...\n", + "Selecting previously unselected package gcc-4.9-base:amd64.\n", + "Preparing to unpack .../18-gcc-4.9-base_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking gcc-4.9-base:amd64 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libmpfr4:amd64.\n", + "Preparing to unpack .../19-libmpfr4_3.1.4-1_amd64.deb ...\n", + "Unpacking libmpfr4:amd64 (3.1.4-1) ...\n", + "Selecting previously unselected package cpp-4.9.\n", + "Preparing to unpack .../20-cpp-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking cpp-4.9 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libasan1:amd64.\n", + "Preparing to unpack .../21-libasan1_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libasan1:amd64 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libgcc-4.9-dev:amd64.\n", + "Preparing to unpack .../22-libgcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libgcc-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package gcc-4.9.\n", + "Preparing to unpack .../23-gcc-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking gcc-4.9 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libstdc++-4.9-dev:amd64.\n", + "Preparing to unpack .../24-libstdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libstdc++-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package g++-4.9.\n", + "Preparing to unpack .../25-g++-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking g++-4.9 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libc6-i386.\n", + "Preparing to unpack .../26-libc6-i386_2.27-3ubuntu1.4_amd64.deb ...\n", + "Unpacking libc6-i386 (2.27-3ubuntu1.4) ...\n", + "Selecting previously unselected package libc6-dev-i386.\n", + "Preparing to unpack .../27-libc6-dev-i386_2.27-3ubuntu1.4_amd64.deb ...\n", + "Unpacking libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", + "Selecting previously unselected package libc6-x32.\n", + "Preparing to unpack .../28-libc6-x32_2.27-3ubuntu1.4_amd64.deb ...\n", + "Unpacking libc6-x32 (2.27-3ubuntu1.4) ...\n", + "Selecting previously unselected package libc6-dev-x32.\n", + "Preparing to unpack .../29-libc6-dev-x32_2.27-3ubuntu1.4_amd64.deb ...\n", + "Unpacking libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", + "Selecting previously unselected package lib32gcc1.\n", + "Preparing to unpack .../30-lib32gcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32gcc1.\n", + "Preparing to unpack .../31-libx32gcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32gomp1.\n", + "Preparing to unpack .../32-lib32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32gomp1.\n", + "Preparing to unpack .../33-libx32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32itm1.\n", + "Preparing to unpack .../34-lib32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32itm1 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32itm1.\n", + "Preparing to unpack .../35-libx32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32itm1 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32atomic1.\n", + "Preparing to unpack .../36-lib32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32atomic1.\n", + "Preparing to unpack .../37-libx32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32asan1.\n", + "Preparing to unpack .../38-lib32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking lib32asan1 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libx32asan1.\n", + "Preparing to unpack .../39-libx32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libx32asan1 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package lib32stdc++6.\n", + "Preparing to unpack .../40-lib32stdc++6_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32ubsan0.\n", + "Preparing to unpack .../41-lib32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32stdc++6.\n", + "Preparing to unpack .../42-libx32stdc++6_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32ubsan0.\n", + "Preparing to unpack .../43-libx32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32cilkrts5.\n", + "Preparing to unpack .../44-lib32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32cilkrts5.\n", + "Preparing to unpack .../45-libx32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32quadmath0.\n", + "Preparing to unpack .../46-lib32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32quadmath0.\n", + "Preparing to unpack .../47-libx32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32gcc-4.9-dev.\n", + "Preparing to unpack .../48-lib32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking lib32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libx32gcc-4.9-dev.\n", + "Preparing to unpack .../49-libx32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package gcc-4.9-multilib.\n", + "Preparing to unpack .../50-gcc-4.9-multilib_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking gcc-4.9-multilib (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package lib32stdc++-4.9-dev.\n", + "Preparing to unpack .../51-lib32stdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking lib32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libx32stdc++-4.9-dev.\n", + "Preparing to unpack .../52-libx32stdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libx32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package g++-4.9-multilib.\n", + "Preparing to unpack .../53-g++-4.9-multilib_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking g++-4.9-multilib (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libgmpxx4ldbl:amd64.\n", + "Preparing to unpack .../54-libgmpxx4ldbl_2%3a6.1.2+dfsg-2_amd64.deb ...\n", + "Unpacking libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...\n", + "Selecting previously unselected package libgmp-dev:amd64.\n", + "Preparing to unpack .../55-libgmp-dev_2%3a6.1.2+dfsg-2_amd64.deb ...\n", + "Unpacking libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...\n", + "Selecting previously unselected package gcc-4.9-plugin-dev.\n", + "Preparing to unpack .../56-gcc-4.9-plugin-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking gcc-4.9-plugin-dev (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libnghttp2-14:amd64.\n", + "Preparing to unpack .../57-libnghttp2-14_1.30.0-1ubuntu1_amd64.deb ...\n", + "Unpacking libnghttp2-14:amd64 (1.30.0-1ubuntu1) ...\n", + "Selecting previously unselected package librtmp1:amd64.\n", + "Preparing to unpack .../58-librtmp1_2.4+20151223.gitfa8646d.1-1_amd64.deb ...\n", + "Unpacking librtmp1:amd64 (2.4+20151223.gitfa8646d.1-1) ...\n", + "Selecting previously unselected package libcurl3-gnutls:amd64.\n", + "Preparing to unpack .../59-libcurl3-gnutls_7.58.0-2ubuntu3.13_amd64.deb ...\n", + "Unpacking libcurl3-gnutls:amd64 (7.58.0-2ubuntu3.13) ...\n", + "Selecting previously unselected package liberror-perl.\n", + "Preparing to unpack .../60-liberror-perl_0.17025-1_all.deb ...\n", + "Unpacking liberror-perl (0.17025-1) ...\n", + "Selecting previously unselected package git-man.\n", + "Preparing to unpack .../61-git-man_1%3a2.17.1-1ubuntu0.8_all.deb ...\n", + "Unpacking git-man (1:2.17.1-1ubuntu0.8) ...\n", + "Selecting previously unselected package git.\n", + "Preparing to unpack .../62-git_1%3a2.17.1-1ubuntu0.8_amd64.deb ...\n", + "Unpacking git (1:2.17.1-1ubuntu0.8) ...\n", + "Selecting previously unselected package iverilog.\n", + "Preparing to unpack .../63-iverilog_10.1-0.1build1_amd64.deb ...\n", + "Unpacking iverilog (10.1-0.1build1) ...\n", + "Selecting previously unselected package libbdd0c2.\n", + "Preparing to unpack .../64-libbdd0c2_2.4-11_amd64.deb ...\n", + "Unpacking libbdd0c2 (2.4-11) ...\n", + "Selecting previously unselected package libbdd-dev.\n", + "Preparing to unpack .../65-libbdd-dev_2.4-11_amd64.deb ...\n", + "Unpacking libbdd-dev (2.4-11) ...\n", + "Selecting previously unselected package libclang-4.0-dev.\n", + "Preparing to unpack .../66-libclang-4.0-dev_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking libclang-4.0-dev (1:4.0.1-10) ...\n", + "Selecting previously unselected package libtinfo-dev:amd64.\n", + "Preparing to unpack .../67-libtinfo-dev_6.1-1ubuntu1.18.04_amd64.deb ...\n", + "Unpacking libtinfo-dev:amd64 (6.1-1ubuntu1.18.04) ...\n", + "Selecting previously unselected package llvm-4.0-runtime.\n", + "Preparing to unpack .../68-llvm-4.0-runtime_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking llvm-4.0-runtime (1:4.0.1-10) ...\n", + "Selecting previously unselected package llvm-4.0.\n", + "Preparing to unpack .../69-llvm-4.0_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking llvm-4.0 (1:4.0.1-10) ...\n", + "Selecting previously unselected package libffi-dev:amd64.\n", + "Preparing to unpack .../70-libffi-dev_3.2.1-8_amd64.deb ...\n", + "Unpacking libffi-dev:amd64 (3.2.1-8) ...\n", + "Selecting previously unselected package llvm-4.0-dev.\n", + "Preparing to unpack .../71-llvm-4.0-dev_1%3a4.0.1-10_amd64.deb ...\n", + "Unpacking llvm-4.0-dev (1:4.0.1-10) ...\n", + "Selecting previously unselected package verilator.\n", + "Preparing to unpack .../72-verilator_3.916-1build1_amd64.deb ...\n", + "Unpacking verilator (3.916-1build1) ...\n", + "Setting up libquadmath0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libedit2:amd64 (3.1-20170329-1) ...\n", + "Setting up libc6-x32 (2.27-3ubuntu1.4) ...\n", + "Setting up libgomp1:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libatomic1:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up git-man (1:2.17.1-1ubuntu0.8) ...\n", + "Setting up libcc1-0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libx32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libnghttp2-14:amd64 (1.30.0-1ubuntu1) ...\n", + "Setting up liberror-perl (0.17025-1) ...\n", + "Setting up libpsl5:amd64 (0.19.1-5build1) ...\n", + "Setting up libbdd0c2 (2.4-11) ...\n", + "Setting up libtsan0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libtinfo-dev:amd64 (6.1-1ubuntu1.18.04) ...\n", + "Setting up libgc1c2:amd64 (1:7.4.2-8ubuntu1) ...\n", + "Setting up libffi-dev:amd64 (3.2.1-8) ...\n", + "Setting up iverilog (10.1-0.1build1) ...\n", + "Setting up libpipeline1:amd64 (1.5.0-1) ...\n", + "Setting up libc6-i386 (2.27-3ubuntu1.4) ...\n", + "Setting up librtmp1:amd64 (2.4+20151223.gitfa8646d.1-1) ...\n", + "Setting up libkrb5support0:amd64 (1.16-2ubuntu0.2) ...\n", + "Setting up libx32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up lib32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libx32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up liblsan0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libx32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libmpx2:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libllvm4.0:amd64 (1:4.0.1-10) ...\n", + "Setting up libclang1-4.0:amd64 (1:4.0.1-10) ...\n", + "Setting up libx32itm1 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libmpfr4:amd64 (3.1.4-1) ...\n", + "Setting up gcc-4.9-base:amd64 (4.9.3-13ubuntu2) ...\n", + "Setting up libc-dev-bin (2.27-3ubuntu1.4) ...\n", + "Setting up verilator (3.916-1build1) ...\n", + "Setting up libkeyutils1:amd64 (1.5.9-9.2ubuntu2) ...\n", + "Setting up libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...\n", + "Setting up lib32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up ca-certificates (20210119~18.04.1) ...\n", + "debconf: unable to initialize frontend: Dialog\n", + "debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)\n", + "debconf: falling back to frontend: Readline\n", + "Updating certificates in /etc/ssl/certs...\n", + "23 added, 27 removed; done.\n", + "Setting up libc6-dev:amd64 (2.27-3ubuntu1.4) ...\n", + "Setting up lib32itm1 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libitm1:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libx32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up lib32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libjsoncpp1:amd64 (1.7.4-3) ...\n", + "Setting up libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...\n", + "Setting up binfmt-support (2.1.8-2) ...\n", + "mount: /proc/sys/fs/binfmt_misc: permission denied.\n", + "update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.\n", + "mount: /proc/sys/fs/binfmt_misc: permission denied.\n", + "update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.\n", + "invoke-rc.d: could not determine current runlevel\n", + "invoke-rc.d: policy-rc.d denied execution of start.\n", + "Setting up libk5crypto3:amd64 (1.16-2ubuntu0.2) ...\n", + "Setting up libobjc4:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libx32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libclang-common-4.0-dev (1:4.0.1-10) ...\n", + "Setting up libx32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up libbdd-dev (2.4-11) ...\n", + "Setting up llvm-4.0-runtime (1:4.0.1-10) ...\n", + "mount: /proc/sys/fs/binfmt_misc: permission denied.\n", + "update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.\n", + "Setting up cpp-4.9 (4.9.3-13ubuntu2) ...\n", + "Setting up libobjc-7-dev:amd64 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up libx32asan1 (4.9.3-13ubuntu2) ...\n", + "Setting up libasan1:amd64 (4.9.3-13ubuntu2) ...\n", + "Setting up libgcc-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", + "Setting up lib32asan1 (4.9.3-13ubuntu2) ...\n", + "Setting up lib32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libkrb5-3:amd64 (1.16-2ubuntu0.2) ...\n", + "Setting up lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", + "Setting up libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", + "Setting up libclang-4.0-dev (1:4.0.1-10) ...\n", + "Setting up libstdc++-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", + "Setting up gcc-4.9 (4.9.3-13ubuntu2) ...\n", + "Setting up clang-4.0 (1:4.0.1-10) ...\n", + "Setting up llvm-4.0 (1:4.0.1-10) ...\n", + "Setting up gcc-4.9-plugin-dev (4.9.3-13ubuntu2) ...\n", + "Setting up libgssapi-krb5-2:amd64 (1.16-2ubuntu0.2) ...\n", + "Setting up lib32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Setting up lib32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Setting up g++-4.9 (4.9.3-13ubuntu2) ...\n", + "Setting up libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Setting up llvm-4.0-dev (1:4.0.1-10) ...\n", + "Setting up gcc-4.9-multilib (4.9.3-13ubuntu2) ...\n", + "Setting up libcurl3-gnutls:amd64 (7.58.0-2ubuntu3.13) ...\n", + "Setting up libx32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", + "Setting up git (1:2.17.1-1ubuntu0.8) ...\n", + "Setting up g++-4.9-multilib (4.9.3-13ubuntu2) ...\n", + "Processing triggers for libc-bin (2.27-3ubuntu1) ...\n", + "Processing triggers for ca-certificates (20210119~18.04.1) ...\n", + "Updating certificates in /etc/ssl/certs...\n", + "0 added, 0 removed; done.\n", + "Running hooks in /etc/ca-certificates/update.d...\n", + "done.\n", + "Cloning into 'bambu-tutorial'...\n", + "remote: Enumerating objects: 208, done.\u001b[K\n", + "remote: Counting objects: 100% (52/52), done.\u001b[K\n", + "remote: Compressing objects: 100% (42/42), done.\u001b[K\n", + "remote: Total 208 (delta 10), reused 51 (delta 9), pack-reused 156\u001b[K\n", + "Receiving objects: 100% (208/208), 212.07 MiB | 7.63 MiB/s, done.\n", + "Resolving deltas: 100% (32/32), done.\n", + "env: PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin\n" + ] + } + ] }, { "cell_type": "markdown", @@ -102,11 +422,143 @@ "id": "pjUguz8lZr_2" }, "source": [ - "% cd /content/bambu-tutorial/01-introduction/Exercise1\n", + "%cd /content/bambu-tutorial/01-introduction/Exercise1\n", "!bambu icrc.c --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c 2>&1 | tee icrc1.log" ], - "execution_count": null, - "outputs": [] + "execution_count": 3, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[Errno 2] No such file or directory: '/content/bambu-tutorial/01-introduction/Exercise1'\n", + "/opt/colab\n", + " == Bambu executed with: bambu --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c icrc.c \n", + "\n", + "\n", + "********************************************************************************\n", + " ____ _\n", + " | __ ) __ _ _ __ ___ | |_ _ _\n", + " | _ \\ / _` | '_ ` _ \\| '_ \\| | | |\n", + " | |_) | (_| | | | | | | |_) | |_| |\n", + " |____/ \\__,_|_| |_| |_|_.__/ \\__,_|\n", + "\n", + "********************************************************************************\n", + " High-Level Synthesis Tool\n", + "\n", + " Politecnico di Milano - DEIB\n", + " System Architectures Group\n", + "********************************************************************************\n", + " Copyright (C) 2004-2021 Politecnico di Milano\n", + "Version: PandA 0.9.7-dev - Revision c318ea52ad45d9149d2f2d2a40a8af130ee11f55-panda-0.9.7-dev\n", + "\n", + "Parameters parsed in 0.00 seconds\n", + "\n", + "Target technology = FPGA\n", + "Library Name : STD_FU\n", + " Total cells : 3\n", + " - combinational: 0\n", + " - others: 3\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 10\n", + " - combinational: 0\n", + " - others: 10\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 31\n", + " - combinational: 0\n", + " - others: 31\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 8\n", + " - combinational: 0\n", + " - others: 8\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 56\n", + " - combinational: 0\n", + " - others: 56\n", + "\n", + "Library Name : CS_COMPONENT\n", + " Total cells : 16\n", + " - combinational: 0\n", + " - others: 16\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 2\n", + " - combinational: 0\n", + " - others: 2\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 0\n", + " - combinational: 0\n", + " - others: 0\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 0\n", + " - combinational: 0\n", + " - others: 0\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 17\n", + " - combinational: 0\n", + " - others: 17\n", + "\n", + "Library Name : STD\n", + " Total cells : 14\n", + " - combinational: 0\n", + " - others: 14\n", + "\n", + "Library Name : STD_COMMON\n", + " Total cells : 57\n", + " - combinational: 0\n", + " - others: 57\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 8\n", + " - combinational: 0\n", + " - others: 8\n", + "\n", + "Library Name : STD_PC\n", + " Total cells : 16\n", + " - combinational: 0\n", + " - others: 16\n", + "\n", + "Library Name : STD_SOFT_FLOAT\n", + " Total cells : 2\n", + " - combinational: 0\n", + " - others: 2\n", + "\n", + "Library Name : STD\n", + " Total cells : 72\n", + " - combinational: 0\n", + " - others: 72\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 2\n", + " - combinational: 0\n", + " - others: 2\n", + "\n", + "Library Name : STD_FU\n", + " Total cells : 4\n", + " - combinational: 0\n", + " - others: 4\n", + "\n", + "Library Name : WBWrapper\n", + " Total cells : 12\n", + " - combinational: 0\n", + " - others: 12\n", + "\n", + "Compilation time: 0.00 seconds;\n", + "Error in compilation\n", + "/opt/colab/panda-temp/shell_script_8: line 3: /usr/bin/clang-6.0: No such file or directory\n", + "error -> Front-end compiler returns an error during compilation 2\n", + "\tvoid CompilerWrapper::CompileFile(const string&, std::__cxx11::string&, const string&, bool, CompilerWrapper_CompilerMode)\n", + "\t../../src/wrapper/compiler/compiler_wrapper.cpp:708\n" + ] + } + ] }, { "cell_type": "markdown", @@ -153,7 +605,7 @@ "id": "IoMlPfH7-wMD" }, "source": [ - "% cd /content/bambu-tutorial/01-introduction/Exercise2\n", + "%cd /content/bambu-tutorial/01-introduction/Exercise2\n", "!./bambu.sh" ], "execution_count": null, @@ -302,12 +754,15 @@ "source": [ "# **Optimizations**\n", "\n", - "**Exercise 1**: modify Bambu options to evaluate the effect of:\n", + "## **Exercise 1**: \n", + "\n", + "Modify Bambu options to evaluate the effect of:\n", "\n", "\n", - "* different levels of optimization\n", - "* vectorization\n", - "* inlining\n" + "* different levels of optimization (-O0, -O1, -O2, -O3, -Os)\n", + "* vectorization (-ftree-vectorize)\n", + "* inlining (-finline-limit=100000)\n", + "* different frontend compilers (--compiler={I386_GCC49|I386_GCC7|I386_CLANG6|I386_CLANG11})\n" ] }, { @@ -328,7 +783,11 @@ "id": "mJOV50V4IiE2" }, "source": [ - "**Exercise 2**: use the command that yielded the best result in Exercise 1 and verify if SDC scheduling can introduce further improvements." + "## **Exercise 2**: \n", + "\n", + "Use the command that yielded the best result in Exercise 1 and verify if SDC scheduling can introduce further improvements.\n", + "\n", + "* -s or --speculative-sdc-scheduling" ] }, { @@ -337,19 +796,29 @@ "id": "Qi_ZpIr1IzZ7" }, "source": [ + "%cd /content/bambu-tutorial/03-optimizations/Exercise1/\n", "!bambu adpcm.c -O0 --simulate" ], "execution_count": null, "outputs": [] }, { + "source": [ + "## **Exercise 3**:\n", + "\n", + "Modify Bambu options to evaluate the effect of different integer division implementations.\n", + "\n", + "--hls-div=\n", + "* none - use a HDL based pipelined restoring division\n", + "* nr1 - use a C-based non-restoring division with unrolling factor equal to 1 (default)\n", + "* nr2 - use a C-based non-restoring division with unrolling factor equal to 2\n", + "* NR - use a C-based Newton-Raphson division\n", + "* as - use a C-based align divisor shift dividend method\n" + ], "cell_type": "markdown", "metadata": { "id": "StGBkKaJJEfr" - }, - "source": [ - "**Exercise 3**: modify Bambu options to evaluate the effect of different integer division implementations." - ] + } }, { "cell_type": "code", @@ -369,7 +838,9 @@ "id": "YSRwNv1o2Jqx" }, "source": [ - "**Exercise 4**: write C functions that compute the following formula with single precision and double precision data types, experimenting with softfloat and libm implementations.\n", + "## **Exercise 4**: \n", + "\n", + "Write C function that compute the following formula with single precision and double precision data types, experimenting with softfloat and libm implementations.\n", "\n", "![formula.png](data:image/png;base64,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)" ] @@ -383,26 +854,15 @@ "Start by editing this code and then try different bambu options:" ] }, - { - "cell_type": "code", - "metadata": { - "id": "C5tEypGc7B0A" - }, - "source": [ - "%cd /content/bambu-tutorial/03-optimizations/Exercise4/" - ], - "execution_count": null, - "outputs": [] - }, { "cell_type": "code", "metadata": { "id": "LuhiArbj6XnA" }, "source": [ - "%%writefile module.c\n", + "%%writefile /content/bambu-tutorial/03-optimizations/Exercise4/module.c\n", "#include \n", - "float formula_pow(float a, float b, float c)\n", + "float awesome_math(float a, float b, float c)\n", "{\n", " return acosf((powf(a,2) + powf(b,2) - powf(c,2))/(2*a*b));\n", "}" @@ -416,29 +876,8 @@ "id": "_Rg4Gthy2vDm" }, "source": [ - "!bambu module.c -O3 -lm --simulate --top-fname=formula_pow --generate-tb=\"a=3.0,b=4.0,c=5.0\" --speculative-sdc-scheduling --libm-std-rounding --hls-div=none --soft-float" - ], - "execution_count": null, - "outputs": [] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "xbsgMK4D-EYq" - }, - "source": [ - "**USE THIS LATER**" - ] - }, - { - "cell_type": "code", - "metadata": { - "id": "rGIIMMugjEim" - }, - "source": [ - "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", - "%cd bambu-tutorial\n", - "!tar xvf dist.tar.xz -C /" + "%cd /content/bambu-tutorial/03-optimizations/Exercise4/\n", + "!bambu module.c -O3 -lm --simulate --top-fname=awesome_math --generate-tb=\"a=3.0,b=4.0,c=5.0\" --speculative-sdc-scheduling --libm-std-rounding --hls-fpdiv=G --soft-float" ], "execution_count": null, "outputs": [] From 6c1352800c7774b06c55f86d7ebd6ae8a4e209c4 Mon Sep 17 00:00:00 2001 From: Michele Fiorito Date: Mon, 14 Jun 2021 01:23:19 +0200 Subject: [PATCH 12/32] Further information added in section 3 --- documentation/tutorial_ics_2021/bambu.ipynb | 718 +++++++++----------- 1 file changed, 326 insertions(+), 392 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 123464ffa..3492d1383 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -31,7 +31,11 @@ "id": "ZoxqLkfA9zqM", "tags": [ "outputPrepend" - ] + ], + "outputId": "bd1e15a0-4857-4e4a-f6e5-0227fe2cd24c", + "colab": { + "base_uri": "https://localhost:8080/" + } }, "source": [ "!echo \"deb http://dk.archive.ubuntu.com/ubuntu/ xenial main universe\" >> /etc/apt/sources.list\n", @@ -46,360 +50,398 @@ "outputs": [ { "output_type": "stream", - "name": "stdout", "text": [ - "packing liblsan0:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", - "Preparing to unpack .../2-libtsan0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libtsan0:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", - "Preparing to unpack .../3-libcc1-0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libcc1-0:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", - "Preparing to unpack .../4-libatomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libatomic1:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", - "Preparing to unpack .../5-libgomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libgomp1:amd64 (8.4.0-1ubuntu1~18.04) over (8.3.0-26ubuntu1~18.04) ...\n", - "Preparing to unpack .../6-libgcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libgcc1:amd64 (1:8.4.0-1ubuntu1~18.04) over (1:8.3.0-26ubuntu1~18.04) ...\n", - "Setting up libgcc1:amd64 (1:8.4.0-1ubuntu1~18.04) ...\n", - "(Reading database ... 15001 files and directories currently installed.)\n", - "Preparing to unpack .../libc6_2.27-3ubuntu1.4_amd64.deb ...\n", - "debconf: unable to initialize frontend: Dialog\n", - "debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)\n", - "debconf: falling back to frontend: Readline\n", - "Unpacking libc6:amd64 (2.27-3ubuntu1.4) over (2.27-3ubuntu1) ...\n", - "Setting up libc6:amd64 (2.27-3ubuntu1.4) ...\n", - "debconf: unable to initialize frontend: Dialog\n", - "debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)\n", - "debconf: falling back to frontend: Readline\n", - "(Reading database ... 15001 files and directories currently installed.)\n", - "Preparing to unpack .../00-ca-certificates_20210119~18.04.1_all.deb ...\n", - "Unpacking ca-certificates (20210119~18.04.1) over (20180409) ...\n", - "Selecting previously unselected package libedit2:amd64.\n", - "Preparing to unpack .../01-libedit2_3.1-20170329-1_amd64.deb ...\n", - "Unpacking libedit2:amd64 (3.1-20170329-1) ...\n", - "Selecting previously unselected package libkrb5support0:amd64.\n", - "Preparing to unpack .../02-libkrb5support0_1.16-2ubuntu0.2_amd64.deb ...\n", - "Unpacking libkrb5support0:amd64 (1.16-2ubuntu0.2) ...\n", - "Selecting previously unselected package libk5crypto3:amd64.\n", - "Preparing to unpack .../03-libk5crypto3_1.16-2ubuntu0.2_amd64.deb ...\n", - "Unpacking libk5crypto3:amd64 (1.16-2ubuntu0.2) ...\n", - "Selecting previously unselected package libkeyutils1:amd64.\n", - "Preparing to unpack .../04-libkeyutils1_1.5.9-9.2ubuntu2_amd64.deb ...\n", - "Unpacking libkeyutils1:amd64 (1.5.9-9.2ubuntu2) ...\n", - "Selecting previously unselected package libkrb5-3:amd64.\n", - "Preparing to unpack .../05-libkrb5-3_1.16-2ubuntu0.2_amd64.deb ...\n", - "Unpacking libkrb5-3:amd64 (1.16-2ubuntu0.2) ...\n", - "Selecting previously unselected package libgssapi-krb5-2:amd64.\n", - "Preparing to unpack .../06-libgssapi-krb5-2_1.16-2ubuntu0.2_amd64.deb ...\n", - "Unpacking libgssapi-krb5-2:amd64 (1.16-2ubuntu0.2) ...\n", - "Selecting previously unselected package libpipeline1:amd64.\n", - "Preparing to unpack .../07-libpipeline1_1.5.0-1_amd64.deb ...\n", - "Unpacking libpipeline1:amd64 (1.5.0-1) ...\n", - "Selecting previously unselected package libpsl5:amd64.\n", - "Preparing to unpack .../08-libpsl5_0.19.1-5build1_amd64.deb ...\n", - "Unpacking libpsl5:amd64 (0.19.1-5build1) ...\n", - "Selecting previously unselected package binfmt-support.\n", - "Preparing to unpack .../09-binfmt-support_2.1.8-2_amd64.deb ...\n", - "Unpacking binfmt-support (2.1.8-2) ...\n", - "Selecting previously unselected package libjsoncpp1:amd64.\n", - "Preparing to unpack .../10-libjsoncpp1_1.7.4-3_amd64.deb ...\n", - "Unpacking libjsoncpp1:amd64 (1.7.4-3) ...\n", - "Selecting previously unselected package libllvm4.0:amd64.\n", - "Preparing to unpack .../11-libllvm4.0_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking libllvm4.0:amd64 (1:4.0.1-10) ...\n", - "Selecting previously unselected package libgc1c2:amd64.\n", - "Preparing to unpack .../12-libgc1c2_1%3a7.4.2-8ubuntu1_amd64.deb ...\n", - "Unpacking libgc1c2:amd64 (1:7.4.2-8ubuntu1) ...\n", - "Selecting previously unselected package libobjc4:amd64.\n", - "Preparing to unpack .../13-libobjc4_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libobjc4:amd64 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package libobjc-7-dev:amd64.\n", - "Preparing to unpack .../14-libobjc-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libobjc-7-dev:amd64 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package libclang-common-4.0-dev.\n", - "Preparing to unpack .../15-libclang-common-4.0-dev_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking libclang-common-4.0-dev (1:4.0.1-10) ...\n", - "Selecting previously unselected package libclang1-4.0:amd64.\n", - "Preparing to unpack .../16-libclang1-4.0_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking libclang1-4.0:amd64 (1:4.0.1-10) ...\n", - "Selecting previously unselected package clang-4.0.\n", - "Preparing to unpack .../17-clang-4.0_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking clang-4.0 (1:4.0.1-10) ...\n", + "Get:1 https://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease [5,527 B]\n", + "Get:2 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ InRelease [3,626 B]\n", + "Ign:3 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 InRelease\n", + "Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]\n", + "Ign:5 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 InRelease\n", + "Get:6 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Release [697 B]\n", + "Hit:7 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 Release\n", + "Get:8 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Release.gpg [836 B]\n", + "Get:9 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic InRelease [15.9 kB]\n", + "Ign:1 https://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease\n", + "Get:10 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 Packages [8,790 B]\n", + "Hit:11 http://archive.ubuntu.com/ubuntu bionic InRelease\n", + "Get:12 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]\n", + "Get:13 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ Packages [61.8 kB]\n", + "Hit:14 http://ppa.launchpad.net/cran/libgit2/ubuntu bionic InRelease\n", + "Get:15 http://dk.archive.ubuntu.com/ubuntu xenial InRelease [247 kB]\n", + "Get:17 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic InRelease [15.9 kB]\n", + "Get:18 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]\n", + "Ign:19 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Packages\n", + "Get:19 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Packages [800 kB]\n", + "Get:20 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic InRelease [21.3 kB]\n", + "Get:21 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [1,415 kB]\n", + "Get:22 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [2,185 kB]\n", + "Get:23 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [450 kB]\n", + "Get:24 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main Sources [1,772 kB]\n", + "Get:25 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [33.5 kB]\n", + "Get:26 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [2,619 kB]\n", + "Get:27 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [9,827 kB]\n", + "Get:28 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [2,184 kB]\n", + "Get:29 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main amd64 Packages [906 kB]\n", + "Get:30 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [481 kB]\n", + "Get:31 http://dk.archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1,558 kB]\n", + "Get:32 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic/main amd64 Packages [40.9 kB]\n", + "Get:33 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic/main amd64 Packages [41.6 kB]\n", + "Fetched 24.9 MB in 5s (4,630 kB/s)\n", + "Reading package lists... Done\n", + "W: GPG error: https://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 15CF4D18AF4F7421\n", + "W: The repository 'http://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease' is not signed.\n", + "N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.\n", + "N: See apt-secure(8) manpage for repository creation and user configuration details.\n", + "Reading package lists... Done\n", + "Building dependency tree \n", + "Reading state information... Done\n", + "clang-6.0 is already the newest version (1:6.0-1ubuntu2).\n", + "clang-6.0 set to manually installed.\n", + "ca-certificates is already the newest version (20210119~18.04.1).\n", + "git is already the newest version (1:2.17.1-1ubuntu0.8).\n", + "The following additional packages will be installed:\n", + " cpp-4.9 g++-7-multilib gcc-4.9-base gcc-7-multilib lib32asan1 lib32asan4\n", + " lib32atomic1 lib32cilkrts5 lib32gcc-4.9-dev lib32gcc-7-dev lib32gomp1\n", + " lib32itm1 lib32mpx2 lib32quadmath0 lib32stdc++-7-dev lib32ubsan0 libasan1\n", + " libbdd0c2 libc6-dev-i386 libc6-dev-x32 libc6-x32 libclang-common-11-dev\n", + " libclang-cpp11 libclang1-11 libgcc-4.9-dev libgmp-dev libgmpxx4ldbl\n", + " libllvm11 libmpc-dev libmpfr-dev libmpfr4 libstdc++-4.9-dev libx32asan1\n", + " libx32asan4 libx32atomic1 libx32cilkrts5 libx32gcc-4.9-dev libx32gcc-7-dev\n", + " libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc++-7-dev\n", + " libx32stdc++6 libx32ubsan0\n", + "Suggested packages:\n", + " clang-11-doc gcc-4.9-locales g++-4.9-multilib gcc-4.9-doc libstdc++6-4.9-dbg\n", + " lib32stdc++6-7-dbg libx32stdc++6-7-dbg libgcc1-dbg libgomp1-dbg libitm1-dbg\n", + " libatomic1-dbg libasan1-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg\n", + " libcilkrts5-dbg libquadmath0-dbg gtkwave gmp-doc libgmp10-doc libmpfr-doc\n", + " libstdc++-4.9-doc systemc\n", + "Recommended packages:\n", + " llvm-11-dev libomp-11-dev\n", + "The following NEW packages will be installed:\n", + " clang-11 cpp-4.9 g++-4.9 g++-7-multilib g++-multilib gcc-4.9 gcc-4.9-base\n", + " gcc-4.9-multilib gcc-4.9-plugin-dev gcc-7-multilib gcc-7-plugin-dev\n", + " gcc-multilib iverilog lib32asan1 lib32asan4 lib32atomic1 lib32cilkrts5\n", + " lib32gcc-4.9-dev lib32gcc-7-dev lib32gomp1 lib32itm1 lib32mpx2\n", + " lib32quadmath0 lib32stdc++-7-dev lib32ubsan0 libasan1 libbdd-dev libbdd0c2\n", + " libc6-dev-i386 libc6-dev-x32 libc6-x32 libclang-11-dev libclang-6.0-dev\n", + " libclang-common-11-dev libclang-cpp11 libclang1-11 libgcc-4.9-dev libgmp-dev\n", + " libgmpxx4ldbl libllvm11 libmpc-dev libmpfr-dev libmpfr4 libstdc++-4.9-dev\n", + " libx32asan1 libx32asan4 libx32atomic1 libx32cilkrts5 libx32gcc-4.9-dev\n", + " libx32gcc-7-dev libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0\n", + " libx32stdc++-7-dev libx32stdc++6 libx32ubsan0 verilator\n", + "0 upgraded, 58 newly installed, 0 to remove and 48 not upgraded.\n", + "Need to get 137 MB of archives.\n", + "After this operation, 904 MB of additional disk space will be used.\n", + "WARNING: The following packages cannot be authenticated!\n", + " libllvm11 libclang-cpp11 libclang-common-11-dev libclang1-11 clang-11\n", + " libclang-11-dev\n", + "Authentication warning overridden.\n", + "Get:1 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libllvm11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [17.7 MB]\n", + "Get:7 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libc6-dev-i386 amd64 2.27-3ubuntu1.4 [1,818 kB]\n", + "Get:2 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang-cpp11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [9,554 kB]\n", + "Get:3 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang-common-11-dev amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [4,911 kB]\n", + "Get:8 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9-base amd64 4.9.3-13ubuntu2 [15.3 kB]\n", + "Get:4 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang1-11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [5,501 kB]\n", + "Get:5 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 clang-11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [108 kB]\n", + "Get:6 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang-11-dev amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [18.1 MB]\n", + "Get:9 http://dk.archive.ubuntu.com/ubuntu xenial/main amd64 libmpfr4 amd64 3.1.4-1 [191 kB]\n", + "Get:10 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libc6-x32 amd64 2.27-3ubuntu1.4 [2,845 kB]\n", + "Get:11 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libc6-dev-x32 amd64 2.27-3ubuntu1.4 [2,017 kB]\n", + "Get:12 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 cpp-4.9 amd64 4.9.3-13ubuntu2 [4,972 kB]\n", + "Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32gcc1 amd64 1:8.4.0-1ubuntu1~18.04 [40.5 kB]\n", + "Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32gomp1 amd64 8.4.0-1ubuntu1~18.04 [83.7 kB]\n", + "Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32gomp1 amd64 8.4.0-1ubuntu1~18.04 [77.8 kB]\n", + "Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32itm1 amd64 8.4.0-1ubuntu1~18.04 [30.0 kB]\n", + "Get:17 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32itm1 amd64 8.4.0-1ubuntu1~18.04 [28.1 kB]\n", + "Get:18 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32atomic1 amd64 8.4.0-1ubuntu1~18.04 [8,664 B]\n", + "Get:19 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32atomic1 amd64 8.4.0-1ubuntu1~18.04 [9,188 B]\n", + "Get:20 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32asan4 amd64 7.5.0-3ubuntu1~18.04 [362 kB]\n", + "Get:21 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32asan4 amd64 7.5.0-3ubuntu1~18.04 [351 kB]\n", + "Get:22 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32ubsan0 amd64 7.5.0-3ubuntu1~18.04 [140 kB]\n", + "Get:23 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32stdc++6 amd64 8.4.0-1ubuntu1~18.04 [387 kB]\n", + "Get:24 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32ubsan0 amd64 7.5.0-3ubuntu1~18.04 [127 kB]\n", + "Get:25 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32cilkrts5 amd64 7.5.0-3ubuntu1~18.04 [47.2 kB]\n", + "Get:26 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32cilkrts5 amd64 7.5.0-3ubuntu1~18.04 [43.0 kB]\n", + "Get:27 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32mpx2 amd64 8.4.0-1ubuntu1~18.04 [12.9 kB]\n", + "Get:28 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32quadmath0 amd64 8.4.0-1ubuntu1~18.04 [208 kB]\n", + "Get:29 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32quadmath0 amd64 8.4.0-1ubuntu1~18.04 [135 kB]\n", + "Get:30 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32gcc-7-dev amd64 7.5.0-3ubuntu1~18.04 [2,211 kB]\n", + "Get:31 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32gcc-7-dev amd64 7.5.0-3ubuntu1~18.04 [1,999 kB]\n", + "Get:32 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 gcc-7-multilib amd64 7.5.0-3ubuntu1~18.04 [1,048 B]\n", + "Get:33 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32stdc++-7-dev amd64 7.5.0-3ubuntu1~18.04 [626 kB]\n", + "Get:34 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32stdc++-7-dev amd64 7.5.0-3ubuntu1~18.04 [582 kB]\n", + "Get:35 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 g++-7-multilib amd64 7.5.0-3ubuntu1~18.04 [1,064 B]\n", + "Get:36 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 gcc-multilib amd64 4:7.4.0-1ubuntu2.3 [1,428 B]\n", + "Get:37 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 g++-multilib amd64 4:7.4.0-1ubuntu2.3 [1,020 B]\n", + "Get:38 http://archive.ubuntu.com/ubuntu bionic/main amd64 libgmpxx4ldbl amd64 2:6.1.2+dfsg-2 [8,964 B]\n", + "Get:39 http://archive.ubuntu.com/ubuntu bionic/main amd64 libgmp-dev amd64 2:6.1.2+dfsg-2 [316 kB]\n", + "Get:40 http://archive.ubuntu.com/ubuntu bionic/main amd64 libmpfr-dev amd64 4.0.1-1 [249 kB]\n", + "Get:41 http://archive.ubuntu.com/ubuntu bionic/main amd64 libmpc-dev amd64 1.1.0-1 [50.5 kB]\n", + "Get:42 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 gcc-7-plugin-dev amd64 7.5.0-3ubuntu1~18.04 [1,162 kB]\n", + "Get:43 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libasan1 amd64 4.9.3-13ubuntu2 [197 kB]\n", + "Get:44 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libgcc-4.9-dev amd64 4.9.3-13ubuntu2 [2,073 kB]\n", + "Get:45 http://archive.ubuntu.com/ubuntu bionic/universe amd64 iverilog amd64 10.1-0.1build1 [1,811 kB]\n", + "Get:46 http://archive.ubuntu.com/ubuntu bionic/universe amd64 libbdd0c2 amd64 2.4-11 [51.5 kB]\n", + "Get:47 http://archive.ubuntu.com/ubuntu bionic/universe amd64 libbdd-dev amd64 2.4-11 [454 kB]\n", + "Get:48 http://archive.ubuntu.com/ubuntu bionic/universe amd64 libclang-6.0-dev amd64 1:6.0-1ubuntu2 [20.4 MB]\n", + "Get:49 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9 amd64 4.9.3-13ubuntu2 [5,442 kB]\n", + "Get:50 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libstdc++-4.9-dev amd64 4.9.3-13ubuntu2 [1,126 kB]\n", + "Get:51 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 g++-4.9 amd64 4.9.3-13ubuntu2 [21.0 MB]\n", + "Get:52 http://archive.ubuntu.com/ubuntu bionic/universe amd64 verilator amd64 3.916-1build1 [2,878 kB]\n", + "Get:53 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 lib32asan1 amd64 4.9.3-13ubuntu2 [190 kB]\n", + "Get:54 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libx32asan1 amd64 4.9.3-13ubuntu2 [190 kB]\n", + "Get:55 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 lib32gcc-4.9-dev amd64 4.9.3-13ubuntu2 [1,920 kB]\n", + "Get:56 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libx32gcc-4.9-dev amd64 4.9.3-13ubuntu2 [1,782 kB]\n", + "Get:57 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9-multilib amd64 4.9.3-13ubuntu2 [964 B]\n", + "Get:58 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9-plugin-dev amd64 4.9.3-13ubuntu2 [806 kB]\n", + "Fetched 137 MB in 4s (31.5 MB/s)\n", + "Extracting templates from packages: 100%\n", + "Selecting previously unselected package libllvm11:amd64.\n", + "(Reading database ... 160772 files and directories currently installed.)\n", + "Preparing to unpack .../00-libllvm11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", + "Unpacking libllvm11:amd64 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Selecting previously unselected package libclang-cpp11.\n", + "Preparing to unpack .../01-libclang-cpp11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", + "Unpacking libclang-cpp11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Selecting previously unselected package libclang-common-11-dev.\n", + "Preparing to unpack .../02-libclang-common-11-dev_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", + "Unpacking libclang-common-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Selecting previously unselected package libclang1-11.\n", + "Preparing to unpack .../03-libclang1-11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", + "Unpacking libclang1-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Selecting previously unselected package clang-11.\n", + "Preparing to unpack .../04-clang-11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", + "Unpacking clang-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", "Selecting previously unselected package gcc-4.9-base:amd64.\n", - "Preparing to unpack .../18-gcc-4.9-base_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../05-gcc-4.9-base_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking gcc-4.9-base:amd64 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package libmpfr4:amd64.\n", - "Preparing to unpack .../19-libmpfr4_3.1.4-1_amd64.deb ...\n", + "Preparing to unpack .../06-libmpfr4_3.1.4-1_amd64.deb ...\n", "Unpacking libmpfr4:amd64 (3.1.4-1) ...\n", "Selecting previously unselected package cpp-4.9.\n", - "Preparing to unpack .../20-cpp-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../07-cpp-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking cpp-4.9 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package libasan1:amd64.\n", - "Preparing to unpack .../21-libasan1_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../08-libasan1_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking libasan1:amd64 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package libgcc-4.9-dev:amd64.\n", - "Preparing to unpack .../22-libgcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../09-libgcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking libgcc-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package gcc-4.9.\n", - "Preparing to unpack .../23-gcc-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../10-gcc-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking gcc-4.9 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package libstdc++-4.9-dev:amd64.\n", - "Preparing to unpack .../24-libstdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../11-libstdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking libstdc++-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package g++-4.9.\n", - "Preparing to unpack .../25-g++-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../12-g++-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking g++-4.9 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libc6-i386.\n", - "Preparing to unpack .../26-libc6-i386_2.27-3ubuntu1.4_amd64.deb ...\n", - "Unpacking libc6-i386 (2.27-3ubuntu1.4) ...\n", "Selecting previously unselected package libc6-dev-i386.\n", - "Preparing to unpack .../27-libc6-dev-i386_2.27-3ubuntu1.4_amd64.deb ...\n", + "Preparing to unpack .../13-libc6-dev-i386_2.27-3ubuntu1.4_amd64.deb ...\n", "Unpacking libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", "Selecting previously unselected package libc6-x32.\n", - "Preparing to unpack .../28-libc6-x32_2.27-3ubuntu1.4_amd64.deb ...\n", + "Preparing to unpack .../14-libc6-x32_2.27-3ubuntu1.4_amd64.deb ...\n", "Unpacking libc6-x32 (2.27-3ubuntu1.4) ...\n", "Selecting previously unselected package libc6-dev-x32.\n", - "Preparing to unpack .../29-libc6-dev-x32_2.27-3ubuntu1.4_amd64.deb ...\n", + "Preparing to unpack .../15-libc6-dev-x32_2.27-3ubuntu1.4_amd64.deb ...\n", "Unpacking libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", - "Selecting previously unselected package lib32gcc1.\n", - "Preparing to unpack .../30-lib32gcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32gcc1.\n", - "Preparing to unpack .../31-libx32gcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../16-libx32gcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package lib32gomp1.\n", - "Preparing to unpack .../32-lib32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../17-lib32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32gomp1.\n", - "Preparing to unpack .../33-libx32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../18-libx32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package lib32itm1.\n", - "Preparing to unpack .../34-lib32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../19-lib32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking lib32itm1 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32itm1.\n", - "Preparing to unpack .../35-libx32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../20-libx32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32itm1 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package lib32atomic1.\n", - "Preparing to unpack .../36-lib32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../21-lib32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking lib32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32atomic1.\n", - "Preparing to unpack .../37-libx32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../22-libx32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32asan1.\n", - "Preparing to unpack .../38-lib32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking lib32asan1 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libx32asan1.\n", - "Preparing to unpack .../39-libx32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libx32asan1 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package lib32stdc++6.\n", - "Preparing to unpack .../40-lib32stdc++6_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32asan4.\n", + "Preparing to unpack .../23-lib32asan4_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32asan4 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32asan4.\n", + "Preparing to unpack .../24-libx32asan4_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32asan4 (7.5.0-3ubuntu1~18.04) ...\n", "Selecting previously unselected package lib32ubsan0.\n", - "Preparing to unpack .../41-lib32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../25-lib32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", "Unpacking lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32stdc++6.\n", - "Preparing to unpack .../42-libx32stdc++6_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../26-libx32stdc++6_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32ubsan0.\n", - "Preparing to unpack .../43-libx32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../27-libx32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", "Selecting previously unselected package lib32cilkrts5.\n", - "Preparing to unpack .../44-lib32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../28-lib32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", "Unpacking lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32cilkrts5.\n", - "Preparing to unpack .../45-libx32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../29-libx32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32mpx2.\n", + "Preparing to unpack .../30-lib32mpx2_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32mpx2 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package lib32quadmath0.\n", - "Preparing to unpack .../46-lib32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../31-lib32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking lib32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", "Selecting previously unselected package libx32quadmath0.\n", - "Preparing to unpack .../47-libx32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", + "Preparing to unpack .../32-libx32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", "Unpacking libx32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32gcc-7-dev.\n", + "Preparing to unpack .../33-lib32gcc-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32gcc-7-dev.\n", + "Preparing to unpack .../34-libx32gcc-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package gcc-7-multilib.\n", + "Preparing to unpack .../35-gcc-7-multilib_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking gcc-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package lib32stdc++-7-dev.\n", + "Preparing to unpack .../36-lib32stdc++-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking lib32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package libx32stdc++-7-dev.\n", + "Preparing to unpack .../37-libx32stdc++-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking libx32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package g++-7-multilib.\n", + "Preparing to unpack .../38-g++-7-multilib_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking g++-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", + "Selecting previously unselected package gcc-multilib.\n", + "Preparing to unpack .../39-gcc-multilib_4%3a7.4.0-1ubuntu2.3_amd64.deb ...\n", + "Unpacking gcc-multilib (4:7.4.0-1ubuntu2.3) ...\n", + "Selecting previously unselected package g++-multilib.\n", + "Preparing to unpack .../40-g++-multilib_4%3a7.4.0-1ubuntu2.3_amd64.deb ...\n", + "Unpacking g++-multilib (4:7.4.0-1ubuntu2.3) ...\n", + "Selecting previously unselected package lib32asan1.\n", + "Preparing to unpack .../41-lib32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking lib32asan1 (4.9.3-13ubuntu2) ...\n", + "Selecting previously unselected package libx32asan1.\n", + "Preparing to unpack .../42-libx32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", + "Unpacking libx32asan1 (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package lib32gcc-4.9-dev.\n", - "Preparing to unpack .../48-lib32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../43-lib32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking lib32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package libx32gcc-4.9-dev.\n", - "Preparing to unpack .../49-libx32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../44-libx32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package gcc-4.9-multilib.\n", - "Preparing to unpack .../50-gcc-4.9-multilib_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../45-gcc-4.9-multilib_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking gcc-4.9-multilib (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package lib32stdc++-4.9-dev.\n", - "Preparing to unpack .../51-lib32stdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking lib32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libx32stdc++-4.9-dev.\n", - "Preparing to unpack .../52-libx32stdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libx32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package g++-4.9-multilib.\n", - "Preparing to unpack .../53-g++-4.9-multilib_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking g++-4.9-multilib (4.9.3-13ubuntu2) ...\n", "Selecting previously unselected package libgmpxx4ldbl:amd64.\n", - "Preparing to unpack .../54-libgmpxx4ldbl_2%3a6.1.2+dfsg-2_amd64.deb ...\n", + "Preparing to unpack .../46-libgmpxx4ldbl_2%3a6.1.2+dfsg-2_amd64.deb ...\n", "Unpacking libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...\n", "Selecting previously unselected package libgmp-dev:amd64.\n", - "Preparing to unpack .../55-libgmp-dev_2%3a6.1.2+dfsg-2_amd64.deb ...\n", + "Preparing to unpack .../47-libgmp-dev_2%3a6.1.2+dfsg-2_amd64.deb ...\n", "Unpacking libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...\n", "Selecting previously unselected package gcc-4.9-plugin-dev.\n", - "Preparing to unpack .../56-gcc-4.9-plugin-dev_4.9.3-13ubuntu2_amd64.deb ...\n", + "Preparing to unpack .../48-gcc-4.9-plugin-dev_4.9.3-13ubuntu2_amd64.deb ...\n", "Unpacking gcc-4.9-plugin-dev (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libnghttp2-14:amd64.\n", - "Preparing to unpack .../57-libnghttp2-14_1.30.0-1ubuntu1_amd64.deb ...\n", - "Unpacking libnghttp2-14:amd64 (1.30.0-1ubuntu1) ...\n", - "Selecting previously unselected package librtmp1:amd64.\n", - "Preparing to unpack .../58-librtmp1_2.4+20151223.gitfa8646d.1-1_amd64.deb ...\n", - "Unpacking librtmp1:amd64 (2.4+20151223.gitfa8646d.1-1) ...\n", - "Selecting previously unselected package libcurl3-gnutls:amd64.\n", - "Preparing to unpack .../59-libcurl3-gnutls_7.58.0-2ubuntu3.13_amd64.deb ...\n", - "Unpacking libcurl3-gnutls:amd64 (7.58.0-2ubuntu3.13) ...\n", - "Selecting previously unselected package liberror-perl.\n", - "Preparing to unpack .../60-liberror-perl_0.17025-1_all.deb ...\n", - "Unpacking liberror-perl (0.17025-1) ...\n", - "Selecting previously unselected package git-man.\n", - "Preparing to unpack .../61-git-man_1%3a2.17.1-1ubuntu0.8_all.deb ...\n", - "Unpacking git-man (1:2.17.1-1ubuntu0.8) ...\n", - "Selecting previously unselected package git.\n", - "Preparing to unpack .../62-git_1%3a2.17.1-1ubuntu0.8_amd64.deb ...\n", - "Unpacking git (1:2.17.1-1ubuntu0.8) ...\n", + "Selecting previously unselected package libmpfr-dev:amd64.\n", + "Preparing to unpack .../49-libmpfr-dev_4.0.1-1_amd64.deb ...\n", + "Unpacking libmpfr-dev:amd64 (4.0.1-1) ...\n", + "Selecting previously unselected package libmpc-dev:amd64.\n", + "Preparing to unpack .../50-libmpc-dev_1.1.0-1_amd64.deb ...\n", + "Unpacking libmpc-dev:amd64 (1.1.0-1) ...\n", + "Selecting previously unselected package gcc-7-plugin-dev.\n", + "Preparing to unpack .../51-gcc-7-plugin-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", + "Unpacking gcc-7-plugin-dev (7.5.0-3ubuntu1~18.04) ...\n", "Selecting previously unselected package iverilog.\n", - "Preparing to unpack .../63-iverilog_10.1-0.1build1_amd64.deb ...\n", + "Preparing to unpack .../52-iverilog_10.1-0.1build1_amd64.deb ...\n", "Unpacking iverilog (10.1-0.1build1) ...\n", "Selecting previously unselected package libbdd0c2.\n", - "Preparing to unpack .../64-libbdd0c2_2.4-11_amd64.deb ...\n", + "Preparing to unpack .../53-libbdd0c2_2.4-11_amd64.deb ...\n", "Unpacking libbdd0c2 (2.4-11) ...\n", "Selecting previously unselected package libbdd-dev.\n", - "Preparing to unpack .../65-libbdd-dev_2.4-11_amd64.deb ...\n", + "Preparing to unpack .../54-libbdd-dev_2.4-11_amd64.deb ...\n", "Unpacking libbdd-dev (2.4-11) ...\n", - "Selecting previously unselected package libclang-4.0-dev.\n", - "Preparing to unpack .../66-libclang-4.0-dev_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking libclang-4.0-dev (1:4.0.1-10) ...\n", - "Selecting previously unselected package libtinfo-dev:amd64.\n", - "Preparing to unpack .../67-libtinfo-dev_6.1-1ubuntu1.18.04_amd64.deb ...\n", - "Unpacking libtinfo-dev:amd64 (6.1-1ubuntu1.18.04) ...\n", - "Selecting previously unselected package llvm-4.0-runtime.\n", - "Preparing to unpack .../68-llvm-4.0-runtime_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking llvm-4.0-runtime (1:4.0.1-10) ...\n", - "Selecting previously unselected package llvm-4.0.\n", - "Preparing to unpack .../69-llvm-4.0_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking llvm-4.0 (1:4.0.1-10) ...\n", - "Selecting previously unselected package libffi-dev:amd64.\n", - "Preparing to unpack .../70-libffi-dev_3.2.1-8_amd64.deb ...\n", - "Unpacking libffi-dev:amd64 (3.2.1-8) ...\n", - "Selecting previously unselected package llvm-4.0-dev.\n", - "Preparing to unpack .../71-llvm-4.0-dev_1%3a4.0.1-10_amd64.deb ...\n", - "Unpacking llvm-4.0-dev (1:4.0.1-10) ...\n", + "Selecting previously unselected package libclang-11-dev.\n", + "Preparing to unpack .../55-libclang-11-dev_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", + "Unpacking libclang-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Selecting previously unselected package libclang-6.0-dev.\n", + "Preparing to unpack .../56-libclang-6.0-dev_1%3a6.0-1ubuntu2_amd64.deb ...\n", + "Unpacking libclang-6.0-dev (1:6.0-1ubuntu2) ...\n", "Selecting previously unselected package verilator.\n", - "Preparing to unpack .../72-verilator_3.916-1build1_amd64.deb ...\n", + "Preparing to unpack .../57-verilator_3.916-1build1_amd64.deb ...\n", "Unpacking verilator (3.916-1build1) ...\n", - "Setting up libquadmath0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libedit2:amd64 (3.1-20170329-1) ...\n", "Setting up libc6-x32 (2.27-3ubuntu1.4) ...\n", - "Setting up libgomp1:amd64 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libatomic1:amd64 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up git-man (1:2.17.1-1ubuntu0.8) ...\n", - "Setting up libcc1-0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up libx32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libnghttp2-14:amd64 (1.30.0-1ubuntu1) ...\n", - "Setting up liberror-perl (0.17025-1) ...\n", - "Setting up libpsl5:amd64 (0.19.1-5build1) ...\n", + "Setting up lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up libbdd0c2 (2.4-11) ...\n", - "Setting up libtsan0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libtinfo-dev:amd64 (6.1-1ubuntu1.18.04) ...\n", - "Setting up libgc1c2:amd64 (1:7.4.2-8ubuntu1) ...\n", - "Setting up libffi-dev:amd64 (3.2.1-8) ...\n", + "Setting up lib32asan4 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up lib32mpx2 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up iverilog (10.1-0.1build1) ...\n", - "Setting up libpipeline1:amd64 (1.5.0-1) ...\n", - "Setting up libc6-i386 (2.27-3ubuntu1.4) ...\n", - "Setting up librtmp1:amd64 (2.4+20151223.gitfa8646d.1-1) ...\n", - "Setting up libkrb5support0:amd64 (1.16-2ubuntu0.2) ...\n", + "Setting up libllvm11:amd64 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", "Setting up libx32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libclang-6.0-dev (1:6.0-1ubuntu2) ...\n", "Setting up lib32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up libx32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up liblsan0:amd64 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up libx32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libmpx2:amd64 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libllvm4.0:amd64 (1:4.0.1-10) ...\n", - "Setting up libclang1-4.0:amd64 (1:4.0.1-10) ...\n", "Setting up libx32itm1 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up libmpfr4:amd64 (3.1.4-1) ...\n", "Setting up gcc-4.9-base:amd64 (4.9.3-13ubuntu2) ...\n", - "Setting up libc-dev-bin (2.27-3ubuntu1.4) ...\n", "Setting up verilator (3.916-1build1) ...\n", - "Setting up libkeyutils1:amd64 (1.5.9-9.2ubuntu2) ...\n", "Setting up libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...\n", + "Setting up lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", "Setting up lib32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up ca-certificates (20210119~18.04.1) ...\n", - "debconf: unable to initialize frontend: Dialog\n", - "debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 76.)\n", - "debconf: falling back to frontend: Readline\n", - "Updating certificates in /etc/ssl/certs...\n", - "23 added, 27 removed; done.\n", - "Setting up libc6-dev:amd64 (2.27-3ubuntu1.4) ...\n", + "Setting up lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", + "Setting up libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", "Setting up lib32itm1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libitm1:amd64 (8.4.0-1ubuntu1~18.04) ...\n", "Setting up libx32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up lib32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libjsoncpp1:amd64 (1.7.4-3) ...\n", + "Setting up libclang1-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Setting up libclang-cpp11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", "Setting up libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...\n", - "Setting up binfmt-support (2.1.8-2) ...\n", - "mount: /proc/sys/fs/binfmt_misc: permission denied.\n", - "update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.\n", - "mount: /proc/sys/fs/binfmt_misc: permission denied.\n", - "update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.\n", - "invoke-rc.d: could not determine current runlevel\n", - "invoke-rc.d: policy-rc.d denied execution of start.\n", - "Setting up libk5crypto3:amd64 (1.16-2ubuntu0.2) ...\n", - "Setting up libobjc4:amd64 (8.4.0-1ubuntu1~18.04) ...\n", + "Setting up libx32asan4 (7.5.0-3ubuntu1~18.04) ...\n", "Setting up libx32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libclang-common-4.0-dev (1:4.0.1-10) ...\n", + "Setting up libclang-common-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", "Setting up libx32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", "Setting up libbdd-dev (2.4-11) ...\n", - "Setting up llvm-4.0-runtime (1:4.0.1-10) ...\n", - "mount: /proc/sys/fs/binfmt_misc: permission denied.\n", - "update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.\n", "Setting up cpp-4.9 (4.9.3-13ubuntu2) ...\n", - "Setting up libobjc-7-dev:amd64 (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up libx32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", "Setting up libx32asan1 (4.9.3-13ubuntu2) ...\n", + "Setting up clang-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", "Setting up libasan1:amd64 (4.9.3-13ubuntu2) ...\n", "Setting up libgcc-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", + "Setting up lib32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", "Setting up lib32asan1 (4.9.3-13ubuntu2) ...\n", - "Setting up lib32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libkrb5-3:amd64 (1.16-2ubuntu0.2) ...\n", - "Setting up lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", - "Setting up libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", - "Setting up libclang-4.0-dev (1:4.0.1-10) ...\n", + "Setting up libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", "Setting up libstdc++-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", + "Setting up libmpfr-dev:amd64 (4.0.1-1) ...\n", + "Setting up libclang-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", + "Setting up libx32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", "Setting up gcc-4.9 (4.9.3-13ubuntu2) ...\n", - "Setting up clang-4.0 (1:4.0.1-10) ...\n", - "Setting up llvm-4.0 (1:4.0.1-10) ...\n", + "Setting up gcc-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", "Setting up gcc-4.9-plugin-dev (4.9.3-13ubuntu2) ...\n", - "Setting up libgssapi-krb5-2:amd64 (1.16-2ubuntu0.2) ...\n", + "Setting up lib32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up g++-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", "Setting up lib32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Setting up lib32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", "Setting up g++-4.9 (4.9.3-13ubuntu2) ...\n", - "Setting up libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Setting up llvm-4.0-dev (1:4.0.1-10) ...\n", + "Setting up libmpc-dev:amd64 (1.1.0-1) ...\n", "Setting up gcc-4.9-multilib (4.9.3-13ubuntu2) ...\n", - "Setting up libcurl3-gnutls:amd64 (7.58.0-2ubuntu3.13) ...\n", - "Setting up libx32stdc++-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Setting up git (1:2.17.1-1ubuntu0.8) ...\n", - "Setting up g++-4.9-multilib (4.9.3-13ubuntu2) ...\n", - "Processing triggers for libc-bin (2.27-3ubuntu1) ...\n", - "Processing triggers for ca-certificates (20210119~18.04.1) ...\n", - "Updating certificates in /etc/ssl/certs...\n", - "0 added, 0 removed; done.\n", - "Running hooks in /etc/ca-certificates/update.d...\n", - "done.\n", + "Setting up gcc-7-plugin-dev (7.5.0-3ubuntu1~18.04) ...\n", + "Setting up gcc-multilib (4:7.4.0-1ubuntu2.3) ...\n", + "Setting up g++-multilib (4:7.4.0-1ubuntu2.3) ...\n", + "Processing triggers for man-db (2.8.3-2ubuntu0.1) ...\n", + "Processing triggers for libc-bin (2.27-3ubuntu1.2) ...\n", + "/sbin/ldconfig.real: /usr/local/lib/python3.7/dist-packages/ideep4py/lib/libmkldnn.so.0 is not a symbolic link\n", + "\n", "Cloning into 'bambu-tutorial'...\n", - "remote: Enumerating objects: 208, done.\u001b[K\n", - "remote: Counting objects: 100% (52/52), done.\u001b[K\n", - "remote: Compressing objects: 100% (42/42), done.\u001b[K\n", - "remote: Total 208 (delta 10), reused 51 (delta 9), pack-reused 156\u001b[K\n", - "Receiving objects: 100% (208/208), 212.07 MiB | 7.63 MiB/s, done.\n", - "Resolving deltas: 100% (32/32), done.\n", + "remote: Enumerating objects: 214, done.\u001b[K\n", + "remote: Counting objects: 100% (58/58), done.\u001b[K\n", + "remote: Compressing objects: 100% (46/46), done.\u001b[K\n", + "remote: Total 214 (delta 13), reused 56 (delta 11), pack-reused 156\u001b[K\n", + "Receiving objects: 100% (214/214), 297.12 MiB | 37.02 MiB/s, done.\n", + "Resolving deltas: 100% (35/35), done.\n", "env: PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin\n" - ] + ], + "name": "stdout" } ] }, @@ -425,140 +467,8 @@ "%cd /content/bambu-tutorial/01-introduction/Exercise1\n", "!bambu icrc.c --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c 2>&1 | tee icrc1.log" ], - "execution_count": 3, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "[Errno 2] No such file or directory: '/content/bambu-tutorial/01-introduction/Exercise1'\n", - "/opt/colab\n", - " == Bambu executed with: bambu --top-fname=icrc1 --simulator=VERILATOR --simulate --generate-tb=test_icrc1.xml -v2 --print-dot --pretty-print=a.c icrc.c \n", - "\n", - "\n", - "********************************************************************************\n", - " ____ _\n", - " | __ ) __ _ _ __ ___ | |_ _ _\n", - " | _ \\ / _` | '_ ` _ \\| '_ \\| | | |\n", - " | |_) | (_| | | | | | | |_) | |_| |\n", - " |____/ \\__,_|_| |_| |_|_.__/ \\__,_|\n", - "\n", - "********************************************************************************\n", - " High-Level Synthesis Tool\n", - "\n", - " Politecnico di Milano - DEIB\n", - " System Architectures Group\n", - "********************************************************************************\n", - " Copyright (C) 2004-2021 Politecnico di Milano\n", - "Version: PandA 0.9.7-dev - Revision c318ea52ad45d9149d2f2d2a40a8af130ee11f55-panda-0.9.7-dev\n", - "\n", - "Parameters parsed in 0.00 seconds\n", - "\n", - "Target technology = FPGA\n", - "Library Name : STD_FU\n", - " Total cells : 3\n", - " - combinational: 0\n", - " - others: 3\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 10\n", - " - combinational: 0\n", - " - others: 10\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 31\n", - " - combinational: 0\n", - " - others: 31\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 8\n", - " - combinational: 0\n", - " - others: 8\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 56\n", - " - combinational: 0\n", - " - others: 56\n", - "\n", - "Library Name : CS_COMPONENT\n", - " Total cells : 16\n", - " - combinational: 0\n", - " - others: 16\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 2\n", - " - combinational: 0\n", - " - others: 2\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 0\n", - " - combinational: 0\n", - " - others: 0\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 0\n", - " - combinational: 0\n", - " - others: 0\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 17\n", - " - combinational: 0\n", - " - others: 17\n", - "\n", - "Library Name : STD\n", - " Total cells : 14\n", - " - combinational: 0\n", - " - others: 14\n", - "\n", - "Library Name : STD_COMMON\n", - " Total cells : 57\n", - " - combinational: 0\n", - " - others: 57\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 8\n", - " - combinational: 0\n", - " - others: 8\n", - "\n", - "Library Name : STD_PC\n", - " Total cells : 16\n", - " - combinational: 0\n", - " - others: 16\n", - "\n", - "Library Name : STD_SOFT_FLOAT\n", - " Total cells : 2\n", - " - combinational: 0\n", - " - others: 2\n", - "\n", - "Library Name : STD\n", - " Total cells : 72\n", - " - combinational: 0\n", - " - others: 72\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 2\n", - " - combinational: 0\n", - " - others: 2\n", - "\n", - "Library Name : STD_FU\n", - " Total cells : 4\n", - " - combinational: 0\n", - " - others: 4\n", - "\n", - "Library Name : WBWrapper\n", - " Total cells : 12\n", - " - combinational: 0\n", - " - others: 12\n", - "\n", - "Compilation time: 0.00 seconds;\n", - "Error in compilation\n", - "/opt/colab/panda-temp/shell_script_8: line 3: /usr/bin/clang-6.0: No such file or directory\n", - "error -> Front-end compiler returns an error during compilation 2\n", - "\tvoid CompilerWrapper::CompileFile(const string&, std::__cxx11::string&, const string&, bool, CompilerWrapper_CompilerMode)\n", - "\t../../src/wrapper/compiler/compiler_wrapper.cpp:708\n" - ] - } - ] + "execution_count": null, + "outputs": [] }, { "cell_type": "markdown", @@ -765,6 +675,16 @@ "* different frontend compilers (--compiler={I386_GCC49|I386_GCC7|I386_CLANG6|I386_CLANG11})\n" ] }, + { + "cell_type": "markdown", + "metadata": { + "id": "dWWTy4TGZLfk" + }, + "source": [ + "##### **ADPCM from CHStone benchmark suite**\n", + "Adaptive Diferential Pulse-Code Modulation is an algorithm used to perform audio compression (mainly in telephony). It is part of the CHStone benchmark suite for C-based HLS tools." + ] + }, { "cell_type": "code", "metadata": { @@ -803,6 +723,10 @@ "outputs": [] }, { + "cell_type": "markdown", + "metadata": { + "id": "StGBkKaJJEfr" + }, "source": [ "## **Exercise 3**:\n", "\n", @@ -814,11 +738,17 @@ "* nr2 - use a C-based non-restoring division with unrolling factor equal to 2\n", "* NR - use a C-based Newton-Raphson division\n", "* as - use a C-based align divisor shift dividend method\n" - ], + ] + }, + { "cell_type": "markdown", "metadata": { - "id": "StGBkKaJJEfr" - } + "id": "GNUiSuZVbBNS" + }, + "source": [ + "##### **FPDiv from CHStone**\n", + "Soft floating-point division implementation from the CHStone benchmark suite for C-based HLS." + ] }, { "cell_type": "code", @@ -840,9 +770,11 @@ "source": [ "## **Exercise 4**: \n", "\n", - "Write C function that compute the following formula with single precision and double precision data types, experimenting with softfloat and libm implementations.\n", + "Write C implementation that compute the following function:\n", + "\n", + "# $awesome\\_math(a,b,c) = acos(\\frac{a^2+b^2-c^2}{2ab})$\n", "\n", - "![formula.png](data:image/png;base64,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)" + "Experiment with single and double precision data types, different softfloat and libm implementations offered by bambu." ] }, { @@ -851,7 +783,9 @@ "id": "mGggAqUu6SJv" }, "source": [ - "Start by editing this code and then try different bambu options:" + "Start by editing this code and then try different bambu options:\n", + "* Different floating-point arithmetic implementations (--softfloat, --soft-fp, --flopoco)\n", + "* Different libm implementations (--libm-std-rounding)" ] }, { @@ -877,7 +811,7 @@ }, "source": [ "%cd /content/bambu-tutorial/03-optimizations/Exercise4/\n", - "!bambu module.c -O3 -lm --simulate --top-fname=awesome_math --generate-tb=\"a=3.0,b=4.0,c=5.0\" --speculative-sdc-scheduling --libm-std-rounding --hls-fpdiv=G --soft-float" + "!bambu module.c -O3 -lm --simulate --top-fname=awesome_math --generate-tb=\"a=3.0,b=4.0,c=5.0\" --speculative-sdc-scheduling --libm-std-rounding --hls-div=none --soft-float" ], "execution_count": null, "outputs": [] From 511cd127956c9c211162326894977bb74e4472a8 Mon Sep 17 00:00:00 2001 From: Serena Curzel <48477065+SerenaC94@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:15:10 +0200 Subject: [PATCH 13/32] Update bambu.ipynb clean up otuput cell --- documentation/tutorial_ics_2021/bambu.ipynb | 402 +------------------- 1 file changed, 3 insertions(+), 399 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 3492d1383..6486cd6ac 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -46,404 +46,8 @@ "!tar xf bambu-tutorial/panda-dist.tar.gz -C /\n", "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" ], - "execution_count": 1, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Get:1 https://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease [5,527 B]\n", - "Get:2 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ InRelease [3,626 B]\n", - "Ign:3 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 InRelease\n", - "Get:4 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]\n", - "Ign:5 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 InRelease\n", - "Get:6 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Release [697 B]\n", - "Hit:7 https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 Release\n", - "Get:8 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Release.gpg [836 B]\n", - "Get:9 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic InRelease [15.9 kB]\n", - "Ign:1 https://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease\n", - "Get:10 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 Packages [8,790 B]\n", - "Hit:11 http://archive.ubuntu.com/ubuntu bionic InRelease\n", - "Get:12 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]\n", - "Get:13 https://cloud.r-project.org/bin/linux/ubuntu bionic-cran40/ Packages [61.8 kB]\n", - "Hit:14 http://ppa.launchpad.net/cran/libgit2/ubuntu bionic InRelease\n", - "Get:15 http://dk.archive.ubuntu.com/ubuntu xenial InRelease [247 kB]\n", - "Get:17 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic InRelease [15.9 kB]\n", - "Get:18 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]\n", - "Ign:19 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Packages\n", - "Get:19 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 Packages [800 kB]\n", - "Get:20 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic InRelease [21.3 kB]\n", - "Get:21 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [1,415 kB]\n", - "Get:22 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [2,185 kB]\n", - "Get:23 http://security.ubuntu.com/ubuntu bionic-security/restricted amd64 Packages [450 kB]\n", - "Get:24 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main Sources [1,772 kB]\n", - "Get:25 http://archive.ubuntu.com/ubuntu bionic-updates/multiverse amd64 Packages [33.5 kB]\n", - "Get:26 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [2,619 kB]\n", - "Get:27 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [9,827 kB]\n", - "Get:28 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [2,184 kB]\n", - "Get:29 http://ppa.launchpad.net/c2d4u.team/c2d4u4.0+/ubuntu bionic/main amd64 Packages [906 kB]\n", - "Get:30 http://archive.ubuntu.com/ubuntu bionic-updates/restricted amd64 Packages [481 kB]\n", - "Get:31 http://dk.archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1,558 kB]\n", - "Get:32 http://ppa.launchpad.net/deadsnakes/ppa/ubuntu bionic/main amd64 Packages [40.9 kB]\n", - "Get:33 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu bionic/main amd64 Packages [41.6 kB]\n", - "Fetched 24.9 MB in 5s (4,630 kB/s)\n", - "Reading package lists... Done\n", - "W: GPG error: https://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 15CF4D18AF4F7421\n", - "W: The repository 'http://apt.llvm.org/bionic llvm-toolchain-bionic-11 InRelease' is not signed.\n", - "N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.\n", - "N: See apt-secure(8) manpage for repository creation and user configuration details.\n", - "Reading package lists... Done\n", - "Building dependency tree \n", - "Reading state information... Done\n", - "clang-6.0 is already the newest version (1:6.0-1ubuntu2).\n", - "clang-6.0 set to manually installed.\n", - "ca-certificates is already the newest version (20210119~18.04.1).\n", - "git is already the newest version (1:2.17.1-1ubuntu0.8).\n", - "The following additional packages will be installed:\n", - " cpp-4.9 g++-7-multilib gcc-4.9-base gcc-7-multilib lib32asan1 lib32asan4\n", - " lib32atomic1 lib32cilkrts5 lib32gcc-4.9-dev lib32gcc-7-dev lib32gomp1\n", - " lib32itm1 lib32mpx2 lib32quadmath0 lib32stdc++-7-dev lib32ubsan0 libasan1\n", - " libbdd0c2 libc6-dev-i386 libc6-dev-x32 libc6-x32 libclang-common-11-dev\n", - " libclang-cpp11 libclang1-11 libgcc-4.9-dev libgmp-dev libgmpxx4ldbl\n", - " libllvm11 libmpc-dev libmpfr-dev libmpfr4 libstdc++-4.9-dev libx32asan1\n", - " libx32asan4 libx32atomic1 libx32cilkrts5 libx32gcc-4.9-dev libx32gcc-7-dev\n", - " libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc++-7-dev\n", - " libx32stdc++6 libx32ubsan0\n", - "Suggested packages:\n", - " clang-11-doc gcc-4.9-locales g++-4.9-multilib gcc-4.9-doc libstdc++6-4.9-dbg\n", - " lib32stdc++6-7-dbg libx32stdc++6-7-dbg libgcc1-dbg libgomp1-dbg libitm1-dbg\n", - " libatomic1-dbg libasan1-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg\n", - " libcilkrts5-dbg libquadmath0-dbg gtkwave gmp-doc libgmp10-doc libmpfr-doc\n", - " libstdc++-4.9-doc systemc\n", - "Recommended packages:\n", - " llvm-11-dev libomp-11-dev\n", - "The following NEW packages will be installed:\n", - " clang-11 cpp-4.9 g++-4.9 g++-7-multilib g++-multilib gcc-4.9 gcc-4.9-base\n", - " gcc-4.9-multilib gcc-4.9-plugin-dev gcc-7-multilib gcc-7-plugin-dev\n", - " gcc-multilib iverilog lib32asan1 lib32asan4 lib32atomic1 lib32cilkrts5\n", - " lib32gcc-4.9-dev lib32gcc-7-dev lib32gomp1 lib32itm1 lib32mpx2\n", - " lib32quadmath0 lib32stdc++-7-dev lib32ubsan0 libasan1 libbdd-dev libbdd0c2\n", - " libc6-dev-i386 libc6-dev-x32 libc6-x32 libclang-11-dev libclang-6.0-dev\n", - " libclang-common-11-dev libclang-cpp11 libclang1-11 libgcc-4.9-dev libgmp-dev\n", - " libgmpxx4ldbl libllvm11 libmpc-dev libmpfr-dev libmpfr4 libstdc++-4.9-dev\n", - " libx32asan1 libx32asan4 libx32atomic1 libx32cilkrts5 libx32gcc-4.9-dev\n", - " libx32gcc-7-dev libx32gcc1 libx32gomp1 libx32itm1 libx32quadmath0\n", - " libx32stdc++-7-dev libx32stdc++6 libx32ubsan0 verilator\n", - "0 upgraded, 58 newly installed, 0 to remove and 48 not upgraded.\n", - "Need to get 137 MB of archives.\n", - "After this operation, 904 MB of additional disk space will be used.\n", - "WARNING: The following packages cannot be authenticated!\n", - " libllvm11 libclang-cpp11 libclang-common-11-dev libclang1-11 clang-11\n", - " libclang-11-dev\n", - "Authentication warning overridden.\n", - "Get:1 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libllvm11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [17.7 MB]\n", - "Get:7 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libc6-dev-i386 amd64 2.27-3ubuntu1.4 [1,818 kB]\n", - "Get:2 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang-cpp11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [9,554 kB]\n", - "Get:3 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang-common-11-dev amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [4,911 kB]\n", - "Get:8 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9-base amd64 4.9.3-13ubuntu2 [15.3 kB]\n", - "Get:4 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang1-11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [5,501 kB]\n", - "Get:5 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 clang-11 amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [108 kB]\n", - "Get:6 https://apt.llvm.org/bionic llvm-toolchain-bionic-11/main amd64 libclang-11-dev amd64 1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164 [18.1 MB]\n", - "Get:9 http://dk.archive.ubuntu.com/ubuntu xenial/main amd64 libmpfr4 amd64 3.1.4-1 [191 kB]\n", - "Get:10 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libc6-x32 amd64 2.27-3ubuntu1.4 [2,845 kB]\n", - "Get:11 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libc6-dev-x32 amd64 2.27-3ubuntu1.4 [2,017 kB]\n", - "Get:12 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 cpp-4.9 amd64 4.9.3-13ubuntu2 [4,972 kB]\n", - "Get:13 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32gcc1 amd64 1:8.4.0-1ubuntu1~18.04 [40.5 kB]\n", - "Get:14 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32gomp1 amd64 8.4.0-1ubuntu1~18.04 [83.7 kB]\n", - "Get:15 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32gomp1 amd64 8.4.0-1ubuntu1~18.04 [77.8 kB]\n", - "Get:16 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32itm1 amd64 8.4.0-1ubuntu1~18.04 [30.0 kB]\n", - "Get:17 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32itm1 amd64 8.4.0-1ubuntu1~18.04 [28.1 kB]\n", - "Get:18 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32atomic1 amd64 8.4.0-1ubuntu1~18.04 [8,664 B]\n", - "Get:19 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32atomic1 amd64 8.4.0-1ubuntu1~18.04 [9,188 B]\n", - "Get:20 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32asan4 amd64 7.5.0-3ubuntu1~18.04 [362 kB]\n", - "Get:21 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32asan4 amd64 7.5.0-3ubuntu1~18.04 [351 kB]\n", - "Get:22 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32ubsan0 amd64 7.5.0-3ubuntu1~18.04 [140 kB]\n", - "Get:23 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32stdc++6 amd64 8.4.0-1ubuntu1~18.04 [387 kB]\n", - "Get:24 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32ubsan0 amd64 7.5.0-3ubuntu1~18.04 [127 kB]\n", - "Get:25 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32cilkrts5 amd64 7.5.0-3ubuntu1~18.04 [47.2 kB]\n", - "Get:26 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32cilkrts5 amd64 7.5.0-3ubuntu1~18.04 [43.0 kB]\n", - "Get:27 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32mpx2 amd64 8.4.0-1ubuntu1~18.04 [12.9 kB]\n", - "Get:28 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32quadmath0 amd64 8.4.0-1ubuntu1~18.04 [208 kB]\n", - "Get:29 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32quadmath0 amd64 8.4.0-1ubuntu1~18.04 [135 kB]\n", - "Get:30 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32gcc-7-dev amd64 7.5.0-3ubuntu1~18.04 [2,211 kB]\n", - "Get:31 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32gcc-7-dev amd64 7.5.0-3ubuntu1~18.04 [1,999 kB]\n", - "Get:32 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 gcc-7-multilib amd64 7.5.0-3ubuntu1~18.04 [1,048 B]\n", - "Get:33 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 lib32stdc++-7-dev amd64 7.5.0-3ubuntu1~18.04 [626 kB]\n", - "Get:34 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 libx32stdc++-7-dev amd64 7.5.0-3ubuntu1~18.04 [582 kB]\n", - "Get:35 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 g++-7-multilib amd64 7.5.0-3ubuntu1~18.04 [1,064 B]\n", - "Get:36 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 gcc-multilib amd64 4:7.4.0-1ubuntu2.3 [1,428 B]\n", - "Get:37 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 g++-multilib amd64 4:7.4.0-1ubuntu2.3 [1,020 B]\n", - "Get:38 http://archive.ubuntu.com/ubuntu bionic/main amd64 libgmpxx4ldbl amd64 2:6.1.2+dfsg-2 [8,964 B]\n", - "Get:39 http://archive.ubuntu.com/ubuntu bionic/main amd64 libgmp-dev amd64 2:6.1.2+dfsg-2 [316 kB]\n", - "Get:40 http://archive.ubuntu.com/ubuntu bionic/main amd64 libmpfr-dev amd64 4.0.1-1 [249 kB]\n", - "Get:41 http://archive.ubuntu.com/ubuntu bionic/main amd64 libmpc-dev amd64 1.1.0-1 [50.5 kB]\n", - "Get:42 http://archive.ubuntu.com/ubuntu bionic-updates/main amd64 gcc-7-plugin-dev amd64 7.5.0-3ubuntu1~18.04 [1,162 kB]\n", - "Get:43 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libasan1 amd64 4.9.3-13ubuntu2 [197 kB]\n", - "Get:44 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libgcc-4.9-dev amd64 4.9.3-13ubuntu2 [2,073 kB]\n", - "Get:45 http://archive.ubuntu.com/ubuntu bionic/universe amd64 iverilog amd64 10.1-0.1build1 [1,811 kB]\n", - "Get:46 http://archive.ubuntu.com/ubuntu bionic/universe amd64 libbdd0c2 amd64 2.4-11 [51.5 kB]\n", - "Get:47 http://archive.ubuntu.com/ubuntu bionic/universe amd64 libbdd-dev amd64 2.4-11 [454 kB]\n", - "Get:48 http://archive.ubuntu.com/ubuntu bionic/universe amd64 libclang-6.0-dev amd64 1:6.0-1ubuntu2 [20.4 MB]\n", - "Get:49 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9 amd64 4.9.3-13ubuntu2 [5,442 kB]\n", - "Get:50 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libstdc++-4.9-dev amd64 4.9.3-13ubuntu2 [1,126 kB]\n", - "Get:51 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 g++-4.9 amd64 4.9.3-13ubuntu2 [21.0 MB]\n", - "Get:52 http://archive.ubuntu.com/ubuntu bionic/universe amd64 verilator amd64 3.916-1build1 [2,878 kB]\n", - "Get:53 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 lib32asan1 amd64 4.9.3-13ubuntu2 [190 kB]\n", - "Get:54 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libx32asan1 amd64 4.9.3-13ubuntu2 [190 kB]\n", - "Get:55 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 lib32gcc-4.9-dev amd64 4.9.3-13ubuntu2 [1,920 kB]\n", - "Get:56 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 libx32gcc-4.9-dev amd64 4.9.3-13ubuntu2 [1,782 kB]\n", - "Get:57 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9-multilib amd64 4.9.3-13ubuntu2 [964 B]\n", - "Get:58 http://dk.archive.ubuntu.com/ubuntu xenial/universe amd64 gcc-4.9-plugin-dev amd64 4.9.3-13ubuntu2 [806 kB]\n", - "Fetched 137 MB in 4s (31.5 MB/s)\n", - "Extracting templates from packages: 100%\n", - "Selecting previously unselected package libllvm11:amd64.\n", - "(Reading database ... 160772 files and directories currently installed.)\n", - "Preparing to unpack .../00-libllvm11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", - "Unpacking libllvm11:amd64 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Selecting previously unselected package libclang-cpp11.\n", - "Preparing to unpack .../01-libclang-cpp11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", - "Unpacking libclang-cpp11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Selecting previously unselected package libclang-common-11-dev.\n", - "Preparing to unpack .../02-libclang-common-11-dev_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", - "Unpacking libclang-common-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Selecting previously unselected package libclang1-11.\n", - "Preparing to unpack .../03-libclang1-11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", - "Unpacking libclang1-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Selecting previously unselected package clang-11.\n", - "Preparing to unpack .../04-clang-11_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", - "Unpacking clang-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Selecting previously unselected package gcc-4.9-base:amd64.\n", - "Preparing to unpack .../05-gcc-4.9-base_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking gcc-4.9-base:amd64 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libmpfr4:amd64.\n", - "Preparing to unpack .../06-libmpfr4_3.1.4-1_amd64.deb ...\n", - "Unpacking libmpfr4:amd64 (3.1.4-1) ...\n", - "Selecting previously unselected package cpp-4.9.\n", - "Preparing to unpack .../07-cpp-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking cpp-4.9 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libasan1:amd64.\n", - "Preparing to unpack .../08-libasan1_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libasan1:amd64 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libgcc-4.9-dev:amd64.\n", - "Preparing to unpack .../09-libgcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libgcc-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package gcc-4.9.\n", - "Preparing to unpack .../10-gcc-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking gcc-4.9 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libstdc++-4.9-dev:amd64.\n", - "Preparing to unpack .../11-libstdc++-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libstdc++-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package g++-4.9.\n", - "Preparing to unpack .../12-g++-4.9_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking g++-4.9 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libc6-dev-i386.\n", - "Preparing to unpack .../13-libc6-dev-i386_2.27-3ubuntu1.4_amd64.deb ...\n", - "Unpacking libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", - "Selecting previously unselected package libc6-x32.\n", - "Preparing to unpack .../14-libc6-x32_2.27-3ubuntu1.4_amd64.deb ...\n", - "Unpacking libc6-x32 (2.27-3ubuntu1.4) ...\n", - "Selecting previously unselected package libc6-dev-x32.\n", - "Preparing to unpack .../15-libc6-dev-x32_2.27-3ubuntu1.4_amd64.deb ...\n", - "Unpacking libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", - "Selecting previously unselected package libx32gcc1.\n", - "Preparing to unpack .../16-libx32gcc1_1%3a8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32gomp1.\n", - "Preparing to unpack .../17-lib32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32gomp1.\n", - "Preparing to unpack .../18-libx32gomp1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32itm1.\n", - "Preparing to unpack .../19-lib32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32itm1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32itm1.\n", - "Preparing to unpack .../20-libx32itm1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32itm1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32atomic1.\n", - "Preparing to unpack .../21-lib32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32atomic1.\n", - "Preparing to unpack .../22-libx32atomic1_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32asan4.\n", - "Preparing to unpack .../23-lib32asan4_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32asan4 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32asan4.\n", - "Preparing to unpack .../24-libx32asan4_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32asan4 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32ubsan0.\n", - "Preparing to unpack .../25-lib32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32stdc++6.\n", - "Preparing to unpack .../26-libx32stdc++6_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32ubsan0.\n", - "Preparing to unpack .../27-libx32ubsan0_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32cilkrts5.\n", - "Preparing to unpack .../28-lib32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32cilkrts5.\n", - "Preparing to unpack .../29-libx32cilkrts5_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32mpx2.\n", - "Preparing to unpack .../30-lib32mpx2_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32mpx2 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32quadmath0.\n", - "Preparing to unpack .../31-lib32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32quadmath0.\n", - "Preparing to unpack .../32-libx32quadmath0_8.4.0-1ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32gcc-7-dev.\n", - "Preparing to unpack .../33-lib32gcc-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32gcc-7-dev.\n", - "Preparing to unpack .../34-libx32gcc-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package gcc-7-multilib.\n", - "Preparing to unpack .../35-gcc-7-multilib_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking gcc-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package lib32stdc++-7-dev.\n", - "Preparing to unpack .../36-lib32stdc++-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking lib32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package libx32stdc++-7-dev.\n", - "Preparing to unpack .../37-libx32stdc++-7-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking libx32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package g++-7-multilib.\n", - "Preparing to unpack .../38-g++-7-multilib_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking g++-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package gcc-multilib.\n", - "Preparing to unpack .../39-gcc-multilib_4%3a7.4.0-1ubuntu2.3_amd64.deb ...\n", - "Unpacking gcc-multilib (4:7.4.0-1ubuntu2.3) ...\n", - "Selecting previously unselected package g++-multilib.\n", - "Preparing to unpack .../40-g++-multilib_4%3a7.4.0-1ubuntu2.3_amd64.deb ...\n", - "Unpacking g++-multilib (4:7.4.0-1ubuntu2.3) ...\n", - "Selecting previously unselected package lib32asan1.\n", - "Preparing to unpack .../41-lib32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking lib32asan1 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libx32asan1.\n", - "Preparing to unpack .../42-libx32asan1_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libx32asan1 (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package lib32gcc-4.9-dev.\n", - "Preparing to unpack .../43-lib32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking lib32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libx32gcc-4.9-dev.\n", - "Preparing to unpack .../44-libx32gcc-4.9-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package gcc-4.9-multilib.\n", - "Preparing to unpack .../45-gcc-4.9-multilib_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking gcc-4.9-multilib (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libgmpxx4ldbl:amd64.\n", - "Preparing to unpack .../46-libgmpxx4ldbl_2%3a6.1.2+dfsg-2_amd64.deb ...\n", - "Unpacking libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...\n", - "Selecting previously unselected package libgmp-dev:amd64.\n", - "Preparing to unpack .../47-libgmp-dev_2%3a6.1.2+dfsg-2_amd64.deb ...\n", - "Unpacking libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...\n", - "Selecting previously unselected package gcc-4.9-plugin-dev.\n", - "Preparing to unpack .../48-gcc-4.9-plugin-dev_4.9.3-13ubuntu2_amd64.deb ...\n", - "Unpacking gcc-4.9-plugin-dev (4.9.3-13ubuntu2) ...\n", - "Selecting previously unselected package libmpfr-dev:amd64.\n", - "Preparing to unpack .../49-libmpfr-dev_4.0.1-1_amd64.deb ...\n", - "Unpacking libmpfr-dev:amd64 (4.0.1-1) ...\n", - "Selecting previously unselected package libmpc-dev:amd64.\n", - "Preparing to unpack .../50-libmpc-dev_1.1.0-1_amd64.deb ...\n", - "Unpacking libmpc-dev:amd64 (1.1.0-1) ...\n", - "Selecting previously unselected package gcc-7-plugin-dev.\n", - "Preparing to unpack .../51-gcc-7-plugin-dev_7.5.0-3ubuntu1~18.04_amd64.deb ...\n", - "Unpacking gcc-7-plugin-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Selecting previously unselected package iverilog.\n", - "Preparing to unpack .../52-iverilog_10.1-0.1build1_amd64.deb ...\n", - "Unpacking iverilog (10.1-0.1build1) ...\n", - "Selecting previously unselected package libbdd0c2.\n", - "Preparing to unpack .../53-libbdd0c2_2.4-11_amd64.deb ...\n", - "Unpacking libbdd0c2 (2.4-11) ...\n", - "Selecting previously unselected package libbdd-dev.\n", - "Preparing to unpack .../54-libbdd-dev_2.4-11_amd64.deb ...\n", - "Unpacking libbdd-dev (2.4-11) ...\n", - "Selecting previously unselected package libclang-11-dev.\n", - "Preparing to unpack .../55-libclang-11-dev_1%3a11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164_amd64.deb ...\n", - "Unpacking libclang-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Selecting previously unselected package libclang-6.0-dev.\n", - "Preparing to unpack .../56-libclang-6.0-dev_1%3a6.0-1ubuntu2_amd64.deb ...\n", - "Unpacking libclang-6.0-dev (1:6.0-1ubuntu2) ...\n", - "Selecting previously unselected package verilator.\n", - "Preparing to unpack .../57-verilator_3.916-1build1_amd64.deb ...\n", - "Unpacking verilator (3.916-1build1) ...\n", - "Setting up libc6-x32 (2.27-3ubuntu1.4) ...\n", - "Setting up libx32gcc1 (1:8.4.0-1ubuntu1~18.04) ...\n", - "Setting up lib32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libbdd0c2 (2.4-11) ...\n", - "Setting up lib32asan4 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up lib32mpx2 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up iverilog (10.1-0.1build1) ...\n", - "Setting up libllvm11:amd64 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Setting up libx32stdc++6 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libclang-6.0-dev (1:6.0-1ubuntu2) ...\n", - "Setting up lib32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libx32atomic1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libx32gomp1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libx32itm1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libmpfr4:amd64 (3.1.4-1) ...\n", - "Setting up gcc-4.9-base:amd64 (4.9.3-13ubuntu2) ...\n", - "Setting up verilator (3.916-1build1) ...\n", - "Setting up libgmpxx4ldbl:amd64 (2:6.1.2+dfsg-2) ...\n", - "Setting up lib32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up lib32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up lib32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up libc6-dev-i386 (2.27-3ubuntu1.4) ...\n", - "Setting up libc6-dev-x32 (2.27-3ubuntu1.4) ...\n", - "Setting up lib32itm1 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libx32quadmath0 (8.4.0-1ubuntu1~18.04) ...\n", - "Setting up libclang1-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Setting up libclang-cpp11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Setting up libgmp-dev:amd64 (2:6.1.2+dfsg-2) ...\n", - "Setting up libx32asan4 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up libx32cilkrts5 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up libclang-common-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Setting up libx32ubsan0 (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up libbdd-dev (2.4-11) ...\n", - "Setting up cpp-4.9 (4.9.3-13ubuntu2) ...\n", - "Setting up libx32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up libx32asan1 (4.9.3-13ubuntu2) ...\n", - "Setting up clang-11 (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Setting up libasan1:amd64 (4.9.3-13ubuntu2) ...\n", - "Setting up libgcc-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", - "Setting up lib32gcc-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up lib32asan1 (4.9.3-13ubuntu2) ...\n", - "Setting up libx32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Setting up libstdc++-4.9-dev:amd64 (4.9.3-13ubuntu2) ...\n", - "Setting up libmpfr-dev:amd64 (4.0.1-1) ...\n", - "Setting up libclang-11-dev (1:11.1.0~++20210428103915+1fdec59bffc1-1~exp1~20210428204556.164) ...\n", - "Setting up libx32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up gcc-4.9 (4.9.3-13ubuntu2) ...\n", - "Setting up gcc-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up gcc-4.9-plugin-dev (4.9.3-13ubuntu2) ...\n", - "Setting up lib32stdc++-7-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up g++-7-multilib (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up lib32gcc-4.9-dev (4.9.3-13ubuntu2) ...\n", - "Setting up g++-4.9 (4.9.3-13ubuntu2) ...\n", - "Setting up libmpc-dev:amd64 (1.1.0-1) ...\n", - "Setting up gcc-4.9-multilib (4.9.3-13ubuntu2) ...\n", - "Setting up gcc-7-plugin-dev (7.5.0-3ubuntu1~18.04) ...\n", - "Setting up gcc-multilib (4:7.4.0-1ubuntu2.3) ...\n", - "Setting up g++-multilib (4:7.4.0-1ubuntu2.3) ...\n", - "Processing triggers for man-db (2.8.3-2ubuntu0.1) ...\n", - "Processing triggers for libc-bin (2.27-3ubuntu1.2) ...\n", - "/sbin/ldconfig.real: /usr/local/lib/python3.7/dist-packages/ideep4py/lib/libmkldnn.so.0 is not a symbolic link\n", - "\n", - "Cloning into 'bambu-tutorial'...\n", - "remote: Enumerating objects: 214, done.\u001b[K\n", - "remote: Counting objects: 100% (58/58), done.\u001b[K\n", - "remote: Compressing objects: 100% (46/46), done.\u001b[K\n", - "remote: Total 214 (delta 13), reused 56 (delta 11), pack-reused 156\u001b[K\n", - "Receiving objects: 100% (214/214), 297.12 MiB | 37.02 MiB/s, done.\n", - "Resolving deltas: 100% (35/35), done.\n", - "env: PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin\n" - ], - "name": "stdout" - } - ] + "execution_count": null, + "outputs": [] }, { "cell_type": "markdown", @@ -817,4 +421,4 @@ "outputs": [] } ] -} \ No newline at end of file +} From 376f687db574d847d5a64f347afdc6b1cfdd1ad5 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 11:58:08 +0200 Subject: [PATCH 14/32] presentation 02 added --- .../02-Target-Customization.pdf | Bin 0 -> 285826 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 documentation/tutorial_ics_2021/02-Target-Customization.pdf diff --git a/documentation/tutorial_ics_2021/02-Target-Customization.pdf b/documentation/tutorial_ics_2021/02-Target-Customization.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3e0f0ab1a6d13b4a98d79a35390b6c195a35337e GIT binary patch literal 285826 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�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

mup6^Q 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

hV9O9?Ch`!aHLJo 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%0AJ1a6&&86Q2j4hT@_ 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 z Y%zaC*AJ;%^#hsvw4Y%wPoyRYo6T`k~q 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 E2Vmuv6951J literal 0 HcmV?d00001 From 664143b917103a3a5195473fa2355ade0cbaf907 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 12:04:47 +0200 Subject: [PATCH 15/32] clean up --- .../02-Target-Customization.pdf | Bin 285826 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 documentation/tutorial_ics_2021/02-Target-Customization.pdf diff --git a/documentation/tutorial_ics_2021/02-Target-Customization.pdf b/documentation/tutorial_ics_2021/02-Target-Customization.pdf deleted file mode 100644 index 3e0f0ab1a6d13b4a98d79a35390b6c195a35337e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 285826 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

nQKdcJl=dIte%Ql$wZEg^tXLMYM^r3gX* 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�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

hV9O9?Ch`!aHLJo zqKnof1AB*!Enw2RKtZ%QV1m=aaKIcQS|A+|MFPY5S%zL^i@cZ9S2kOa1my$TJt-5< zQ6r}DB4!<(x#~oDww6#s;0O5sRaHK|p1`2ziP^(Z0NR)4f2TqK-zmT<+W7)dld&J~ zS*|_3p?_q?CESV!jK%@bx7>AIHz8r@34NfvnYJjHe8Dv%#S_4z0gR%x^o%mb!+uPg zPYcnHn0K(Kf~W=(urT~guanJFL}Vez;NV)su7z;ACb&O;((BTD0sJ+80RR*r4g41c zI^F%IL1$vn>EciQnIA;${i#0sfT;05)!W}h=AZi6Z{n8@i2Mcf{7dHraB>4;J^qnB zIRR0B8(#Yb`nTPV-(r6o{tM$T%g=v6GJg|Kf9ij!J^ZQvDSw%M0sJlZ+xXvNYil6E ze~kZv`NuXtsP&KO-{EBbM*bV{m&o4`XFh)n|1xn7s;&KD{pH3w;BTRSTK-R{zkT?l z{8w0i!~Y8Y@00;M0wnk^TEFT*rN7hh2k7t4`NQ}-Lw^{5=jadPe=dKa{~H^0ZwL$k z1_2HQ_4myo;C)z9CItflLB&roD2)1crzDeSe}B`UY=)T3Z+53Ltbg&OqK$qBJw-7A z00(^U>196jB%o=dBO*;QTHlb}S3g5+A%=msks1Ih+;S?rtMUlH9q0s4{a$^vHTHpL zcIwY*f@8cUyan$TBw_)1E(DC=ebKYyE>8ejpt`00igv2M+!1 zKn+Im45nWT6VpOfqLI$N`l(C{Q5TiRoz7%xms4P%I8q;VET9Snc*7E`(y`2yN+$w2 zH;{VLr?ZZ0;+uUq0OM*+eS!w7H!3p_%x zAPrItdI{>@%p*$tzTm(8T> z$ z07I)Pv?j%jppa?ka=^eTAkmjZHBS_D#hgp0`(-{9UJk52AQYd3k-q!8jJXb?FCINC zRonM!kj*gZEwSzxL>$EIkeuln?6@*@n`R7=`u2pV4?I(4e2dJ79yE!1Ukn>k1qZ*` zbPsLcmhXLDbS) zD78$Phh*z>Bx$IpLcooG>vw{Il=~5FlU%T4a2aW6f z&V-=n+}jn$ovHB5?(F%~@cLX>^CPTeG>mn~*?iP9lxT#Jnv4BE5?OH6(v*jJIXNGq z6`?kCj%665pgqo-_eXk3lw`AL-=b8&CBDKLdIY|tG#LW9=5>;(*!ucF2Yy9btAK_D zbrrjaB2it<1tMptYD5iq3BWc;j#R~HEn-eihm)q@-)LMFqwjLy%#)@PYxyu{k&Zc( zetQYt96DUChB9ZYr)eQnrsG-UmMx?vxG1Az!?kOZBdV&Ku*_+%Nd!KDL&Bo`QvfE) zp~6%ZpfT$FA6czG(OKnH?F_90uPy%(65)RVgh|pcbEeqoT5*el;=N_$4h7lsMtrp? zec>>bw4Qa`8ge3qYXZ>GY-;#!LJ;pjQa(-H1=fgv`#DkqZ(Zt+q(iNY%*j@QQiU-DUC?+Mq5CIDPq-mu6o3;)>; z8EF3rv_tk^+zb1ct+4-OC+yD-7ZWoORSEvj4w#s=fuqS^dtm?RRvA2S+YGcrMxsRm z@<#{$pZze`v?DJl-}fp@FJE06{MDPanuViLASic)m16n@bW!>Q6ey5T6v3Dj1W-j# z;1X2#KjvBOe={*UUiN6e@Hn;}on09r@`E=la%W7cRTt!3BVXryJ5G|YbZD(Yz{%xFY)&8Jp(xC(q1Lk4Sw z=I!uer*OKktCyK^w6E~C)lE~$xlbumC;;;rlb_pnBZ}y<|A6W?_wwDxp<|?5nxB&B z;r`>W2C<=6N?+GWUEH^vLcPH8;MZcqD3y#~;APM}%~AvsyE~HXRJOSFRTkQy_)VBX zJw9$EX$n9>g*T031`-$b%TQepeyo61WLpq950$XR)i6y+0yEjIKolw)Q0cOG%sONH z4q3P{pegV!FdP%`J>D(EA!G!Ft3><0-`65f zZ&EOlDTky$ydEQWY8}-3@A!SBJ$N?3M2FPGnid3q*WOx2gS!Zv)U#(Nd0LCCI;I*2OqDeQ9 zNn;YFqP1it-}kxX`F2k?q8X6avd_i%?F@uhqH23E^>jml`vvv++Yr!+onCMa2NT%sXNOhB86DcvC6~=^*(R+7?2gjFvDqRlTJmyrdeeq>3JLy87Mg zsP%WKJ?OSG2JmF@nfu6~bQ|-0V1SvZYbRaLTHQC=!e@uGo^E}$YrjYN2|e^FBfw;!ekdPonwklAJZ^biodzt%5-$;lr%Ti&n~nQzWn7gvo*|9vT&vXs5}AMz|jG zwIJEP<6gP~*e5CJ;{J67^xHcn!~RQ6`m&O>Vc)OuclbH9$Nr3Gq3fZ`Cm`tw?H_)c z@sEWxq$dh&Se@#HdvRVppE8wDHj?yhQ--l6kdK9Fb}wB0^a{_ozK7AxCFFcg*wR*1 zdFFMMsL*43HX$?r{I&q2eQuE6=Zuzf?9%~2A)Eh+Hi7|7p~nmpY{_*S5HK9+(emrnRoEz$X_{?$)H`AV>?Hg#sTS?p}qAR?Mm?-%0AJ1a6&&86Q2j4hT@_ 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 z Y%zaC*AJ;%^#hsvw4Y%wPoyRYo6T`k~q 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 E2Vmuv6951J From 4793dd7ee70eb4dd89b8de5458d9a7c32cabebbb Mon Sep 17 00:00:00 2001 From: Fabrizio Ferrandi Date: Mon, 14 Jun 2021 12:07:25 +0200 Subject: [PATCH 16/32] Fix on intro. --- documentation/tutorial_ics_2021/bambu.ipynb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 6486cd6ac..640ef7a0b 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -31,11 +31,7 @@ "id": "ZoxqLkfA9zqM", "tags": [ "outputPrepend" - ], - "outputId": "bd1e15a0-4857-4e4a-f6e5-0227fe2cd24c", - "colab": { - "base_uri": "https://localhost:8080/" - } + ] }, "source": [ "!echo \"deb http://dk.archive.ubuntu.com/ubuntu/ xenial main universe\" >> /etc/apt/sources.list\n", @@ -43,7 +39,7 @@ "!apt-get -o Acquire::AllowInsecureRepositories=true update\n", "!apt-get -o Acquire::AllowInsecureRepositories=true --allow-unauthenticated install -y --no-install-recommends ca-certificates git libbdd-dev iverilog verilator gcc-4.9 gcc-4.9-plugin-dev gcc-4.9-multilib g++-4.9 g++-multilib gcc-multilib gcc-7-plugin-dev g++-multilib clang-6.0 libclang-6.0-dev clang-11 libclang-11-dev\n", "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", - "!tar xf bambu-tutorial/panda-dist.tar.gz -C /\n", + "!tar xf bambu-tutorial/panda-dist.tar.xz -C /\n", "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" ], "execution_count": null, @@ -57,7 +53,7 @@ "source": [ "# **Introduction**\n", "\n", - "Have a look at the C code for **Exercise 1**: /content/bambu-tutorial/01-introduction/Exercise1/module.c\n", + "Have a look at the C code for **Exercise 1**: /content/bambu-tutorial/01-introduction/Exercise1/icrc.c\n", "\n", "Launch bambu:" ] From 28b17f505d35b1dde3e66ceb88c74245c3a46bd8 Mon Sep 17 00:00:00 2001 From: Michele Fiorito Date: Mon, 14 Jun 2021 13:18:16 +0200 Subject: [PATCH 17/32] Section 3 minor fixes --- documentation/tutorial_ics_2021/bambu.ipynb | 61 +++++++++------------ 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 640ef7a0b..b6807f6dd 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -262,17 +262,7 @@ "id": "IlQDB6nqHqz0" }, "source": [ - "# **Optimizations**\n", - "\n", - "## **Exercise 1**: \n", - "\n", - "Modify Bambu options to evaluate the effect of:\n", - "\n", - "\n", - "* different levels of optimization (-O0, -O1, -O2, -O3, -Os)\n", - "* vectorization (-ftree-vectorize)\n", - "* inlining (-finline-limit=100000)\n", - "* different frontend compilers (--compiler={I386_GCC49|I386_GCC7|I386_CLANG6|I386_CLANG11})\n" + "# **Optimizations**\n" ] }, { @@ -281,8 +271,19 @@ "id": "dWWTy4TGZLfk" }, "source": [ - "##### **ADPCM from CHStone benchmark suite**\n", - "Adaptive Diferential Pulse-Code Modulation is an algorithm used to perform audio compression (mainly in telephony). It is part of the CHStone benchmark suite for C-based HLS tools." + "## **Exercise 1**: \n", + "\n", + "Modify Bambu options to evaluate the effect of:\n", + "\n", + "\n", + "* different levels of optimization (-O0, -O1, -O2, -O3, -Os)\n", + "* vectorization (-ftree-vectorize)\n", + "* inlining (-finline-limit=100000)\n", + "* different frontend compilers (--compiler={I386_GCC49|I386_GCC7|I386_CLANG6|I386_CLANG11})\n", + "\n", + "#### **ADPCM from CHStone benchmark suite**\n", + "Adaptive Diferential Pulse-Code Modulation is an algorithm used to perform audio compression (mainly in telephony). It is part of the CHStone benchmark suite for C-based HLS tools.\n", + "* Yuko Hara, Hiroyuki Tomiyama, Shinya Honda and Hiroaki Takada, \"Proposal and Quantitative Analysis of the CHStone Benchmark Program Suite for Practical C-based High-level Synthesis\", *Journal of Information Processing*, Vol. 17, pp.242-254, (2009)." ] }, { @@ -328,7 +329,7 @@ "id": "StGBkKaJJEfr" }, "source": [ - "## **Exercise 3**:\n", + "## **Exercise 3**\n", "\n", "Modify Bambu options to evaluate the effect of different integer division implementations.\n", "\n", @@ -337,17 +338,11 @@ "* nr1 - use a C-based non-restoring division with unrolling factor equal to 1 (default)\n", "* nr2 - use a C-based non-restoring division with unrolling factor equal to 2\n", "* NR - use a C-based Newton-Raphson division\n", - "* as - use a C-based align divisor shift dividend method\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "GNUiSuZVbBNS" - }, - "source": [ - "##### **FPDiv from CHStone**\n", - "Soft floating-point division implementation from the CHStone benchmark suite for C-based HLS." + "* as - use a C-based align divisor shift dividend method\n", + "\n", + "#### **FPDiv from CHStone**\n", + "Soft floating-point division implementation from the CHStone benchmark suite for C-based HLS.\n", + "* Yuko Hara, Hiroyuki Tomiyama, Shinya Honda and Hiroaki Takada, \"Proposal and Quantitative Analysis of the CHStone Benchmark Program Suite for Practical C-based High-level Synthesis\", *Journal of Information Processing*, Vol. 17, pp.242-254, (2009).\n" ] }, { @@ -374,18 +369,12 @@ "\n", "# $awesome\\_math(a,b,c) = acos(\\frac{a^2+b^2-c^2}{2ab})$\n", "\n", - "Experiment with single and double precision data types, different softfloat and libm implementations offered by bambu." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "mGggAqUu6SJv" - }, - "source": [ + "Experiment with single and double precision data types, different softfloat and libm implementations offered by bambu.\n", + "\n", "Start by editing this code and then try different bambu options:\n", "* Different floating-point arithmetic implementations (--softfloat, --soft-fp, --flopoco)\n", - "* Different libm implementations (--libm-std-rounding)" + "* Different libm implementations (--libm-std-rounding)\n", + "* Different square implementation (pow, simple multiplication)" ] }, { @@ -417,4 +406,4 @@ "outputs": [] } ] -} +} \ No newline at end of file From 937078f5d6b25361bae3fa798258028742d270d7 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 14:20:55 +0200 Subject: [PATCH 18/32] simd and context switch added --- documentation/tutorial_ics_2021/bambu.ipynb | 237 +++++++++++++++++--- 1 file changed, 210 insertions(+), 27 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index b6807f6dd..308a2bbea 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -39,7 +39,26 @@ "!apt-get -o Acquire::AllowInsecureRepositories=true update\n", "!apt-get -o Acquire::AllowInsecureRepositories=true --allow-unauthenticated install -y --no-install-recommends ca-certificates git libbdd-dev iverilog verilator gcc-4.9 gcc-4.9-plugin-dev gcc-4.9-multilib g++-4.9 g++-multilib gcc-multilib gcc-7-plugin-dev g++-multilib clang-6.0 libclang-6.0-dev clang-11 libclang-11-dev\n", "!git clone https://github.com/SerenaC94/bambu-tutorial.git\n", - "!tar xf bambu-tutorial/panda-dist.tar.xz -C /\n", + "!tar xf bambu-tutorial/panda-dist.tar.xz -C /" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "G3ueZCx7YYpW" + }, + "source": [ + "Edit PATH variable (to be repeated if the Google Colab runtime is restarted):" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dgqgZ30DYf27" + }, + "source": [ "%env PATH=/opt/panda/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/tools/node/bin:/tools/google-cloud-sdk/bin:/opt/bin" ], "execution_count": null, @@ -129,29 +148,17 @@ "source": [ "# **Target selection and tool integration**\n", "\n", - "**Exercise 1**: synthesize a module that returns the minimum and maximum value in an array.\n", - "\n", + "## **Exercise 1**: synthesize a module that returns the minimum and maximum value in an array of integers with arbitrary size.\n", "Start by modifying the code below:" ] }, - { - "cell_type": "code", - "metadata": { - "id": "paTFkaqqiQBk" - }, - "source": [ - "%cd /content/bambu-tutorial/02-target_customization/Exercise1/" - ], - "execution_count": null, - "outputs": [] - }, { "cell_type": "code", "metadata": { "id": "Qk6YNsG6hFS8" }, "source": [ - "%%writefile minmax.c\n", + "%%writefile /content/bambu-tutorial/02-target_customization/Exercise1/minmax.c\n", "void max(int input[10], int * max)\n", "{\n", " int local_max = input[0];\n", @@ -175,7 +182,7 @@ "id": "l2LzyiJbhMIs" }, "source": [ - "Synthesize with bambu:" + "Synthesize with Bambu:" ] }, { @@ -184,6 +191,7 @@ "id": "ghLrn4d0hOH_" }, "source": [ + "%cd /content/bambu-tutorial/02-target_customization/Exercise1/\n", "!bambu minmax.c" ], "execution_count": null, @@ -195,7 +203,7 @@ "id": "mJgyQoCPBfAz" }, "source": [ - "**Exercise 2**: write a testbench to test arrays with different elemets and different sizes.\n", + "## **Exercise 2**: write a testbench to test arrays with different elements and different sizes.\n", "\n", "Start by modifying the code below **(change parameter names so that they correspond to function arguments in your code)**:" ] @@ -206,10 +214,10 @@ "id": "5oOodjt2Bz9P" }, "source": [ - "%%writefile test.xml\n", + "%%writefile /content/bambu-tutorial/02-target_customization/Exercise1/testbench.xml\n", "\n", "\n", - " \n", + " \n", "" ], "execution_count": null, @@ -221,7 +229,7 @@ "id": "_n8JLBQYCzIA" }, "source": [ - "!bambu minmax.c --generate-tb=test.xml --simulate" + "!bambu minmax.c --generate-tb=testbench.xml --simulate" ], "execution_count": null, "outputs": [] @@ -232,16 +240,16 @@ "id": "cbLOvR1FEFoP" }, "source": [ - "**Exercise 3**: compare simulations across different target platforms and frequencies.\n", + "## **Exercise 3**: compare simulations across different target platforms and frequencies.\n", "\n", "Start from the given command and modify the options appropriately to test the following combinations:\n", "\n", "\n", - "* xc4vlx100-10ff1513 – 66MHz\n", - "* 5SGXEA7N2F45C1 – 200MHz\n", - "* xc7vx690t-3ffg1930-VVD – 100MHz\n", - "* xc7vx690t-3ffg1930-VVD – 333MHz\n", - "* xc7vx690t-3ffg1930-VVD – 400MHz\n", + "* xc4vlx100-10ff1513 (Xilinx Virtex 4) – 66MHz\n", + "* 5SGXEA7N2F45C1 (Intel Stratix V) – 200MHz\n", + "* xc7vx690t-3ffg1930-VVD (Xilinx Virtex 7) – 100MHz\n", + "* xc7vx690t-3ffg1930-VVD (Xilinx Virtex 7) – 333MHz\n", + "* xc7vx690t-3ffg1930-VVD (Xilinx Virtex 7) – 400MHz\n", "\n" ] }, @@ -404,6 +412,181 @@ ], "execution_count": null, "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "RLfPwBYWgl9v" + }, + "source": [ + "# **SIMD vectorization**\n", + "\n", + "Exercise 1: generate an accelerator with vector size of 1." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5isGCK0jgykN" + }, + "source": [ + "%cd /content/bambu-tutorial/04-simd/Exercise1/\n", + "!bambu --compiler=I386_GCC49 --device-name=5SGXEA7N2F45C1 --simulate -fwhole-program -fno-delete-null-pointer-checks --clock-period=10 --experimental-setup=BAMBU-BALANCED-MP -fdisable-tree-cunroll -fdisable-tree-ivopts --param max-inline-insns-auto=1000 histogram.c -fopenmp-simd=1 --pretty-print=output.c" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "sduMUHPag6FE" + }, + "source": [ + "Compare **histogram.c** and **output.c** to see the effects of code transformations." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "Luq_0W6YhbnO" + }, + "source": [ + "Exercise 2: **edit** Bambu options to generate an accelerator with vector size of 4 and evaluate the speed-up." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_JyDjCrchnaq" + }, + "source": [ + "!bambu --compiler=I386_GCC49 --device-name=5SGXEA7N2F45C1 --simulate -fwhole-program -fno-delete-null-pointer-checks --clock-period=10 --experimental-setup=BAMBU-BALANCED-MP -fdisable-tree-cunroll -fdisable-tree-ivopts --param max-inline-insns-auto=1000 histogram.c -fopenmp-simd=1 --pretty-print=output.c" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "g5VDY9N3h4cv" + }, + "source": [ + "Exercise 3: **edit** Bambu options to generate accelerators with vector size equal to 2, 3, 4, and 8; evaluate the speed-up." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "_OTW8OrNiJTe" + }, + "source": [ + "!bambu --compiler=I386_GCC49 --device-name=5SGXEA7N2F45C1 --simulate -fwhole-program -fno-delete-null-pointer-checks --clock-period=10 --experimental-setup=BAMBU-BALANCED-MP -fdisable-tree-cunroll -fdisable-tree-ivopts --param max-inline-insns-auto=1000 histogram.c -fopenmp-simd=1 --pretty-print=output.c" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "gryqeIGXiRS0" + }, + "source": [ + "# **Context switching**\n", + "\n", + "Exercise 1: create a sequential accelerator for the LUBM-t4 benchmark.\n", + "\n", + "Edit /common/bambu-tutorial/05-context-switch/Exercise1/bambu.sh as follows:\n", + "\n", + "\n", + "* set `search` as top function\n", + "* specify that all memories need to be allocated outside the accelerator\n", + "* set the external memory latency to 20 for both read and write\n", + "* add the `test-1.xml` testbench for simulation\n", + "\n", + "Hint: you can find out all Bambu options by running `bambu --help`." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "B-9M47ZxHkui" + }, + "source": [ + "%cd /content/bambu-tutorial/05-context-switch/Exercise1/\n", + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "enf-YqUHIK_V" + }, + "source": [ + "Exercise 2: create a parallel accelerator without context switching.\n", + "\n", + "Edit the script with Bambu options as follows:\n", + "\n", + "* specify that 2 copies of the kernel need to be synthesized with `--num-threads=2`\n", + "* select 4 external memory banks with 2 channels\n", + "* disable context switching by setting the correspondent option to 1\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "52HsQm4KaPiH" + }, + "source": [ + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "b2lheBF0azgJ" + }, + "source": [ + "Exercise 3: introduce context switching.\n", + "\n", + "Keep all options as before, but set 4 logic threads per kernel." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rzWIDXyAbVO8" + }, + "source": [ + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "FiiteRZ5ba6x" + }, + "source": [ + "Exercise 4: explore different configurations.\n", + "\n", + "Change the number of contexts, memory banks and memory channels to find a better solution." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "lU-kWtVEbZFY" + }, + "source": [ + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] } ] -} \ No newline at end of file +} From fb7f411929775621b6a8c1aca50e99852cd430dd Mon Sep 17 00:00:00 2001 From: Fabrizio Ferrandi Date: Mon, 14 Jun 2021 14:40:06 +0200 Subject: [PATCH 19/32] New version of the notebook. --- documentation/tutorial_ics_2021/bambu.ipynb | 162 +++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 640ef7a0b..141ae9e38 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -82,6 +82,7 @@ "* test_icrc1.xml\n", "* simulate_icrc1.sh\n", "* synthesize_Synthesis_icrc1.sh\n", + "* a.c\n", "\n", "\n", "\n", @@ -103,10 +104,17 @@ { "cell_type": "markdown", "metadata": { - "id": "1vnkBTJD-lzY" + "id": "cZUdpPMNA-Vk" }, "source": [ - "Navigate through the explorer to see the code for other exercises, **edit** this box to execute them:" + "\n", + "**Exercise 2**: /content/bambu-tutorial/01-introduction/Exercise2/tree.c\n", + "\n", + "Search and insertion in a binary tree\n", + " - Two data structures: stack and binary tree\n", + " - Static memory allocators\n", + " - Tail recursive functions\n", + " - Use of pointer to pointers (some HLSs have problems)" ] }, { @@ -121,6 +129,154 @@ "execution_count": null, "outputs": [] }, + { + "cell_type": "markdown", + "metadata": { + "id": "5oTPfkiRQ_HO" + }, + "source": [ + "Inspect the generated files in the explorer tab on the left:\n", + "\n", + "* bambu.sh\n", + "* profiling_results.txt" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "A50OIi5sS_6C" + }, + "source": [ + "\n", + "**Exercise 3**: /content/bambu-tutorial/01-introduction/Exercise3/Keccak.c\n", + "\n", + "Crypto core: synthesis starting from .ll" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "RempES6CTcvl" + }, + "source": [ + "%cd /content/bambu-tutorial/01-introduction/Exercise3/\n", + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "TDEuJ3fLUIVH" + }, + "source": [ + "Inspect the generated files in the explorer tab on the left:\n", + "\n", + "* bambu.sh\n", + "* test.ll" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "u55xe2k1YikL" + }, + "source": [ + "Same crypto core but with clang11\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "uxDYcFVDYRbM" + }, + "source": [ + "%cd /content/bambu-tutorial/01-introduction/Exercise3/\n", + "!./bambu-clang11.sh\n" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "70S_CvTsZLcr" + }, + "source": [ + "**Exercise 4**: /content/bambu-tutorial/01-introduction/Exercise4/LUdecomposition.c" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "rVVbmuOLaDyk" + }, + "source": [ + "%cd /content/bambu-tutorial/01-introduction/Exercise4/\n", + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "pb72PNDCaWJY" + }, + "source": [ + "from graphviz import Source\n", + "Source.from_file('ludecomp/HLS_output/dot/call_graph_final.dot')" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "xOdDf6q7bocd" + }, + "source": [ + "**Exercise 5**: /content/bambu-tutorial/01-introduction/Exercise5/main_test.c\n" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "CyB40S-wcAsN" + }, + "source": [ + "%cd /content/bambu-tutorial/01-introduction/Exercise5/\n", + "!git pull\n", + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "IUtMMEpPc-qB" + }, + "source": [ + "**Exercise 6**: \n", + "- /content/bambu-tutorial/01-introduction/Exercise6/test.c \n", + "- /content/bambu-tutorial/01-introduction/Exercise6/less.c \n", + "- /content/bambu-tutorial/01-introduction/Exercise6/qsort.c" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "vPpnKBSidsQf" + }, + "source": [ + "%cd /content/bambu-tutorial/01-introduction/Exercise6/\n", + "!./bambu.sh" + ], + "execution_count": null, + "outputs": [] + }, { "cell_type": "markdown", "metadata": { @@ -417,4 +573,4 @@ "outputs": [] } ] -} +} \ No newline at end of file From 6d11e62f07dc3720a7af5d317bca470b003edc6d Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 14:56:40 +0200 Subject: [PATCH 20/32] minor layout fixes --- documentation/tutorial_ics_2021/bambu.ipynb | 107 ++++++++++++++------ 1 file changed, 77 insertions(+), 30 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index cc663c6d8..60af25d21 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -5,7 +5,8 @@ "colab": { "name": "bambu.ipynb", "provenance": [], - "collapsed_sections": [] + "collapsed_sections": [], + "toc_visible": true }, "kernelspec": { "name": "python3", @@ -71,8 +72,17 @@ }, "source": [ "# **Introduction**\n", + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "la-zNHdckW4f" + }, + "source": [ + "## **Exercise 1**\n", "\n", - "Have a look at the C code for **Exercise 1**: /content/bambu-tutorial/01-introduction/Exercise1/icrc.c\n", + "Have a look at the C code in /content/bambu-tutorial/01-introduction/Exercise1/icrc.c\n", "\n", "Launch bambu:" ] @@ -127,7 +137,8 @@ }, "source": [ "\n", - "**Exercise 2**: /content/bambu-tutorial/01-introduction/Exercise2/tree.c\n", + "##**Exercise 2** + "Look into /content/bambu-tutorial/01-introduction/Exercise2/tree.c\n", "\n", "Search and insertion in a binary tree\n", " - Two data structures: stack and binary tree\n", @@ -167,7 +178,8 @@ }, "source": [ "\n", - "**Exercise 3**: /content/bambu-tutorial/01-introduction/Exercise3/Keccak.c\n", + "##**Exercise 3**: + "/content/bambu-tutorial/01-introduction/Exercise3/Keccak.c\n", "\n", "Crypto core: synthesis starting from .ll" ] @@ -223,7 +235,8 @@ "id": "70S_CvTsZLcr" }, "source": [ - "**Exercise 4**: /content/bambu-tutorial/01-introduction/Exercise4/LUdecomposition.c" + "##**Exercise 4** + "/content/bambu-tutorial/01-introduction/Exercise4/LUdecomposition.c" ] }, { @@ -256,7 +269,8 @@ "id": "xOdDf6q7bocd" }, "source": [ - "**Exercise 5**: /content/bambu-tutorial/01-introduction/Exercise5/main_test.c\n" + "##**Exercise 5** + "/content/bambu-tutorial/01-introduction/Exercise5/main_test.c\n" ] }, { @@ -278,7 +292,7 @@ "id": "IUtMMEpPc-qB" }, "source": [ - "**Exercise 6**: \n", + "##**Exercise 6** \n", "- /content/bambu-tutorial/01-introduction/Exercise6/test.c \n", "- /content/bambu-tutorial/01-introduction/Exercise6/less.c \n", "- /content/bambu-tutorial/01-introduction/Exercise6/qsort.c" @@ -296,15 +310,24 @@ "execution_count": null, "outputs": [] }, + { + "cell_type": "markdown", + "metadata": { + "id": "J6sGI0m8fJ1J" + }, + "source": [ + "# **Target selection and tool integration**" + ] + }, { "cell_type": "markdown", "metadata": { "id": "BZdmA4VKfyzL" }, "source": [ - "# **Target selection and tool integration**\n", + "## **Exercise 1**\n", "\n", - "## **Exercise 1**: synthesize a module that returns the minimum and maximum value in an array of integers with arbitrary size.\n", + "Synthesize a module that returns the minimum and maximum value in an array of integers with arbitrary size.\n", "Start by modifying the code below:" ] }, @@ -359,7 +382,9 @@ "id": "mJgyQoCPBfAz" }, "source": [ - "## **Exercise 2**: write a testbench to test arrays with different elements and different sizes.\n", + "## **Exercise 2**\n", + "\n", + "Write a testbench to test arrays with different elements and different sizes.\n", "\n", "Start by modifying the code below **(change parameter names so that they correspond to function arguments in your code)**:" ] @@ -396,7 +421,8 @@ "id": "cbLOvR1FEFoP" }, "source": [ - "## **Exercise 3**: compare simulations across different target platforms and frequencies.\n", + "## **Exercise 3**\n", + "Compare simulations across different target platforms and frequencies.\n", "\n", "Start from the given command and modify the options appropriately to test the following combinations:\n", "\n", @@ -415,7 +441,7 @@ "id": "FryYdWLmEh81" }, "source": [ - "!bambu minmax.c --device-name=xc4vlx100-10ff1513 --clock-period=15 --simulate" + "!bambu minmax.c --device-name=xc4vlx100-10ff1513 --clock-period=15 --simulate --generate-tb=testbench.xml" ], "execution_count": null, "outputs": [] @@ -435,7 +461,7 @@ "id": "dWWTy4TGZLfk" }, "source": [ - "## **Exercise 1**: \n", + "## **Exercise 1** \n", "\n", "Modify Bambu options to evaluate the effect of:\n", "\n", @@ -468,7 +494,7 @@ "id": "mJOV50V4IiE2" }, "source": [ - "## **Exercise 2**: \n", + "## **Exercise 2** \n", "\n", "Use the command that yielded the best result in Exercise 1 and verify if SDC scheduling can introduce further improvements.\n", "\n", @@ -527,7 +553,7 @@ "id": "YSRwNv1o2Jqx" }, "source": [ - "## **Exercise 4**: \n", + "## **Exercise 4** \n", "\n", "Write C implementation that compute the following function:\n", "\n", @@ -569,15 +595,23 @@ "execution_count": null, "outputs": [] }, - { +{ "cell_type": "markdown", "metadata": { "id": "RLfPwBYWgl9v" }, "source": [ - "# **SIMD vectorization**\n", - "\n", - "Exercise 1: generate an accelerator with vector size of 1." + "# **SIMD vectorization**" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "NKH7rLb8fgk7" + }, + "source": [ + "## **Exercise 1** \n", + "Generate an accelerator with vector size of 1.\n" ] }, { @@ -598,7 +632,7 @@ "id": "sduMUHPag6FE" }, "source": [ - "Compare **histogram.c** and **output.c** to see the effects of code transformations." + "Look into **output.c** to see the effects of code transformations." ] }, { @@ -607,7 +641,8 @@ "id": "Luq_0W6YhbnO" }, "source": [ - "Exercise 2: **edit** Bambu options to generate an accelerator with vector size of 4 and evaluate the speed-up." + "## **Exercise 2** \n", + "**Edit** Bambu options to generate an accelerator with vector size of 4 and evaluate the speed-up." ] }, { @@ -627,7 +662,8 @@ "id": "g5VDY9N3h4cv" }, "source": [ - "Exercise 3: **edit** Bambu options to generate accelerators with vector size equal to 2, 3, 4, and 8; evaluate the speed-up." + "## **Exercise 3** \n", + "**Edit** Bambu options to generate accelerators with vector size equal to 2, 3, 4, and 8; evaluate the speed-up." ] }, { @@ -641,15 +677,23 @@ "execution_count": null, "outputs": [] }, + { + "cell_type": "markdown", + "metadata": { + "id": "dqYtjGVigqpp" + }, + "source": [ + "# **Context switching**" + ] + }, { "cell_type": "markdown", "metadata": { "id": "gryqeIGXiRS0" }, "source": [ - "# **Context switching**\n", - "\n", - "Exercise 1: create a sequential accelerator for the LUBM-t4 benchmark.\n", + "## **Exercise 1** \n", + "Create a sequential accelerator for the LUBM-t4 benchmark.\n", "\n", "Edit /common/bambu-tutorial/05-context-switch/Exercise1/bambu.sh as follows:\n", "\n", @@ -680,11 +724,12 @@ "id": "enf-YqUHIK_V" }, "source": [ - "Exercise 2: create a parallel accelerator without context switching.\n", + "## **Exercise 2** \n", + "Create a parallel accelerator without context switching.\n", "\n", "Edit the script with Bambu options as follows:\n", "\n", - "* specify that 2 copies of the kernel need to be synthesized with `--num-threads=2`\n", + "* specify that 2 copies of the kernel need to be synthesized\n", "* select 4 external memory banks with 2 channels\n", "* disable context switching by setting the correspondent option to 1\n" ] @@ -706,7 +751,8 @@ "id": "b2lheBF0azgJ" }, "source": [ - "Exercise 3: introduce context switching.\n", + "## **Exercise 3**\n", + "Introduce context switching.\n", "\n", "Keep all options as before, but set 4 logic threads per kernel." ] @@ -728,7 +774,8 @@ "id": "FiiteRZ5ba6x" }, "source": [ - "Exercise 4: explore different configurations.\n", + "## **Exercise 4**\n", + "Explore different configurations.\n", "\n", "Change the number of contexts, memory banks and memory channels to find a better solution." ] @@ -745,4 +792,4 @@ "outputs": [] } ] -} \ No newline at end of file +} From 6bb4948f35862c7ab33a46213154dbe3ff6d0f36 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 14:58:06 +0200 Subject: [PATCH 21/32] fix typo --- documentation/tutorial_ics_2021/bambu.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 60af25d21..737b166cb 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -71,7 +71,7 @@ "id": "la-zNHdckW4f" }, "source": [ - "# **Introduction**\n", + "# **Introduction**\n" ] }, { From eb2cf4c9993916fbb1b6febd92bad02c34023617 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 14:59:08 +0200 Subject: [PATCH 22/32] fix other typo --- documentation/tutorial_ics_2021/bambu.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 737b166cb..498a0379b 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -137,7 +137,7 @@ }, "source": [ "\n", - "##**Exercise 2** + "##**Exercise 2**\n", "Look into /content/bambu-tutorial/01-introduction/Exercise2/tree.c\n", "\n", "Search and insertion in a binary tree\n", From 503b9874e74718482711cdf4a043bbdecdac5c87 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 15:00:59 +0200 Subject: [PATCH 23/32] fix --- documentation/tutorial_ics_2021/bambu.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index 498a0379b..e06ef44e8 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -136,8 +136,8 @@ "id": "cZUdpPMNA-Vk" }, "source": [ + "## **Exercise 2**\n", "\n", - "##**Exercise 2**\n", "Look into /content/bambu-tutorial/01-introduction/Exercise2/tree.c\n", "\n", "Search and insertion in a binary tree\n", From bc13f654d80ef7b064794664f84b3a435cbe5ab5 Mon Sep 17 00:00:00 2001 From: curzel Date: Mon, 14 Jun 2021 15:02:03 +0200 Subject: [PATCH 24/32] last fixes --- documentation/tutorial_ics_2021/bambu.ipynb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/documentation/tutorial_ics_2021/bambu.ipynb b/documentation/tutorial_ics_2021/bambu.ipynb index e06ef44e8..b9e2e8468 100644 --- a/documentation/tutorial_ics_2021/bambu.ipynb +++ b/documentation/tutorial_ics_2021/bambu.ipynb @@ -178,7 +178,8 @@ }, "source": [ "\n", - "##**Exercise 3**: + "## **Exercise 3**\n", + "\n", "/content/bambu-tutorial/01-introduction/Exercise3/Keccak.c\n", "\n", "Crypto core: synthesis starting from .ll" @@ -235,7 +236,8 @@ "id": "70S_CvTsZLcr" }, "source": [ - "##**Exercise 4** + "## **Exercise 4**\n", + "\n", "/content/bambu-tutorial/01-introduction/Exercise4/LUdecomposition.c" ] }, @@ -269,7 +271,8 @@ "id": "xOdDf6q7bocd" }, "source": [ - "##**Exercise 5** + "## **Exercise 5**\n", + "\n", "/content/bambu-tutorial/01-introduction/Exercise5/main_test.c\n" ] }, @@ -292,7 +295,8 @@ "id": "IUtMMEpPc-qB" }, "source": [ - "##**Exercise 6** \n", + "## **Exercise 6**\n", + "\n", "- /content/bambu-tutorial/01-introduction/Exercise6/test.c \n", "- /content/bambu-tutorial/01-introduction/Exercise6/less.c \n", "- /content/bambu-tutorial/01-introduction/Exercise6/qsort.c" From 5d163696ba8a2b1e61c6f131aecb61d70593b646 Mon Sep 17 00:00:00 2001 From: Michele Fiorito Date: Thu, 14 Oct 2021 19:45:12 +0200 Subject: [PATCH 25/32] ICS 2021 tutorial updated --- .../01-introduction/Exercise1/bambu.sh | 11 + .../01-introduction/Exercise1/icrc.c | 14 + .../01-introduction/Exercise2/bambu.sh | 13 + .../01-introduction/Exercise2/tree.c | 323 + .../01-introduction/Exercise3/Keccak.c | 142 + .../Exercise3/bambu-clang11.sh | 12 + .../01-introduction/Exercise3/bambu.sh | 13 + .../01-introduction/Exercise3/test.xml | 4 + .../Exercise4/LUdecomposition.c | 270 + .../01-introduction/Exercise4/bambu.sh | 12 + .../01-introduction/Exercise4/test.xml | 4 + .../01-introduction/Exercise5/README.txt | 24 + .../01-introduction/Exercise5/bambu.sh | 16 + .../Exercise5/constraints_STD.xml | 6 + .../01-introduction/Exercise5/main_test.c | 22 + .../01-introduction/Exercise5/module1.c | 8 + .../01-introduction/Exercise5/module1.v | 226 + .../01-introduction/Exercise5/module2.c | 7 + .../01-introduction/Exercise5/module2.v | 201 + .../01-introduction/Exercise5/module_lib.h | 32 + .../01-introduction/Exercise5/module_lib.xml | 262 + .../01-introduction/Exercise5/printer1.c | 6 + .../01-introduction/Exercise5/printer1.v | 45 + .../01-introduction/Exercise5/printer2.c | 6 + .../01-introduction/Exercise5/printer2.v | 44 + .../01-introduction/Exercise5/test.xml | 4 + .../01-introduction/Exercise5/top.c | 23 + .../01-introduction/Exercise6/aggregate.h | 16 + .../01-introduction/Exercise6/bambu.sh | 12 + .../01-introduction/Exercise6/less.c | 31 + .../01-introduction/Exercise6/qsort.c | 247 + .../01-introduction/Exercise6/test.c | 17 + .../01-introduction/Exercise6/test.xml | 4 + .../02-target_customization/Exercise1/README | 1 + .../02-target_customization/Exercise1/hint.c | 13 + .../02-target_customization/Exercise1/hint.sh | 5 + .../Exercise1/solution/minmax.c | 19 + .../Exercise1/solution/synthesize.sh | 2 + .../Exercise1/solution/testbench.xml | 7 + .../03-optimizations/Exercise1/README | 5 + .../03-optimizations/Exercise1/adpcm.c | 882 + .../03-optimizations/Exercise1/hint.sh | 4 + .../Exercise1/solution/adpcm.c | 882 + .../Exercise1/solution/adpcm.csv | 25 + .../Exercise1/solution/adpcm_sdc.csv | 28 + .../03-optimizations/Exercise1/solution/list | 7 + .../Exercise1/solution/synthesize.sh | 9 + .../03-optimizations/Exercise3/README | 1 + .../03-optimizations/Exercise3/SPARC-GCC.h | 88 + .../03-optimizations/Exercise3/dfdiv.c | 159 + .../03-optimizations/Exercise3/hint.txt | 1 + .../03-optimizations/Exercise3/milieu.h | 53 + .../Exercise3/softfloat-macros | 247 + .../Exercise3/softfloat-specialize | 123 + .../03-optimizations/Exercise3/softfloat.c | 316 + .../03-optimizations/Exercise3/softfloat.h | 77 + .../Exercise3/solution/SPARC-GCC.h | 88 + .../Exercise3/solution/dfdiv.c | 159 + .../Exercise3/solution/dfdiv.csv | 6 + .../03-optimizations/Exercise3/solution/list | 5 + .../Exercise3/solution/milieu.h | 53 + .../Exercise3/solution/softfloat-macros | 247 + .../Exercise3/solution/softfloat-specialize | 123 + .../Exercise3/solution/softfloat.c | 316 + .../Exercise3/solution/softfloat.h | 77 + .../Exercise3/solution/synthesize.sh | 6 + .../03-optimizations/Exercise4/README | 5 + .../03-optimizations/Exercise4/hint.sh | 7 + .../03-optimizations/Exercise4/hint.txt | 4 + .../03-optimizations/Exercise4/solution/list | 4 + .../Exercise4/solution/module.c | 24 + .../Exercise4/solution/synthesize.sh | 11 + .../Exercise4/solution/testbench.xml | 5 + .../03-optimizations/test_panda.py | 961 + .../04-simd/Exercise1/bambu.sh | 9 + .../04-simd/Exercise1/histogram.c | 88 + .../04-simd/Exercise1/histogram.h | 6 + .../04-simd/Exercise1/solution/bambu.sh | 10 + .../04-simd/Exercise2/bambu.sh | 9 + .../04-simd/Exercise2/histogram.c | 98 + .../04-simd/Exercise2/histogram.h | 6 + .../04-simd/Exercise2/solution/bambu.sh | 9 + .../04-simd/Exercise3/bambu.sh | 9 + .../04-simd/Exercise3/histogram.c | 98 + .../04-simd/Exercise3/histogram.h | 6 + .../04-simd/Exercise3/solution/bambu.sh | 44 + .../05-context-switch/Exercise1/bambu.sh | 5 + .../Exercise1/common/atominIncrement.c | 8 + .../05-context-switch/Exercise1/common/data.c | 8 + .../Exercise1/common/load_graph.c | 60 + .../Exercise1/common/simple_API.h | 79 + .../Exercise1/solution/bambu.sh | 6 + .../05-context-switch/Exercise1/test-1.xml | 25420 ++++++++++++++++ .../Exercise1/trinityq4/lubm_trinityq4.c | 133 + .../05-context-switch/Exercise2/bambu.sh | 6 + .../Exercise2/common/atominIncrement.c | 8 + .../05-context-switch/Exercise2/common/data.c | 8 + .../Exercise2/common/load_graph.c | 60 + .../Exercise2/common/simple_API.h | 79 + .../Exercise2/solution/bambu.sh | 6 + .../05-context-switch/Exercise2/test-1.xml | 25420 ++++++++++++++++ .../Exercise2/trinityq4/lubm_trinityq4.c | 133 + .../05-context-switch/Exercise3/bambu.sh | 6 + .../Exercise3/common/atominIncrement.c | 8 + .../05-context-switch/Exercise3/common/data.c | 8 + .../Exercise3/common/load_graph.c | 60 + .../Exercise3/common/simple_API.h | 79 + .../Exercise3/solution/bambu.sh | 6 + .../05-context-switch/Exercise3/test-1.xml | 25420 ++++++++++++++++ .../Exercise3/trinityq4/lubm_trinityq4.c | 133 + .../05-context-switch/Exercise4/bambu.sh | 6 + .../Exercise4/common/atominIncrement.c | 8 + .../05-context-switch/Exercise4/common/data.c | 8 + .../Exercise4/common/load_graph.c | 60 + .../Exercise4/common/simple_API.h | 79 + .../Exercise4/solution/bambu.sh | 30 + .../05-context-switch/Exercise4/test-1.xml | 25420 ++++++++++++++++ .../Exercise4/trinityq4/lubm_trinityq4.c | 133 + documentation/tutorial_ics_2021/bambu.ipynb | 231 +- 119 files changed, 110535 insertions(+), 123 deletions(-) create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise1/bambu.sh create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise1/icrc.c create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise2/bambu.sh create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise2/tree.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise3/Keccak.c create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise3/bambu-clang11.sh create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise3/bambu.sh create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise3/test.xml create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise4/LUdecomposition.c create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise4/bambu.sh create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise4/test.xml create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/README.txt create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise5/bambu.sh create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/constraints_STD.xml create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/main_test.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.v create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.v create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.h create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.xml create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.v create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.v create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/test.xml create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise5/top.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise6/aggregate.h create mode 100755 documentation/tutorial_ics_2021/01-introduction/Exercise6/bambu.sh create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise6/less.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise6/qsort.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise6/test.c create mode 100644 documentation/tutorial_ics_2021/01-introduction/Exercise6/test.xml create mode 100644 documentation/tutorial_ics_2021/02-target_customization/Exercise1/README create mode 100644 documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.c create mode 100755 documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.sh create mode 100644 documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/minmax.c create mode 100755 documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/synthesize.sh create mode 100644 documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/testbench.xml create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise1/README create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise1/adpcm.c create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise1/hint.sh create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.c create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.csv create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm_sdc.csv create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/list create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/synthesize.sh create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise3/README create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/SPARC-GCC.h create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/dfdiv.c create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise3/hint.txt create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/milieu.h create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-macros create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-specialize create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.c create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.h create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/SPARC-GCC.h create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.c create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.csv create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/list create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/milieu.h create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-macros create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-specialize create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.c create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.h create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/synthesize.sh create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise4/README create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.sh create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.txt create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/list create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/module.c create mode 100755 documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/synthesize.sh create mode 100644 documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/testbench.xml create mode 100755 documentation/tutorial_ics_2021/03-optimizations/test_panda.py create mode 100755 documentation/tutorial_ics_2021/04-simd/Exercise1/bambu.sh create mode 100644 documentation/tutorial_ics_2021/04-simd/Exercise1/histogram.c create mode 100644 documentation/tutorial_ics_2021/04-simd/Exercise1/histogram.h create mode 100755 documentation/tutorial_ics_2021/04-simd/Exercise1/solution/bambu.sh create mode 100755 documentation/tutorial_ics_2021/04-simd/Exercise2/bambu.sh create mode 100644 documentation/tutorial_ics_2021/04-simd/Exercise2/histogram.c create mode 100644 documentation/tutorial_ics_2021/04-simd/Exercise2/histogram.h create mode 100755 documentation/tutorial_ics_2021/04-simd/Exercise2/solution/bambu.sh create mode 100755 documentation/tutorial_ics_2021/04-simd/Exercise3/bambu.sh create mode 100644 documentation/tutorial_ics_2021/04-simd/Exercise3/histogram.c create mode 100644 documentation/tutorial_ics_2021/04-simd/Exercise3/histogram.h create mode 100755 documentation/tutorial_ics_2021/04-simd/Exercise3/solution/bambu.sh create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise1/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise1/common/atominIncrement.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise1/common/data.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise1/common/load_graph.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise1/common/simple_API.h create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise1/solution/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise1/test-1.xml create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise1/trinityq4/lubm_trinityq4.c create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise2/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise2/common/atominIncrement.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise2/common/data.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise2/common/load_graph.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise2/common/simple_API.h create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise2/solution/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise2/test-1.xml create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise2/trinityq4/lubm_trinityq4.c create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise3/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise3/common/atominIncrement.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise3/common/data.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise3/common/load_graph.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise3/common/simple_API.h create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise3/solution/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise3/test-1.xml create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise3/trinityq4/lubm_trinityq4.c create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise4/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise4/common/atominIncrement.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise4/common/data.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise4/common/load_graph.c create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise4/common/simple_API.h create mode 100755 documentation/tutorial_ics_2021/05-context-switch/Exercise4/solution/bambu.sh create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise4/test-1.xml create mode 100644 documentation/tutorial_ics_2021/05-context-switch/Exercise4/trinityq4/lubm_trinityq4.c diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise1/bambu.sh b/documentation/tutorial_ics_2021/01-introduction/Exercise1/bambu.sh new file mode 100755 index 000000000..34be96f47 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise1/bambu.sh @@ -0,0 +1,11 @@ +#!/bin/bash +script=$(readlink -e $0) +root_dir=$(dirname $script) + +rm -rf icrc1 +mkdir -p icrc1 +cd icrc1 +echo "#synthesis of icrc1" +bambu ../icrc.c --top-fname=icrc1 \ + --generate-tb=../test_icrc1.xml --simulator=VERILATOR --simulate \ + -v2 --print-dot --pretty-print=a.c "$@" |& tee icrc1.log \ No newline at end of file diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise1/icrc.c b/documentation/tutorial_ics_2021/01-introduction/Exercise1/icrc.c new file mode 100644 index 000000000..8852b50a1 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise1/icrc.c @@ -0,0 +1,14 @@ +unsigned short icrc1(unsigned short crc, unsigned char onech) +{ + int i; + unsigned short ans=(crc^onech << 8); + + for (i=0;i<8;i++) { + if (ans & 0x8000) + ans = (ans <<= 1) ^ 4129; + else + ans <<= 1; + } + return ans; +} + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise2/bambu.sh b/documentation/tutorial_ics_2021/01-introduction/Exercise2/bambu.sh new file mode 100755 index 000000000..0f0129a54 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise2/bambu.sh @@ -0,0 +1,13 @@ +#!/bin/bash +script=$(readlink -e $0) +root_dir=$(dirname $script) + +rm -rf search +mkdir -p search +cd search +echo "#simulation of search function" +bambu $root_dir/tree.c --top-fname=main --top-rtldesign-name=search \ + -DNDEBUG -DBAMBU_PROFILING \ + -O3 --experimental-setup=BAMBU \ + --generate-tb=$root_dir/test_search.xml --simulator=ICARUS --simulate \ + --print-dot -v2 "$@" |& tee search.log \ No newline at end of file diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise2/tree.c b/documentation/tutorial_ics_2021/01-introduction/Exercise2/tree.c new file mode 100644 index 000000000..088ea68c2 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise2/tree.c @@ -0,0 +1,323 @@ +#include +#include +#include + +#define MAX_NUMBER_OF_NODES 255 +extern void __builtin_bambu_time_start(); +extern void __builtin_bambu_time_stop(); + +/* stack data structure */ +struct stack +{ + void *data; + struct stack *next; +}; + +typedef struct stack node_stack; + +/* Auxiliary memory stack allocation utilities */ +static node_stack StaticPoolStack[MAX_NUMBER_OF_NODES]; +static node_stack* head_stack_free_list; + +void push_stack_free_list(node_stack ** head, node_stack * new_node) +{ + new_node->data = 0; + new_node->next = *head; + *head = new_node; +} +node_stack* pop_stack_free_list(node_stack ** head) +{ + node_stack* retval = 0; + node_stack * next_node = NULL; + + if (*head == NULL) + return NULL; + + next_node = (*head)->next; + retval = *head; + *head = next_node; + + return retval; +} +void init_stack_free_list() +{ + int index; + for(index=0; index < MAX_NUMBER_OF_NODES; ++index) + push_stack_free_list(&head_stack_free_list, &StaticPoolStack[index]); +} + +/* Stack related functions */ +void push(node_stack** head, void *t) +{ + node_stack* temp = pop_stack_free_list(&head_stack_free_list); + assert(temp); + temp->data = t; + temp->next = (*head); + *head= temp; +} +_Bool isEmpty(node_stack *head) +{ + return (head == NULL)? 1 : 0; +} +void *pop(node_stack** head) +{ + void *res; + node_stack *top; + + assert(!isEmpty(*head)); + top = *head; + res = top->data; + *head = top->next; + push_stack_free_list(&head_stack_free_list, top); + return res; +} + +void* top(node_stack* head) +{ + return head->data; +} + +/* binary tree data structure */ +struct bin_tree { + int data; + struct bin_tree * right, * left; +}; +typedef struct bin_tree node_tree; + +/* Auxiliary memory tree allocation utilities */ +static node_tree StaticPoolTree[MAX_NUMBER_OF_NODES]; +static node_tree* head_tree_free_list; + +void push_tree_free_list(node_tree ** head, node_tree * new_node) +{ + new_node->data = 0; + new_node->left = *head; + new_node->right = 0; + *head = new_node; +} +node_tree* pop_tree_free_list(node_tree ** head) +{ + node_tree* retval = 0; + node_tree * next_node = NULL; + + if (*head == NULL) + return NULL; + + next_node = (*head)->left; + retval = *head; + *head = next_node; + + return retval; +} +void init_tree_free_list() +{ + int index; + for(index=0; index < MAX_NUMBER_OF_NODES; ++index) + push_tree_free_list(&head_tree_free_list, &StaticPoolTree[index]); +} + + +/* binary tree functions */ +void insert(node_tree ** tree, int val) +{ + node_tree *temp = NULL; + if(!(*tree)) + { + temp = pop_tree_free_list(&head_tree_free_list); + assert(temp); + temp->left = temp->right = NULL; + temp->data = val; + *tree = temp; + return; + } + if(val < (*tree)->data) + { + insert(&(*tree)->left, val); + } + else if(val > (*tree)->data) + { + insert(&(*tree)->right, val); + } +} + +void print_preorder(node_tree * root) +{ + if (root) + { + node_tree *current; + node_stack *s = NULL; + push(&s, root); + + while (!isEmpty(s)) + { + current = pop(&s); + printf ("%d\n", current->data); + + if (current->right) + push(&s, current->right); + if (current->left) + push(&s, current->left); + } + } +} + +/* Iterative function for inorder binary tree print */ +void print_inorder(node_tree *root) +{ + node_tree *current = root; + node_stack *s = NULL; + _Bool done = 0; + + while (!done) + { + if(current != NULL) + { + push(&s, current); + current = current->left; + } + else + { + if (!isEmpty(s)) + { + current = pop(&s); + printf("%d\n", current->data); + current = current->right; + } + else + done = 1; + } + } +} + + +void print_postorder(node_tree * root) +{ + if (root) + { + node_tree *prev=NULL; + node_stack *s = NULL; + push(&s, root); + + while (!isEmpty(s)) { + node_tree *curr = top(s); + if (!prev || prev->left == curr || prev->right == curr) { + if (curr->left) + push(&s, curr->left); + else if (curr->right) + push(&s, curr->right); + } else if (curr->left == prev) { + if (curr->right) + push(&s, curr->right); + } else { + printf("%d\n", curr->data); + pop(&s); + } + prev = curr; + } + } +} + +void deltree(node_tree * root) +{ + if (root) + { + node_tree *prev=NULL; + node_stack *s = NULL; + push(&s, root); + + while (!isEmpty(s)) { + node_tree *curr = top(s); + if (!prev || prev->left == curr || prev->right == curr) { + if (curr->left) + push(&s, curr->left); + else if (curr->right) + push(&s, curr->right); + } else if (curr->left == prev) { + if (curr->right) + push(&s, curr->right); + } else { + push_tree_free_list(&head_tree_free_list, curr); + pop(&s); + } + prev = curr; + } + } +} + +node_tree* __attribute__ ((noinline)) search(node_tree * tree, int val) +{ + if(tree == NULL|| tree->data == val) + return tree; + + if (tree->data < val) + return search(tree->right, val); + else + return search(tree->left, val); +} + +int main() +{ + node_tree *root; + node_tree *tmp; + //int i; + init_tree_free_list(); + init_stack_free_list(); + + root = NULL; + /* Inserting nodes into tree */ + insert(&root, 9); + insert(&root, 4); + insert(&root, 15); + insert(&root, 6); + insert(&root, 12); + insert(&root, 17); + insert(&root, 2); + + /* Printing nodes of tree */ + printf("Pre Order Display\n"); + print_preorder(root); + + printf("In Order Display\n"); + print_inorder(root); + + printf("Post Order Display\n"); + print_postorder(root); + + /* Search node into tree */ +#ifdef BAMBU_PROFILING + __builtin_bambu_time_start(); +#endif + tmp = search(root, 4); +#ifdef BAMBU_PROFILING + __builtin_bambu_time_stop(); +#endif + if (tmp) + { + printf("Searched node=%d\n", tmp->data); + } + else + { + printf("Data Not found in tree.\n"); + } + + /* Search node into tree */ +#ifdef BAMBU_PROFILING + __builtin_bambu_time_start(); +#endif + tmp = search(root, 6); +#ifdef BAMBU_PROFILING + __builtin_bambu_time_stop(); +#endif + if (tmp) + { + printf("Second searched node=%d\n", tmp->data); + } + else + { + printf("Data Not found in tree.\n"); + } + + /* Deleting all nodes of tree */ + deltree(root); + return 0; +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise3/Keccak.c b/documentation/tutorial_ics_2021/01-introduction/Exercise3/Keccak.c new file mode 100644 index 000000000..cbc8cc651 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise3/Keccak.c @@ -0,0 +1,142 @@ +/* + * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, + * Michaël Peeters and Gilles Van Assche. For more information, feedback or + * questions, please refer to our website: http://keccak.noekeon.org/ + * Implementation by the designers, + * hereby denoted as "the implementer". + * To the extent possible under law, the implementer has waived all copyright + * and related or neighboring rights to the source code in this file. + * http://creativecommons.org/publicdomain/zero/1.0/ + * + */ +typedef unsigned char UINT8; +typedef unsigned long long int UINT64; +#define nrRounds 24 + +#define GET_KRC_VAL(index) (KeccakRoundConstants[index]) + +static UINT64 KeccakRoundConstants[nrRounds] = { + 0x0000000000000001ULL, + 0x0000000000008082ULL, + 0x800000000000808aULL, + 0x8000000080008000ULL, + 0x000000000000808bULL, + 0x0000000080000001ULL, + 0x8000000080008081ULL, + 0x8000000000008009ULL, + 0x000000000000008aULL, + 0x0000000000000088ULL, + 0x0000000080008009ULL, + 0x000000008000000aULL, + 0x000000008000808bULL, + 0x800000000000008bULL, + 0x8000000000008089ULL, + 0x8000000000008003ULL, + 0x8000000000008002ULL, + 0x8000000000000080ULL, + 0x000000000000800aULL, + 0x800000008000000aULL, + 0x8000000080008081ULL, + 0x8000000000008080ULL, + 0x0000000080000001ULL, + 0x8000000080008008ULL +}; + +#define nrLanes 25 +static unsigned char KeccakRhoOffsets[nrLanes] = { + 0, + 1, + 62, + 28, + 27, + 36, + 44, + 6, + 55, + 20, + 3, + 10, + 43, + 25, + 39, + 41, + 45, + 15, + 21, + 8, + 18, + 2, + 61, + 56, + 14 +}; + +#define index(x, y) (((x)%5)+5*((y)%5)) +#define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a) + +void theta(UINT64 *A) +{ + unsigned int x, y; + UINT64 C[5], D[5]; + + for(x=0; x<5; x++) { + C[x] = 0; + for(y=0; y<5; y++) + C[x] ^= A[index(x, y)]; + } + for(x=0; x<5; x++) + D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5]; + for(x=0; x<5; x++) + for(y=0; y<5; y++) + A[index(x, y)] ^= D[x]; +} + +void rho(UINT64 *A) +{ + unsigned int x, y; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]); +} + +void pi(UINT64 *A) +{ + unsigned int x, y; + UINT64 tempA[25]; + + for(x=0; x<5; x++) for(y=0; y<5; y++) + tempA[index(x, y)] = A[index(x, y)]; + for(x=0; x<5; x++) for(y=0; y<5; y++) + A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)]; +} + +void chi(UINT64 *A) +{ + unsigned int x, y; + UINT64 C[5]; + + for(y=0; y<5; y++) { + for(x=0; x<5; x++) + C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]); + for(x=0; x<5; x++) + A[index(x, y)] = C[x]; + } +} + +void iota(UINT64 *A, unsigned int indexRound) +{ + A[index(0, 0)] ^= GET_KRC_VAL(indexRound); +} + + +void kekka_coproc(UINT64 A[25]) +{ + unsigned int i; + for(i=0;i + + + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise4/LUdecomposition.c b/documentation/tutorial_ics_2021/01-introduction/Exercise4/LUdecomposition.c new file mode 100644 index 000000000..a20e6b9f7 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise4/LUdecomposition.c @@ -0,0 +1,270 @@ +//////////////////////////////////////////////////////////////////////////////// +// int Upper_Triangular_Solve(float *U, float *B, float x[], int n) // +// // +// Description: // +// This routine solves the linear equation Ux = B, where U is an n x n // +// upper triangular matrix. (The subdiagonal part of the matrix is // +// not addressed.) // +// The algorithm follows: // +// x[n-1] = B[n-1]/U[n-1][n-1], and // +// x[i] = [B[i] - (U[i][i+1] * x[i+1] + ... + U[i][n-1] * x[n-1])] // +// / U[i][i], // +// for i = n-2, ..., 0. // +// // +// Arguments: // +// float *U Pointer to the first element of the upper triangular // +// matrix. // +// float *B Pointer to the column vector, (n x 1) matrix, B. // +// float *x Pointer to the column vector, (n x 1) matrix, x. // +// int n The number of rows or columns of the matrix U. // +// // +// Return Values: // +// 0 Success // +// -1 Failure - The matrix U is singular. // +// // +// Example: // +// #define N // +// float A[N][N], B[N], x[N]; // +// // +// (your code to create matrix A and column vector B) // +// err = Upper_Triangular_Solve(&A[0][0], B, x, n); // +// if (err < 0) printf(" Matrix A is singular\n"); // +// else printf(" The solution is \n"); // +// ... // +//////////////////////////////////////////////////////////////////////////////// +// // +int Upper_Triangular_Solve(float *U, float B[], float x[], int n) +{ + int i, k; + +// Solve the linear equation Ux = B for x, where U is an upper +// triangular matrix. + + for (k = n-1, U += n * (n - 1); k >= 0; U -= n, k--) { + if (*(U + k) == 0.0) return -1; // The matrix U is singular + x[k] = B[k]; + for (i = k + 1; i < n; i++) x[k] -= x[i] * *(U + i); + x[k] /= *(U + k); + } + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// +// void Unit_Lower_Triangular_Solve(float *L, float *B, float x[], int n) // +// // +// Description: // +// This routine solves the linear equation Lx = B, where L is an n x n // +// unit lower triangular matrix. (Only the subdiagonal part of the matrix// +// is addressed.) The diagonal is assumed to consist of 1's and is not // +// addressed. // +// The algorithm follows: // +// x[0] = B[0], and // +// x[i] = B[i] - (L[i][0] * x[0] + ... + L[i][i-1] * x[i-1]), // +// for i = 1, ..., n-1. // +// // +// Arguments: // +// float *L Pointer to the first element of the unit lower triangular // +// matrix. // +// float *B Pointer to the column vector, (n x 1) matrix, B. // +// float *x Pointer to the column vector, (n x 1) matrix, x. // +// int n The number of rows or columns of the matrix L. // +// // +// Return Values: // +// void // +// // +// Example: // +// #define N // +// float A[N][N], B[N], x[N]; // +// // +// (your code to create matrix A and column vector B) // +// Unit_Lower_Triangular_Solve(&A[0][0], B, x, n); // +// printf(" The solution is \n"); // +// ... // +//////////////////////////////////////////////////////////////////////////////// +// // +void Unit_Lower_Triangular_Solve(float *L, float B[], float x[], int n) +{ + int i, k; + +// Solve the linear equation Lx = B for x, where L is a unit lower +// triangular matrix. + + x[0] = B[0]; + for (k = 1, L += n; k < n; L += n, k++) + for (i = 0, x[k] = B[k]; i < k; i++) x[k] -= x[i] * *(L + i); +} + +//////////////////////////////////////////////////////////////////////////////// +// int Doolittle_LU_Decomposition(float *A, int n) // +// // +// Description: // +// This routine uses Doolittle's method to decompose the n x n matrix A // +// into a unit lower triangular matrix L and an upper triangular matrix U // +// such that A = LU. // +// The matrices L and U replace the matrix A so that the original matrix // +// A is destroyed. // +// Note! In Doolittle's method the diagonal elements of L are 1 and are // +// not stored. // +// Note! The determinant of A is the product of the diagonal elements // +// of U. (det A = det L * det U = det U). // +// This routine is suitable for those classes of matrices which when // +// performing Gaussian elimination do not need to undergo partial // +// pivoting, e.g. positive definite symmetric matrices, diagonally // +// dominant band matrices, etc. // +// For the more general case in which partial pivoting is needed use // +// Doolittle_LU_Decomposition_with_Pivoting. // +// The LU decomposition is convenient when one needs to solve the linear // +// equation Ax = B for the vector x while the matrix A is fixed and the // +// vector B is varied. The routine for solving the linear system Ax = B // +// after performing the LU decomposition for A is Doolittle_LU_Solve // +// (see below). // +// // +// The Doolittle method is given by evaluating, in order, the following // +// pair of expressions for k = 0, ... , n-1: // +// U[k][j] = A[k][j] - (L[k][0]*U[0][j] + ... + L[k][k-1]*U[k-1][j]) // +// for j = k, k+1, ... , n-1 // +// L[i][k] = (A[i][k] - (L[i][0]*U[0][k] + . + L[i][k-1]*U[k-1][k])) // +// / U[k][k] // +// for i = k+1, ... , n-1. // +// The matrix U forms the upper triangular matrix, and the matrix L // +// forms the lower triangular matrix. // +// // +// Arguments: // +// float *A Pointer to the first element of the matrix A[n][n]. // +// int n The number of rows or columns of the matrix A. // +// // +// Return Values: // +// 0 Success // +// -1 Failure - The matrix A is singular. // +// // +// Example: // +// #define N // +// float A[N][N]; // +// // +// (your code to intialize the matrix A) // +// // +// err = Doolittle_LU_Decomposition(&A[0][0], N); // +// if (err < 0) printf(" Matrix A is singular\n"); // +// else { printf(" The LU decomposition of A is \n"); // +// ... // +//////////////////////////////////////////////////////////////////////////////// +// // +int Doolittle_LU_Decomposition(float *A, int n) +{ + int i, j, k, p; + float *p_k, *p_row, *p_col; + +// For each row and column, k = 0, ..., n-1, +// find the upper triangular matrix elements for row k +// and if the matrix is non-singular (nonzero diagonal element). +// find the lower triangular matrix elements for column k. + + for (k = 0, p_k = A; k < n; p_k += n, k++) { + for (j = k; j < n; j++) { + for (p = 0, p_col = A; p < k; p_col += n, p++) + *(p_k + j) -= *(p_k + p) * *(p_col + j); + } + if ( *(p_k + k) == 0.0 ) return -1; + for (i = k+1, p_row = p_k + n; i < n; p_row += n, i++) { + for (p = 0, p_col = A; p < k; p_col += n, p++) + *(p_row + k) -= *(p_row + p) * *(p_col + k); + *(p_row + k) /= *(p_k + k); + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////// +// int Doolittle_LU_Solve(float *LU, float *B, float *x, int n) // +// // +// Description: // +// This routine uses Doolittle's method to solve the linear equation // +// Ax = B. This routine is called after the matrix A has been decomposed // +// into a product of a unit lower triangular matrix L and an upper // +// triangular matrix U without pivoting. The argument LU is a pointer to // +// the matrix the subdiagonal part of which is L and the superdiagonal // +// together with the diagonal part is U. (The diagonal part of L is 1 and // +// is not stored.) The matrix A = LU. // +// The solution proceeds by solving the linear equation Ly = B for y and // +// subsequently solving the linear equation Ux = y for x. // +// // +// Arguments: // +// float *LU Pointer to the first element of the matrix whose elements // +// form the lower and upper triangular matrix factors of A. // +// float *B Pointer to the column vector, (n x 1) matrix, B // +// float *x Solution to the equation Ax = B. // +// int n The number of rows or columns of the matrix LU. // +// // +// Return Values: // +// 0 Success // +// -1 Failure - The matrix A is singular. // +// // +// Example: // +// #define N // +// float A[N][N], B[N], x[N]; // +// // +// (your code to create matrix A and column vector B) // +// err = Doolittle_LU_Decomposition(&A[0][0], N); // +// if (err < 0) printf(" Matrix A is singular\n"); // +// else { // +// err = Doolittle_LU_Solve(&A[0][0], B, x, n); // +// if (err < 0) printf(" Matrix A is singular\n"); // +// else printf(" The solution is \n"); // +// ... // +// } // +//////////////////////////////////////////////////////////////////////////////// +// // +int Doolittle_LU_Solve(float *LU, float B[], float x[], int n) +{ + +// Solve the linear equation Lx = B for x, where L is a lower +// triangular matrix with an implied 1 along the diagonal. + + Unit_Lower_Triangular_Solve(LU, B, x, n); + +// Solve the linear equation Ux = y, where y is the solution +// obtained above of Lx = B and U is an upper triangular matrix. + + return Upper_Triangular_Solve(LU, x, x, n); +} + +int invertMatrix(float *LU, float *invA, float *I) +{ + int i, j; + // float I[4][4] = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}; + float resultColumn[4]; + + for (i = 0; i < 4; ++i) + { + int res = Doolittle_LU_Solve(LU, I + i*4, resultColumn, 4); + + if (res != 0) return res; + for (j = 0; j < 4; ++j) + *(invA + i + j * 4) = resultColumn[j]; + } + + return 0; +} + +//float A[4][4] = {{1, 1, 1, 1}, {1, 4, 2, 3}, {1, 2, 1, 2}, {1, 1, 1, 0}}; +//float invA[4][4]= {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; + +int fun(float *A, float *invA, float *b, float *x, float *I) +{ + int res = Doolittle_LU_Decomposition((float *)A, 4); + + if (res != 0) return res; + + // float b[4] = {63, 105, 48, 186}; + // float x[4]; + + res = Doolittle_LU_Solve((float *)A, b, x, 4); + + if (res != 0) return res; + + res = invertMatrix((float *)A, (float *)invA, I); + + return res; +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise4/bambu.sh b/documentation/tutorial_ics_2021/01-introduction/Exercise4/bambu.sh new file mode 100755 index 000000000..f37d97ff8 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise4/bambu.sh @@ -0,0 +1,12 @@ +#!/bin/bash +script=$(readlink -e $0) +root_dir=$(dirname $script) + +rm -rf ludecomp +mkdir -p ludecomp +cd ludecomp +echo "#synthesis of fun" +bambu $root_dir/LUdecomposition.c --top-fname=fun \ + -O1 \ + --generate-tb=$root_dir/test.xml --simulate --simulator=VERILATOR \ + -v2 --print-dot "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise4/test.xml b/documentation/tutorial_ics_2021/01-introduction/Exercise4/test.xml new file mode 100644 index 000000000..500454cc7 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise4/test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/README.txt b/documentation/tutorial_ics_2021/01-introduction/Exercise5/README.txt new file mode 100644 index 000000000..bdaccd406 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/README.txt @@ -0,0 +1,24 @@ +Simple example describing how to integrate and verify existing IP with functions written in C that receives structs passed by pointers. + +Hereafter a small description of files +-------------------------------------- + +top.c: file to be compiled/synthesized by bambu. +module_lib.h: header that declares the interfaces to existing Verilog IPs. +module_lib.xml: XML file that describes interfaces of existing Verilog IPs. +module1.v: verilog of an existing synthesizable IP. +module1.c: C stub used to emulate the module1 IP in C. +module2.v: verilog of an existing synthesizable IP. +module2.c: C stub used to emulate the module2 IP in C. +printer1.v: verilog of an existing non-synthesizable IP. +printer1.c: C stub used to emulate the printer1 IP in C. +printer2.v: verilog of an existing non-synthesizable IP. +printer2.c: C stub used to emulate the printer2 IP in C. +main_test.c: C testbench +constraints_STD.xml: resource constraint file passed to bambu to generate a Verilog design with just 1 my_ip module. +test.xml: XML file describing the testbench inputs. It is empty since we use the main_test.c as testbench generator. +bambu.sh: synthesis and simulation script. It requires Vivado RTL and Verilator to properly work. + +All C/H files were validated using the "gcc -c" command. +A C executable can be created with this command: "gcc -o ip_test main_test.c top.c module1.c module2.c printer1.c printer2.c + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/bambu.sh b/documentation/tutorial_ics_2021/01-introduction/Exercise5/bambu.sh new file mode 100755 index 000000000..2365638eb --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/bambu.sh @@ -0,0 +1,16 @@ +#!/bin/bash +script=$(readlink -e $0) +root_dir=$(dirname $script) + +rm -rf hls +mkdir -p hls +cd hls +echo "# integrating IP simulation" +bambu $root_dir/main_test.c $root_dir/top.c --top-fname=main --top-rtldesign-name=my_ip \ + --C-no-parse=$root_dir/module1.c,$root_dir/module2.c,$root_dir/printer1.c,$root_dir/printer2.c \ + --file-input-data=$root_dir/module1.v,$root_dir/module2.v,$root_dir/printer1.v,$root_dir/printer2.v \ + $root_dir/module_lib.xml $root_dir/constraints_STD.xml \ + --experimental-setup=BAMBU -O3 \ + --no-iob --memory-allocation-policy=ALL_BRAM \ + --generate-tb=$root_dir/test.xml --simulate --simulator=VERILATOR \ + --print-dot -v4 "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/constraints_STD.xml b/documentation/tutorial_ics_2021/01-introduction/Exercise5/constraints_STD.xml new file mode 100644 index 000000000..bd4f51938 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/constraints_STD.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/main_test.c b/documentation/tutorial_ics_2021/01-introduction/Exercise5/main_test.c new file mode 100644 index 000000000..fdc441e97 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/main_test.c @@ -0,0 +1,22 @@ +#include "module_lib.h" +#ifdef BAMBU_PROFILING +extern void __builtin_bambu_time_start(); +extern void __builtin_bambu_time_stop(); +#endif + +int main() +{ + uint32_t param1=10; + uint32_t param2=10<<16; +#ifdef BAMBU_PROFILING + __builtin_bambu_time_start(); +#endif + my_ip(0, param1, param2); + my_ip(1, param1, param2); + my_ip(2, param1, param2); + my_ip(3, param1, param2); +#ifdef BAMBU_PROFILING + __builtin_bambu_time_stop(); +#endif + return 0; +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.c b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.c new file mode 100644 index 000000000..21ba71f5f --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.c @@ -0,0 +1,8 @@ +#include "module_lib.h" +void module1(uint32_t input1, uint16_t input2, module1_output_t *outputs) +{ + outputs->output1 = input1 * input2; + outputs->output2 = input1 + input2; + outputs->output3 = (~input2) + 1; + outputs->output4 = input2 | (((uint32_t)input2)<<16); +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.v b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.v new file mode 100644 index 000000000..32ffa7810 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module1.v @@ -0,0 +1,226 @@ +module module1_IP + (input wire clock, + input wire reset, + + input wire start_port, + output reg done_port, + + input wire [31:0] input1, + input wire [15:0] input2, + + output reg [63:0] output1, + output reg [63:0] output2, + output reg [15:0] output3, + output reg [31:0] output4); + + reg done_port_reg; + reg [63:0] output1_reg; + reg [63:0] output2_reg; + reg [15:0] output3_reg; + reg [31:0] output4_reg; + + + //---------------------------------------------------------------- + // Simulate processing on input + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port_reg <= 0; + output1_reg <= 0; + output2_reg <= 0; + output3_reg <= 0; + output4_reg <= 0; + end + else begin + done_port_reg <= start_port; + output1_reg <= input1 * input2; + output2_reg <= {32'd0, input1} + {48'd0, input2}; + output3_reg <= (~input2) + 1; + output4_reg <= {input2, input2}; + end + end + + + //---------------------------------------------------------------- + // Outputs, two cycle latency + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port <= 0; + output1 <= 0; + output2 <= 0; + output3 <= 0; + output4 <= 0; + end + else begin + done_port <= done_port_reg; + output1 <= output1_reg; + output2 <= output2_reg; + output3 <= output3_reg; + output4 <= output4_reg; + end + end + +endmodule + +module module1 (clock, reset, start_port, input1, input2, outputs, done_port, Min_oe_ram, Mout_oe_ram, Min_we_ram, Mout_we_ram, Min_addr_ram, Mout_addr_ram, M_Rdata_ram, Min_Wdata_ram, Mout_Wdata_ram, Min_data_ram_size, Mout_data_ram_size, M_DataRdy); + parameter BITSIZE_outputs=1, BITSIZE_Min_addr_ram=1, BITSIZE_Mout_addr_ram=1, BITSIZE_M_Rdata_ram=8, BITSIZE_Min_Wdata_ram=8, BITSIZE_Mout_Wdata_ram=8, BITSIZE_Min_data_ram_size=1, BITSIZE_Mout_data_ram_size=1; + // IN + input clock; + input reset; + input start_port; + input [31:0] input1; + input [15:0] input2; + input [BITSIZE_outputs-1:0] outputs; + input Min_oe_ram; + input Min_we_ram; + input [BITSIZE_Min_addr_ram-1:0] Min_addr_ram; + input [BITSIZE_M_Rdata_ram-1:0] M_Rdata_ram; + input [BITSIZE_Min_Wdata_ram-1:0] Min_Wdata_ram; + input [BITSIZE_Min_data_ram_size-1:0] Min_data_ram_size; + input M_DataRdy; + // OUT + output done_port; + output Mout_oe_ram; + output Mout_we_ram; + output [BITSIZE_Mout_addr_ram-1:0] Mout_addr_ram; + output [BITSIZE_Mout_Wdata_ram-1:0] Mout_Wdata_ram; + output [BITSIZE_Mout_data_ram_size-1:0] Mout_data_ram_size; + + wire [63:0] output1_int; + wire [63:0] output2_int; + wire [15:0] output3_int; + wire [31:0] output4_int; + reg [63:0] output1_reg; + reg [63:0] output2_reg; + reg [15:0] output3_reg; + reg [31:0] output4_reg; + + reg done_port; + wire done_port_my_ip; + wire start_port_fsm; + reg start_port_memstore; + wire done_port_memstore; + reg [63:0] data_int; + reg [BITSIZE_outputs-1:0] addr_int; + reg [6:0] size_int; + + reg Min_oe_ram_int; + reg Min_we_ram_int; + reg [BITSIZE_Min_addr_ram-1:0] Min_addr_ram_int; + reg [BITSIZE_Min_Wdata_ram-1:0] Min_Wdata_ram_int; + reg [BITSIZE_Min_data_ram_size-1:0] Min_data_ram_size_int; + parameter [2:0] S_0 = 3'd0, + S_1 = 3'd1, + S_2 = 3'd2, + S_3 = 3'd3, + S_4 = 3'd4; + reg [2:0] _present_state=S_0, _next_state; + + module1_IP my_module1_IP (.done_port(done_port_my_ip), .clock(clock), .reset(reset), .start_port(start_port), .input1(input1), .input2(input2), .output1(output1_int), .output2(output2_int), .output3(output3_int), .output4(output4_int)); + assign start_port_fsm = done_port_my_ip; + + __builtin_memstore #(.BITSIZE_data(64), .BITSIZE_addr(BITSIZE_outputs), .BITSIZE_size(7), .BITSIZE_Min_addr_ram(BITSIZE_Min_addr_ram), .BITSIZE_Mout_addr_ram(BITSIZE_Mout_addr_ram), .BITSIZE_M_Rdata_ram(BITSIZE_M_Rdata_ram), .BITSIZE_Min_Wdata_ram(BITSIZE_Min_Wdata_ram), .BITSIZE_Mout_Wdata_ram(BITSIZE_Mout_Wdata_ram), .BITSIZE_Min_data_ram_size(BITSIZE_Min_data_ram_size), .BITSIZE_Mout_data_ram_size(BITSIZE_Mout_data_ram_size)) my__builtin_memstore (.clock(clock), .reset(reset), .start_port(start_port_memstore), .data(data_int), .addr(addr_int), .size(size_int), .done_port(done_port_memstore), .Min_oe_ram(Min_oe_ram_int), .Mout_oe_ram(Mout_oe_ram), .Min_we_ram(Min_we_ram_int), .Mout_we_ram(Mout_we_ram), .Min_addr_ram(Min_addr_ram_int), .Mout_addr_ram(Mout_addr_ram), .M_Rdata_ram(M_Rdata_ram), .Min_Wdata_ram(Min_Wdata_ram_int), .Mout_Wdata_ram(Mout_Wdata_ram), .Min_data_ram_size(Min_data_ram_size_int), .Mout_data_ram_size(Mout_data_ram_size), .M_DataRdy(M_DataRdy)); + + always @(posedge clock or negedge reset) + if (!reset) + begin + _present_state <= S_0; + end + else + _present_state <= _next_state; + + always @(posedge clock or negedge reset) + if (!reset) + begin + output1_reg <= 0; + output2_reg <= 0; + output3_reg <= 0; + output4_reg <= 0; + end + else if(done_port_my_ip == 1'b1) + begin + output1_reg <= output1_int; + output2_reg <= output2_int; + output3_reg <= output3_int; + output4_reg <= output4_int; + end + + always @(*) + begin + _next_state=S_0; + done_port=1'b0; + start_port_memstore=1'b0; + addr_int=0; + data_int=0; + size_int=0; + Min_oe_ram_int=Min_oe_ram; + Min_we_ram_int=Min_we_ram; + Min_data_ram_size_int=Min_data_ram_size; + Min_Wdata_ram_int=Min_Wdata_ram; + Min_addr_ram_int=Min_addr_ram; + case (_present_state) + S_0 : + if(start_port_fsm != 1'b1) + begin + _next_state=S_0; + end + else + begin + _next_state=S_1; + end + S_1 : + begin + _next_state=S_1; + start_port_memstore=1'b1; + addr_int=outputs; + data_int=output1_reg; + size_int=64; + if(done_port_memstore) + begin + _next_state=S_2; + end + end + S_2 : + begin + _next_state=S_2; + start_port_memstore=1'b1; + addr_int=outputs+64/8; + data_int=output2_reg; + size_int=64; + if(done_port_memstore) + begin + _next_state=S_3; + end + end + S_3 : + begin + _next_state=S_3; + start_port_memstore=1'b1; + addr_int=outputs+(64+64)/8; + data_int=output3_reg; + size_int=15; + if(done_port_memstore) + begin + _next_state=S_4; + end + end + S_4 : + begin + _next_state=S_4; + start_port_memstore=1'b1; + addr_int=outputs+(64+64+32)/8; + data_int=output4_reg; + size_int=32; + if(done_port_memstore) + begin + _next_state=S_0; + done_port=1'b1; + end + end + endcase + end +endmodule + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.c b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.c new file mode 100644 index 000000000..890e8444a --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.c @@ -0,0 +1,7 @@ +#include "module_lib.h" +void module2(uint32_t input1, module2_output_t *outputs) +{ + outputs->output1 = input1 * input1; + outputs->output2 = input1 | (((uint64_t)input1)<<32); + outputs->output3 = (uint16_t)input1; +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.v b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.v new file mode 100644 index 000000000..4d42e2395 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module2.v @@ -0,0 +1,201 @@ +module module2_IP + (input wire clock, + input wire reset, + + input wire start_port, + output reg done_port, + + input wire [31:0] input1, + + output reg [63:0] output1, + output reg [63:0] output2, + output reg [15:0] output3); + + reg done_port_reg; + reg [63:0] output1_reg; + reg [63:0] output2_reg; + reg [15:0] output3_reg; + + + //---------------------------------------------------------------- + // Simulate processing on input + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port_reg <= 0; + output1_reg <= 0; + output2_reg <= 0; + output3_reg <= 0; + end + else begin + done_port_reg <= start_port; + output1_reg <= input1 * input1; + output2_reg <= {input1, input1}; + output3_reg <= input1[15:0]; + end + end + + + //---------------------------------------------------------------- + // Outputs, two cycle latency + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port <= 0; + output1 <= 0; + output2 <= 0; + output3 <= 0; + end + else begin + done_port <= done_port_reg; + output1 <= output1_reg; + output2 <= output2_reg; + output3 <= output3_reg; + end + end + +endmodule + +module module2 (clock, reset, start_port, input1, outputs, done_port, Min_oe_ram, Mout_oe_ram, Min_we_ram, Mout_we_ram, Min_addr_ram, Mout_addr_ram, M_Rdata_ram, Min_Wdata_ram, Mout_Wdata_ram, Min_data_ram_size, Mout_data_ram_size, M_DataRdy); + parameter BITSIZE_outputs=1, BITSIZE_Min_addr_ram=1, BITSIZE_Mout_addr_ram=1, BITSIZE_M_Rdata_ram=8, BITSIZE_Min_Wdata_ram=8, BITSIZE_Mout_Wdata_ram=8, BITSIZE_Min_data_ram_size=1, BITSIZE_Mout_data_ram_size=1; + // IN + input clock; + input reset; + input start_port; + input [31:0] input1; + input [BITSIZE_outputs-1:0] outputs; + input Min_oe_ram; + input Min_we_ram; + input [BITSIZE_Min_addr_ram-1:0] Min_addr_ram; + input [BITSIZE_M_Rdata_ram-1:0] M_Rdata_ram; + input [BITSIZE_Min_Wdata_ram-1:0] Min_Wdata_ram; + input [BITSIZE_Min_data_ram_size-1:0] Min_data_ram_size; + input M_DataRdy; + // OUT + output done_port; + output Mout_oe_ram; + output Mout_we_ram; + output [BITSIZE_Mout_addr_ram-1:0] Mout_addr_ram; + output [BITSIZE_Mout_Wdata_ram-1:0] Mout_Wdata_ram; + output [BITSIZE_Mout_data_ram_size-1:0] Mout_data_ram_size; + + wire [63:0] output1_int; + wire [63:0] output2_int; + wire [15:0] output3_int; + reg [63:0] output1_reg; + reg [63:0] output2_reg; + reg [15:0] output3_reg; + + reg done_port; + wire done_port_my_ip; + wire start_port_fsm; + reg start_port_memstore; + wire done_port_memstore; + reg [63:0] data_int; + reg [BITSIZE_outputs-1:0] addr_int; + reg [6:0] size_int; + + reg Min_oe_ram_int; + reg Min_we_ram_int; + reg [BITSIZE_Min_addr_ram-1:0] Min_addr_ram_int; + reg [BITSIZE_Min_Wdata_ram-1:0] Min_Wdata_ram_int; + reg [BITSIZE_Min_data_ram_size-1:0] Min_data_ram_size_int; + parameter [1:0] S_0 = 2'd0, + S_1 = 2'd1, + S_2 = 2'd2, + S_3 = 2'd3; + reg [1:0] _present_state=S_0, _next_state; + + module2_IP my_module2_IP (.done_port(done_port_my_ip), .clock(clock), .reset(reset), .start_port(start_port), .input1(input1), .output1(output1_int), .output2(output2_int), .output3(output3_int)); + assign start_port_fsm = done_port_my_ip; + + __builtin_memstore #(.BITSIZE_data(64), .BITSIZE_addr(BITSIZE_outputs), .BITSIZE_size(7), .BITSIZE_Min_addr_ram(BITSIZE_Min_addr_ram), .BITSIZE_Mout_addr_ram(BITSIZE_Mout_addr_ram), .BITSIZE_M_Rdata_ram(BITSIZE_M_Rdata_ram), .BITSIZE_Min_Wdata_ram(BITSIZE_Min_Wdata_ram), .BITSIZE_Mout_Wdata_ram(BITSIZE_Mout_Wdata_ram), .BITSIZE_Min_data_ram_size(BITSIZE_Min_data_ram_size), .BITSIZE_Mout_data_ram_size(BITSIZE_Mout_data_ram_size)) my__builtin_memstore (.clock(clock), .reset(reset), .start_port(start_port_memstore), .data(data_int), .addr(addr_int), .size(size_int), .done_port(done_port_memstore), .Min_oe_ram(Min_oe_ram_int), .Mout_oe_ram(Mout_oe_ram), .Min_we_ram(Min_we_ram_int), .Mout_we_ram(Mout_we_ram), .Min_addr_ram(Min_addr_ram_int), .Mout_addr_ram(Mout_addr_ram), .M_Rdata_ram(M_Rdata_ram), .Min_Wdata_ram(Min_Wdata_ram_int), .Mout_Wdata_ram(Mout_Wdata_ram), .Min_data_ram_size(Min_data_ram_size_int), .Mout_data_ram_size(Mout_data_ram_size), .M_DataRdy(M_DataRdy)); + + always @(posedge clock or negedge reset) + if (!reset) + begin + _present_state <= S_0; + end + else + _present_state <= _next_state; + + always @(posedge clock or negedge reset) + if (!reset) + begin + output1_reg <= 0; + output2_reg <= 0; + output3_reg <= 0; + end + else if(done_port_my_ip == 1'b1) + begin + output1_reg <= output1_int; + output2_reg <= output2_int; + output3_reg <= output3_int; + end + + always @(*) + begin + _next_state=S_0; + done_port=1'b0; + start_port_memstore=1'b0; + addr_int=0; + data_int=0; + size_int=0; + Min_oe_ram_int=Min_oe_ram; + Min_we_ram_int=Min_we_ram; + Min_data_ram_size_int=Min_data_ram_size; + Min_Wdata_ram_int=Min_Wdata_ram; + Min_addr_ram_int=Min_addr_ram; + case (_present_state) + S_0 : + if(start_port_fsm != 1'b1) + begin + _next_state=S_0; + end + else + begin + _next_state=S_1; + end + S_1 : + begin + _next_state=S_1; + start_port_memstore=1'b1; + addr_int=outputs; + data_int=output1_reg; + size_int=64; + if(done_port_memstore) + begin + _next_state=S_2; + end + end + S_2 : + begin + _next_state=S_2; + start_port_memstore=1'b1; + addr_int=outputs+64/8; + data_int=output2_reg; + size_int=64; + if(done_port_memstore) + begin + _next_state=S_3; + end + end + S_3 : + begin + _next_state=S_3; + start_port_memstore=1'b1; + addr_int=outputs+(64+64)/8; + size_int=16; + data_int=output3_reg; + if(done_port_memstore) + begin + _next_state=S_0; + done_port=1'b1; + end + end + endcase + end +endmodule + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.h b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.h new file mode 100644 index 000000000..6bff2ed40 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.h @@ -0,0 +1,32 @@ +#ifndef MODULE_LIB_H +#define MODULE_LIB_H + +#include + +typedef struct { + uint64_t output1; + uint64_t output2; + uint16_t output3; + uint32_t output4; +} module1_output_t; + +extern void module1(uint32_t input1, uint16_t input2, module1_output_t *outputs); + + + +typedef struct { + uint64_t output1; + uint64_t output2; + uint16_t output3; +} module2_output_t; + +extern void module2(uint32_t input1, module2_output_t *outputs); + + +extern void printer1(uint64_t value1, uint64_t value2, uint16_t value3, uint32_t value4); + +extern void printer2(uint64_t value1, uint64_t value2, uint16_t value3); + +extern void my_ip(uint8_t command, uint32_t param1, uint32_t param2); + +#endif diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.xml b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.xml new file mode 100644 index 000000000..edd567d75 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/module_lib.xml @@ -0,0 +1,262 @@ + + + + module_lib + + module1 + + MEM_ACC_11,MEM_ACC_N1 + + + Module 1 IP + foo + foo + foo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + module2 + MEM_ACC_11,MEM_ACC_N1 + + + + Module 2 IP + foo + foo + foo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + printer2 + + + + Printer 2 IP + foo + foo + foo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + printer1 + + + + Printer 1 IP + foo + foo + foo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.c b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.c new file mode 100644 index 000000000..49fd269f7 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.c @@ -0,0 +1,6 @@ +#include "module_lib.h" +#include +void printer1(uint64_t value1, uint64_t value2, uint16_t value3, uint32_t value4) +{ + printf("printer1: %llx %llx %x %x\n", value1, value2, value3, value4); +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.v b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.v new file mode 100644 index 000000000..b572577e6 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer1.v @@ -0,0 +1,45 @@ +module printer1 + (input wire clock, + input wire reset, + + input wire start_port, + output reg done_port, + + input wire [63:0] value1, + input wire [63:0] value2, + input wire [15:0] value3, + input wire [31:0] value4); + + reg done_port_reg; + + //---------------------------------------------------------------- + // Simulate processing on input + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port_reg <= 0; + end + else begin + done_port_reg <= start_port; + end + end + + + //---------------------------------------------------------------- + // Outputs, two cycle latency + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port <= 0; + end + else begin + done_port <= done_port_reg; + if (done_port_reg) begin + $display("printer1: %h %h %h %h", value1, value2, value3, value4); + end + end + end + +endmodule diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.c b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.c new file mode 100644 index 000000000..a73c63f62 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.c @@ -0,0 +1,6 @@ +#include "module_lib.h" +#include +void printer2(uint64_t value1, uint64_t value2, uint16_t value3) +{ + printf("printer2: %llx %llx %x\n", value1, value2, value3); +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.v b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.v new file mode 100644 index 000000000..15fc5bdd0 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/printer2.v @@ -0,0 +1,44 @@ +module printer2 + (input wire clock, + input wire reset, + + input wire start_port, + output reg done_port, + + input wire [63:0] value1, + input wire [63:0] value2, + input wire [15:0] value3); + + reg done_port_reg; + + //---------------------------------------------------------------- + // Simulate processing on input + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port_reg <= 0; + end + else begin + done_port_reg <= start_port; + end + end + + + //---------------------------------------------------------------- + // Outputs, two cycle latency + //---------------------------------------------------------------- + + always @(posedge clock) begin + if (!reset) begin + done_port <= 0; + end + else begin + done_port <= done_port_reg; + if (done_port_reg) begin + $display("printer2: %h %h %h", value1, value2, value3); + end + end + end + +endmodule diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/test.xml b/documentation/tutorial_ics_2021/01-introduction/Exercise5/test.xml new file mode 100644 index 000000000..6a8f8acff --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise5/top.c b/documentation/tutorial_ics_2021/01-introduction/Exercise5/top.c new file mode 100644 index 000000000..46fa1c11a --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise5/top.c @@ -0,0 +1,23 @@ +#include "module_lib.h" + +void my_ip(uint8_t command, uint32_t param1, uint32_t param2) { + static module1_output_t module1_output; + static module2_output_t module2_output; + + switch(command) { + case 0: + module1(param1, param2 >> 16, &module1_output); + break; + case 1: + module2(param1, &module2_output); + break; + case 2: + printer1(module1_output.output1, module1_output.output2, module1_output.output3, module1_output.output4); + break; + case 3: + printer2(module2_output.output1, module2_output.output2, module2_output.output3); + break; + default: + break; + } +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise6/aggregate.h b/documentation/tutorial_ics_2021/01-introduction/Exercise6/aggregate.h new file mode 100644 index 000000000..2d0e9085f --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise6/aggregate.h @@ -0,0 +1,16 @@ +#ifndef AGGREGATE_H +#define AGGREGATE_H + +struct aggregate +{ + float a0; + float a1; + float a2; + float a3; + float a4; + float a5; + float a6; + float a7; +}; + +#endif /* AGGREGATE_H */ diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise6/bambu.sh b/documentation/tutorial_ics_2021/01-introduction/Exercise6/bambu.sh new file mode 100755 index 000000000..7219597b6 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise6/bambu.sh @@ -0,0 +1,12 @@ +#!/bin/bash +script=$(readlink -e $0) +root_dir=$(dirname $script) + +rm -rf hls +mkdir hls +cd hls +echo "#simulation of qsort" +bambu $root_dir/test.c $root_dir/less.c $root_dir/qsort.c --top-fname=test \ + -Os --no-iob \ + --generate-tb=$root_dir/test.xml --simulate \ + -v2 --print-dot --pretty-print=a.c "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise6/less.c b/documentation/tutorial_ics_2021/01-introduction/Exercise6/less.c new file mode 100644 index 000000000..6b5a20dfd --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise6/less.c @@ -0,0 +1,31 @@ +#include "aggregate.h" + + +int less (const void * a, const void * b, void * notUsed) +{ + struct aggregate * aPtr = (struct aggregate *)a; + struct aggregate * bPtr = (struct aggregate *)b; + + float aSum = aPtr->a0 + + aPtr->a1 + + aPtr->a2 + + aPtr->a3 + + aPtr->a4 + + aPtr->a5 + + aPtr->a6 + + aPtr->a7; + float bSum = bPtr->a0 + + bPtr->a1 + + bPtr->a2 + + bPtr->a3 + + bPtr->a4 + + bPtr->a5 + + bPtr->a6 + + bPtr->a7; + int equal = (bSum - aSum) == 0; + if (equal) return 0; + + int lt = (aSum - bSum) < 0; + return lt ? -1 : 1; +} + diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise6/qsort.c b/documentation/tutorial_ics_2021/01-introduction/Exercise6/qsort.c new file mode 100644 index 000000000..64e5a1a81 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise6/qsort.c @@ -0,0 +1,247 @@ +/* Copyright (C) 1991-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* If you consider tuning this algorithm, you should consult first: + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + +#include +#include + +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + size_t __size = (size); \ + char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ +#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + +void +_quicksort (void *const pbase, size_t total_elems, size_t size, + int (*cmp)(const void *, const void *, void *), void *arg) +{ + char *base_ptr = (char *) pbase; + + const size_t max_thresh = MAX_THRESH * size; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + stack_node *top = stack; + + PUSH (NULL, NULL); + + while (STACK_NOT_EMPTY) + { + char *left_ptr; + char *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) + SWAP (mid, lo, size); + jump_over:; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) + left_ptr += size; + + while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise6/test.c b/documentation/tutorial_ics_2021/01-introduction/Exercise6/test.c new file mode 100644 index 000000000..f968a2897 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise6/test.c @@ -0,0 +1,17 @@ +typedef unsigned int size_t; + +typedef int (*__compar_d_fn_t)(void *, void *, void *); + +#include "aggregate.h" + +//#include "qsort.c" +void +_quicksort (void *const pbase, size_t total_elems, size_t size, + int (*cmp)(const void *, const void *, void *), void *arg); +//#include "less.c" +int less (void * a, void * b, void * notUsed); + +void test(float * const pbase, size_t total_elems) +{ + _quicksort(pbase, (sizeof(float) * total_elems) / sizeof(struct aggregate), sizeof(struct aggregate), less , (void *)0); +} diff --git a/documentation/tutorial_ics_2021/01-introduction/Exercise6/test.xml b/documentation/tutorial_ics_2021/01-introduction/Exercise6/test.xml new file mode 100644 index 000000000..a98af4c69 --- /dev/null +++ b/documentation/tutorial_ics_2021/01-introduction/Exercise6/test.xml @@ -0,0 +1,4 @@ + + + + diff --git a/documentation/tutorial_ics_2021/02-target_customization/Exercise1/README b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/README new file mode 100644 index 000000000..a769ec99e --- /dev/null +++ b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/README @@ -0,0 +1 @@ +Synthesize a module which takes as input an array of integer with arbitrary size and returns the minimum and maximum value diff --git a/documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.c b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.c new file mode 100644 index 000000000..2f5a6eaa8 --- /dev/null +++ b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.c @@ -0,0 +1,13 @@ +void max(int input[10], int * max) +{ + int local_max = input[0]; + int i = 0; + for(i = 0; i < 10; i++) + { + if(input[i] > local_max) + { + local_max = input[i]; + } + } + *max = local_max; +} diff --git a/documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.sh b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.sh new file mode 100755 index 000000000..631daa9b8 --- /dev/null +++ b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/hint.sh @@ -0,0 +1,5 @@ +#!/bin/bash +abs_script=$(readlink -e $0) +dir_script=$(dirname $abs_script) + +bambu $dir_script/hint.c "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/minmax.c b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/minmax.c new file mode 100644 index 000000000..2058b7576 --- /dev/null +++ b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/minmax.c @@ -0,0 +1,19 @@ +void min_max(int * input, int num_elements, int * max, int * min) +{ + int local_max = input[0]; + int local_min = input[0]; + int i = 0; + for(i = 0; i < num_elements; i++) + { + if(input[i] > local_max) + { + local_max = input[i]; + } + else if(input[i] < local_min) + { + local_min = input[i]; + } + } + *min = local_min; + *max = local_max; +} diff --git a/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/synthesize.sh b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/synthesize.sh new file mode 100755 index 000000000..48f30b583 --- /dev/null +++ b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/synthesize.sh @@ -0,0 +1,2 @@ +#!/bin/bash +bambu minmax.c --generate-tb=testbench.xml --simulate "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/testbench.xml b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/testbench.xml new file mode 100644 index 000000000..3781cfbc4 --- /dev/null +++ b/documentation/tutorial_ics_2021/02-target_customization/Exercise1/solution/testbench.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/README b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/README new file mode 100644 index 000000000..ebe8c2298 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/README @@ -0,0 +1,5 @@ +Evaluate the effects of GCC optimizations on the number of cycles of adpcm benchmark: +- Different level of optimizations +- Vectorization +- Different inlining + diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/adpcm.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/adpcm.c new file mode 100755 index 000000000..613b1bdb5 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/adpcm.c @@ -0,0 +1,882 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*************************************************************************/ +/* */ +/* SNU-RT Benchmark Suite for Worst Case Timing Analysis */ +/* ===================================================== */ +/* Collected and Modified by S.-S. Lim */ +/* sslim@archi.snu.ac.kr */ +/* Real-Time Research Group */ +/* Seoul National University */ +/* */ +/* */ +/* < Features > - restrictions for our experimental environment */ +/* */ +/* 1. Completely structured. */ +/* - There are no unconditional jumps. */ +/* - There are no exit from loop bodies. */ +/* (There are no 'break' or 'return' in loop bodies) */ +/* 2. No 'switch' statements. */ +/* 3. No 'do..while' statements. */ +/* 4. Expressions are restricted. */ +/* - There are no multiple expressions joined by 'or', */ +/* 'and' operations. */ +/* 5. No library calls. */ +/* - All the functions needed are implemented in the */ +/* source file. */ +/* */ +/* */ +/*************************************************************************/ +/* */ +/* FILE: adpcm.c */ +/* SOURCE : C Algorithms for Real-Time DSP by P. M. Embree */ +/* */ +/* DESCRIPTION : */ +/* */ +/* CCITT G.722 ADPCM (Adaptive Differential Pulse Code Modulation) */ +/* algorithm. */ +/* 16khz sample rate data is stored in the array test_data[SIZE]. */ +/* Results are stored in the array compressed[SIZE] and result[SIZE].*/ +/* Execution time is determined by the constant SIZE (default value */ +/* is 2000). */ +/* */ +/* REMARK : */ +/* */ +/* EXECUTION TIME : */ +/* */ +/* */ +/*************************************************************************/ +#include + +int encode (int, int); +void decode (int); +int filtez (int *bpl, int *dlt); +void upzero (int dlt, int *dlti, int *bli); +int filtep (int rlt1, int al1, int rlt2, int al2); +int quantl (int el, int detl); +int logscl (int il, int nbl); +int scalel (int nbl, int shift_constant); +int uppol2 (int al1, int al2, int plt, int plt1, int plt2); +int uppol1 (int al1, int apl2, int plt, int plt1); +int logsch (int ih, int nbh); +void reset (); + +/* G722 C code */ + +/* variables for transimit quadrature mirror filter here */ +int tqmf[24]; + +/* QMF filter coefficients: +scaled by a factor of 4 compared to G722 CCITT recomendation */ +const int h[24] = { + 12, -44, -44, 212, 48, -624, 128, 1448, + -840, -3220, 3804, 15504, 15504, 3804, -3220, -840, + 1448, 128, -624, 48, 212, -44, -44, 12 +}; + +int xl, xh; + +/* variables for receive quadrature mirror filter here */ +int accumc[11], accumd[11]; + +/* outputs of decode() */ +int xout1, xout2; + +int xs, xd; + +/* variables for encoder (hi and lo) here */ + +int il, szl, spl, sl, el; + +const int qq4_code4_table[16] = { + 0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, 4240, 2584, 1200, 0 +}; + + +const int qq6_code6_table[64] = { + -136, -136, -136, -136, -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, 432, 136, -432, -136 +}; + +int delay_bpl[6]; + +int delay_dltx[6]; + +const int wl_code_table[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; + +const int ilb_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; + +int nbl; /* delay line */ +int al1, al2; +int plt, plt1, plt2; +int dlt; +int rlt, rlt1, rlt2; + +/* decision levels - pre-multiplied by 8, 0 to indicate end */ +const int decis_levl[30] = { + 280, 576, 880, 1200, 1520, 1864, 2208, 2584, + 2960, 3376, 3784, 4240, 4696, 5200, 5712, 6288, + 6864, 7520, 8184, 8968, 9752, 10712, 11664, 12896, + 14120, 15840, 17560, 20456, 23352, 32767 +}; + +int detl; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +const int quant26bt_pos[31] = { + 61, 60, 59, 58, 57, 56, 55, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 38, + 37, 36, 35, 34, 33, 32, 32 +}; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +const int quant26bt_neg[31] = { + 63, 62, 31, 30, 29, 28, 27, 26, + 25, 24, 23, 22, 21, 20, 19, 18, + 17, 16, 15, 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 4 +}; + + +int deth; +int sh; /* this comes from adaptive predictor */ +int eh; + +const int qq2_code2_table[4] = { + -7408, -1616, 7408, 1616 +}; + +const int wh_code_table[4] = { + 798, -214, 798, -214 +}; + + +int dh, ih; +int nbh, szh; +int sph, ph, yh, rh; + +int delay_dhx[6]; + +int delay_bph[6]; + +int ah1, ah2; +int ph1, ph2; +int rh1, rh2; + +/* variables for decoder here */ +int ilr, rl; +int dec_deth, dec_detl, dec_dlt; + +int dec_del_bpl[6]; + +int dec_del_dltx[6]; + +int dec_plt, dec_plt1, dec_plt2; +int dec_szl, dec_spl, dec_sl; +int dec_rlt1, dec_rlt2, dec_rlt; +int dec_al1, dec_al2; +int dl; +int dec_nbl, dec_dh, dec_nbh; + +/* variables used in filtez */ +int dec_del_bph[6]; + +int dec_del_dhx[6]; + +int dec_szh; +/* variables used in filtep */ +int dec_rh1, dec_rh2; +int dec_ah1, dec_ah2; +int dec_ph, dec_sph; + +int dec_sh; + +int dec_ph1, dec_ph2; + +/* G722 encode function two ints in, one 8 bit output */ + +/* put input samples in xin1 = first value, xin2 = second value */ +/* returns il and ih stored together */ + +int +abs (int n) +{ + int m; + + if (n >= 0) + m = n; + else + m = -n; + return m; +} + +int +encode (int xin1, int xin2) +{ + int i; + const int *h_ptr; + int *tqmf_ptr, *tqmf_ptr1; + long int xa, xb; + int decis; + +/* transmit quadrature mirror filters implemented here */ + h_ptr = h; + tqmf_ptr = tqmf; + xa = (long) (*tqmf_ptr++) * (*h_ptr++); + xb = (long) (*tqmf_ptr++) * (*h_ptr++); +/* main multiply accumulate loop for samples and coefficients */ + for (i = 0; i < 10; i++) + { + xa += (long) (*tqmf_ptr++) * (*h_ptr++); + xb += (long) (*tqmf_ptr++) * (*h_ptr++); + } +/* final mult/accumulate */ + xa += (long) (*tqmf_ptr++) * (*h_ptr++); + xb += (long) (*tqmf_ptr) * (*h_ptr++); + +/* update delay line tqmf */ + tqmf_ptr1 = tqmf_ptr - 2; + for (i = 0; i < 22; i++) + *tqmf_ptr-- = *tqmf_ptr1--; + *tqmf_ptr-- = xin1; + *tqmf_ptr = xin2; + +/* scale outputs */ + xl = (xa + xb) >> 15; + xh = (xa - xb) >> 15; + +/* end of quadrature mirror filter code */ + +/* starting with lower sub band encoder */ + +/* filtez - compute predictor output section - zero section */ + szl = filtez (delay_bpl, delay_dltx); + +/* filtep - compute predictor output signal (pole section) */ + spl = filtep (rlt1, al1, rlt2, al2); + +/* compute the predictor output value in the lower sub_band encoder */ + sl = szl + spl; + el = xl - sl; + +/* quantl: quantize the difference signal */ + il = quantl (el, detl); + +/* computes quantized difference signal */ +/* for invqbl, truncate by 2 lsbs, so mode = 3 */ + dlt = ((long) detl * qq4_code4_table[il >> 2]) >> 15; + +/* logscl: updates logarithmic quant. scale factor in low sub band */ + nbl = logscl (il, nbl); + +/* scalel: compute the quantizer scale factor in the lower sub band */ +/* calling parameters nbl and 8 (constant such that scalel can be scaleh) */ + detl = scalel (nbl, 8); + +/* parrec - simple addition to compute recontructed signal for adaptive pred */ + plt = dlt + szl; + +/* upzero: update zero section predictor coefficients (sixth order)*/ +/* calling parameters: dlt, dlt1, dlt2, ..., dlt6 from dlt */ +/* bpli (linear_buffer in which all six values are delayed */ +/* return params: updated bpli, delayed dltx */ + upzero (dlt, delay_dltx, delay_bpl); + +/* uppol2- update second predictor coefficient apl2 and delay it as al2 */ +/* calling parameters: al1, al2, plt, plt1, plt2 */ + al2 = uppol2 (al1, al2, plt, plt1, plt2); + +/* uppol1 :update first predictor coefficient apl1 and delay it as al1 */ +/* calling parameters: al1, apl2, plt, plt1 */ + al1 = uppol1 (al1, al2, plt, plt1); + +/* recons : compute recontructed signal for adaptive predictor */ + rlt = sl + dlt; + +/* done with lower sub_band encoder; now implement delays for next time*/ + rlt2 = rlt1; + rlt1 = rlt; + plt2 = plt1; + plt1 = plt; + +/* high band encode */ + + szh = filtez (delay_bph, delay_dhx); + + sph = filtep (rh1, ah1, rh2, ah2); + +/* predic: sh = sph + szh */ + sh = sph + szh; +/* subtra: eh = xh - sh */ + eh = xh - sh; + +/* quanth - quantization of difference signal for higher sub-band */ +/* quanth: in-place for speed params: eh, deth (has init. value) */ + if (eh >= 0) + { + ih = 3; /* 2,3 are pos codes */ + } + else + { + ih = 1; /* 0,1 are neg codes */ + } + decis = (564L * (long) deth) >> 12L; + if (abs (eh) > decis) + ih--; /* mih = 2 case */ + +/* compute the quantized difference signal, higher sub-band*/ + dh = ((long) deth * qq2_code2_table[ih]) >> 15L; + +/* logsch: update logarithmic quantizer scale factor in hi sub-band*/ + nbh = logsch (ih, nbh); + +/* note : scalel and scaleh use same code, different parameters */ + deth = scalel (nbh, 10); + +/* parrec - add pole predictor output to quantized diff. signal */ + ph = dh + szh; + +/* upzero: update zero section predictor coefficients (sixth order) */ +/* calling parameters: dh, dhi, bphi */ +/* return params: updated bphi, delayed dhx */ + upzero (dh, delay_dhx, delay_bph); + +/* uppol2: update second predictor coef aph2 and delay as ah2 */ +/* calling params: ah1, ah2, ph, ph1, ph2 */ + ah2 = uppol2 (ah1, ah2, ph, ph1, ph2); + +/* uppol1: update first predictor coef. aph2 and delay it as ah1 */ + ah1 = uppol1 (ah1, ah2, ph, ph1); + +/* recons for higher sub-band */ + yh = sh + dh; + +/* done with higher sub-band encoder, now Delay for next time */ + rh2 = rh1; + rh1 = yh; + ph2 = ph1; + ph1 = ph; + +/* multiplex ih and il to get signals together */ + return (il | (ih << 6)); +} + +/* decode function, result in xout1 and xout2 */ + +void +decode (int input) +{ + int i; + long int xa1, xa2; /* qmf accumulators */ + const int *h_ptr; + int *ac_ptr, *ac_ptr1, *ad_ptr, *ad_ptr1; + +/* split transmitted word from input into ilr and ih */ + ilr = input & 0x3f; + ih = input >> 6; + +/* LOWER SUB_BAND DECODER */ + +/* filtez: compute predictor output for zero section */ + dec_szl = filtez (dec_del_bpl, dec_del_dltx); + +/* filtep: compute predictor output signal for pole section */ + dec_spl = filtep (dec_rlt1, dec_al1, dec_rlt2, dec_al2); + + dec_sl = dec_spl + dec_szl; + +/* compute quantized difference signal for adaptive predic */ + dec_dlt = ((long) dec_detl * qq4_code4_table[ilr >> 2]) >> 15; + +/* compute quantized difference signal for decoder output */ + dl = ((long) dec_detl * qq6_code6_table[il]) >> 15; + + rl = dl + dec_sl; + +/* logscl: quantizer scale factor adaptation in the lower sub-band */ + dec_nbl = logscl (ilr, dec_nbl); + +/* scalel: computes quantizer scale factor in the lower sub band */ + dec_detl = scalel (dec_nbl, 8); + +/* parrec - add pole predictor output to quantized diff. signal */ +/* for partially reconstructed signal */ + dec_plt = dec_dlt + dec_szl; + +/* upzero: update zero section predictor coefficients */ + upzero (dec_dlt, dec_del_dltx, dec_del_bpl); + +/* uppol2: update second predictor coefficient apl2 and delay it as al2 */ + dec_al2 = uppol2 (dec_al1, dec_al2, dec_plt, dec_plt1, dec_plt2); + +/* uppol1: update first predictor coef. (pole setion) */ + dec_al1 = uppol1 (dec_al1, dec_al2, dec_plt, dec_plt1); + +/* recons : compute recontructed signal for adaptive predictor */ + dec_rlt = dec_sl + dec_dlt; + +/* done with lower sub band decoder, implement delays for next time */ + dec_rlt2 = dec_rlt1; + dec_rlt1 = dec_rlt; + dec_plt2 = dec_plt1; + dec_plt1 = dec_plt; + +/* HIGH SUB-BAND DECODER */ + +/* filtez: compute predictor output for zero section */ + dec_szh = filtez (dec_del_bph, dec_del_dhx); + +/* filtep: compute predictor output signal for pole section */ + dec_sph = filtep (dec_rh1, dec_ah1, dec_rh2, dec_ah2); + +/* predic:compute the predictor output value in the higher sub_band decoder */ + dec_sh = dec_sph + dec_szh; + +/* in-place compute the quantized difference signal */ + dec_dh = ((long) dec_deth * qq2_code2_table[ih]) >> 15L; + +/* logsch: update logarithmic quantizer scale factor in hi sub band */ + dec_nbh = logsch (ih, dec_nbh); + +/* scalel: compute the quantizer scale factor in the higher sub band */ + dec_deth = scalel (dec_nbh, 10); + +/* parrec: compute partially recontructed signal */ + dec_ph = dec_dh + dec_szh; + +/* upzero: update zero section predictor coefficients */ + upzero (dec_dh, dec_del_dhx, dec_del_bph); + +/* uppol2: update second predictor coefficient aph2 and delay it as ah2 */ + dec_ah2 = uppol2 (dec_ah1, dec_ah2, dec_ph, dec_ph1, dec_ph2); + +/* uppol1: update first predictor coef. (pole setion) */ + dec_ah1 = uppol1 (dec_ah1, dec_ah2, dec_ph, dec_ph1); + +/* recons : compute recontructed signal for adaptive predictor */ + rh = dec_sh + dec_dh; + +/* done with high band decode, implementing delays for next time here */ + dec_rh2 = dec_rh1; + dec_rh1 = rh; + dec_ph2 = dec_ph1; + dec_ph1 = dec_ph; + +/* end of higher sub_band decoder */ + +/* end with receive quadrature mirror filters */ + xd = rl - rh; + xs = rl + rh; + +/* receive quadrature mirror filters implemented here */ + h_ptr = h; + ac_ptr = accumc; + ad_ptr = accumd; + xa1 = (long) xd *(*h_ptr++); + xa2 = (long) xs *(*h_ptr++); +/* main multiply accumulate loop for samples and coefficients */ + for (i = 0; i < 10; i++) + { + xa1 += (long) (*ac_ptr++) * (*h_ptr++); + xa2 += (long) (*ad_ptr++) * (*h_ptr++); + } +/* final mult/accumulate */ + xa1 += (long) (*ac_ptr) * (*h_ptr++); + xa2 += (long) (*ad_ptr) * (*h_ptr++); + +/* scale by 2^14 */ + xout1 = xa1 >> 14; + xout2 = xa2 >> 14; + +/* update delay lines */ + ac_ptr1 = ac_ptr - 1; + ad_ptr1 = ad_ptr - 1; + for (i = 0; i < 10; i++) + { + *ac_ptr-- = *ac_ptr1--; + *ad_ptr-- = *ad_ptr1--; + } + *ac_ptr = xd; + *ad_ptr = xs; +} + +/* clear all storage locations */ + +void +reset () +{ + int i; + + detl = dec_detl = 32; /* reset to min scale factor */ + deth = dec_deth = 8; + nbl = al1 = al2 = plt1 = plt2 = rlt1 = rlt2 = 0; + nbh = ah1 = ah2 = ph1 = ph2 = rh1 = rh2 = 0; + dec_nbl = dec_al1 = dec_al2 = dec_plt1 = dec_plt2 = dec_rlt1 = dec_rlt2 = 0; + dec_nbh = dec_ah1 = dec_ah2 = dec_ph1 = dec_ph2 = dec_rh1 = dec_rh2 = 0; + + for (i = 0; i < 6; i++) + { + delay_dltx[i] = 0; + delay_dhx[i] = 0; + dec_del_dltx[i] = 0; + dec_del_dhx[i] = 0; + } + + for (i = 0; i < 6; i++) + { + delay_bpl[i] = 0; + delay_bph[i] = 0; + dec_del_bpl[i] = 0; + dec_del_bph[i] = 0; + } + + for (i = 0; i < 24; i++) + tqmf[i] = 0; // i<23 + + for (i = 0; i < 11; i++) + { + accumc[i] = 0; + accumd[i] = 0; + } +} + +/* filtez - compute predictor output signal (zero section) */ +/* input: bpl1-6 and dlt1-6, output: szl */ + +int +filtez (int *bpl, int *dlt) +{ + int i; + long int zl; + zl = (long) (*bpl++) * (*dlt++); + for (i = 1; i < 6; i++) + zl += (long) (*bpl++) * (*dlt++); + + return ((int) (zl >> 14)); /* x2 here */ +} + +/* filtep - compute predictor output signal (pole section) */ +/* input rlt1-2 and al1-2, output spl */ + +int +filtep (int rlt1, int al1, int rlt2, int al2) +{ + long int pl, pl2; + pl = 2 * rlt1; + pl = (long) al1 *pl; + pl2 = 2 * rlt2; + pl += (long) al2 *pl2; + return ((int) (pl >> 15)); +} + +/* quantl - quantize the difference signal in the lower sub-band */ +int +quantl (int el, int detl) +{ + int ril, mil; + long int wd, decis; + +/* abs of difference signal */ + wd = abs (el); +/* determine mil based on decision levels and detl gain */ + for (mil = 0; mil < 30; mil++) + { + decis = (decis_levl[mil] * (long) detl) >> 15L; + if (wd <= decis) + break; + } +/* if mil=30 then wd is less than all decision levels */ + if (el >= 0) + ril = quant26bt_pos[mil]; + else + ril = quant26bt_neg[mil]; + return (ril); +} + +/* logscl - update log quantizer scale factor in lower sub-band */ +/* note that nbl is passed and returned */ + +int +logscl (int il, int nbl) +{ + long int wd; + wd = ((long) nbl * 127L) >> 7L; /* leak factor 127/128 */ + nbl = (int) wd + wl_code_table[il >> 2]; + if (nbl < 0) + nbl = 0; + if (nbl > 18432) + nbl = 18432; + return (nbl); +} + +/* scalel: compute quantizer scale factor in lower or upper sub-band*/ + +int +scalel (int nbl, int shift_constant) +{ + int wd1, wd2, wd3; + wd1 = (nbl >> 6) & 31; + wd2 = nbl >> 11; + wd3 = ilb_table[wd1] >> (shift_constant + 1 - wd2); + return (wd3 << 3); +} + +/* upzero - inputs: dlt, dlti[0-5], bli[0-5], outputs: updated bli[0-5] */ +/* also implements delay of bli and update of dlti from dlt */ + +void +upzero (int dlt, int *dlti, int *bli) +{ + int i, wd2, wd3; +/*if dlt is zero, then no sum into bli */ + if (dlt == 0) + { + for (i = 0; i < 6; i++) + { + bli[i] = (int) ((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + } + } + else + { + for (i = 0; i < 6; i++) + { + if ((long) dlt * dlti[i] >= 0) + wd2 = 128; + else + wd2 = -128; + wd3 = (int) ((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + bli[i] = wd2 + wd3; + } + } +/* implement delay line for dlt */ + dlti[5] = dlti[4]; + dlti[4] = dlti[3]; + dlti[3] = dlti[2]; + dlti[2] = dlti[1]; + dlti[1] = dlti[0]; + dlti[0] = dlt; +} + +/* uppol2 - update second predictor coefficient (pole section) */ +/* inputs: al1, al2, plt, plt1, plt2. outputs: apl2 */ + +int +uppol2 (int al1, int al2, int plt, int plt1, int plt2) +{ + long int wd2, wd4; + int apl2; + wd2 = 4L * (long) al1; + if ((long) plt * plt1 >= 0L) + wd2 = -wd2; /* check same sign */ + wd2 = wd2 >> 7; /* gain of 1/128 */ + if ((long) plt * plt2 >= 0L) + { + wd4 = wd2 + 128; /* same sign case */ + } + else + { + wd4 = wd2 - 128; + } + apl2 = wd4 + (127L * (long) al2 >> 7L); /* leak factor of 127/128 */ + +/* apl2 is limited to +-.75 */ + if (apl2 > 12288) + apl2 = 12288; + if (apl2 < -12288) + apl2 = -12288; + return (apl2); +} + +/* uppol1 - update first predictor coefficient (pole section) */ +/* inputs: al1, apl2, plt, plt1. outputs: apl1 */ + +int +uppol1 (int al1, int apl2, int plt, int plt1) +{ + long int wd2; + int wd3, apl1; + wd2 = ((long) al1 * 255L) >> 8L; /* leak factor of 255/256 */ + if ((long) plt * plt1 >= 0L) + { + apl1 = (int) wd2 + 192; /* same sign case */ + } + else + { + apl1 = (int) wd2 - 192; + } +/* note: wd3= .9375-.75 is always positive */ + wd3 = 15360 - apl2; /* limit value */ + if (apl1 > wd3) + apl1 = wd3; + if (apl1 < -wd3) + apl1 = -wd3; + return (apl1); +} + +/* logsch - update log quantizer scale factor in higher sub-band */ +/* note that nbh is passed and returned */ + +int +logsch (int ih, int nbh) +{ + int wd; + wd = ((long) nbh * 127L) >> 7L; /* leak factor 127/128 */ + nbh = wd + wh_code_table[ih]; + if (nbh < 0) + nbh = 0; + if (nbh > 22528) + nbh = 22528; + return (nbh); +} + +/* ++--------------------------------------------------------------------------+ +| * Test Vectors (added for CHStone) | +| test_data : input data | +| test_compressed : expected output data for "encode" | +| test_result : expected output data for "decode" | ++--------------------------------------------------------------------------+ +*/ + +#define SIZE 100 +#define IN_END 100 + +const int test_data[SIZE] = { + 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x43, 0x43, 0x43, + 0x43, 0x43, 0x43, 0x43, 0x42, + 0x42, 0x42, 0x42, 0x42, 0x42, + 0x41, 0x41, 0x41, 0x41, 0x41, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x3f, 0x3f, + 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c +}; +int compressed[SIZE], result[SIZE]; +const int test_compressed[SIZE] = { + 0xfd, 0xde, 0x77, 0xba, 0xf2, + 0x90, 0x20, 0xa0, 0xec, 0xed, + 0xef, 0xf1, 0xf3, 0xf4, 0xf5, + 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, + 0xf6, 0xf7, 0xf8, 0xf7, 0xf8, + 0xf7, 0xf9, 0xf8, 0xf7, 0xf9, + 0xf8, 0xf8, 0xf6, 0xf8, 0xf8, + 0xf7, 0xf9, 0xf9, 0xf9, 0xf8, + 0xf7, 0xfa, 0xf8, 0xf8, 0xf7, + 0xfb, 0xfa, 0xf9, 0xf8, 0xf8 +}; +const int test_result[SIZE] = { + 0, 0xffffffff, 0xffffffff, 0, 0, + 0xffffffff, 0, 0, 0xffffffff, 0xffffffff, + 0, 0, 0x1, 0x1, 0, + 0xfffffffe, 0xffffffff, 0xfffffffe, 0, 0xfffffffc, + 0x1, 0x1, 0x1, 0xfffffffb, 0x2, + 0x2, 0x3, 0xb, 0x14, 0x14, + 0x16, 0x18, 0x20, 0x21, 0x26, + 0x27, 0x2e, 0x2f, 0x33, 0x32, + 0x35, 0x33, 0x36, 0x34, 0x37, + 0x34, 0x37, 0x35, 0x38, 0x36, + 0x39, 0x38, 0x3b, 0x3a, 0x3f, + 0x3f, 0x40, 0x3a, 0x3d, 0x3e, + 0x41, 0x3c, 0x3e, 0x3f, 0x42, + 0x3e, 0x3b, 0x37, 0x3b, 0x3e, + 0x41, 0x3b, 0x3b, 0x3a, 0x3b, + 0x36, 0x39, 0x3b, 0x3f, 0x3c, + 0x3b, 0x37, 0x3b, 0x3d, 0x41, + 0x3d, 0x3e, 0x3c, 0x3e, 0x3b, + 0x3a, 0x37, 0x3b, 0x3e, 0x41, + 0x3c, 0x3b, 0x39, 0x3a, 0x36 +}; + +void +adpcm_main () +{ + int i, j; + +/* reset, initialize required memory */ + reset (); + + j = 10; + + for (i = 0; i < IN_END; i += 2) + { + compressed[i / 2] = encode (test_data[i], test_data[i + 1]); + } + for (i = 0; i < IN_END; i += 2) + { + decode (compressed[i / 2]); + result[i] = xout1; + result[i + 1] = xout2; + } +} + +int +main () +{ + int i; + int main_result; + + main_result = 0; + adpcm_main (); + for (i = 0; i < IN_END / 2; i++) + { + if (compressed[i] != test_compressed[i]) + { + main_result += 1; + } + } + for (i = 0; i < IN_END; i++) + { + if (result[i] != test_result[i]) + { + main_result += 1; + } + } + printf ("%d\n", main_result); + return main_result; + } diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/hint.sh b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/hint.sh new file mode 100755 index 000000000..3bb28d85f --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/hint.sh @@ -0,0 +1,4 @@ +#!/bin/bash +abs_script=$(readlink -e $0) +dir_script=$(dirname $abs_script) +bambu $dir_script/adpcm.c -O0 --simulate "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.c new file mode 100755 index 000000000..613b1bdb5 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.c @@ -0,0 +1,882 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*************************************************************************/ +/* */ +/* SNU-RT Benchmark Suite for Worst Case Timing Analysis */ +/* ===================================================== */ +/* Collected and Modified by S.-S. Lim */ +/* sslim@archi.snu.ac.kr */ +/* Real-Time Research Group */ +/* Seoul National University */ +/* */ +/* */ +/* < Features > - restrictions for our experimental environment */ +/* */ +/* 1. Completely structured. */ +/* - There are no unconditional jumps. */ +/* - There are no exit from loop bodies. */ +/* (There are no 'break' or 'return' in loop bodies) */ +/* 2. No 'switch' statements. */ +/* 3. No 'do..while' statements. */ +/* 4. Expressions are restricted. */ +/* - There are no multiple expressions joined by 'or', */ +/* 'and' operations. */ +/* 5. No library calls. */ +/* - All the functions needed are implemented in the */ +/* source file. */ +/* */ +/* */ +/*************************************************************************/ +/* */ +/* FILE: adpcm.c */ +/* SOURCE : C Algorithms for Real-Time DSP by P. M. Embree */ +/* */ +/* DESCRIPTION : */ +/* */ +/* CCITT G.722 ADPCM (Adaptive Differential Pulse Code Modulation) */ +/* algorithm. */ +/* 16khz sample rate data is stored in the array test_data[SIZE]. */ +/* Results are stored in the array compressed[SIZE] and result[SIZE].*/ +/* Execution time is determined by the constant SIZE (default value */ +/* is 2000). */ +/* */ +/* REMARK : */ +/* */ +/* EXECUTION TIME : */ +/* */ +/* */ +/*************************************************************************/ +#include + +int encode (int, int); +void decode (int); +int filtez (int *bpl, int *dlt); +void upzero (int dlt, int *dlti, int *bli); +int filtep (int rlt1, int al1, int rlt2, int al2); +int quantl (int el, int detl); +int logscl (int il, int nbl); +int scalel (int nbl, int shift_constant); +int uppol2 (int al1, int al2, int plt, int plt1, int plt2); +int uppol1 (int al1, int apl2, int plt, int plt1); +int logsch (int ih, int nbh); +void reset (); + +/* G722 C code */ + +/* variables for transimit quadrature mirror filter here */ +int tqmf[24]; + +/* QMF filter coefficients: +scaled by a factor of 4 compared to G722 CCITT recomendation */ +const int h[24] = { + 12, -44, -44, 212, 48, -624, 128, 1448, + -840, -3220, 3804, 15504, 15504, 3804, -3220, -840, + 1448, 128, -624, 48, 212, -44, -44, 12 +}; + +int xl, xh; + +/* variables for receive quadrature mirror filter here */ +int accumc[11], accumd[11]; + +/* outputs of decode() */ +int xout1, xout2; + +int xs, xd; + +/* variables for encoder (hi and lo) here */ + +int il, szl, spl, sl, el; + +const int qq4_code4_table[16] = { + 0, -20456, -12896, -8968, -6288, -4240, -2584, -1200, + 20456, 12896, 8968, 6288, 4240, 2584, 1200, 0 +}; + + +const int qq6_code6_table[64] = { + -136, -136, -136, -136, -24808, -21904, -19008, -16704, + -14984, -13512, -12280, -11192, -10232, -9360, -8576, -7856, + -7192, -6576, -6000, -5456, -4944, -4464, -4008, -3576, + -3168, -2776, -2400, -2032, -1688, -1360, -1040, -728, + 24808, 21904, 19008, 16704, 14984, 13512, 12280, 11192, + 10232, 9360, 8576, 7856, 7192, 6576, 6000, 5456, + 4944, 4464, 4008, 3576, 3168, 2776, 2400, 2032, + 1688, 1360, 1040, 728, 432, 136, -432, -136 +}; + +int delay_bpl[6]; + +int delay_dltx[6]; + +const int wl_code_table[16] = { + -60, 3042, 1198, 538, 334, 172, 58, -30, + 3042, 1198, 538, 334, 172, 58, -30, -60 +}; + +const int ilb_table[32] = { + 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383, + 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834, + 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371, + 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008 +}; + +int nbl; /* delay line */ +int al1, al2; +int plt, plt1, plt2; +int dlt; +int rlt, rlt1, rlt2; + +/* decision levels - pre-multiplied by 8, 0 to indicate end */ +const int decis_levl[30] = { + 280, 576, 880, 1200, 1520, 1864, 2208, 2584, + 2960, 3376, 3784, 4240, 4696, 5200, 5712, 6288, + 6864, 7520, 8184, 8968, 9752, 10712, 11664, 12896, + 14120, 15840, 17560, 20456, 23352, 32767 +}; + +int detl; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +const int quant26bt_pos[31] = { + 61, 60, 59, 58, 57, 56, 55, 54, + 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 39, 38, + 37, 36, 35, 34, 33, 32, 32 +}; + +/* quantization table 31 long to make quantl look-up easier, +last entry is for mil=30 case when wd is max */ +const int quant26bt_neg[31] = { + 63, 62, 31, 30, 29, 28, 27, 26, + 25, 24, 23, 22, 21, 20, 19, 18, + 17, 16, 15, 14, 13, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 4 +}; + + +int deth; +int sh; /* this comes from adaptive predictor */ +int eh; + +const int qq2_code2_table[4] = { + -7408, -1616, 7408, 1616 +}; + +const int wh_code_table[4] = { + 798, -214, 798, -214 +}; + + +int dh, ih; +int nbh, szh; +int sph, ph, yh, rh; + +int delay_dhx[6]; + +int delay_bph[6]; + +int ah1, ah2; +int ph1, ph2; +int rh1, rh2; + +/* variables for decoder here */ +int ilr, rl; +int dec_deth, dec_detl, dec_dlt; + +int dec_del_bpl[6]; + +int dec_del_dltx[6]; + +int dec_plt, dec_plt1, dec_plt2; +int dec_szl, dec_spl, dec_sl; +int dec_rlt1, dec_rlt2, dec_rlt; +int dec_al1, dec_al2; +int dl; +int dec_nbl, dec_dh, dec_nbh; + +/* variables used in filtez */ +int dec_del_bph[6]; + +int dec_del_dhx[6]; + +int dec_szh; +/* variables used in filtep */ +int dec_rh1, dec_rh2; +int dec_ah1, dec_ah2; +int dec_ph, dec_sph; + +int dec_sh; + +int dec_ph1, dec_ph2; + +/* G722 encode function two ints in, one 8 bit output */ + +/* put input samples in xin1 = first value, xin2 = second value */ +/* returns il and ih stored together */ + +int +abs (int n) +{ + int m; + + if (n >= 0) + m = n; + else + m = -n; + return m; +} + +int +encode (int xin1, int xin2) +{ + int i; + const int *h_ptr; + int *tqmf_ptr, *tqmf_ptr1; + long int xa, xb; + int decis; + +/* transmit quadrature mirror filters implemented here */ + h_ptr = h; + tqmf_ptr = tqmf; + xa = (long) (*tqmf_ptr++) * (*h_ptr++); + xb = (long) (*tqmf_ptr++) * (*h_ptr++); +/* main multiply accumulate loop for samples and coefficients */ + for (i = 0; i < 10; i++) + { + xa += (long) (*tqmf_ptr++) * (*h_ptr++); + xb += (long) (*tqmf_ptr++) * (*h_ptr++); + } +/* final mult/accumulate */ + xa += (long) (*tqmf_ptr++) * (*h_ptr++); + xb += (long) (*tqmf_ptr) * (*h_ptr++); + +/* update delay line tqmf */ + tqmf_ptr1 = tqmf_ptr - 2; + for (i = 0; i < 22; i++) + *tqmf_ptr-- = *tqmf_ptr1--; + *tqmf_ptr-- = xin1; + *tqmf_ptr = xin2; + +/* scale outputs */ + xl = (xa + xb) >> 15; + xh = (xa - xb) >> 15; + +/* end of quadrature mirror filter code */ + +/* starting with lower sub band encoder */ + +/* filtez - compute predictor output section - zero section */ + szl = filtez (delay_bpl, delay_dltx); + +/* filtep - compute predictor output signal (pole section) */ + spl = filtep (rlt1, al1, rlt2, al2); + +/* compute the predictor output value in the lower sub_band encoder */ + sl = szl + spl; + el = xl - sl; + +/* quantl: quantize the difference signal */ + il = quantl (el, detl); + +/* computes quantized difference signal */ +/* for invqbl, truncate by 2 lsbs, so mode = 3 */ + dlt = ((long) detl * qq4_code4_table[il >> 2]) >> 15; + +/* logscl: updates logarithmic quant. scale factor in low sub band */ + nbl = logscl (il, nbl); + +/* scalel: compute the quantizer scale factor in the lower sub band */ +/* calling parameters nbl and 8 (constant such that scalel can be scaleh) */ + detl = scalel (nbl, 8); + +/* parrec - simple addition to compute recontructed signal for adaptive pred */ + plt = dlt + szl; + +/* upzero: update zero section predictor coefficients (sixth order)*/ +/* calling parameters: dlt, dlt1, dlt2, ..., dlt6 from dlt */ +/* bpli (linear_buffer in which all six values are delayed */ +/* return params: updated bpli, delayed dltx */ + upzero (dlt, delay_dltx, delay_bpl); + +/* uppol2- update second predictor coefficient apl2 and delay it as al2 */ +/* calling parameters: al1, al2, plt, plt1, plt2 */ + al2 = uppol2 (al1, al2, plt, plt1, plt2); + +/* uppol1 :update first predictor coefficient apl1 and delay it as al1 */ +/* calling parameters: al1, apl2, plt, plt1 */ + al1 = uppol1 (al1, al2, plt, plt1); + +/* recons : compute recontructed signal for adaptive predictor */ + rlt = sl + dlt; + +/* done with lower sub_band encoder; now implement delays for next time*/ + rlt2 = rlt1; + rlt1 = rlt; + plt2 = plt1; + plt1 = plt; + +/* high band encode */ + + szh = filtez (delay_bph, delay_dhx); + + sph = filtep (rh1, ah1, rh2, ah2); + +/* predic: sh = sph + szh */ + sh = sph + szh; +/* subtra: eh = xh - sh */ + eh = xh - sh; + +/* quanth - quantization of difference signal for higher sub-band */ +/* quanth: in-place for speed params: eh, deth (has init. value) */ + if (eh >= 0) + { + ih = 3; /* 2,3 are pos codes */ + } + else + { + ih = 1; /* 0,1 are neg codes */ + } + decis = (564L * (long) deth) >> 12L; + if (abs (eh) > decis) + ih--; /* mih = 2 case */ + +/* compute the quantized difference signal, higher sub-band*/ + dh = ((long) deth * qq2_code2_table[ih]) >> 15L; + +/* logsch: update logarithmic quantizer scale factor in hi sub-band*/ + nbh = logsch (ih, nbh); + +/* note : scalel and scaleh use same code, different parameters */ + deth = scalel (nbh, 10); + +/* parrec - add pole predictor output to quantized diff. signal */ + ph = dh + szh; + +/* upzero: update zero section predictor coefficients (sixth order) */ +/* calling parameters: dh, dhi, bphi */ +/* return params: updated bphi, delayed dhx */ + upzero (dh, delay_dhx, delay_bph); + +/* uppol2: update second predictor coef aph2 and delay as ah2 */ +/* calling params: ah1, ah2, ph, ph1, ph2 */ + ah2 = uppol2 (ah1, ah2, ph, ph1, ph2); + +/* uppol1: update first predictor coef. aph2 and delay it as ah1 */ + ah1 = uppol1 (ah1, ah2, ph, ph1); + +/* recons for higher sub-band */ + yh = sh + dh; + +/* done with higher sub-band encoder, now Delay for next time */ + rh2 = rh1; + rh1 = yh; + ph2 = ph1; + ph1 = ph; + +/* multiplex ih and il to get signals together */ + return (il | (ih << 6)); +} + +/* decode function, result in xout1 and xout2 */ + +void +decode (int input) +{ + int i; + long int xa1, xa2; /* qmf accumulators */ + const int *h_ptr; + int *ac_ptr, *ac_ptr1, *ad_ptr, *ad_ptr1; + +/* split transmitted word from input into ilr and ih */ + ilr = input & 0x3f; + ih = input >> 6; + +/* LOWER SUB_BAND DECODER */ + +/* filtez: compute predictor output for zero section */ + dec_szl = filtez (dec_del_bpl, dec_del_dltx); + +/* filtep: compute predictor output signal for pole section */ + dec_spl = filtep (dec_rlt1, dec_al1, dec_rlt2, dec_al2); + + dec_sl = dec_spl + dec_szl; + +/* compute quantized difference signal for adaptive predic */ + dec_dlt = ((long) dec_detl * qq4_code4_table[ilr >> 2]) >> 15; + +/* compute quantized difference signal for decoder output */ + dl = ((long) dec_detl * qq6_code6_table[il]) >> 15; + + rl = dl + dec_sl; + +/* logscl: quantizer scale factor adaptation in the lower sub-band */ + dec_nbl = logscl (ilr, dec_nbl); + +/* scalel: computes quantizer scale factor in the lower sub band */ + dec_detl = scalel (dec_nbl, 8); + +/* parrec - add pole predictor output to quantized diff. signal */ +/* for partially reconstructed signal */ + dec_plt = dec_dlt + dec_szl; + +/* upzero: update zero section predictor coefficients */ + upzero (dec_dlt, dec_del_dltx, dec_del_bpl); + +/* uppol2: update second predictor coefficient apl2 and delay it as al2 */ + dec_al2 = uppol2 (dec_al1, dec_al2, dec_plt, dec_plt1, dec_plt2); + +/* uppol1: update first predictor coef. (pole setion) */ + dec_al1 = uppol1 (dec_al1, dec_al2, dec_plt, dec_plt1); + +/* recons : compute recontructed signal for adaptive predictor */ + dec_rlt = dec_sl + dec_dlt; + +/* done with lower sub band decoder, implement delays for next time */ + dec_rlt2 = dec_rlt1; + dec_rlt1 = dec_rlt; + dec_plt2 = dec_plt1; + dec_plt1 = dec_plt; + +/* HIGH SUB-BAND DECODER */ + +/* filtez: compute predictor output for zero section */ + dec_szh = filtez (dec_del_bph, dec_del_dhx); + +/* filtep: compute predictor output signal for pole section */ + dec_sph = filtep (dec_rh1, dec_ah1, dec_rh2, dec_ah2); + +/* predic:compute the predictor output value in the higher sub_band decoder */ + dec_sh = dec_sph + dec_szh; + +/* in-place compute the quantized difference signal */ + dec_dh = ((long) dec_deth * qq2_code2_table[ih]) >> 15L; + +/* logsch: update logarithmic quantizer scale factor in hi sub band */ + dec_nbh = logsch (ih, dec_nbh); + +/* scalel: compute the quantizer scale factor in the higher sub band */ + dec_deth = scalel (dec_nbh, 10); + +/* parrec: compute partially recontructed signal */ + dec_ph = dec_dh + dec_szh; + +/* upzero: update zero section predictor coefficients */ + upzero (dec_dh, dec_del_dhx, dec_del_bph); + +/* uppol2: update second predictor coefficient aph2 and delay it as ah2 */ + dec_ah2 = uppol2 (dec_ah1, dec_ah2, dec_ph, dec_ph1, dec_ph2); + +/* uppol1: update first predictor coef. (pole setion) */ + dec_ah1 = uppol1 (dec_ah1, dec_ah2, dec_ph, dec_ph1); + +/* recons : compute recontructed signal for adaptive predictor */ + rh = dec_sh + dec_dh; + +/* done with high band decode, implementing delays for next time here */ + dec_rh2 = dec_rh1; + dec_rh1 = rh; + dec_ph2 = dec_ph1; + dec_ph1 = dec_ph; + +/* end of higher sub_band decoder */ + +/* end with receive quadrature mirror filters */ + xd = rl - rh; + xs = rl + rh; + +/* receive quadrature mirror filters implemented here */ + h_ptr = h; + ac_ptr = accumc; + ad_ptr = accumd; + xa1 = (long) xd *(*h_ptr++); + xa2 = (long) xs *(*h_ptr++); +/* main multiply accumulate loop for samples and coefficients */ + for (i = 0; i < 10; i++) + { + xa1 += (long) (*ac_ptr++) * (*h_ptr++); + xa2 += (long) (*ad_ptr++) * (*h_ptr++); + } +/* final mult/accumulate */ + xa1 += (long) (*ac_ptr) * (*h_ptr++); + xa2 += (long) (*ad_ptr) * (*h_ptr++); + +/* scale by 2^14 */ + xout1 = xa1 >> 14; + xout2 = xa2 >> 14; + +/* update delay lines */ + ac_ptr1 = ac_ptr - 1; + ad_ptr1 = ad_ptr - 1; + for (i = 0; i < 10; i++) + { + *ac_ptr-- = *ac_ptr1--; + *ad_ptr-- = *ad_ptr1--; + } + *ac_ptr = xd; + *ad_ptr = xs; +} + +/* clear all storage locations */ + +void +reset () +{ + int i; + + detl = dec_detl = 32; /* reset to min scale factor */ + deth = dec_deth = 8; + nbl = al1 = al2 = plt1 = plt2 = rlt1 = rlt2 = 0; + nbh = ah1 = ah2 = ph1 = ph2 = rh1 = rh2 = 0; + dec_nbl = dec_al1 = dec_al2 = dec_plt1 = dec_plt2 = dec_rlt1 = dec_rlt2 = 0; + dec_nbh = dec_ah1 = dec_ah2 = dec_ph1 = dec_ph2 = dec_rh1 = dec_rh2 = 0; + + for (i = 0; i < 6; i++) + { + delay_dltx[i] = 0; + delay_dhx[i] = 0; + dec_del_dltx[i] = 0; + dec_del_dhx[i] = 0; + } + + for (i = 0; i < 6; i++) + { + delay_bpl[i] = 0; + delay_bph[i] = 0; + dec_del_bpl[i] = 0; + dec_del_bph[i] = 0; + } + + for (i = 0; i < 24; i++) + tqmf[i] = 0; // i<23 + + for (i = 0; i < 11; i++) + { + accumc[i] = 0; + accumd[i] = 0; + } +} + +/* filtez - compute predictor output signal (zero section) */ +/* input: bpl1-6 and dlt1-6, output: szl */ + +int +filtez (int *bpl, int *dlt) +{ + int i; + long int zl; + zl = (long) (*bpl++) * (*dlt++); + for (i = 1; i < 6; i++) + zl += (long) (*bpl++) * (*dlt++); + + return ((int) (zl >> 14)); /* x2 here */ +} + +/* filtep - compute predictor output signal (pole section) */ +/* input rlt1-2 and al1-2, output spl */ + +int +filtep (int rlt1, int al1, int rlt2, int al2) +{ + long int pl, pl2; + pl = 2 * rlt1; + pl = (long) al1 *pl; + pl2 = 2 * rlt2; + pl += (long) al2 *pl2; + return ((int) (pl >> 15)); +} + +/* quantl - quantize the difference signal in the lower sub-band */ +int +quantl (int el, int detl) +{ + int ril, mil; + long int wd, decis; + +/* abs of difference signal */ + wd = abs (el); +/* determine mil based on decision levels and detl gain */ + for (mil = 0; mil < 30; mil++) + { + decis = (decis_levl[mil] * (long) detl) >> 15L; + if (wd <= decis) + break; + } +/* if mil=30 then wd is less than all decision levels */ + if (el >= 0) + ril = quant26bt_pos[mil]; + else + ril = quant26bt_neg[mil]; + return (ril); +} + +/* logscl - update log quantizer scale factor in lower sub-band */ +/* note that nbl is passed and returned */ + +int +logscl (int il, int nbl) +{ + long int wd; + wd = ((long) nbl * 127L) >> 7L; /* leak factor 127/128 */ + nbl = (int) wd + wl_code_table[il >> 2]; + if (nbl < 0) + nbl = 0; + if (nbl > 18432) + nbl = 18432; + return (nbl); +} + +/* scalel: compute quantizer scale factor in lower or upper sub-band*/ + +int +scalel (int nbl, int shift_constant) +{ + int wd1, wd2, wd3; + wd1 = (nbl >> 6) & 31; + wd2 = nbl >> 11; + wd3 = ilb_table[wd1] >> (shift_constant + 1 - wd2); + return (wd3 << 3); +} + +/* upzero - inputs: dlt, dlti[0-5], bli[0-5], outputs: updated bli[0-5] */ +/* also implements delay of bli and update of dlti from dlt */ + +void +upzero (int dlt, int *dlti, int *bli) +{ + int i, wd2, wd3; +/*if dlt is zero, then no sum into bli */ + if (dlt == 0) + { + for (i = 0; i < 6; i++) + { + bli[i] = (int) ((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + } + } + else + { + for (i = 0; i < 6; i++) + { + if ((long) dlt * dlti[i] >= 0) + wd2 = 128; + else + wd2 = -128; + wd3 = (int) ((255L * bli[i]) >> 8L); /* leak factor of 255/256 */ + bli[i] = wd2 + wd3; + } + } +/* implement delay line for dlt */ + dlti[5] = dlti[4]; + dlti[4] = dlti[3]; + dlti[3] = dlti[2]; + dlti[2] = dlti[1]; + dlti[1] = dlti[0]; + dlti[0] = dlt; +} + +/* uppol2 - update second predictor coefficient (pole section) */ +/* inputs: al1, al2, plt, plt1, plt2. outputs: apl2 */ + +int +uppol2 (int al1, int al2, int plt, int plt1, int plt2) +{ + long int wd2, wd4; + int apl2; + wd2 = 4L * (long) al1; + if ((long) plt * plt1 >= 0L) + wd2 = -wd2; /* check same sign */ + wd2 = wd2 >> 7; /* gain of 1/128 */ + if ((long) plt * plt2 >= 0L) + { + wd4 = wd2 + 128; /* same sign case */ + } + else + { + wd4 = wd2 - 128; + } + apl2 = wd4 + (127L * (long) al2 >> 7L); /* leak factor of 127/128 */ + +/* apl2 is limited to +-.75 */ + if (apl2 > 12288) + apl2 = 12288; + if (apl2 < -12288) + apl2 = -12288; + return (apl2); +} + +/* uppol1 - update first predictor coefficient (pole section) */ +/* inputs: al1, apl2, plt, plt1. outputs: apl1 */ + +int +uppol1 (int al1, int apl2, int plt, int plt1) +{ + long int wd2; + int wd3, apl1; + wd2 = ((long) al1 * 255L) >> 8L; /* leak factor of 255/256 */ + if ((long) plt * plt1 >= 0L) + { + apl1 = (int) wd2 + 192; /* same sign case */ + } + else + { + apl1 = (int) wd2 - 192; + } +/* note: wd3= .9375-.75 is always positive */ + wd3 = 15360 - apl2; /* limit value */ + if (apl1 > wd3) + apl1 = wd3; + if (apl1 < -wd3) + apl1 = -wd3; + return (apl1); +} + +/* logsch - update log quantizer scale factor in higher sub-band */ +/* note that nbh is passed and returned */ + +int +logsch (int ih, int nbh) +{ + int wd; + wd = ((long) nbh * 127L) >> 7L; /* leak factor 127/128 */ + nbh = wd + wh_code_table[ih]; + if (nbh < 0) + nbh = 0; + if (nbh > 22528) + nbh = 22528; + return (nbh); +} + +/* ++--------------------------------------------------------------------------+ +| * Test Vectors (added for CHStone) | +| test_data : input data | +| test_compressed : expected output data for "encode" | +| test_result : expected output data for "decode" | ++--------------------------------------------------------------------------+ +*/ + +#define SIZE 100 +#define IN_END 100 + +const int test_data[SIZE] = { + 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x43, 0x43, 0x43, + 0x43, 0x43, 0x43, 0x43, 0x42, + 0x42, 0x42, 0x42, 0x42, 0x42, + 0x41, 0x41, 0x41, 0x41, 0x41, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x3f, 0x3f, + 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, + 0x3e, 0x3e, 0x3e, 0x3e, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c +}; +int compressed[SIZE], result[SIZE]; +const int test_compressed[SIZE] = { + 0xfd, 0xde, 0x77, 0xba, 0xf2, + 0x90, 0x20, 0xa0, 0xec, 0xed, + 0xef, 0xf1, 0xf3, 0xf4, 0xf5, + 0xf5, 0xf5, 0xf5, 0xf6, 0xf6, + 0xf6, 0xf7, 0xf8, 0xf7, 0xf8, + 0xf7, 0xf9, 0xf8, 0xf7, 0xf9, + 0xf8, 0xf8, 0xf6, 0xf8, 0xf8, + 0xf7, 0xf9, 0xf9, 0xf9, 0xf8, + 0xf7, 0xfa, 0xf8, 0xf8, 0xf7, + 0xfb, 0xfa, 0xf9, 0xf8, 0xf8 +}; +const int test_result[SIZE] = { + 0, 0xffffffff, 0xffffffff, 0, 0, + 0xffffffff, 0, 0, 0xffffffff, 0xffffffff, + 0, 0, 0x1, 0x1, 0, + 0xfffffffe, 0xffffffff, 0xfffffffe, 0, 0xfffffffc, + 0x1, 0x1, 0x1, 0xfffffffb, 0x2, + 0x2, 0x3, 0xb, 0x14, 0x14, + 0x16, 0x18, 0x20, 0x21, 0x26, + 0x27, 0x2e, 0x2f, 0x33, 0x32, + 0x35, 0x33, 0x36, 0x34, 0x37, + 0x34, 0x37, 0x35, 0x38, 0x36, + 0x39, 0x38, 0x3b, 0x3a, 0x3f, + 0x3f, 0x40, 0x3a, 0x3d, 0x3e, + 0x41, 0x3c, 0x3e, 0x3f, 0x42, + 0x3e, 0x3b, 0x37, 0x3b, 0x3e, + 0x41, 0x3b, 0x3b, 0x3a, 0x3b, + 0x36, 0x39, 0x3b, 0x3f, 0x3c, + 0x3b, 0x37, 0x3b, 0x3d, 0x41, + 0x3d, 0x3e, 0x3c, 0x3e, 0x3b, + 0x3a, 0x37, 0x3b, 0x3e, 0x41, + 0x3c, 0x3b, 0x39, 0x3a, 0x36 +}; + +void +adpcm_main () +{ + int i, j; + +/* reset, initialize required memory */ + reset (); + + j = 10; + + for (i = 0; i < IN_END; i += 2) + { + compressed[i / 2] = encode (test_data[i], test_data[i + 1]); + } + for (i = 0; i < IN_END; i += 2) + { + decode (compressed[i / 2]); + result[i] = xout1; + result[i + 1] = xout2; + } +} + +int +main () +{ + int i; + int main_result; + + main_result = 0; + adpcm_main (); + for (i = 0; i < IN_END / 2; i++) + { + if (compressed[i] != test_compressed[i]) + { + main_result += 1; + } + } + for (i = 0; i < IN_END; i++) + { + if (result[i] != test_result[i]) + { + main_result += 1; + } + } + printf ("%d\n", main_result); + return main_result; + } diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.csv b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.csv new file mode 100644 index 000000000..7139cb2f5 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm.csv @@ -0,0 +1,25 @@ +Benchmark, CYCLES, HLS_execution_time, +CLANG11:adpcm_O0:main_0, 23643,43.0299999999999999989, +CLANG11:adpcm_O1:main_0, 23643,43.8199999999999999997, +CLANG11:adpcm_O2:main_0, 9651,61.9900000000000000015, +CLANG11:adpcm_O3:main_0, 8855,70.1500000000000000014, +CLANG11:adpcm_Os:main_0, 21593,49.4599999999999999992, +CLANG6:adpcm_O0:main_0, 23393,44.1500000000000000014, +CLANG6:adpcm_O1:main_0, 23393,42.9500000000000000007, +CLANG6:adpcm_O2:main_0, 17392,62.4700000000000000011, +CLANG6:adpcm_O3:main_0, 17392,62.5200000000000000004, +CLANG6:adpcm_Os:main_0, 21543,54.5099999999999999985, +GCC49:adpcm_O0:main_0, 33429,23.0499999999999999993, +GCC49:adpcm_O1:main_0, 24547,18.7199999999999999994, +GCC49:adpcm_O2:main_0, 24043,43.2599999999999999985, +GCC49:adpcm_O3:main_0, 10429,76.4499999999999999972, +GCC49:adpcm_O3_inline:main_0, 7503,99.5800000000000000017, +GCC49:adpcm_O3_vectorize:main_0, 6995,49.3100000000000000012, +GCC49:adpcm_Os:main_0, 24847,25.2099999999999999992, +GCC7:adpcm_O0:main_0, 34015,15.8599999999999999997, +GCC7:adpcm_O1:main_0, 24933,16.9500000000000000007, +GCC7:adpcm_O2:main_0, 22526,40.7200000000000000011, +GCC7:adpcm_O3:main_0, 8345,51.0699999999999999997, +GCC7:adpcm_O3_inline:main_0, 5441,59.3400000000000000001, +GCC7:adpcm_O3_vectorize:main_0, 8765,32.6100000000000000006, +GCC7:adpcm_Os:main_0, 25033,27.2199999999999999994, diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm_sdc.csv b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm_sdc.csv new file mode 100644 index 000000000..fdf820d8c --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/adpcm_sdc.csv @@ -0,0 +1,28 @@ +Benchmark, CYCLES, HLS_execution_time, +CLANG11:adpcm_O0:main_0, 23693,92.9400000000000000022, +CLANG11:adpcm_O1:main_0, 23693,91.7799999999999999989, +CLANG11:adpcm_O2:main_0, 10071,147.809999999999999998, +CLANG11:adpcm_O3:main_0, 8719,183.690000000000000002, +CLANG11:adpcm_O3_inline:main_0, 8719,183.960000000000000006, +CLANG11:adpcm_Os:main_0, 22063,97.5100000000000000019, +CLANG6:adpcm_O0:main_0, 23443,91.2099999999999999992, +CLANG6:adpcm_O1:main_0, 23443,93.6999999999999999972, +CLANG6:adpcm_O2:main_0, 17804,124.870000000000000002, +CLANG6:adpcm_O3:main_0, 17804,129.610000000000000001, +CLANG6:adpcm_O3_inline:main_0, 17804,127.849999999999999999, +CLANG6:adpcm_O3_vectorize:main_0, 17804,126.870000000000000002, +CLANG6:adpcm_Os:main_0, 22013,105.059999999999999998, +GCC49:adpcm_O0:main_0, 33479,64.3799999999999999975, +GCC49:adpcm_O1:main_0, 24297,57.0900000000000000001, +GCC49:adpcm_O2:main_0, 22863,83.5299999999999999989, +GCC49:adpcm_O3:main_0, 9149,175.929999999999999993, +GCC49:adpcm_O3_inline:main_0, 5356,210.619999999999999996, +GCC49:adpcm_O3_vectorize:main_0, 6135,110.809999999999999998, +GCC49:adpcm_Os:main_0, 24397,68.4499999999999999972, +GCC7:adpcm_O0:main_0, 32979,46.5, +GCC7:adpcm_O1:main_0, 24297,47.0299999999999999989, +GCC7:adpcm_O2:main_0, 21513,80.2399999999999999981, +GCC7:adpcm_O3:main_0, 7653,152.220000000000000001, +GCC7:adpcm_O3_inline:main_0, 5003,136.25, +GCC7:adpcm_O3_vectorize:main_0, 8235,97.4300000000000000003, +GCC7:adpcm_Os:main_0, 24397,58.2000000000000000007, diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/list b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/list new file mode 100644 index 000000000..9a26f25da --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/list @@ -0,0 +1,7 @@ +adpcm.c --benchmark-name=adpcm_O0 -O0 +adpcm.c --benchmark-name=adpcm_O1 -O1 +adpcm.c --benchmark-name=adpcm_O2 -O2 +adpcm.c --benchmark-name=adpcm_O3 -O3 +adpcm.c --benchmark-name=adpcm_O3_inline -O3 -finline-limit=1000000 +adpcm.c --benchmark-name=adpcm_O3_vectorize -O3 -ftree-vectorize +adpcm.c --benchmark-name=adpcm_Os -Os diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/synthesize.sh b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/synthesize.sh new file mode 100755 index 000000000..8d9bc09cc --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise1/solution/synthesize.sh @@ -0,0 +1,9 @@ +#!/bin/bash +abs_script=$(readlink -e $0) +dir_script=$(dirname $abs_script) +$dir_script/../../test_panda.py --tool=bambu --bambu=bambu --spider=spider \ + --args="--configuration-name=GCC49 --compiler=I386_GCC49" \ + --args="--configuration-name=GCC7 --compiler=I386_GCC7" \ + --args="--configuration-name=CLANG6 --compiler=I386_CLANG6" \ + --args="--configuration-name=CLANG11 --compiler=I386_CLANG11" \ + -c=--simulate -b$dir_script -l$dir_script/list "$@" diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/README b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/README new file mode 100644 index 000000000..cb138e2fb --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/README @@ -0,0 +1 @@ +Evaluate the effects on the number of cycles in using different integer division implementations on the dfdiv algorithm targeting Zynq and 66MHz diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/SPARC-GCC.h b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/SPARC-GCC.h new file mode 100755 index 000000000..523e274f6 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/SPARC-GCC.h @@ -0,0 +1,88 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Each of the following `typedef's defines the most convenient type that holds +| integers of at least as many bits as specified. For example, `uint8' should +| be the most convenient type that can hold unsigned integers of as many as +| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most +| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +| to the same as `int'. +*----------------------------------------------------------------------------*/ +typedef int flag; +typedef int int8; +typedef int int16; + +/*---------------------------------------------------------------------------- +| Each of the following `typedef's defines a type that holds integers +| of _exactly_ the number of bits specified. For instance, for most +| implementation of C, `bits16' and `sbits16' should be `typedef'ed to +| `unsigned short int' and `signed short int' (or `short int'), respectively. +*----------------------------------------------------------------------------*/ +typedef unsigned short int bits16; +typedef unsigned int bits32; +typedef unsigned long long int bits64; +typedef signed long long int sbits64; + +/*---------------------------------------------------------------------------- +| The `LIT64' macro takes as its argument a textual integer literal and +| if necessary ``marks'' the literal as having a 64-bit integer type. +| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +| appended with the letters `LL' standing for `long long', which is `gcc's +| name for the 64-bit integer type. Some compilers may allow `LIT64' to be +| defined as the identity macro: `#define LIT64( a ) a'. +*----------------------------------------------------------------------------*/ +#define LIT64( a ) a##LL + +/*---------------------------------------------------------------------------- +| The macro `INLINE' can be used before functions that should be inlined. If +| a compiler does not support explicit inlining, this macro should be defined +| to be `static'. +*----------------------------------------------------------------------------*/ +#define INLINE diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/dfdiv.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/dfdiv.c new file mode 100755 index 000000000..7fd9823bd --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/dfdiv.c @@ -0,0 +1,159 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/* + * Copyright (C) 2008 + * Y. Hara, H. Tomiyama, S. Honda, H. Takada and K. Ishii + * Nagoya University, Japan + * All rights reserved. + * + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The authors disclaims any and all warranties, + * whether express, implied, or statuary, including any implied warranties or + * merchantability or of fitness for a particular purpose. In no event shall the + * copyright-holder be liable for any incidental, punitive, or consequential damages + * of any kind whatsoever arising from the use of these programs. This disclaimer + * of warranty extends to the user of these programs and user's customers, employees, + * agents, transferees, successors, and assigns. + * + */ +#include +#include "softfloat.c" + +double +ullong_to_double (unsigned long long x) +{ + union + { + double d; + unsigned long long ll; + } t; + + t.ll = x; + return t.d; +} + +/* ++--------------------------------------------------------------------------+ +| * Test Vectors (added for CHStone) | +| a_input, b_input : input data | +| z_output : expected output data | ++--------------------------------------------------------------------------+ +*/ +#define N 22 + +const float64 a_input[N] = { + 0x7FFF000000000000ULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x7FF0000000000000ULL, /* inf */ + 0x7FF0000000000000ULL, /* inf */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x0000000000000000ULL, /* 0.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x0000000000000000ULL, /* 0.0 */ + 0x8000000000000000ULL, /* -0.0 */ + 0x4008000000000000ULL, /* 3.0 */ + 0xC008000000000000ULL, /* -3.0 */ + 0x4008000000000000ULL, /* 3.0 */ + 0xC008000000000000ULL, /* -3.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* -2.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* -2.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0xBFF0000000000000ULL, /* -1.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0xBFF0000000000000ULL /* -1.0 */ +}; + +const float64 b_input[N] = { + 0x3FF0000000000000ULL, /* 1.0 */ + 0x7FF8000000000000ULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x7FF8000000000000ULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x0000000000000000ULL, /* 0.0 */ + 0x0000000000000000ULL, /* 0.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* -2.0 */ + 0x4010000000000000ULL, /* 4.0 */ + 0x4010000000000000ULL, /* 4.0 */ + 0xC010000000000000ULL, /* -4.0 */ + 0xC010000000000000ULL, /* -4.0 */ + 0x3FF8000000000000ULL, /* 1.5 */ + 0x3FF8000000000000ULL, /* 1.5 */ + 0xBFF8000000000000ULL, /* -1.5 */ + 0xBFF8000000000000ULL /* -1.5 */ +}; + +const float64 z_output[N] = { + 0x7FFF000000000000ULL, /* nan */ + 0x7FF8000000000000ULL, /* nan */ + 0x7FFFFFFFFFFFFFFFULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x7FF8000000000000ULL, /* nan */ + 0x0000000000000000ULL, /* 0.0 */ + 0x7FFFFFFFFFFFFFFFULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x0000000000000000ULL, /* 0.0 */ + 0x8000000000000000ULL, /* -0.0 */ + 0x3FF8000000000000ULL, /* 1.5 */ + 0xBFF8000000000000ULL, /* -1.5 */ + 0xBFF8000000000000ULL, /* 1.5 */ + 0x3FF8000000000000ULL, /* -1.5 */ + 0x3FE0000000000000ULL, /* 0.5 */ + 0xBFE0000000000000ULL, /* 5.0 */ + 0xBFE0000000000000ULL, /* -5.0 */ + 0x3FE0000000000000ULL, /* 0.5 */ + 0x3FE5555555555555ULL, /* 0.666667 */ + 0xBFE5555555555555ULL, /* -0.666667 */ + 0xBFE5555555555555ULL, /* -0.666667 */ + 0x3FE5555555555555ULL /* 0.666667 */ +}; + +int +main () +{ + int main_result; + int i; + float64 x1, x2; + main_result = 0; + for (i = 0; i < N; i++) + { + float64 result; + x1 = a_input[i]; + x2 = b_input[i]; + result = float64_div (x1, x2); + main_result += (result != z_output[i]); + + printf + ("a_input=%016llx b_input=%016llx expected=%016llx output=%016llx (%lf)\n", + a_input[i], b_input[i], z_output[i], result, + ullong_to_double (result)); + } + printf ("%d\n", main_result); + return main_result; + } diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/hint.txt b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/hint.txt new file mode 100644 index 000000000..c68ac9a75 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/hint.txt @@ -0,0 +1 @@ +--hls-div= diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/milieu.h b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/milieu.h new file mode 100755 index 000000000..4d92d5e05 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/milieu.h @@ -0,0 +1,53 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Include common integer types and flags. +*----------------------------------------------------------------------------*/ +#include "SPARC-GCC.h" diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-macros b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-macros new file mode 100755 index 000000000..a735f741e --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-macros @@ -0,0 +1,247 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Shifts `a' right by the number of bits given in `count'. If any nonzero +| bits are shifted off, they are ``jammed'' into the least significant bit of +| the result by setting the least significant bit to 1. The value of `count' +| can be arbitrarily large; in particular, if `count' is greater than 64, the +| result will be either 0 or 1, depending on whether `a' is zero or nonzero. +| The result is stored in the location pointed to by `zPtr'. +*----------------------------------------------------------------------------*/ + +INLINE void +shift64RightJamming (bits64 a, int16 count, bits64 * zPtr) +{ + bits64 z; + + if (count == 0) + { + z = a; + } + else if (count < 64) + { + z = (a >> count) | ((a << ((-count) & 63)) != 0); + } + else + { + z = (a != 0); + } + *zPtr = z; + +} + +/*---------------------------------------------------------------------------- +| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit +| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so +| any carry out is lost. The result is broken into two 64-bit pieces which +| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void +add128 (bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, + bits64 * z1Ptr) +{ + bits64 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + (z1 < a1); + +} + +/*---------------------------------------------------------------------------- +| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +| 2^128, so any borrow out (carry out) is lost. The result is broken into two +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +| `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void +sub128 (bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, + bits64 * z1Ptr) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - (a1 < b1); + +} + +/*---------------------------------------------------------------------------- +| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken +| into two 64-bit pieces which are stored at the locations pointed to by +| `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void +mul64To128 (bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr) +{ + bits32 aHigh, aLow, bHigh, bLow; + bits64 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a >> 32; + bLow = b; + bHigh = b >> 32; + z1 = ((bits64) aLow) * bLow; + zMiddleA = ((bits64) aLow) * bHigh; + zMiddleB = ((bits64) aHigh) * bLow; + z0 = ((bits64) aHigh) * bHigh; + zMiddleA += zMiddleB; + z0 += (((bits64) (zMiddleA < zMiddleB)) << 32) + (zMiddleA >> 32); + zMiddleA <<= 32; + z1 += zMiddleA; + z0 += (z1 < zMiddleA); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the 64-bit integer quotient obtained by dividing +| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The +| divisor `b' must be at least 2^63. If q is the exact quotient truncated +| toward zero, the approximation returned lies between q and q + 2 inclusive. +| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +| unsigned integer is returned. +*----------------------------------------------------------------------------*/ + +static bits64 +estimateDiv128To64 (bits64 a0, bits64 a1, bits64 b) +{ + bits64 b0, b1; + bits64 rem0, rem1, term0, term1; + bits64 z; + + if (b <= a0) + return LIT64 (0xFFFFFFFFFFFFFFFF); + b0 = b >> 32; + z = (b0 << 32 <= a0) ? LIT64 (0xFFFFFFFF00000000) : (a0 / b0) << 32; + mul64To128 (b, z, &term0, &term1); + sub128 (a0, a1, term0, term1, &rem0, &rem1); + while (((sbits64) rem0) < 0) + { + z -= LIT64 (0x100000000); + b1 = b << 32; + add128 (rem0, rem1, b0, b1, &rem0, &rem1); + } + rem0 = (rem0 << 32) | (rem1 >> 32); + z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : rem0 / b0; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 32 is returned. +*----------------------------------------------------------------------------*/ + +static int8 +countLeadingZeros32 (bits32 a) +{ + static const int8 countLeadingZerosHigh[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if (a < 0x10000) + { + shiftCount += 16; + a <<= 16; + } + if (a < 0x1000000) + { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[a >> 24]; + return shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 64 is returned. +*----------------------------------------------------------------------------*/ + +static int8 +countLeadingZeros64 (bits64 a) +{ + int8 shiftCount; + + shiftCount = 0; + if (a < ((bits64) 1) << 32) + { + shiftCount += 32; + } + else + { + a >>= 32; + } + shiftCount += countLeadingZeros32 (a); + return shiftCount; + +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-specialize b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-specialize new file mode 100755 index 000000000..3c5105928 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat-specialize @@ -0,0 +1,123 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Underflow tininess-detection mode, statically initialized to default value. +| (The declaration in `softfloat.h' must match the `int8' type here.) +*----------------------------------------------------------------------------*/ +#define float_detect_tininess float_tininess_before_rounding + +/*---------------------------------------------------------------------------- +| Raises the exceptions specified by `flags'. Floating-point traps can be +| defined here if desired. It is currently not possible for such a trap +| to substitute a result value. If traps are not implemented, this routine +| should be simply `float_exception_flags |= flags;'. +*----------------------------------------------------------------------------*/ + +void +float_raise (int8 flags) +{ + float_exception_flags |= flags; + +} + + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +#define float64_default_nan LIT64( 0x7FFFFFFFFFFFFFFF ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag +float64_is_nan (float64 a) +{ + + return (LIT64 (0xFFE0000000000000) < (bits64) (a << 1)); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag +float64_is_signaling_nan (float64 a) +{ + + return (((a >> 51) & 0xFFF) == 0xFFE) && (a & LIT64 (0x0007FFFFFFFFFFFF)); + +} + +/*---------------------------------------------------------------------------- +| Takes two double-precision floating-point values `a' and `b', one of which +| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float64 +propagateFloat64NaN (float64 a, float64 b) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan (a); + aIsSignalingNaN = float64_is_signaling_nan (a); + bIsNaN = float64_is_nan (b); + bIsSignalingNaN = float64_is_signaling_nan (b); + a |= LIT64 (0x0008000000000000); + b |= LIT64 (0x0008000000000000); + if (aIsSignalingNaN | bIsSignalingNaN) + float_raise (float_flag_invalid); + return bIsSignalingNaN ? b : aIsSignalingNaN ? a : bIsNaN ? b : a; + +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.c new file mode 100755 index 000000000..8604da331 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.c @@ -0,0 +1,316 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +#include "milieu.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Floating-point rounding mode, extended double-precision rounding precision, +| and exception flags. +*----------------------------------------------------------------------------*/ +int8 float_rounding_mode = float_round_nearest_even; +int8 float_exception_flags = 0; + +/*---------------------------------------------------------------------------- +| Primitive arithmetic functions, including multi-word arithmetic, and +| division and square root approximations. (Can be specialized to target if +| desired.) +*----------------------------------------------------------------------------*/ +#include "softfloat-macros" + +/*---------------------------------------------------------------------------- +| Functions and definitions to determine: (1) whether tininess for underflow +| is detected before or after rounding by default, (2) what (if anything) +| happens when exceptions are raised, (3) how signaling NaNs are distinguished +| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +| are propagated from function inputs to output. These details are target- +| specific. +*----------------------------------------------------------------------------*/ +#include "softfloat-specialize" + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE bits64 +extractFloat64Frac (float64 a) +{ + + return a & LIT64 (0x000FFFFFFFFFFFFF); + +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE int16 +extractFloat64Exp (float64 a) +{ + + return (a >> 52) & 0x7FF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE flag +extractFloat64Sign (float64 a) +{ + + return a >> 63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal double-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void +normalizeFloat64Subnormal (bits64 aSig, int16 * zExpPtr, bits64 * zSigPtr) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64 (aSig) - 11; + *zSigPtr = aSig << shiftCount; + *zExpPtr = 1 - shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +| double-precision floating-point value, returning the result. After being +| shifted into the proper positions, the three fields are simply added +| together to form the result. This means that any integer portion of `zSig' +| will be added into the exponent. Since a properly normalized significand +| will have an integer portion equal to 1, the `zExp' input should be 1 less +| than the desired result exponent whenever `zSig' is a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +INLINE float64 +packFloat64 (flag zSign, int16 zExp, bits64 zSig) +{ + + return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig; + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper double-precision floating- +| point value corresponding to the abstract input. Ordinarily, the abstract +| value is simply rounded and packed into the double-precision format, with +| the inexact exception raised if the abstract input cannot be represented +| exactly. However, if the abstract value is too large, the overflow and +| inexact exceptions are raised and an infinity or maximal finite value is +| returned. If the abstract value is too small, the input value is rounded +| to a subnormal number, and the underflow and inexact exceptions are raised +| if the abstract input cannot be represented exactly as a subnormal double- +| precision floating-point number. +| The input significand `zSig' has its binary point between bits 62 +| and 61, which is 10 bits to the left of the usual location. This shifted +| significand must be normalized or smaller. If `zSig' is not normalized, +| `zExp' must be 0; in that case, the result returned is a subnormal number, +| and it must not require rounding. In the usual case that `zSig' is +| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. +| The handling of underflow and overflow follows the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 +roundAndPackFloat64 (flag zSign, int16 zExp, bits64 zSig) +{ + int8 roundingMode; + flag roundNearestEven, isTiny; + int16 roundIncrement, roundBits; + + roundingMode = float_rounding_mode; + roundNearestEven = (roundingMode == float_round_nearest_even); + roundIncrement = 0x200; + if (!roundNearestEven) + { + if (roundingMode == float_round_to_zero) + { + roundIncrement = 0; + } + else + { + roundIncrement = 0x3FF; + if (zSign) + { + if (roundingMode == float_round_up) + roundIncrement = 0; + } + else + { + if (roundingMode == float_round_down) + roundIncrement = 0; + } + } + } + roundBits = zSig & 0x3FF; + if (0x7FD <= (bits16) zExp) + { + if ((0x7FD < zExp) + || ((zExp == 0x7FD) && ((sbits64) (zSig + roundIncrement) < 0))) + { + float_raise (float_flag_overflow | float_flag_inexact); + return packFloat64 (zSign, 0x7FF, 0) - (roundIncrement == 0); + } + if (zExp < 0) + { + isTiny = (float_detect_tininess == float_tininess_before_rounding) + || (zExp < -1) + || (zSig + roundIncrement < LIT64 (0x8000000000000000)); + shift64RightJamming (zSig, -zExp, &zSig); + zExp = 0; + roundBits = zSig & 0x3FF; + if (isTiny && roundBits) + float_raise (float_flag_underflow); + } + } + if (roundBits) + float_exception_flags |= float_flag_inexact; + zSig = (zSig + roundIncrement) >> 10; + zSig &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven); + if (zSig == 0) + zExp = 0; + return packFloat64 (zSign, zExp, zSig); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the double-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to +| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 +float64_div (float64 a, float64 b) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1, term0, term1; + + aSig = extractFloat64Frac (a); + aExp = extractFloat64Exp (a); + aSign = extractFloat64Sign (a); + bSig = extractFloat64Frac (b); + bExp = extractFloat64Exp (b); + bSign = extractFloat64Sign (b); + zSign = aSign ^ bSign; + if (aExp == 0x7FF) + { + if (aSig) + return propagateFloat64NaN (a, b); + if (bExp == 0x7FF) + { + if (bSig) + return propagateFloat64NaN (a, b); + float_raise (float_flag_invalid); + return float64_default_nan; + } + return packFloat64 (zSign, 0x7FF, 0); + } + if (bExp == 0x7FF) + { + if (bSig) + return propagateFloat64NaN (a, b); + return packFloat64 (zSign, 0, 0); + } + if (bExp == 0) + { + if (bSig == 0) + { + if ((aExp | aSig) == 0) + { + float_raise (float_flag_invalid); + return float64_default_nan; + } + float_raise (float_flag_divbyzero); + return packFloat64 (zSign, 0x7FF, 0); + } + normalizeFloat64Subnormal (bSig, &bExp, &bSig); + } + if (aExp == 0) + { + if (aSig == 0) + return packFloat64 (zSign, 0, 0); + normalizeFloat64Subnormal (aSig, &aExp, &aSig); + } + zExp = aExp - bExp + 0x3FD; + aSig = (aSig | LIT64 (0x0010000000000000)) << 10; + bSig = (bSig | LIT64 (0x0010000000000000)) << 11; + if (bSig <= (aSig + aSig)) + { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64 (aSig, 0, bSig); + if ((zSig & 0x1FF) <= 2) + { + mul64To128 (bSig, zSig, &term0, &term1); + sub128 (aSig, 0, term0, term1, &rem0, &rem1); + while ((sbits64) rem0 < 0) + { + --zSig; + add128 (rem0, rem1, 0, bSig, &rem0, &rem1); + } + zSig |= (rem1 != 0); + } + return roundAndPackFloat64 (zSign, zExp, zSig); + +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.h b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.h new file mode 100755 index 000000000..6d075ca15 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/softfloat.h @@ -0,0 +1,77 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point types. +*----------------------------------------------------------------------------*/ +typedef unsigned int float32; +typedef unsigned long long float64; + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point underflow tininess-detection mode. +*----------------------------------------------------------------------------*/ +#define float_tininess_after_rounding 0 +#define float_tininess_before_rounding 1 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point rounding mode. +*----------------------------------------------------------------------------*/ +#define float_round_nearest_even 0 +#define float_round_to_zero 1 +#define float_round_up 2 +#define float_round_down 3 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point exception flags. +*----------------------------------------------------------------------------*/ +#define float_flag_inexact 1 +#define float_flag_divbyzero 2 +#define float_flag_underflow 4 +#define float_flag_overflow 8 +#define float_flag_invalid 16 diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/SPARC-GCC.h b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/SPARC-GCC.h new file mode 100755 index 000000000..523e274f6 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/SPARC-GCC.h @@ -0,0 +1,88 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Each of the following `typedef's defines the most convenient type that holds +| integers of at least as many bits as specified. For example, `uint8' should +| be the most convenient type that can hold unsigned integers of as many as +| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most +| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +| to the same as `int'. +*----------------------------------------------------------------------------*/ +typedef int flag; +typedef int int8; +typedef int int16; + +/*---------------------------------------------------------------------------- +| Each of the following `typedef's defines a type that holds integers +| of _exactly_ the number of bits specified. For instance, for most +| implementation of C, `bits16' and `sbits16' should be `typedef'ed to +| `unsigned short int' and `signed short int' (or `short int'), respectively. +*----------------------------------------------------------------------------*/ +typedef unsigned short int bits16; +typedef unsigned int bits32; +typedef unsigned long long int bits64; +typedef signed long long int sbits64; + +/*---------------------------------------------------------------------------- +| The `LIT64' macro takes as its argument a textual integer literal and +| if necessary ``marks'' the literal as having a 64-bit integer type. +| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +| appended with the letters `LL' standing for `long long', which is `gcc's +| name for the 64-bit integer type. Some compilers may allow `LIT64' to be +| defined as the identity macro: `#define LIT64( a ) a'. +*----------------------------------------------------------------------------*/ +#define LIT64( a ) a##LL + +/*---------------------------------------------------------------------------- +| The macro `INLINE' can be used before functions that should be inlined. If +| a compiler does not support explicit inlining, this macro should be defined +| to be `static'. +*----------------------------------------------------------------------------*/ +#define INLINE diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.c new file mode 100755 index 000000000..7fd9823bd --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.c @@ -0,0 +1,159 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/* + * Copyright (C) 2008 + * Y. Hara, H. Tomiyama, S. Honda, H. Takada and K. Ishii + * Nagoya University, Japan + * All rights reserved. + * + * Disclaimer of Warranty + * + * These software programs are available to the user without any license fee or + * royalty on an "as is" basis. The authors disclaims any and all warranties, + * whether express, implied, or statuary, including any implied warranties or + * merchantability or of fitness for a particular purpose. In no event shall the + * copyright-holder be liable for any incidental, punitive, or consequential damages + * of any kind whatsoever arising from the use of these programs. This disclaimer + * of warranty extends to the user of these programs and user's customers, employees, + * agents, transferees, successors, and assigns. + * + */ +#include +#include "softfloat.c" + +double +ullong_to_double (unsigned long long x) +{ + union + { + double d; + unsigned long long ll; + } t; + + t.ll = x; + return t.d; +} + +/* ++--------------------------------------------------------------------------+ +| * Test Vectors (added for CHStone) | +| a_input, b_input : input data | +| z_output : expected output data | ++--------------------------------------------------------------------------+ +*/ +#define N 22 + +const float64 a_input[N] = { + 0x7FFF000000000000ULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x7FF0000000000000ULL, /* inf */ + 0x7FF0000000000000ULL, /* inf */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x0000000000000000ULL, /* 0.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x0000000000000000ULL, /* 0.0 */ + 0x8000000000000000ULL, /* -0.0 */ + 0x4008000000000000ULL, /* 3.0 */ + 0xC008000000000000ULL, /* -3.0 */ + 0x4008000000000000ULL, /* 3.0 */ + 0xC008000000000000ULL, /* -3.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* -2.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* -2.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0xBFF0000000000000ULL, /* -1.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0xBFF0000000000000ULL /* -1.0 */ +}; + +const float64 b_input[N] = { + 0x3FF0000000000000ULL, /* 1.0 */ + 0x7FF8000000000000ULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x7FF8000000000000ULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x0000000000000000ULL, /* 0.0 */ + 0x0000000000000000ULL, /* 0.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x3FF0000000000000ULL, /* 1.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0x4000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* 2.0 */ + 0xC000000000000000ULL, /* -2.0 */ + 0x4010000000000000ULL, /* 4.0 */ + 0x4010000000000000ULL, /* 4.0 */ + 0xC010000000000000ULL, /* -4.0 */ + 0xC010000000000000ULL, /* -4.0 */ + 0x3FF8000000000000ULL, /* 1.5 */ + 0x3FF8000000000000ULL, /* 1.5 */ + 0xBFF8000000000000ULL, /* -1.5 */ + 0xBFF8000000000000ULL /* -1.5 */ +}; + +const float64 z_output[N] = { + 0x7FFF000000000000ULL, /* nan */ + 0x7FF8000000000000ULL, /* nan */ + 0x7FFFFFFFFFFFFFFFULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x7FF8000000000000ULL, /* nan */ + 0x0000000000000000ULL, /* 0.0 */ + 0x7FFFFFFFFFFFFFFFULL, /* nan */ + 0x7FF0000000000000ULL, /* inf */ + 0x0000000000000000ULL, /* 0.0 */ + 0x8000000000000000ULL, /* -0.0 */ + 0x3FF8000000000000ULL, /* 1.5 */ + 0xBFF8000000000000ULL, /* -1.5 */ + 0xBFF8000000000000ULL, /* 1.5 */ + 0x3FF8000000000000ULL, /* -1.5 */ + 0x3FE0000000000000ULL, /* 0.5 */ + 0xBFE0000000000000ULL, /* 5.0 */ + 0xBFE0000000000000ULL, /* -5.0 */ + 0x3FE0000000000000ULL, /* 0.5 */ + 0x3FE5555555555555ULL, /* 0.666667 */ + 0xBFE5555555555555ULL, /* -0.666667 */ + 0xBFE5555555555555ULL, /* -0.666667 */ + 0x3FE5555555555555ULL /* 0.666667 */ +}; + +int +main () +{ + int main_result; + int i; + float64 x1, x2; + main_result = 0; + for (i = 0; i < N; i++) + { + float64 result; + x1 = a_input[i]; + x2 = b_input[i]; + result = float64_div (x1, x2); + main_result += (result != z_output[i]); + + printf + ("a_input=%016llx b_input=%016llx expected=%016llx output=%016llx (%lf)\n", + a_input[i], b_input[i], z_output[i], result, + ullong_to_double (result)); + } + printf ("%d\n", main_result); + return main_result; + } diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.csv b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.csv new file mode 100644 index 000000000..daedfee6a --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/dfdiv.csv @@ -0,0 +1,6 @@ +Benchmark, CYCLES, HLS_execution_time, +GCC49:dfdiv_NR:main_0, 825,44.9199999999999999983, +GCC49:dfdiv_as:main_0, 841,30.1399999999999999994, +GCC49:dfdiv_none:main_0, 1777,37.5, +GCC49:dfdiv_nr1:main_0, 1849,41.1800000000000000003, +GCC49:dfdiv_nr2:main_0, 1105,43.119999999999999999, diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/list b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/list new file mode 100644 index 000000000..a46f62bf6 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/list @@ -0,0 +1,5 @@ +dfdiv.c --benchmark-name=dfdiv_none --hls-div=none +dfdiv.c --benchmark-name=dfdiv_nr1 --hls-div=nr1 +dfdiv.c --benchmark-name=dfdiv_nr2 --hls-div=nr2 +dfdiv.c --benchmark-name=dfdiv_NR --hls-div=NR +dfdiv.c --benchmark-name=dfdiv_as --hls-div=as diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/milieu.h b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/milieu.h new file mode 100755 index 000000000..4d92d5e05 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/milieu.h @@ -0,0 +1,53 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Include common integer types and flags. +*----------------------------------------------------------------------------*/ +#include "SPARC-GCC.h" diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-macros b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-macros new file mode 100755 index 000000000..a735f741e --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-macros @@ -0,0 +1,247 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Shifts `a' right by the number of bits given in `count'. If any nonzero +| bits are shifted off, they are ``jammed'' into the least significant bit of +| the result by setting the least significant bit to 1. The value of `count' +| can be arbitrarily large; in particular, if `count' is greater than 64, the +| result will be either 0 or 1, depending on whether `a' is zero or nonzero. +| The result is stored in the location pointed to by `zPtr'. +*----------------------------------------------------------------------------*/ + +INLINE void +shift64RightJamming (bits64 a, int16 count, bits64 * zPtr) +{ + bits64 z; + + if (count == 0) + { + z = a; + } + else if (count < 64) + { + z = (a >> count) | ((a << ((-count) & 63)) != 0); + } + else + { + z = (a != 0); + } + *zPtr = z; + +} + +/*---------------------------------------------------------------------------- +| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit +| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so +| any carry out is lost. The result is broken into two 64-bit pieces which +| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void +add128 (bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, + bits64 * z1Ptr) +{ + bits64 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + (z1 < a1); + +} + +/*---------------------------------------------------------------------------- +| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +| 2^128, so any borrow out (carry out) is lost. The result is broken into two +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +| `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void +sub128 (bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr, + bits64 * z1Ptr) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - (a1 < b1); + +} + +/*---------------------------------------------------------------------------- +| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken +| into two 64-bit pieces which are stored at the locations pointed to by +| `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void +mul64To128 (bits64 a, bits64 b, bits64 * z0Ptr, bits64 * z1Ptr) +{ + bits32 aHigh, aLow, bHigh, bLow; + bits64 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a >> 32; + bLow = b; + bHigh = b >> 32; + z1 = ((bits64) aLow) * bLow; + zMiddleA = ((bits64) aLow) * bHigh; + zMiddleB = ((bits64) aHigh) * bLow; + z0 = ((bits64) aHigh) * bHigh; + zMiddleA += zMiddleB; + z0 += (((bits64) (zMiddleA < zMiddleB)) << 32) + (zMiddleA >> 32); + zMiddleA <<= 32; + z1 += zMiddleA; + z0 += (z1 < zMiddleA); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the 64-bit integer quotient obtained by dividing +| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The +| divisor `b' must be at least 2^63. If q is the exact quotient truncated +| toward zero, the approximation returned lies between q and q + 2 inclusive. +| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +| unsigned integer is returned. +*----------------------------------------------------------------------------*/ + +static bits64 +estimateDiv128To64 (bits64 a0, bits64 a1, bits64 b) +{ + bits64 b0, b1; + bits64 rem0, rem1, term0, term1; + bits64 z; + + if (b <= a0) + return LIT64 (0xFFFFFFFFFFFFFFFF); + b0 = b >> 32; + z = (b0 << 32 <= a0) ? LIT64 (0xFFFFFFFF00000000) : (a0 / b0) << 32; + mul64To128 (b, z, &term0, &term1); + sub128 (a0, a1, term0, term1, &rem0, &rem1); + while (((sbits64) rem0) < 0) + { + z -= LIT64 (0x100000000); + b1 = b << 32; + add128 (rem0, rem1, b0, b1, &rem0, &rem1); + } + rem0 = (rem0 << 32) | (rem1 >> 32); + z |= (b0 << 32 <= rem0) ? 0xFFFFFFFF : rem0 / b0; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 32 is returned. +*----------------------------------------------------------------------------*/ + +static int8 +countLeadingZeros32 (bits32 a) +{ + static const int8 countLeadingZerosHigh[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if (a < 0x10000) + { + shiftCount += 16; + a <<= 16; + } + if (a < 0x1000000) + { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[a >> 24]; + return shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 64 is returned. +*----------------------------------------------------------------------------*/ + +static int8 +countLeadingZeros64 (bits64 a) +{ + int8 shiftCount; + + shiftCount = 0; + if (a < ((bits64) 1) << 32) + { + shiftCount += 32; + } + else + { + a >>= 32; + } + shiftCount += countLeadingZeros32 (a); + return shiftCount; + +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-specialize b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-specialize new file mode 100755 index 000000000..3c5105928 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat-specialize @@ -0,0 +1,123 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C source fragment is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Underflow tininess-detection mode, statically initialized to default value. +| (The declaration in `softfloat.h' must match the `int8' type here.) +*----------------------------------------------------------------------------*/ +#define float_detect_tininess float_tininess_before_rounding + +/*---------------------------------------------------------------------------- +| Raises the exceptions specified by `flags'. Floating-point traps can be +| defined here if desired. It is currently not possible for such a trap +| to substitute a result value. If traps are not implemented, this routine +| should be simply `float_exception_flags |= flags;'. +*----------------------------------------------------------------------------*/ + +void +float_raise (int8 flags) +{ + float_exception_flags |= flags; + +} + + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +#define float64_default_nan LIT64( 0x7FFFFFFFFFFFFFFF ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag +float64_is_nan (float64 a) +{ + + return (LIT64 (0xFFE0000000000000) < (bits64) (a << 1)); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag +float64_is_signaling_nan (float64 a) +{ + + return (((a >> 51) & 0xFFF) == 0xFFE) && (a & LIT64 (0x0007FFFFFFFFFFFF)); + +} + +/*---------------------------------------------------------------------------- +| Takes two double-precision floating-point values `a' and `b', one of which +| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float64 +propagateFloat64NaN (float64 a, float64 b) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan (a); + aIsSignalingNaN = float64_is_signaling_nan (a); + bIsNaN = float64_is_nan (b); + bIsSignalingNaN = float64_is_signaling_nan (b); + a |= LIT64 (0x0008000000000000); + b |= LIT64 (0x0008000000000000); + if (aIsSignalingNaN | bIsSignalingNaN) + float_raise (float_flag_invalid); + return bIsSignalingNaN ? b : aIsSignalingNaN ? a : bIsNaN ? b : a; + +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.c new file mode 100755 index 000000000..8604da331 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.c @@ -0,0 +1,316 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +#include "milieu.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Floating-point rounding mode, extended double-precision rounding precision, +| and exception flags. +*----------------------------------------------------------------------------*/ +int8 float_rounding_mode = float_round_nearest_even; +int8 float_exception_flags = 0; + +/*---------------------------------------------------------------------------- +| Primitive arithmetic functions, including multi-word arithmetic, and +| division and square root approximations. (Can be specialized to target if +| desired.) +*----------------------------------------------------------------------------*/ +#include "softfloat-macros" + +/*---------------------------------------------------------------------------- +| Functions and definitions to determine: (1) whether tininess for underflow +| is detected before or after rounding by default, (2) what (if anything) +| happens when exceptions are raised, (3) how signaling NaNs are distinguished +| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +| are propagated from function inputs to output. These details are target- +| specific. +*----------------------------------------------------------------------------*/ +#include "softfloat-specialize" + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE bits64 +extractFloat64Frac (float64 a) +{ + + return a & LIT64 (0x000FFFFFFFFFFFFF); + +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE int16 +extractFloat64Exp (float64 a) +{ + + return (a >> 52) & 0x7FF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE flag +extractFloat64Sign (float64 a) +{ + + return a >> 63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal double-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void +normalizeFloat64Subnormal (bits64 aSig, int16 * zExpPtr, bits64 * zSigPtr) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64 (aSig) - 11; + *zSigPtr = aSig << shiftCount; + *zExpPtr = 1 - shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a +| double-precision floating-point value, returning the result. After being +| shifted into the proper positions, the three fields are simply added +| together to form the result. This means that any integer portion of `zSig' +| will be added into the exponent. Since a properly normalized significand +| will have an integer portion equal to 1, the `zExp' input should be 1 less +| than the desired result exponent whenever `zSig' is a complete, normalized +| significand. +*----------------------------------------------------------------------------*/ + +INLINE float64 +packFloat64 (flag zSign, int16 zExp, bits64 zSig) +{ + + return (((bits64) zSign) << 63) + (((bits64) zExp) << 52) + zSig; + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper double-precision floating- +| point value corresponding to the abstract input. Ordinarily, the abstract +| value is simply rounded and packed into the double-precision format, with +| the inexact exception raised if the abstract input cannot be represented +| exactly. However, if the abstract value is too large, the overflow and +| inexact exceptions are raised and an infinity or maximal finite value is +| returned. If the abstract value is too small, the input value is rounded +| to a subnormal number, and the underflow and inexact exceptions are raised +| if the abstract input cannot be represented exactly as a subnormal double- +| precision floating-point number. +| The input significand `zSig' has its binary point between bits 62 +| and 61, which is 10 bits to the left of the usual location. This shifted +| significand must be normalized or smaller. If `zSig' is not normalized, +| `zExp' must be 0; in that case, the result returned is a subnormal number, +| and it must not require rounding. In the usual case that `zSig' is +| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. +| The handling of underflow and overflow follows the IEC/IEEE Standard for +| Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 +roundAndPackFloat64 (flag zSign, int16 zExp, bits64 zSig) +{ + int8 roundingMode; + flag roundNearestEven, isTiny; + int16 roundIncrement, roundBits; + + roundingMode = float_rounding_mode; + roundNearestEven = (roundingMode == float_round_nearest_even); + roundIncrement = 0x200; + if (!roundNearestEven) + { + if (roundingMode == float_round_to_zero) + { + roundIncrement = 0; + } + else + { + roundIncrement = 0x3FF; + if (zSign) + { + if (roundingMode == float_round_up) + roundIncrement = 0; + } + else + { + if (roundingMode == float_round_down) + roundIncrement = 0; + } + } + } + roundBits = zSig & 0x3FF; + if (0x7FD <= (bits16) zExp) + { + if ((0x7FD < zExp) + || ((zExp == 0x7FD) && ((sbits64) (zSig + roundIncrement) < 0))) + { + float_raise (float_flag_overflow | float_flag_inexact); + return packFloat64 (zSign, 0x7FF, 0) - (roundIncrement == 0); + } + if (zExp < 0) + { + isTiny = (float_detect_tininess == float_tininess_before_rounding) + || (zExp < -1) + || (zSig + roundIncrement < LIT64 (0x8000000000000000)); + shift64RightJamming (zSig, -zExp, &zSig); + zExp = 0; + roundBits = zSig & 0x3FF; + if (isTiny && roundBits) + float_raise (float_flag_underflow); + } + } + if (roundBits) + float_exception_flags |= float_flag_inexact; + zSig = (zSig + roundIncrement) >> 10; + zSig &= ~(((roundBits ^ 0x200) == 0) & roundNearestEven); + if (zSig == 0) + zExp = 0; + return packFloat64 (zSign, zExp, zSig); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the double-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to +| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 +float64_div (float64 a, float64 b) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1, term0, term1; + + aSig = extractFloat64Frac (a); + aExp = extractFloat64Exp (a); + aSign = extractFloat64Sign (a); + bSig = extractFloat64Frac (b); + bExp = extractFloat64Exp (b); + bSign = extractFloat64Sign (b); + zSign = aSign ^ bSign; + if (aExp == 0x7FF) + { + if (aSig) + return propagateFloat64NaN (a, b); + if (bExp == 0x7FF) + { + if (bSig) + return propagateFloat64NaN (a, b); + float_raise (float_flag_invalid); + return float64_default_nan; + } + return packFloat64 (zSign, 0x7FF, 0); + } + if (bExp == 0x7FF) + { + if (bSig) + return propagateFloat64NaN (a, b); + return packFloat64 (zSign, 0, 0); + } + if (bExp == 0) + { + if (bSig == 0) + { + if ((aExp | aSig) == 0) + { + float_raise (float_flag_invalid); + return float64_default_nan; + } + float_raise (float_flag_divbyzero); + return packFloat64 (zSign, 0x7FF, 0); + } + normalizeFloat64Subnormal (bSig, &bExp, &bSig); + } + if (aExp == 0) + { + if (aSig == 0) + return packFloat64 (zSign, 0, 0); + normalizeFloat64Subnormal (aSig, &aExp, &aSig); + } + zExp = aExp - bExp + 0x3FD; + aSig = (aSig | LIT64 (0x0010000000000000)) << 10; + bSig = (bSig | LIT64 (0x0010000000000000)) << 11; + if (bSig <= (aSig + aSig)) + { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64 (aSig, 0, bSig); + if ((zSig & 0x1FF) <= 2) + { + mul64To128 (bSig, zSig, &term0, &term1); + sub128 (aSig, 0, term0, term1, &rem0, &rem1); + while ((sbits64) rem0 < 0) + { + --zSig; + add128 (rem0, rem1, 0, bSig, &rem0, &rem1); + } + zSig |= (rem1 != 0); + } + return roundAndPackFloat64 (zSign, zExp, zSig); + +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.h b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.h new file mode 100755 index 000000000..6d075ca15 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/softfloat.h @@ -0,0 +1,77 @@ +/* ++--------------------------------------------------------------------------+ +| CHStone : a suite of benchmark programs for C-based High-Level Synthesis | +| ======================================================================== | +| | +| * Collected and Modified : Y. Hara, H. Tomiyama, S. Honda, | +| H. Takada and K. Ishii | +| Nagoya University, Japan | +| | +| * Remark : | +| 1. This source code is modified to unify the formats of the benchmark | +| programs in CHStone. | +| 2. Test vectors are added for CHStone. | +| 3. If "main_result" is 0 at the end of the program, the program is | +| correctly executed. | +| 4. Please follow the copyright of each benchmark program. | ++--------------------------------------------------------------------------+ +*/ +/*============================================================================ + +This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic +Package, Release 2b. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, +COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) the source code for the derivative work includes prominent notice that +the work is derivative, and (2) the source code includes prominent notice with +these four paragraphs for those parts of this code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point types. +*----------------------------------------------------------------------------*/ +typedef unsigned int float32; +typedef unsigned long long float64; + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point underflow tininess-detection mode. +*----------------------------------------------------------------------------*/ +#define float_tininess_after_rounding 0 +#define float_tininess_before_rounding 1 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point rounding mode. +*----------------------------------------------------------------------------*/ +#define float_round_nearest_even 0 +#define float_round_to_zero 1 +#define float_round_up 2 +#define float_round_down 3 + +/*---------------------------------------------------------------------------- +| Software IEC/IEEE floating-point exception flags. +*----------------------------------------------------------------------------*/ +#define float_flag_inexact 1 +#define float_flag_divbyzero 2 +#define float_flag_underflow 4 +#define float_flag_overflow 8 +#define float_flag_invalid 16 diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/synthesize.sh b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/synthesize.sh new file mode 100755 index 000000000..5180fef4b --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise3/solution/synthesize.sh @@ -0,0 +1,6 @@ +#!/bin/bash +abs_script=$(readlink -e $0) +dir_script=$(dirname $abs_script) +$dir_script/../../test_panda.py --tool=bambu --bambu=bambu --spider=spider \ + --args="--configuration-name=GCC49 --compiler=I386_GCC49" \ + -c=--simulate -b$dir_script -l$dir_script/list "$@" diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/README b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/README new file mode 100644 index 000000000..955068302 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/README @@ -0,0 +1,5 @@ +1. Generate the module implementing the following formula (single precision and double precision): + +gamma = acos((a**2+b**2-c**2)/(2*a*b)) + +2. Identify the combination of softfloat ops and libm which produces the best performances. diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.sh b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.sh new file mode 100755 index 000000000..244aa73b5 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.sh @@ -0,0 +1,7 @@ +#!/bin/bash +abs_script=$(readlink -e $0) +dir_script=$(dirname $abs_script) +bambu $dir_script/module.c --top-fname=awesome_math \ + -O3 -lm --speculative-sdc-scheduling --libm-std-rounding --soft-float \ + --simulate --generate-tb="a=3.0,b=4.0,c=5.0" \ + "$@" |& tee log.txt diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.txt b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.txt new file mode 100644 index 000000000..783879ebf --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/hint.txt @@ -0,0 +1,4 @@ +Use the following parameters: +--libm-std-rounding +--soft-float +... diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/list b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/list new file mode 100644 index 000000000..b2a51a80b --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/list @@ -0,0 +1,4 @@ +module.c --benchmark-name=std_rounding_softfloat --libm-std-rounding --soft-float +module.c --benchmark-name=std_rounding_soft-fp --libm-std-rounding --soft-fp +module.c --benchmark-name=faith_rounding_softfloat --soft-float +module.c --benchmark-name=faith_rounding_soft-fp --soft-fp diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/module.c b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/module.c new file mode 100644 index 000000000..266c15765 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/module.c @@ -0,0 +1,24 @@ +#include + +#ifdef FP_SINGLE +#define FP_TYPE float +#define ACOS(a) acosf(a) +#else +#define FP_TYPE double +#define ACOS(a) acos(a) +#endif + +#ifdef MULT_SQUARE +#define SQUARE(a) (a*a) +#else +#ifdef FP_SINGLE +#define SQUARE(a) powf(a,2) +#else +#define SQUARE(a) pow(a,2) +#endif +#endif + +FP_TYPE awesome_math(FP_TYPE a, FP_TYPE b, FP_TYPE c) +{ + return ACOS((SQUARE(a) + SQUARE(b) - SQUARE(c))/(2*a*b)); +} diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/synthesize.sh b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/synthesize.sh new file mode 100755 index 000000000..07ba2bbd5 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/synthesize.sh @@ -0,0 +1,11 @@ +#!/bin/bash +abs_script=$(readlink -e $0) +dir_script=$(dirname $abs_script) +$dir_script/../../test_panda.py --tool=bambu --bambu=bambu --spider=spider \ + --args="--configuration-name=pow_square " \ + --args="--configuration-name=mult_square -DMULT_SQUARE" \ + --args="--configuration-name=single_pow_square -DFP_SINGLE" \ + --args="--configuration-name=single_mult_square -DFP_SINGLE -DMULT_SQUARE" \ + -c=--simulate -c=-lm -c=--generate-tb=$dir_script/testbench.xml -c=--speculative-sdc-scheduling \ + -c=--top-fname=awesome_math \ + -b$dir_script -l$dir_script/list "$@" diff --git a/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/testbench.xml b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/testbench.xml new file mode 100644 index 000000000..63bd95293 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/Exercise4/solution/testbench.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/documentation/tutorial_ics_2021/03-optimizations/test_panda.py b/documentation/tutorial_ics_2021/03-optimizations/test_panda.py new file mode 100755 index 000000000..d486f8b83 --- /dev/null +++ b/documentation/tutorial_ics_2021/03-optimizations/test_panda.py @@ -0,0 +1,961 @@ +#!/usr/bin/python + +import argparse +import datetime +import distutils.spawn +import logging +import os +import re +import shlex +import shutil +import signal +import subprocess +import sys +import threading +import xml.dom.minidom +from collections import deque + +line_index = 0 +failure = False + +def positive_integer(value): + pos_int = int(value) + if pos_int <= 0: + raise argparse.ArgumentTypeError("%s must be a positive integer" % value) + return pos_int + +class StoreOrUpdateMin(argparse.Action): + first_parsed = True + def __call__(self, parser, namespace, values, option_string=None): + if self.first_parsed == True : + self.first_parsed = False + setattr(namespace, self.dest, values) + else : + setattr(namespace, self.dest, min(namespace.j, values)) + + +#Return children of a process +def GetChildren(parent_pid): + ret = set() + ps_command = subprocess.Popen("ps -o pid --ppid %d --noheaders" % parent_pid, shell=True, stdout=subprocess.PIPE) + ps_output = ps_command.stdout.read() + ps_command.wait() + for pid_str in ps_output.split("\n")[:-1]: + ret.add(int(pid_str)) + return ret + +#Kill a process than kill its children +def kill_proc_tree(pid): + children = GetChildren(pid) + os.kill(pid, signal.SIGKILL) + for child in children: + kill_proc_tree(child) +#Process benchmark in list +def execute_tests(named_list,thread_index): + global passed_benchmark + global total_benchmark + global line_index + global children + global failure + lines = open(named_list).readlines() + with lock: + local_index = line_index + line_index += 1 + while local_index < len(lines) and not (failure and args.stop): + cwd = ComputeDirectory(lines[local_index]) + failed_output_file_name = os.path.join(cwd, args.tool + "_failed_output") + if os.path.exists(failed_output_file_name): + os.remove(failed_output_file_name) + tool_return_value_file_name = os.path.join(cwd, args.tool + "_return_value") + if args.restart and os.path.exists(os.path.join(cwd, args.tool + "_return_value")): + tool_return_value_file = open(tool_return_value_file_name, "r") + return_value = tool_return_value_file.read() + tool_return_value_file.close() + if return_value == "0": + with lock: + total_benchmark += 1 + passed_benchmark += 1 + logging.info(" SKIPPING --- OVERALL: " + str(passed_benchmark) + " passed, " + str(total_benchmark-passed_benchmark) + " failed, " + str(len(lines)-total_benchmark) + " queued --- " + lines[local_index].replace("\\", "")) + local_index = line_index + line_index += 1 + continue + HLS_output_directory = os.path.join(cwd, "HLS_output") + if os.path.exists(HLS_output_directory): + shutil.rmtree(HLS_output_directory) + output_file_name = os.path.join(cwd, args.tool + "_execution_output") + output_file = open(output_file_name, "w") + local_args = lines[local_index] + if local_args[0] == "\"": + local_args = local_args[1:-1] + if args.tool != "bambu" and args.tool != "zebu": + tokens = shlex.split(lines[local_index]) + args_without_benchmark_name = "" + for token in tokens: + if token.find("--benchmark-name") == -1: + args_without_benchmark_name += token + " " + local_args = args_without_benchmark_name + local_command = "ulimit " + args.ulimit + "; exec timeout " + args.timeout + " " + tool_exe + local_command = local_command + " " + local_args + output_file.write("#" * 80 + "\n") + output_file.write("cd " + cwd + "; ") + output_file.write(local_command + "\n") + output_file.write("#" * 80 + "\n") + output_file.flush() + return_value = -1 + with lock_creation_destruction: + if not (failure and args.stop): + children[thread_index] = subprocess.Popen(local_command, stderr=output_file, stdout=output_file, cwd=cwd, shell=True, executable="/bin/bash") + try: + return_value = children[thread_index].wait() + except: + pass + with lock_creation_destruction: + if return_value != 0 and (args.stop or args.returnfail): + failure = True + if failure and args.stop: + for local_thread_index in range(n_jobs): + if children[local_thread_index] != None: + if children[local_thread_index].poll() == None: + try: + kill_proc_tree(children[local_thread_index].pid) + except OSError: + pass + os.fsync(output_file.fileno()) + output_file.close() + tool_return_value_file = open(tool_return_value_file_name, "w") + tool_return_value_file.write(str(return_value)) + tool_return_value_file.close() + args_file = open(os.path.join(cwd, "args"), "w") + args_file.write(lines[local_index]) + args_file.close() + if return_value == 0 and os.path.exists(os.path.join(cwd, args.tool + "_results_0.xml")): + tool_results_file_name = os.path.join(cwd, args.tool + "_results") + tool_results_file = open(tool_results_file_name, "w") + tool_results_string = "" + xml_document = xml.dom.minidom.parse(os.path.join(cwd, args.tool + "_results_0.xml")) + if len(xml_document.getElementsByTagName("CYCLES")) > 0: + cycles_tag = xml_document.getElementsByTagName("CYCLES")[0] + tool_results_string = tool_results_string + cycles_tag.attributes["value"].value + " CYCLES" + if len(xml_document.getElementsByTagName("CLOCK_SLACK")) > 0: + slack_tag = xml_document.getElementsByTagName("CLOCK_SLACK")[0] + tool_results_string = tool_results_string + " *** " + slack_tag.attributes["value"].value + "ns" + tool_results_file.write(tool_results_string) + tool_results_file.close() + if not (failure and args.stop) or (return_value != -9 and return_value != 0): + if return_value != 0: + shutil.copy(output_file_name, str(os.path.join(os.path.dirname(output_file_name), args.tool + "_failed_output"))) + with lock: + total_benchmark += 1 + if return_value == 0: + passed_benchmark += 1 + if not args.no_clean: + for sub in os.listdir(cwd): + if os.path.isdir(os.path.join(cwd, sub)): + shutil.rmtree(os.path.join(cwd, sub)) + else: + if sub != args.tool + "_return_value" and sub != args.tool + "_execution_output" and sub != args.tool + "_results_0.xml" and sub != "args": + os.remove(os.path.join(cwd, sub)) + if os.path.exists(os.path.join(cwd, args.tool + "_results_0.xml")): + logging.info(" SUCCESS (" + tool_results_string + ") --- OVERALL: " + str(passed_benchmark) + " passed, " + str(total_benchmark-passed_benchmark) + " failed, " + str(len(lines)-total_benchmark) + " queued --- " + lines[local_index].replace("\\", "")) + else: + logging.info(" SUCCESS --- OVERALL: " + str(passed_benchmark) + " passed, " + str(total_benchmark-passed_benchmark) + " failed, " + str(len(lines)-total_benchmark) + " queued --- " + lines[local_index].replace("\\", "")) + elif return_value == 124: + logging.info(" FAILURE (Timeout) --- OVERALL: " + str(passed_benchmark) + " passed, " + str(total_benchmark-passed_benchmark) + " failed, " + str(len(lines)-total_benchmark) + " queued --- " + lines[local_index].replace("\\", "")) + elif return_value == 153: + logging.info(" FAILURE (File size limit exceeded) --- OVERALL: " + str(passed_benchmark) + " passed, " + str(total_benchmark-passed_benchmark) + " failed, " + str(len(lines)-total_benchmark) + " queued --- " + lines[local_index].replace("\\", "")) + else: + logging.info(" FAILURE --- OVERALL: " + str(passed_benchmark) + " passed, " + str(total_benchmark-passed_benchmark) + " failed, " + str(len(lines)-total_benchmark) + " queued --- " + lines[local_index].replace("\\", "")) + with lock: + local_index = line_index + line_index += 1 + +#Computing relative path +def ComputeDirectory(line): + configuration_name = "" + benchmark_name = "" + tokens = shlex.split(line) + for token in tokens: + if token.find("--configuration-name") != -1: + configuration_name = token[len("--configuration-name="):] + if token.find("--benchmark-name") != -1: + benchmark_name = token[len("--benchmark-name="):] + new_dir = os.path.join(abs_path, configuration_name, benchmark_name) + return new_dir + +#Search c files +def SearchCFiles(directory): + logging.info(" Looking for file in " + str(directory)) + files = set() + for element in os.listdir(directory): + if os.path.isdir(os.path.join(directory, element)): + files = files.union(SearchCFiles(os.path.join(directory, element))) + elif (element[-2:] == ".c") or (element[-2:] == ".C") or (element[-4:] == ".CPP") or (element[-4:] == ".cpp") or (element[-4:] == ".cxx") or (element[-3:] == ".cc") or (element[-4:] == ".c++"): + files.add(os.path.join(directory, element)) + return files + +#Collecting results +def CollectResults(directory): + #Skip if this is a leaf directory + if os.path.exists(os.path.join(directory, args.tool + "_return_value")) or os.listdir(directory) == []: + return + subdirs = [s for s in sorted(os.listdir(directory)) if os.path.isdir(os.path.join(directory,s)) and s != "panda-temp" and s != "HLS_output"] + for subdir in subdirs: + CollectResults(os.path.join(directory, subdir)) + tool_failed_output = open(os.path.join(directory, args.tool + "_failed_output"), "w") + for subdir in subdirs: + if os.path.exists(os.path.join(directory, subdir, args.tool + "_failed_output")): + tool_failed_output.write(open(os.path.join(directory, subdir, args.tool + "_failed_output")).read()) + if os.path.exists(os.path.join(directory, subdir, args.tool + "_execution_output")): + tool_failed_output.write("\n") + tool_failed_output.write("\n") + tool_failed_output.write("\n") + tool_failed_output.close() + report_file = open(os.path.join(directory, "report"), "w") + for subdir in subdirs: + if os.path.exists(os.path.join(directory, subdir, args.tool + "_return_value")): + return_value_file_name = os.path.join(directory, subdir, args.tool + "_return_value") + return_value_file = open(return_value_file_name) + return_value = return_value_file.read() + return_value_file.close() + args_file = open(os.path.join(directory, subdir, "args")) + command_args = args_file.readlines()[0] + command_args = command_args.replace(abs_benchmarks_root + "/", "") + args_file.close() + if return_value == "0": + tool_results_file_name = os.path.join(directory, subdir, args.tool + "_results") + if os.path.exists(tool_results_file_name): + report_file.write("SUCCESS (" + open(tool_results_file_name).read() + " cycles) " + command_args.replace("\\", "")) + else: + report_file.write("SUCCESS: " + command_args.replace("\\", "")) + else: + if return_value == "124": + report_file.write("FAILURE(Timeout): " + command_args.replace("\\", "")) + else: + report_file.write("FAILURE: " + command_args.replace("\\", "")) + report_file.write("\n") + elif os.path.exists(os.path.join(directory, subdir, "report")): + local_report_file = open(os.path.join(directory, subdir, "report")) + report_file.write(local_report_file.read()) + local_report_file.close() + report_file.close() + if args.tool == "bambu": + local_args = "" + named_list_name = os.path.join(abs_path, "named_list") + lines = open(named_list_name).readlines() + for line in lines: + local_dir = ComputeDirectory(line) + if os.path.exists(os.path.join(local_dir, args.tool + "_results_0.xml")): + local_args = local_args + " " + os.path.join(local_dir, args.tool + "_results_0.xml") + if len(local_args) > 0: + #Generate experimental setup xml + experimental_setup_file_name = os.path.join(abs_path, "experimental_setup.xml") + temp_list = open(experimental_setup_file_name, "w") + bambu_version_file_name = os.path.join(abs_path, "bambu_version") + bambu_version_file = open(bambu_version_file_name, "w") + bambu_version_command = [tool_exe] + bambu_version_command.extend(shlex.split("--version")) + subprocess.call(bambu_version_command, stdout=bambu_version_file) + bambu_version_file.close() + bambu_version_file = open(bambu_version_file_name, "r") + bambu_version = bambu_version_file.readlines()[-2].rstrip() + bambu_version_file.close() + if args.commonargs != None: + bambu_arguments = ' '.join(' '.join(map(str,l)) for l in args.commonargs) + else: + bambu_arguments = "" + temp_list.write("\n") + temp_list.write("\n") + temp_list.write(" \n") + temp_list.write(" \n") + temp_list.write("

mup6^Q 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