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

Synthesis fails for newtypes of types with multiple fields. #2698

Open
lmbollen opened this issue Mar 14, 2024 · 0 comments
Open

Synthesis fails for newtypes of types with multiple fields. #2698

lmbollen opened this issue Mar 14, 2024 · 0 comments

Comments

@lmbollen
Copy link
Contributor

Clash fails to generate a hdl for designs that contain newtype wrappers of e.g. records

Reproducer:

import Clash.Prelude
import Clash.Annotations.TH

data Foo a = Foo a
data Bar = Bar
  { a :: Int
  , b :: Int
  }

top :: Foo Bar
top = undefined

{-# ANN top (Synthesize
  { t_name   = "top"
  , t_inputs = []
  , t_output = PortProduct "" [PortProduct "" [PortName "a", PortName "b"]]
  })

Error:

ghci> main
GHC: Setting up GHC took: 0.093s
GHC: Compiling and loading modules took: 0.465s
Clash: Parsing and compiling primitives took 0.173s
Loading dependencies took 1.101s
Clash: Ignoring previously made caches
Clash: Compiling Main.top
Clash: Normalization took 0.
*** Exception: Saw a PortProduct in a Synthesize annotation:

  PortProduct "" [PortProduct "" [PortName "a",PortName "b"]]

but the port type:

  Product "Main.Bar" (Just ["a","b"]) [Signed 64,Signed 64]

is not a product!
CallStack (from HasCallStack):
  error, called at clash-lib/src/Clash/Netlist/Util.hs:1942:8 in main:Clash.Netlist.Util
  expandTopEntityOrErrM, called at clash-lib/src/Clash/Netlist/Util.hs:784:8 in main:Clash.Netlist.Util
  mkUniqueNormalized, called at clash-lib/src/Clash/Netlist.hs:273:9 in main:Clash.Netlist
  genComponentT, called at clash-lib/src/Clash/Netlist.hs:247:41 in main:Clash.Netlist
  genComponent, called at clash-lib/src/Clash/Netlist.hs:125:9 in main:Clash.Netlist
ghci> 

Error is generated by Clash.Netlist.Util.goPort, relevant arguments:
FilteredHwType:

FilteredHWType
    (Product "Main.Bar" (Just [ "a" , "b" ]) [ Signed 64 , Signed 64 ])
    [ [ ( False
        , FilteredHWType
            (Product "Main.Bar" (Just [ "a" , "b" ]) [ Signed 64 , Signed 64 ])
            [ [ ( False
                , FilteredHWType
                    (Signed 64) [ [ ( False , FilteredHWType (Signed 64) [] ) ] ]
                )
              , ( False
                , FilteredHWType
                    (Signed 64) [ [ ( False , FilteredHWType (Signed 64) [] ) ] ]
                )
              ]
            ]
        )
      ]
    ]

PortName:

PortProduct "" [ PortProduct "" [ PortName "a" , PortName "b" ] ]

The FilteredHwType is not considered a product by the isProduct function, causing a fall through.
Adjusting isProduct makes hdl generation succeed:

  -- Vector and RTree are hardcoded as product types, even when instantiated as
  -- /Vec 1 a/ or /RTree 0 a/ respectively.
  isProduct :: FilteredHWType -> Bool
  isProduct (FilteredHWType (CustomProduct {}) _) =
    -- CustomProducts are not yet support in mkTopInput/mkTopOutput so we can't treat
    -- them as product types.
    -- FIXME: Support CustomProduct in top entity annotations
    False
  isProduct (FilteredHWType (Vector {}) _) = True
  isProduct (FilteredHWType (RTree {}) _) = True
  ----------------------------------------------
  -- Introduced pattern match
  isProduct (FilteredHWType (Product _ _ _) [[(_, fwHwTy)]]) = isProduct fwHwTy
  ----------------------------------------------
  isProduct (FilteredHWType _ [(_:_:_)]) = True
  isProduct _ = False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant