aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2019-01-19 19:20:33 +0000
committerYann Herklotz <ymherklotz@gmail.com>2019-01-19 19:20:33 +0000
commit4ba440d842e9a0502b429fbc04e2be41c8037a4c (patch)
treefb6440ebe2905b4c2c820dece67ef430d92731af /src/VeriFuzz
parent708e0b680a48e6eb21664a5f1de21815bebf91d2 (diff)
downloadverismith-4ba440d842e9a0502b429fbc04e2be41c8037a4c.tar.gz
verismith-4ba440d842e9a0502b429fbc04e2be41c8037a4c.zip
Add brittany formatting instead of stylish-haskell
Diffstat (limited to 'src/VeriFuzz')
-rw-r--r--src/VeriFuzz/Circuit.hs4
-rw-r--r--src/VeriFuzz/Graph/ASTGen.hs58
-rw-r--r--src/VeriFuzz/Graph/CodeGen.hs55
-rw-r--r--src/VeriFuzz/Graph/Random.hs44
-rw-r--r--src/VeriFuzz/Graph/RandomAlt.hs21
-rw-r--r--src/VeriFuzz/Internal/Gen.hs21
-rw-r--r--src/VeriFuzz/Simulator.hs3
-rw-r--r--src/VeriFuzz/Simulator/General.hs10
-rw-r--r--src/VeriFuzz/Simulator/Icarus.hs35
-rw-r--r--src/VeriFuzz/Simulator/Xst.hs10
-rw-r--r--src/VeriFuzz/Simulator/Yosys.hs18
-rw-r--r--src/VeriFuzz/Verilog.hs3
-rw-r--r--src/VeriFuzz/Verilog/AST.hs135
-rw-r--r--src/VeriFuzz/Verilog/CodeGen.hs128
-rw-r--r--src/VeriFuzz/Verilog/Helpers.hs16
-rw-r--r--src/VeriFuzz/Verilog/Mutate.hs113
16 files changed, 385 insertions, 289 deletions
diff --git a/src/VeriFuzz/Circuit.hs b/src/VeriFuzz/Circuit.hs
index 7958f6a..1891ff9 100644
--- a/src/VeriFuzz/Circuit.hs
+++ b/src/VeriFuzz/Circuit.hs
@@ -12,7 +12,9 @@ Definition of the circuit graph.
module VeriFuzz.Circuit where
-import Data.Graph.Inductive (Gr, LNode)
+import Data.Graph.Inductive ( Gr
+ , LNode
+ )
import System.Random
import Test.QuickCheck
diff --git a/src/VeriFuzz/Graph/ASTGen.hs b/src/VeriFuzz/Graph/ASTGen.hs
index f7bd058..0403f51 100644
--- a/src/VeriFuzz/Graph/ASTGen.hs
+++ b/src/VeriFuzz/Graph/ASTGen.hs
@@ -12,10 +12,12 @@ Generates the AST from the graph directly.
module VeriFuzz.Graph.ASTGen where
-import Data.Foldable (fold)
-import Data.Graph.Inductive (LNode, Node)
-import qualified Data.Graph.Inductive as G
-import Data.Maybe (catMaybes)
+import Data.Foldable ( fold )
+import Data.Graph.Inductive ( LNode
+ , Node
+ )
+import qualified Data.Graph.Inductive as G
+import Data.Maybe ( catMaybes )
import VeriFuzz.Circuit
import VeriFuzz.Internal.Gen
import VeriFuzz.Verilog.AST
@@ -33,52 +35,48 @@ fromGate Or = BinOr
fromGate Xor = BinXor
inputsC :: Circuit -> [Node]
-inputsC c =
- inputs (getCircuit c)
+inputsC c = inputs (getCircuit c)
outputsC :: Circuit -> [Node]
-outputsC c =
- outputs (getCircuit c)
+outputsC c = outputs (getCircuit c)
genPortsAST :: (Circuit -> [Node]) -> Circuit -> [Port]
-genPortsAST f c =
- port . frNode <$> f c
- where
- port = Port Wire 4
+genPortsAST f c = port . frNode <$> f c where port = Port Wire 4
-- | Generates the nested expression AST, so that it can then generate the
-- assignment expressions.
genAssignExpr :: Gate -> [Node] -> Maybe Expr
-genAssignExpr _ [] = Nothing
-genAssignExpr _ [n] = Just . Id $ frNode n
-genAssignExpr g (n:ns) = BinOp wire op <$> genAssignExpr g ns
- where
- wire = Id $ frNode n
- op = fromGate g
+genAssignExpr _ [] = Nothing
+genAssignExpr _ [n ] = Just . Id $ frNode n
+genAssignExpr g (n : ns) = BinOp wire op <$> genAssignExpr g ns
+ where
+ wire = Id $ frNode n
+ op = fromGate g
-- | Generate the continuous assignment AST for a particular node. If it does
-- not have any nodes that link to it then return 'Nothing', as that means that
-- the assignment will just be empty.
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
+ 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
+ where
+ gr = getCircuit c
+ nodes = G.labNodes gr
genModuleDeclAST :: Circuit -> ModDecl
genModuleDeclAST c = ModDecl i output ports items
- where
- i = Identifier "gen_module"
- ports = genPortsAST inputsC c
- output = [Port Wire 90 "y"]
- items = genAssignAST c ++ [ModCA . ContAssign "y" . fold $ portToExpr <$> ports]
+ where
+ i = Identifier "gen_module"
+ ports = genPortsAST inputsC c
+ output = [Port Wire 90 "y"]
+ items =
+ genAssignAST c ++ [ModCA . ContAssign "y" . fold $ portToExpr <$> ports]
generateAST :: Circuit -> VerilogSrc
generateAST c = VerilogSrc [Description $ genModuleDeclAST c]
diff --git a/src/VeriFuzz/Graph/CodeGen.hs b/src/VeriFuzz/Graph/CodeGen.hs
index 57e7b2a..3c45a9c 100644
--- a/src/VeriFuzz/Graph/CodeGen.hs
+++ b/src/VeriFuzz/Graph/CodeGen.hs
@@ -12,13 +12,19 @@ Define the code generation directly from the random DAG.
module VeriFuzz.Graph.CodeGen
( generate
- ) where
+ )
+where
-import Data.Foldable (fold)
-import Data.Graph.Inductive (Graph, LNode, Node, labNodes, pre)
-import Data.Maybe (fromMaybe)
-import Data.Text (Text)
-import qualified Data.Text as T
+import Data.Foldable ( fold )
+import Data.Graph.Inductive ( Graph
+ , LNode
+ , Node
+ , labNodes
+ , pre
+ )
+import Data.Maybe ( fromMaybe )
+import Data.Text ( Text )
+import qualified Data.Text as T
import VeriFuzz.Circuit
import VeriFuzz.Internal.Gen
import VeriFuzz.Internal.Shared
@@ -30,30 +36,33 @@ toOperator Xor = " ^ "
statList :: Gate -> [Node] -> Maybe Text
statList g n = toStr <$> safe tail n
- where
- toStr = fold . fmap ((<> toOperator g) . fromNode)
+ where toStr = fold . fmap ((<> toOperator g) . fromNode)
lastEl :: [Node] -> Maybe Text
lastEl n = fromNode <$> safe head n
toStmnt :: (Graph gr) => gr Gate e -> LNode Gate -> Text
toStmnt graph (n, g) =
- fromMaybe T.empty $ Just " assign " <> Just (fromNode n)
- <> Just " = " <> statList g nodeL <> lastEl nodeL <> Just ";\n"
- where
- nodeL = pre graph n
+ fromMaybe T.empty
+ $ Just " assign "
+ <> Just (fromNode n)
+ <> Just " = "
+ <> statList g nodeL
+ <> lastEl nodeL
+ <> Just ";\n"
+ where nodeL = pre graph n
generate :: (Graph gr) => gr Gate e -> Text
generate graph =
"module generated_module(\n"
- <> fold (imap " input wire " ",\n" inp)
- <> T.intercalate ",\n" (imap " output wire " "" out)
- <> ");\n"
- <> fold (toStmnt graph <$> labNodes graph)
- <> "endmodule\n\nmodule main;\n initial\n begin\n "
- <> "$display(\"Hello, world\");\n $finish;\n "
- <> "end\nendmodule"
- where
- inp = inputs graph
- out = outputs graph
- imap b e = fmap ((\s -> b <> s <> e) . fromNode)
+ <> fold (imap " input wire " ",\n" inp)
+ <> T.intercalate ",\n" (imap " output wire " "" out)
+ <> ");\n"
+ <> fold (toStmnt graph <$> labNodes graph)
+ <> "endmodule\n\nmodule main;\n initial\n begin\n "
+ <> "$display(\"Hello, world\");\n $finish;\n "
+ <> "end\nendmodule"
+ where
+ inp = inputs graph
+ out = outputs graph
+ imap b e = fmap ((\s -> b <> s <> e) . fromNode)
diff --git a/src/VeriFuzz/Graph/Random.hs b/src/VeriFuzz/Graph/Random.hs
index ef0a0c5..5b36c48 100644
--- a/src/VeriFuzz/Graph/Random.hs
+++ b/src/VeriFuzz/Graph/Random.hs
@@ -12,18 +12,21 @@ Define the random generation for the directed acyclic graph.
module VeriFuzz.Graph.Random where
-import Data.Graph.Inductive (Context, LEdge)
-import qualified Data.Graph.Inductive as G
-import Data.Graph.Inductive.PatriciaTree (Gr)
-import Data.List (nub)
-import Test.QuickCheck (Arbitrary, Gen)
-import qualified Test.QuickCheck as QC
+import Data.Graph.Inductive ( Context
+ , LEdge
+ )
+import qualified Data.Graph.Inductive as G
+import Data.Graph.Inductive.PatriciaTree
+ ( Gr )
+import Data.List ( nub )
+import Test.QuickCheck ( Arbitrary
+ , Gen
+ )
+import qualified Test.QuickCheck as QC
dupFolder :: (Eq a, Eq b) => Context a b -> [Context a b] -> [Context a b]
-dupFolder cont ns =
- unique cont : ns
- where
- unique (a, b, c, d) = (nub a, b, c, nub d)
+dupFolder cont ns = unique cont : ns
+ where unique (a, b, c, d) = (nub a, b, c, nub d)
-- | Remove duplicates.
rDups :: (Eq a, Eq b) => Gr a b -> Gr a b
@@ -33,26 +36,23 @@ rDups g = G.buildGr $ G.ufold dupFolder [] g
-- `n` that is passed to it.
arbitraryEdge :: (Arbitrary e) => Int -> Gen (LEdge e)
arbitraryEdge n = do
- x <- with $ \a -> a < n && a > 0 && a /= n-1
+ x <- with $ \a -> a < n && a > 0 && a /= n - 1
y <- with $ \a -> x < a && a < n && a > 0
z <- QC.arbitrary
return (x, y, z)
- where
- with = QC.suchThat $ QC.resize n QC.arbitrary
+ where with = QC.suchThat $ QC.resize n QC.arbitrary
-- | Gen instance for a random acyclic DAG.
-randomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e)
- => Gen (Gr l e) -- ^ The generated graph. It uses Arbitrary to
+randomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e) => Gen (Gr l e) -- ^ The generated graph. It uses Arbitrary to
-- generate random instances of each node
randomDAG = do
list <- QC.infiniteListOf QC.arbitrary
- l <- QC.infiniteListOf aE
- QC.sized (\n -> return . G.mkGraph (nodes list n) $ take (10*n) l)
- where
- nodes l n = zip [0..n] $ take n l
- aE = QC.sized arbitraryEdge
+ l <- QC.infiniteListOf aE
+ QC.sized (\n -> return . G.mkGraph (nodes list n) $ take (10 * n) l)
+ where
+ nodes l n = zip [0 .. n] $ take n l
+ aE = QC.sized arbitraryEdge
-- | Generate a random acyclic DAG with an IO instance.
-genRandomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e)
- => IO (Gr l e)
+genRandomDAG :: (Arbitrary l, Arbitrary e, Eq l, Eq e) => IO (Gr l e)
genRandomDAG = QC.generate randomDAG
diff --git a/src/VeriFuzz/Graph/RandomAlt.hs b/src/VeriFuzz/Graph/RandomAlt.hs
index 21ef678..c5fad9e 100644
--- a/src/VeriFuzz/Graph/RandomAlt.hs
+++ b/src/VeriFuzz/Graph/RandomAlt.hs
@@ -12,17 +12,18 @@ Define the random generation for the directed acyclic graph.
module VeriFuzz.Graph.RandomAlt where
-import qualified Data.Graph.Inductive.Arbitrary as G
-import Data.Graph.Inductive.PatriciaTree (Gr)
-import Test.QuickCheck (Arbitrary, Gen)
-import qualified Test.QuickCheck as QC
+import qualified Data.Graph.Inductive.Arbitrary
+ as G
+import Data.Graph.Inductive.PatriciaTree
+ ( Gr )
+import Test.QuickCheck ( Arbitrary
+ , Gen
+ )
+import qualified Test.QuickCheck as QC
-randomDAG :: (Arbitrary l, Arbitrary e)
- => Gen (Gr l e)
-randomDAG =
- G.looplessGraph <$> QC.arbitrary
+randomDAG :: (Arbitrary l, Arbitrary e) => Gen (Gr l e)
+randomDAG = G.looplessGraph <$> QC.arbitrary
-- | Generate a random acyclic DAG with an IO instance.
-genRandomDAG :: (Arbitrary l, Arbitrary e)
- => IO (Gr l e)
+genRandomDAG :: (Arbitrary l, Arbitrary e) => IO (Gr l e)
genRandomDAG = QC.generate randomDAG
diff --git a/src/VeriFuzz/Internal/Gen.hs b/src/VeriFuzz/Internal/Gen.hs
index be275dd..6e44524 100644
--- a/src/VeriFuzz/Internal/Gen.hs
+++ b/src/VeriFuzz/Internal/Gen.hs
@@ -12,18 +12,25 @@ Internal helpers for generation.
module VeriFuzz.Internal.Gen where
-import Data.Graph.Inductive (Graph, Node)
-import qualified Data.Graph.Inductive as G
-import qualified Data.Text as T
+import Data.Graph.Inductive ( Graph
+ , Node
+ )
+import qualified Data.Graph.Inductive as G
+import qualified Data.Text as T
fromNode :: Int -> T.Text
fromNode node = T.pack $ "w" <> show node
filterGr :: (Graph gr) => gr n e -> (Node -> Bool) -> [Node]
-filterGr graph f =
- filter f $ G.nodes graph
-
-only :: (Graph gr) => gr n e -> (gr n e -> Node -> Int) -> (gr n e -> Node -> Int) -> Node -> Bool
+filterGr graph f = filter f $ G.nodes graph
+
+only
+ :: (Graph gr)
+ => gr n e
+ -> (gr n e -> Node -> Int)
+ -> (gr n e -> Node -> Int)
+ -> Node
+ -> Bool
only graph fun1 fun2 n = fun1 graph n == 0 && fun2 graph n /= 0
inputs :: (Graph gr) => gr n e -> [Node]
diff --git a/src/VeriFuzz/Simulator.hs b/src/VeriFuzz/Simulator.hs
index 0a2cf44..0692c31 100644
--- a/src/VeriFuzz/Simulator.hs
+++ b/src/VeriFuzz/Simulator.hs
@@ -15,7 +15,8 @@ module VeriFuzz.Simulator
, module VeriFuzz.Simulator.Yosys
, module VeriFuzz.Simulator.Xst
, module VeriFuzz.Simulator.Icarus
- ) where
+ )
+where
import VeriFuzz.Simulator.General
import VeriFuzz.Simulator.Icarus
diff --git a/src/VeriFuzz/Simulator/General.hs b/src/VeriFuzz/Simulator/General.hs
index 3615d3a..9001bf9 100644
--- a/src/VeriFuzz/Simulator/General.hs
+++ b/src/VeriFuzz/Simulator/General.hs
@@ -12,11 +12,11 @@ Class of the simulator and the synthesize tool.
module VeriFuzz.Simulator.General where
-import Data.Bits (shiftL)
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import Data.Text (Text)
-import Prelude hiding (FilePath)
+import Data.Bits ( shiftL )
+import Data.ByteString ( ByteString )
+import qualified Data.ByteString as B
+import Data.Text ( Text )
+import Prelude hiding ( FilePath )
import Shelly
import VeriFuzz.Verilog.AST
diff --git a/src/VeriFuzz/Simulator/Icarus.hs b/src/VeriFuzz/Simulator/Icarus.hs
index 1f5ad38..443f096 100644
--- a/src/VeriFuzz/Simulator/Icarus.hs
+++ b/src/VeriFuzz/Simulator/Icarus.hs
@@ -13,12 +13,12 @@ Icarus verilog module.
module VeriFuzz.Simulator.Icarus where
import Control.Lens
-import Data.ByteString (ByteString)
-import qualified Data.ByteString as B
-import Data.Foldable (fold)
+import Data.ByteString ( ByteString )
+import qualified Data.ByteString as B
+import Data.Foldable ( fold )
import Data.Hashable
-import Data.List (transpose)
-import Prelude hiding (FilePath)
+import Data.List ( transpose )
+import Prelude hiding ( FilePath )
import Shelly
import VeriFuzz.Simulator.General
import VeriFuzz.Verilog
@@ -37,26 +37,29 @@ defaultIcarus :: Icarus
defaultIcarus = Icarus "iverilog" "vvp"
addDisplay :: [Stmnt] -> [Stmnt]
-addDisplay s =
- concat $ transpose [s, replicate l $ TimeCtrl 1 Nothing
- , replicate l . SysTaskEnable $ Task "display" ["%h", Id "y"]]
- where
- l = length s
+addDisplay s = concat $ transpose
+ [ s
+ , replicate l $ TimeCtrl 1 Nothing
+ , replicate l . SysTaskEnable $ Task "display" ["%h", Id "y"]
+ ]
+ where l = length s
assignFunc :: [Port] -> ByteString -> Stmnt
assignFunc inp bs =
NonBlockAssign . Assign conc Nothing . Number (B.length bs * 4) $ bsToI bs
- where
- conc = RegConcat (portToExpr <$> inp)
+ where conc = RegConcat (portToExpr <$> inp)
runSimIcarus :: Icarus -> ModDecl -> [ByteString] -> Sh Int
runSimIcarus sim m bss = do
- let tb = ModDecl "main" [] []
- [ Initial $
- fold (addDisplay $ assignFunc (m ^. modInPorts) <$> bss)
+ let tb = ModDecl
+ "main"
+ []
+ []
+ [ Initial
+ $ fold (addDisplay $ assignFunc (m ^. modInPorts) <$> bss)
<> (SysTaskEnable $ Task "finish" [])
]
- let newtb = instantiateMod m tb
+ let newtb = instantiateMod m tb
let modWithTb = VerilogSrc $ Description <$> [newtb, m]
writefile "main.v" $ genSource modWithTb
run_ (icarusPath sim) ["-o", "main", "main.v"]
diff --git a/src/VeriFuzz/Simulator/Xst.hs b/src/VeriFuzz/Simulator/Xst.hs
index 16e9b97..3209caf 100644
--- a/src/VeriFuzz/Simulator/Xst.hs
+++ b/src/VeriFuzz/Simulator/Xst.hs
@@ -14,10 +14,10 @@ Xst (ise) simulator implementation.
module VeriFuzz.Simulator.Xst where
-import Control.Lens hiding ((<.>))
-import Prelude hiding (FilePath)
+import Control.Lens hiding ( (<.>) )
+import Prelude hiding ( FilePath )
import Shelly
-import Text.Shakespeare.Text (st)
+import Text.Shakespeare.Text ( st )
import VeriFuzz.Simulator.General
import VeriFuzz.Verilog.AST
import VeriFuzz.Verilog.CodeGen
@@ -33,8 +33,10 @@ instance Synthesize Xst where
runSynth = runSynthXst
defaultXst :: Xst
-defaultXst = Xst "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xst" "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/netgen"
+defaultXst = Xst "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/xst"
+ "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/netgen"
+-- brittany-disable-next-binding
runSynthXst :: Xst -> ModDecl -> FilePath -> Sh ()
runSynthXst sim m outf = do
writefile xstFile [st|run
diff --git a/src/VeriFuzz/Simulator/Yosys.hs b/src/VeriFuzz/Simulator/Yosys.hs
index af950f2..028fbb2 100644
--- a/src/VeriFuzz/Simulator/Yosys.hs
+++ b/src/VeriFuzz/Simulator/Yosys.hs
@@ -15,10 +15,10 @@ Yosys simulator implementation.
module VeriFuzz.Simulator.Yosys where
import Control.Lens
-import Data.Text (Text)
-import Prelude hiding (FilePath)
+import Data.Text ( Text )
+import Prelude hiding ( FilePath )
import Shelly
-import Text.Shakespeare.Text (st)
+import Text.Shakespeare.Text ( st )
import VeriFuzz.Simulator.General
import VeriFuzz.Verilog
@@ -33,6 +33,7 @@ instance Synthesize Yosys where
defaultYosys :: Yosys
defaultYosys = Yosys "/usr/bin/yosys"
+-- brittany-disable-next-binding
writeSimFile :: Yosys -- ^ Simulator instance
-> ModDecl -- ^ Current module
-> FilePath -- ^ Output sim file
@@ -47,11 +48,12 @@ runSynthYosys :: Yosys -> ModDecl -> FilePath -> Sh ()
runSynthYosys sim m outf = do
writefile inpf $ genSource m
run_ (yosysPath sim) ["-q", "-b", "verilog -noattr", "-o", out, "-S", inp]
- where
- inpf = "rtl.v"
- inp = toTextIgnore inpf
- out = toTextIgnore outf
+ where
+ inpf = "rtl.v"
+ inp = toTextIgnore inpf
+ out = toTextIgnore outf
+-- brittany-disable-next-binding
writeSatFile :: (Synthesize a, Synthesize b) => Text -> a -> Maybe b -> ModDecl -> Sh ()
writeSatFile checkFile sim1 sim2 m =
writefile (fromText checkFile) [st|read_verilog syn_#{toText sim1}.v
@@ -69,10 +71,12 @@ sat -timeout 20 -verify-no-timeout -ignore_div_by_zero -prove y_1 y_2 #{modName}
modName = m ^. moduleId . getIdentifier
-- ids = T.intercalate "," $ allVars m ^.. traverse . getIdentifier
+-- brittany-disable-next-binding
runOtherSynth :: (Synthesize a) => Maybe a -> ModDecl -> Sh ()
runOtherSynth (Just sim) m = runSynth sim m $ fromText [st|syn_#{toText sim}.v|]
runOtherSynth Nothing m = writefile "syn_rtl.v" $ genSource m
+-- brittany-disable-next-binding
runEquiv :: (Synthesize a, Synthesize b) => Yosys -> a -> Maybe b -> ModDecl -> Sh ()
runEquiv yosys sim1 sim2 m = do
writefile "top.v" . genSource . initMod $ makeTop 2 m
diff --git a/src/VeriFuzz/Verilog.hs b/src/VeriFuzz/Verilog.hs
index 4e8ed22..6b6a13f 100644
--- a/src/VeriFuzz/Verilog.hs
+++ b/src/VeriFuzz/Verilog.hs
@@ -18,7 +18,8 @@ module VeriFuzz.Verilog
-- * Verilog mutations
, module VeriFuzz.Verilog.Mutate
, module VeriFuzz.Verilog.Helpers
- ) where
+ )
+where
import VeriFuzz.Verilog.AST
import VeriFuzz.Verilog.CodeGen
diff --git a/src/VeriFuzz/Verilog/AST.hs b/src/VeriFuzz/Verilog/AST.hs
index 35f678f..dd61f03 100644
--- a/src/VeriFuzz/Verilog/AST.hs
+++ b/src/VeriFuzz/Verilog/AST.hs
@@ -15,53 +15,112 @@ Defines the types to build a Verilog AST.
module VeriFuzz.Verilog.AST
( -- * Top level types
- VerilogSrc(..), getVerilogSrc
- , Description(..), getDescription
+ VerilogSrc(..)
+ , getVerilogSrc
+ , Description(..)
+ , getDescription
-- * Primitives
-- ** Identifier
- , Identifier(..), getIdentifier
+ , Identifier(..)
+ , getIdentifier
-- ** Control
- , Delay(..), getDelay
+ , Delay(..)
+ , getDelay
, Event(..)
-- ** Operators
, BinaryOperator(..)
, UnaryOperator(..)
-- ** Task
- , Task(..), taskName, taskExpr
+ , Task(..)
+ , taskName
+ , taskExpr
-- ** Left hand side value
- , LVal(..), regId, regExprId, regExpr, regSizeId, regSizeMSB
- , regSizeLSB, regConc
+ , LVal(..)
+ , regId
+ , regExprId
+ , regExpr
+ , regSizeId
+ , regSizeMSB
+ , regSizeLSB
+ , regConc
-- ** Ports
, PortDir(..)
- , PortType(..), regSigned
- , Port(..), portType, portSize, portName
+ , PortType(..)
+ , regSigned
+ , Port(..)
+ , portType
+ , portSize
+ , portName
-- * Expression
- , Expr(..), exprSize, exprVal, exprId, exprConcat
- , exprUnOp, exprPrim, exprLhs, exprBinOp, exprRhs
- , exprCond, exprTrue, exprFalse, exprStr, traverseExpr
- , ConstExpr(..), constNum
+ , Expr(..)
+ , exprSize
+ , exprVal
+ , exprId
+ , exprConcat
+ , exprUnOp
+ , exprPrim
+ , exprLhs
+ , exprBinOp
+ , exprRhs
+ , exprCond
+ , exprTrue
+ , exprFalse
+ , exprStr
+ , traverseExpr
+ , ConstExpr(..)
+ , constNum
-- * Assignment
- , Assign(..), assignReg, assignDelay, assignExpr
- , ContAssign(..), contAssignNetLVal, contAssignExpr
+ , Assign(..)
+ , assignReg
+ , assignDelay
+ , assignExpr
+ , ContAssign(..)
+ , contAssignNetLVal
+ , contAssignExpr
-- * Statment
- , Stmnt(..), statDelay, statDStat, statEvent, statEStat, statements
- , stmntBA, stmntNBA, stmntCA, stmntTask, stmntSysTask
+ , Stmnt(..)
+ , statDelay
+ , statDStat
+ , statEvent
+ , statEStat
+ , statements
+ , stmntBA
+ , stmntNBA
+ , stmntCA
+ , stmntTask
+ , stmntSysTask
-- * Module
- , ModDecl(..), moduleId, modOutPorts, modInPorts, modItems
- , ModItem(..), _ModCA, modInstId, modInstName, modInstConns, declDir, declPort
- , ModConn(..), modConn
- ) where
-
-import Control.Lens (makeLenses, makePrisms)
-import Control.Monad (replicateM)
-import Data.String (IsString, fromString)
-import Data.Text (Text)
-import qualified Data.Text as T
-import Data.Traversable (sequenceA)
-import qualified Test.QuickCheck as QC
+ , ModDecl(..)
+ , moduleId
+ , modOutPorts
+ , modInPorts
+ , modItems
+ , ModItem(..)
+ , _ModCA
+ , modInstId
+ , modInstName
+ , modInstConns
+ , declDir
+ , declPort
+ , ModConn(..)
+ , modConn
+ )
+where
+
+import Control.Lens ( makeLenses
+ , makePrisms
+ )
+import Control.Monad ( replicateM )
+import Data.String ( IsString
+ , fromString
+ )
+import Data.Text ( Text )
+import qualified Data.Text as T
+import Data.Traversable ( sequenceA )
+import qualified Test.QuickCheck as QC
positiveArb :: (QC.Arbitrary a, Ord a, Num a) => QC.Gen a
-positiveArb = QC.suchThat QC.arbitrary (>0)
+positiveArb = QC.suchThat QC.arbitrary (> 0)
-- | Identifier in Verilog. This is just a string of characters that can either
-- be lowercase and uppercase for now. This might change in the future though,
@@ -232,23 +291,24 @@ expr n
[ Id <$> QC.arbitrary
, Number <$> positiveArb <*> QC.arbitrary
, Concat <$> QC.listOf1 (subexpr 4)
- , UnOp <$> QC.arbitrary <*> QC.arbitrary
+ , UnOp
+ <$> QC.arbitrary
+ <*> QC.arbitrary
-- , Str <$> QC.arbitrary
, BinOp <$> subexpr 2 <*> QC.arbitrary <*> subexpr 2
, Cond <$> subexpr 3 <*> subexpr 3 <*> subexpr 3
]
| otherwise = expr 0
- where
- subexpr y = expr (n `div` y)
+ where subexpr y = expr (n `div` y)
instance QC.Arbitrary Expr where
arbitrary = QC.sized expr
traverseExpr :: (Applicative f) => (Expr -> f Expr) -> Expr -> f Expr
-traverseExpr f (Concat e) = Concat <$> sequenceA (f <$> e)
-traverseExpr f (UnOp un e) = UnOp un <$> f e
+traverseExpr f (Concat e ) = Concat <$> sequenceA (f <$> e)
+traverseExpr f (UnOp un e ) = UnOp un <$> f e
traverseExpr f (BinOp l op r) = BinOp <$> f l <*> pure op <*> f r
-traverseExpr f (Cond c l r) = Cond <$> f c <*> f l <*> f r
+traverseExpr f (Cond c l r) = Cond <$> f c <*> f l <*> f r
traverseExpr _ e = pure e
makeLenses ''Expr
@@ -409,8 +469,7 @@ statement n
, SysTaskEnable <$> QC.arbitrary
]
| otherwise = statement 0
- where
- substat y = statement (n `div` y)
+ where substat y = statement (n `div` y)
instance QC.Arbitrary Stmnt where
arbitrary = QC.sized statement
diff --git a/src/VeriFuzz/Verilog/CodeGen.hs b/src/VeriFuzz/Verilog/CodeGen.hs
index fbc2fc1..338838f 100644
--- a/src/VeriFuzz/Verilog/CodeGen.hs
+++ b/src/VeriFuzz/Verilog/CodeGen.hs
@@ -15,12 +15,14 @@ This module generates the code from the Verilog AST defined in
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 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 VeriFuzz.Verilog.AST
-- | 'Source' class which determines that source code is able to be generated
@@ -44,29 +46,30 @@ 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
+genVerilogSrc source = fold $ genDescription <$> source ^. getVerilogSrc
-- | Generate the 'Description' to 'Text'.
genDescription :: Description -> Text
-genDescription desc =
- genModuleDecl $ desc ^. getDescription
+genDescription desc = genModuleDecl $ desc ^. getDescription
-- | Generate the 'ModDecl' for a module and convert it to 'Text'.
genModuleDecl :: ModDecl -> Text
genModuleDecl m =
- "module " <> m ^. moduleId . 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)
+ "module "
+ <> m
+ ^. moduleId
+ . 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.
@@ -75,14 +78,12 @@ 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
+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
@@ -96,30 +97,26 @@ genModuleItem (ModCA ca) = genContAssign ca
genModuleItem (ModInst (Identifier i) (Identifier name) conn) =
i <> " " <> name <> "(" <> comma (genExpr . _modConn <$> conn) <> ")" <> ";\n"
genModuleItem (Initial stat) = "initial " <> genStmnt stat
-genModuleItem (Always stat) = "always " <> genStmnt stat
+genModuleItem (Always stat) = "always " <> genStmnt stat
genModuleItem (Decl dir port) =
(maybe "" makePort dir) <> genPort port <> ";\n"
- where
- makePort = (<>" ") . genPortDir
+ where makePort = (<> " ") . genPortDir
-- | Generate continuous assignment
genContAssign :: ContAssign -> Text
-genContAssign (ContAssign val e) =
- "assign " <> name <> " = " <> expr <> ";\n"
- where
- name = val ^. getIdentifier
- expr = genExpr e
+genContAssign (ContAssign val e) = "assign " <> name <> " = " <> expr <> ";\n"
+ where
+ name = val ^. getIdentifier
+ expr = genExpr e
-- | Generate 'Expr' to 'Text'.
genExpr :: Expr -> Text
genExpr (BinOp eRhs bin eLhs) =
"(" <> genExpr eRhs <> genBinaryOperator bin <> genExpr eLhs <> ")"
-genExpr (Number s n) =
- showT s <> "'h" <> T.pack (showHex n "")
-genExpr (Id i) = i ^. getIdentifier
-genExpr (Concat c) = "{" <> comma (genExpr <$> c) <> "}"
-genExpr (UnOp u e) =
- "(" <> genUnaryOperator u <> genExpr e <> ")"
+genExpr (Number s n) = showT s <> "'h" <> T.pack (showHex n "")
+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 (Str t) = "\"" <> t <> "\""
@@ -167,7 +164,7 @@ genUnaryOperator UnNxorInv = "^~"
-- | Generate verilog code for an 'Event'.
genEvent :: Event -> Text
-genEvent (EId i) = "@(" <> i ^. getIdentifier <> ")"
+genEvent (EId i ) = "@(" <> i ^. getIdentifier <> ")"
genEvent (EExpr expr) = "@(" <> genExpr expr <> ")"
genEvent EAll = "@*"
@@ -177,44 +174,45 @@ 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 (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) <> "}"
+ 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"
+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"
+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
+ where i = name ^. getIdentifier
-- | Render the 'Text' to 'IO'. This is equivalent to 'putStrLn'.
render :: (Source a) => a -> IO ()
diff --git a/src/VeriFuzz/Verilog/Helpers.hs b/src/VeriFuzz/Verilog/Helpers.hs
index 554b8ba..53d219b 100644
--- a/src/VeriFuzz/Verilog/Helpers.hs
+++ b/src/VeriFuzz/Verilog/Helpers.hs
@@ -13,7 +13,7 @@ Defaults and common functions.
module VeriFuzz.Verilog.Helpers where
import Control.Lens
-import Data.Text (Text)
+import Data.Text ( Text )
import VeriFuzz.Verilog.AST
regDecl :: Identifier -> ModItem
@@ -38,16 +38,16 @@ addDescription :: Description -> VerilogSrc -> VerilogSrc
addDescription desc = getVerilogSrc %~ (:) desc
testBench :: ModDecl
-testBench =
- ModDecl "main" [] []
+testBench = ModDecl
+ "main"
+ []
+ []
[ regDecl "a"
, regDecl "b"
, wireDecl "c"
- , ModInst "and" "and_gate"
- [ ModConn $ Id "c"
- , ModConn $ Id "a"
- , ModConn $ Id "b"
- ]
+ , ModInst "and"
+ "and_gate"
+ [ModConn $ Id "c", ModConn $ Id "a", ModConn $ Id "b"]
, Initial $ SeqBlock
[ BlockAssign . Assign (RegId "a") Nothing $ Number 1 1
, BlockAssign . Assign (RegId "b") Nothing $ Number 1 1
diff --git a/src/VeriFuzz/Verilog/Mutate.hs b/src/VeriFuzz/Verilog/Mutate.hs
index eddb93a..bca1c39 100644
--- a/src/VeriFuzz/Verilog/Mutate.hs
+++ b/src/VeriFuzz/Verilog/Mutate.hs
@@ -14,7 +14,9 @@ more random patterns, such as nesting wires instead of creating new ones.
module VeriFuzz.Verilog.Mutate where
import Control.Lens
-import Data.Maybe (catMaybes, fromMaybe)
+import Data.Maybe ( catMaybes
+ , fromMaybe
+ )
import VeriFuzz.Internal.Gen
import VeriFuzz.Internal.Shared
import VeriFuzz.Verilog.AST
@@ -23,27 +25,25 @@ import VeriFuzz.Verilog.CodeGen
-- | Return if the 'Identifier' is in a 'ModDecl'.
inPort :: Identifier -> ModDecl -> Bool
inPort i m = inInput
- where
- inInput = any (\a -> a ^. portName == i) $ m ^. modInPorts ++ m ^. modOutPorts
+ where
+ inInput =
+ any (\a -> a ^. portName == i) $ m ^. modInPorts ++ m ^. modOutPorts
-- | Find the last assignment of a specific wire/reg to an expression, and
-- returns that expression.
findAssign :: Identifier -> [ModItem] -> Maybe Expr
-findAssign i items =
- safe last . catMaybes $ isAssign <$> items
- where
- isAssign (ModCA (ContAssign val expr))
- | val == i = Just expr
- | otherwise = Nothing
- isAssign _ = Nothing
+findAssign i items = safe last . catMaybes $ isAssign <$> items
+ where
+ isAssign (ModCA (ContAssign val expr)) | val == i = Just expr
+ | otherwise = Nothing
+ isAssign _ = Nothing
-- | Transforms an expression by replacing an Identifier with an
-- expression. This is used inside 'transformOf' and 'traverseExpr' to replace
-- the 'Identifier' recursively.
idTrans :: Identifier -> Expr -> Expr -> Expr
-idTrans i expr (Id id')
- | id' == i = expr
- | otherwise = Id id'
+idTrans i expr (Id id') | id' == i = expr
+ | otherwise = Id id'
idTrans _ _ e = e
-- | Replaces the identifier recursively in an expression.
@@ -58,27 +58,28 @@ replace = (transformOf traverseExpr .) . idTrans
-- expression. This would require a different approach though.
nestId :: Identifier -> ModDecl -> ModDecl
nestId i m
- | not $ inPort i m =
- let expr = fromMaybe def . findAssign i $ m ^. modItems
- in m & get %~ replace i expr
- | otherwise = m
- where
- get = modItems . traverse . _ModCA . contAssignExpr
- def = Id i
+ | not $ inPort i m
+ = let expr = fromMaybe def . findAssign i $ m ^. modItems
+ in m & get %~ replace i expr
+ | otherwise
+ = m
+ where
+ get = modItems . traverse . _ModCA . contAssignExpr
+ def = Id i
-- | Replaces an identifier by a expression in all the module declaration.
nestSource :: Identifier -> VerilogSrc -> VerilogSrc
-nestSource i src =
- src & getVerilogSrc . traverse . getDescription %~ nestId i
+nestSource i src = src & getVerilogSrc . traverse . getDescription %~ nestId i
-- | Nest variables in the format @w[0-9]*@ up to a certain number.
nestUpTo :: Int -> VerilogSrc -> VerilogSrc
nestUpTo i src =
- foldl (flip nestSource) src $ Identifier . fromNode <$> [1..i]
+ foldl (flip nestSource) src $ Identifier . fromNode <$> [1 .. i]
allVars :: ModDecl -> [Identifier]
allVars m =
- (m ^.. modOutPorts . traverse . portName) ++ (m ^.. modInPorts . traverse . portName)
+ (m ^.. modOutPorts . traverse . portName)
+ ++ (m ^.. modInPorts . traverse . portName)
-- $setup
-- >>> let m = (ModDecl (Identifier "m") [Port Wire 5 (Identifier "y")] [Port Wire 5 "x"] [])
-- >>> let main = (ModDecl "main" [] [] [])
@@ -95,14 +96,21 @@ allVars m =
-- endmodule
-- <BLANKLINE>
instantiateMod :: ModDecl -> ModDecl -> ModDecl
-instantiateMod m main =
- main & modItems %~ ((out ++ regIn ++ [inst])++)
- where
- out = Decl Nothing <$> m ^. modOutPorts
- regIn = Decl Nothing <$> (m ^. modInPorts & traverse . portType .~ Reg False)
- inst = ModInst (m ^. moduleId) (m ^. moduleId <> (Identifier . showT $ count+1)) conns
- count = length . filter (==m ^. moduleId) $ main ^.. modItems . traverse . modInstId
- conns = ModConn . Id <$> allVars m
+instantiateMod m main = main & modItems %~ ((out ++ regIn ++ [inst]) ++)
+ where
+ out = Decl Nothing <$> m ^. modOutPorts
+ regIn = Decl Nothing <$> (m ^. modInPorts & traverse . portType .~ Reg False)
+ inst = ModInst (m ^. moduleId)
+ (m ^. moduleId <> (Identifier . showT $ count + 1))
+ conns
+ count =
+ length
+ . filter (== m ^. moduleId)
+ $ main
+ ^.. modItems
+ . traverse
+ . modInstId
+ conns = ModConn . Id <$> allVars m
-- | Instantiate without adding wire declarations. It also does not count the
-- current instantiations of the same module.
@@ -111,11 +119,13 @@ instantiateMod m main =
-- m m(y, x);
-- <BLANKLINE>
instantiateMod_ :: ModDecl -> ModItem
-instantiateMod_ m =
- ModInst (m ^. moduleId) (m ^. moduleId) conns
- where
- conns = ModConn . Id <$>
- (m ^.. modOutPorts . traverse . portName) ++ (m ^.. modInPorts . traverse . portName)
+instantiateMod_ m = ModInst (m ^. moduleId) (m ^. moduleId) conns
+ where
+ conns =
+ ModConn
+ . Id
+ <$> (m ^.. modOutPorts . traverse . portName)
+ ++ (m ^.. modInPorts . traverse . portName)
-- | Initialise all the inputs and outputs to a module.
--
@@ -126,23 +136,24 @@ instantiateMod_ m =
-- endmodule
-- <BLANKLINE>
initMod :: ModDecl -> ModDecl
-initMod m = m & modItems %~ ((out ++ inp)++)
- where
- out = Decl (Just PortOut) <$> (m ^. modOutPorts)
- inp = Decl (Just PortIn) <$> (m ^. modInPorts)
+initMod m = m & modItems %~ ((out ++ inp) ++)
+ where
+ out = Decl (Just PortOut) <$> (m ^. modOutPorts)
+ inp = Decl (Just PortIn) <$> (m ^. modInPorts)
makeIdFrom :: (Show a) => a -> Identifier -> Identifier
-makeIdFrom a i =
- (i<>) . Identifier . ("_"<>) $ showT a
+makeIdFrom a i = (i <>) . Identifier . ("_" <>) $ showT a
-- | Make top level module for equivalence verification. Also takes in how many
-- modules to instantiate.
makeTop :: Int -> ModDecl -> ModDecl
-makeTop i m =
- ModDecl (m ^. moduleId) ys (m ^. modInPorts) modIt
- where
- ys = Port Wire 90 . (flip makeIdFrom) "y" <$> [1..i]
- modIt = instantiateMod_ . modN <$> [1..i]
- modN n = m
- & moduleId %~ makeIdFrom n
- & modOutPorts .~ [Port Wire 90 (makeIdFrom n "y")]
+makeTop i m = ModDecl (m ^. moduleId) ys (m ^. modInPorts) modIt
+ where
+ ys = Port Wire 90 . (flip makeIdFrom) "y" <$> [1 .. i]
+ modIt = instantiateMod_ . modN <$> [1 .. i]
+ modN n =
+ m
+ & moduleId
+ %~ makeIdFrom n
+ & modOutPorts
+ .~ [Port Wire 90 (makeIdFrom n "y")]