From 1aa30ea8139c3f5cfc9d24983437ee051b1871e6 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Tue, 27 Jul 2021 19:17:03 -0400 Subject: [PATCH] allow genvars to be shadowed --- src/Convert/DuplicateGenvar.hs | 2 +- src/Convert/Scoper.hs | 14 +++++++++++++- src/Convert/TypeOf.hs | 24 +++++++++++++++--------- test/core/duplicate_genvar_shadow.sv | 26 ++++++++++++++++++++++++++ test/core/duplicate_genvar_shadow.v | 9 +++++++++ 5 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 test/core/duplicate_genvar_shadow.sv create mode 100644 test/core/duplicate_genvar_shadow.v diff --git a/src/Convert/DuplicateGenvar.hs b/src/Convert/DuplicateGenvar.hs index fae44d5..46b3dff 100644 --- a/src/Convert/DuplicateGenvar.hs +++ b/src/Convert/DuplicateGenvar.hs @@ -18,7 +18,7 @@ traverseDescription = partScoper return traverseModuleItemM return return traverseModuleItemM :: ModuleItem -> Scoper () ModuleItem traverseModuleItemM (Genvar x) = do - details <- lookupElemM x + details <- lookupLocalIdentM x if details == Nothing then insertElem x () >> return (Genvar x) else return $ Generate [] diff --git a/src/Convert/Scoper.hs b/src/Convert/Scoper.hs index fbdf9f2..28fd59e 100644 --- a/src/Convert/Scoper.hs +++ b/src/Convert/Scoper.hs @@ -56,6 +56,8 @@ module Convert.Scoper , procedureLocM , isLoopVar , isLoopVarM + , loopVarDepth + , loopVarDepthM , lookupLocalIdent , lookupLocalIdentM , scopeModuleItemT @@ -65,7 +67,7 @@ module Convert.Scoper import Control.Monad.State.Strict import Data.Functor.Identity (runIdentity) -import Data.List (partition) +import Data.List (findIndices, partition) import Data.Maybe (isNothing) import qualified Data.Map.Strict as Map @@ -357,6 +359,16 @@ isLoopVar scopes x = any matches $ sCurrent scopes isLoopVarM :: Monad m => Identifier -> ScoperT a m Bool isLoopVarM = embedScopes isLoopVar +loopVarDepth :: Scopes a -> Identifier -> Maybe Int +loopVarDepth scopes x = + case findIndices matches $ sCurrent scopes of + [] -> Nothing + indices -> Just $ last indices + where matches = (== x) . tierIndex + +loopVarDepthM :: Monad m => Identifier -> ScoperT a m (Maybe Int) +loopVarDepthM = embedScopes loopVarDepth + evalScoper :: MapperM (Scoper a) Decl -> MapperM (Scoper a) ModuleItem diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index cd5c0c9..b75a398 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -157,18 +157,24 @@ traverseTypeM other = -- attempts to find the given (potentially hierarchical or generate-scoped) -- expression in the available scope information lookupTypeOf :: Expr -> ST Type +lookupTypeOf expr@(Ident x) = do + details <- lookupElemM x + loopVar <- loopVarDepthM x + return $ case details of + Nothing -> + if loopVar == Nothing + then TypeOf expr + else IntegerAtom TInteger Unspecified + Just (accesses, replacements, typ) -> + if maybe True (length accesses >) loopVar + then replaceInType replacements typ + else IntegerAtom TInteger Unspecified lookupTypeOf expr = do details <- lookupElemM expr - case details of - Nothing -> case expr of - Ident x -> do - isGenvar <- isLoopVarM x - return $ if isGenvar - then IntegerAtom TInteger Unspecified - else TypeOf expr - _ -> return $ TypeOf expr + return $ case details of + Nothing -> TypeOf expr Just (_, replacements, typ) -> - return $ replaceInType replacements typ + replaceInType replacements typ -- determines the type of an expression based on the available scope information -- according the semantics defined in IEEE 1800-2017, especially Section 11.6 diff --git a/test/core/duplicate_genvar_shadow.sv b/test/core/duplicate_genvar_shadow.sv new file mode 100644 index 0000000..d2f7051 --- /dev/null +++ b/test/core/duplicate_genvar_shadow.sv @@ -0,0 +1,26 @@ +`define DUMP(L) initial $display(`"L %0d`", $bits(i)); +module top; + genvar i; + for (i = 0; i < 1; i = 1) begin + `DUMP(A) + if (1) begin + localparam [9:0] i = 1; + `DUMP(B) + if (1) begin + genvar i; + for (i = 0; i < 1; i = 1) begin + `DUMP(C) + if (1) begin + localparam [5:0] i = 1; + `DUMP(D) + if (1) begin + genvar i; + for (i = 0; i < 1; i = 1) + `DUMP(E) + end + end + end + end + end + end +endmodule diff --git a/test/core/duplicate_genvar_shadow.v b/test/core/duplicate_genvar_shadow.v new file mode 100644 index 0000000..780b2a6 --- /dev/null +++ b/test/core/duplicate_genvar_shadow.v @@ -0,0 +1,9 @@ +module top; + initial begin + $display("A %0d", 32); + $display("B %0d", 10); + $display("C %0d", 32); + $display("D %0d", 6); + $display("E %0d", 32); + end +endmodule