Commit 1b8aace1 by Zachary Snow

check for module or interface names used as type names

parent b7738a32
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
* Port connection attributes (e.g., [pulp_soc.sv]) are now ignored with a * Port connection attributes (e.g., [pulp_soc.sv]) are now ignored with a
warning rather than failing to parse warning rather than failing to parse
* Improved error message when specifying an extraneous named port connection * Improved error message when specifying an extraneous named port connection
* Added checks for accidental usage of interface or module names as type names
[pulp_soc.sv]: https://github.com/pulp-platform/pulp_soc/blob/0573a85c/rtl/pulp_soc/pulp_soc.sv#L733 [pulp_soc.sv]: https://github.com/pulp-platform/pulp_soc/blob/0573a85c/rtl/pulp_soc/pulp_soc.sv#L733
......
...@@ -10,6 +10,7 @@ module Convert.Interface (convert) where ...@@ -10,6 +10,7 @@ module Convert.Interface (convert) where
import Data.List (intercalate, (\\)) import Data.List (intercalate, (\\))
import Data.Maybe (isJust, isNothing, mapMaybe) import Data.Maybe (isJust, isNothing, mapMaybe)
import Control.Monad.Writer.Strict import Control.Monad.Writer.Strict
import Text.Read (readMaybe)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Convert.ExprUtils (endianCondExpr) import Convert.ExprUtils (endianCondExpr)
...@@ -70,13 +71,26 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) = ...@@ -70,13 +71,26 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) =
traverseDeclM :: Decl -> Scoper [ModportDecl] Decl traverseDeclM :: Decl -> Scoper [ModportDecl] Decl
traverseDeclM decl = do traverseDeclM decl = do
case decl of case decl of
Variable _ _ x _ _ -> insertElem x DeclVal Variable _ t x _ _ -> checkDeclType t x $ insertElem x DeclVal
Net _ _ _ _ x _ _ -> insertElem x DeclVal Net _ _ _ t x _ _ -> checkDeclType t x $ insertElem x DeclVal
Param _ _ x _ -> insertElem x DeclVal Param _ t x _ -> checkDeclType t x $ insertElem x DeclVal
ParamType _ x _ -> insertElem x DeclVal ParamType _ x _ -> insertElem x DeclVal
CommentDecl{} -> return () CommentDecl{} -> return ()
return decl return decl
-- check for module or interface names used as type names
checkDeclType :: Type -> Identifier -> Scoper a b -> Scoper a b
checkDeclType (Alias typeName _) declName continue
| isNothing (readMaybe declName :: Maybe Int) = do
maybeType <- lookupElemM typeName
case (maybePart, maybeType) of
(Just part, Nothing{}) -> scopedErrorM $ "declaration " ++
declName ++ " uses " ++ show (pKind part) ++ " name " ++
typeName ++ " where a type name is expected"
_ -> continue
where maybePart = Map.lookup typeName parts
checkDeclType _ _ other = other
lookupIntfElem :: Scopes [ModportDecl] -> Expr -> LookupResult [ModportDecl] lookupIntfElem :: Scopes [ModportDecl] -> Expr -> LookupResult [ModportDecl]
lookupIntfElem modports expr = lookupIntfElem modports expr =
case lookupElem modports expr of case lookupElem modports expr of
...@@ -285,6 +299,7 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) = ...@@ -285,6 +299,7 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) =
else if elem x (pPorts partInfo) then else if elem x (pPorts partInfo) then
tell [(x, info)] >> return decl tell [(x, info)] >> return decl
else else
-- TODO: This does not handle shadowed typenames.
scopedErrorM $ scopedErrorM $
"Modport not in port list: " ++ show t ++ " " ++ x "Modport not in port list: " ++ show t ++ " " ++ x
++ ". Is this an interface missing a port list?" ++ ". Is this an interface missing a port list?"
......
interface I;
logic [3:0] x;
endinterface
module top;
I i();
if (1) begin : blk
typedef logic I;
var I i;
assign i = 0;
end
initial $display("%b %b", i.x, blk.i);
endmodule
module top;
generate
if (1) begin : i
wire [3:0] x;
end
if (1) begin : blk
wire i;
assign i = 0;
end
endgenerate
initial $display("%b %b", i.x, blk.i);
endmodule
// pattern: declaration dst uses interface name I where a type name is expected
// location: interface_name_func.sv:5:12
interface I;
logic [3:0] x;
task t(I dst, I src);
dst.x <= src.x;
endtask
endinterface
module top;
I i();
endmodule
// pattern: declaration i uses interface name I where a type name is expected
// location: interface_name_var.sv:7:12
interface I;
logic [3:0] x;
endinterface
module top;
if (1) var I i;
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