You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Normally, when a function recognised as a test bench makes use of a function recognised as a top entity, these two end up in separate directories (and VHDL libraries). However, when testBench passes the topEntity down to a called function, a new design unit inside the test bench output directory is created with a name based on topEntity, and testBench no longer uses the separate topEntity.
and testBench.vhdl only refers to vhdl/TBInline.testBench/topEntity_0.vhdl, there is no reference to vhdl/TBInline.topEntity/topEntity.vhdl.
topEntity_0.vhdl actually contains tb0, not just topEntity.
Adding INLINE on tb0 fixes the issue.
A certain minimum amount of complexity inside tb0 is needed to prevent automatic inlining, so I just wrote a bog-standard test bench to pass that bar.
The exact same thing happens when, instead of using functions named testBench and topEntity, we use functions with a defSyn and a TestBench annotation; it is not related to the magic names themselves.
The text was updated successfully, but these errors were encountered:
Note that there is a functional difference. The following code:
Click to expand code block
moduleTBInlinewhereimportClash.Explicit.PreludeimportClash.Explicit.TestbenchtypeTop=ClockSystem->ResetSystem->EnableSystem->SignalSystem (Unsigned8) ->SignalSystem (Unsigned8)
myReg::Top
myReg clk rst en = register clk rst en 0
{-# NOINLINE myReg #-}
top::Top
top = myReg
{-# NOINLINE top #-}
{-# ANN top (defSyn "top") #-}
tb0::Top->SignalSystemBool
tb0 top0 = done
where
testInput = stimuliGenerator clk rst $(listToVecTH [1::Unsigned8..10])
expectedOutput = outputVerifier' clk rst
$(listToVecTH [0::Unsigned8..10])
done = expectedOutput (top0 clk rst en testInput)
clk = tbClockGen (not<$> done)
rst = resetGen
en = enableGen
tb::SignalSystemBool
tb = tb0 top
{-# NOINLINE tb #-}
{-# ANN tb (TestBench 'top) #-}
will exercise the register primitive with ~ISACTIVEENABLE evaluating false because the enableGen is visible from myReg. But adding INLINE to tb0 so it uses the actual top entity will have ~ISACTIVEENABLE evaluate true because it is a proper enable line in that configuration. So the test bench exercises a different primitive code path than usual due to this issue.
(Note I chose annotations instead of special names in this variant just to have an example of that too).
Normally, when a function recognised as a test bench makes use of a function recognised as a top entity, these two end up in separate directories (and VHDL libraries). However, when
testBench
passes thetopEntity
down to a called function, a new design unit inside the test bench output directory is created with a name based ontopEntity
, andtestBench
no longer uses the separatetopEntity
.This code:
gives the following directory structure:
and
testBench.vhdl
only refers tovhdl/TBInline.testBench/topEntity_0.vhdl
, there is no reference tovhdl/TBInline.topEntity/topEntity.vhdl
.topEntity_0.vhdl
actually containstb0
, not justtopEntity
.Adding
INLINE
ontb0
fixes the issue.A certain minimum amount of complexity inside
tb0
is needed to prevent automatic inlining, so I just wrote a bog-standard test bench to pass that bar.The exact same thing happens when, instead of using functions named
testBench
andtopEntity
, we use functions with adefSyn
and aTestBench
annotation; it is not related to the magic names themselves.The text was updated successfully, but these errors were encountered: