mirror of https://github.com/zachjs/sv2v.git
fix errant expr resolution flagging
- references to other instances are no longer flagged - special handling for genvars to avoid flagging and modport scoping - interface inlining visits expressions in declarations - Scoper has interface for removing entries
This commit is contained in:
parent
1e6fa7b858
commit
1311e449fe
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
module Convert.Interface (convert) where
|
||||
|
||||
import Data.Maybe (isNothing, mapMaybe)
|
||||
import Data.Maybe (isJust, isNothing, mapMaybe)
|
||||
import Control.Monad.Writer.Strict
|
||||
import qualified Data.Map.Strict as Map
|
||||
|
||||
|
|
@ -391,17 +391,26 @@ inlineInstance global ranges modportBindings items partName
|
|||
Param _ _ x _ -> insertElem x ()
|
||||
ParamType _ x _ -> insertElem x ()
|
||||
CommentDecl{} -> return ()
|
||||
return decl
|
||||
traverseDeclExprsM traverseExprM decl
|
||||
|
||||
traverseModuleItemM :: ModuleItem -> Scoper () ModuleItem
|
||||
traverseModuleItemM (item @ Modport{}) =
|
||||
traverseModuleItemM item@Modport{} =
|
||||
traverseExprsM (scopeExpr >=> traverseExprM) item
|
||||
traverseModuleItemM item@(Instance _ _ x _ _) =
|
||||
insertElem x () >> traverseExprsM traverseExprM item
|
||||
traverseModuleItemM item =
|
||||
traverseExprsM traverseExprM item >>=
|
||||
traverseLHSsM traverseLHSM
|
||||
|
||||
traverseGenItemM :: GenItem -> Scoper () GenItem
|
||||
traverseGenItemM = traverseGenItemExprsM traverseExprM
|
||||
traverseGenItemM item@(GenFor (x, _) _ _ _) = do
|
||||
-- don't want to be scoped in modports
|
||||
insertElem x ()
|
||||
item' <- traverseGenItemExprsM traverseExprM item
|
||||
removeElem x
|
||||
return item'
|
||||
traverseGenItemM item =
|
||||
traverseGenItemExprsM traverseExprM item
|
||||
|
||||
traverseStmtM :: Stmt -> Scoper () Stmt
|
||||
traverseStmtM =
|
||||
|
|
@ -497,14 +506,20 @@ inlineInstance global ranges modportBindings items partName
|
|||
|
||||
checkExprResolution :: Scopes () -> Expr -> a -> a
|
||||
checkExprResolution local expr =
|
||||
case (lookupElem local expr, lookupElem global expr) of
|
||||
(Nothing, Just (_, _, DeclVal)) ->
|
||||
if not (exprResolves local expr) && exprResolves global expr
|
||||
then
|
||||
error $ "inlining instance \"" ++ instanceName ++ "\" of "
|
||||
++ inlineKind ++ " \"" ++ partName
|
||||
++ "\" would make expression \"" ++ show expr
|
||||
++ "\" used in \"" ++ instanceName
|
||||
++ "\" resolvable when it wasn't previously"
|
||||
_ -> id
|
||||
else id
|
||||
|
||||
exprResolves :: Scopes a -> Expr -> Bool
|
||||
exprResolves local (Ident x) =
|
||||
isJust (lookupElem local x) || isLoopVar local x
|
||||
exprResolves local expr =
|
||||
isJust (lookupElem local expr)
|
||||
|
||||
-- unambiguous reference to the current instance
|
||||
scopedInstanceRaw = accessesToExpr $ localAccesses global instanceName
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ module Convert.Scoper
|
|||
, scopeExpr
|
||||
, scopeType
|
||||
, insertElem
|
||||
, removeElem
|
||||
, injectItem
|
||||
, injectTopItem
|
||||
, injectDecl
|
||||
|
|
@ -218,10 +219,16 @@ instance ScopePath [Access] where
|
|||
where Ident y = iy
|
||||
|
||||
insertElem :: Monad m => ScopePath k => k -> a -> ScoperT a m ()
|
||||
insertElem key element = do
|
||||
insertElem key = setElem key . Just
|
||||
|
||||
removeElem :: Monad m => ScopePath k => k -> ScoperT a m ()
|
||||
removeElem key = setElem key Nothing
|
||||
|
||||
setElem :: Monad m => ScopePath k => k -> Maybe a -> ScoperT a m ()
|
||||
setElem key maybeElement = do
|
||||
s <- get
|
||||
let mapping = sMapping s
|
||||
let entry = Entry (Just element) "" Map.empty
|
||||
let entry = Entry maybeElement "" Map.empty
|
||||
let mapping' = setScope (toTiers s key) entry mapping
|
||||
put $ s { sMapping = mapping' }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
interface intf;
|
||||
byte x;
|
||||
endinterface
|
||||
|
||||
module mod(intf j);
|
||||
intf i();
|
||||
assign j.x = 1;
|
||||
assign i.x = 2;
|
||||
genvar z;
|
||||
for (z = 0; z < 2; z++) begin : blk
|
||||
wire [7:0] x = $bits(j.x) - 5 + z;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module top;
|
||||
byte z = 0;
|
||||
intf i();
|
||||
mod m(i);
|
||||
`define DUMP(expr) $display(`"expr = %b`", expr);
|
||||
initial begin
|
||||
`DUMP(z)
|
||||
`DUMP(i.x)
|
||||
`DUMP(m.i.x)
|
||||
`DUMP(m.blk[0].x)
|
||||
`DUMP(m.blk[1].x)
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
module top;
|
||||
reg [7:0] z = 0;
|
||||
`define DUMP(expr, val) $display(`"expr = %b`", val);
|
||||
initial begin
|
||||
`DUMP(z, z)
|
||||
`DUMP(i.x, 8'd1)
|
||||
`DUMP(m.i.x, 8'd2)
|
||||
`DUMP(m.blk[0].x, 8'd3)
|
||||
`DUMP(m.blk[1].x, 8'd4)
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// pattern: inlining instance "intf" of interface "Interface" would make expression "x" used in "intf" resolvable when it wasn't previously
|
||||
interface Interface;
|
||||
assign x = 1;
|
||||
endinterface
|
||||
module top;
|
||||
for (genvar x = 0; x < 2; x++)
|
||||
Interface intf();
|
||||
endmodule
|
||||
Loading…
Reference in New Issue