{"id":1203,"date":"2020-02-03T22:08:20","date_gmt":"2020-02-03T21:08:20","guid":{"rendered":"http:\/\/www.fabienm.eu\/flf\/?p=1203"},"modified":"2020-02-26T15:51:27","modified_gmt":"2020-02-26T14:51:27","slug":"prove-chisel-design-with-yosys-smtbmc","status":"publish","type":"post","link":"http:\/\/www.fabienm.eu\/flf\/prove-chisel-design-with-yosys-smtbmc\/","title":{"rendered":"Prove Chisel design with Yosys-smtbmc"},"content":{"rendered":"\n<p>Formal prove is a great method to find bugs into our gateware.  But for many years, this was reserved to big companies with lot of $$. Some years ago,<a href=\"http:\/\/www.clifford.at\/\"> Clifford <\/a>opened the method with it&rsquo;s  synthesis software <a href=\"http:\/\/www.clifford.at\/yosys\/\">Yosys<\/a>. Explanation about formal prove with Yosys-smtbmc and can be found in <a href=\"http:\/\/www.clifford.at\/papers\/2016\/yosys-smtbmc\/slides.pdf\">this presentation<\/a>. Dan Guisselquist (ZipCPU) give lot of great tutorials on formal prove with Verilog and SystemVerilog design on <a href=\"https:\/\/zipcpu.com\/tutorial\/\">it&rsquo;s blog<\/a>.  It&rsquo;s a good start to learn formal prove.<\/p>\n\n\n\n<p>But, Yosys-smtbmc is made for Verilog (and a bit of SystemVerilog). It&rsquo;s too bad but it&rsquo;s the only open source formal tool available for gateware.<\/p>\n\n\n\n<p>How can we prove our VHDL, <a href=\"https:\/\/clash-lang.org\/\">Clash<\/a> or <a href=\"https:\/\/www.chisel-lang.org\/\">Chisel<\/a> gateware ?<\/p>\n\n\n\n<p>One of the solution consist of writing a TOP component in SystemVerilog that integrate the assume\/assert\/cover method and instantiate our DUT in it. It&rsquo;s the way <a href=\"https:\/\/www.youtube.com\/watch?v=o2gcHxPkXlA\">Pepijn De Vos choose<\/a> for verifying it&rsquo;s VHDL gateware. Its VHDL code is <a href=\"http:\/\/pepijndevos.nl\/2019\/08\/15\/open-source-formal-verification-in-vhdl.html\">converted into Verilog with the new GHDL feature <\/a>not-yet-finished and a systemVerilog top component instantiate the VHDL gateware converted in verilog by <a href=\"https:\/\/github.com\/tgingold\/ghdlsynth-beta\">GHDL synthesis<\/a> feature.<\/p>\n\n\n\n<p>That&rsquo;s an interesting way to do it and it can be done in the same way with Chisel. But it&rsquo;s a bit limited to input\/output ports of our gateware. If we want to add some property about internal counters or flags or others internals states machines registers, we have to export it with some conditional preprocessor value  like follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>`ifdef FORMAL\n\/\/ Declare some signal output ports\n`endif<\/code><\/pre>\n\n\n\n<p>It&rsquo;s became little bit difficult to do that with chisel and its <a href=\"https:\/\/github.com\/freechipsproject\/chisel3\/wiki\/BlackBoxes\">blackbox<\/a> system. Then if we want to include formal property under the verilog generated module, we have to open the generated verilog code and write it directly. <\/p>\n\n\n\n<p>It&rsquo;s not a lasting solution. Because each time we regenerate Verilog code from Chisel, each time we have to re-write formal properties. It&rsquo;s rapidly become a pain !<\/p>\n\n\n\n<p>To (temporarily) fix this problem a little python tools has been written by <a href=\"https:\/\/github.com\/Martoni\">Martoni<\/a>  for injecting rules automatically under generated Verilog module. We will see how it&rsquo;s work in this article with a simple project named <a href=\"https:\/\/github.com\/Martoni\/chisNesPad\">ChisNesPad<\/a>. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ChisNesPad project<\/h2>\n\n\n\n<p>ChisNesPad is a little project that aim to drive Super Nintendo Pad with an FPGA.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"800\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/snes_pad_ctrl.jpeg\" alt=\"\" class=\"wp-image-1361\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/snes_pad_ctrl.jpeg 800w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/snes_pad_ctrl-300x300.jpeg 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/snes_pad_ctrl-150x150.jpeg 150w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/snes_pad_ctrl-768x768.jpeg 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption>In electronic point of view, super nes controller is simply a 16 bits shift register.<\/figcaption><\/figure>\n\n\n\n<p>The gamepad pinout is relativelly easy to find on the web.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"428\" height=\"209\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/Snes_keypad_pinout.jpg\" alt=\"\" class=\"wp-image-1364\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/Snes_keypad_pinout.jpg 428w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/Snes_keypad_pinout-300x146.jpg 300w\" sizes=\"auto, (max-width: 428px) 100vw, 428px\" \/><figcaption>SuperNes gamePAD pinout<\/figcaption><\/figure><\/div>\n\n\n\n<p> For FPGA point of view 3 signals interest us :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>DATA : Gamepad output for serial datas<\/li><li>LATCH: Game pad input to take a \u00ab\u00a0picture\u00a0\u00bb of 16 buttons<\/li><li>CLOCK: To synchronize shifter<\/li><\/ul>\n\n\n\n<p>Internally, the game pad is composed of two <a href=\"https:\/\/pinoutguide.com\/Game\/snescontroller_pinout.shtml\">4021 chips serialized<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Basic Chisel\/Formal directory structure<\/h2>\n\n\n\n<p>The directory structure of the project is following :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\n|-- build.sbt  &lt;- scala build configuration\n|-- src\/   &lt;- all chisel sources\n|   |-- main\/\n|       |-- scala\/\n|           |-- chisnespad.scala &lt;- Chisel module we will prove\n|           |-- snespadled.scala &lt;- \"top\" module to test with\n|                                    tang nano (gowin)\n|-- formal\/   &lt;- formal directory where systemVerilog\n|                and sby yosys configuration are.\n|-- platform\/ &lt;- some usefull file for synthesis with \n                 final platform (gowin).<\/code><\/pre>\n\n\n\n<p>To generate Verilog file we just have to launch following command in main project directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sbt 'runMain chisnespad.ChisNesPad'<\/code><\/pre>\n\n\n\n<p>The generated file  will be named <code>ChisNesPad.v <\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">smtbmcify tool<\/h2>\n\n\n\n<p>smtbmcify tool is a python3 module that can be found on this <a href=\"https:\/\/github.com\/Martoni\/chisverilogutils\">github project.<\/a> It can be installed on the dev machine as follow:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git clone https:\/\/github.com\/Martoni\/chisverilogutils\n$ cd chisverilogutils\/smtbmcify\n$ python -m pip install -e .<\/code><\/pre>\n\n\n\n<p>A command named smtbmcify will then be available on system :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$  smtbmcify -h\nUsages:\n$ python smtbmcify.py [options]\n-h, --help             print this help message\n-v, --verilog=module.v verilog module to read\n-f, --formal=formal.sv formals rules\n-o, --output=name.sv   output filename, default is moduleFormal.sv\n<\/code><\/pre>\n\n\n\n<p>To use smtbmc formal tools with smtbmcify we will need two more source\/configuration files :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>ChisNesPadRules.sv<\/code> That contain SystemVerilog formals properties<\/li><li><code>ChisNesPadRules.sby<\/code> That contain yosys-smtbmc script configuration<\/li><\/ul>\n\n\n\n<p>These two files must be saved in <code>formal\/<\/code> directory. sby files are SymbiYosys configuration files, installation instruction of SymbiYosys can be <a href=\"https:\/\/symbiyosys.readthedocs.io\/en\/latest\/\">found here<\/a>.<\/p>\n\n\n\n<p>For simply testing, the rule (written in file <code>ChisNesPadRules.sv<\/code>) we want to \u00ab\u00a0inject\u00a0\u00bb is following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/BeginModule:ChisNesPad\n\nalways@(posedge clock) begin\n    assume(io_dlatch == 1'b1);\n    assert(stateReg == 2'b00); \nend\n\n\/\/EndModule:ChisNesPad<\/code><\/pre>\n\n\n\n<p>With this rule, we assert that if<code> io.dlatch<\/code> output is 1, the internal <code>stateReg<\/code> will be set to<code> sInit <\/code>state (00). <\/p>\n\n\n\n<p>The comments BeginModule and EndModule must be set with the exact chisel module name  :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/...\nclass ChisNesPad (val mainClockFreq: Int = 100,\n                  val clockFreq: Int = 1,\n                  val regLen: Int = 16) extends Module {\n  val io = IO(new Bundle{\n\/\/...<\/code><\/pre>\n\n\n\n<p>Hence, the tool smtbmcify will find the module in verilog generated module and inject the rules at the end of it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cd formal\n$ smtbmcify -v ..\/ChisNesPad.v -f ChisNesPadRules.sv -o ChisNesPadFormal.sv<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>...\n    end else begin\n      validReg &lt;= _T_19;\n    end\n    _T_21 &lt;= stateReg == 2'h1;\n    _T_23 &lt;= stateReg == 2'h0;\n  end\n\/\/BeginModule:ChisNesPad\n\nalways@(posedge clock) begin\n    assume(io_dlatch == 1'b1);\n    assert(stateReg == 2'b00); \nend\n\n\/\/EndModule:ChisNesPad\nendmodule<\/code><\/pre>\n\n\n\n<p> The module name is mandatory because a Chisel Verilog generated module can contain several module.<\/p>\n\n\n\n<p>Some naming convention should be know to write systemverilog rules:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>dot &lsquo;.&rsquo; syntax is replaced with &lsquo;_&rsquo;  in Verilog: for this example <code>io.dlatch<\/code> chisel signal is replaced with <code>io_dlatch<\/code>.<\/li><li>Some registers can disappear (be simplified) in generated Verilog.<a href=\"https:\/\/www.chisel-lang.org\/api\/latest\/chisel3\/dontTouch$.html\"> dontTouch() <\/a>can be used to keep it in generated Verilog.<\/li><\/ul>\n\n\n\n<p>To launch the formal engine we are using a sby script like it (named ChisNesPad.sby:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[options]\nmode bmc \ndepth 30\n\n[engines]\nsmtbmc\n\n[script]\nread -formal ChisNesPadFormal.sv\nprep -top ChisNesPad\n\n[files]\nChisNesPadFormal.sv<\/code><\/pre>\n\n\n\n<p>The launch command is :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sby ChisNesPad.sby\nSBY 21:12:00 [ChisNesPad] Copy 'ChisNesPadFormal.sv' to 'ChisNesPad\/src\/ChisNesPadFormal.sv'.\nSBY 21:12:00 [ChisNesPad] engine_0: smtbmc\nSBY 21:12:00 [ChisNesPad] base: starting process \"cd ChisNesPad\/src; yosys -ql ..\/model\/design.log ..\/model\/design.ys\"\nSBY 21:12:00 [ChisNesPad] base: finished (returncode=0)\nSBY 21:12:00 [ChisNesPad] smt2: starting process \"cd ChisNesPad\/model; yosys -ql design_smt2.log design_smt2.ys\"\nSBY 21:12:00 [ChisNesPad] smt2: finished (returncode=0)\nSBY 21:12:00 [ChisNesPad] engine_0: starting process \"cd ChisNesPad; yosys-smtbmc --presat --unroll --noprogress -t 30 --append 0 --dump-vcd engine_0\/trace.vcd --dump-vlogtb engine_0\/trace_tb.v --dump-smtc engine_0\/trace.smtc model\/design_smt2.smt2\"\nSBY 21:12:01 [ChisNesPad] engine_0: ##   0:00:00  Solver: yices\nSBY 21:12:01 [ChisNesPad] engine_0: ##   0:00:00  Checking assumptions in step 0..\nSBY 21:12:01 [ChisNesPad] engine_0: ##   0:00:00  Checking assertions in step 0..\n[...]\nSBY 21:12:01 [ChisNesPad] engine_0: ##   0:00:00  Checking assumptions in step 29..\nSBY 21:12:01 [ChisNesPad] engine_0: ##   0:00:00  Checking assertions in step 29..\nSBY 21:12:01 [ChisNesPad] engine_0: ##   0:00:00  Status: passed\nSBY 21:12:01 [ChisNesPad] engine_0: finished (returncode=0)\nSBY 21:12:01 [ChisNesPad] engine_0: Status returned by engine: pass\nSBY 21:12:01 [ChisNesPad] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:00 (0)\nSBY 21:12:01 [ChisNesPad] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:00 (0)\nSBY 21:12:01 [ChisNesPad] summary: engine_0 (smtbmc) returned pass\nSBY 21:12:01 [ChisNesPad] DONE (PASS, rc=0)\n<\/code><\/pre>\n\n\n\n<p>This simple rule finish with success (PASS) and create a directory with all generated file under it.<\/p>\n\n\n\n<p>Rapidly, we will need a Makefile to launch each step of this procedure and to clean generated file.<\/p>\n\n\n\n<p>Of course, all code described so far is available on the<a href=\"https:\/\/github.com\/Martoni\/chisNesPad\/tree\/master\/formal\"> github ChisNesPad project<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Find bugs<\/h2>\n\n\n\n<p>Ok the test we done so far PASS without problem. Let&rsquo;s find a bug adding this rules in ChisNesPadRules.sv :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>always@(posedge clock) begin\n    assert(regCount &lt;= 16); \nend<\/code><\/pre>\n\n\n\n<p>This rule generate a FAIL :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ make\ncd ..;sbt \"runMain chisnespad.ChisNesPad\"\n[info] Loading project definition from \/home\/fabien\/myapp\/chisNesPad\/project\n[info] Loading settings for project chisnespad from build.sbt ...\n[info] Set current project to chisNesPad (in build file:\/home\/fabien\/myapp\/chisNesPad\/)\n[warn] Multiple main classes detected.  Run 'show discoveredMainClasses' to see the list\n[info] running chisnespad.ChisNesPad \nGenerating Verilog sources for ChisNesPad Module\n[info] [0.004] Elaborating design...\n[info] [1.735] Done elaborating.\nTotal FIRRTL Compile Time: 1396.1 ms\n[success] Total time: 5 s, completed Feb 3, 2020 9:49:48 PM\nsmtbmcify -v ..\/ChisNesPad.v -f ChisNesPadRules.sv -o ChisNesPadFormal.sv\nGenerating file ChisNesPadFormal.sv\n1 module will be filled :\nChisNesPad\nrm -rf ChisNesPad\nsby ChisNesPad.sby\nSBY 21:49:48 [ChisNesPad] Copy 'ChisNesPadFormal.sv' to 'ChisNesPad\/src\/ChisNesPadFormal.sv'.\nSBY 21:49:48 [ChisNesPad] engine_0: smtbmc\nSBY 21:49:48 [ChisNesPad] base: starting process \"cd ChisNesPad\/src; yosys -ql ..\/model\/design.log ..\/model\/design.ys\"\nSBY 21:49:49 [ChisNesPad] base: finished (returncode=0)\nSBY 21:49:49 [ChisNesPad] smt2: starting process \"cd ChisNesPad\/model; yosys -ql design_smt2.log design_smt2.ys\"\nSBY 21:49:49 [ChisNesPad] smt2: finished (returncode=0)\nSBY 21:49:49 [ChisNesPad] engine_0: starting process \"cd ChisNesPad; yosys-smtbmc --presat --unroll --noprogress -t 30 --append 0 --dump-vcd engine_0\/trace.vcd --dump-vlogtb engine_0\/trace_tb.v --dump-smtc engine_0\/trace.smtc model\/design_smt2.smt2\"\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Solver: yices\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Checking assumptions in step 0..\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Checking assertions in step 0..\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Checking assumptions in step 1..\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Checking assertions in step 1..\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  BMC failed!\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Assert failed in ChisNesPad: ChisNesPadFormal.sv:230\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Writing trace to VCD file: engine_0\/trace.vcd\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Writing trace to Verilog testbench: engine_0\/trace_tb.v\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Writing trace to constraints file: engine_0\/trace.smtc\nSBY 21:49:49 [ChisNesPad] engine_0: ##   0:00:00  Status: failed (!)\nSBY 21:49:49 [ChisNesPad] engine_0: finished (returncode=1)\nSBY 21:49:49 [ChisNesPad] engine_0: Status returned by engine: FAIL\nSBY 21:49:49 [ChisNesPad] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:00 (0)\nSBY 21:49:49 [ChisNesPad] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:00 (0)\nSBY 21:49:49 [ChisNesPad] summary: engine_0 (smtbmc) returned FAIL\nSBY 21:49:49 [ChisNesPad] summary: counterexample trace: ChisNesPad\/engine_0\/trace.vcd\nSBY 21:49:49 [ChisNesPad] DONE (FAIL, rc=2)\nmake: *** [Makefile:10: ChisNesPad\/PASS] Error 2<\/code><\/pre>\n\n\n\n<p>An error is found at second step. A vcd trace is generated that we can see with <a href=\"http:\/\/gtkwave.sourceforge.net\/\">gtkwave<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ gtkwave ChisNesPad\/engine_0\/trace.vcd<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1004\" height=\"627\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/formal_chisnespad.png\" alt=\"\" class=\"wp-image-1372\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/formal_chisnespad.png 1004w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/formal_chisnespad-300x187.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2020\/02\/formal_chisnespad-768x480.png 768w\" sizes=\"auto, (max-width: 1004px) 100vw, 1004px\" \/><figcaption>Formal engine found a bug, and print it as a VCD trace<\/figcaption><\/figure>\n\n\n\n<p>We can also get verilog testbench that reproduce the bug  under the same directory (trace_tb.v).<\/p>\n\n\n\n<p>The problem here is that we didn&rsquo;t define initial reset condition as explained in <a href=\"https:\/\/zipcpu.com\/tutorial\/class-verilog.pdf\">ZipCPU course<\/a>.  To solve this problem we have to change the rule adding initial rules (reset should be set at the begining) and assert counter value only when reset is not set :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>initial\n    assume(reset==1'b1);\n\nalways@(posedge clock) begin\n    if(reset == 1'b0) \n        assert(regCount &lt;= 16); \nend<\/code><\/pre>\n\n\n\n<p>With that rules, it pass :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ make\ncd ..;sbt \"runMain chisnespad.ChisNesPad\"\n[info] Loading project definition from \/home\/fabien\/myapp\/chisNesPad\/project\n[info] Loading settings for project chisnespad from build.sbt ...\n[info] Set current project to chisNesPad (in build file:\/home\/fabien\/myapp\/chisNesPad\/)\n[warn] Multiple main classes detected.  Run 'show discoveredMainClasses' to see the list\n[info] running chisnespad.ChisNesPad \nGenerating Verilog sources for ChisNesPad Module\n[info] [0.004] Elaborating design...\n[info] [1.612] Done elaborating.\nTotal FIRRTL Compile Time: 1324.0 ms\n[success] Total time: 5 s, completed Feb 3, 2020 10:04:37 PM\nsmtbmcify -v ..\/ChisNesPad.v -f ChisNesPadRules.sv -o ChisNesPadFormal.sv\nGenerating file ChisNesPadFormal.sv\n1 module will be filled :\nChisNesPad\nrm -rf ChisNesPad\nsby ChisNesPad.sby\nSBY 22:04:38 [ChisNesPad] Copy 'ChisNesPadFormal.sv' to 'ChisNesPad\/src\/ChisNesPadFormal.sv'.\nSBY 22:04:38 [ChisNesPad] engine_0: smtbmc\nSBY 22:04:38 [ChisNesPad] base: starting process \"cd ChisNesPad\/src; yosys -ql ..\/model\/design.log ..\/model\/design.ys\"\nSBY 22:04:38 [ChisNesPad] base: finished (returncode=0)\nSBY 22:04:38 [ChisNesPad] smt2: starting process \"cd ChisNesPad\/model; yosys -ql design_smt2.log design_smt2.ys\"\nSBY 22:04:38 [ChisNesPad] smt2: finished (returncode=0)\nSBY 22:04:38 [ChisNesPad] engine_0: starting process \"cd ChisNesPad; yosys-smtbmc --presat --unroll --noprogress -t 30 --append 0 --dump-vcd engine_0\/trace.vcd --dump-vlogtb engine_0\/trace_tb.v --dump-smtc engine_0\/trace.smtc model\/design_smt2.smt2\"\nSBY 22:04:38 [ChisNesPad] engine_0: ##   0:00:00  Solver: yices\nSBY 22:04:38 [ChisNesPad] engine_0: ##   0:00:00  Checking assumptions in step 0..\n[...]\nSBY 22:04:39 [ChisNesPad] engine_0: ##   0:00:00  Checking assertions in step 29..\nSBY 22:04:39 [ChisNesPad] engine_0: ##   0:00:00  Status: passed\nSBY 22:04:39 [ChisNesPad] engine_0: finished (returncode=0)\nSBY 22:04:39 [ChisNesPad] engine_0: Status returned by engine: pass\nSBY 22:04:39 [ChisNesPad] summary: Elapsed clock time [H:MM:SS (secs)]: 0:00:00 (0)\nSBY 22:04:39 [ChisNesPad] summary: Elapsed process time [H:MM:SS (secs)]: 0:00:00 (0)\nSBY 22:04:39 [ChisNesPad] summary: engine_0 (smtbmc) returned pass\nSBY 22:04:39 [ChisNesPad] DONE (PASS, rc=0)\n<\/code><\/pre>\n\n\n\n<p>This is just a little introduction on how to use yosys-smtbmc and symbiYosys to formally prove your chisel design.<\/p>\n\n\n\n<p>Maybe this formal rules injector will be integrated in<a href=\"https:\/\/stackoverflow.com\/questions\/49320801\/formal-verification-with-chisel\"> Chisel a day <\/a>?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Formal prove is a great method to find bugs into our gateware. But for many years, this was reserved to big companies with lot of $$. Some years ago, Clifford opened the method with it&rsquo;s synthesis software Yosys. Explanation about formal prove with Yosys-smtbmc and can be found in this presentation. Dan Guisselquist (ZipCPU) give &hellip; <a href=\"http:\/\/www.fabienm.eu\/flf\/prove-chisel-design-with-yosys-smtbmc\/\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Prove Chisel design with Yosys-smtbmc<\/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":[1],"tags":[57,88,170,172,81,30,45,171],"class_list":["post-1203","post","type-post","status-publish","format-standard","hentry","category-non-classe","tag-chisel","tag-chisel3","tag-formal","tag-smtbmc","tag-systemverilog","tag-verilog","tag-yosys","tag-yosys-smtbmc"],"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":1,"uagb_excerpt":"Formal prove is a great method to find bugs into our gateware. But for many years, this was reserved to big companies with lot of $$. Some years ago, Clifford opened the method with it&rsquo;s synthesis software Yosys. Explanation about formal prove with Yosys-smtbmc and can be found in this presentation. Dan Guisselquist (ZipCPU) give\u2026","_links":{"self":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1203","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=1203"}],"version-history":[{"count":26,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1203\/revisions"}],"predecessor-version":[{"id":1427,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1203\/revisions\/1427"}],"wp:attachment":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/media?parent=1203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/categories?post=1203"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/tags?post=1203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}