diff --git a/package-lock.json b/package-lock.json index b7ae8b37..c727a8c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "electron": "^9.4.0", "electron-packager": "^15.2.0", "file-saver": "^2.0.5", + "heapdump": "^0.3.15", "jsdom": "^12.2.0", "jsfuzz": "^1.0.14", "jszip": "^3.5.0", @@ -3134,6 +3135,19 @@ "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": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -4725,6 +4739,12 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "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": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -10128,6 +10148,15 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "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": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -11397,6 +11426,12 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "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": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", diff --git a/package.json b/package.json index 4f7207a0..034e9cef 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "electron": "^9.4.0", "electron-packager": "^15.2.0", "file-saver": "^2.0.5", + "heapdump": "^0.3.15", "jsdom": "^12.2.0", "jsfuzz": "^1.0.14", "jszip": "^3.5.0", diff --git a/src/common/hdl/hdlwasm.ts b/src/common/hdl/hdlwasm.ts index 8f393b14..b356819f 100644 --- a/src/common/hdl/hdlwasm.ts +++ b/src/common/hdl/hdlwasm.ts @@ -371,7 +371,7 @@ export class HDLModuleWASM implements HDLModuleRunner { //console.log(this.bmod.emitText()); //this.bmod.optimize(); if (!this.bmod.validate()) { - console.log(this.bmod.emitText()); + //console.log(this.bmod.emitText()); 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); } _shiftr2wasm(e: HDLBinop) { - // TODO: signed? 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) { return this.binop(e, this.i3264(e.dtype).add); } @@ -1050,6 +1052,9 @@ export class HDLModuleWASM implements HDLModuleRunner { _mul2wasm(e: HDLBinop) { 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) { return this.binop(e, this.i3264(e.dtype).rem_u); } diff --git a/src/common/hdl/vxmlparser.ts b/src/common/hdl/vxmlparser.ts index 7b99b8df..6254c28c 100644 --- a/src/common/hdl/vxmlparser.ts +++ b/src/common/hdl/vxmlparser.ts @@ -116,7 +116,12 @@ export class VerilogXMLParser implements HDLUnit { this.dtypes['IData'] = {left:31, right:0}; this.dtypes['SData'] = {left:15, 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['integer'] = {left:31, right:0}; + this.dtypes['longint'] = {left:63, right:0}; + this.dtypes['time'] = {left:63, right:0}; } defer(fn: () => void) { @@ -522,6 +527,9 @@ export class VerilogXMLParser implements HDLUnit { visit_constpool(node: XMLNode) { } + visit_comment(node: XMLNode) { + } + expectChildren(node: XMLNode, low: number, high: number) { if (node.children.length < low || node.children.length > high) throw new CompileError(node, `expected between ${low} and ${high} children`); diff --git a/src/worker/workermain.ts b/src/worker/workermain.ts index af646d92..23418ada 100644 --- a/src/worker/workermain.ts +++ b/src/worker/workermain.ts @@ -15,6 +15,18 @@ const ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; var _WASM_module_cache = {}; 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) { var module = _WASM_module_cache[module_id]; if (!module) { @@ -1770,10 +1782,11 @@ function compileVerilator(step:BuildStep) { var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?):(\d+)?[:]?\s*(.+)/i, 3, 4, step.path, 2); var verilator_mod = emglobal.verilator_bin({ instantiateWasm: moduleInstFn('verilator_bin'), - noInitialRun:true, - noExitRuntime:true, - print:print_fn, - printErr:match_fn, + noInitialRun: true, + noExitRuntime: true, + print: print_fn, + printErr: match_fn, + wasmMemory: getWASMMemory(), // reuse memory //INITIAL_MEMORY:256*1024*1024, }); var code = getWorkFileAsString(step.path); diff --git a/test/cli/testverilog.js b/test/cli/testverilog.js index 7ae74258..1b8f711d 100644 --- a/test/cli/testverilog.js +++ b/test/cli/testverilog.js @@ -5,6 +5,7 @@ var _path = require('path') var _cproc = require('child_process'); var fs = require('fs'); var wtu = require('./workertestutils.js'); +var heapdump = require("heapdump"); createTestDOM(); @@ -66,6 +67,7 @@ function testPerf(msg) { } function compileVerilator(filename, code, callback, nerrors, depends) { + // files come back from worker global.postMessage = async function(msg) { try { if (msg.errors && msg.errors.length) { @@ -90,6 +92,7 @@ function compileVerilator(filename, code, callback, nerrors, depends) { } } }; + // send files to worker for build try { global.onmessage({ data:{ @@ -116,19 +119,20 @@ function testVerilator(filename, disables, nerrors, depends) { console.log(filename); //if (depends) testIcarus(filename); var csource = ab2str(fs.readFileSync(filename)); + var header = ''; for (var i=0; i<(disables||[]).length; i++) - csource = "/* verilator lint_off " + disables[i] + " */\n" + csource; - compileVerilator(filename, csource, done, nerrors||0, depends); + header += "/* verilator lint_off " + disables[i] + " */ "; + compileVerilator(filename, header + "\n" + csource, done, nerrors||0, depends); }); } describe('Verilog Worker', function() { 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) { 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}}); } @@ -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/cpu6502.v'); +}).afterAll(() => { +/* + heapdump.writeSnapshot((err, filename) => { + console.log("Heap dump written to", filename); + }); +*/ }); diff --git a/test/cli/verilog/t_math_div0.v b/test/cli/verilog/t_math_div0.v deleted file mode 100644 index 2612c5fb..00000000 --- a/test/cli/verilog/t_math_div0.v +++ /dev/null @@ -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 diff --git a/test/cli/verilog/t_order_loop_bad.v b/test/cli/verilog/t_order_loop_bad.v deleted file mode 100644 index 9b4c0175..00000000 --- a/test/cli/verilog/t_order_loop_bad.v +++ /dev/null @@ -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