-
Notifications
You must be signed in to change notification settings - Fork 154
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
No inlining let-bound global vars with clock types #2846
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ADDED: `Distributive` and `Representable` instances for `Vec` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
FIXED: Clash generates illegal Verilog names [#2845](https://github.com/clash-lang/clash-compiler/issues/2845) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -155,7 +155,18 @@ isWorkFreeClockOrResetOrEnable tcm e = | |
if isClockOrReset tcm eTy || isEnable tcm eTy then | ||
case collectArgs e of | ||
(Prim p,_) -> Just (primName p == Text.showt 'removedArg) | ||
(Var _, []) -> Just True | ||
-- Only local variables with a clock type are work-free. When it is a global | ||
-- variable, it is probably backed by a clock generator, which is definitely | ||
-- not work-free. | ||
-- | ||
-- Inlining let-bindings referencing a global variable with a clock type | ||
-- can sometimes lead to the post-normalization flattening stage to generate | ||
-- code that violates the invariants of the netlist generation stage. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you remember which invariants? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We cannot have let-expressions appear in the argument position of an application. |
||
-- Especially when this global binder is defined recursively such as when | ||
-- using `tbClockGen`. | ||
-- This then ultimately leads to bad verilog names being generated as | ||
-- reported in: https://github.com/clash-lang/clash-compiler/issues/2845 | ||
(Var v, []) -> Just (isLocalId v) | ||
(Data _, [_dom, Left (stripTicks -> Data _)]) -> Just True -- For Enable True/False | ||
(Literal _,_) -> Just True | ||
_ -> Just False | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module T2845 where | ||
|
||
import Clash.Explicit.Prelude | ||
import Clash.Explicit.Testbench | ||
|
||
topEntity :: | ||
Signal System (Unsigned 8) | ||
topEntity = cntr + x | ||
where | ||
cntr = register clk noReset enableGen 0 0 | ||
x = register clk noReset enableGen 100 0 | ||
done = (== 100) <$> cntr | ||
clk = tbClockGen $ not <$> done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The local variable distinction feel arbitrary to me.
Given:
As I understand it, you're saying here it is ok for bindConstantVar to replace
clkA
inside of[...]
withclkLocal
, but notclkB
withclkGlobal
.Is that what you're saying?
And if so, why?
They seem equivalent to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's what I'm saying. Inlining
clkA
everywhere will not make the circuitf
any larger (perform work). InliningclkB
everywhere will make the circuitf
larger, because it will have duplicated calls to what will ultimately beclockGen
.