aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2018-12-25 13:24:43 +0100
committerYann Herklotz <ymherklotz@gmail.com>2018-12-25 13:24:43 +0100
commit31c0d84a385c311b52860b86664ba459ac93ad5f (patch)
treebb5e5e1ed7a9b1ba58b564de856415e937edfa4b /src
parent5f117a30bc978e649ecc8421a48fb933e7e4ae95 (diff)
downloadverismith-31c0d84a385c311b52860b86664ba459ac93ad5f.tar.gz
verismith-31c0d84a385c311b52860b86664ba459ac93ad5f.zip
Add code generation for new types
Diffstat (limited to 'src')
-rw-r--r--src/Test/VeriFuzz/CodeGen.hs150
1 files changed, 130 insertions, 20 deletions
diff --git a/src/Test/VeriFuzz/CodeGen.hs b/src/Test/VeriFuzz/CodeGen.hs
index 755f52f..acfa020 100644
--- a/src/Test/VeriFuzz/CodeGen.hs
+++ b/src/Test/VeriFuzz/CodeGen.hs
@@ -16,12 +16,19 @@ This module generates the code from the Verilog AST defined in
module Test.VeriFuzz.CodeGen where
import Control.Lens
+import Data.Maybe (fromMaybe)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Test.VeriFuzz.Internal.Shared
import Test.VeriFuzz.VerilogAST
+showT :: (Show a) => a -> Text
+showT = T.pack . show
+
+defMap :: Maybe Statement -> Text
+defMap stat = fromMaybe ";" $ genStatement <$> stat
+
-- | Convert the 'SourceText' type to 'Text' so that it can be rendered.
genSourceText :: SourceText -> Text
genSourceText source =
@@ -32,23 +39,26 @@ genDescription :: Description -> Text
genDescription desc =
genModuleDecl $ desc ^. getDescription
--- | Generate the 'ModuleDecl' for a module and convert it to 'Text'.
-genModuleDecl :: ModuleDecl -> Text
+-- | Generate the 'ModDecl' for a module and convert it to 'Text'.
+genModuleDecl :: ModDecl -> Text
genModuleDecl mod =
"module " <> mod ^. moduleId . getIdentifier
- <> "(\n" <> ports <> "\n);\n"
+ <> ports <> ";\n"
<> modItems
<> "endmodule\n"
where
- ports = sep ",\n" $ genPort <$> mod ^. modPorts
+ ports
+ | null $ mod ^. modPorts = ""
+ | otherwise = "(\n" <> (sep ",\n" $ genPort <$> mod ^. modPorts) <> "\n)"
modItems = fromList $ genModuleItem <$> mod ^. moduleItems
-- | Generate the 'Port' description.
genPort :: Port -> Text
genPort port =
- " " <> dir <> " " <> name
+ " " <> dir <> " " <> t <> " " <> name
where
- dir = genPortDir $ port ^. portDir
+ dir = fromMaybe "" $ genPortDir <$> port ^. portDir
+ t = fromMaybe "" $ genPortType <$> port ^. portType
name = port ^. portName . getIdentifier
-- | Convert the 'PortDir' type to 'Text'.
@@ -57,25 +67,33 @@ genPortDir Input = "input"
genPortDir Output = "output"
genPortDir InOut = "inout"
--- | Generate a 'ModuleItem'.
-genModuleItem :: ModuleItem -> Text
-genModuleItem (Assign assign) = genContAssign assign
+-- | Generate a 'ModItem'.
+genModuleItem :: ModItem -> Text
+genModuleItem (ModCA ca) = genContAssign ca
+genModuleItem (ModInst (Identifier id) (Identifier name) conn) =
+ id <> " " <> name <> "(" <> sep ", " (genExpr . _modConn <$> conn) <> ")" <> ";\n"
+genModuleItem (Initial stat) = "initial\n" <> genStatement stat
+genModuleItem (Always stat) = "always\n" <> genStatement stat
+genModuleItem (Decl port) = genPort port <> ";\n"
--- | Generate the 'ContinuousAssignment' to 'Text'.
+-- | Generate continuous assignment
genContAssign :: ContAssign -> Text
-genContAssign assign =
+genContAssign (ContAssign val e) =
" assign " <> name <> " = " <> expr <> ";\n"
where
- name = assign ^. contAssignNetLVal . getIdentifier
- expr = genExpr $ assign ^. contAssignExpr
+ name = val ^. getIdentifier
+ expr = genExpr $ e
-- | Generate 'Expression' to 'Text'.
genExpr :: Expression -> Text
genExpr (OpExpr exprRhs bin exprLhs) =
- genExpr exprRhs <> genBinaryOperator bin <> genExpr exprLhs
-genExpr (PrimExpr prim) =
- genPrimary prim
-genExpr _ = "TODO"
+ "(" <> genExpr exprRhs <> genBinaryOperator bin <> genExpr exprLhs <> ")"
+genExpr (PrimExpr prim) = genPrimary prim
+genExpr (UnPrimExpr u e) =
+ "(" <> genUnaryOperator u <> genPrimary e <> ")"
+genExpr (CondExpr l t f) =
+ "(" <> genExpr l <> " ? " <> genExpr t <> " : " <> genExpr f
+genExpr (ExprStr t) = "\"" <> t <> "\""
-- | Generate a 'PrimaryExpression' to 'Text'.
genPrimary :: Primary -> Text
@@ -90,9 +108,101 @@ genPrimary (PrimId ident) = ident ^. getIdentifier
-- | Convert 'BinaryOperator' to 'Text'.
genBinaryOperator :: BinaryOperator -> Text
-genBinaryOperator BinAnd = " & "
-genBinaryOperator BinOr = " | "
-genBinaryOperator BinXor = " ^ "
+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 = " >>> "
+
+genUnaryOperator :: UnaryOperator -> Text
+genUnaryOperator UnPlus = " + "
+genUnaryOperator UnMinus = " - "
+genUnaryOperator UnNot = " ! "
+genUnaryOperator UnAnd = " & "
+genUnaryOperator UnNand = " ~& "
+genUnaryOperator UnOr = " | "
+genUnaryOperator UnNor = " ~| "
+genUnaryOperator UnXor = " ^ "
+genUnaryOperator UnNxor = " ~^ "
+genUnaryOperator UnNxorInv = " ^~ "
+
+genNet :: Net -> Text
+genNet Wire = "wire"
+genNet Tri = "tri"
+genNet Tri1 = "tri1"
+genNet Supply0 = "supply0"
+genNet Wand = "wand"
+genNet TriAnd = "triand"
+genNet Tri0 = "tri0"
+genNet Supply1 = "supply1"
+genNet Wor = "wor"
+genNet Trior = "trior"
+
+genEvent :: Event -> Text
+genEvent (EId id) = "@" <> id ^. getIdentifier
+genEvent (EExpr expr) = "@" <> genExpr expr
+genEvent EAll = "@*"
+
+genDelay :: Delay -> Text
+genDelay (Delay i) = "#" <> showT i
+
+genRegLVal :: RegLVal -> Text
+genRegLVal (RegId id) = id ^. getIdentifier
+genRegLVal (RegExpr id expr) =
+ id ^. getIdentifier <> " [" <> genExpr expr <> "]"
+genRegLVal (RegSize id msb lsb) =
+ id ^. getIdentifier <> " [" <> genConstExpr msb <> ":" <> genConstExpr lsb <> "]"
+
+genConstExpr :: ConstExpr -> Text
+genConstExpr (ConstExpr num) = showT num
+
+genPortType :: PortType -> Text
+genPortType (PortNet net) = genNet net
+genPortType (Reg signed)
+ | signed = " reg signed "
+ | otherwise = " reg "
+
+genAssign :: Text -> Assign -> Text
+genAssign op (Assign r d e) =
+ genRegLVal r <> op <> fromMaybe "" (genDelay <$> d) <> genExpr e
+
+genStatement :: Statement -> Text
+genStatement (TimeCtrl d stat) = genDelay d <> " " <> defMap stat
+genStatement (EventCtrl e stat) = genEvent e <> " " <> defMap stat
+genStatement (SeqBlock s) =
+ "begin\n" <> fromList (genStatement <$> s) <> "end\n"
+genStatement (BlockAssign a) = genAssign " = " a <> ";\n"
+genStatement (NonBlockAssign a) = genAssign " <= " a <> ";\n"
+genStatement (StatCA a) = genContAssign a
+genStatement (TaskEnable task) = genTask task <> ";\n"
+genStatement (SysTaskEnable task) = "$" <> genTask task <> ";\n"
+
+genTask :: Task -> Text
+genTask (Task name expr)
+ | null expr = id
+ | otherwise = id <> "(" <> sep ", " (genExpr <$> expr) <> ")"
+ where
+ id = name ^. getIdentifier
-- | Render the 'Text' to 'IO'. This is equivalent to 'putStrLn'.
render :: Text -> IO ()