Skip to content

Instantly share code, notes, and snippets.

@hackfin
Created March 15, 2024 12:51
Show Gist options
  • Save hackfin/b701a66e26961a5a98abe15a49262f79 to your computer and use it in GitHub Desktop.
Save hackfin/b701a66e26961a5a98abe15a49262f79 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "dfd7651d-06e5-482e-9a54-e086f7094cea",
"metadata": {},
"source": [
"# Direct RTL via yosys\n",
"\n",
"The former 'jupyosys' fork from myHDL is in process of migrating into this development tree.\n",
"The current 'jupyosys' development has dropped myHDL support entirely and is fully based on Cyrite HDL (cyhdl)\n",
"\n",
"Status notes:\n",
" * Do not rely on pyosys API\n",
" * Crashes and irregularities may occur\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "39577a8d-4df7-4f2a-ad84-c4cb65fa81a2",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"sys.path.insert(0, \"../..\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f3a927f3-aba0-4662-a83b-3077b8c78c82",
"metadata": {},
"outputs": [],
"source": [
"from cyhdl import *\n",
"\n",
"Byte = Signal.Type(intbv, 8)\n",
"Bool = Signal.Type(bool)\n",
"\n",
"@block\n",
"def lfsr8(clk : ClkSignal, ce : Bool, reset : ResetSignal, dout : Byte.Output,\n",
" RVAL : int = 1):\n",
" \"\"\"LFSR with all states\"\"\"\n",
" \n",
" v = Signal(intbv(RVAL)[8:])\n",
" \n",
" fb = Signal(bool())\n",
" \n",
" e = v[7:0] == 0\n",
"\n",
" @always_seq(clk.posedge, reset)\n",
" def worker():\n",
" if ce == 1:\n",
" v.next = concat(v[6], v[5], v[4], v[3] ^ fb, v[2] ^ fb, v[1] ^ fb, v[0], fb)\n",
"\n",
" @always_comb\n",
" def assign():\n",
" fb.next = v[7] ^ e\n",
" dout.next = v\n",
"\n",
" return instances()\n",
"\n",
"# Wrapper hack to use local dictionary for instance naming\n",
"def use_local_names(arg):\n",
" arg.use_local_names = True\n",
" return arg\n",
"\n",
"@use_local_names\n",
"@block\n",
"def unit_count(clk : ClkSignal, ce: Signal, reset : ResetSignal, q : Signal.Output):\n",
" \n",
" c, d = [ Signal(intbv(0)[8:]) for _ in range(2) ]\n",
" \n",
" inst_lfsr = lfsr8(clk, ce, reset, d, RVAL = 0xfa)\n",
"\n",
" @always_seq(clk.posedge, reset)\n",
" def counter():\n",
" c.next = c + 1\n",
"# q.next = d ^ c\n",
"\n",
" wires = [ q.wireup(d ^ c) ]\n",
" \n",
" return instances()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "c476cce3-5621-4f1d-86ed-50545e94cff7",
"metadata": {},
"outputs": [],
"source": [
"from myirl.targets import pyosys\n",
"\n",
"def test_expr(tgt):\n",
" ce = Signal(bool())\n",
" clk = ClkSignal()\n",
" reset = ResetSignal(0, 1, isasync = True)\n",
" q = Signal(intbv()[8:])\n",
"\n",
" t = unit_count(clk, ce, reset, q)\n",
" designs = t.elab(tgt, elab_all = True)\n",
"\n",
" return designs[0]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "17f66eb8-0222-4083-aff3-1577e6ba05a7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[32m Adding module with name `lfsr8` \u001b[0m\n",
"\u001b[32m Adding module with name `unit_count` \u001b[0m\n",
"\u001b[7;34m FINALIZE implementation `unit_count` of `unit_count` \u001b[0m\n",
"\n",
"-- Running command `hierarchy -top \\unit_count' --\n",
"\n",
"1. Executing HIERARCHY pass (managing design hierarchy).\n",
"\n",
"1.1. Analyzing design hierarchy..\n",
"Top module: \\unit_count\n",
"Used module: \\lfsr8\n",
"\n",
"1.2. Analyzing design hierarchy..\n",
"Top module: \\unit_count\n",
"Used module: \\lfsr8\n",
"Removed 0 unused modules.\n",
"\n",
"-- Running command `show -format dot -prefix top unit_count' --\n",
"\n",
"2. Generating Graphviz representation of design.\n",
"Writing dot description to `top.dot'.\n",
"Dumping module unit_count to page 1.\n"
]
}
],
"source": [
"tgt = pyosys.RTLIL(\"top\")\n",
"\n",
"design = test_expr(tgt)\n",
"design.display_rtl(selection = \"unit_count\", fmt='dot')\n",
"# design.display_rtl(selection = \"lfsr8\", fmt='dot')"
]
},
{
"cell_type": "markdown",
"id": "f66bb0eb-feca-4b75-8050-02cc7d15dc16",
"metadata": {},
"source": [
"### RTL Display\n",
"\n",
"The `@use_local_names` construct sets the myHDL instance variable names for the identifier.\n",
"\n",
"Note: Pan and zoom may not work on some browsers."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "fc8b26c2-c4d0-4874-b9df-cb05bc5bcff2",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" <div class=\"svg_container_1710506894\">\n",
" <style>\n",
" .svg_container_1710506894 {\n",
" overflow:hidden\n",
" }\n",
" .svg_container_1710506894 SVG {\n",
" height:auto\n",
" }\n",
" </style>\n",
" <script src=\"https://section5.ch/svg-pan-zoom.min.js\"></script>\n",
" <script type=\"text/javascript\">\n",
" attempts = 5;\n",
" var existCondition = setInterval(function() {\n",
" console.log(attempts);\n",
" svg_el = document.querySelector(\".svg_container_1710506894 svg\");\n",
" if (svg_el != null) {\n",
" console.log(\"Exists!\");\n",
" clearInterval(existCondition);\n",
" svgPanZoom(svg_el, {controlIconsEnabled: true, zoomScaleSensitivity: 0.4, minZoom: 0.2});\n",
" }\n",
" if (--attempts == 0) {\n",
" console.warn(\"SVG element not found, zoom wont work\");\n",
" clearInterval(existCondition);\n",
" }\n",
" }, 100); // check every 100ms\n",
" </script>\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"1351pt\" height=\"331pt\" viewBox=\"0.00 0.00 1351.29 330.50\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 326.5)\">\n",
"<title>unit_count</title>\n",
"<polygon fill=\"white\" stroke=\"transparent\" points=\"-4,4 -4,-326.5 1347.29,-326.5 1347.29,4 -4,4\"/>\n",
"<text text-anchor=\"middle\" x=\"671.64\" y=\"-7.8\" font-family=\"Times,serif\" font-size=\"14.00\">unit_count</text>\n",
"<!-- n6 -->\n",
"<g id=\"node1\" class=\"node\">\n",
"<title>n6</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1343.29,-291.54 1343.29,-306.46 1327.47,-317 1305.1,-317 1289.29,-306.46 1289.29,-291.54 1305.1,-281 1327.47,-281 1343.29,-291.54\"/>\n",
"<text text-anchor=\"middle\" x=\"1316.29\" y=\"-295.3\" font-family=\"Times,serif\" font-size=\"14.00\">q</text>\n",
"</g>\n",
"<!-- n7 -->\n",
"<g id=\"node2\" class=\"node\">\n",
"<title>n7</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"529.86,-214.54 529.86,-229.46 508.14,-240 477.43,-240 455.72,-229.46 455.72,-214.54 477.43,-204 508.14,-204 529.86,-214.54\"/>\n",
"<text text-anchor=\"middle\" x=\"492.79\" y=\"-218.3\" font-family=\"Times,serif\" font-size=\"14.00\">reset</text>\n",
"</g>\n",
"<!-- c20 -->\n",
"<g id=\"node8\" class=\"node\">\n",
"<title>c20</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"566.29,-133.5 566.29,-202.5 790.29,-202.5 790.29,-133.5 566.29,-133.5\"/>\n",
"<text text-anchor=\"middle\" x=\"594.29\" y=\"-187.3\" font-family=\"Times,serif\" font-size=\"14.00\">ARST</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"566.29,-179.5 622.29,-179.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"594.29\" y=\"-164.3\" font-family=\"Times,serif\" font-size=\"14.00\">CLK</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"566.29,-156.5 622.29,-156.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"594.29\" y=\"-141.3\" font-family=\"Times,serif\" font-size=\"14.00\">D</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"622.29,-133.5 622.29,-202.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"692.29\" y=\"-171.8\" font-family=\"Times,serif\" font-size=\"14.00\">$counter::c_6619</text>\n",
"<text text-anchor=\"middle\" x=\"692.29\" y=\"-156.8\" font-family=\"Times,serif\" font-size=\"14.00\">$adff</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"762.29,-133.5 762.29,-202.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"776.29\" y=\"-164.3\" font-family=\"Times,serif\" font-size=\"14.00\">Q</text>\n",
"</g>\n",
"<!-- n7&#45;&gt;c20 -->\n",
"<g id=\"edge11\" class=\"edge\">\n",
"<title>n7:e-&gt;c20:w</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M530.29,-222C547.28,-222 546.56,-201.93 556.64,-194.09\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"557.83,-197.38 566.29,-191 555.7,-190.71 557.83,-197.38\"/>\n",
"</g>\n",
"<!-- c23 -->\n",
"<g id=\"node11\" class=\"node\">\n",
"<title>c23</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"590.29,-221.5 590.29,-290.5 766.29,-290.5 766.29,-221.5 590.29,-221.5\"/>\n",
"<text text-anchor=\"middle\" x=\"616.79\" y=\"-275.3\" font-family=\"Times,serif\" font-size=\"14.00\">ce</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"590.29,-267.5 643.29,-267.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"616.79\" y=\"-252.3\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"590.29,-244.5 643.29,-244.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"616.79\" y=\"-229.3\" font-family=\"Times,serif\" font-size=\"14.00\">reset</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"643.29,-221.5 643.29,-290.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"680.29\" y=\"-259.8\" font-family=\"Times,serif\" font-size=\"14.00\">inst_lfsr</text>\n",
"<text text-anchor=\"middle\" x=\"680.29\" y=\"-244.8\" font-family=\"Times,serif\" font-size=\"14.00\">lfsr8</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"717.29,-221.5 717.29,-290.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"741.79\" y=\"-252.3\" font-family=\"Times,serif\" font-size=\"14.00\">dout</text>\n",
"</g>\n",
"<!-- n7&#45;&gt;c23 -->\n",
"<g id=\"edge12\" class=\"edge\">\n",
"<title>n7:e-&gt;c23:w</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M530.29,-222C553.21,-222 560.61,-230.12 579.17,-232.41\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"579.1,-235.91 589.29,-233 579.51,-228.92 579.1,-235.91\"/>\n",
"</g>\n",
"<!-- n8 -->\n",
"<g id=\"node3\" class=\"node\">\n",
"<title>n8</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"519.79,-268.54 519.79,-283.46 503.97,-294 481.6,-294 465.79,-283.46 465.79,-268.54 481.6,-258 503.97,-258 519.79,-268.54\"/>\n",
"<text text-anchor=\"middle\" x=\"492.79\" y=\"-272.3\" font-family=\"Times,serif\" font-size=\"14.00\">ce</text>\n",
"</g>\n",
"<!-- n8&#45;&gt;c23 -->\n",
"<g id=\"edge13\" class=\"edge\">\n",
"<title>n8:e-&gt;c23:w</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M520.79,-276C547.57,-276 556.65,-278.32 579.14,-278.88\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"579.25,-282.38 589.29,-279 579.33,-275.38 579.25,-282.38\"/>\n",
"</g>\n",
"<!-- n9 -->\n",
"<g id=\"node4\" class=\"node\">\n",
"<title>n9</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"519.79,-160.54 519.79,-175.46 503.97,-186 481.6,-186 465.79,-175.46 465.79,-160.54 481.6,-150 503.97,-150 519.79,-160.54\"/>\n",
"<text text-anchor=\"middle\" x=\"492.79\" y=\"-164.3\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"</g>\n",
"<!-- n9&#45;&gt;c20 -->\n",
"<g id=\"edge14\" class=\"edge\">\n",
"<title>n9:e-&gt;c20:w</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M520.79,-168C537.06,-168 543.51,-168 555.95,-168\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"556.29,-171.5 566.29,-168 556.29,-164.5 556.29,-171.5\"/>\n",
"</g>\n",
"<!-- n9&#45;&gt;c23 -->\n",
"<g id=\"edge15\" class=\"edge\">\n",
"<title>n9:e-&gt;c23:w</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M520.79,-168C566.48,-168 544.02,-242.79 579.06,-254.47\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"578.88,-257.98 589.29,-256 579.92,-251.06 578.88,-257.98\"/>\n",
"</g>\n",
"<!-- n10 -->\n",
"<g id=\"node5\" class=\"node\">\n",
"<title>n10</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"65.64,-123 38.64,-105 65.64,-87 92.64,-105 65.64,-123\"/>\n",
"<text text-anchor=\"middle\" x=\"65.64\" y=\"-101.3\" font-family=\"Times,serif\" font-size=\"14.00\">c</text>\n",
"</g>\n",
"<!-- c15 -->\n",
"<g id=\"node7\" class=\"node\">\n",
"<title>c15</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"916.29,-276 916.29,-322 1163.29,-322 1163.29,-276 916.29,-276\"/>\n",
"<text text-anchor=\"middle\" x=\"929.79\" y=\"-306.8\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"916.29,-299 943.29,-299 \"/>\n",
"<text text-anchor=\"middle\" x=\"929.79\" y=\"-283.8\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"943.29,-276 943.29,-322 \"/>\n",
"<text text-anchor=\"middle\" x=\"1040.29\" y=\"-302.8\" font-family=\"Times,serif\" font-size=\"14.00\">$counter:44::ab0c/xor:_u</text>\n",
"<text text-anchor=\"middle\" x=\"1040.29\" y=\"-287.8\" font-family=\"Times,serif\" font-size=\"14.00\">$xor</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"1137.29,-276 1137.29,-322 \"/>\n",
"<text text-anchor=\"middle\" x=\"1150.29\" y=\"-295.3\" font-family=\"Times,serif\" font-size=\"14.00\">Y</text>\n",
"</g>\n",
"<!-- n10&#45;&gt;c15 -->\n",
"<g id=\"edge3\" class=\"edge\">\n",
"<title>n10:e-&gt;c15:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M93.64,-105C118.84,-105 466.6,-322 491.79,-322 491.79,-322 491.79,-322 679.29,-322 769.55,-322 791.1,-306.86 880.29,-293 892.31,-291.13 897.42,-288.69 906.07,-287.59\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"906.51,-291.07 916.29,-287 906.1,-284.08 906.51,-291.07\"/>\n",
"</g>\n",
"<!-- c21 -->\n",
"<g id=\"node10\" class=\"node\">\n",
"<title>c21</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"167.29,-30 167.29,-76 419.29,-76 419.29,-30 167.29,-30\"/>\n",
"<text text-anchor=\"middle\" x=\"180.79\" y=\"-60.8\" font-family=\"Times,serif\" font-size=\"14.00\">A</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"167.29,-53 194.29,-53 \"/>\n",
"<text text-anchor=\"middle\" x=\"180.79\" y=\"-37.8\" font-family=\"Times,serif\" font-size=\"14.00\">B</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"194.29,-30 194.29,-76 \"/>\n",
"<text text-anchor=\"middle\" x=\"293.79\" y=\"-56.8\" font-family=\"Times,serif\" font-size=\"14.00\">$counter:44::0398/add:_u</text>\n",
"<text text-anchor=\"middle\" x=\"293.79\" y=\"-41.8\" font-family=\"Times,serif\" font-size=\"14.00\">$add</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"393.29,-30 393.29,-76 \"/>\n",
"<text text-anchor=\"middle\" x=\"406.29\" y=\"-49.3\" font-family=\"Times,serif\" font-size=\"14.00\">Y</text>\n",
"</g>\n",
"<!-- n10&#45;&gt;c21 -->\n",
"<g id=\"edge4\" class=\"edge\">\n",
"<title>n10:e-&gt;c21:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M93.64,-105C127.11,-105 129.82,-72.71 157.04,-66.15\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"157.74,-69.6 167.29,-65 156.96,-62.64 157.74,-69.6\"/>\n",
"</g>\n",
"<!-- n11 -->\n",
"<g id=\"node6\" class=\"node\">\n",
"<title>n11</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"853.29,-284 826.29,-266 853.29,-248 880.29,-266 853.29,-284\"/>\n",
"<text text-anchor=\"middle\" x=\"853.29\" y=\"-262.3\" font-family=\"Times,serif\" font-size=\"14.00\">d</text>\n",
"</g>\n",
"<!-- n11&#45;&gt;c15 -->\n",
"<g id=\"edge6\" class=\"edge\">\n",
"<title>n11:e-&gt;c15:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M880.29,-266C901.7,-266 894.57,-297.45 906.62,-307.76\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"905.69,-311.15 916.29,-311 907.92,-304.51 905.69,-311.15\"/>\n",
"</g>\n",
"<!-- x3 -->\n",
"<g id=\"node14\" class=\"node\">\n",
"<title>x3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1241.29,-317C1241.29,-317 1211.29,-317 1211.29,-317 1205.29,-317 1199.29,-311 1199.29,-305 1199.29,-305 1199.29,-293 1199.29,-293 1199.29,-287 1205.29,-281 1211.29,-281 1211.29,-281 1241.29,-281 1241.29,-281 1247.29,-281 1253.29,-287 1253.29,-293 1253.29,-293 1253.29,-305 1253.29,-305 1253.29,-311 1247.29,-317 1241.29,-317\"/>\n",
"<text text-anchor=\"middle\" x=\"1226.29\" y=\"-295.3\" font-family=\"Times,serif\" font-size=\"14.00\">BUF</text>\n",
"</g>\n",
"<!-- c15&#45;&gt;x3 -->\n",
"<g id=\"edge1\" class=\"edge\">\n",
"<title>c15:e-&gt;x3:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M1163.29,-299C1175.29,-299 1180.54,-299 1189.16,-299\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"1189.29,-302.5 1199.29,-299 1189.29,-295.5 1189.29,-302.5\"/>\n",
"</g>\n",
"<!-- x2 -->\n",
"<g id=\"node13\" class=\"node\">\n",
"<title>x2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M868.29,-155C868.29,-155 838.29,-155 838.29,-155 832.29,-155 826.29,-149 826.29,-143 826.29,-143 826.29,-131 826.29,-131 826.29,-125 832.29,-119 838.29,-119 838.29,-119 868.29,-119 868.29,-119 874.29,-119 880.29,-125 880.29,-131 880.29,-131 880.29,-143 880.29,-143 880.29,-149 874.29,-155 868.29,-155\"/>\n",
"<text text-anchor=\"middle\" x=\"853.29\" y=\"-133.3\" font-family=\"Times,serif\" font-size=\"14.00\">BUF</text>\n",
"</g>\n",
"<!-- c20&#45;&gt;x2 -->\n",
"<g id=\"edge7\" class=\"edge\">\n",
"<title>c20:e-&gt;x2:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M790.29,-168C807.28,-168 806.56,-147.93 816.64,-140.09\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"817.83,-143.38 826.29,-137 815.7,-136.71 817.83,-143.38\"/>\n",
"</g>\n",
"<!-- v0 -->\n",
"<g id=\"node9\" class=\"node\">\n",
"<title>v0</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"65.64\" cy=\"-41\" rx=\"65.79\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"65.64\" y=\"-37.3\" font-family=\"Times,serif\" font-size=\"14.00\">8'00000001</text>\n",
"</g>\n",
"<!-- v0&#45;&gt;c21 -->\n",
"<g id=\"edge16\" class=\"edge\">\n",
"<title>v0:e-&gt;c21:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M131.29,-41C143.29,-41 148.54,-41 157.16,-41\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"157.29,-44.5 167.29,-41 157.29,-37.5 157.29,-44.5\"/>\n",
"</g>\n",
"<!-- x1 -->\n",
"<g id=\"node12\" class=\"node\">\n",
"<title>x1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M467.29,-38C467.29,-38 518.29,-38 518.29,-38 524.29,-38 530.29,-44 530.29,-50 530.29,-50 530.29,-62 530.29,-62 530.29,-68 524.29,-74 518.29,-74 518.29,-74 467.29,-74 467.29,-74 461.29,-74 455.29,-68 455.29,-62 455.29,-62 455.29,-50 455.29,-50 455.29,-44 461.29,-38 467.29,-38\"/>\n",
"<text text-anchor=\"middle\" x=\"492.79\" y=\"-52.3\" font-family=\"Times,serif\" font-size=\"14.00\">7:0 - 7:0</text>\n",
"</g>\n",
"<!-- c21&#45;&gt;x1 -->\n",
"<g id=\"edge8\" class=\"edge\">\n",
"<title>c21:e-&gt;x1:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M419.29,-53C431.33,-53 436.53,-54.69 445.15,-55.53\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"445.14,-59.03 455.29,-56 445.46,-52.04 445.14,-59.03\"/>\n",
"</g>\n",
"<!-- c23&#45;&gt;n11 -->\n",
"<g id=\"edge5\" class=\"edge\">\n",
"<title>c23:e-&gt;n11:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M767.29,-256C790.14,-256 797.65,-263.39 816.19,-265.46\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"816.12,-268.96 826.29,-266 816.49,-261.97 816.12,-268.96\"/>\n",
"</g>\n",
"<!-- x1&#45;&gt;c20 -->\n",
"<g id=\"edge9\" class=\"edge\">\n",
"<title>x1:e-&gt;c20:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M530.29,-56C568.79,-56 532.38,-128.47 556.25,-142.62\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"555.75,-146.1 566.29,-145 557.37,-139.29 555.75,-146.1\"/>\n",
"</g>\n",
"<!-- x2&#45;&gt;n10 -->\n",
"<g id=\"edge2\" class=\"edge\">\n",
"<title>x2:e-&gt;n10:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M881.29,-137C889.3,-137 886.11,-149.49 880.29,-155 862.85,-171.49 848.79,-163.35 826.29,-155 806.49,-147.65 810.08,-131.36 790.29,-124 780.5,-120.36 46.22,-130.18 38.64,-123 36.28,-120.76 34.35,-117.37 33.43,-114.13\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"36.63,-115.55 37.64,-105 30.28,-112.61 36.63,-115.55\"/>\n",
"</g>\n",
"<!-- x3&#45;&gt;n6 -->\n",
"<g id=\"edge10\" class=\"edge\">\n",
"<title>x3:e-&gt;n6:w</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-width=\"3\" d=\"M1253.29,-299C1265.29,-299 1270.54,-299 1279.16,-299\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" stroke-width=\"3\" points=\"1279.29,-302.5 1289.29,-299 1279.29,-295.5 1279.29,-302.5\"/>\n",
"</g>\n",
"<!-- \\n -->\n",
"<g id=\"node15\" class=\"node\">\n",
"<title>\\n</title>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"65.64\" cy=\"-159\" rx=\"27\" ry=\"18\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n",
" </div>\n",
" "
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from yosys import display\n",
"display.display_dot(design.name)"
]
},
{
"cell_type": "markdown",
"id": "ee9de89e-781f-4646-a962-5928cd8d3b4b",
"metadata": {},
"source": [
"## Test bench (myHDL style)\n",
"\n",
"Note that `and`, `or` and `not` boolean constructs are no longer allowed with signals. Also keep in mind that the test bench below is a co-simulation testbench:\n",
" * `inst` runs as compiled hardware simulation\n",
" * `@sim.always` and `@sequence` is native Python."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "21365dab-9b35-4e8c-927e-68a00d004bc9",
"metadata": {},
"outputs": [],
"source": [
"from yosys.simulator import CXXRTL as Sim\n",
"from cyrite.simulation import sim\n",
"\n",
"@sim.testbench(Sim, time_unit = 'ns')\n",
"def testbench():\n",
" clk = ClkSignal()\n",
" reset = ResetSignal(1, 1, isasync = False)\n",
" ce = Signal(bool())\n",
"\n",
" a = Signal(intbv()[8:])\n",
"\n",
" inst = unit_count(clk, ce, reset, a)\n",
"\n",
" @sim.always(delay(2))\n",
" def clkgen():\n",
" clk.next = ~ clk\n",
"\n",
" @sim.sequence\n",
" def reset_seq():\n",
" yield delay(21)\n",
" reset.next = False\n",
" yield delay(1)\n",
" ce.next = True\n",
" yield delay(20)\n",
"\n",
" return instances()"
]
},
{
"cell_type": "markdown",
"id": "31861a7c-7740-4896-8754-b870ef17e7fe",
"metadata": {},
"source": [
"The simulation is executed using the `.run` method below. Note that the simulation may not be fully 'delta' accurate and will only serve for synchronous designs.\n",
"\n",
"**Note**: It is mandatory to yield an initial delay in the sequential code to properly arm the concurrent process scheduling."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "441f6d7e-da0f-4175-8087-98f00d72e64f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[32m Module unit_count: Existing instance unit_count, rename to unit_count_1 \u001b[0m\n",
"\u001b[32m Module unit_count: Existing instance lfsr8, rename to lfsr8_1 \u001b[0m\n",
"\u001b[32m Adding module with name `lfsr8_1` \u001b[0m\n",
"\u001b[32m Adding module with name `unit_count_1` \u001b[0m\n",
"\u001b[7;34m FINALIZE implementation `unit_count_1` of `unit_count` \u001b[0m\n",
"\n",
"-- Running command `hierarchy -top \\unit_count_1' --\n",
"\n",
"3. Executing HIERARCHY pass (managing design hierarchy).\n",
"\n",
"3.1. Analyzing design hierarchy..\n",
"Top module: \\unit_count_1\n",
"Used module: \\lfsr8_1\n",
"\n",
"3.2. Analyzing design hierarchy..\n",
"Top module: \\unit_count_1\n",
"Used module: \\lfsr8_1\n",
"Removed 0 unused modules.\n",
"Compiling /tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f.pyx because it changed.\n",
"[1/1] Cythonizing /tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f.pyx\n",
"running build_ext\n",
"building 'unit_count_1_468f' extension\n",
"creating build/temp.linux-x86_64-3.9/tmp/myirl_unit_count_4mi6a5jl\n",
"x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCOSIM_NAMESPACE=unit_count_1_468f -I../../myirl/kernel/../ -I/tmp/myirl_unit_count_4mi6a5jl/ -I/usr/share/yosys/include -I/usr/include/python3.9 -c /tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f.cpp -o build/temp.linux-x86_64-3.9/tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f.o\n",
"x86_64-linux-gnu-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -g -fwrapv -O2 -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -DCOSIM_NAMESPACE=unit_count_1_468f -I../../myirl/kernel/../ -I/tmp/myirl_unit_count_4mi6a5jl/ -I/usr/share/yosys/include -I/usr/include/python3.9 -c /tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f_rtl.cpp -o build/temp.linux-x86_64-3.9/tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f_rtl.o\n",
"x86_64-linux-gnu-g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -Wl,-z,relro -g -fwrapv -O2 -g -ffile-prefix-map=/build/python3.9-RNBry6/python3.9-3.9.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.9/tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f.o build/temp.linux-x86_64-3.9/tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f_rtl.o -o build/lib.linux-x86_64-3.9/unit_count_1_468f.cpython-39-x86_64-linux-gnu.so\n",
"copying build/lib.linux-x86_64-3.9/unit_count_1_468f.cpython-39-x86_64-linux-gnu.so -> \n",
"Open for writing: testbench.vcd\n",
"DEBUG STOP PROCESS reset_seq\n"
]
}
],
"source": [
"def test_simulation(n):\n",
" t = testbench()\n",
" assert t._uut.obj.ctx == unit_count.ctx\n",
" t.run(n)\n",
" return t\n",
"\n",
"t = test_simulation(2000)"
]
},
{
"cell_type": "markdown",
"id": "b48fab93-be1e-4b1a-b2cd-a4981a931e70",
"metadata": {},
"source": [
"The resulting test bench file: [testbench.vcd](testbench.vcd)"
]
},
{
"cell_type": "markdown",
"id": "6a145b11-29ac-4a55-9580-5e8da1178d33",
"metadata": {},
"source": [
"## Customizing RTLIL targets\n",
"\n",
"When the `.elab()` method is called, the design is elaborated as RTLIL and a list of design elements is returned, the first being a RTLIL Design handle.\n",
"The `.finalize()` method is called last inside elaboration, which can perform some optimizations or emissions to specific targets.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "f472f6fd-6039-45f6-bda2-219c94cbca33",
"metadata": {},
"outputs": [],
"source": [
"class MyRTL(pyosys.RTLIL):\n",
" def finalize(self, top, objs = None):\n",
" tname = top.name\n",
" design = self._design\n",
" design.run(\"hierarchy -top %s\" % tname)\n",
" print(80 * '=')\n",
" design.write_verilog(name = top.obj.name)\n",
" design.run(\"flatten; ls; select %s; stat\" % tname)\n",
" \n",
" return [design]"
]
},
{
"cell_type": "markdown",
"id": "54e56e82-4571-4a9a-9887-8545e94616ce",
"metadata": {},
"source": [
"The `.finalize()` function must return the created elements in a list, which is in turn returned from the `.elab()` call."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "490b03b6-6cfb-4465-832c-b5ebfa8b5a44",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[32m Module unit_count: Existing instance unit_count, rename to unit_count_2 \u001b[0m\n",
"\u001b[32m Module unit_count: Existing instance lfsr8, rename to lfsr8_2 \u001b[0m\n",
"\u001b[32m Adding module with name `lfsr8_2` \u001b[0m\n",
"\u001b[32m Adding module with name `unit_count_2` \u001b[0m\n",
"================================================================================\n",
"\n",
"-- Running command `tee -q write_cxxrtl -namespace unit_count_1_468f -header /tmp/myirl_unit_count_4mi6a5jl/unit_count_1_468f_rtl.cpp' --\n",
"\n",
"-- Running command `tee -q hierarchy -top unit_count_2' --\n",
"\n",
"-- Running command `ls; check' --\n",
"\n",
"6. Executing CHECK pass (checking for obvious problems).\n",
"Found and reported 0 problems.\n",
"\n",
"-- Running command `hierarchy -check' --\n",
"\n",
"7. Executing HIERARCHY pass (managing design hierarchy).\n",
"\n",
"-- Running command `write_verilog unit_count_mapped.v' --\n",
"\n",
"8. Executing Verilog backend.\n",
"Dumping module `\\lfsr8_2'.\n",
"Dumping module `\\unit_count_2'.\n",
"\n",
"-- Running command `tee -q flatten; ls; select unit_count_2; stat' --\n",
"\n",
"1 modules:\n",
" unit_count_2\n",
"\n",
"10. Printing statistics.\n"
]
}
],
"source": [
"tgt = MyRTL(\"top2\")\n",
"\n",
"design = test_expr(tgt)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "7195d6f9-aeaf-4464-ac62-6dc5ad7dba64",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/* Generated by Yosys 0.13+3 (git sha1 4656b0171, gcc 10.2.1-6 -Og -fPIC) */\n",
"\n",
"module lfsr8_2(clk, ce, reset, dout);\n",
" wire [7:0] _00_;\n",
" wire [-1:0] _01_;\n",
" wire _02_;\n",
" wire _03_;\n",
" wire _04_;\n",
" wire _05_;\n",
" wire [7:0] _06_;\n",
" wire _07_;\n",
" wire _08_;\n",
" wire _09_;\n",
" wire [7:0] _10_;\n",
" reg [7:0] _11_;\n",
" wire [7:0] _12_;\n",
" wire [7:0] _13_;\n",
" input ce;\n",
" input clk;\n",
" output [7:0] dout;\n",
" wire fb;\n",
" input reset;\n",
" wire [7:0] v;\n",
" assign _08_ = v[6:0] == 7'h00;\n",
" assign _09_ = v[7] ^ _08_;\n",
" assign _05_ = ce == 1'h1;\n",
" assign _03_ = v[2] ^ fb;\n",
" assign _04_ = v[3] ^ fb;\n",
" assign _06_ = _05_ ? _00_ : _13_;\n",
" assign _02_ = v[1] ^ fb;\n",
" always @(posedge clk, posedge reset)\n",
" if (reset) _11_ <= 8'hfa;\n",
" else _11_ <= _06_;\n",
" assign _00_ = { v[6:4], _04_, _03_, _02_, v[0], fb };\n",
" assign v = _11_;\n",
" assign _13_ = _11_;\n",
" assign _07_ = _09_;\n",
" assign _10_ = v;\n",
" assign fb = _07_;\n",
" assign dout = _10_;\n",
"endmodule\n",
"\n",
"(* top = 1 *)\n",
"module unit_count_2(clk, ce, reset, q);\n",
" wire [7:0] _0_;\n",
" wire [8:0] _1_;\n",
" wire [7:0] _2_;\n",
" reg [7:0] _3_;\n",
" wire [7:0] _4_;\n",
" wire [7:0] c;\n",
" input ce;\n",
" input clk;\n",
" wire [7:0] d;\n",
" output [7:0] q;\n",
" input reset;\n",
" assign _2_ = d ^ c;\n",
" assign _1_ = c + 8'h01;\n",
" always @(posedge clk, posedge reset)\n",
" if (reset) _3_ <= 8'h00;\n",
" else _3_ <= _0_;\n",
" lfsr8_2 inst_lfsr (\n",
" .ce(ce),\n",
" .clk(clk),\n",
" .dout(d),\n",
" .reset(reset)\n",
" );\n",
" assign _0_ = _1_[7:0];\n",
" assign c = _3_;\n",
" assign q = _2_;\n",
"endmodule\n"
]
}
],
"source": [
"!cat unit_count_mapped.v"
]
},
{
"cell_type": "markdown",
"id": "54ffaa3d-e31b-4520-9599-9bedb011c2d6",
"metadata": {},
"source": [
"## Limitations\n",
"\n",
"Some constructs that work for the VHDL target may not yet be supported:\n",
"\n",
"* Custom generators (bulk signal assignment, particular @hdlmacro constructs)"
]
}
],
"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
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment