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
That is, a function
primtive
rendered in two modulesprimitive.vhdl
andprimitive_0.vhdl
will generate variablesx
andx_0
respectively when asking forx
. 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:
Gives: