Commit b0eedfe3 by Zachary Snow

$bits conversion handles basic expressions

parent 73f83112
...@@ -6,25 +6,77 @@ ...@@ -6,25 +6,77 @@
module Convert.Bits (convert) where module Convert.Bits (convert) where
import Control.Monad.State
import qualified Data.Map.Strict as Map
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type Info = Map.Map Identifier (Type, [Range])
convert :: AST -> AST convert :: AST -> AST
convert = convert = traverseDescriptions convertDescription
traverseDescriptions $
traverseModuleItems $ convertDescription :: Description -> Description
traverseExprs $ convertDescription =
traverseNestedExprs $ scopedConversion traverseDeclM traverseModuleItemM traverseStmtM Map.empty
convertExpr
-- collects and converts multi-dimensional packed-array declarations
convertExpr :: Expr -> Expr traverseDeclM :: Decl -> State Info Decl
convertExpr (Bits (Left (IntegerVector _ _ rs))) = size rs traverseDeclM (origDecl @ (Variable _ t ident a _)) = do
convertExpr (Bits (Left (Implicit _ rs))) = size rs modify $ Map.insert ident (t, a)
convertExpr other = other return origDecl
traverseDeclM other = return other
size :: [Range] -> Expr
size ranges = traverseModuleItemM :: ModuleItem -> State Info ModuleItem
simplify $ traverseModuleItemM item = traverseExprsM traverseExprM item
foldl (BinOp Mul) (Number "1") $
map rangeSize $ traverseStmtM :: Stmt -> State Info Stmt
ranges traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
traverseExprM :: Expr -> State Info Expr
traverseExprM = traverseNestedExprsM $ stately convertExpr
convertExpr :: Info -> Expr -> Expr
convertExpr _ (Bits (Left t)) =
case t of
IntegerVector _ _ rs -> dimensionsSize rs
Implicit _ rs -> dimensionsSize rs
Net _ rs -> dimensionsSize rs
_ -> Bits $ Left t
convertExpr info (Bits (Right e)) =
case e of
Ident x ->
case Map.lookup x info of
Nothing -> Bits $ Right e
Just (t, rs) -> simplify $ BinOp Mul
(dimensionsSize rs)
(convertExpr info $ Bits $ Left t)
Concat exprs ->
foldl (BinOp Add) (Number "0") $
map (convertExpr info) $
map (Bits . Right) $
exprs
Range expr mode range ->
simplify $ BinOp Mul size
(convertExpr info $ Bits $ Right $ Bit expr (Number "0"))
where
size = case mode of
NonIndexed -> rangeSize range
IndexedPlus -> snd range
IndexedMinus -> snd range
Bit (Ident x) idx ->
case Map.lookup x info of
Nothing -> Bits $ Right $ Bit (Ident x) idx
Just (t, rs) ->
convertExpr info $ Bits $ Left t'
where t' = popRange t rs
_ -> Bits $ Right e
convertExpr _ other = other
popRange :: Type -> [Range] -> Type
popRange t rs =
tf $ tail rsCombined
where
(tf, trs) = typeRanges t
rsCombined = rs ++ trs
...@@ -35,19 +35,9 @@ convert :: AST -> AST ...@@ -35,19 +35,9 @@ convert :: AST -> AST
convert = traverseDescriptions convertDescription convert = traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription (description @ (Part _ _ _ _ _ _)) = convertDescription =
evalState scopedConversion traverseDeclM traverseModuleItemM traverseStmtM
(initialTraverse description >>= scopedTraverse)
(Info Map.empty) (Info Map.empty)
where
initialTraverse = traverseModuleItemsM traverseMIDecl
scopedTraverse = traverseModuleItemsM $
traverseScopesM traverseDeclM traverseModuleItemM traverseStmtM
traverseMIDecl :: ModuleItem -> State Info ModuleItem
traverseMIDecl (MIDecl decl) =
traverseDeclM decl >>= return . MIDecl
traverseMIDecl other = return other
convertDescription description = description
-- collects and converts multi-dimensional packed-array declarations -- collects and converts multi-dimensional packed-array declarations
traverseDeclM :: Decl -> State Info Decl traverseDeclM :: Decl -> State Info Decl
......
...@@ -217,11 +217,8 @@ convertAsgn structs types (lhs, expr) = ...@@ -217,11 +217,8 @@ convertAsgn structs types (lhs, expr) =
Pattern [(Just "default", e)] Pattern [(Just "default", e)]
else if null rs then else if null rs then
expanded expanded
else if length rs == 1 then
Repeat (rangeSize $ head rs) [expanded]
else else
error $ "default pattern for multi-dimensional struct array " Repeat (dimensionsSize rs) [expanded]
++ show structTf ++ " is not allowed"
where where
structTf = Struct (Packed sg) fields structTf = Struct (Packed sg) fields
expanded = convertExpr (structTf []) $ Pattern $ expanded = convertExpr (structTf []) $ Pattern $
......
...@@ -71,6 +71,7 @@ module Convert.Traverse ...@@ -71,6 +71,7 @@ module Convert.Traverse
, traverseNestedLHSs , traverseNestedLHSs
, collectNestedLHSsM , collectNestedLHSsM
, traverseScopesM , traverseScopesM
, scopedConversion
, stately , stately
) where ) where
...@@ -929,6 +930,26 @@ traverseScopesM declMapper moduleItemMapper stmtMapper = ...@@ -929,6 +930,26 @@ traverseScopesM declMapper moduleItemMapper stmtMapper =
else error $ "illegal scope state modification: " else error $ "illegal scope state modification: "
++ show (prevState, item, currState, item') ++ show (prevState, item, currState, item')
-- applies the given decl conversion across the description, and then performs a
-- scoped traversal for each ModuleItem in the description
scopedConversion
:: (Eq s, Show s)
=> MapperM (State s) Decl
-> MapperM (State s) ModuleItem
-> MapperM (State s) Stmt
-> s
-> Description
-> Description
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM s description =
evalState (initialTraverse description >>= scopedTraverse) s
where
initialTraverse = traverseModuleItemsM traverseMIDecl
scopedTraverse = traverseModuleItemsM $
traverseScopesM traverseDeclM traverseModuleItemM traverseStmtM
traverseMIDecl (MIDecl decl) =
traverseDeclM decl >>= return . MIDecl
traverseMIDecl other = return other
-- convert a basic mapper with an initial argument to a stateful mapper -- convert a basic mapper with an initial argument to a stateful mapper
stately :: (Eq s, Show s) => (s -> Mapper a) -> MapperM (State s) a stately :: (Eq s, Show s) => (s -> Mapper a) -> MapperM (State s) a
stately mapper thing = do stately mapper thing = do
......
...@@ -17,6 +17,7 @@ module Language.SystemVerilog.AST.Expr ...@@ -17,6 +17,7 @@ module Language.SystemVerilog.AST.Expr
, endianCondExpr , endianCondExpr
, endianCondRange , endianCondRange
, sizedExpr , sizedExpr
, dimensionsSize
) where ) where
import Data.List (intercalate) import Data.List (intercalate)
...@@ -209,3 +210,10 @@ sizedExpr x r (Number n) = ...@@ -209,3 +210,10 @@ sizedExpr x r (Number n) =
else size ++ n else size ++ n
Just num -> size ++ "'d" ++ show num Just num -> size ++ "'d" ++ show num
sizedExpr _ _ e = e sizedExpr _ _ e = e
dimensionsSize :: [Range] -> Expr
dimensionsSize ranges =
simplify $
foldl (BinOp Mul) (Number "1") $
map rangeSize $
ranges
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment