{ "cells": [ { "cell_type": "markdown", "id": "efedd6e1-55af-4709-ad1a-18eb68e4b815", "metadata": {}, "source": [ "# Boolean pitfalls\n", "\n", "In classic myHDL you can do this:" ] }, { "cell_type": "code", "execution_count": 2, "id": "606b4adf-0d16-4fa0-9a5f-281123ae09c3", "metadata": {}, "outputs": [], "source": [ "from myhdl import *" ] }, { "cell_type": "code", "execution_count": 3, "id": "f21b8ae0-b0b5-4c3e-8d85-d7f5c8661a84", "metadata": {}, "outputs": [], "source": [ "@block\n", "def unit():\n", " a, b, c, d = [ Signal(bool()) for _ in range(4) ]\n", " clk = Signal(bool(0))\n", " \n", " @always(clk.posedge)\n", " def worker():\n", " if ((a == True) and b == False and (c == True)):\n", " d.next = (a == True) and b == False and (c == True)\n", " \n", " return instances()" ] }, { "cell_type": "code", "execution_count": 4, "id": "b40bcf60-0d86-4b7e-aeef-00671b3263da", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/cyrite/.local/lib/python3.10/site-packages/myhdl/conversion/_toVHDL.py:513: ToVHDLWarning: Signal is not driven: clk\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/cyrite/.local/lib/python3.10/site-packages/myhdl/conversion/_toVHDL.py:513: ToVHDLWarning: Signal is not driven: a\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/cyrite/.local/lib/python3.10/site-packages/myhdl/conversion/_toVHDL.py:513: ToVHDLWarning: Signal is not driven: b\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/cyrite/.local/lib/python3.10/site-packages/myhdl/conversion/_toVHDL.py:513: ToVHDLWarning: Signal is not driven: c\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/cyrite/.local/lib/python3.10/site-packages/myhdl/conversion/_toVHDL.py:471: ToVHDLWarning: Signal is driven but not read: d\n", " warnings.warn(\"%s: %s\" % (_error.UnreadSignal, s._name),\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = unit()\n", "u.convert('vhdl')" ] }, { "cell_type": "code", "execution_count": 5, "id": "b6678efb-5fde-47f3-9b2e-ca74416b3b02", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UNIT_WORKER: process (clk) is\n", "begin\n", " if rising_edge(clk) then\n", " if ((a = '1') and (b = '0') and (c = '1')) then\n", " d <= stdl((a = '1') and (b = '0') and (c = '1'));\n", " end if;\n", "--\n", "end process UNIT_WORKER;\n", "\n", "end architecture MyHDL;\n" ] } ], "source": [ "!grep -A 5 WORKER unit.vhd" ] }, { "cell_type": "markdown", "id": "55ab2f62-741e-4f97-a25a-acdb53190df5", "metadata": {}, "source": [ "However, when you change the `and` to `&`, the precedence will fool you:" ] }, { "cell_type": "code", "execution_count": 6, "id": "99c35484-b2e5-4c33-9947-44b5d97f27d7", "metadata": {}, "outputs": [], "source": [ "@block\n", "def unit2():\n", " a, b, c, d = [ Signal(bool()) for _ in range(4) ]\n", " clk = Signal(bool(0))\n", " \n", " @always(clk.posedge)\n", " def worker():\n", " if ((a == True) & b == False & (c == True)):\n", " d.next = (a == True) & b == False & (c == True)\n", " \n", " return instances()" ] }, { "cell_type": "code", "execution_count": 7, "id": "c74353dc-13a2-4ee0-9829-c2becaaec21a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = unit2()\n", "u.convert('vhdl')" ] }, { "cell_type": "code", "execution_count": 8, "id": "48415e3e-7e9e-44ec-ad6a-26b3fd4671af", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "< UNIT2_WORKER: process (clk) is\n", "---\n", "> UNIT_WORKER: process (clk) is\n", "39,40c39,40\n", "< if ((stdl(a = '1') and b) = ('0' and stdl(c = '1'))) then\n", "< d <= stdl((stdl(a = '1') and b) = ('0' and stdl(c = '1')));\n", "---\n", "> if ((a = '1') and (b = '0') and (c = '1')) then\n", "> d <= stdl((a = '1') and (b = '0') and (c = '1'));\n", "--\n", "< end process UNIT2_WORKER;\n", "---\n", "> end process UNIT_WORKER;\n" ] } ], "source": [ "! diff unit2.vhd unit.vhd | grep -A 6 WORKER" ] }, { "cell_type": "markdown", "id": "be7cb8f8-3a30-4a1a-8b97-010f5bb4a3cd", "metadata": {}, "source": [ "## Bool adding\n", "\n", "Adding of booleans simply is not covered and will produce errors in VHDL." ] }, { "cell_type": "code", "execution_count": 9, "id": "849c4788-5a53-44a1-b962-ae3856be8cd2", "metadata": {}, "outputs": [], "source": [ "@block\n", "def unit3(clk):\n", " b, c, d = [ Signal(bool()) for _ in range(3) ]\n", " a = Signal(intbv()[3:])\n", " \n", " @always(clk.posedge)\n", " def worker():\n", " a.next = b + c\n", " d.next = b + c\n", " \n", " @instance\n", " def run():\n", " b.next = True\n", " print(\"WOW\")\n", " yield delay(3)\n", " print(\"D:\", a)\n", " # raise StopSimulation\n", " \n", " return instances()" ] }, { "cell_type": "code", "execution_count": 10, "id": "65bdbab4-b223-41bf-b525-7b217dd88278", "metadata": {}, "outputs": [], "source": [ "@block\n", "def tb():\n", " clk = Signal(bool(0))\n", "\n", " @always(delay(1))\n", " def clkgen():\n", " clk.next = not clk\n", " \n", " uut = unit3(clk)\n", " \n", " return instances()" ] }, { "cell_type": "code", "execution_count": 11, "id": "04bc7ef4-7895-4194-b1dc-e81995b84644", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WOW\n", "D: 1\n", "QUIT\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ ": Simulated 4 timesteps\n" ] } ], "source": [ "u = tb()\n", "u.config_sim(trace=True)\n", "u.run_sim(4)\n", "print(\"QUIT\")\n", "u.quit_sim()" ] }, { "cell_type": "code", "execution_count": 12, "id": "806d827f-9c76-41e3-a17e-c17625b60c37", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clk = Signal(bool(0))\n", "u = unit3(clk)\n", "u.convert('vhdl')" ] }, { "cell_type": "code", "execution_count": 13, "id": "ed2c32ed-ef3d-45f2-9b91-22984f70d7e4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1\t-- File: unit3.vhd\n", " 2\t-- Generated by MyHDL 0.11.49\n", " 3\t-- Date: Wed Jul 17 20:05:27 2024\n", " 4\t\n", " 5\t\n", " 6\tlibrary IEEE;\n", " 7\tuse IEEE.std_logic_1164.all;\n", " 8\tuse IEEE.numeric_std.all;\n", " 9\tuse std.textio.all;\n", " 10\t\n", " 11\tuse work.pck_myhdl_011.all;\n", " 12\t\n", " 13\tentity unit3 is\n", " 14\t port (\n", " 15\t clk: in std_logic\n", " 16\t );\n", " 17\tend entity unit3;\n", " 18\t\n", " 19\t\n", " 20\tarchitecture MyHDL of unit3 is\n", " 21\t\n", " 22\t\n", " 23\t\n", " 24\tsignal a: unsigned(2 downto 0);\n", " 25\tsignal b: std_logic;\n", " 26\tsignal c: std_logic;\n", " 27\tsignal d: std_logic;\n", " 28\t\n", " 29\tbegin\n", " 30\t\n", " 31\t\n", " 32\tc <= '0';\n", " 33\t\n", " 34\t\n", " 35\tUNIT3_WORKER: process (clk) is\n", " 36\tbegin\n", " 37\t if rising_edge(clk) then\n", " 38\t a <= (to_unsigned(b, 3) + to_unsigned(c, 1));\n", " 39\t d <= (to_unsigned(b, 1) + to_unsigned(c, 1));\n", " 40\t end if;\n", " 41\tend process UNIT3_WORKER;\n", " 42\t\n", " 43\tUNIT3_RUN: process is\n", " 44\t variable L: line;\n", " 45\tbegin\n", " 46\t b <= '1';\n", " 47\t write(L, string'(\"WOW\"));\n", " 48\t writeline(output, L);\n", " 49\t wait for 3 * 1 ns;\n", " 50\t write(L, string'(\"D:\"));\n", " 51\t write(L, string'(\" \"));\n", " 52\t write(L, to_hstring(a));\n", " 53\t writeline(output, L);\n", " 54\t wait;\n", " 55\tend process UNIT3_RUN;\n", " 56\t\n", " 57\tend architecture MyHDL;\n" ] } ], "source": [ "!cat -n unit3.vhd" ] }, { "cell_type": "code", "execution_count": 14, "id": "678f6375-3018-4d0d-8075-2f67d6968e3f", "metadata": {}, "outputs": [], "source": [ "! ghdl -i --std=08 unit3.vhd pck_myhdl_011.vhd" ] }, { "cell_type": "code", "execution_count": 15, "id": "e0874760-a05c-48d6-b978-36649acc42e2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1munit3.vhd:39:33:\u001b[1;31merror:\u001b[0;1m no function declarations for operator \"+\"\u001b[0m\n" ] } ], "source": [ "! ghdl -m --std=08 unit3" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.0" } }, "nbformat": 4, "nbformat_minor": 5 }