verilog: worker re-uses memory
This commit is contained in:
parent
5cf56f9d04
commit
e703c16dfe
|
@ -30,6 +30,7 @@
|
||||||
"electron": "^9.4.0",
|
"electron": "^9.4.0",
|
||||||
"electron-packager": "^15.2.0",
|
"electron-packager": "^15.2.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"heapdump": "^0.3.15",
|
||||||
"jsdom": "^12.2.0",
|
"jsdom": "^12.2.0",
|
||||||
"jsfuzz": "^1.0.14",
|
"jsfuzz": "^1.0.14",
|
||||||
"jszip": "^3.5.0",
|
"jszip": "^3.5.0",
|
||||||
|
@ -3134,6 +3135,19 @@
|
||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/heapdump": {
|
||||||
|
"version": "0.3.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.15.tgz",
|
||||||
|
"integrity": "sha512-n8aSFscI9r3gfhOcAECAtXFaQ1uy4QSke6bnaL+iymYZ/dWs9cqDqHM+rALfsHUwukUbxsdlECZ0pKmJdQ/4OA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"nan": "^2.13.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hosted-git-info": {
|
"node_modules/hosted-git-info": {
|
||||||
"version": "2.8.9",
|
"version": "2.8.9",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||||
|
@ -4725,6 +4739,12 @@
|
||||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/nan": {
|
||||||
|
"version": "2.14.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||||
|
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/neo-async": {
|
"node_modules/neo-async": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||||
|
@ -10128,6 +10148,15 @@
|
||||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"heapdump": {
|
||||||
|
"version": "0.3.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.15.tgz",
|
||||||
|
"integrity": "sha512-n8aSFscI9r3gfhOcAECAtXFaQ1uy4QSke6bnaL+iymYZ/dWs9cqDqHM+rALfsHUwukUbxsdlECZ0pKmJdQ/4OA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"nan": "^2.13.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hosted-git-info": {
|
"hosted-git-info": {
|
||||||
"version": "2.8.9",
|
"version": "2.8.9",
|
||||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||||
|
@ -11397,6 +11426,12 @@
|
||||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nan": {
|
||||||
|
"version": "2.14.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||||
|
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"neo-async": {
|
"neo-async": {
|
||||||
"version": "2.6.2",
|
"version": "2.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
"electron": "^9.4.0",
|
"electron": "^9.4.0",
|
||||||
"electron-packager": "^15.2.0",
|
"electron-packager": "^15.2.0",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
|
"heapdump": "^0.3.15",
|
||||||
"jsdom": "^12.2.0",
|
"jsdom": "^12.2.0",
|
||||||
"jsfuzz": "^1.0.14",
|
"jsfuzz": "^1.0.14",
|
||||||
"jszip": "^3.5.0",
|
"jszip": "^3.5.0",
|
||||||
|
|
|
@ -371,7 +371,7 @@ export class HDLModuleWASM implements HDLModuleRunner {
|
||||||
//console.log(this.bmod.emitText());
|
//console.log(this.bmod.emitText());
|
||||||
//this.bmod.optimize();
|
//this.bmod.optimize();
|
||||||
if (!this.bmod.validate()) {
|
if (!this.bmod.validate()) {
|
||||||
console.log(this.bmod.emitText());
|
//console.log(this.bmod.emitText());
|
||||||
throw new HDLError(null, `could not validate wasm module`);
|
throw new HDLError(null, `could not validate wasm module`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1038,9 +1038,11 @@ export class HDLModuleWASM implements HDLModuleRunner {
|
||||||
return this.binop(e, this.i3264(e.dtype).shl, false, true);
|
return this.binop(e, this.i3264(e.dtype).shl, false, true);
|
||||||
}
|
}
|
||||||
_shiftr2wasm(e: HDLBinop) {
|
_shiftr2wasm(e: HDLBinop) {
|
||||||
// TODO: signed?
|
|
||||||
return this.binop(e, this.i3264(e.dtype).shr_u, false, true);
|
return this.binop(e, this.i3264(e.dtype).shr_u, false, true);
|
||||||
}
|
}
|
||||||
|
_shiftrs2wasm(e: HDLBinop) {
|
||||||
|
return this.binop(e, this.i3264(e.dtype).shr_s, false, true);
|
||||||
|
}
|
||||||
_add2wasm(e: HDLBinop) {
|
_add2wasm(e: HDLBinop) {
|
||||||
return this.binop(e, this.i3264(e.dtype).add);
|
return this.binop(e, this.i3264(e.dtype).add);
|
||||||
}
|
}
|
||||||
|
@ -1050,6 +1052,9 @@ export class HDLModuleWASM implements HDLModuleRunner {
|
||||||
_mul2wasm(e: HDLBinop) {
|
_mul2wasm(e: HDLBinop) {
|
||||||
return this.binop(e, this.i3264(e.dtype).mul);
|
return this.binop(e, this.i3264(e.dtype).mul);
|
||||||
}
|
}
|
||||||
|
_muls2wasm(e: HDLBinop) {
|
||||||
|
return this.binop(e, this.i3264(e.dtype).mul); // TODO: signed?
|
||||||
|
}
|
||||||
_moddiv2wasm(e: HDLBinop) {
|
_moddiv2wasm(e: HDLBinop) {
|
||||||
return this.binop(e, this.i3264(e.dtype).rem_u);
|
return this.binop(e, this.i3264(e.dtype).rem_u);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,12 @@ export class VerilogXMLParser implements HDLUnit {
|
||||||
this.dtypes['IData'] = {left:31, right:0};
|
this.dtypes['IData'] = {left:31, right:0};
|
||||||
this.dtypes['SData'] = {left:15, right:0};
|
this.dtypes['SData'] = {left:15, right:0};
|
||||||
this.dtypes['CData'] = {left:7, right:0};
|
this.dtypes['CData'] = {left:7, right:0};
|
||||||
|
this.dtypes['byte'] = {left:7, right:0};
|
||||||
|
this.dtypes['shortint'] = {left:15, right:0};
|
||||||
this.dtypes['int'] = {left:31, right:0};
|
this.dtypes['int'] = {left:31, right:0};
|
||||||
|
this.dtypes['integer'] = {left:31, right:0};
|
||||||
|
this.dtypes['longint'] = {left:63, right:0};
|
||||||
|
this.dtypes['time'] = {left:63, right:0};
|
||||||
}
|
}
|
||||||
|
|
||||||
defer(fn: () => void) {
|
defer(fn: () => void) {
|
||||||
|
@ -522,6 +527,9 @@ export class VerilogXMLParser implements HDLUnit {
|
||||||
visit_constpool(node: XMLNode) {
|
visit_constpool(node: XMLNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visit_comment(node: XMLNode) {
|
||||||
|
}
|
||||||
|
|
||||||
expectChildren(node: XMLNode, low: number, high: number) {
|
expectChildren(node: XMLNode, low: number, high: number) {
|
||||||
if (node.children.length < low || node.children.length > high)
|
if (node.children.length < low || node.children.length > high)
|
||||||
throw new CompileError(node, `expected between ${low} and ${high} children`);
|
throw new CompileError(node, `expected between ${low} and ${high} children`);
|
||||||
|
|
|
@ -15,6 +15,18 @@ const ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
|
||||||
var _WASM_module_cache = {};
|
var _WASM_module_cache = {};
|
||||||
var CACHE_WASM_MODULES = true; // if false, use asm.js only
|
var CACHE_WASM_MODULES = true; // if false, use asm.js only
|
||||||
|
|
||||||
|
// TODO: which modules need this?
|
||||||
|
var wasmMemory;
|
||||||
|
function getWASMMemory() {
|
||||||
|
if (wasmMemory == null) {
|
||||||
|
wasmMemory = new WebAssembly.Memory({
|
||||||
|
'initial': 32768,
|
||||||
|
'maximum': 32768,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return wasmMemory;
|
||||||
|
}
|
||||||
|
|
||||||
function getWASMModule(module_id:string) {
|
function getWASMModule(module_id:string) {
|
||||||
var module = _WASM_module_cache[module_id];
|
var module = _WASM_module_cache[module_id];
|
||||||
if (!module) {
|
if (!module) {
|
||||||
|
@ -1770,10 +1782,11 @@ function compileVerilator(step:BuildStep) {
|
||||||
var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?):(\d+)?[:]?\s*(.+)/i, 3, 4, step.path, 2);
|
var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?):(\d+)?[:]?\s*(.+)/i, 3, 4, step.path, 2);
|
||||||
var verilator_mod = emglobal.verilator_bin({
|
var verilator_mod = emglobal.verilator_bin({
|
||||||
instantiateWasm: moduleInstFn('verilator_bin'),
|
instantiateWasm: moduleInstFn('verilator_bin'),
|
||||||
noInitialRun:true,
|
noInitialRun: true,
|
||||||
noExitRuntime:true,
|
noExitRuntime: true,
|
||||||
print:print_fn,
|
print: print_fn,
|
||||||
printErr:match_fn,
|
printErr: match_fn,
|
||||||
|
wasmMemory: getWASMMemory(), // reuse memory
|
||||||
//INITIAL_MEMORY:256*1024*1024,
|
//INITIAL_MEMORY:256*1024*1024,
|
||||||
});
|
});
|
||||||
var code = getWorkFileAsString(step.path);
|
var code = getWorkFileAsString(step.path);
|
||||||
|
|
|
@ -5,6 +5,7 @@ var _path = require('path')
|
||||||
var _cproc = require('child_process');
|
var _cproc = require('child_process');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var wtu = require('./workertestutils.js');
|
var wtu = require('./workertestutils.js');
|
||||||
|
var heapdump = require("heapdump");
|
||||||
|
|
||||||
createTestDOM();
|
createTestDOM();
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ function testPerf(msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileVerilator(filename, code, callback, nerrors, depends) {
|
function compileVerilator(filename, code, callback, nerrors, depends) {
|
||||||
|
// files come back from worker
|
||||||
global.postMessage = async function(msg) {
|
global.postMessage = async function(msg) {
|
||||||
try {
|
try {
|
||||||
if (msg.errors && msg.errors.length) {
|
if (msg.errors && msg.errors.length) {
|
||||||
|
@ -90,6 +92,7 @@ function compileVerilator(filename, code, callback, nerrors, depends) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// send files to worker for build
|
||||||
try {
|
try {
|
||||||
global.onmessage({
|
global.onmessage({
|
||||||
data:{
|
data:{
|
||||||
|
@ -116,19 +119,20 @@ function testVerilator(filename, disables, nerrors, depends) {
|
||||||
console.log(filename);
|
console.log(filename);
|
||||||
//if (depends) testIcarus(filename);
|
//if (depends) testIcarus(filename);
|
||||||
var csource = ab2str(fs.readFileSync(filename));
|
var csource = ab2str(fs.readFileSync(filename));
|
||||||
|
var header = '';
|
||||||
for (var i=0; i<(disables||[]).length; i++)
|
for (var i=0; i<(disables||[]).length; i++)
|
||||||
csource = "/* verilator lint_off " + disables[i] + " */\n" + csource;
|
header += "/* verilator lint_off " + disables[i] + " */ ";
|
||||||
compileVerilator(filename, csource, done, nerrors||0, depends);
|
compileVerilator(filename, header + "\n" + csource, done, nerrors||0, depends);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Verilog Worker', function() {
|
describe('Verilog Worker', function() {
|
||||||
|
|
||||||
var files = _fs.readdirSync('test/cli/verilog').filter(fn => fn.endsWith('.v'));
|
var files = _fs.readdirSync('test/cli/verilog').filter(fn => fn.endsWith('.v'));
|
||||||
files = files.slice(0,80);
|
//files = files.slice(0,75);
|
||||||
for (var fn of files) {
|
for (var fn of files) {
|
||||||
testVerilator('test/cli/verilog/' + fn,
|
testVerilator('test/cli/verilog/' + fn,
|
||||||
['UNDRIVEN','BLKSEQ','WIDTH','PINCONNECTEMPTY','SYNCASYNCNET','UNOPT','UNOPTFLAT','VARHIDDEN','EOFNEWLINE']
|
['UNDRIVEN','BLKSEQ','WIDTH','PINCONNECTEMPTY','SYNCASYNCNET','UNOPT','UNOPTFLAT','VARHIDDEN','EOFNEWLINE','ASSIGNDLY','CASEX','SYMRSVDWORD','STMTDLY','PROCASSWIRE']
|
||||||
);
|
);
|
||||||
global.onmessage({data:{reset:true}});
|
global.onmessage({data:{reset:true}});
|
||||||
}
|
}
|
||||||
|
@ -146,4 +150,10 @@ describe('Verilog Worker', function() {
|
||||||
testVerilator('presets/verilog/tile_renderer.v', null, null, ['tile_renderer.v', 'font_cp437_8x8.v', 'ram.v', 'hvsync_generator.v']);
|
testVerilator('presets/verilog/tile_renderer.v', null, null, ['tile_renderer.v', 'font_cp437_8x8.v', 'ram.v', 'hvsync_generator.v']);
|
||||||
testVerilator('presets/verilog/cpu6502.v');
|
testVerilator('presets/verilog/cpu6502.v');
|
||||||
|
|
||||||
|
}).afterAll(() => {
|
||||||
|
/*
|
||||||
|
heapdump.writeSnapshot((err, filename) => {
|
||||||
|
console.log("Heap dump written to", filename);
|
||||||
|
});
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
// DESCRIPTION: Verilator: Verilog Test module
|
|
||||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
|
||||||
// any use, without warranty, 2020 by Wilson Snyder.
|
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
|
||||||
|
|
||||||
module t(/*AUTOARG*/
|
|
||||||
// Outputs
|
|
||||||
y, d2, m2, d3, m3
|
|
||||||
);
|
|
||||||
output [3:0] y;
|
|
||||||
output [31:0] d2;
|
|
||||||
output [31:0] m2;
|
|
||||||
output [63:0] d3;
|
|
||||||
output [63:0] m3;
|
|
||||||
// bug775
|
|
||||||
// verilator lint_off WIDTH
|
|
||||||
assign y = ((0/0) ? 1 : 2) % 0;
|
|
||||||
|
|
||||||
// bug2460
|
|
||||||
reg [31:0] b;
|
|
||||||
assign d2 = $signed(32'h80000000) / $signed(b);
|
|
||||||
assign m2 = $signed(32'h80000000) % $signed(b);
|
|
||||||
reg [63:0] b3;
|
|
||||||
assign d3 = $signed(64'h80000000_00000000) / $signed(b3);
|
|
||||||
assign m3 = $signed(64'h80000000_00000000) % $signed(b3);
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
b = 32'hffffffff;
|
|
||||||
b3 = 64'hffffffff_ffffffff;
|
|
||||||
$write("*-* All Finished *-*\n");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
endmodule
|
|
|
@ -1,42 +0,0 @@
|
||||||
// DESCRIPTION: Verilator: Non-cutable edge in loop
|
|
||||||
//
|
|
||||||
// This code (stripped down from a much larger application) has a loop between
|
|
||||||
// the use of ready in the first two always blocks. However it should
|
|
||||||
// trivially trigger the $write on the first clk posedge.
|
|
||||||
//
|
|
||||||
// This is a regression test against issue 513.
|
|
||||||
//
|
|
||||||
// This file ONLY is placed into the Public Domain, for any use,
|
|
||||||
// without warranty, 2012 by Jeremy Bennett.
|
|
||||||
// SPDX-License-Identifier: CC0-1.0
|
|
||||||
|
|
||||||
module t (/*AUTOARG*/
|
|
||||||
// Inputs
|
|
||||||
clk
|
|
||||||
);
|
|
||||||
input clk;
|
|
||||||
|
|
||||||
reg ready;
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
ready = 1'b0;
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge ready) begin
|
|
||||||
if ((ready === 1'b1)) begin
|
|
||||||
$write("*-* All Finished *-*\n");
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge ready) begin
|
|
||||||
if ((ready === 1'b0)) begin
|
|
||||||
ready = 1'b1 ;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
ready = 1'b1;
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
Loading…
Reference in New Issue