aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--default.nix32
-rw-r--r--nix/hedgehog-fn.nix17
-rw-r--r--nix/parser-combinators.nix10
-rw-r--r--nix/tomland.nix33
-rw-r--r--release.nix17
-rw-r--r--shell.nix25
-rw-r--r--src/VeriFuzz/Verilog/Gen.hs65
-rw-r--r--stack.yaml7
9 files changed, 184 insertions, 26 deletions
diff --git a/.gitignore b/.gitignore
index 8997a16..870ff77 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/stack.yaml b/stack.yaml
index ecce8d6..8283ae6 100644
--- a/stack.yaml
+++ b/stack.yaml
@@ -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