From 9e2fc25486480ff431b69bca12459f398c2d9def Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Sat, 3 Oct 2026 16:45:07 +0200 Subject: [PATCH] verilog: parse warnings as warnings --- CHANGELOG.md | 1 + src/worker/tools/verilog.ts | 21 +++++++++++++++------ test/cli/testworker.js | 7 +++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e83371..e084e8dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ See [extension/CHANGELOG.md](extension/CHANGELOG.md). - Platform detection no longer confuses the Atari 8-bit targets: `atari.h` means the 800 (it is guarded by `__ATARI__`), `atari5200.h` means the 5200, and a folder named for a platform breaks a near-tie. - Emulators now run on a timeline: step back, seek, reverse run, `rbreak`, and deterministic replay with a replay-verification test that found determinism bugs in several platforms. - Step Over for C and assembly sources, a Breakpoints pane, and more breakpoint conditions. +- Verilator warnings (width mismatches, etc.) no longer fail the build and show as warnings; a Verilator error no longer also reports "tool called exit(1)". - Call Stack view renamed Call Graph, with clocks and more detail per line. - Compiler warnings no longer fail a build or get lost: `WorkerError` has an optional `severity`, and a successful build returns `warnings`. cc65/ca65/ld65 and SDCC warnings show as gutter markers in the IDE (not in the error dialog), as warnings in the VS Code Problems panel, and on stderr from `8bws` (`--no-warnings` hides them). SDCC 3 warnings no longer fail the build. - `buildpresets` lists compiler warnings per preset, flags a rising warning count against `--baseline`, and fails builds with warnings unless `--no-strict` is given. diff --git a/src/worker/tools/verilog.ts b/src/worker/tools/verilog.ts index d42478ac..8a495ab3 100644 --- a/src/worker/tools/verilog.ts +++ b/src/worker/tools/verilog.ts @@ -6,7 +6,7 @@ import { Assembler } from "../assembler"; import * as vxmlparser from '../../common/hdl/vxmlparser'; import { EmscriptenModule, emglobal, execMain, getWASMMemory, loadNative, moduleInstFn, print_fn, setupFS } from "../wasmutils"; import { getWorkFileAsString, BuildStep, BuildStepResult, gatherFiles, staleFiles, populateFiles, starttime, endtime, putWorkFile, anyTargetChanged, populateExtraFiles } from "../builder"; -import { makeErrorMatcher } from "../listingutils"; +import { makeErrorMatcher, hasErrors } from "../listingutils"; function detectModuleName(code: string) { var m = /^\s*module\s+(\w+_top)\b/m.exec(code) @@ -128,7 +128,13 @@ export function compileVerilator(step: BuildStep): BuildStepResult { if (staleFiles(step, [xmlPath])) { // TODO: %Error: Specified --top-module 'ALU' isn't at the top level, it's under another cell 'cpu' // TODO: ... Use "/* verilator lint_off BLKSEQ */" and lint_on around source to disable this message. - var match_fn = makeErrorMatcher(errors, /%(.+?): (.+?):(\d+)?[:]?\s*(.+)/i, 3, 4, step.path, 2); + var match_errs = makeErrorMatcher(errors, /%(.+?): (.+?):(\d+)?[:]?\s*(.+)/i, 3, 4, step.path, 2); + // verilator prefixes warnings with "%Warning-:" + var match_fn = (s: string) => { + var n = errors.length; + match_errs(s); + if (errors.length > n && /^%Warning/.test(s)) errors[n].severity = 'warning'; + }; var verilator_mod: EmscriptenModule = emglobal.verilator_bin({ instantiateWasm: moduleInstFn('verilator_bin'), noInitialRun: true, @@ -162,20 +168,23 @@ export function compileVerilator(step: BuildStep): BuildStepResult { var args = ["--cc", "-O3", "-DEXT_INLINE_ASM", "-DTOPMOD__" + topmod, "-D__8BITWORKSHOP__", "-Wall", - "-Wno-DECLFILENAME", "-Wno-UNUSED", "-Wno-EOFNEWLINE", "-Wno-PROCASSWIRE", + "-Wno-fatal", "-Wno-DECLFILENAME", "-Wno-UNUSED", "-Wno-EOFNEWLINE", "-Wno-PROCASSWIRE", "--x-assign", "fast", "--noassert", "--pins-sc-biguint", "--debug-check", // for XML output "--top-module", topmod, step.path] execMain(step, verilator_mod, args); } catch (e) { console.log(e); - errors.push({ line: 0, msg: "Compiler internal error: " + e }); + // exit(1) is just the symptom if verilator already reported errors + if (!hasErrors(errors)) { + errors.push({ line: 0, msg: "Compiler internal error: " + e }); + } } endtime("compile"); // remove boring errors errors = errors.filter(function (e) { return !/Exiting due to \d+/.exec(e.msg); }, errors); errors = errors.filter(function (e) { return !/Use ["][/][*]/.exec(e.msg); }, errors); - if (errors.length) { + if (hasErrors(errors)) { return { errors: errors }; } starttime(); @@ -203,7 +212,7 @@ export function compileVerilator(step: BuildStep): BuildStepResult { } return { output: xmlParser, - errors: errors, + warnings: errors, listings: listings, }; } diff --git a/test/cli/testworker.js b/test/cli/testworker.js index 4c40703c..c8a471eb 100644 --- a/test/cli/testworker.js +++ b/test/cli/testworker.js @@ -192,6 +192,13 @@ describe('Worker', function() { assert.ok(msg.warnings.length >= 1); assert.ok(msg.warnings.every(w => w.severity == 'warning' && w.line > 0)); }); + it('should return Verilator warnings on a successful build, marked as warnings', async function() { + var msg = await queryWorker({code:"module t_top(input clk, output reg [3:0] q);\n always @(posedge clk) q <= 5'd300;\nendmodule\n", platform:'verilog', tool:'verilator', path:'src.v', mainfile:true}); + assert.ok(!(msg.errors && msg.errors.length)); + assert.ok(msg.output); + assert.ok(msg.warnings.length >= 1); + assert.ok(msg.warnings.every(w => w.severity == 'warning' && w.line > 0)); + }); it('should NOT compile CC65 (link error)', function(done) { compile('cc65', 'extern void bad();\nint main() {\nbad();\nreturn 0;\n}', 'nes', done, 0, 0, 1, {ignoreErrorPath:true}); });