diff --git a/CHANGELOG.md b/CHANGELOG.md index 59d50c6..2eb6ac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * Fixed conflicting genvar names when inlining interfaces and modules that use them; all genvars are now given a design-wide unique name * Fixed unconverted structs within explicit type casts +* Fixed unconverted multidimensional struct fields within dimension queries * Fixed non-typenames (e.g., from packages or subsequent declarations) improperly shadowing the names of `struct` pattern fields * Fixed failure to resolve typenames suffixed with dimensions in contexts diff --git a/src/Convert/MultiplePacked.hs b/src/Convert/MultiplePacked.hs index 2c3e6f4..b05d2c2 100644 --- a/src/Convert/MultiplePacked.hs +++ b/src/Convert/MultiplePacked.hs @@ -50,21 +50,22 @@ convertDescription other = other -- collects and converts declarations with multiple packed dimensions traverseDeclM :: Decl -> Scoper TypeInfo Decl traverseDeclM (Variable dir t ident a e) = do - t' <- traverseTypeM t a ident + recordTypeM t a ident traverseDeclExprsM traverseExprM $ Variable dir t' ident a e + where t' = flattenType t traverseDeclM net@Net{} = traverseNetAsVarM traverseDeclM net traverseDeclM (Param s t ident e) = do - t' <- traverseTypeM t [] ident + recordTypeM t [] ident traverseDeclExprsM traverseExprM $ Param s t' ident e + where t' = flattenType t traverseDeclM other = traverseDeclExprsM traverseExprM other --- write down the given declaration and then flatten it -traverseTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo Type -traverseTypeM t a ident = do +-- write down the given declaration +recordTypeM :: Type -> [Range] -> Identifier -> Scoper TypeInfo () +recordTypeM t a ident = do tScoped <- scopeType t insertElem ident (tScoped, a) - return $ flattenType t -- flatten the innermost dimension of the given type, and any types it contains flattenType :: Type -> Type @@ -132,7 +133,20 @@ traverseStmtM = traverseStmtExprsM traverseExprM traverseExprM :: Expr -> Scoper TypeInfo Expr -traverseExprM = traverseNestedExprsM convertExprM +traverseExprM = + embedScopes convertExpr >=> + traverseExprTypesM traverseTypeM >=> + traverseSinglyNestedExprsM traverseExprM + +traverseTypeM :: Type -> Scoper TypeInfo Type +traverseTypeM typ = + traverseTypeExprsM traverseExprM >=> + traverseSinglyNestedTypesM traverseTypeM $ + case typ of + Struct{} -> typ' + Union {} -> typ' + _ -> typ + where typ' = traverseSinglyNestedTypes flattenType typ traverseGenItemM :: GenItem -> Scoper TypeInfo GenItem traverseGenItemM = traverseGenItemExprsM traverseExprM @@ -147,20 +161,10 @@ traverseLHSM = traverseNestedLHSsM traverseLHSSingleM traverseLHSSingleM :: LHS -> Scoper TypeInfo LHS traverseLHSSingleM lhs = do let expr = lhsToExpr lhs - expr' <- convertExprM expr + expr' <- embedScopes convertExpr expr let Just lhs' = exprToLHS expr' return lhs' -convertExprM :: Expr -> Scoper TypeInfo Expr -convertExprM = - traverseExprTypesM convertTypeM >=> - embedScopes convertExpr - -convertTypeM :: Type -> Scoper TypeInfo Type -convertTypeM = - traverseNestedTypesM $ traverseTypeExprsM $ - traverseNestedExprsM convertExprM - convertExpr :: Scopes TypeInfo -> Expr -> Expr convertExpr scopes = rewriteExpr diff --git a/test/core/multipack_inline.sv b/test/core/multipack_inline.sv new file mode 100644 index 0000000..02eff2a --- /dev/null +++ b/test/core/multipack_inline.sv @@ -0,0 +1,24 @@ +module top; + typedef struct packed { + logic [1:0][1:0][1:0] x; + } U; + typedef union packed { + logic [$bits(U) - 1:0][7:0] a; + logic [3:0][15:0] b; + U [7:0] c; + } T; + typedef struct packed { + logic [$bits(U) - 1:0][7:0] a; + logic [3:0][15:0] b; + U [7:0] c; + T [2:0] d; + } S; + if ($bits(U) != 8) + $error("invalid width U"); + if ($bits(T) != 64) + $error("invalid width T"); + if ($bits(S) != 64 * 6) + $error("invalid width S"); + logic [31:0] x; + assign x[$bits(U) - 1:0] = '1; +endmodule diff --git a/test/core/multipack_inline.v b/test/core/multipack_inline.v new file mode 100644 index 0000000..60e7038 --- /dev/null +++ b/test/core/multipack_inline.v @@ -0,0 +1,4 @@ +module top; + wire [31:0] x; + assign x[7:0] = 1'sb1; +endmodule