improve binding resolution error messages

This commit is contained in:
Zachary Snow 2024-12-15 00:42:13 -05:00
parent 30677b3dcb
commit 576a804d90
13 changed files with 44 additions and 20 deletions

View File

@ -29,6 +29,7 @@
### Other Enhancements
* Improved error messages for invalid port or parameter bindings
* `--write path/to/dir/` can now also be used with `--pass-through`
## v0.0.12

View File

@ -1,3 +1,4 @@
{-# LANGUAGE FlexibleInstances #-}
{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
@ -16,12 +17,14 @@ module Convert.ResolveBindings
import Control.Monad.Writer.Strict
import Data.List (intercalate, (\\))
import Data.Maybe (isNothing)
import qualified Data.Map.Strict as Map
import Convert.Traverse
import Language.SystemVerilog.AST
type Parts = Map.Map Identifier ([(Identifier, Bool)], [Identifier])
data PartInfo = PartInfo PartKW [(Identifier, Bool)] [Identifier]
type Parts = Map.Map Identifier PartInfo
convert :: [AST] -> [AST]
convert =
@ -30,8 +33,8 @@ convert =
(traverseDescriptions . traverseModuleItems . mapInstance)
collectPartsM :: Description -> Writer Parts ()
collectPartsM (Part _ _ _ _ name ports items) =
tell $ Map.singleton name (params, ports)
collectPartsM (Part _ _ kw _ name ports items) =
tell $ Map.singleton name $ PartInfo kw params ports
where params = parameterInfos items
collectPartsM _ = return ()
@ -48,16 +51,17 @@ parameterInfos =
mapInstance :: Parts -> ModuleItem -> ModuleItem
mapInstance parts (Instance m paramBindings x rs portBindings) =
-- if we can't find it, just skip :(
if maybePartInfo == Nothing
if isNothing maybePartInfo
then Instance m paramBindings x rs portBindings
else Instance m paramBindings' x rs portBindings'
where
maybePartInfo = Map.lookup m parts
Just (paramInfos, portNames) = maybePartInfo
Just (PartInfo kw paramInfos portNames) = maybePartInfo
paramNames = map fst paramInfos
msg :: String -> String
msg = flip (++) $ " in instance " ++ show x ++ " of " ++ show m
msg = flip (++) $ " in instance " ++ show x ++ " of " ++ show kw ++ " "
++ show m
paramBindings' = map checkParam $
resolveBindings (msg "parameter overrides") paramNames paramBindings
@ -101,22 +105,41 @@ mapInstance parts (Instance m paramBindings x rs portBindings) =
mapInstance _ other = other
class BindingArg k where
showBinding :: k -> String
instance BindingArg TypeOrExpr where
showBinding = either show show
instance BindingArg Expr where
showBinding = show
type Binding t = (Identifier, t)
-- give a set of bindings explicit names
resolveBindings :: String -> [Identifier] -> [Binding t] -> [Binding t]
resolveBindings
:: BindingArg t => String -> [Identifier] -> [Binding t] -> [Binding t]
resolveBindings _ _ [] = []
resolveBindings location available bindings@(("", _) : _) =
if length available < length bindings then
error $ "too many bindings specified for " ++ location
error $ "too many bindings specified for " ++ location ++ ": "
++ describeList "specified" (map (showBinding . snd) bindings)
++ ", but only " ++ describeList "available" (map show available)
else
zip available $ map snd bindings
resolveBindings location available bindings =
if not $ null unknowns then
error $ "unknown binding" ++ unknownsPlural ++ " "
++ unknownsStr ++ " specified for " ++ location
++ unknownsStr ++ " specified for " ++ location ++ ", "
++ describeList "available" (map show available)
else
bindings
where
unknowns = map fst bindings \\ available
unknownsPlural = if length unknowns == 1 then "" else "s"
unknownsStr = intercalate ", " $ map show unknowns
describeList :: String -> [String] -> String
describeList desc [] = "0 " ++ desc
describeList desc xs =
show (length xs) ++ " " ++ desc ++ " (" ++ xsStr ++ ")"
where xsStr = intercalate ", " xs

View File

@ -1,4 +1,4 @@
// pattern: unknown binding "R" specified for parameters in class specialization of "example"
// pattern: unknown binding "R" specified for parameters in class specialization of "example", 2 available \("P", "Q"\)
class example #(
parameter P = 1,
parameter Q = 1

View File

@ -1,4 +1,4 @@
// pattern: unknown binding "z" specified for port connections in instance "e" of "example"
// pattern: unknown binding "z" specified for port connections in instance "e" of module "example", 2 available \("x", "y"\)
module example(
input x, y
);

View File

@ -1,4 +1,4 @@
// pattern: unknown binding "R" specified for parameter overrides in instance "e" of "example"
// pattern: unknown binding "R" specified for parameter overrides in instance "e" of module "example", 2 available \("P", "Q"\)
module example;
parameter P = 1;
parameter Q = 1;

View File

@ -1,4 +1,4 @@
// pattern: unknown bindings "w", "z" specified for port connections in instance "e" of "example"
// pattern: unknown bindings "w", "z" specified for port connections in instance "e" of module "example", 2 available \("x", "y"\)
module example(
input x, y
);

View File

@ -1,4 +1,4 @@
// pattern: too many bindings specified for parameters in class specialization of "example"
// pattern: too many bindings specified for parameters in class specialization of "example": 3 specified \(1, 2, 3\), but only 2 available \("P", "Q"\)
class example #(
parameter P = 1,
parameter Q = 1

View File

@ -1,4 +1,4 @@
// pattern: too many bindings specified for parameter overrides in instance "e" of "example"
// pattern: too many bindings specified for parameter overrides in instance "e" of module "example": 3 specified \(1, 2, 3\), but only 2 available \("P", "Q"\)
module example;
parameter P = 1;
parameter Q = 1;

View File

@ -1,4 +1,4 @@
// pattern: too many bindings specified for port connections in instance "e" of "example"
// pattern: too many bindings specified for port connections in instance "e" of module "example": 3 specified \(1'b1, 1'b0, 1'b0\), but only 2 available \("x", "y"\)
module example(
input x, y
);

View File

@ -1,4 +1,4 @@
// pattern: parameter "P" in instance "intf" of "Interface" expects an expression, but was given type logic
// pattern: parameter "P" in instance "intf" of interface "Interface" expects an expression, but was given type logic
interface Interface;
parameter P = 0;
logic [P-1:0] x;

View File

@ -1,4 +1,4 @@
// pattern: parameter "P" in instance "intf" of "Interface" expects a type, but was given expression 1
// pattern: parameter "P" in instance "intf" of interface "Interface" expects a type, but was given expression 1
interface Interface;
parameter type P;
P x;

View File

@ -1,4 +1,4 @@
// pattern: parameter "P" in instance "mod" of "Module" expects an expression, but was given type logic
// pattern: parameter "P" in instance "mod" of module "Module" expects an expression, but was given type logic
module Module;
parameter P = 0;
logic [P-1:0] x;

View File

@ -1,4 +1,4 @@
// pattern: parameter "P" in instance "mod" of "Module" expects a type, but was given expression 1
// pattern: parameter "P" in instance "mod" of module "Module" expects a type, but was given expression 1
module Module;
parameter type P;
P x;