{ "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": 1, "id": "606b4adf-0d16-4fa0-9a5f-281123ae09c3", "metadata": {}, "outputs": [], "source": [ "from myhdl import *" ] }, { "cell_type": "code", "execution_count": 2, "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": 3, "id": "b40bcf60-0d86-4b7e-aeef-00671b3263da", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/testing/.local/lib/python3.9/site-packages/myhdl/conversion/_toVHDL.py:500: ToVHDLWarning: Signal is not driven: clk\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/testing/.local/lib/python3.9/site-packages/myhdl/conversion/_toVHDL.py:500: ToVHDLWarning: Signal is not driven: a\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/testing/.local/lib/python3.9/site-packages/myhdl/conversion/_toVHDL.py:500: ToVHDLWarning: Signal is not driven: b\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/testing/.local/lib/python3.9/site-packages/myhdl/conversion/_toVHDL.py:500: ToVHDLWarning: Signal is not driven: c\n", " warnings.warn(\"%s: %s\" % (_error.UndrivenSignal, s._name),\n", "/home/testing/.local/lib/python3.9/site-packages/myhdl/conversion/_toVHDL.py:467: ToVHDLWarning: Signal is driven but not read: d\n", " warnings.warn(\"%s: %s\" % (_error.UnreadSignal, s._name),\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = unit()\n", "u.convert('vhdl')" ] }, { "cell_type": "code", "execution_count": 4, "id": "b6678efb-5fde-47f3-9b2e-ca74416b3b02", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UNIT_WORKER: process (clk) is\r\n", "begin\r\n", " if rising_edge(clk) then\r\n", " if ((a = '1') and (b = '0') and (c = '1')) then\r\n", " d <= stdl((a = '1') and (b = '0') and (c = '1'));\r\n", " end if;\r\n", "--\r\n", "end process UNIT_WORKER;\r\n", "\r\n", "end architecture MyHDL;\r\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": 5, "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": 6, "id": "c74353dc-13a2-4ee0-9829-c2becaaec21a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u = unit2()\n", "u.convert('vhdl')" ] }, { "cell_type": "code", "execution_count": 7, "id": "48415e3e-7e9e-44ec-ad6a-26b3fd4671af", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "< UNIT2_WORKER: process (clk) is\r\n", "---\r\n", "> UNIT_WORKER: process (clk) is\r\n", "39,40c39,40\r\n", "< if ((stdl(a = '1') and b) = ('0' and stdl(c = '1'))) then\r\n", "< d <= stdl((stdl(a = '1') and b) = ('0' and stdl(c = '1')));\r\n", "---\r\n", "> if ((a = '1') and (b = '0') and (c = '1')) then\r\n", "> d <= stdl((a = '1') and (b = '0') and (c = '1'));\r\n", "--\r\n", "< end process UNIT2_WORKER;\r\n", "---\r\n", "> end process UNIT_WORKER;\r\n" ] } ], "source": [ "! diff unit2.vhd unit.vhd | grep -A 6 WORKER" ] }, { "cell_type": "markdown", "id": "be7cb8f8-3a30-4a1a-8b97-010f5bb4a3cd", "metadata": {}, "source": [ "## Bool adding" ] }, { "cell_type": "code", "execution_count": 8, "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": 9, "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": 10, "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": 11, "id": "806d827f-9c76-41e3-a17e-c17625b60c37", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clk = Signal(bool(0))\n", "u = unit3(clk)\n", "u.convert('vhdl')" ] }, { "cell_type": "code", "execution_count": 12, "id": "ed2c32ed-ef3d-45f2-9b91-22984f70d7e4", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1\t-- File: unit3.vhd\r\n", " 2\t-- Generated by MyHDL 0.11\r\n", " 3\t-- Date: Thu Apr 14 13:24:32 2022\r\n", " 4\t\r\n", " 5\t\r\n", " 6\tlibrary IEEE;\r\n", " 7\tuse IEEE.std_logic_1164.all;\r\n", " 8\tuse IEEE.numeric_std.all;\r\n", " 9\tuse std.textio.all;\r\n", " 10\t\r\n", " 11\tuse work.pck_myhdl_011.all;\r\n", " 12\t\r\n", " 13\tentity unit3 is\r\n", " 14\t port (\r\n", " 15\t clk: in std_logic\r\n", " 16\t );\r\n", " 17\tend entity unit3;\r\n", " 18\t\r\n", " 19\t\r\n", " 20\tarchitecture MyHDL of unit3 is\r\n", " 21\t\r\n", " 22\t\r\n", " 23\t\r\n", " 24\tsignal a: unsigned(2 downto 0);\r\n", " 25\tsignal b: std_logic;\r\n", " 26\tsignal c: std_logic;\r\n", " 27\tsignal d: std_logic;\r\n", " 28\t\r\n", " 29\tbegin\r\n", " 30\t\r\n", " 31\t\r\n", " 32\tc <= '0';\r\n", " 33\t\r\n", " 34\t\r\n", " 35\tUNIT3_WORKER: process (clk) is\r\n", " 36\tbegin\r\n", " 37\t if rising_edge(clk) then\r\n", " 38\t a <= (to_unsigned(b, 3) + to_unsigned(c, 1));\r\n", " 39\t d <= (to_unsigned(b, 1) + to_unsigned(c, 1));\r\n", " 40\t end if;\r\n", " 41\tend process UNIT3_WORKER;\r\n", " 42\t\r\n", " 43\tUNIT3_RUN: process is\r\n", " 44\t variable L: line;\r\n", " 45\tbegin\r\n", " 46\t b <= '1';\r\n", " 47\t write(L, string'(\"WOW\"));\r\n", " 48\t writeline(output, L);\r\n", " 49\t wait for 3 * 1 ns;\r\n", " 50\t write(L, string'(\"D:\"));\r\n", " 51\t write(L, string'(\" \"));\r\n", " 52\t write(L, to_hstring(a));\r\n", " 53\t writeline(output, L);\r\n", " 54\t wait;\r\n", " 55\tend process UNIT3_RUN;\r\n", " 56\t\r\n", " 57\tend architecture MyHDL;\r\n" ] } ], "source": [ "!cat -n unit3.vhd" ] }, { "cell_type": "code", "execution_count": 13, "id": "678f6375-3018-4d0d-8075-2f67d6968e3f", "metadata": {}, "outputs": [], "source": [ "! ghdl -i --std=08 unit3.vhd pck_myhdl_011.vhd" ] }, { "cell_type": "code", "execution_count": 14, "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\r\n" ] } ], "source": [ "! ghdl -m --std=08 unit3" ] }, { "cell_type": "code", "execution_count": null, "id": "673adbd9-15e7-4e75-8202-d6b66b1e66f5", "metadata": {}, "outputs": [], "source": [] } ], "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.9.2" } }, "nbformat": 4, "nbformat_minor": 5 }