diff --git a/CHANGELOG.md b/CHANGELOG.md index b10b6e6..b4cd8c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ declarations tagged with an attribute * Fixed stray attributes producing invalid nested output when attached to inlined interfaces and interface-bounds modules +* Fixed conversion of struct variables that shadow their module's name * Fixed `` `resetall `` not resetting the `` `default_nettype `` ### Other Enhancements diff --git a/src/Convert/Struct.hs b/src/Convert/Struct.hs index 9dd75a7..8986885 100644 --- a/src/Convert/Struct.hs +++ b/src/Convert/Struct.hs @@ -380,7 +380,7 @@ convertLHS l = do -- try expression conversion by looking at the *innermost* type first convertSubExpr :: Scopes Type -> Expr -> (Type, Expr) convertSubExpr scopes (Dot e x) = - if isntStruct subExprType then + if isntStruct subExprType || isHier then fallbackType scopes $ Dot e' x else if structIsntReady subExprType then (fieldType, Dot e' x) @@ -388,7 +388,7 @@ convertSubExpr scopes (Dot e x) = (fieldType, undottedWithSign) where (subExprType, e') = convertSubExpr scopes e - (fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x + (isHier, fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x base = fst bounds len = rangeSize bounds undotted = if null dims || rangeSize (head dims) == RawNum 1 @@ -403,7 +403,7 @@ convertSubExpr scopes (Dot e x) = else undotted convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) = - if isntStruct subExprType then + if isntStruct subExprType || isHier then (UnknownType, orig') else if structIsntReady subExprType then (replaceInnerTypeRange NonIndexed rOuter' fieldType, orig') @@ -420,7 +420,7 @@ convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) = (_, roRight') = convertSubExpr scopes roRight rOuter' = (roLeft', roRight') orig' = Range (Dot e' x) NonIndexed rOuter' - (fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x + (isHier, fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x [dim] = dims rangeLeft = ( BinOp Sub (fst bounds) $ BinOp Sub (fst dim) roLeft' , BinOp Sub (fst bounds) $ BinOp Sub (fst dim) roRight' ) @@ -429,7 +429,7 @@ convertSubExpr scopes (Range (Dot e x) NonIndexed rOuter) = undotted = Range e' NonIndexed $ endianCondRange dim rangeLeft rangeRight convertSubExpr scopes (Range (Dot e x) mode (baseO, lenO)) = - if isntStruct subExprType then + if isntStruct subExprType || isHier then (UnknownType, orig') else if structIsntReady subExprType then (replaceInnerTypeRange mode (baseO', lenO') fieldType, orig') @@ -444,7 +444,7 @@ convertSubExpr scopes (Range (Dot e x) mode (baseO, lenO)) = (_, baseO') = convertSubExpr scopes baseO (_, lenO') = convertSubExpr scopes lenO orig' = Range (Dot e' x) mode (baseO', lenO') - (fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x + (isHier, fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x [dim] = dims baseLeft = BinOp Sub (fst bounds) $ BinOp Sub (fst dim) baseO' baseRight = BinOp Add (snd bounds) $ BinOp Sub (snd dim) baseO' @@ -463,7 +463,7 @@ convertSubExpr scopes (Range e mode (left, right)) = (_, right') = convertSubExpr scopes right r' = (left', right') convertSubExpr scopes (Bit (Dot e x) i) = - if isntStruct subExprType then + if isntStruct subExprType || isHier then (dropInnerTypeRange backupType, orig') else if structIsntReady subExprType then (dropInnerTypeRange fieldType, orig') @@ -477,7 +477,7 @@ convertSubExpr scopes (Bit (Dot e x) i) = (_, i') = convertSubExpr scopes i (backupType, _) = fallbackType scopes $ Dot e' x orig' = Bit (Dot e' x) i' - (fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x + (isHier, fieldType, bounds, dims) = lookupFieldInfo scopes subExprType e' x [dim] = dims left = BinOp Sub (fst bounds) $ BinOp Sub (fst dim) i' right = BinOp Add (snd bounds) $ BinOp Sub (snd dim) i' @@ -536,13 +536,11 @@ isntStruct = (== Nothing) . getFields -- get the field type, flattened bounds, and original type dimensions lookupFieldInfo :: Scopes Type -> Type -> Expr -> Identifier - -> (Type, Range, [Range]) + -> (Bool, Type, Range, [Range]) lookupFieldInfo scopes struct base fieldName = if maybeFieldType == Nothing - then scopedError scopes $ "field '" ++ fieldName ++ "' not found in " - ++ show struct ++ ", in expression " - ++ show (Dot base fieldName) - else (fieldType, bounds, dims) + then (isHier, err, err, err) + else (False, fieldType, bounds, dims) where Just fields = getFields struct maybeFieldType = lookup fieldName $ map swap fields @@ -550,6 +548,10 @@ lookupFieldInfo scopes struct base fieldName = dims = snd $ typeRanges fieldType Just (_, unstructRanges) = convertStruct struct Just bounds = lookup fieldName unstructRanges + err = scopedError scopes $ "field '" ++ fieldName ++ "' not found in " + ++ show struct ++ ", in expression " + ++ show (Dot base fieldName) + isHier = lookupElem scopes (Dot base fieldName) /= Nothing -- attempts to convert based on the assignment-like contexts of TF arguments convertCall :: Scopes Type -> Expr -> Args -> Args diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index deaa497..914da53 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -159,8 +159,11 @@ isStringParam _ = return False -- checks if referring to part.wire is needlessly explicit unneededModuleScope :: Identifier -> Identifier -> ST Bool unneededModuleScope part wire = do + partDetails <- lookupElemM part accessesLocal <- localAccessesM wire - if accessesLocal == accessesTop then + if partDetails /= Nothing then + return False + else if accessesLocal == accessesTop then return True else if head accessesLocal == head accessesTop then do details <- lookupElemM wire diff --git a/test/core/struct_hier_shadow.sv b/test/core/struct_hier_shadow.sv new file mode 100644 index 0000000..2416825 --- /dev/null +++ b/test/core/struct_hier_shadow.sv @@ -0,0 +1,19 @@ +package P; + localparam [31:0] L = 8; + typedef struct packed { + logic [L + L[0] + L[1:0] + L[0+:1] - 1:0] x; + } S; +endpackage +module top; + P::S top; + logic [2:0] x; + assign x = '0; + assign top.x = '1; + initial begin + #1; + $display("%b %b", x, top.x); + $display("%b %b", x[0], top.x[0]); + $display("%b %b", x[1:0], top.x[1:0]); + $display("%b %b", x[0+:1], top.x[0+:1]); + end +endmodule diff --git a/test/core/struct_hier_shadow.v b/test/core/struct_hier_shadow.v new file mode 100644 index 0000000..58bfa95 --- /dev/null +++ b/test/core/struct_hier_shadow.v @@ -0,0 +1,13 @@ +module top; + wire [7:0] top; + wire [2:0] x; + assign x = 0; + assign top = 8'hFF; + initial begin + #1; + $display("%b %b", x, top); + $display("%b %b", x[0], top[0]); + $display("%b %b", x[1:0], top[1:0]); + $display("%b %b", x[0+:1], top[0+:1]); + end +endmodule