<html><head>
<title>YosysJS Example Application #02</title>
<script type="text/javascript" src="yosysjs.js"></script>
<script src="http://wavedrom.com/skins/default.js" type="text/javascript"></script>
<script src="http://wavedrom.com/WaveDrom.js" type="text/javascript"></script>
<style type="text/css">
.noedit { color: #666; }
</style>
<script id="golden_verilog" type="text/plain">
module ref(input clk, reset, input [7:0] A, output reg [7:0] Y);
	always @(posedge clk) begin
		if (reset)
			Y <= 0;
		else
			Y <= ((Y << 5) + Y) ^ A;
	end
endmodule
</script>
</head><body>
	<div id="popup" style="position: fixed; left: 0; top: 0; width:100%; height:100%; text-align:center; z-index: 1000;
		background-color: rgba(100, 100, 100, 0.5);"><div style="width:300px; margin: 200px auto; background-color: #88f;
		border:3px dashed #000; padding:15px; text-align:center;"><span id="popupmsg">Loading...</span></div>
	</div>
	<h1>YosysJS Example Application #03</h1>
	<b>Your mission:</b> Create a behavioral Verilog model for the following circuit:
	<p/>
	<div id="main" style="visibility: hidden">
		<svg id="schem" width="800"></svg>
		<p/>
		<pre id="code" style="width: 800px; border:2px solid #000; padding: 0.5em;"><span class="noedit">module top(input clk, reset, input [7:0] A, output reg [7:0] Y);
  always @(posedge clock) begin</span><span class="edit" contenteditable="true">
    Y &lt;= A | {4{reset}};
  </span><span class="noedit">end
endmodule</span></pre><p/>
		<input type="button" value="Check Model" onclick="check_model()"> <span id="checkmessage"></span>
		<p/>
		<p id="wave">&nbsp;</p>
	</div>
	<script type="text/javascript">
		function on_ys_ready() {
			ys.write_file('golden.v', document.getElementById('golden_verilog').textContent);
			ys.run('echo on; read_verilog golden.v; proc;;');
			ys.run('show -notitle -width -stretch');
			YosysJS.dot_into_svg(ys.read_file('show.dot'), 'schem');
			document.getElementById('popup').style.visibility = 'hidden';
			document.getElementById('popupmsg').textContent = 'Please wait..';
			document.getElementById('main').style.visibility = 'visible';
		}
		function check_model() {
			function work() {
				ys.remove_file('wave.json');
				ys.write_file('code.v', document.getElementById('code').textContent);
				ys.errmsg = '';
				ys.run('design -reset; read_verilog code.v; hierarchy -top top; proc; opt; flatten; hierarchy; ' +
					'read_verilog golden.v; proc; miter -equiv -ignore_gold_x -make_outputs -flatten ref top miter; ' +
					'hierarchy -top miter; clean -purge; sat -set-init-undef -seq 8 -dump_json wave.json -show-ports ' +
					'-max_undef -prove trigger 0 miter');
				w = document.getElementById('wave')
				if (ys.errmsg) {
					w.innerHTML = '<b><pre>ERROR: ' + ys.errmsg.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;') + '</pre></b>';
				} else {
					wdata = ys.read_file('wave.json');
					if (wdata) {
						wdata = JSON.parse(wdata);
						function wsignal(signame, newname) {
							for (i = 0; i < wdata["signal"].length; i++)
								if (wdata["signal"][i].name == signame) {
									if (newname)
										wdata["signal"][i].name = newname;
									return wdata["signal"][i];
								}
							return {};
						}
						wdata2 = {
							"signal" : [
								{ name: 'clk', wave: 'P........' },
								wsignal("trigger"),
								{},
								[ "Inputs", wsignal("in_reset", "reset"), wsignal("in_A", "A") ],
								{},
								[ "Y Output", wsignal("gold_Y", "Ref"), wsignal("gate_Y", "UUT") ],
							],
							"config" : wdata["config"]
						};
						wdata2 = JSON.stringify(wdata2)
						w.innerHTML = '<b>The model did not pass verification:</b><p/>' +
								'<script type="WaveDrom">' + wdata2 + '<\/script>';
						WaveDrom.ProcessAll();
					} else {
						w.innerHTML = '<b>Congratulations! The model did pass verification.</b><p/>';
					}
				}
				document.getElementById('popup').style.visibility = 'hidden';
			}
			document.getElementById('popup').style.visibility = 'visible';
			window.setTimeout(work, 100);
		}

		YosysJS.load_viz();
		var ys = YosysJS.create('', on_ys_ready);
		ys.logprint = true;
	</script>
</body></html>
000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #ffffff; }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */</style><div class="highlight"><pre><span></span><span class="cm">/*</span>
<span class="cm"> *  nextpnr -- Next Generation Place and Route</span>
<span class="cm"> *</span>
<span class="cm"> *  Copyright (C) 2018  SymbioticEDA</span>
<span class="cm"> *</span>
<span class="cm"> *  Permission to use, copy, modify, and/or distribute this software for any</span>
<span class="cm"> *  purpose with or without fee is hereby granted, provided that the above</span>
<span class="cm"> *  copyright notice and this permission notice appear in all copies.</span>
<span class="cm"> *</span>
<span class="cm"> *  THE SOFTWARE IS PROVIDED &quot;AS IS&quot; AND THE AUTHOR DISCLAIMS ALL WARRANTIES</span>
<span class="cm"> *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF</span>
<span class="cm"> *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR</span>
<span class="cm"> *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES</span>
<span class="cm"> *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN</span>
<span class="cm"> *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF</span>
<span class="cm"> *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</span>
<span class="cm"> *</span>
<span class="cm"> */</span>

<span class="cp">#ifndef JSON_PARSER</span>
<span class="cp">#define JSON_PARSER</span>

<span class="cp">#include</span> <span class="cpf">&lt;istream&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;nextpnr.h&quot;</span><span class="cp"></span>

<span class="n">NEXTPNR_NAMESPACE_BEGIN</span>

<span class="k">extern</span> <span class="kt">void</span> <span class="n">parse_json_file</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">istream</span> <span class="o">*&amp;</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&amp;</span><span class="p">,</span> <span class="n">Context</span> <span class="o">*</span><span class="p">);</span>

<span class="n">NEXTPNR_NAMESPACE_END</span>

<span class="cp">#endif</span>
</pre></div>