Skip to content

Commit

Permalink
Merge pull request #3 from clash-lang/transfer-clash-testsuite
Browse files Browse the repository at this point in the history
Move over relevant clash-testsuite tests
  • Loading branch information
t-wallet authored Aug 26, 2024
2 parents e205083 + e1d612d commit 2dee5a3
Show file tree
Hide file tree
Showing 34 changed files with 3,873 additions and 4 deletions.
23 changes: 23 additions & 0 deletions clash-cores.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,26 @@ test-suite doctests
clash-cores,
doctest-parallel >= 0.2 && < 0.4,
filepath

test-suite cores-testsuite
import: basic-config
hs-source-dirs: test
type: exitcode-stdio-1.0
main-is: cores-testsuite.hs

build-depends:
base,
data-default,
directory,
extra,
filepath,
ghc,
process,
tasty >= 1.5,
tasty-hunit,
text,
clash-cores,
clash-ghc,
clash-lib,
clash-prelude,
clash-testsuite
16 changes: 15 additions & 1 deletion nix/nixpkgs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,19 @@ let
# Haskell overrides
haskellPackages = pkgs.haskell.packages.${haskell_compiler}.override {
overrides = self: super: {
# Add overrides here
# Ignore dependency bounds for tasty < 1.5
cabal2nix = pkgs.haskell.lib.doJailbreak super.cabal2nix;
quickcheck-instances = pkgs.haskell.lib.doJailbreak super.quickcheck-instances;
aeson = pkgs.haskell.lib.doJailbreak super.aeson;
time-compat = pkgs.haskell.lib.doJailbreak super.time-compat;
indexed-traversable-instances = pkgs.haskell.lib.doJailbreak super.indexed-traversable-instances;

tasty = super.tasty_1_5;

# Required by clash-testsuite. The tests of singletons-base-3.2 are
# unfortunately broken, so we have to override it like this.
singletons-base = pkgs.haskell.lib.dontCheck super.singletons-base;

circuit-notation =
self.callCabal2nix "circuit-notation" sources.circuit-notation {};
doctest-parallel =
Expand All @@ -36,6 +48,8 @@ let
self.callCabal2nix "clash-ghc" (sources.clash-compiler + "/clash-ghc") {};
clash-prelude-hedgehog =
self.callCabal2nix "clash-prelude" (sources.clash-compiler + "/clash-prelude-hedgehog") {};
clash-testsuite =
self.callCabal2nix "clash-testsuite" (sources.clash-compiler + "/tests") {};
tasty-hedgehog =
self.callCabal2nix "tasty-hedgehog" sources.tasty-hedgehog {};
hedgehog =
Expand Down
6 changes: 3 additions & 3 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"homepage": "https://clash-lang.org/",
"owner": "clash-lang",
"repo": "clash-compiler",
"rev": "aba55fed9f45711c8336935721a43d243f7f78c1",
"sha256": "1hrzp8g189v46qfr9ds7w6w0yj5w8y4im1pa3lf5vjx3z64v26qv",
"rev": "b14ff0ef2ccfad8854210a9035e9db1e32b3be07",
"sha256": "00gq0v4fi2dy13xchllxxhhjfpvvj0ig8cgp5y65c7zb7qw5b30y",
"type": "tarball",
"url": "https://github.com/clash-lang/clash-compiler/archive/aba55fed9f45711c8336935721a43d243f7f78c1.tar.gz",
"url": "https://github.com/clash-lang/clash-compiler/archive/b14ff0ef2ccfad8854210a9035e9db1e32b3be07.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz",
"version": "1.8.1"
},
Expand Down
322 changes: 322 additions & 0 deletions test/cores-testsuite.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}

module Main (main) where

import Prelude

import Clash.Annotations.Primitive (HDL(..))
import Data.Default (def)
import Data.List (intercalate)
import Data.List.Extra (trim)
import Data.Version (versionBranch)
import System.Directory
(getCurrentDirectory, doesDirectoryExist, makeAbsolute, setCurrentDirectory)
import System.Environment
import System.Info
import System.Process (readProcess)
import GHC.Conc (numCapabilities)
import GHC.Stack
import GHC.IO.Unsafe (unsafePerformIO)
import Text.Printf (printf)

import Test.Tasty
import Test.Tasty.Clash

-- | GHC version as major.minor.patch1. For example: 8.10.2.
ghcVersion3 :: String
ghcVersion3 =
#ifdef __GLASGOW_HASKELL_PATCHLEVEL2__
let ghc_p1 = __GLASGOW_HASKELL_PATCHLEVEL1__
ghc_p2 = __GLASGOW_HASKELL_PATCHLEVEL2__ in
case ghc_p2 of
0 ->
intercalate "." (map show (versionBranch compilerVersion <> [ghc_p1]))
_ ->
intercalate "." (map show (versionBranch compilerVersion <> [ghc_p1,ghc_p2]))
#else
let ghc_p1 = __GLASGOW_HASKELL_PATCHLEVEL1__ in
intercalate "." (map show (versionBranch compilerVersion <> [ghc_p1]))
#endif

-- Directory clash binary is expected to live in
cabalClashBinDir :: IO String
cabalClashBinDir = makeAbsolute rel_path
where
rel_path = printf templ platform ghcVersion3 (VERSION_clash_ghc :: String)
platform :: String -- XXX: Hardcoded
platform = case os of
"mingw32" -> arch <> "-windows"
_ -> arch <> "-" <> os
templ = "dist-newstyle/build/%s/ghc-%s/clash-ghc-%s/x/clash/build/clash/" :: String

-- | Set GHC_PACKAGE_PATH for local Cabal install. Currently hardcoded for Unix;
-- override by setting @store_dir@ to point to local cabal installation.
setCabalPackagePaths :: IO ()
setCabalPackagePaths = do
ch <- lookupEnv "store_dir"
storeDir <- case ch of
Just dir -> pure dir
Nothing -> case os of
"mingw32" -> pure "C:/cabal/store" -- default ghcup location
_ -> (<> "/.cabal/store") <$> getEnv "HOME"
here <- getCurrentDirectory
setEnv "GHC_PACKAGE_PATH" $
storeDir <> "/ghc-" <> ghcVersion3 <> "/package.db"
<> ":"
<> here <> "/dist-newstyle/packagedb/ghc-" <> ghcVersion3
<> ":"

-- | See 'compiledWith'
data RunWith
= Stack
| Cabal
| Global
deriving (Show, Eq)

-- | Detects Clash binary the testsuite should use (in order):
--
-- * If USE_GLOBAL_CLASH=1, use globally installed Clash
-- * If STACK_EXE is present, use Stack's Clash
-- * If dist-newstyle is present, use Cabal's Clash
-- * Use globally installed Clash
--
compiledWith :: RunWith
compiledWith = unsafePerformIO $ do
clash_global <- lookupEnv "USE_GLOBAL_CLASH"
stack_exe <- lookupEnv "STACK_EXE"
distNewstyleExists <- doesDirectoryExist "dist-newstyle"

pure $ case (clash_global, stack_exe, distNewstyleExists) of
(Just "1", Just _, _ ) -> error "Can't use global clash with 'stack run'"
(Just "1", _, _ ) -> Global
(_, Just _, _ ) -> Stack
(_, _ , True) -> Cabal
(_, _ , _ ) -> Global
{-# NOINLINE compiledWith #-}

-- | Set environment variables that allow Clash to be executed by simply calling
-- 'clash' without extra arguments.
setClashEnvs :: HasCallStack => RunWith -> IO ()
setClashEnvs Global = setEnv "GHC_ENVIRONMENT" "-"
setClashEnvs Stack = pure ()
setClashEnvs Cabal = do
binDir <- cabalClashBinDir
path <- getEnv "PATH"
let seperator = case os of { "mingw32" -> ";"; _ -> ":" }
setEnv "PATH" (binDir <> seperator <> path)
setCabalPackagePaths

clashTestRoot
:: [[TestName] -> TestTree]
-> TestTree
clashTestRoot testTrees =
clashTestGroup "." testTrees []

-- | `clashTestGroup` and `clashTestRoot` make sure that each test knows its
-- fully qualified test name at construction time. This is used to pass -i flags
-- to Clash as the test layout matches the layout in @shouldwork/@.
clashTestGroup
:: TestName
-> [[TestName] -> TestTree]
-> ([TestName] -> TestTree)
clashTestGroup testName testTrees =
\parentNames ->
testGroup testName $
zipWith ($) testTrees (repeat (testName : parentNames))

runClashTest :: IO ()
runClashTest = defaultMain $ clashTestRoot
[ clashTestGroup "test"
[ clashTestGroup "shouldfail"
[ clashTestGroup "Xilinx"
[ clashTestGroup "VIO"
[ runTest "DuplicateOutputNames" def{
hdlTargets=[VHDL]
, expectClashFail=Just (def, "Tried create a signal called 'a', but identifier generation returned")
}
, runTest "DuplicateInputNames" def{
hdlTargets=[VHDL]
, expectClashFail=Just (def, "Tried create a signal called 'a', but identifier generation returned")
}
, runTest "DuplicateInputOutputNames" def{
hdlTargets=[VHDL]
, expectClashFail=Just (def, "Tried create a signal called 'a', but identifier generation returned")
}
, runTest "OutputBusWidthExceeded" def{
hdlTargets=[VHDL, Verilog, SystemVerilog]
, expectClashFail=Just (def, "Probe signals must be been between 1 and 256 bits wide.")
}
, runTest "OutputProbesExceeded" def{
hdlTargets=[VHDL, Verilog, SystemVerilog]
, expectClashFail=Just (def, "At most 256 input/output probes are supported.")
}
, runTest "InputBusWidthExceeded" def{
hdlTargets=[VHDL, Verilog, SystemVerilog]
, expectClashFail=Just (def, "Probe signals must be been between 1 and 256 bits wide.")
}
, runTest "InputProbesExceeded" def{
hdlTargets=[VHDL, Verilog, SystemVerilog]
, expectClashFail=Just (def, "At most 256 input/output probes are supported.")
}
]
]
]
, clashTestGroup "shouldwork"
[ clashTestGroup "Xilinx"
[ runTest "TdpBlockRam" def
{ -- Compiling with VHDL gives:
-- https://github.com/clash-lang/clash-compiler/issues/2446
hdlTargets = [Verilog]
, hdlLoad = [Vivado]
, hdlSim = [Vivado]
, clashFlags=["-fclash-hdlsyn", "Vivado"]
, buildTargets=BuildSpecific [ "normalWritesTB", "writeEnableWritesTB" ]
}
, let _opts = def{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
-- addShortPLTB now segfaults :-(
, buildTargets=BuildSpecific [ "addBasicTB"
, "addEnableTB"
-- , "addShortPLTB"
, "subBasicTB"
, "mulBasicTB"
, "divBasicTB"
, "compareBasicTB"
, "compareEnableTB"
, "fromUBasicTB"
, "fromUEnableTB"
, "fromSBasicTB"
, "fromSEnableTB"
]
}
in runTest "Floating" _opts
, runTest "XpmCdcArraySingle" $ def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific ["tb" <> show n | n <- [(0::Int)..7]]
}
, runTest "XpmCdcGray" $ def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific ["tb" <> show n | n <- [(0::Int)..7]]
}
, runTest "XpmCdcHandshake" $ def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific ["tb" <> show n | n <- [(0::Int)..6]]
}
, runTest "XpmCdcPulse" $ def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific ["tb" <> show n | n <- [(0::Int)..7]]
}
, runTest "XpmCdcSingle" $ def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific ["tb" <> show n | n <- [(0::Int)..7]]
}
, runTest "XpmCdcSyncRst" $ def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific ["tb" <> show n | n <- [(0::Int)..7]]
}
, runTest "DnaPortE2" def
{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
}
, clashTestGroup "DcFifo"
[ let _opts =
def{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
}
in runTest "Basic" _opts
, let _opts = def{ hdlTargets=[VHDL, Verilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific [ "testBench_17_2"
, "testBench_2_17"
, "testBench_2_2"
]
}
in runTest "Lfsr" _opts
]
, let _opts =
def{ hdlTargets=[VHDL, Verilog, SystemVerilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific [ "noInputTrue"
, "noInputFalse"
, "noInputLow"
, "noInputHigh"
, "noInputSigned"
, "noInputUnsigned"
, "noInputBitVector"
, "noInputPair"
, "noInputVec"
, "noInputCustom"
, "noInputNested"
, "singleInputBool"
, "singleInputBit"
, "singleInputSigned"
, "singleInputUnsigned"
, "singleInputBitVector"
, "singleInputPair"
, "singleInputVec"
, "singleInputCustom"
, "singleInputNested"
, "multipleInputs"
, "inputsAndOutputs"
, "withSetName"
, "withSetNameNoResult"
]
}
in runTest "VIO" _opts
, let _opts =
def{ hdlTargets=[VHDL, Verilog, SystemVerilog]
, hdlLoad=[Vivado]
, hdlSim=[Vivado]
, buildTargets=BuildSpecific [ "testWithDefaultsOne"
, "testWithDefaultsThree"
, "testWithLefts"
, "testWithRights"
, "testWithRightsSameCu"
]
}
in runTest "Ila" _opts
, let _opts =
def{ hdlTargets=[VHDL, Verilog, SystemVerilog]
, buildTargets=BuildSpecific [ "testWithDefaultsOne"
, "testWithDefaultsThree"
, "testWithLefts"
, "testWithRights"
, "testWithRightsSameCu"
]
}
in outputTest "Ila" _opts
, outputTest "VIO" def{
hdlTargets=[VHDL]
, buildTargets=BuildSpecific ["withSetName", "withSetNameNoResult"]
}
, runTest "T2549" def{hdlTargets=[Verilog],hdlSim=[]}
]
] -- end shouldwork
]
] -- end .

main :: IO ()
main = do
projectRoot <- trim <$> readProcess "git" ["rev-parse", "--show-toplevel"] ""
setCurrentDirectory projectRoot
setEnv "TASTY_NUM_THREADS" (show numCapabilities)
setClashEnvs compiledWith
runClashTest
Loading

0 comments on commit 2dee5a3

Please sign in to comment.