From fb604109bff271f3d05856faf2b87431aa844476 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 14 Apr 2024 18:22:09 -0400 Subject: [PATCH] don't sign-extend signed unsized numbers with a leading 1 bit I'm opting for iverilog's interpretation of the specifications here. The commercial simulators I tested seem to agree. --- .github/workflows/main.yaml | 2 +- CHANGELOG.md | 2 ++ src/Language/SystemVerilog/AST/Number.hs | 7 ++++++- test/core/cast_literal.vh | 22 ++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 93379f6..5c1293b 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -41,7 +41,7 @@ jobs: - macOS-11 needs: build env: - IVERILOG_REF: 8ee1d56e1acbc130aa63da3c8ef0d535a551cf28 + IVERILOG_REF: f31d0dcbc5ddcd97e1e2e6f7bc7eb0f5a547fe16 steps: - uses: actions/checkout@v1 - name: Install Dependencies (macOS) diff --git a/CHANGELOG.md b/CHANGELOG.md index 588f320..5a7a6d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ ### Bug Fixes * Fixed an issue that prevented parsing tasks and functions with `inout` ports +* Fixed signed unsized literals with a leading 1 bit (e.g., `'sb1`, `'sh8f`) + incorrectly sign-extending in size and type casts * Fixed conflicting genvar names when inlining interfaces and modules that use them; all genvars are now given a design-wide unique name * Fixed byte order of strings in size casts diff --git a/src/Language/SystemVerilog/AST/Number.hs b/src/Language/SystemVerilog/AST/Number.hs index e5f2418..6744590 100644 --- a/src/Language/SystemVerilog/AST/Number.hs +++ b/src/Language/SystemVerilog/AST/Number.hs @@ -153,12 +153,17 @@ parseNormalized oversizedNumbers str = -- high-order X or Z is extended up to the size of the literal leadDigit = head digits - numDigits = length digits + numDigits = length digits + if isSignedUnsizedWithLeading1 then 1 else 0 leadDigitIsXZ = elem leadDigit xzDigits digitsExtended = if leadDigitIsXZ then replicate (sizeDigits - numDigits) leadDigit ++ digits else digits + isSignedUnsizedWithLeading1 = + maybeBase /= Nothing && + not leadDigitIsXZ && + signed && + digitToInt leadDigit >= div (baseSize base) 2 -- determine the number of digits needed based on the size sizeDigits = ((abs size) `div` bitsPerDigit) + sizeExtraDigit diff --git a/test/core/cast_literal.vh b/test/core/cast_literal.vh index 9152bac..898387b 100644 --- a/test/core/cast_literal.vh +++ b/test/core/cast_literal.vh @@ -47,6 +47,16 @@ `TEST_ALL(7'so0x) `TEST_ALL(7'sox1) `TEST_ALL(7'soz0) +`TEST_ALL('so7) +`TEST_ALL('so37) +`TEST_ALL('so47) +`TEST_ALL('so57) +`TEST_ALL('so07) +`TEST_ALL('o7) +`TEST_ALL('o37) +`TEST_ALL('o47) +`TEST_ALL('o57) +`TEST_ALL('o07) `TEST_ALL('bx) `TEST_ALL('ozx) @@ -58,6 +68,18 @@ `TEST_ALL('bzzz1) `TEST_ALL('ozzz1) `TEST_ALL('hzzz1) +`TEST_ALL('shf) +`TEST_ALL('sh6f) +`TEST_ALL('sh7f) +`TEST_ALL('sh8f) +`TEST_ALL('sh9f) +`TEST_ALL('sh0f) +`TEST_ALL('hf) +`TEST_ALL('h6f) +`TEST_ALL('h7f) +`TEST_ALL('h8f) +`TEST_ALL('h9f) +`TEST_ALL('h0f) `TEST_ALL(1'ox) `TEST_ALL(1'oz)