10000 Bit width truncation due to signed int return type causes incorrect signal width interpretation · Issue #6023 · verilator/verilator · GitHub
[go: up one dir, main page]

Skip to content
Bit width truncation due to signed int return type causes incorrect signal width interpretation #6023
@sdjasj

Description

@sdjasj

Consider the following code test.v, which contains a signal with an extremely large bit-width (exceeding the range representable by a 32-bit int):

`timescale 1ns/1ps

module top (out0);
  output wire [32'hFFFF_FFFF:1] out0;

  assign out0 = 1;

  initial begin
    #10;
    $display("out0: %b", out0);
    $finish; 
  end

endmodule

When running the following commands:

verilator --binary -Wno-lint --timing test.v
./obj_dir/Vtest

The code compiles successfully (the excessively large bit-width seems to bypass Verilator’s width checks, such as Width of bit range is huge; vector of over 1 billion bits: or Value too wide for 32-bits expected in this context 36'haffffffff), and treats out0 as a 3-bit signal. The output is:

out0: 001

So it appears that somewhere in the code, a conversion from uint32_t to int occurs, which causes 32'hffff_ffff to be interpreted as -1.

I further looked into the source code and found the following problematic line:

const int width = nodep->elementsConst();

Here, the width value should ideally be of type uint32_t.

After further investigation, it turns out that the cause is the following functions, which return int instead:

verilator/src/V3AstNodeOther.h

Lines 2698 to 2710 in f74c67d

inline int leftConst() const VL_MT_STABLE;
inline int rightConst() const VL_MT_STABLE;
int hiConst() const VL_MT_STABLE {
const int l = leftConst();
const int r = rightConst();
return l > r ? l : r;
}
int loConst() const VL_MT_STABLE {
const int l = leftConst();
const int r = rightConst();
return l > r ? r : l;
}
int elementsConst() const VL_MT_STABLE { return hiConst() - loConst() + 1; }

A straightforward fix would be to change the return type of these functions to uint32_t. However, I’m not sure how extensive the impact would be on the rest of the codebase. If it's safe and has no side effects, I’d be happy to submit a PR to fix this.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0