sv2v/src/Convert/Stream.hs

99 lines
3.6 KiB
Haskell
Raw Normal View History

2019-09-04 05:36:29 +02:00
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion of streaming concatenations.
-}
module Convert.Stream (convert) where
import Control.Monad.Writer
2019-09-12 05:01:34 +02:00
import Data.List.Unique (complex)
2019-09-04 05:36:29 +02:00
import Convert.Traverse
import Language.SystemVerilog.AST
type Funcs = [ModuleItem]
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription (description @ Part{}) =
Part attrs extern kw lifetime name ports (items ++ funcs)
2019-09-04 05:36:29 +02:00
where
(description', funcSet) =
runWriter $ traverseModuleItemsM (traverseStmtsM traverseStmtM) description
Part attrs extern kw lifetime name ports items = description'
2019-09-12 05:01:34 +02:00
(funcs, _, _) = complex funcSet
2019-09-04 05:36:29 +02:00
convertDescription other = other
streamerBlock :: Expr -> Expr -> (LHS -> Expr -> Stmt) -> LHS -> Expr -> Stmt
streamerBlock chunk size asgn output input =
Block Seq ""
2019-09-04 05:36:29 +02:00
[ Variable Local t inp [] $ Just input
, Variable Local t out [] Nothing
, Variable Local (IntegerAtom TInteger Unspecified) idx [] Nothing
, Variable Local (IntegerAtom TInteger Unspecified) bas [] Nothing
]
[ For inits cmp incr stmt
, Asgn AsgnOpEq Nothing (LHSIdent bas) (Ident idx)
2019-09-04 05:36:29 +02:00
, For inits cmp2 incr2 stmt2
, asgn output (Ident out)
]
where
lo = Number "0"
hi = BinOp Sub size (Number "1")
t = IntegerVector TLogic Unspecified [(hi, lo)]
name = streamerBlockName chunk size
inp = name ++ "_inp"
out = name ++ "_out"
idx = name ++ "_idx"
bas = name ++ "_bas"
-- main chunk loop
inits = Right [(LHSIdent idx, lo)]
cmp = BinOp Le (Ident idx) (BinOp Sub hi chunk)
2019-09-04 05:36:29 +02:00
incr = [(LHSIdent idx, AsgnOp Add, chunk)]
lhs = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi (Ident idx), chunk)
expr = Range (Ident inp) IndexedPlus (Ident idx, chunk)
stmt = Asgn AsgnOpEq Nothing lhs expr
2019-09-04 05:36:29 +02:00
-- final chunk loop
cmp2 = BinOp Lt (Ident idx) (BinOp Sub size (Ident bas))
2019-09-04 05:36:29 +02:00
incr2 = [(LHSIdent idx, AsgnOp Add, Number "1")]
lhs2 = LHSBit (LHSIdent out) (Ident idx)
expr2 = Bit (Ident inp) (BinOp Add (Ident idx) (Ident bas))
stmt2 = Asgn AsgnOpEq Nothing lhs2 expr2
2019-09-04 05:36:29 +02:00
streamerBlockName :: Expr -> Expr -> Identifier
streamerBlockName chunk size =
2019-09-04 05:52:22 +02:00
"_sv2v_strm_" ++ shortHash (chunk, size)
2019-09-04 05:36:29 +02:00
traverseStmtM :: Stmt -> Writer Funcs Stmt
traverseStmtM (Asgn op mt lhs expr) =
traverseAsgnM (lhs, expr) (Asgn op mt)
2019-09-04 05:36:29 +02:00
traverseStmtM other = return other
traverseAsgnM :: (LHS, Expr) -> (LHS -> Expr -> Stmt) -> Writer Funcs Stmt
traverseAsgnM (lhs, Stream StreamR _ exprs) constructor =
return $ constructor lhs expr
where
expr = Concat $ exprs ++ [Repeat delta [Number "1'b0"]]
size = DimsFn FnBits $ Right $ lhsToExpr lhs
exprSize = DimsFn FnBits $ Right (Concat exprs)
2019-09-04 05:36:29 +02:00
delta = BinOp Sub size exprSize
traverseAsgnM (LHSStream StreamR _ lhss, expr) constructor =
return $ constructor (LHSConcat lhss) expr
traverseAsgnM (lhs, Stream StreamL chunk exprs) constructor = do
return $ streamerBlock chunk size constructor lhs expr
where
expr = Concat $ Repeat delta [Number "1'b0"] : exprs
size = DimsFn FnBits $ Right $ lhsToExpr lhs
exprSize = DimsFn FnBits $ Right (Concat exprs)
2019-09-04 05:36:29 +02:00
delta = BinOp Sub size exprSize
traverseAsgnM (LHSStream StreamL chunk lhss, expr) constructor = do
return $ streamerBlock chunk size constructor lhs expr
where
lhs = LHSConcat lhss
size = DimsFn FnBits $ Right expr
2019-09-04 05:36:29 +02:00
traverseAsgnM (lhs, expr) constructor =
return $ constructor lhs expr