aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz/Verilog/CodeGen.hs
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2019-02-01 19:39:52 +0000
committerYann Herklotz <ymherklotz@gmail.com>2019-02-01 19:39:52 +0000
commit1067284cc1f6ca8ba646545c5b8d0a79cc2e41ad (patch)
tree2c9a8d54bf6f9870f0ae62c150803ccec90d46e7 /src/VeriFuzz/Verilog/CodeGen.hs
parenta38289ca9d96e97bc4e65b67c50f5805d56a3d86 (diff)
downloadverismith-1067284cc1f6ca8ba646545c5b8d0a79cc2e41ad.tar.gz
verismith-1067284cc1f6ca8ba646545c5b8d0a79cc2e41ad.zip
More restructuring
Diffstat (limited to 'src/VeriFuzz/Verilog/CodeGen.hs')
-rw-r--r--src/VeriFuzz/Verilog/CodeGen.hs276
1 files changed, 0 insertions, 276 deletions
diff --git a/src/VeriFuzz/Verilog/CodeGen.hs b/src/VeriFuzz/Verilog/CodeGen.hs
deleted file mode 100644
index 3253f86..0000000
--- a/src/VeriFuzz/Verilog/CodeGen.hs
+++ /dev/null
@@ -1,276 +0,0 @@
-{-|
-Module : VeriFuzz.Verilog.CodeGen
-Description : Code generation for Verilog AST.
-Copyright : (c) 2018-2019, Yann Herklotz Grave
-License : BSD-3
-Maintainer : ymherklotz [at] gmail [dot] com
-Stability : experimental
-Portability : POSIX
-
-This module generates the code from the Verilog AST defined in
-"VeriFuzz.Verilog.AST".
--}
-
-{-# LANGUAGE FlexibleInstances #-}
-
-module VeriFuzz.Verilog.CodeGen where
-
-import Control.Lens (view, (^.))
-import Data.Foldable (fold)
-import Data.Text (Text)
-import qualified Data.Text as T
-import qualified Data.Text.IO as T
-import Numeric (showHex)
-import Test.QuickCheck (Arbitrary, arbitrary)
-import VeriFuzz.Verilog.AST
-
--- | 'Source' class which determines that source code is able to be generated
--- from the data structure using 'genSource'. This will be stored in 'Text' and
--- can then be processed further.
-class Source a where
- genSource :: a -> Text
-
--- | Inserts commas between '[Text]' and except the last one.
-comma :: [Text] -> Text
-comma = T.intercalate ", "
-
--- | Show function for 'Text'
-showT :: (Show a) => a -> Text
-showT = T.pack . show
-
--- | Map a 'Maybe Stmnt' to 'Text'. If it is 'Just stmnt', the generated
--- statements are returned. If it is 'Nothing', then @;\n@ is returned.
-defMap :: Maybe Stmnt -> Text
-defMap = maybe ";\n" genStmnt
-
--- | Convert the 'VerilogSrc' type to 'Text' so that it can be rendered.
-genVerilogSrc :: VerilogSrc -> Text
-genVerilogSrc source = fold $ genDescription <$> source ^. getVerilogSrc
-
--- | Generate the 'Description' to 'Text'.
-genDescription :: Description -> Text
-genDescription desc = genModuleDecl $ desc ^. getDescription
-
--- | Generate the 'ModDecl' for a module and convert it to 'Text'.
-genModuleDecl :: ModDecl -> Text
-genModuleDecl m =
- "module " <> m ^. modId . getIdentifier <> ports <> ";\n" <> modI <> "endmodule\n"
- where
- ports | noIn && noOut = ""
- | otherwise = "(" <> comma (genModPort <$> outIn) <> ")"
- modI = fold $ genModuleItem <$> m ^. modItems
- noOut = null $ m ^. modOutPorts
- noIn = null $ m ^. modInPorts
- outIn = (m ^. modOutPorts) ++ (m ^. modInPorts)
-
--- | Conversts 'Port' to 'Text' for the module list, which means it only
--- generates a list of identifiers.
-genModPort :: Port -> Text
-genModPort port = port ^. portName . getIdentifier
-
--- | Generate the 'Port' description.
-genPort :: Port -> Text
-genPort port = t <> size <> name
- where
- t = (<> " ") . genPortType $ port ^. portType
- size | port ^. portSize > 1 = "[" <> showT (port ^. portSize - 1) <> ":0] "
- | otherwise = ""
- name = port ^. portName . getIdentifier
-
--- | Convert the 'PortDir' type to 'Text'.
-genPortDir :: PortDir -> Text
-genPortDir PortIn = "input"
-genPortDir PortOut = "output"
-genPortDir PortInOut = "inout"
-
--- | Generate a 'ModItem'.
-genModuleItem :: ModItem -> Text
-genModuleItem (ModCA ca) = genContAssign ca
-genModuleItem (ModInst (Identifier i) (Identifier name) conn) =
- i <> " " <> name <> "(" <> comma (genModConn <$> conn) <> ")" <> ";\n"
-genModuleItem (Initial stat ) = "initial " <> genStmnt stat
-genModuleItem (Always stat ) = "always " <> genStmnt stat
-genModuleItem (Decl dir port) = maybe "" makePort dir <> genPort port <> ";\n"
- where makePort = (<> " ") . genPortDir
-
-genModConn :: ModConn -> Text
-genModConn (ModConn c) =
- genExpr c
-genModConn (ModConnNamed n c) =
- "." <> n ^. getIdentifier <> "(" <> genExpr c <> ")"
-
--- | Generate continuous assignment
-genContAssign :: ContAssign -> Text
-genContAssign (ContAssign val e) = "assign " <> name <> " = " <> expr <> ";\n"
- where
- name = val ^. getIdentifier
- expr = genExpr e
-
--- | Generate 'Function' to 'Text'
-genFunc :: Function -> Text
-genFunc SignedFunc = "$signed"
-genFunc UnSignedFunc = "$unsigned"
-
--- | Generate 'Expr' to 'Text'.
-genExpr :: Expr -> Text
-genExpr (BinOp eRhs bin eLhs) = "(" <> genExpr eRhs <> genBinaryOperator bin <> genExpr eLhs <> ")"
-genExpr (Number s n ) = minus <> showT s <> "'h" <> T.pack (showHex (abs n) "")
- where minus | signum n > 0 = "" | otherwise = "-"
-genExpr (Id i ) = i ^. getIdentifier
-genExpr (Concat c ) = "{" <> comma (genExpr <$> c) <> "}"
-genExpr (UnOp u e ) = "(" <> genUnaryOperator u <> genExpr e <> ")"
-genExpr (Cond l t f ) = "(" <> genExpr l <> " ? " <> genExpr t <> " : " <> genExpr f <> ")"
-genExpr (Func f e ) = genFunc f <> "(" <> genExpr e <> ")"
-genExpr (Str t ) = "\"" <> t <> "\""
-
--- | Convert 'BinaryOperator' to 'Text'.
-genBinaryOperator :: BinaryOperator -> Text
-genBinaryOperator BinPlus = " + "
-genBinaryOperator BinMinus = " - "
-genBinaryOperator BinTimes = " * "
-genBinaryOperator BinDiv = " / "
-genBinaryOperator BinMod = " % "
-genBinaryOperator BinEq = " == "
-genBinaryOperator BinNEq = " != "
-genBinaryOperator BinCEq = " === "
-genBinaryOperator BinCNEq = " !== "
-genBinaryOperator BinLAnd = " && "
-genBinaryOperator BinLOr = " || "
-genBinaryOperator BinLT = " < "
-genBinaryOperator BinLEq = " <= "
-genBinaryOperator BinGT = " > "
-genBinaryOperator BinGEq = " >= "
-genBinaryOperator BinAnd = " & "
-genBinaryOperator BinOr = " | "
-genBinaryOperator BinXor = " ^ "
-genBinaryOperator BinXNor = " ^~ "
-genBinaryOperator BinXNorInv = " ~^ "
-genBinaryOperator BinPower = " ** "
-genBinaryOperator BinLSL = " << "
-genBinaryOperator BinLSR = " >> "
-genBinaryOperator BinASL = " <<< "
-genBinaryOperator BinASR = " >>> "
-
--- | Convert 'UnaryOperator' to 'Text'.
-genUnaryOperator :: UnaryOperator -> Text
-genUnaryOperator UnPlus = "+"
-genUnaryOperator UnMinus = "-"
-genUnaryOperator UnNot = "!"
-genUnaryOperator UnAnd = "&"
-genUnaryOperator UnNand = "~&"
-genUnaryOperator UnOr = "|"
-genUnaryOperator UnNor = "~|"
-genUnaryOperator UnXor = "^"
-genUnaryOperator UnNxor = "~^"
-genUnaryOperator UnNxorInv = "^~"
-
--- | Generate verilog code for an 'Event'.
-genEvent :: Event -> Text
-genEvent (EId i ) = "@(" <> i ^. getIdentifier <> ")"
-genEvent (EExpr expr) = "@(" <> genExpr expr <> ")"
-genEvent EAll = "@*"
-genEvent (EPosEdge i) = "@(posedge " <> i ^. getIdentifier <> ")"
-genEvent (ENegEdge i) = "@(negedge " <> i ^. getIdentifier <> ")"
-
--- | Generates verilog code for a 'Delay'.
-genDelay :: Delay -> Text
-genDelay (Delay i) = "#" <> showT i
-
--- | Generate the verilog code for an 'LVal'.
-genLVal :: LVal -> Text
-genLVal (RegId i ) = i ^. getIdentifier
-genLVal (RegExpr i expr) = i ^. getIdentifier <> " [" <> genExpr expr <> "]"
-genLVal (RegSize i msb lsb) =
- i ^. getIdentifier <> " [" <> genConstExpr msb <> ":" <> genConstExpr lsb <> "]"
-genLVal (RegConcat e) = "{" <> comma (genExpr <$> e) <> "}"
-
-genConstExpr :: ConstExpr -> Text
-genConstExpr (ConstExpr num) = showT num
-
-genPortType :: PortType -> Text
-genPortType Wire = "wire"
-genPortType (Reg signed) | signed = "reg signed"
- | otherwise = "reg"
-
-genAssign :: Text -> Assign -> Text
-genAssign op (Assign r d e) = genLVal r <> op <> maybe "" genDelay d <> genExpr e
-
-genStmnt :: Stmnt -> Text
-genStmnt (TimeCtrl d stat ) = genDelay d <> " " <> defMap stat
-genStmnt (EventCtrl e stat ) = genEvent e <> " " <> defMap stat
-genStmnt (SeqBlock s ) = "begin\n" <> fold (genStmnt <$> s) <> "end\n"
-genStmnt (BlockAssign a ) = genAssign " = " a <> ";\n"
-genStmnt (NonBlockAssign a ) = genAssign " <= " a <> ";\n"
-genStmnt (StatCA a ) = genContAssign a
-genStmnt (TaskEnable task) = genTask task <> ";\n"
-genStmnt (SysTaskEnable task) = "$" <> genTask task <> ";\n"
-
-genTask :: Task -> Text
-genTask (Task name expr) | null expr = i
- | otherwise = i <> "(" <> comma (genExpr <$> expr) <> ")"
- where i = name ^. getIdentifier
-
--- | Render the 'Text' to 'IO'. This is equivalent to 'putStrLn'.
-render :: (Source a) => a -> IO ()
-render = T.putStrLn . genSource
-
--- Instances
-
-instance Source Identifier where
- genSource = view getIdentifier
-
-instance Source Task where
- genSource = genTask
-
-instance Source Stmnt where
- genSource = genStmnt
-
-instance Source PortType where
- genSource = genPortType
-
-instance Source ConstExpr where
- genSource = genConstExpr
-
-instance Source LVal where
- genSource = genLVal
-
-instance Source Delay where
- genSource = genDelay
-
-instance Source Event where
- genSource = genEvent
-
-instance Source UnaryOperator where
- genSource = genUnaryOperator
-
-instance Source Expr where
- genSource = genExpr
-
-instance Source ContAssign where
- genSource = genContAssign
-
-instance Source ModItem where
- genSource = genModuleItem
-
-instance Source PortDir where
- genSource = genPortDir
-
-instance Source Port where
- genSource = genPort
-
-instance Source ModDecl where
- genSource = genModuleDecl
-
-instance Source Description where
- genSource = genDescription
-
-instance Source VerilogSrc where
- genSource = genVerilogSrc
-
-newtype GenVerilog a = GenVerilog { unGenVerilog :: a }
-
-instance (Source a) => Show (GenVerilog a) where
- show = T.unpack . genSource . unGenVerilog
-
-instance (Arbitrary a) => Arbitrary (GenVerilog a) where
- arbitrary = GenVerilog <$> arbitrary