Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix literal rendering of Index values #2816

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

leonschoorl
Copy link
Member

@leonschoorl leonschoorl commented Oct 1, 2024

There was confusion between the size in bits and the type level argument to Index.
Causing it to use way too big numbers in the overflow calculation.

Fixes #2813

Still TODO:

  • Write a changelog entry (see changelog/README.md)
  • Check copyright notices are up to date in edited files

@leonschoorl
Copy link
Member Author

This fixes the hang that Felix experienced.

But I've still left this as a draft, as the overflow behaviour still isn't right, or at least not the same as in Haskell.

topEntity = 6 :: Index 5

Evaluating this in Haskell produces:

*** Exception: X: Clash.Sized.Index: result 6 is out of bounds: [0..4]

But clash will just generate HDL with the 6 in it:

  assign result = 3'd6;

Should it just produce the same HDL as if one would call errorX?
So:

  assign result = {3 {1'bx}};

or:

  result <= Index_topEntity_types.index_5'(0 to 2 => '-');

There was confusion between the size in bits and the type level argument to Index.

Fixes #2813
@leonschoorl leonschoorl force-pushed the fix-index-lit-rendering-verilog branch from 1bc05cd to af3f884 Compare October 1, 2024 12:55
@leonschoorl leonschoorl changed the title Fix (System)Verilog literal rendering of Index values Fix literal rendering of Index values Oct 1, 2024
@DigitalBrains1
Copy link
Member

But I've still left this as a draft, as the overflow behaviour still isn't right, or at least not the same as in Haskell.

Should it just produce the same HDL as if one would call errorX? So:

Let me just note that the contract is "When Clash produces an XException, the HDL can produce any value whatsoever". So it's law-abiding.

I'll not touch the issue whether it's desired.

@leonschoorl leonschoorl marked this pull request as ready for review October 1, 2024 12:57
@leonschoorl
Copy link
Member Author

I've now added the overflow detection too

@@ -1228,7 +1228,9 @@ expr_ _ (BlackBoxE pNm _ _ _ _ bbCtx _)
expr_ _ (BlackBoxE pNm _ _ _ _ bbCtx _)
| pNm == "Clash.Sized.Internal.Index.fromInteger#"
, [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
= exprLitSV (Just (Index (fromInteger n),fromInteger n)) i
, Just k <- clogBase 2 n
, let k' = max 1 k
Copy link
Member

Choose a reason for hiding this comment

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

When would k be zero in this code path?

I feel like that only happens for types like Index 1 which shouldn't render in the first place?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was basically copying what the VHDL backend does:

expr_ _ (BlackBoxE pNm _ _ _ _ bbCtx _)
| pNm == "Clash.Sized.Internal.Index.fromInteger#"
, [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
, Just k <- clogBase 2 n
, let k' = max 1 k
= exprLit (Just (Unsigned k',k')) i

Copy link
Member Author

Choose a reason for hiding this comment

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

But I think you're right

Copy link
Member

Choose a reason for hiding this comment

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

That code was added in version 0.6.15 6b365dc#diff-d636015ead3ec91b11144d7f18c90be9133810ab83457b3649a91e046cfae73fR647

Which might be from a time before we elided 0-bit values?

Copy link
Member Author

@leonschoorl leonschoorl Oct 10, 2024

Choose a reason for hiding this comment

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

Yeah probably.

I had seen that, at least in simple cases clash, removes Index 1 literals because they're 0 bits wide values.
But I'm wasn't sure if there was some code path I didn't foresee. And assumed the author of that code in VHDL.hs knew what they were doing.

You want me to take out the clogBase?

@leonschoorl leonschoorl force-pushed the fix-index-lit-rendering-verilog branch from af3f884 to d7150eb Compare October 1, 2024 14:47
Copy link
Member

@christiaanb christiaanb left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -0,0 +1,2 @@
FIXED: Clash hanging when rendering `Index n` literals, for large values of `n` [#2813](https://github.com/clash-lang/clash-compiler/issues/2813)
FIXED: Render overflowed Index literals as errors
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
FIXED: Render overflowed Index literals as errors
FIXED: Render overflowed Index literals as don't-cares in HDL

?

Maybe that's not good either, but I worry people might not understand what "render as an error" means. I'd also like to emphasise that we're talking about HDL here for clarity.

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

Successfully merging this pull request may close these issues.

The power of Index
3 participants