blob: b709967fae43159866c3805fd646ae720ec97e02 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
{-|
Module : VeriFuzz.Icarus
Description : Icarus verilog module.
Copyright : (c) 2018-2019, Yann Herklotz Grave
License : BSD-3
Maintainer : ymherklotz [at] gmail [dot] com
Stability : experimental
Portability : POSIX
Icarus verilog module.
-}
module VeriFuzz.Icarus 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.AST
import VeriFuzz.CodeGen
import VeriFuzz.Internal
import VeriFuzz.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 :: [Stmnt] -> [Stmnt]
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 -> Stmnt
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 = VerilogSrc $ 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"])
|