diff --git a/src/Convert/PortDecl.hs b/src/Convert/PortDecl.hs index 0561f10..9e3a808 100644 --- a/src/Convert/PortDecl.hs +++ b/src/Convert/PortDecl.hs @@ -28,11 +28,20 @@ traverseDescription :: Description -> Description traverseDescription (Part attrs extern kw liftetime name ports items) = Part attrs extern kw liftetime name ports items' where items' = convertPorts name ports items +traverseDescription (PackageItem item) = + PackageItem $ convertPackageItem item traverseDescription other = other +convertPackageItem :: PackageItem -> PackageItem +convertPackageItem (Function l t x decls stmts) = + Function l t x (convertTFDecls decls) stmts +convertPackageItem (Task l x decls stmts) = + Task l x (convertTFDecls decls) stmts +convertPackageItem other = other + convertPorts :: Identifier -> [Identifier] -> [ModuleItem] -> [ModuleItem] convertPorts name ports items - | not (null extraPorts) = + | not (null name) && not (null extraPorts) = error $ "declared ports " ++ intercalate ", " extraPorts ++ " are not in the port list of " ++ name | otherwise = @@ -48,6 +57,8 @@ convertPorts name ports items | Variable d _ x _ e <- decl = rewrite decl (combineIdent x) d x e | Net d _ _ _ x _ e <- decl = rewrite decl (combineIdent x) d x e | otherwise = MIPackageItem $ Decl decl + traverseItem (MIPackageItem item) = + MIPackageItem $ convertPackageItem item traverseItem other = other -- produce the combined declaration for a port, if it has one @@ -57,6 +68,17 @@ convertPorts name ports items dataDecl <- lookup x dataDecls Just $ combineDecls portDecl dataDecl +-- wrapper for convertPorts enabling its application to task or function decls +convertTFDecls :: [Decl] -> [Decl] +convertTFDecls = + map unwrap . convertPorts "" [] . map wrap + where + wrap :: Decl -> ModuleItem + wrap = MIPackageItem . Decl + unwrap :: ModuleItem -> Decl + unwrap item = decl + where MIPackageItem (Decl decl) = item + -- given helpfully extracted information, update the given declaration rewrite :: Decl -> Maybe Decl -> Direction -> Identifier -> Expr -> ModuleItem -- implicitly-typed ports default to `logic` in SystemVerilog diff --git a/test/core/non_ansi_port_decl_tf.sv b/test/core/non_ansi_port_decl_tf.sv new file mode 100644 index 0000000..b8842c1 --- /dev/null +++ b/test/core/non_ansi_port_decl_tf.sv @@ -0,0 +1,22 @@ +function automatic [4:0] f; + input signed [3:0] x; + reg [3:0] x; + var type(x) y; + y = x; + f = y; +endfunction +module top; + task t; + input signed [3:0] x; + reg [3:0] x; + var type(x) y; + reg [4:0] z; + y = x; + z = y; + $display("t(%b) -> %b", x, z); + endtask + localparam [3:0] X = 4'b1011; + localparam [4:0] Y = f(X); + initial $display("f(%b) -> %b", X, Y); + initial t(X); +endmodule diff --git a/test/core/non_ansi_port_decl_tf.v b/test/core/non_ansi_port_decl_tf.v new file mode 100644 index 0000000..0f6998c --- /dev/null +++ b/test/core/non_ansi_port_decl_tf.v @@ -0,0 +1,18 @@ +module top; + function automatic [4:0] f; + input reg signed [3:0] x; + f = x; + endfunction + task t; + input signed [3:0] x; + reg [4:0] z; + begin + z = x; + $display("t(%b) -> %b", x, z); + end + endtask + localparam [3:0] X = 4'b1011; + localparam [4:0] Y = f(X); + initial $display("f(%b) -> %b", X, Y); + initial t(X); +endmodule