Commit 5667bdb5 by Zachary Snow

unpacked array conversion supports generate scoped data

- added type class for looking up elements in scoped conversions
parent b19259c6
...@@ -99,7 +99,7 @@ traverseModuleItem ports scopes = ...@@ -99,7 +99,7 @@ traverseModuleItem ports scopes =
isRegType _ = False isRegType _ = False
isReg' :: LHS -> Writer [Bool] () isReg' :: LHS -> Writer [Bool] ()
isReg' lhs = isReg' lhs =
case lookupLHS scopes lhs of case lookupElem scopes lhs of
Just (_, _, t) -> tell [isRegType t] Just (_, _, t) -> tell [isRegType t]
_ -> tell [False] _ -> tell [False]
...@@ -167,7 +167,7 @@ rewriteDeclM (Variable d t x a e) = do ...@@ -167,7 +167,7 @@ rewriteDeclM (Variable d t x a e) = do
(d', t') <- case t of (d', t') <- case t of
IntegerVector TLogic sg rs -> do IntegerVector TLogic sg rs -> do
insertElem x t insertElem x t
details <- lookupIdentM x details <- lookupElemM x
let Just (accesses, _, _) = details let Just (accesses, _, _) = details
let location = map accessName accesses let location = map accessName accesses
usedAsReg <- lift $ gets $ Set.member location usedAsReg <- lift $ gets $ Set.member location
...@@ -205,7 +205,7 @@ traverseStmtM stmt = do ...@@ -205,7 +205,7 @@ traverseStmtM stmt = do
collectLHSM :: LHS -> ST () collectLHSM :: LHS -> ST ()
collectLHSM lhs = do collectLHSM lhs = do
details <- lookupLHSM lhs details <- lookupElemM lhs
case details of case details of
Just (accesses, _, _) -> do Just (accesses, _, _) -> do
let location = map accessName accesses let location = map accessName accesses
......
...@@ -188,7 +188,7 @@ convertExpr scopes = ...@@ -188,7 +188,7 @@ convertExpr scopes =
fallbackLevels expr = fallbackLevels expr =
fmap ((, expr) . thd3) res fmap ((, expr) . thd3) res
where where
res = lookupExpr scopes expr res = lookupElem scopes expr
thd3 (_, _, c) = c thd3 (_, _, c) = c
-- given an expression, returns the two most significant (innermost, -- given an expression, returns the two most significant (innermost,
......
{-# LANGUAGE TupleSections #-} {-# LANGUAGE TupleSections #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{- sv2v {- sv2v
- Author: Zachary Snow <zach@zachjs.com> - Author: Zachary Snow <zach@zachjs.com>
- -
...@@ -30,15 +31,10 @@ module Convert.Scoper ...@@ -30,15 +31,10 @@ module Convert.Scoper
, partScoperT , partScoperT
, insertElem , insertElem
, injectItem , injectItem
, lookupExpr , lookupElem
, lookupLHS , lookupElemM
, lookupIdent
, lookupAccesses
, lookupExprM
, lookupLHSM
, lookupIdentM
, lookupAccessesM
, Access(..) , Access(..)
, ScopeKey
, Scopes , Scopes
, embedScopes , embedScopes
, withinProcedure , withinProcedure
...@@ -104,7 +100,7 @@ enterScope :: Monad m => Identifier -> Identifier -> ScoperT a m () ...@@ -104,7 +100,7 @@ enterScope :: Monad m => Identifier -> Identifier -> ScoperT a m ()
enterScope name index = do enterScope name index = do
s <- get s <- get
let current' = sCurrent s ++ [Tier name index] let current' = sCurrent s ++ [Tier name index]
existingResult <- lookupIdentM name existingResult <- lookupElemM name
let existingElement = fmap thd3 existingResult let existingElement = fmap thd3 existingResult
let entry = Entry existingElement index Map.empty let entry = Entry existingElement index Map.empty
let mapping' = setScope current' entry $ sMapping s let mapping' = setScope current' entry $ sMapping s
...@@ -149,9 +145,6 @@ exprToAccesses (Dot e x) = do ...@@ -149,9 +145,6 @@ exprToAccesses (Dot e x) = do
Just $ accesses ++ [Access x Nil] Just $ accesses ++ [Access x Nil]
exprToAccesses _ = Nothing exprToAccesses _ = Nothing
lhsToAccesses :: LHS -> Maybe [Access]
lhsToAccesses = exprToAccesses . lhsToExpr
insertElem :: Monad m => Identifier -> a -> ScoperT a m () insertElem :: Monad m => Identifier -> a -> ScoperT a m ()
insertElem name element = do insertElem name element = do
s <- get s <- get
...@@ -191,26 +184,19 @@ attemptResolve mapping (Access x e : rest) = do ...@@ -191,26 +184,19 @@ attemptResolve mapping (Access x e : rest) = do
type LookupResult a = Maybe ([Access], Replacements, a) type LookupResult a = Maybe ([Access], Replacements, a)
lookupExprM :: Monad m => Expr -> ScoperT a m (LookupResult a) class ScopeKey k where
lookupExprM = embedScopes lookupExpr lookupElem :: Scopes a -> k -> LookupResult a
lookupElemM :: Monad m => k -> ScoperT a m (LookupResult a)
lookupLHSM :: Monad m => LHS -> ScoperT a m (LookupResult a) lookupElemM = embedScopes lookupElem
lookupLHSM = embedScopes lookupLHS
lookupIdentM :: Monad m => Identifier -> ScoperT a m (LookupResult a)
lookupIdentM = embedScopes lookupIdent
lookupAccessesM :: Monad m => [Access] -> ScoperT a m (LookupResult a)
lookupAccessesM = embedScopes lookupAccesses
lookupExpr :: Scopes a -> Expr -> LookupResult a instance ScopeKey Expr where
lookupExpr scopes = join . fmap (lookupAccesses scopes) . exprToAccesses lookupElem scopes = join . fmap (lookupAccesses scopes) . exprToAccesses
lookupLHS :: Scopes a -> LHS -> LookupResult a instance ScopeKey LHS where
lookupLHS scopes = join . fmap (lookupAccesses scopes) . lhsToAccesses lookupElem scopes = lookupElem scopes . lhsToExpr
lookupIdent :: Scopes a -> Identifier -> LookupResult a instance ScopeKey Identifier where
lookupIdent scopes ident = lookupAccesses scopes [Access ident Nil] lookupElem scopes ident = lookupAccesses scopes [Access ident Nil]
lookupAccesses :: Scopes a -> [Access] -> LookupResult a lookupAccesses :: Scopes a -> [Access] -> LookupResult a
lookupAccesses scopes accesses = do lookupAccesses scopes accesses = do
......
...@@ -71,7 +71,7 @@ traverseExprM = ...@@ -71,7 +71,7 @@ traverseExprM =
fallback = convertCastM (Number s) (Number n) fallback = convertCastM (Number s) (Number n)
num = return . Number num = return . Number
convertExprM (Cast (Right (Ident x)) e) = do convertExprM (Cast (Right (Ident x)) e) = do
details <- lookupIdentM x details <- lookupElemM x
-- can't convert this cast yet because x could be a typename -- can't convert this cast yet because x could be a typename
if details == Nothing if details == Nothing
then return $ Cast (Right $ Ident x) e then return $ Cast (Right $ Ident x) e
...@@ -102,7 +102,7 @@ traverseExprM = ...@@ -102,7 +102,7 @@ traverseExprM =
convertCastWithSigningM :: Expr -> Expr -> Signing -> Scoper Type Expr convertCastWithSigningM :: Expr -> Expr -> Signing -> Scoper Type Expr
convertCastWithSigningM s e sg = do convertCastWithSigningM s e sg = do
details <- lookupIdentM $ castFnName s sg details <- lookupElemM $ castFnName s sg
when (details == Nothing) $ injectItem $ MIPackageItem $ castFn s sg when (details == Nothing) $ injectItem $ MIPackageItem $ castFn s sg
let f = castFnName s sg let f = castFnName s sg
let args = Args [e] [] let args = Args [e] []
...@@ -164,7 +164,7 @@ exprSigning scopes (BinOp op e1 e2) = ...@@ -164,7 +164,7 @@ exprSigning scopes (BinOp op e1 e2) =
ShiftAR -> curry fst ShiftAR -> curry fst
_ -> \_ _ -> Just Unspecified _ -> \_ _ -> Just Unspecified
exprSigning scopes expr = exprSigning scopes expr =
case lookupExpr scopes expr of case lookupElem scopes expr of
Just (_, _, t) -> typeSigning t Just (_, _, t) -> typeSigning t
Nothing -> Just Unspecified Nothing -> Just Unspecified
......
...@@ -305,7 +305,7 @@ convertExpr _ other = other ...@@ -305,7 +305,7 @@ convertExpr _ other = other
fallbackType :: Scopes Type -> Expr -> (Type, Expr) fallbackType :: Scopes Type -> Expr -> (Type, Expr)
fallbackType scopes e = fallbackType scopes e =
case lookupExpr scopes e of case lookupElem scopes e of
Nothing -> (unknownType, e) Nothing -> (unknownType, e)
Just (_, _, t) -> (t, e) Just (_, _, t) -> (t, e)
...@@ -463,7 +463,7 @@ convertCall scopes fn (Args pnArgs kwArgs) = ...@@ -463,7 +463,7 @@ convertCall scopes fn (Args pnArgs kwArgs) =
convertArg lhs (x, e) = convertArg lhs (x, e) =
(x, e') (x, e')
where where
details = lookupLHS scopes $ LHSDot lhs x details = lookupElem scopes $ LHSDot lhs x
typ = maybe unknownType thd3 details typ = maybe unknownType thd3 details
thd3 (_, _, c) = c thd3 (_, _, c) = c
(_, e') = convertSubExpr scopes $ convertExpr typ e (_, e') = convertSubExpr scopes $ convertExpr typ e
...@@ -55,7 +55,7 @@ traverseTypeM other = return other ...@@ -55,7 +55,7 @@ traverseTypeM other = return other
lookupTypeOf :: Expr -> Scoper Type Type lookupTypeOf :: Expr -> Scoper Type Type
lookupTypeOf expr = do lookupTypeOf expr = do
details <- lookupExprM expr details <- lookupElemM expr
case details of case details of
Nothing -> return $ TypeOf expr Nothing -> return $ TypeOf expr
-- functions with no return type implicitly return a single bit -- functions with no return type implicitly return a single bit
......
...@@ -21,12 +21,12 @@ convert = map $ traverseDescriptions $ partScoper ...@@ -21,12 +21,12 @@ convert = map $ traverseDescriptions $ partScoper
traverseTypeOrExprM :: TypeOrExpr -> Scoper Type TypeOrExpr traverseTypeOrExprM :: TypeOrExpr -> Scoper Type TypeOrExpr
traverseTypeOrExprM (Left (TypeOf (Ident x))) = do traverseTypeOrExprM (Left (TypeOf (Ident x))) = do
details <- lookupIdentM x details <- lookupElemM x
return $ case details of return $ case details of
Nothing -> Left $ TypeOf $ Ident x Nothing -> Left $ TypeOf $ Ident x
Just (_, _, typ) -> Left typ Just (_, _, typ) -> Left typ
traverseTypeOrExprM (Right (Ident x)) = do traverseTypeOrExprM (Right (Ident x)) = do
details <- lookupIdentM x details <- lookupElemM x
return $ case details of return $ case details of
Nothing -> Right $ Ident x Nothing -> Right $ Ident x
Just (_, _, typ) -> Left typ Just (_, _, typ) -> Left typ
...@@ -84,7 +84,7 @@ traverseStmtM = ...@@ -84,7 +84,7 @@ traverseStmtM =
traverseTypeM :: Type -> Scoper Type Type traverseTypeM :: Type -> Scoper Type Type
traverseTypeM (Alias st rs1) = do traverseTypeM (Alias st rs1) = do
details <- lookupIdentM st details <- lookupElemM st
return $ case details of return $ case details of
Nothing -> Alias st rs1 Nothing -> Alias st rs1
Just (_, _, typ) -> case typ of Just (_, _, typ) -> case typ of
......
...@@ -15,50 +15,56 @@ ...@@ -15,50 +15,56 @@
module Convert.UnpackedArray (convert) where module Convert.UnpackedArray (convert) where
import Control.Monad.State import Control.Monad.State
import Control.Monad.Writer
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Convert.Scoper
import Convert.Traverse import Convert.Traverse
import Language.SystemVerilog.AST import Language.SystemVerilog.AST
type DeclMap = Map.Map Identifier Decl type Location = [Identifier]
type DeclSet = Set.Set Decl type Locations = Set.Set Location
type ST = ScoperT Decl (State Locations)
type ST = StateT DeclMap (Writer DeclSet)
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description convertDescription :: Description -> Description
convertDescription description = convertDescription (description @ (Part _ _ Module _ _ _ _)) =
traverseModuleItems (traverseDecls $ packDecl declsToPack) description' evalState (operation description) Set.empty
where where
(description', declsToPack) = runWriter $ operation =
scopedConversionM traverseDeclM traverseModuleItemM traverseStmtM partScoperT traverseDeclM traverseModuleItemM noop traverseStmtM >=>
Map.empty description partScoperT rewriteDeclM noop noop noop
noop = return
convertDescription other = other
-- collects and converts multi-dimensional packed-array declarations -- tracks multi-dimensional unpacked array declarations
traverseDeclM :: Decl -> ST Decl traverseDeclM :: Decl -> ST Decl
traverseDeclM (orig @ (Variable dir _ x _ e)) = do traverseDeclM (decl @ (Variable _ _ _ [] _)) = return decl
modify $ Map.insert x orig traverseDeclM (decl @ (Variable dir _ x _ e)) = do
() <- if dir /= Local || e /= Nil insertElem x decl
then lift $ tell $ Set.singleton orig if dir /= Local || e /= Nil
then flatUsageM x
else return () else return ()
return orig return decl
traverseDeclM other = return other traverseDeclM other = return other
-- pack the given decls marked for packing -- pack decls marked for packing
packDecl :: DeclSet -> Decl -> Decl rewriteDeclM :: Decl -> ST Decl
packDecl decls (orig @ (Variable d t x a e)) = do rewriteDeclM (decl @ (Variable _ _ _ [] _)) = return decl
if Set.member orig decls rewriteDeclM (decl @ (Variable d t x a e)) = do
insertElem x decl
details <- lookupElemM x
let Just (accesses, _, _) = details
let location = map accessName accesses
usedAsPacked <- lift $ gets $ Set.member location
if usedAsPacked
then do then do
let (tf, rs) = typeRanges t let (tf, rs) = typeRanges t
let t' = tf $ a ++ rs let t' = tf $ a ++ rs
Variable d t' x [] e return $ Variable d t' x [] e
else orig else return decl
packDecl _ other = other rewriteDeclM other = return other
traverseModuleItemM :: ModuleItem -> ST ModuleItem traverseModuleItemM :: ModuleItem -> ST ModuleItem
traverseModuleItemM = traverseModuleItemM =
...@@ -73,10 +79,9 @@ traverseModuleItemM' (Instance a b c d bindings) = do ...@@ -73,10 +79,9 @@ traverseModuleItemM' (Instance a b c d bindings) = do
return $ Instance a b c d bindings' return $ Instance a b c d bindings'
where where
collectBinding :: PortBinding -> ST PortBinding collectBinding :: PortBinding -> ST PortBinding
collectBinding (y, Ident x) = do collectBinding (y, x) = do
flatUsageM x flatUsageM x
return (y, Ident x) return (y, x)
collectBinding other = return other
traverseModuleItemM' other = return other traverseModuleItemM' other = return other
traverseStmtM :: Stmt -> ST Stmt traverseStmtM :: Stmt -> ST Stmt
...@@ -86,40 +91,29 @@ traverseStmtM = ...@@ -86,40 +91,29 @@ traverseStmtM =
traverseStmtAsgnsM traverseAsgnM traverseStmtAsgnsM traverseAsgnM
traverseExprM :: Expr -> ST Expr traverseExprM :: Expr -> ST Expr
traverseExprM (Range (Ident x) mode i) = do traverseExprM (Range x mode i) =
flatUsageM x flatUsageM x >> return (Range x mode i)
return $ Range (Ident x) mode i
traverseExprM other = return other traverseExprM other = return other
traverseLHSM :: LHS -> ST LHS traverseLHSM :: LHS -> ST LHS
traverseLHSM (LHSIdent x) = do traverseLHSM x = flatUsageM x >> return x
flatUsageM x
return $ LHSIdent x
traverseLHSM other = return other
traverseAsgnM :: (LHS, Expr) -> ST (LHS, Expr) traverseAsgnM :: (LHS, Expr) -> ST (LHS, Expr)
traverseAsgnM (LHSIdent x, Mux cond (Ident y) (Ident z)) = do traverseAsgnM (x, Mux cond y z) = do
flatUsageM x flatUsageM x
flatUsageM y flatUsageM y
flatUsageM z flatUsageM z
return (LHSIdent x, Mux cond (Ident y) (Ident z)) return (x, Mux cond y z)
traverseAsgnM (LHSIdent x, Mux cond y (Ident z)) = do traverseAsgnM (x, y) = do
flatUsageM x
flatUsageM z
return (LHSIdent x, Mux cond y (Ident z))
traverseAsgnM (LHSIdent x, Mux cond (Ident y) z) = do
flatUsageM x
flatUsageM y
return (LHSIdent x, Mux cond (Ident y) z)
traverseAsgnM (LHSIdent x, Ident y) = do
flatUsageM x flatUsageM x
flatUsageM y flatUsageM y
return (LHSIdent x, Ident y) return (x, y)
traverseAsgnM other = return other
flatUsageM :: Identifier -> ST () flatUsageM :: ScopeKey e => e -> ST ()
flatUsageM x = do flatUsageM x = do
declMap <- get details <- lookupElemM x
case Map.lookup x declMap of case details of
Just decl -> lift $ tell $ Set.singleton decl Just (accesses, _, _) -> do
let location = map accessName accesses
lift $ modify $ Set.insert location
Nothing -> return () Nothing -> return ()
...@@ -63,7 +63,7 @@ traverseExprM = traverseNestedExprsM $ embedScopes convertExpr ...@@ -63,7 +63,7 @@ traverseExprM = traverseNestedExprsM $ embedScopes convertExpr
lookupPattern :: Scopes Number -> Expr -> Maybe Number lookupPattern :: Scopes Number -> Expr -> Maybe Number
lookupPattern _ (Number n) = Just n lookupPattern _ (Number n) = Just n
lookupPattern scopes e = lookupPattern scopes e =
case lookupExpr scopes e of case lookupElem scopes e of
Nothing -> Nothing Nothing -> Nothing
Just (_, _, n) -> Just n Just (_, _, n) -> Just n
......
...@@ -9,4 +9,13 @@ module top; ...@@ -9,4 +9,13 @@ module top;
logic [1:0] e [3]; logic [1:0] e [3];
initial x = 0; initial x = 0;
assign c = x ? d : e; assign c = x ? d : e;
generate
begin : A
logic [1:0] c [3];
logic [1:0] d [3];
end
endgenerate
assign A.d = 0;
initial $display("%b %b", A.c[0], A.d[0]);
endmodule endmodule
...@@ -9,4 +9,13 @@ module top; ...@@ -9,4 +9,13 @@ module top;
wire [5:0] e; wire [5:0] e;
initial x = 0; initial x = 0;
assign c = x ? d : e; assign c = x ? d : e;
generate
begin : A
wire [1:0] c [0:2];
wire [5:0] d;
end
endgenerate
assign A.d = 0;
initial $display("%b %b", A.c[0], A.d[1:0]);
endmodule endmodule
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