From fd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 2 Apr 2019 19:47:32 +0100 Subject: Large refactor with passing tests --- src/VeriFuzz/Sim/Icarus.hs | 112 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/VeriFuzz/Sim/Icarus.hs (limited to 'src/VeriFuzz/Sim/Icarus.hs') diff --git a/src/VeriFuzz/Sim/Icarus.hs b/src/VeriFuzz/Sim/Icarus.hs new file mode 100644 index 0000000..6bf21f4 --- /dev/null +++ b/src/VeriFuzz/Sim/Icarus.hs @@ -0,0 +1,112 @@ +{-| +Module : VeriFuzz.Sim.Icarus +Description : Icarus verilog module. +Copyright : (c) 2018-2019, Yann Herklotz +License : BSD-3 +Maintainer : ymherklotz [at] gmail [dot] com +Stability : experimental +Portability : POSIX + +Icarus verilog module. +-} + +module VeriFuzz.Sim.Icarus + ( Icarus(..) + , defaultIcarus + ) +where + +import Control.Lens +import Crypto.Hash (Digest, hash) +import Crypto.Hash.Algorithms (SHA256) +import Data.Binary (encode) +import qualified Data.ByteArray as BA (convert) +import Data.ByteString (ByteString) +import qualified Data.ByteString as B +import Data.ByteString.Lazy (toStrict) +import qualified Data.ByteString.Lazy as L (ByteString) +import Data.Char (digitToInt) +import Data.Foldable (fold) +import Data.List (transpose) +import Data.Maybe (listToMaybe) +import Data.Text (Text) +import qualified Data.Text as T +import Numeric (readInt) +import Prelude hiding (FilePath) +import Shelly +import VeriFuzz.Sim.Internal +import VeriFuzz.Verilog.AST +import VeriFuzz.Verilog.CodeGen +import VeriFuzz.Verilog.Internal +import VeriFuzz.Verilog.Mutate + +data Icarus = Icarus { icarusPath :: FilePath + , vvpPath :: FilePath + } + deriving (Eq, Show) + +instance Tool Icarus where + toText _ = "iverilog" + +instance Simulator Icarus where + runSim = runSimIcarus + runSimWithFile = runSimIcarusWithFile + +defaultIcarus :: Icarus +defaultIcarus = Icarus "iverilog" "vvp" + +addDisplay :: [Statement] -> [Statement] +addDisplay s = concat $ transpose + [ s + , replicate l $ TimeCtrl 1 Nothing + , replicate l . SysTaskEnable $ Task "display" ["%b", Id "y"] + ] + where l = length s + +assignFunc :: [Port] -> ByteString -> Statement +assignFunc inp bs = + NonBlockAssign . Assign conc Nothing . Number (B.length bs * 8) $ bsToI bs + where conc = RegConcat (portToExpr <$> inp) + +convert :: Text -> ByteString +convert = + toStrict + . (encode :: Integer -> L.ByteString) + . maybe 0 fst + . listToMaybe + . readInt 2 (`elem` ("01" :: String)) digitToInt + . T.unpack + +mask :: Text -> Text +mask = T.replace "x" "0" + +callback :: ByteString -> Text -> ByteString +callback b t = b <> convert (mask t) + +runSimIcarus :: Icarus -> SourceInfo -> [ByteString] -> Sh ByteString +runSimIcarus sim rinfo bss = do + let tb = ModDecl + "main" + [] + [] + [ Initial + $ fold (addDisplay $ assignFunc (_modInPorts m) <$> bss) + <> (SysTaskEnable $ Task "finish" []) + ] + let newtb = instantiateMod m tb + let modWithTb = Verilog $ Description <$> [newtb, m] + writefile "main.v" $ genSource modWithTb + runSimWithFile sim "main.v" bss + where m = rinfo ^. mainModule + +runSimIcarusWithFile :: Icarus -> FilePath -> [ByteString] -> Sh ByteString +runSimIcarusWithFile sim f _ = do + dir <- pwd + echoP "Icarus: Compile" + _ <- logger dir "icarus" + $ run (icarusPath sim) ["-o", "main", toTextIgnore f] + echoP "Icarus: Run" + B.take 8 . BA.convert . (hash :: ByteString -> Digest SHA256) <$> logger + dir + "vvp" + (runFoldLines (mempty :: ByteString) callback (vvpPath sim) ["main"]) -- cgit