Skip to content

Fix linter warnings detected by iverilog and add resize(foo,n) support#38

Open
ApexGP wants to merge 4 commits into
ldoolitt:masterfrom
ApexGP:feat/resize
Open

Fix linter warnings detected by iverilog and add resize(foo,n) support#38
ApexGP wants to merge 4 commits into
ldoolitt:masterfrom
ApexGP:feat/resize

Conversation

@ApexGP

@ApexGP ApexGP commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

This PR is meant to address two issues

Copilot AI review requested due to automatic review settings February 16, 2026 13:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates vhd2vl’s parsing/emission to (a) eliminate iverilog -Wall warnings in generated example outputs and (b) add translation support for resize(vec, n) into explicit Verilog extension/truncation.

Changes:

  • Add resize(foo, n) handling in the parser, emitting explicit zero-extend or truncation logic in Verilog.
  • Enhance conv_integer(...) handling in port maps by looking up formal port widths and emitting explicit 32-bit extension to avoid iverilog padding warnings.
  • Update example VHDL sources and committed translated Verilog examples, plus bump GHDL example compilation to --std=08.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vhd2vl.y Adds entity port tracking for formal-width lookup, introduces param_list, and implements resize(...) + port-map extension logic.
src/vhd2vl.l Ensures CONVFUNC_2 tokens carry the function name (needed to detect resize).
examples/resize.vhd New VHDL example covering resize extension/truncation behavior.
translated_examples/resize.v New expected translated Verilog for the resize example.
examples/conv_integer.vhd Expands test coverage for conv_integer in port maps across const/signal/port and widths.
translated_examples/conv_integer.v Updates expected translated Verilog to explicitly extend to 32-bit ports (avoids iverilog padding warnings).
examples/agg_risk_demo.vhd Adjusts example to avoid an always @* block with no sensitivities (adds real inputs).
translated_examples/agg_risk_demo.v Updates expected Verilog accordingly so always @* is sensitivity-driven.
examples/Makefile Uses VHDL-2008 mode (--std=08) when compiling examples with GHDL.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/vhd2vl.y Outdated
Comment on lines +732 to +735
sl = addsl(NULL, expr_to_sl(vec));
sl = addtxt(sl, "[");
sl = addval(sl, width_val - 1);
sl = addtxt(sl, ":0]");

Copilot AI Feb 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

build_resize() truncation emits vec[width_val-1:0], which assumes the source vector is 0-based. This will produce incorrect/out-of-range selects for signals declared with non-zero low bounds (the translator already emits such ranges, e.g. [15:8]). Consider carrying the source vrange (or at least its nlo) into build_resize and slicing [nlo+width_val-1:nlo] (or an equivalent part-select) instead of hardcoding :0.

Suggested change
sl = addsl(NULL, expr_to_sl(vec));
sl = addtxt(sl, "[");
sl = addval(sl, width_val - 1);
sl = addtxt(sl, ":0]");
/* Without knowing the original low index of 'vec', emitting
* [width_val-1:0] would only be correct for 0-based vectors
* and can result in out-of-range or incorrect selects when
* translating signals declared with non-zero low bounds.
* To avoid generating invalid Verilog, fall back to the
* unmodified expression here instead of slicing.
*/
sl = addsl(NULL, expr_to_sl(vec));

Copilot uses AI. Check for mistakes.
Comment thread src/vhd2vl.y
Comment on lines +710 to +714
if (e->op == 'S') {
sl = addsl(sl, inner);
sl = addtxt(sl, "[");
sl = addval(sl, src - 1);
sl = addtxt(sl, "]}},");

Copilot AI Feb 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signed extension in build_conv_portmap_ext() uses inner[src-1] as the sign bit, which assumes the vector’s MSB index equals (width-1). For vectors with non-zero low bounds (e.g. [15:8]) this points at the wrong bit and will sign-extend incorrectly. Use the declared MSB index from the symbol’s vrange (e.g. range->nhi) rather than (src-1).

Copilot uses AI. Check for mistakes.
Comment thread src/vhd2vl.y Outdated
sg = lookup(io_list, e->sl->data.txt);
if (!sg) {
sg = lookup(sig_list, e->sl->data.txt);
}

Copilot AI Feb 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_src_width() only looks up identifiers in io_list and sig_list, but resize(vec,w) should also work when vec is a VHDL constant (which is emitted as a Verilog parameter and is now tracked in param_list). Add a param_list lookup here so resize() can determine widths for constants/parameters too.

Suggested change
}
}
if (!sg) {
sg = lookup(param_list, e->sl->data.txt);
}

Copilot uses AI. Check for mistakes.
Comment thread src/vhd2vl.y
Comment on lines 2523 to 2525
map_item : mvalue {$$=$1;}
| NAME '=' '>' mvalue {
| NAME '=' '>' { portmap_ctx.formal=$1; } mvalue {
slist *sl;

Copilot AI Feb 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

portmap_ctx.formal is set for named associations but never cleared for positional map_item alternatives. This means a later positional port map (or a later positional item after a named one) can reuse a stale formal name and apply width-extension against the wrong port. Clear portmap_ctx.formal (and possibly compnt) when entering a new map_item that is positional, or immediately after finishing each map_item.

Copilot uses AI. Check for mistakes.
- Use `vrange->nlo` for truncation in `buiild_resize()` when known
- Add `param_list` lookup in `get_src_width()`
- Fix sign exts for vecs with non-zero low bounds
@ApexGP

ApexGP commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

Hi @ldoolitt,
I've pushed commit 85d89a3 to address a few edge cases I encountered regarding port mapping and width evaluation:

  • Port map context cleanup : I updated the handling of portmap_ctx.formal to ensure it is cleared when entering a PORT MAP and between individual items. This prevents positional ports from inheriting stale formal metadata, which previously led to incorrect width extensions.
  • Width and Resize logic : get_src_width() now supports lookups for VHDL constants. Additionally, build_resize() has been refined to fall back to the unmodified expression when nlo is unknown, while correctly maintaining w-1:0 indexing for cases where nlo=0.
  • Sign extension fix : In build_conv_portmap_ext(), I've switched to using the declared MSB (nhi) instead of the assumed src-1. This fixes sign extension issues for vectors with non-zero lower bounds (e.g., 15:8).

Looking forward to your thoughts!

@ldoolitt

Copy link
Copy Markdown
Owner

Small patch const1.txt to make your work const-correct.
I still need to study your use of bison midrule actions.

@ApexGP

ApexGP commented Feb 16, 2026

Copy link
Copy Markdown
Contributor Author

Hi @ldoolitt,
Following up on the changes in 85d89a3, I wanted to provide some context on why I introduced Bison midrule actions in vhd2vl.y.

The core issue was managing the portmap_ctx state during the recursive parsing of port maps. Since the translation of mvalue (specifically for CONVFUNC_1 logic) depends on knowing the target formal port's width, the context must be synchronized before the mvalue sub-rule is reduced.

Here is a breakdown of the specific actions:

  • Context Initialization (#Line 1951 and #Line 1963): In the a_body rules for PORT MAP, I added actions to set portmap_ctx.compnt and clear portmap_ctx.formal immediately after the open parenthesis. This ensures a clean state before the map_list parser begins.

  • Preventing Metadata Leakage (#Line 2546): In the map_list recursive rule, I now clear portmap_ctx.formal between items. This handles the edge case where a positional association follows a named association, preventing the positional item from "inheriting" the previous item's formal name and applying the wrong width extension.

  • Late-Bound Formal Mapping (#Line 2556): For named associations (NAME '=>' mvalue), I set portmap_ctx.formal as a midrule action right before mvalue. This allows any conversion functions within mvalue to look up the correct port width and perform the necessary resize or sign-extension.

According to the Bison documentation, these midrule actions are executed as soon as the preceding symbols are shifted, which is exactly what we need to ensure the context is ready for the nested expressions.

LMK if this approach aligns with your vision for the parser's state management.

@ApexGP

ApexGP commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

Hi @ldoolitt, just following up on this PR. All CI and linter checks are green. I've also verified the y.output to ensure these midrule actions didn't introduce new grammar conflicts (maintaining 3 shift/reduces). LMK if you need any further clarification!

@ApexGP

ApexGP commented Mar 5, 2026

Copy link
Copy Markdown
Contributor Author

See #39 . Hi @ldoolitt , I'm just considering whether to fix this within this PR.

@ApexGP

ApexGP commented Mar 5, 2026

Copy link
Copy Markdown
Contributor Author

You can find the latest patch here.

@ApexGP

ApexGP commented Mar 8, 2026

Copy link
Copy Markdown
Contributor Author

See #39 . Hi @ldoolitt , I'm just considering whether to fix this within this PR.

Hi @ldoolitt,

I realized the previous scope of this PR might have been too broad. To make the review process more manageable, I’ve moved the iverilog v13.x compatibility fixes to a separate branch.

I've also performed a final cleanup of the remaining commits to improve code quality and maintainability:

  • Renamed the traversal cursor to node to avoid potential aliasing with the output slist *sl in build_conv_portmap_ext.

  • Added a stderr warning for resize() truncation when nlo cannot be determined, replacing the previous silent fallback to [w-1:0].

  • Explicitly tagged signed/unsigned limitations in build_resize as a KNOWN LIMITATION.

  • Extracted get_src_sglist() to eliminate redundant symbol-table lookups shared between build_resize and get_src_width.

  • Ensured portmap_ctx.compnt is cleared after each PORT MAP to prevent stale component metadata from leaking into subsequent instantiations.

  • Simplified the loop logic in lookup_formal_width by replacing the empty-body for-loop with a more standard while-loop.

Looking forward to your feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants