summaryrefslogtreecommitdiff
path: root/misc/yosysjs
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-02-19 13:36:54 +0100
committerClifford Wolf <clifford@clifford.at>2015-02-19 13:36:54 +0100
commite0e6d130cd083a8285ea2991629e0049023da234 (patch)
tree7be213913f1145b536f7b696e95e300ef67c834f /misc/yosysjs
parent08c0fe164fefb28dc209d35e7bd757538311d2e6 (diff)
YosysJS stuff
Diffstat (limited to 'misc/yosysjs')
-rw-r--r--misc/yosysjs/demo03.html103
-rw-r--r--misc/yosysjs/yosysjs.js19
2 files changed, 120 insertions, 2 deletions
diff --git a/misc/yosysjs/demo03.html b/misc/yosysjs/demo03.html
new file mode 100644
index 00000000..720b82e9
--- /dev/null
+++ b/misc/yosysjs/demo03.html
@@ -0,0 +1,103 @@
+<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/>
+ <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>
+ <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..';
+ }
+ 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) {
+ console.log(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)
+ console.log(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;
+ ys.echo = true;
+ </script>
+</body></html>
diff --git a/misc/yosysjs/yosysjs.js b/misc/yosysjs/yosysjs.js
index 87c95118..a1181493 100644
--- a/misc/yosysjs/yosysjs.js
+++ b/misc/yosysjs/yosysjs.js
@@ -45,6 +45,7 @@ var YosysJS = new function() {
ys.verbose = false;
ys.logprint = false;
ys.echo = false;
+ ys.errmsg = "";
if (typeof(reference_element) == 'string' && reference_element != "")
reference_element = document.getElementById(reference_element);
@@ -151,12 +152,20 @@ var YosysJS = new function() {
ys.write("");
ys.write(ys.prompt() + cmd);
}
- mod.ccall('run', '', ['string'], [cmd]);
+ try {
+ mod.ccall('run', '', ['string'], [cmd]);
+ } catch (e) {
+ ys.errmsg = mod.ccall('errmsg', 'string', [], []);;
+ }
return ys.print_buffer;
}
ys.read_file = function(filename) {
- return ys.window.FS.readFile(filename, {encoding: 'utf8'});
+ try {
+ return ys.window.FS.readFile(filename, {encoding: 'utf8'});
+ } catch (e) {
+ return "";
+ }
}
ys.write_file = function(filename, text) {
@@ -167,6 +176,12 @@ var YosysJS = new function() {
return ys.window.FS.readdir(dirname);
}
+ ys.remove_file = function(filename) {
+ try {
+ ys.window.FS.unlink(filename);
+ } catch (e) { }
+ }
+
doc.open()
doc.write('<script type="text/javascript" src="' + this.url_prefix + 'yosys.js"></' + 'script>');
doc.close()