mirror of https://github.com/YosysHQ/yosys.git
YosysJS stuff
This commit is contained in:
parent
08c0fe164f
commit
e0e6d130cd
12
Makefile
12
Makefile
|
@ -97,16 +97,10 @@ else ifeq ($(CONFIG),emcc)
|
||||||
CXX = emcc
|
CXX = emcc
|
||||||
CXXFLAGS := -std=c++11 $(filter-out -fPIC -ggdb,$(CXXFLAGS))
|
CXXFLAGS := -std=c++11 $(filter-out -fPIC -ggdb,$(CXXFLAGS))
|
||||||
EMCCFLAGS := -Os -Wno-warn-absolute-paths
|
EMCCFLAGS := -Os -Wno-warn-absolute-paths
|
||||||
EMCCFLAGS += --memory-init-file 0 -s NO_EXIT_RUNTIME=1
|
EMCCFLAGS += --memory-init-file 0 --embed-file share -s NO_EXIT_RUNTIME=1
|
||||||
EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt']"
|
EMCCFLAGS += -s EXPORTED_FUNCTIONS="['_main','_run','_prompt','_errmsg']"
|
||||||
EMCCFLAGS += --embed-file share
|
EMCCFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -s ALLOW_MEMORY_GROWTH=1
|
||||||
# https://github.com/kripken/emscripten/blob/master/src/settings.js
|
# https://github.com/kripken/emscripten/blob/master/src/settings.js
|
||||||
# EMCCFLAGS += -s ALLOW_MEMORY_GROWTH=1
|
|
||||||
# EMCCFLAGS += -s DISABLE_EXCEPTION_CATCHING=0
|
|
||||||
# EMCCFLAGS += -s AGGRESSIVE_VARIABLE_ELIMINATION=1
|
|
||||||
# EMCCFLAGS += -s ASSERTIONS=2
|
|
||||||
# EMCCFLAGS += -s SAFE_HEAP=1
|
|
||||||
# EMCCFLAGS += -s RELOOP=0
|
|
||||||
CXXFLAGS += $(EMCCFLAGS)
|
CXXFLAGS += $(EMCCFLAGS)
|
||||||
LDFLAGS += $(EMCCFLAGS)
|
LDFLAGS += $(EMCCFLAGS)
|
||||||
LDLIBS =
|
LDLIBS =
|
||||||
|
|
|
@ -139,6 +139,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
|
||||||
%%
|
%%
|
||||||
|
|
||||||
input: {
|
input: {
|
||||||
|
ast_stack.clear();
|
||||||
ast_stack.push_back(current_ast);
|
ast_stack.push_back(current_ast);
|
||||||
} design {
|
} design {
|
||||||
ast_stack.pop_back();
|
ast_stack.pop_back();
|
||||||
|
|
|
@ -78,6 +78,7 @@ USING_YOSYS_NAMESPACE
|
||||||
|
|
||||||
extern "C" int main(int, char**);
|
extern "C" int main(int, char**);
|
||||||
extern "C" void run(const char*);
|
extern "C" void run(const char*);
|
||||||
|
extern "C" const char *errmsg();
|
||||||
extern "C" const char *prompt();
|
extern "C" const char *prompt();
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
|
@ -92,7 +93,21 @@ int main(int, char**)
|
||||||
|
|
||||||
void run(const char *command)
|
void run(const char *command)
|
||||||
{
|
{
|
||||||
|
int selSize = GetSize(yosys_get_design()->selection_stack);
|
||||||
|
try {
|
||||||
|
log_last_error = "Internal error (see JavaScript console for details)";
|
||||||
run_pass(command);
|
run_pass(command);
|
||||||
|
log_last_error = "";
|
||||||
|
} catch (...) {
|
||||||
|
while (GetSize(yosys_get_design()->selection_stack) > selSize)
|
||||||
|
yosys_get_design()->selection_stack.pop_back();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *errmsg()
|
||||||
|
{
|
||||||
|
return log_last_error.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *prompt()
|
const char *prompt()
|
||||||
|
|
|
@ -48,6 +48,7 @@ bool log_error_stderr = false;
|
||||||
bool log_cmd_error_throw = false;
|
bool log_cmd_error_throw = false;
|
||||||
bool log_quiet_warnings = false;
|
bool log_quiet_warnings = false;
|
||||||
int log_verbose_level;
|
int log_verbose_level;
|
||||||
|
string log_last_error;
|
||||||
|
|
||||||
vector<int> header_count;
|
vector<int> header_count;
|
||||||
pool<RTLIL::IdString> log_id_cache;
|
pool<RTLIL::IdString> log_id_cache;
|
||||||
|
@ -173,6 +174,10 @@ void logv_warning(const char *format, va_list ap)
|
||||||
|
|
||||||
void logv_error(const char *format, va_list ap)
|
void logv_error(const char *format, va_list ap)
|
||||||
{
|
{
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
auto backup_log_files = log_files;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (log_errfile != NULL)
|
if (log_errfile != NULL)
|
||||||
log_files.push_back(log_errfile);
|
log_files.push_back(log_errfile);
|
||||||
|
|
||||||
|
@ -181,10 +186,16 @@ void logv_error(const char *format, va_list ap)
|
||||||
if (f == stdout)
|
if (f == stdout)
|
||||||
f = stderr;
|
f = stderr;
|
||||||
|
|
||||||
log("ERROR: ");
|
log_last_error = vstringf(format, ap);
|
||||||
logv(format, ap);
|
log("ERROR: %s", log_last_error.c_str());
|
||||||
log_flush();
|
log_flush();
|
||||||
|
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
log_files = backup_log_files;
|
||||||
|
throw 0;
|
||||||
|
#else
|
||||||
exit(1);
|
exit(1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void log(const char *format, ...)
|
void log(const char *format, ...)
|
||||||
|
@ -224,8 +235,8 @@ void log_cmd_error(const char *format, ...)
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
|
|
||||||
if (log_cmd_error_throw) {
|
if (log_cmd_error_throw) {
|
||||||
log("ERROR: ");
|
log_last_error = vstringf(format, ap);
|
||||||
logv(format, ap);
|
log("ERROR: %s", log_last_error.c_str());
|
||||||
log_flush();
|
log_flush();
|
||||||
throw log_cmd_error_exception();
|
throw log_cmd_error_exception();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ extern bool log_error_stderr;
|
||||||
extern bool log_cmd_error_throw;
|
extern bool log_cmd_error_throw;
|
||||||
extern bool log_quiet_warnings;
|
extern bool log_quiet_warnings;
|
||||||
extern int log_verbose_level;
|
extern int log_verbose_level;
|
||||||
|
extern string log_last_error;
|
||||||
|
|
||||||
void logv(const char *format, va_list ap);
|
void logv(const char *format, va_list ap);
|
||||||
void logv_header(const char *format, va_list ap);
|
void logv_header(const char *format, va_list ap);
|
||||||
|
|
|
@ -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 <= 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"> </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('&', '&').replace('<', '<').replace('>', '>') + '</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>
|
|
@ -45,6 +45,7 @@ var YosysJS = new function() {
|
||||||
ys.verbose = false;
|
ys.verbose = false;
|
||||||
ys.logprint = false;
|
ys.logprint = false;
|
||||||
ys.echo = false;
|
ys.echo = false;
|
||||||
|
ys.errmsg = "";
|
||||||
|
|
||||||
if (typeof(reference_element) == 'string' && reference_element != "")
|
if (typeof(reference_element) == 'string' && reference_element != "")
|
||||||
reference_element = document.getElementById(reference_element);
|
reference_element = document.getElementById(reference_element);
|
||||||
|
@ -151,12 +152,20 @@ var YosysJS = new function() {
|
||||||
ys.write("");
|
ys.write("");
|
||||||
ys.write(ys.prompt() + cmd);
|
ys.write(ys.prompt() + cmd);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
mod.ccall('run', '', ['string'], [cmd]);
|
mod.ccall('run', '', ['string'], [cmd]);
|
||||||
|
} catch (e) {
|
||||||
|
ys.errmsg = mod.ccall('errmsg', 'string', [], []);;
|
||||||
|
}
|
||||||
return ys.print_buffer;
|
return ys.print_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ys.read_file = function(filename) {
|
ys.read_file = function(filename) {
|
||||||
|
try {
|
||||||
return ys.window.FS.readFile(filename, {encoding: 'utf8'});
|
return ys.window.FS.readFile(filename, {encoding: 'utf8'});
|
||||||
|
} catch (e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ys.write_file = function(filename, text) {
|
ys.write_file = function(filename, text) {
|
||||||
|
@ -167,6 +176,12 @@ var YosysJS = new function() {
|
||||||
return ys.window.FS.readdir(dirname);
|
return ys.window.FS.readdir(dirname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ys.remove_file = function(filename) {
|
||||||
|
try {
|
||||||
|
ys.window.FS.unlink(filename);
|
||||||
|
} catch (e) { }
|
||||||
|
}
|
||||||
|
|
||||||
doc.open()
|
doc.open()
|
||||||
doc.write('<script type="text/javascript" src="' + this.url_prefix + 'yosys.js"></' + 'script>');
|
doc.write('<script type="text/javascript" src="' + this.url_prefix + 'yosys.js"></' + 'script>');
|
||||||
doc.close()
|
doc.close()
|
||||||
|
|
Loading…
Reference in New Issue