module Verismith.Circuit.Gen
( generateAST
)
where
import Data.Graph.Inductive (LNode, Node)
import qualified Data.Graph.Inductive as G
import Data.Maybe (catMaybes)
import Verismith.Circuit.Base
import Verismith.Circuit.Internal
import Verismith.Verilog.AST
import Verismith.Verilog.Mutate
frNode :: Node -> Identifier
frNode = Identifier . fromNode
fromGate :: Gate -> BinaryOperator
fromGate And = BinAnd
fromGate Or = BinOr
fromGate Xor = BinXor
inputsC :: Circuit -> [Node]
inputsC c = inputs (getCircuit c)
genPortsAST :: (Circuit -> [Node]) -> Circuit -> [Port]
genPortsAST f c = port . frNode <$> f c where port = Port Wire False 4
genAssignExpr :: Gate -> [Node] -> Maybe Expr
genAssignExpr _ [] = Nothing
genAssignExpr _ [n ] = Just . Id $ frNode n
genAssignExpr g (n : ns) = BinOp wire oper <$> genAssignExpr g ns
where
wire = Id $ frNode n
oper = fromGate g
genContAssignAST :: Circuit -> LNode Gate -> Maybe ModItem
genContAssignAST c (n, g) = ModCA . ContAssign name <$> genAssignExpr g nodes
where
gr = getCircuit c
nodes = G.pre gr n
name = frNode n
genAssignAST :: Circuit -> [ModItem]
genAssignAST c = catMaybes $ genContAssignAST c <$> nodes
where
gr = getCircuit c
nodes = G.labNodes gr
genModuleDeclAST :: Circuit -> ModDecl
genModuleDeclAST c = ModDecl i output ports (combineAssigns yPort a) []
where
i = Identifier "gen_module"
ports = genPortsAST inputsC c
output = []
a = genAssignAST c
yPort = Port Wire False 90 "y"
generateAST :: Circuit -> Verilog
generateAST c = Verilog [genModuleDeclAST c]