{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE LambdaCase #-}
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module ConCat.Hardware.Verilog
( genVerilog,runVerilog
) where
import Control.Arrow (first, second)
import Data.List ( intersect, nub)
import System.Directory (createDirectoryIfMissing)
import Text.PrettyPrint.HughesPJClass hiding (first)
import Language.Netlist.AST
import Language.Netlist.Util
import Language.Netlist.GenVerilog
import Language.Verilog.PrettyPrint
import ConCat.Circuit
(Bus(..),GenBuses,(:>),simpleComp,mkGraph,CompS(..),busTy)
import qualified ConCat.Circuit as C
effectVerilog :: (GenBuses a, GenBuses b) => String -> (a :> b) -> String
effectVerilog :: forall a b.
(GenBuses a, GenBuses b) =>
String -> (a :> b) -> String
effectVerilog String
name a :> b
circ = [String] -> String
unlines
[ String
"/***"
, String
"* Automatically generated Verilog code. Do not edit."
, String
"*"
, String
"* This code was generated by the Haskell ConCat library, via compiling to categories."
, String
"***/"
, Doc -> String
render (Doc -> String) -> Doc -> String
forall a b. (a -> b) -> a -> b
$ Module -> Doc
ppModule (Module -> Doc) -> Module -> Doc
forall a b. (a -> b) -> a -> b
$ Module -> Module
mk_module (String -> (a :> b) -> Module
forall a b.
(GenBuses a, GenBuses b) =>
String -> (a :> b) -> Module
verilog String
name a :> b
circ)
]
genVerilog :: (GenBuses a, GenBuses b) => String -> (a :> b) -> IO ()
genVerilog :: forall a b. (GenBuses a, GenBuses b) => String -> (a :> b) -> IO ()
genVerilog String
name a :> b
circ =
do Bool -> String -> IO ()
createDirectoryIfMissing Bool
False String
outDir
let o :: String
o = String -> String
outFile String
name
String -> String -> IO ()
writeFile String
o (String -> (a :> b) -> String
forall a b.
(GenBuses a, GenBuses b) =>
String -> (a :> b) -> String
effectVerilog String
name a :> b
circ)
String -> IO ()
putStrLn (String
"Wrote " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
o)
runVerilog :: (GenBuses a, GenBuses b) => String -> (a :> b) -> IO ()
runVerilog :: forall a b. (GenBuses a, GenBuses b) => String -> (a :> b) -> IO ()
runVerilog String
name a :> b
circ =
do String -> (a :> b) -> IO ()
forall a b. (GenBuses a, GenBuses b) => String -> (a :> b) -> IO ()
genVerilog String
name a :> b
circ
outDir :: String
outDir :: String
outDir = String
"out"
outFile :: String -> String
outFile :: String -> String
outFile String
name = String
outDirString -> String -> String
forall a. [a] -> [a] -> [a]
++String
"/"String -> String -> String
forall a. [a] -> [a] -> [a]
++String
nameString -> String -> String
forall a. [a] -> [a] -> [a]
++String
".v"
verilog :: (GenBuses a, GenBuses b) => String -> (a :> b) -> Module
verilog :: forall a b.
(GenBuses a, GenBuses b) =>
String -> (a :> b) -> Module
verilog String
name = String -> [CompS] -> Module
mkModule String
name
([CompS] -> Module) -> ((a :> b) -> [CompS]) -> (a :> b) -> Module
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Comp -> CompS) -> [Comp] -> [CompS]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Comp -> CompS
simpleComp
([Comp] -> [CompS]) -> ((a :> b) -> [Comp]) -> (a :> b) -> [CompS]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a :> b) -> [Comp]
forall a b. Ok2 (:>) a b => (a :> b) -> [Comp]
mkGraph
mkModule :: String -> [CompS] -> Module
mkModule :: String -> [CompS] -> Module
mkModule String
name [CompS]
cs = String
-> [(String, Maybe Range)]
-> [(String, Maybe Range)]
-> [(String, ConstExpr)]
-> [Decl]
-> Module
Module String
name
((String
"clk", Maybe Range
forall a. Maybe a
Nothing) (String, Maybe Range)
-> [(String, Maybe Range)] -> [(String, Maybe Range)]
forall a. a -> [a] -> [a]
: ((String, Maybe Range) -> (String, Maybe Range))
-> [(String, Maybe Range)] -> [(String, Maybe Range)]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> String)
-> (String, Maybe Range) -> (String, Maybe Range)
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_d")) ([Bus] -> [(String, Maybe Range)]
f [Bus]
modIns))
(((String, Maybe Range) -> (String, Maybe Range))
-> [(String, Maybe Range)] -> [(String, Maybe Range)]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> String)
-> (String, Maybe Range) -> (String, Maybe Range)
forall b c d. (b -> c) -> (b, d) -> (c, d)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_q")) ([Bus] -> [(String, Maybe Range)]
f [Bus]
modOuts))
[]
( (Bus -> Decl) -> [Bus] -> [Decl]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Bus -> Decl
busToReg String
"") [Bus]
modIns [Decl] -> [Decl] -> [Decl]
forall a. [a] -> [a] -> [a]
++
(Bus -> Decl) -> [Bus] -> [Decl]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Bus -> Decl
busToReg String
"_q") [Bus]
modOuts [Decl] -> [Decl] -> [Decl]
forall a. [a] -> [a] -> [a]
++
(Bus -> Decl) -> [Bus] -> [Decl]
forall a b. (a -> b) -> [a] -> [b]
map Bus -> Decl
busToNet [Bus]
modNets [Decl] -> [Decl] -> [Decl]
forall a. [a] -> [a] -> [a]
++
[Event -> Maybe (Event, Stmt) -> Stmt -> Decl
ProcessDecl (ConstExpr -> Edge -> Event
Event (String -> ConstExpr
ExprVar String
"clk") Edge
PosEdge) Maybe (Event, Stmt)
forall a. Maybe a
Nothing
([Stmt] -> Stmt
Seq ((Bus -> Stmt) -> [Bus] -> [Stmt]
forall a b. (a -> b) -> [a] -> [b]
map ((\String
x -> ConstExpr -> ConstExpr -> Stmt
Assign (String -> ConstExpr
ExprVar String
x) (String -> ConstExpr
ExprVar (String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_d"))) (String -> Stmt) -> (Bus -> String) -> Bus -> Stmt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bus -> String
busName) [Bus]
modIns [Stmt] -> [Stmt] -> [Stmt]
forall a. [a] -> [a] -> [a]
++
(Bus -> Stmt) -> [Bus] -> [Stmt]
forall a b. (a -> b) -> [a] -> [b]
map ((\String
x -> ConstExpr -> ConstExpr -> Stmt
Assign (String -> ConstExpr
ExprVar (String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"_q")) (String -> ConstExpr
ExprVar String
x)) (String -> Stmt) -> (Bus -> String) -> Bus -> Stmt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bus -> String
busName) [Bus]
modOuts
)
)
] [Decl] -> [Decl] -> [Decl]
forall a. [a] -> [a] -> [a]
++
(CompS -> Decl) -> [CompS] -> [Decl]
forall a b. (a -> b) -> [a] -> [b]
map CompS -> Decl
mkAssignment [CompS]
cs'
)
where
f :: [Bus] -> [(String, Maybe Range)]
f = (Bus -> (String, Maybe Range)) -> [Bus] -> [(String, Maybe Range)]
forall a b. (a -> b) -> [a] -> [b]
map ((Size -> Maybe Range) -> (String, Size) -> (String, Maybe Range)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (Direction -> Size -> Maybe Range
makeRange Direction
Down) ((String, Size) -> (String, Maybe Range))
-> (Bus -> (String, Size)) -> Bus -> (String, Maybe Range)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bus -> (String, Size)
busId')
modIns :: [Bus]
modIns = CompS -> [Bus]
compOuts CompS
inComp
modOuts :: [Bus]
modOuts = CompS -> [Bus]
compIns CompS
outComp
modNets :: [Bus]
modNets = [Bus]
allIns [Bus] -> [Bus] -> [Bus]
forall a. Eq a => [a] -> [a] -> [a]
`intersect` [Bus]
allOuts
allIns :: [Bus]
allIns = [Bus] -> [Bus]
forall a. Eq a => [a] -> [a]
nub ([Bus] -> [Bus]) -> [Bus] -> [Bus]
forall a b. (a -> b) -> a -> b
$ (CompS -> [Bus]) -> [CompS] -> [Bus]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CompS -> [Bus]
compIns [CompS]
cs'
allOuts :: [Bus]
allOuts = (CompS -> [Bus]) -> [CompS] -> [Bus]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CompS -> [Bus]
compOuts [CompS]
cs'
cs' :: [CompS]
cs' = (CompS -> Bool) -> [CompS] -> [CompS]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> [String] -> Bool) -> [String] -> String -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem [String
"In", String
"Out"] (String -> Bool) -> (CompS -> String) -> CompS -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CompS -> String
compName) [CompS]
cs
inComp :: CompS
inComp = String -> CompS
firstCompNamed String
"In"
outComp :: CompS
outComp = String -> CompS
firstCompNamed String
"Out"
firstCompNamed :: String -> CompS
firstCompNamed String
nm = [CompS] -> CompS
forall a. HasCallStack => [a] -> a
head ([CompS] -> CompS) -> [CompS] -> CompS
forall a b. (a -> b) -> a -> b
$ (CompS -> Bool) -> [CompS] -> [CompS]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
nm) (String -> Bool) -> (CompS -> String) -> CompS -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CompS -> String
compName) [CompS]
cs
busId' :: Bus -> (String, Int)
busId' :: Bus -> (String, Size)
busId' (Bus Size
cId Size
ix Ty
ty) = (Char
'n' Char -> String -> String
forall a. a -> [a] -> [a]
: Size -> String
forall a. Show a => a -> String
show Size
cId String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char
'_' Char -> String -> String
forall a. a -> [a] -> [a]
: Size -> String
forall a. Show a => a -> String
show Size
ix), Integer -> Size
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Size) -> Integer -> Size
forall a b. (a -> b) -> a -> b
$ Ty -> Integer
width Ty
ty)
where width :: Ty -> Integer
width = \case
Ty
C.Void -> String -> Integer
forall {a}. String -> a
err String
"Void"
Ty
C.Unit -> Integer
0
Ty
C.Bool -> Integer
1
Ty
C.Int -> Integer
32
Ty
C.Integer -> Integer
32
Ty
C.Float -> Integer
32
Ty
C.Double -> Integer
64
C.Finite Integer
n -> Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Double
forall a. Floating a => a -> a
log (Integer -> Double
forall a. Num a => Integer -> a
fromInteger Integer
n) :: Double)
C.Vector Integer
n Ty
a -> Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Ty -> Integer
width Ty
a
C.Prod Ty
_ Ty
_ -> String -> Integer
forall {a}. String -> a
err String
"Prod"
C.Sum Ty
_ Ty
_ -> String -> Integer
forall {a}. String -> a
err String
"Sum"
C.Fun Ty
_ Ty
_ -> String -> Integer
forall {a}. String -> a
err String
"Fun"
err :: String -> a
err String
t = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"ConCat.Hardware.Verilog.busId': Don't know what to do with Bus of type " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
t String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", yet."
busName :: Bus -> String
busName :: Bus -> String
busName = (String, Size) -> String
forall a b. (a, b) -> a
fst ((String, Size) -> String)
-> (Bus -> (String, Size)) -> Bus -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bus -> (String, Size)
busId'
busWidth :: Bus -> Int
busWidth :: Bus -> Size
busWidth = (String, Size) -> Size
forall a b. (a, b) -> b
snd ((String, Size) -> Size) -> (Bus -> (String, Size)) -> Bus -> Size
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bus -> (String, Size)
busId'
busToNet :: Bus -> Decl
busToNet :: Bus -> Decl
busToNet Bus
b = String -> Maybe Range -> Maybe ConstExpr -> Decl
NetDecl (Bus -> String
busName Bus
b) (Direction -> Size -> Maybe Range
makeRange Direction
Down (Bus -> Size
busWidth Bus
b)) Maybe ConstExpr
forall a. Maybe a
Nothing
busToReg :: String -> Bus -> Decl
busToReg :: String -> Bus -> Decl
busToReg String
suf Bus
b = String -> Maybe Range -> Maybe Range -> Maybe [ConstExpr] -> Decl
MemDecl (Bus -> String
busName Bus
b String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
suf) Maybe Range
forall a. Maybe a
Nothing (Direction -> Size -> Maybe Range
makeRange Direction
Down (Bus -> Size
busWidth Bus
b)) Maybe [ConstExpr]
forall a. Maybe a
Nothing
mkAssignment :: CompS -> Decl
mkAssignment :: CompS -> Decl
mkAssignment CompS
c | [String
o] <- [String]
outs = String -> String -> [String] -> Ty -> Decl
assign String
o String
prim [String]
ins Ty
ty
| Bool
otherwise = String -> Decl
CommentDecl (String -> Decl) -> String -> Decl
forall a b. (a -> b) -> a -> b
$ String
"Concat.Hardware.Verilog.mkAssignment: Component, '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
prim String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"', has no outputs!"
where prim :: String
prim = CompS -> String
compName CompS
c
ins :: [String]
ins = (Bus -> String) -> [Bus] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Bus -> String
busName ([Bus] -> [String]) -> [Bus] -> [String]
forall a b. (a -> b) -> a -> b
$ CompS -> [Bus]
compIns CompS
c
outs :: [String]
outs = (Bus -> String) -> [Bus] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Bus -> String
busName ([Bus] -> [String]) -> [Bus] -> [String]
forall a b. (a -> b) -> a -> b
$ CompS -> [Bus]
compOuts CompS
c
ty :: Ty
ty = Bus -> Ty
busTy (Bus -> Ty) -> ([Bus] -> Bus) -> [Bus] -> Ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Bus] -> Bus
forall a. HasCallStack => [a] -> a
head ([Bus] -> Ty) -> [Bus] -> Ty
forall a b. (a -> b) -> a -> b
$ CompS -> [Bus]
compOuts CompS
c
assign :: String -> String -> [String] -> C.Ty -> Decl
assign :: String -> String -> [String] -> Ty -> Decl
assign String
o String
prim [String]
ins Ty
ty =
case String
prim of
String
"not" -> UnaryOp -> Decl
assignUnary UnaryOp
LNeg
String
"&&" -> BinaryOp -> Decl
assignBinary BinaryOp
LAnd
String
"||" -> BinaryOp -> Decl
assignBinary BinaryOp
LOr
String
"<" -> BinaryOp -> Decl
assignBinary BinaryOp
LessThan
String
">" -> BinaryOp -> Decl
assignBinary BinaryOp
GreaterThan
String
"<=" -> BinaryOp -> Decl
assignBinary BinaryOp
LessEqual
String
">=" -> BinaryOp -> Decl
assignBinary BinaryOp
GreaterEqual
String
"==" -> BinaryOp -> Decl
assignBinary BinaryOp
Equals
String
"/=" -> BinaryOp -> Decl
assignBinary BinaryOp
NotEquals
String
"negate" -> UnaryOp -> Decl
assignUnary UnaryOp
UMinus
String
"+" -> BinaryOp -> Decl
assignBinary BinaryOp
Plus
String
"-" -> BinaryOp -> Decl
assignBinary BinaryOp
Minus
String
"−" -> BinaryOp -> Decl
assignBinary BinaryOp
Minus
String
"*" -> BinaryOp -> Decl
assignBinary BinaryOp
Times
String
"/" -> BinaryOp -> Decl
assignBinary BinaryOp
Divide
String
"mod" -> BinaryOp -> Decl
assignBinary BinaryOp
Modulo
String
"xor" -> BinaryOp -> Decl
assignBinary BinaryOp
Xor
String
"if" -> Decl
assignConditional
String
_ -> String -> ConstExpr -> Decl
NetAssign String
o (ConstExpr -> Decl) -> ConstExpr -> Decl
forall a b. (a -> b) -> a -> b
$ Ty -> String -> ConstExpr
constExpr Ty
ty String
prim
where
assignUnary :: UnaryOp -> Decl
assignUnary UnaryOp
op
| [String
in1] <- [String]
ins = String -> ConstExpr -> Decl
NetAssign String
o (ConstExpr -> Decl) -> ConstExpr -> Decl
forall a b. (a -> b) -> a -> b
$ UnaryOp -> ConstExpr -> ConstExpr
ExprUnary UnaryOp
op (String -> ConstExpr
ExprVar String
in1)
| Bool
otherwise = String -> Decl
forall a. HasCallStack => String -> a
error (String -> Decl) -> String -> Decl
forall a b. (a -> b) -> a -> b
$ String -> String
forall {p}. p -> String
errStr String
"unary"
assignBinary :: BinaryOp -> Decl
assignBinary BinaryOp
op
| [String
in1, String
in2] <- [String]
ins = String -> ConstExpr -> Decl
NetAssign String
o (ConstExpr -> Decl) -> ConstExpr -> Decl
forall a b. (a -> b) -> a -> b
$ BinaryOp -> ConstExpr -> ConstExpr -> ConstExpr
ExprBinary BinaryOp
op (String -> ConstExpr
ExprVar String
in1) (String -> ConstExpr
ExprVar String
in2)
| Bool
otherwise = String -> Decl
forall a. HasCallStack => String -> a
error (String -> Decl) -> String -> Decl
forall a b. (a -> b) -> a -> b
$ String -> String
forall {p}. p -> String
errStr String
"binary"
assignConditional :: Decl
assignConditional
| [String
p, String
t, String
f] <- [String]
ins = String -> ConstExpr -> Decl
NetAssign String
o (ConstExpr -> Decl) -> ConstExpr -> Decl
forall a b. (a -> b) -> a -> b
$ ConstExpr -> ConstExpr -> ConstExpr -> ConstExpr
ExprCond (String -> ConstExpr
ExprVar String
p) (String -> ConstExpr
ExprVar String
t) (String -> ConstExpr
ExprVar String
f)
| Bool
otherwise = String -> Decl
forall a. HasCallStack => String -> a
error (String -> Decl) -> String -> Decl
forall a b. (a -> b) -> a -> b
$ String -> String
forall {p}. p -> String
errStr String
"conditional"
errStr :: p -> String
errStr p
_ = String
"ConCat.Hardware.Verilog.assign: I received an incorrect number of inputs.\n"
constExpr :: C.Ty -> String -> Expr
constExpr :: Ty -> String -> ConstExpr
constExpr Ty
ty String
prim = case Ty
ty of
Ty
C.Bool -> Maybe Size -> ExprLit -> ConstExpr
ExprLit (Size -> Maybe Size
forall a. a -> Maybe a
Just Size
1) (Bit -> ExprLit
ExprBit (Bit -> ExprLit) -> (Bool -> Bit) -> Bool -> ExprLit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bit
boolToBit (Bool -> ExprLit) -> Bool -> ExprLit
forall a b. (a -> b) -> a -> b
$ Bool
forall a. Read a => a
rp)
Ty
C.Int -> Maybe Size -> ExprLit -> ConstExpr
ExprLit (Size -> Maybe Size
forall a. a -> Maybe a
Just Size
32) (Integer -> ExprLit
ExprNum (Integer -> ExprLit) -> Integer -> ExprLit
forall a b. (a -> b) -> a -> b
$ Integer
forall a. Read a => a
rp)
Ty
C.Float -> Maybe Size -> ExprLit -> ConstExpr
ExprLit Maybe Size
forall a. Maybe a
Nothing (Float -> ExprLit
ExprFloat (Float -> ExprLit) -> Float -> ExprLit
forall a b. (a -> b) -> a -> b
$ Float
forall a. Read a => a
rp)
Ty
_ -> String -> ConstExpr
forall a. HasCallStack => String -> a
error (String -> ConstExpr) -> String -> ConstExpr
forall a b. (a -> b) -> a -> b
$ String
"ConCat.Hardware.Verilog.constExpr: Unrecognized type: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Ty -> String
forall a. Show a => a -> String
show Ty
ty
where rp :: Read a => a
rp :: forall a. Read a => a
rp = String -> a
forall a. Read a => String -> a
read String
prim
boolToBit :: Bool -> Bit
boolToBit :: Bool -> Bit
boolToBit Bool
True = Bit
T
boolToBit Bool
False = Bit
F
compName :: CompS -> String
compName :: CompS -> String
compName (CompS Size
_ String
nm [Bus]
_ [Bus]
_) = String
nm
compIns :: CompS -> [Bus]
compIns :: CompS -> [Bus]
compIns (CompS Size
_ String
_ [Bus]
ins [Bus]
_) = [Bus]
ins
compOuts :: CompS -> [Bus]
compOuts :: CompS -> [Bus]
compOuts (CompS Size
_ String
_ [Bus]
_ [Bus]
outs) = [Bus]
outs