diff options
Diffstat (limited to 'src/VeriFuzz/Verilog')
-rw-r--r-- | src/VeriFuzz/Verilog/Gen.hs | 65 |
1 files changed, 43 insertions, 22 deletions
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 |