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
|
2019-09-16 05:17:14 +02:00
|
|
|
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
|
2019-09-16 05:17:14 +02:00
|
|
|
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 =
|
2019-10-01 05:03:55 +02:00
|
|
|
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
|
2020-02-01 21:52:52 +01:00
|
|
|
, 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
|
2019-10-01 05:03:55 +02:00
|
|
|
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)
|
2020-02-01 21:52:52 +01:00
|
|
|
stmt = Asgn AsgnOpEq Nothing lhs expr
|
2019-09-04 05:36:29 +02:00
|
|
|
-- final chunk loop
|
2019-10-01 05:03:55 +02:00
|
|
|
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))
|
2020-02-01 21:52:52 +01:00
|
|
|
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
|
2020-02-01 21:52:52 +01:00
|
|
|
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"]]
|
2019-09-14 18:31:44 +02:00
|
|
|
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
|
2019-09-14 18:31:44 +02:00
|
|
|
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
|
2019-09-14 18:31:44 +02:00
|
|
|
size = DimsFn FnBits $ Right expr
|
2019-09-04 05:36:29 +02:00
|
|
|
traverseAsgnM (lhs, expr) constructor =
|
|
|
|
|
return $ constructor lhs expr
|