{"id":734,"date":"2018-06-21T21:40:45","date_gmt":"2018-06-21T20:40:45","guid":{"rendered":"http:\/\/www.fabienm.eu\/flf\/?p=734"},"modified":"2018-06-21T21:40:45","modified_gmt":"2018-06-21T20:40:45","slug":"manage-high-impedance-z-state-with-chisel","status":"publish","type":"post","link":"http:\/\/www.fabienm.eu\/flf\/manage-high-impedance-z-state-with-chisel\/","title":{"rendered":"Manage high impedance &lsquo;Z&rsquo; state with Chisel"},"content":{"rendered":"<p><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/05\/chip_zorro.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-736\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/05\/chip_zorro.png\" alt=\"\" width=\"768\" height=\"512\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/05\/chip_zorro.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/05\/chip_zorro-300x200.png 300w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><\/p>\n<p>In previous (french) <a href=\"http:\/\/www.fabienm.eu\/flf\/integration-de-taptempo-chisel-sur-apf27\/\">article<\/a>, I described a technic to integrate a Chisel3 component named \u00ab\u00a0TapTempo\u00a0\u00bb in the <a href=\"http:\/\/www.opossom.com\/english\/products-processor_boards-apf27.html\">APF27 board<\/a>.\u00a0 This board is made with an i.MX27 CPU and a Spartan3A FPGA.<\/p>\n<p>To communicate with the FPGA, the i.MX27 is plugged on it with a memory bus named \u00ab<a href=\"http:\/\/www.armadeus.org\/wiki\/index.php?title=IMX27-Spartan3A_interface_description\">WEIM<\/a>\u00bb. But the data signals used in WEIM are also connected on flash nand memory on the board, and this memory contain the Linux kernel and rootfs.<\/p>\n<p>It&rsquo;s not a problem if the FPGA \u00ab\u00a0release\u00a0\u00bb the data bus in high impedance when not used. Ant it&rsquo;s the case when we use ctrl signal correctly (with <strong>oen<\/strong> signal -&gt; <strong>o<\/strong>utput <strong>e<\/strong>nable <strong>n<\/strong>ot)<\/p>\n<p><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/06\/apf27_nand_fpga.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-743\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/06\/apf27_nand_fpga.png\" alt=\"\" width=\"576\" height=\"512\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/06\/apf27_nand_fpga.png 576w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2018\/06\/apf27_nand_fpga-300x267.png 300w\" sizes=\"auto, (max-width: 576px) 100vw, 576px\" \/><\/a><\/p>\n<p>In the first design, as tempo data are only output values read by the CPU, it was declared as \u00ab\u00a0output\u00a0\u00bb in chisel bundle :<\/p>\n<pre>class APF27TapTempo extends Module {\r\nval io = IO(new Bundle {\r\nval data = Output(UInt(16.W))\r\n[...]<\/pre>\n<p>But with this data description, electrical value on physical data bus is continuously held by the FPGA. And when i.MX want to access nand flash memory it can&rsquo;t. And we cannot start Linux as it require reading value in flash memory.<\/p>\n<p>The solution is to set data bus as bidirectional signal and use WEIM signal <strong>oen<\/strong> to enable output on data bus, and when oen is not active the data bus is left on high impedance state &lsquo;Z&rsquo;.<\/p>\n<p>In chisel, to manage bidirectional signal, we have to use the type \u00ab\u00a0analog\u00a0\u00bb as it :<\/p>\n<pre>class APF27TapTempo extends Module {\r\n  val io = IO(new Bundle {\r\n    val oen = Input(Bool())\r\n    val data = Analog(16.W)\r\n  [...]\r\n<\/pre>\n<p>And simply deactivate data when oen is &lsquo;1&rsquo; ?<\/p>\n<pre>when(oen === '1'){\r\n   data := \"bZZZZZZZZZZZZZZZZ\"\r\n}.otherwize {\r\n   data := taptempovalue\r\n}\r\n<\/pre>\n<p>Would be so easy &#8230; But no, we can&rsquo;t do that with Chisel3 \ud83d\ude41<\/p>\n<p>In FPGA or ASIC, the high state value doesn&rsquo;t exist in fact. All signals under FPGA must be input or output and set to &lsquo;0&rsquo; or &lsquo;1&rsquo;. No other values are actually supported.<\/p>\n<p>Other \u00ab\u00a0high impedance\u00a0\u00bb values like &lsquo;Z&rsquo;, &lsquo;H&rsquo; or &lsquo;L&rsquo; can&rsquo;t be synthesized <strong>under<\/strong> the fpga. But these values (mostly &lsquo;Z&rsquo; state in fact) can be synthesized on the <strong>boundary<\/strong>. If a bidirectional signal going out of FPGA, the xilinx synthesizer can instantiate an IOBUF and manage the high state.<\/p>\n<p>Chisel <a href=\"https:\/\/github.com\/freechipsproject\/chisel3\/wiki\/Frequently-Asked-Questions#does-chisel-support-x-and-z-logic-values\">doesn&rsquo;t manage this high state<\/a>. It&rsquo;s a deliberate choice from chisel developers team to simplify Chisel3. But for some design, like on APF27 we need to implement it.<\/p>\n<p>Verilog manage this kind of signal state, then we can write a verilog code to write &lsquo;Z&rsquo; state and include it in our chisel design.<\/p>\n<p>To do this, we use a module chisel type named <a href=\"https:\/\/github.com\/freechipsproject\/chisel3\/wiki\/BlackBoxes\">BlackBox.<\/a> And as we want to add directly verilog source in the chisel code we will add the Trait <a href=\"https:\/\/github.com\/ucb-bar\/chisel3-wiki\/blob\/master\/BlackBoxes.md#blackboxes-with-in-line-verilog\">HasBlackBoxInline<\/a> like described bellow :<\/p>\n<pre>\/\/ import verilog code with HasBlackBoxInline\r\nimport chisel3.util.{HasBlackBoxInline, HasBlackBoxResource}\r\n...\r\n\/\/ Describe blackbox with verilog code\r\nclass Apf27Bus extends BlackBox with HasBlackBoxInline {\r\n  val io = IO(new Bundle {\r\n    val dataout = Output(UInt(16.W))\r\n    val dataio = Analog(16.W)\r\n    val datain = Input(UInt(16.W))\r\n    val oe = Input(Bool())\r\n  })\r\n\r\n  setInline(\"Apf27Bus.v\",\r\n    s\"\"\"\r\n    |module Apf27Bus(\r\n    |     output [15:0] dataout,\r\n    |     inout [15:0] dataio,\r\n    |     input [15:0] datain,\r\n    |     input oen);\r\n    |\r\n    |   assign dataio = (oen == 'b0) ? datain : 'bzzzzzzzzzzzzzzzz;\r\n    |   assign dataout = dataio;\r\n    |endmodule\r\n    \"\"\".stripMargin)\r\n}\r\n\/\/ Verilog will be written in separate file named Apf27Bus.v\r\n\r\n...\r\n\/\/ Then connect it in \"Top\" module\r\n  val iobuf = Module(new Apf27Bus)\r\n  io.data &lt;&gt; iobuf.io.dataio\r\n  iobuf.io.datain := dataout\r\n  iobuf.io.oen &lt;&gt; io.oen\r\n<\/pre>\n<p>As dataio is <strong>Analog<\/strong> type, we have to declare also analog on top bundle module :<\/p>\n<pre>class APF27TapTempo extends Module {\r\n  val io = IO(new Bundle {\r\n    val data = Analog(16.W)\r\n    val oen = Input(Bool())\r\n    val button = Input(Bool())\r\n  })\r\n<\/pre>\n<p>With this method, we keep all our sources codes in the chisel sources and our high &lsquo;Z&rsquo; bidirectional port is correctly synthesized with classical commercials software.<\/p>\n<p>All sources of this project described in this article are available on my github project <a href=\"https:\/\/github.com\/Martoni\/TapTempoChisel\">TapTempoChisel.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In previous (french) article, I described a technic to integrate a Chisel3 component named \u00ab\u00a0TapTempo\u00a0\u00bb in the APF27 board.\u00a0 This board is made with an i.MX27 CPU and a Spartan3A FPGA. To communicate with the FPGA, the i.MX27 is plugged on it with a memory bus named \u00abWEIM\u00bb. But the data signals used in WEIM &hellip; <a href=\"http:\/\/www.fabienm.eu\/flf\/manage-high-impedance-z-state-with-chisel\/\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Manage high impedance &lsquo;Z&rsquo; state with Chisel<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[2,4,3],"tags":[],"class_list":["post-734","post","type-post","status-publish","format-standard","hentry","category-chisel","category-chisel-langages","category-langages"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false},"uagb_author_info":{"display_name":"Fabien Marteau","author_link":"http:\/\/www.fabienm.eu\/flf\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"In previous (french) article, I described a technic to integrate a Chisel3 component named \u00ab\u00a0TapTempo\u00a0\u00bb in the APF27 board.\u00a0 This board is made with an i.MX27 CPU and a Spartan3A FPGA. To communicate with the FPGA, the i.MX27 is plugged on it with a memory bus named \u00abWEIM\u00bb. But the data signals used in WEIM\u2026","_links":{"self":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/734","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/comments?post=734"}],"version-history":[{"count":13,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/734\/revisions"}],"predecessor-version":[{"id":751,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/734\/revisions\/751"}],"wp:attachment":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/media?parent=734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/categories?post=734"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/tags?post=734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}