fix(gen-verilog): signed-aware ordered comparison - #1994
Merged
Conversation
Verilog makes an ordered comparison (< <= > >=) UNSIGNED if either
operand is unsigned. A signed i8 (e.g. trend = -16 = 8'hF0) meeting an
unsigned const read as 240, so `trend > THRESHOLD` diverged from the
Rust/Zig/C backends, which promote both operands to a signed int before
comparing.
When at least one operand is signed, emit the comparison in the signed
domain with C integer-promotion semantics: the signed operand is wrapped
$signed(x) (Verilog sign-extends it into the wider signed comparison
context) and the unsigned operand is zero-extended one bit,
$signed({1'b0, x}), so its value stays non-negative. Unsigned/unsigned
pairs are emitted unchanged.
tri-net corpus: link_quality_monitor's degradation_detection flips to
passing -- the last codegen-side runtime divergence. Full 105-spec
icarus gate: 0 regressions.
FROZEN_HASH resealed.
Refs #1948
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Verilog makes an ordered comparison (
< <= > >=) unsigned if either operand is unsigned. A signedi8(e.g.trend = -16 = 8'hF0) meeting an unsigned const reads as 240, sotrend > THRESHOLDdiverged from the Rust/Zig/C backends, which promote both operands to a signedintbefore comparing.Fix
When at least one operand is signed, emit the comparison in the signed domain with C integer-promotion semantics:
$signed(x)— Verilog sign-extends it into the wider signed comparison context$signed({1'b0, x})— zero-extend one bit so the value stays non-negativeUnsigned/unsigned pairs are emitted unchanged. Example (
is_degrading):Validation
link_quality_monitor'sdegradation_detectionflips to passing — the last codegen-side runtime divergence in the tri-net corpusRefs #1948
🤖 Generated with Claude Code