sv2v/src/Convert/Stream.hs

87 lines
3.1 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 Convert.Traverse
import Language.SystemVerilog.AST
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription (description @ Part{}) =
traverseModuleItems (traverseStmts traverseStmt) description
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 ""
2020-06-14 21:56:09 +02:00
[ Variable Local t inp [] input
, Variable Local t out [] Nil
, Variable Local (IntegerAtom TInteger Unspecified) idx [] Nil
2019-09-04 05:36:29 +02:00
]
[ For inits cmp incr stmt
2020-05-06 00:42:45 +02:00
, If NoCheck cmp2 stmt2 Null
2019-09-04 05:36:29 +02:00
, 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"
-- main chunk loop
inits = Right [(LHSIdent idx, lo)]
2020-05-06 00:42:45 +02:00
cmp = BinOp Lt (Ident idx) base
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
2020-05-06 00:42:45 +02:00
base = BinOp Mul (BinOp Div size chunk) chunk
2019-09-04 05:36:29 +02:00
-- final chunk loop
2020-05-06 00:42:45 +02:00
left = BinOp Sub size base
lhs2 = LHSRange (LHSIdent out) IndexedMinus (BinOp Sub hi base, left)
expr2 = Range (Ident inp) IndexedPlus (base, left)
stmt2 = Asgn AsgnOpEq Nothing lhs2 expr2
2020-05-06 00:42:45 +02:00
cmp2 = BinOp Gt left (Number "0")
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
traverseStmt :: Stmt -> Stmt
traverseStmt (Asgn op mt lhs expr) =
traverseAsgn (lhs, expr) (Asgn op mt)
traverseStmt other = other
2019-09-04 05:36:29 +02:00
traverseAsgn :: (LHS, Expr) -> (LHS -> Expr -> Stmt) -> Stmt
traverseAsgn (lhs, Stream StreamR _ exprs) constructor =
constructor lhs expr
2019-09-04 05:36:29 +02:00
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
traverseAsgn (LHSStream StreamR _ lhss, expr) constructor =
constructor (LHSConcat lhss) expr
traverseAsgn (lhs, Stream StreamL chunk exprs) constructor = do
streamerBlock chunk size constructor lhs expr
2019-09-04 05:36:29 +02:00
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
traverseAsgn (LHSStream StreamL chunk lhss, expr) constructor = do
streamerBlock chunk size constructor lhs expr
2019-09-04 05:36:29 +02:00
where
lhs = LHSConcat lhss
size = DimsFn FnBits $ Right expr
traverseAsgn (lhs, expr) constructor =
constructor lhs expr