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

Clash doesn't clear Id scopes when rendering different modules #2722

Open
martijnbastiaan opened this issue May 19, 2024 · 0 comments
Open
Labels

Comments

@martijnbastiaan
Copy link
Member

That is, a function primtive rendered in two modules primitive.vhdl and primitive_0.vhdl will generate variables x and x_0 respectively when asking for x. While usually not impactful, primitives such as a VIO and ILA rely on name generation to name their probes. In turn, this can cause problems when these VIOs/ILAs are used programmatically: i.e., where external scripts expect certain probe names to exist.

Reproducer:

{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}

-- | Test whether two instantiations of the same primitive rendered in their own
-- module can use the same local identifier.
module T2722 where

import Clash.Explicit.Prelude

import Clash.Annotations.Primitive (Primitive(..))
import Clash.Backend (blockDecl)
import Data.Monoid (Ap(getAp))

import qualified Clash.Netlist.Types as N
import qualified Clash.Netlist.Id as Id

bbTF :: N.TemplateFunction
bbTF = N.TemplateFunction used valid $ \_bbCtx -> do
  x <- Id.make "x"

  () <- case Id.toText x of
    "x" -> pure ()
    xName -> error $ "Unexpected name: " <> show xName <> ". Expected: x."

  getAp $ blockDecl x [N.NetDecl Nothing x N.Bit]
 where
  used    = [0,1]
  valid _ = True

{-# ANN bb (InlinePrimitive [minBound..] "[ { \"BlackBox\" : { \"name\" : \"T2722.bb\", \"kind\": \"Declaration\", \"workInfo\": \"Always\", \"format\": \"Haskell\", \"templateFunction\": \"T2722.bbTF\"}} ]") #-}
bb :: Signal System Bit
bb = pure low
{-# CLASH_OPAQUE bb #-}

-- | 'bbWrapper' is marked as opaque, so Clash will generate a separate HDL module
-- for it. Note that it accepts an extra (unused) argument to prevent Clash's
-- specialization from caching it.
bbWrapper :: Bit -> Signal System Bit
bbWrapper !_ = bb
{-# CLASH_OPAQUE bbWrapper #-}

topEntity :: Signal System Bit
topEntity = bbWrapper low + bbWrapper high

Gives:

$ rm -rf vhdl/ && cabal run clash -- -itests/shouldwork/Issues T2722 --vhdl -Wall -Werror -DCLASH_OPAQUE=OPAQUE
Resolving dependencies...
Loaded package environment from /home/martijn/code/clash-compiler/.ghc.environment.x86_64-linux-9.4.8
GHC: Setting up GHC took: 0.250s
GHC: Compiling and loading modules took: 1.201s
Hint: Interpreting T2722.bbTF
Clash: Parsing and compiling primitives took 1.546s
GHC+Clash: Loading modules cumulatively took 3.130s
Clash: Compiling T2722.topEntity
Clash: Normalization took 0.001s
Clash: Netlist generation took 0.000s

<no location info>: error:
    Clash error call:
    Unexpected name: "x_0". Expected: x.
    CallStack (from HasCallStack):
      error, called at tests/shouldwork/Issues/T2722.hs:23:14 in main:T2722
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant