diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | default.nix | 32 | ||||
-rw-r--r-- | nix/hedgehog-fn.nix | 17 | ||||
-rw-r--r-- | nix/parser-combinators.nix | 10 | ||||
-rw-r--r-- | nix/tomland.nix | 33 | ||||
-rw-r--r-- | release.nix | 17 | ||||
-rw-r--r-- | shell.nix | 25 | ||||
-rw-r--r-- | src/VeriFuzz/Verilog/Gen.hs | 65 | ||||
-rw-r--r-- | stack.yaml | 7 |
9 files changed, 184 insertions, 26 deletions
@@ -2,9 +2,13 @@ TAGS *.jou *.log +*~ +cabal.project.local # Folders .stack-work .shelly failed output* +.ghc* +dist*
\ No newline at end of file diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..9155713 --- /dev/null +++ b/default.nix @@ -0,0 +1,32 @@ +{ mkDerivation, alex, array, base, binary, blaze-html, bytestring +, Cabal, cabal-doctest, cryptonite, deepseq, DRBG, exceptions, fgl +, fgl-visualize, filepath, gitrev, hedgehog, hedgehog-fn, lens +, lifted-base, memory, monad-control, optparse-applicative, parsec +, prettyprinter, random, recursion-schemes, shakespeare, shelly +, stdenv, tasty, tasty-hedgehog, tasty-hunit, template-haskell +, text, time, tomland, transformers, transformers-base +}: +mkDerivation { + pname = "verifuzz"; + version = "0.2.0.0"; + src = ./.; + isLibrary = true; + isExecutable = true; + setupHaskellDepends = [ base Cabal cabal-doctest ]; + libraryHaskellDepends = [ + array base binary blaze-html bytestring cryptonite deepseq DRBG + exceptions fgl fgl-visualize filepath gitrev hedgehog lens + lifted-base memory monad-control optparse-applicative parsec + prettyprinter random recursion-schemes shakespeare shelly + template-haskell text time tomland transformers transformers-base + ]; + libraryToolDepends = [ alex ]; + executableHaskellDepends = [ base ]; + testHaskellDepends = [ + base fgl hedgehog hedgehog-fn lens parsec shakespeare tasty + tasty-hedgehog tasty-hunit text + ]; + homepage = "https://github.com/ymherklotz/VeriFuzz#readme"; + description = "Random verilog generation and simulator testing"; + license = stdenv.lib.licenses.bsd3; +} diff --git a/nix/hedgehog-fn.nix b/nix/hedgehog-fn.nix new file mode 100644 index 0000000..0bf9279 --- /dev/null +++ b/nix/hedgehog-fn.nix @@ -0,0 +1,17 @@ +{ mkDerivation, base, contravariant, hedgehog, stdenv, transformers +}: +mkDerivation { + pname = "hedgehog-fn"; + version = "0.6"; + sha256 = "fb02b67fba97e24c226feba010d2b308934c54e20a0723b6ea7e4eb199f02176"; + revision = "1"; + editedCabalFile = "19v7amg8l6s1gadnya8nxkcbi0vd3wqc7h6gvqvs099qaqm7zbb1"; + isLibrary = true; + isExecutable = true; + libraryHaskellDepends = [ + base contravariant hedgehog transformers + ]; + homepage = "https://github.com/qfpl/hedgehog-fn"; + description = "Function generation for `hedgehog`"; + license = stdenv.lib.licenses.bsd3; +} diff --git a/nix/parser-combinators.nix b/nix/parser-combinators.nix new file mode 100644 index 0000000..d1baab9 --- /dev/null +++ b/nix/parser-combinators.nix @@ -0,0 +1,10 @@ +{ mkDerivation, base, stdenv }: +mkDerivation { + pname = "parser-combinators"; + version = "1.1.0"; + sha256 = "ac7642972b18a47c575d2bcd0b2f6c34f33ca2ed3adb28034420d09ced823e91"; + libraryHaskellDepends = [ base ]; + homepage = "https://github.com/mrkkrp/parser-combinators"; + description = "Lightweight package providing commonly useful parser combinators"; + license = stdenv.lib.licenses.bsd3; +} diff --git a/nix/tomland.nix b/nix/tomland.nix new file mode 100644 index 0000000..e771e20 --- /dev/null +++ b/nix/tomland.nix @@ -0,0 +1,33 @@ +{ mkDerivation, aeson, base, bytestring, containers, deepseq +, directory, gauge, hashable, hedgehog, hspec-megaparsec, htoml +, htoml-megaparsec, markdown-unlit, megaparsec, mtl, parsec +, parser-combinators, stdenv, tasty, tasty-discover, tasty-hedgehog +, tasty-hspec, tasty-silver, text, time, toml-parser, transformers +, unordered-containers +}: +mkDerivation { + pname = "tomland"; + version = "1.1.0.1"; + sha256 = "51cde31c25056c6a0714758eb782bda0c019bdd2ef58f29baf6364cbf6451f46"; + isLibrary = true; + isExecutable = true; + libraryHaskellDepends = [ + base bytestring containers deepseq hashable megaparsec mtl + parser-combinators text time transformers unordered-containers + ]; + executableHaskellDepends = [ base text time unordered-containers ]; + executableToolDepends = [ markdown-unlit ]; + testHaskellDepends = [ + base bytestring containers directory hashable hedgehog + hspec-megaparsec megaparsec tasty tasty-hedgehog tasty-hspec + tasty-silver text time unordered-containers + ]; + testToolDepends = [ tasty-discover ]; + benchmarkHaskellDepends = [ + aeson base deepseq gauge htoml htoml-megaparsec parsec text time + toml-parser + ]; + homepage = "https://github.com/kowainik/tomland"; + description = "Bidirectional TOML serialization"; + license = stdenv.lib.licenses.mpl20; +} diff --git a/release.nix b/release.nix new file mode 100644 index 0000000..d025a5b --- /dev/null +++ b/release.nix @@ -0,0 +1,17 @@ +let + config = { + packageOverrides = pkgs: rec { + haskellPackages = pkgs.haskellPackages.override { + overrides = haskellPackagesNew: haskellPackagesOld: rec { + hedgehog-fn = haskellPackagesNew.callPackage ./nix/hedgehog-fn.nix {}; + tomland = haskellPackagesNew.callPackage ./nix/tomland.nix {}; + parser-combinators = haskellPackagesNew.callPackage ./nix/parser-combinators.nix {}; + }; + }; + }; + }; + pkgs = import <nixpkgs> { inherit config; }; + +in +{ verifuzz = pkgs.haskellPackages.callPackage ./. { }; +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..733234f --- /dev/null +++ b/shell.nix @@ -0,0 +1,25 @@ +{ compiler ? "default", doBenchmark ? false }: + +let + config = { + packageOverrides = pkgs: rec { + haskellPackages = pkgs.haskellPackages.override { + overrides = haskellPackagesNew: haskellPackagesOld: rec { + hedgehog-fn = haskellPackagesNew.callPackage ./nix/hedgehog-fn.nix {}; + tomland = haskellPackagesNew.callPackage ./nix/tomland.nix {}; + parser-combinators = haskellPackagesNew.callPackage ./nix/parser-combinators.nix {}; + }; + }; + }; + }; + pkgs = import <nixpkgs> { inherit config; }; + + haskellPackages = if compiler == "default" + then pkgs.haskellPackages + else pkgs.haskell.packages.${compiler}; + + variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id; + + drv = variant (haskellPackages.callPackage (import ./.) {}); +in + if pkgs.lib.inNixShell then drv.env else drv diff --git a/src/VeriFuzz/Verilog/Gen.hs b/src/VeriFuzz/Verilog/Gen.hs index 0a6ece5..f08e5a6 100644 --- a/src/VeriFuzz/Verilog/Gen.hs +++ b/src/VeriFuzz/Verilog/Gen.hs @@ -11,6 +11,7 @@ Various useful generators. -} {-# LANGUAGE TemplateHaskell #-} +{-# OPTIONS_GHC -Wno-unused-imports #-} module VeriFuzz.Verilog.Gen ( -- * Generation methods @@ -22,18 +23,18 @@ module VeriFuzz.Verilog.Gen ) where -import Control.Lens hiding ( Context ) -import Control.Monad ( replicateM ) -import Control.Monad.Trans.Class ( lift ) -import Control.Monad.Trans.Reader - hiding ( local ) +import Control.Lens hiding (Context) +import Control.Monad (replicateM) +import Control.Monad.Trans.Class (lift) +import Control.Monad.Trans.Reader hiding (local) import Control.Monad.Trans.State.Strict -import Data.Foldable ( fold ) -import Data.Functor.Foldable ( cata ) -import qualified Data.Text as T -import Hedgehog ( Gen ) -import qualified Hedgehog.Gen as Hog -import qualified Hedgehog.Range as Hog +import Data.Foldable (fold) +import Data.Functor.Foldable (cata) +import Data.List (foldl') +import qualified Data.Text as T +import Hedgehog (Gen) +import qualified Hedgehog.Gen as Hog +import qualified Hedgehog.Range as Hog import VeriFuzz.Config import VeriFuzz.Internal import VeriFuzz.Verilog.AST @@ -42,6 +43,10 @@ import VeriFuzz.Verilog.Eval import VeriFuzz.Verilog.Internal import VeriFuzz.Verilog.Mutate +-- Temporary imports +import Debug.Trace +import VeriFuzz.Verilog.CodeGen + data Context = Context { _variables :: [Port] , _parameters :: [Parameter] , _modules :: [ModDecl] @@ -100,7 +105,7 @@ gen :: Gen a -> StateGen a gen = lift . lift largeNum :: Gen Int -largeNum = Hog.int Hog.linearBounded +largeNum = Hog.int $ Hog.linear (-100) 100 wireSize :: Gen Int wireSize = Hog.int $ Hog.linear 2 100 @@ -109,7 +114,7 @@ range :: Gen Range range = Range <$> fmap fromIntegral wireSize <*> pure 0 genBitVec :: Gen BitVec -genBitVec = BitVec <$> wireSize <*> fmap fromIntegral largeNum +genBitVec = fmap fromIntegral largeNum binOp :: Gen BinaryOperator binOp = Hog.element @@ -342,22 +347,38 @@ statement = do alwaysSeq :: StateGen ModItem alwaysSeq = Always . EventCtrl (EPosEdge "clk") . Just <$> seqBlock +-- | Should resize a port that connects to a module port if the latter is +-- larger. This should not cause any problems if the same net is used as input +-- multiple times, and is resized multiple times, as it should only get larger. +resizePort :: [Parameter] -> Identifier -> Range -> [Port] -> [Port] +resizePort ps i ra = foldl' func [] + where + func l p@(Port _ _ ri i') + | i' == i && calc ri < calc ra = (p & portSize .~ ra) : l + | otherwise = p : l + calc = calcRange ps $ Just 64 + +-- | Instantiate a module, where the outputs are new nets that are created, and +-- the inputs are taken from existing ports in the context. instantiate :: ModDecl -> StateGen ModItem instantiate (ModDecl i outP inP _ _) = do context <- get - outs <- fmap (Id . view portName) - <$> replicateM (length outP) (nextPort Wire) - ins <- - (Id "clk" :) - . fmap (Id . view portName) - . take (length inP - 1) - <$> Hog.shuffle (context ^. variables) + outs <- replicateM (length outP) (nextPort Wire) + ins <- take (length inP) <$> Hog.shuffle (context ^. variables) + mapM_ (uncurry process) . zip (ins ^.. traverse . portName) $ inP ^.. traverse . portSize ident <- makeIdentifier "modinst" + vs <- view variables <$> get Hog.choice - [ return . ModInst i ident $ ModConn <$> outs <> ins + [ return . ModInst i ident $ ModConn <$> outE outs <> insE ins , ModInst i ident <$> Hog.shuffle - (zipWith ModConnNamed (view portName <$> outP <> inP) (outs <> ins)) + (zipWith ModConnNamed (view portName <$> outP <> inP) (outE outs <> insE ins)) ] + where + insE ins = Id "clk" : (Id . view portName <$> ins) + outE out = Id . view portName <$> out + process p r = do + params <- view parameters <$> get + variables %= resizePort params p r -- | Generates a module instance by also generating a new module if there are -- not enough modules currently in the context. It keeps generating new modules @@ -4,7 +4,6 @@ packages: extra-deps: - DRBG-0.5.5@sha256:3b8040bed356e2b63927a27fb6d5adbd19d70c9e1d1bb66111bbeb33e56900eb - fgl-visualize-0.1.0.1@sha256:e682066053a6e75478a08fd6822dd0143a3b8ea23244bdb01dd389a266447c5e - - tomland-1.0.0@sha256:a6eb99963469c3c047f7f6a54ccbadc87c2ec046eec82c6f22e535f7edfbc292 - - hedgehog-fn-0.6@sha256:61ad7f2a563825a037decfc0c3301f6d83b8d8ec16296f9b7a411b8a5e5567a7 - - tasty-hedgehog-0.2.0.0@sha256:83a8b777fa472040979e44dba43c32441f55d5ddb9641a4d53deee4b0e09fa34 -resolver: lts-13.20 + - tomland-1.0.1.0@sha256:d8a8d2c6a4a09966070fff3bdc64dd4700e35c061f21a0ba56fdad55035d9600 + +resolver: lts-13.28 |