Commit 086eb786 by Zachary Snow

elaborate accesses to fields of struct constants

parent 4533e4ff
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
static prefixes, which could cause deep recursion and run out of memory on static prefixes, which could cause deep recursion and run out of memory on
some designs some designs
### Other Enhancements
* Added elaboration for accesses to fields of struct constants, which can
substantially improve performance on some designs
## v0.0.10 ## v0.0.10
### Breaking Changes ### Breaking Changes
......
...@@ -48,6 +48,7 @@ import qualified Convert.Simplify ...@@ -48,6 +48,7 @@ import qualified Convert.Simplify
import qualified Convert.Stream import qualified Convert.Stream
import qualified Convert.StringParam import qualified Convert.StringParam
import qualified Convert.Struct import qualified Convert.Struct
import qualified Convert.StructConst
import qualified Convert.TFBlock import qualified Convert.TFBlock
import qualified Convert.Typedef import qualified Convert.Typedef
import qualified Convert.TypeOf import qualified Convert.TypeOf
...@@ -114,6 +115,7 @@ initialPhases selectExclude = ...@@ -114,6 +115,7 @@ initialPhases selectExclude =
, selectExclude Job.Assert Convert.Assertion.convert , selectExclude Job.Assert Convert.Assertion.convert
, selectExclude Job.Always Convert.AlwaysKW.convert , selectExclude Job.Always Convert.AlwaysKW.convert
, Convert.Package.convert , Convert.Package.convert
, Convert.StructConst.convert
, Convert.PortDecl.convert , Convert.PortDecl.convert
, Convert.ParamNoDefault.convert , Convert.ParamNoDefault.convert
, Convert.ResolveBindings.convert , Convert.ResolveBindings.convert
......
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- High-level elaboration for struct constant accesses
-
- This greatly simplifies designs with long sequences of struct parameters
- which extend and reference one another, as seen in BlackParrot.
-}
module Convert.StructConst (convert) where
import Control.Monad.State.Strict
import Data.Maybe (fromMaybe)
import Data.Tuple (swap)
import qualified Data.Map.Strict as Map
import Convert.Traverse
import Language.SystemVerilog.AST
type StructType = [Field]
type StructValue = [(TypeOrExpr, Expr)]
type Const = (StructType, StructValue)
type Consts = Map.Map Identifier Const
type Types = Map.Map Identifier StructType
type SC = State (Types, Consts)
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions convertDescription
convertDescription :: Description -> Description
convertDescription =
flip evalState mempty .
traverseModuleItemsM (traverseDeclsM elaborateDecl)
insertType :: Identifier -> [Field] -> SC ()
insertType ident typ = do
(types, consts) <- get
let types' = Map.insert ident typ types
put (types', consts)
insertConst :: Identifier -> Const -> SC ()
insertConst ident cnst = do
(types, consts) <- get
let consts' = Map.insert ident cnst consts
put (types, consts')
lookupType :: Type -> SC [Field]
lookupType (Alias ident []) = do
maybeFields <- gets $ Map.lookup ident . fst
return $ fromMaybe [] maybeFields
lookupType (Struct (Packed Unspecified) fields []) =
return fields
lookupType _ = return []
lookupConst :: Identifier -> SC (Maybe Const)
lookupConst param = gets $ Map.lookup param . snd
elaborateDecl :: Decl -> SC Decl
-- track struct type parameters
elaborateDecl decl@(ParamType Localparam x t)
| Struct (Packed Unspecified) fields [] <- t =
insertType x fields >> return decl
-- track and resolve struct constants
elaborateDecl (Param Localparam t x e) = do
e' <- elaborateExpr e
fields <- lookupType t
when (not $ null fields) $ do
maybeValues <- extractStructValue e'
case maybeValues of
Just values -> insertConst x (fields, values)
Nothing -> return ()
return $ Param Localparam t x e'
elaborateDecl decl = return decl
-- extract the pattern items, including for simple aliases
extractStructValue :: Expr -> SC (Maybe StructValue)
extractStructValue (Pattern values) = return $ Just values
extractStructValue (Ident param) = fmap (fmap snd) $ lookupConst param
extractStructValue _ = return Nothing
-- elaborate constant field accesses
elaborateExpr :: Expr -> SC Expr
elaborateExpr expr@(Dot (Ident param) field) =
fmap (fromMaybe expr . join . fmap (resolveParam field)) (lookupConst param)
elaborateExpr expr =
traverseSinglyNestedExprsM elaborateExpr expr
-- lookup value in struct constant
resolveParam :: Identifier -> Const -> Maybe Expr
resolveParam field (fields, values) = do
fieldType <- lookup field (map swap fields)
value <- mplus
(lookup (Right $ Ident field) values)
(lookup (Left UnknownType) values)
Just $ Cast (Left fieldType) value
...@@ -101,6 +101,7 @@ executable sv2v ...@@ -101,6 +101,7 @@ executable sv2v
Convert.Stream Convert.Stream
Convert.StringParam Convert.StringParam
Convert.Struct Convert.Struct
Convert.StructConst
Convert.TFBlock Convert.TFBlock
Convert.Traverse Convert.Traverse
Convert.Typedef Convert.Typedef
......
package pkg;
typedef struct packed {
integer unsigned a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
} T;
`define step(b, o, f) f: o.f == "inv" ? b.f : o.f
`define extend(_b, _o) '{ \
`step(_b, _o, a), \
`step(_b, _o, b), \
`step(_b, _o, c), \
`step(_b, _o, d), \
`step(_b, _o, e), \
`step(_b, _o, f), \
`step(_b, _o, g), \
`step(_b, _o, h), \
`step(_b, _o, i), \
`step(_b, _o, j), \
`step(_b, _o, k), \
`step(_b, _o, l), \
`step(_b, _o, m), \
`step(_b, _o, n), \
`step(_b, _o, o), \
`step(_b, _o, p), \
`step(_b, _o, q), \
`step(_b, _o, r), \
`step(_b, _o, s), \
`step(_b, _o, t), \
`step(_b, _o, u), \
`step(_b, _o, v), \
`step(_b, _o, w), \
`step(_b, _o, x), \
`step(_b, _o, y), \
`step(_b, _o, z) \
}
localparam X = 1'd0;
localparam Y = 1'd1;
localparam T a_cfg = '{a: X, b: X, c: X, d: X, e: X, f: X, default: Y};
`define expand(let_a, let_b) \
localparam T let_a``_ext = '{let_a: Y, default: "inv"}; \
localparam T let_b``_cfg = `extend(let_a``_cfg, let_a``_ext);
`expand(a, b)
`expand(b, c)
`expand(c, d)
`expand(d, e)
`expand(e, f)
`expand(f, g)
`expand(g, h)
`expand(h, i)
`expand(i, j)
`expand(j, k)
`expand(k, l)
`expand(l, m)
`expand(m, n)
`expand(n, o)
`expand(o, p)
`expand(p, q)
`expand(q, r)
`expand(r, s)
`expand(s, t)
`expand(t, u)
`expand(u, v)
`expand(v, w)
`expand(w, x)
`expand(x, y)
`expand(y, z)
localparam P = z_cfg.z;
endpackage
module top;
initial $display(pkg::P);
endmodule
module top;
localparam P = 32'd1;
initial $display(P);
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