MikePopoloski / slang

SystemVerilog compiler and language services
MIT License
558 stars 122 forks source link

-16'sd32768 is causing "vector literal too large error" #877

Closed udif closed 5 months ago

udif commented 5 months ago

I started this PR hoping to complete it with the bug report, but it seems that slang first parses 16'sd32768, correctly assigning it a width of 17, and only then applies the unary minus, or at least that's what I think I figured out from the AST and printf-style debug code:

I put this in SVint.h:171 onwards:

            if (value < 0) {
                bitWidth = bitwidth_t(64 - std::countl_one(val) + 1);
                std::cout << "neg!\n";
            } else {
                bitWidth = bitwidth_t(64 - std::countl_zero(val) + 1);
                std::cout << "pos!\n";
            }

And ran the following code:

module t;
int t = -1;
wire [15:0]x = -16'sd32768;
endmodule

The code above only triggered the "pos" code path. When is the "neg" code path ever used?

My best guess so far is a fix around here in OperatorExpressions.cpp:

        case SyntaxKind::UnaryMinusExpression:
            // Supported for both integral and real types. Result is same as input type.
            good = type->isNumeric();
            result->type = type;
            break;

Probably need to check the type and if it is constant integral type reduce its width by 1 if it is -2^N.

udif commented 5 months ago

Closing because this is not a bug. My mistake.