From b8759776cacc9034871f16a4ece3a3c097dcf7eb Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 31 Jan 2021 14:39:13 -0500 Subject: [PATCH] limited progress on typeof signedness - ensure concats and repeats stay unsigned - defer unbased-unsized conversion to enable cast semantics - disable inaccurate folding of binary operations of based numbers - fix typeof and size cast binop signedness logic - fix typeof $unsigned and $signed - test harness allows production of `integer unsigned` --- src/Convert.hs | 2 +- src/Convert/ExprUtils.hs | 10 +- src/Convert/SizeCast.hs | 31 ++++-- src/Convert/TypeOf.hs | 67 ++++++++++--- test/basic/dimensions.sv | 3 + test/basic/dimensions.v | 30 ++++++ test/basic/typeof_signed.sv | 195 ++++++++++++++++++++++++++++++++++++ test/basic/typeof_signed.v | 30 ++++++ test/lib/functions.sh | 2 +- 9 files changed, 342 insertions(+), 28 deletions(-) create mode 100644 test/basic/typeof_signed.sv create mode 100644 test/basic/typeof_signed.v diff --git a/src/Convert.hs b/src/Convert.hs index 2081c8f..00a78b9 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -73,13 +73,13 @@ phases excludes = , Convert.TypeOf.convert , Convert.DimensionQuery.convert , Convert.ParamType.convert + , Convert.UnbasedUnsized.convert , Convert.SizeCast.convert , Convert.Simplify.convert , Convert.Stream.convert , Convert.Struct.convert , Convert.TFBlock.convert , Convert.Typedef.convert - , Convert.UnbasedUnsized.convert , Convert.Unique.convert , Convert.UnpackedArray.convert , Convert.Unsigned.convert diff --git a/src/Convert/ExprUtils.hs b/src/Convert/ExprUtils.hs index 9c44863..aedadc4 100644 --- a/src/Convert/ExprUtils.hs +++ b/src/Convert/ExprUtils.hs @@ -36,8 +36,13 @@ simplifyStep (UniOp LogNot (BinOp Ne a b)) = BinOp Eq a b simplifyStep (UniOp UniSub (UniOp UniSub e)) = e simplifyStep (UniOp UniSub (BinOp Sub e1 e2)) = BinOp Sub e2 e1 -simplifyStep (e @ (Concat [Pattern{}])) = e -simplifyStep (Concat [e]) = e +simplifyStep (Concat [Number (Decimal size _ value)]) = + Number $ Decimal size False value +simplifyStep (Concat [Number (Based size _ base value kinds)]) = + Number $ Based size False base value kinds +simplifyStep (Concat [e @ Stream{}]) = e +simplifyStep (Concat [e @ Concat{}]) = e +simplifyStep (Concat [e @ Repeat{}]) = e simplifyStep (Concat es) = Concat $ filter (/= Concat []) es simplifyStep (Repeat (Dec 0) _) = Concat [] simplifyStep (Repeat (Dec 1) es) = Concat es @@ -107,7 +112,6 @@ simplifyBinOp op e1 e2 = (Dec x, SizDec y) -> constantFold orig op x y (Bas x, Dec y) -> constantFold orig op x y (Dec x, Bas y) -> constantFold orig op x y - (Bas x, Bas y) -> constantFold orig op x y (NegDec x, Dec y) -> constantFold orig op (-x) y (Dec x, NegDec y) -> constantFold orig op x (-y) (NegDec x, NegDec y) -> constantFold orig op (-x) (-y) diff --git a/src/Convert/SizeCast.hs b/src/Convert/SizeCast.hs index 894f7a0..c6a4879 100644 --- a/src/Convert/SizeCast.hs +++ b/src/Convert/SizeCast.hs @@ -59,9 +59,6 @@ traverseGenItemM = traverseGenItemExprsM traverseExprM traverseStmtM :: Stmt -> Scoper Type Stmt traverseStmtM = traverseStmtExprsM traverseExprM -pattern ConvertedUU :: Integer -> Integer -> Expr -pattern ConvertedUU a b = Number (Based 1 True Binary a b) - traverseExprM :: Expr -> Scoper Type Expr traverseExprM = traverseNestedExprsM convertExprM @@ -104,10 +101,24 @@ traverseExprM = convertExprM other = return other convertCastM :: Expr -> Expr -> Scoper Type Expr - convertCastM (RawNum n) (ConvertedUU a b) = + convertCastM (RawNum n) (Number (Based 1 True Binary a b)) = + return $ Number $ Based (fromIntegral n) True Binary + (extend a) (extend b) + where + extend 0 = 0 + extend 1 = (2 ^ n) - 1 + extend _ = error "not possible" + convertCastM (RawNum n) (Number (UnbasedUnsized ch)) = return $ Number $ Based (fromIntegral n) False Binary (extend a) (extend b) where + (a, b) = case ch of + '0' -> (0, 0) + '1' -> (1, 0) + 'x' -> (0, 1) + 'z' -> (1, 1) + _ -> error $ "unexpected unbased-unsized digit: " ++ [ch] + extend :: Integer -> Integer extend 0 = 0 extend 1 = (2 ^ n) - 1 extend _ = error "not possible" @@ -183,6 +194,10 @@ exprSigning scopes (BinOp op e1 e2) = ShiftAL -> curry fst ShiftAR -> curry fst _ -> \_ _ -> Just Unspecified +exprSigning _ (Number n) = + Just $ if numberIsSigned n + then Signed + else Unsigned exprSigning scopes expr = case lookupElem scopes expr of Just (_, _, t) -> typeSigning t @@ -191,11 +206,11 @@ exprSigning scopes expr = combineSigning :: Maybe Signing -> Maybe Signing -> Maybe Signing combineSigning Nothing _ = Nothing combineSigning _ Nothing = Nothing -combineSigning (Just Unspecified) msg = msg -combineSigning msg (Just Unspecified) = msg -combineSigning (Just Signed) _ = Just Signed -combineSigning _ (Just Signed) = Just Signed +combineSigning (Just Unspecified) _ = Just Unspecified +combineSigning _ (Just Unspecified) = Just Unspecified combineSigning (Just Unsigned) _ = Just Unsigned +combineSigning _ (Just Unsigned) = Just Unsigned +combineSigning (Just Signed) (Just Signed) = Just Signed typeSigning :: Type -> Maybe Signing typeSigning (Net _ sg _) = Just sg diff --git a/src/Convert/TypeOf.hs b/src/Convert/TypeOf.hs index 099bf8c..bc124e8 100644 --- a/src/Convert/TypeOf.hs +++ b/src/Convert/TypeOf.hs @@ -117,16 +117,18 @@ typeof (Number n) = typeof (Call (Ident x) args) = typeofCall x args typeof (orig @ (Bit e _)) = do t <- typeof e + let t' = popRange t case t of TypeOf{} -> lookupTypeOf orig Alias{} -> return $ TypeOf orig - _ -> return $ popRange t + _ -> return $ typeSignednessOverride t' Unsigned t' typeof (orig @ (Range e mode r)) = do t <- typeof e + let t' = replaceRange (lo, hi) t return $ case t of TypeOf{} -> TypeOf orig Alias{} -> TypeOf orig - _ -> replaceRange (lo, hi) t + _ -> typeSignednessOverride t' Unsigned t' where lo = fst r hi = case mode of @@ -145,12 +147,12 @@ typeof (orig @ (Dot e x)) = do case lookup x $ map swap fields of Just typ -> typ Nothing -> TypeOf orig -typeof (Cast (Right s) _) = return $ typeOfSize s typeof (UniOp op expr) = typeofUniOp op expr typeof (BinOp op a b) = typeofBinOp op a b typeof (Mux _ a b) = largerSizeType a b -typeof (Concat exprs) = return $ typeOfSize $ concatSize exprs -typeof (Repeat reps exprs) = return $ typeOfSize size +typeof (Concat exprs) = return $ typeOfSize Unsigned $ concatSize exprs +typeof (Stream _ _ exprs) = return $ typeOfSize Unsigned $ concatSize exprs +typeof (Repeat reps exprs) = return $ typeOfSize Unsigned size where size = BinOp Mul reps (concatSize exprs) typeof (String str) = return $ IntegerVector TBit Unspecified [r] @@ -167,12 +169,22 @@ unescapedLength (_ : rest) = 1 + unescapedLength rest -- type of a standard (non-member) function call typeofCall :: String -> Args -> Scoper Type Type -typeofCall "$unsigned" (Args [e] []) = typeof e -typeofCall "$signed" (Args [e] []) = typeof e +typeofCall "$unsigned" (Args [e] []) = return $ typeOfSize Unsigned $ sizeof e +typeofCall "$signed" (Args [e] []) = return $ typeOfSize Signed $ sizeof e typeofCall "$clog2" (Args [_] []) = return $ IntegerAtom TInteger Unspecified typeofCall fnName _ = typeof $ Ident fnName +-- replaces the signing of a type if possible +typeSignednessOverride :: Type -> Signing -> Type -> Type +typeSignednessOverride fallback sg t = + case t of + IntegerVector base _ rs -> IntegerVector base sg rs + IntegerAtom base _ -> IntegerAtom base sg + Net base _ rs -> Net base sg rs + Implicit _ rs -> Implicit sg rs + _ -> fallback + -- type of a unary operator expression typeofUniOp :: UniOp -> Expr -> Scoper Type Type typeofUniOp UniAdd e = typeof e @@ -222,9 +234,36 @@ largerSizeType a (Number (Based 1 _ _ _ _)) = typeof a largerSizeType a b = do t <- typeof a u <- typeof b - return $ if t == u - then t - else typeOfSize $ largerSizeOf a b + let sg = binopSignedness (typeSignedness t) (typeSignedness u) + return $ + if t == u then + t + else if sg == Unspecified then + TypeOf $ BinOp Add a b + else + typeOfSize sg $ largerSizeOf a b + +-- returns the signedness of a traditional arithmetic binop, if possible +binopSignedness :: Signing -> Signing -> Signing +binopSignedness Unspecified _ = Unspecified +binopSignedness _ Unspecified = Unspecified +binopSignedness Unsigned _ = Unsigned +binopSignedness _ Unsigned = Unsigned +binopSignedness Signed Signed = Signed + +-- returns the signedness of the given type, if possible +typeSignedness :: Type -> Signing +typeSignedness (Net _ sg _) = signednessFallback Unsigned sg +typeSignedness (Implicit sg _) = signednessFallback Unsigned sg +typeSignedness (IntegerVector _ sg _) = signednessFallback Unsigned sg +typeSignedness (IntegerAtom t sg ) = signednessFallback fallback sg + where fallback = if t == TTime then Unsigned else Signed +typeSignedness _ = Unspecified + +-- helper for producing the former signing when the latter is unspecified +signednessFallback :: Signing -> Signing -> Signing +signednessFallback fallback Unspecified = fallback +signednessFallback _ sg = sg -- returns the total size of concatenated list of expressions concatSize :: [Expr] -> Expr @@ -245,12 +284,10 @@ largerSizeOf a b = where cond = BinOp Ge (sizeof a) (sizeof b) -- produces a generic type of the given size -typeOfSize :: Expr -> Type -typeOfSize size = +typeOfSize :: Signing -> Expr -> Type +typeOfSize sg size = IntegerVector TLogic sg [(hi, RawNum 0)] - where - sg = Unspecified -- suitable for now - hi = BinOp Sub size (RawNum 1) + where hi = BinOp Sub size (RawNum 1) -- combines a type with unpacked ranges injectRanges :: Type -> [Range] -> Type diff --git a/test/basic/dimensions.sv b/test/basic/dimensions.sv index 50e0b61..d291d7b 100644 --- a/test/basic/dimensions.sv +++ b/test/basic/dimensions.sv @@ -34,6 +34,9 @@ module top; $display("args %b", $size(RamPair, 1'dx)); `EXHAUST(Ram); + `EXHAUST(Ram[0]); + `EXHAUST($unsigned(Ram[0])); + `EXHAUST($signed(Ram[0])); `EXHAUST(Ram[0+:2]); `EXHAUST(Ram[1+:2]); `EXHAUST(Ram[0][2-:1]); diff --git a/test/basic/dimensions.v b/test/basic/dimensions.v index f9d38f8..a00f626 100644 --- a/test/basic/dimensions.v +++ b/test/basic/dimensions.v @@ -23,6 +23,36 @@ module top; $display(1); $display(160); + $display(16, 16, 1'bx); + $display(16, 16, 1'bx); + $display(1, 1, 1'bx); + $display(16, 16, 1'bx); + $display(1, 1, 1'bx); + $display(1, 1, 1'bx); + $display(1); + $display(0); + $display(16); + + $display(16, 16, 1'bx); + $display(15, 15, 1'bx); + $display(0, 0, 1'bx); + $display(15, 15, 1'bx); + $display(0, 0, 1'bx); + $display(1, 1, 1'bx); + $display(1); + $display(0); + $display(16); + + $display(16, 16, 1'bx); + $display(15, 15, 1'bx); + $display(0, 0, 1'bx); + $display(15, 15, 1'bx); + $display(0, 0, 1'bx); + $display(1, 1, 1'bx); + $display(1); + $display(0); + $display(16); + $display(2, 2, 16); $display(0, 0, 16); $display(1, 1, 1); diff --git a/test/basic/typeof_signed.sv b/test/basic/typeof_signed.sv new file mode 100644 index 0000000..8701d5b --- /dev/null +++ b/test/basic/typeof_signed.sv @@ -0,0 +1,195 @@ +`define ASSERT_SIGNEDNESS(expr, signedness_str, signedness_val) \ + initial begin \ + type(expr) typeof; \ + logic signed [$bits(expr):0] ones; \ + logic [$bits(expr):0] extd; \ + typeof = 1'sb1; \ + ones = 1'sb1; \ + extd = typeof; \ + if (signedness_val != (extd == ones)) \ + $display(`"FAIL: expected (expr) to be treated as signedness_str extd=%b`", extd); \ + end + +`define ASSERT_SIGNED(expr) `ASSERT_SIGNEDNESS(expr, signed, 1) +`define ASSERT_UNSIGNED(expr) `ASSERT_SIGNEDNESS(expr, unsigned, 0) + +`define MAKE_PRIM(typ) \ + typ typ``_unspecified = 1; \ + typ unsigned typ``_unsigned = 1; \ + typ signed typ``_signed = 1; \ + `ASSERT_SIGNED(typ``_signed) \ + `ASSERT_UNSIGNED(typ``_unsigned) + +`define MAKE_PRIM_SIGNED(typ) \ + `MAKE_PRIM(typ) \ + `ASSERT_SIGNED(typ``_unspecified) +`define MAKE_PRIM_UNSIGNED(typ) \ + `MAKE_PRIM(typ) \ + `ASSERT_UNSIGNED(typ``_unspecified) + +module top; + logic signed x; + logic signed [1:0] y; + assign x = 0; + assign y = 2; + type(x % y) z; + assign z = x % y; + logic [3:0] w; + assign w = z; + initial #1 $display("%b %b %b %b", x, y, z, w); + + `MAKE_PRIM_SIGNED(byte) + `MAKE_PRIM_SIGNED(shortint) + `MAKE_PRIM_SIGNED(int) + `MAKE_PRIM_SIGNED(integer) + `MAKE_PRIM_SIGNED(longint) + + `MAKE_PRIM_UNSIGNED(bit) + `MAKE_PRIM_UNSIGNED(reg) + `MAKE_PRIM_UNSIGNED(logic) + + reg signed [5:0] arr; + + `ASSERT_SIGNED(0) + `ASSERT_SIGNED('sb0) + `ASSERT_UNSIGNED('b0) + `ASSERT_UNSIGNED('o0) + `ASSERT_UNSIGNED('d0) + `ASSERT_UNSIGNED('h0) + `ASSERT_SIGNED('sb0) + `ASSERT_SIGNED('so0) + `ASSERT_SIGNED('sd0) + `ASSERT_SIGNED('sh0) + + `ASSERT_UNSIGNED({1'b0}) + `ASSERT_UNSIGNED({1'o0}) + `ASSERT_UNSIGNED({1'd0}) + `ASSERT_UNSIGNED({1'h0}) + `ASSERT_UNSIGNED({1'sb0}) + `ASSERT_UNSIGNED({1'so0}) + `ASSERT_UNSIGNED({1'sd0}) + `ASSERT_UNSIGNED({1'sh0}) + `ASSERT_UNSIGNED({reg_unspecified}) + `ASSERT_UNSIGNED({reg_unsigned}) + `ASSERT_UNSIGNED({reg_signed}) + + `ASSERT_UNSIGNED({1 {1'b0}}) + `ASSERT_UNSIGNED({1 {1'o0}}) + `ASSERT_UNSIGNED({1 {1'd0}}) + `ASSERT_UNSIGNED({1 {1'h0}}) + `ASSERT_UNSIGNED({1 {1'sb0}}) + `ASSERT_UNSIGNED({1 {1'so0}}) + `ASSERT_UNSIGNED({1 {1'sd0}}) + `ASSERT_UNSIGNED({1 {1'sh0}}) + `ASSERT_UNSIGNED({1 {reg_unspecified}}) + `ASSERT_UNSIGNED({1 {reg_unsigned}}) + `ASSERT_UNSIGNED({1 {reg_signed}}) + + `ASSERT_SIGNED($signed(reg_unspecified)) + `ASSERT_SIGNED($signed(reg_unsigned)) + `ASSERT_SIGNED($signed(reg_signed)) + `ASSERT_UNSIGNED($unsigned(reg_unspecified)) + `ASSERT_UNSIGNED($unsigned(reg_unsigned)) + `ASSERT_UNSIGNED($unsigned(reg_signed)) + +`define UNIOP_ALWAYS_UNSIGNED(op) \ + `ASSERT_UNSIGNED(op 2'sb11) \ + `ASSERT_UNSIGNED(op 2'b11) \ + `ASSERT_UNSIGNED(op reg_signed) \ + `ASSERT_UNSIGNED(op reg_unsigned) + +`define UNIOP_SAME_SIGN(op) \ + `ASSERT_SIGNED(op 2'sb11) \ + `ASSERT_UNSIGNED(op 2'b11) \ + `ASSERT_SIGNED(op reg_signed) \ + `ASSERT_UNSIGNED(op reg_unsigned) + + `UNIOP_ALWAYS_UNSIGNED(!) + `UNIOP_SAME_SIGN(~) + `UNIOP_SAME_SIGN(+) + `UNIOP_SAME_SIGN(-) + `UNIOP_ALWAYS_UNSIGNED(&) + `UNIOP_ALWAYS_UNSIGNED(~&) + `UNIOP_ALWAYS_UNSIGNED(|) + `UNIOP_ALWAYS_UNSIGNED(~|) + `UNIOP_ALWAYS_UNSIGNED(^) + `UNIOP_ALWAYS_UNSIGNED(~^) + +`define BINOP_BOTH_SIGNED(op) \ + `ASSERT_SIGNED(reg_signed op reg_signed) \ + `ASSERT_UNSIGNED(reg_unsigned op reg_signed) \ + `ASSERT_UNSIGNED(reg_signed op reg_unsigned) \ + `ASSERT_UNSIGNED(reg_unsigned op reg_unsigned) \ + `ASSERT_UNSIGNED(reg_unsigned op arr) \ + `ASSERT_UNSIGNED(arr op reg_unsigned) \ + `ASSERT_SIGNED(arr op arr) \ + `ASSERT_SIGNED(arr op reg_signed) \ + `ASSERT_SIGNED(reg_signed op arr) \ + `ASSERT_SIGNED(1'sb1 op 2'sb11) \ + `ASSERT_UNSIGNED(1'b1 op 2'sb11) \ + `ASSERT_UNSIGNED(1'sb1 op 2'b11) \ + `ASSERT_UNSIGNED(1'b1 op 2'b11) + +`define BINOP_FIRST_SIGNED(op) \ + `ASSERT_SIGNED(reg_signed op reg_signed) \ + `ASSERT_UNSIGNED(reg_unsigned op reg_signed) \ + `ASSERT_SIGNED(reg_signed op reg_unsigned) \ + `ASSERT_UNSIGNED(reg_unsigned op reg_unsigned) \ + `ASSERT_SIGNED(1'sb1 op 2'sb11) \ + `ASSERT_UNSIGNED(1'b1 op 2'sb11) \ + `ASSERT_SIGNED(1'sb1 op 2'b11) \ + `ASSERT_UNSIGNED(1'b1 op 2'b11) + +`define BINOP_NEVER_SIGNED(op) \ + `ASSERT_UNSIGNED(reg_signed op reg_signed) \ + `ASSERT_UNSIGNED(reg_unsigned op reg_signed) \ + `ASSERT_UNSIGNED(reg_signed op reg_unsigned) \ + `ASSERT_UNSIGNED(reg_unsigned op reg_unsigned) \ + `ASSERT_UNSIGNED(1'sb1 op 2'sb11) \ + `ASSERT_UNSIGNED(1'b1 op 2'sb11) \ + `ASSERT_UNSIGNED(1'sb1 op 2'b11) \ + `ASSERT_UNSIGNED(1'b1 op 2'b11) + + `BINOP_NEVER_SIGNED(&& ) + `BINOP_NEVER_SIGNED(|| ) + `BINOP_NEVER_SIGNED(-> ) + `BINOP_NEVER_SIGNED(<->) + `BINOP_BOTH_SIGNED( & ) + `BINOP_BOTH_SIGNED( ^ ) + `BINOP_BOTH_SIGNED( ~^ ) + `BINOP_BOTH_SIGNED( | ) + `BINOP_BOTH_SIGNED( * ) + `BINOP_BOTH_SIGNED( / ) + `BINOP_BOTH_SIGNED( + ) + `BINOP_BOTH_SIGNED( - ) + `BINOP_FIRST_SIGNED(** ) + `BINOP_FIRST_SIGNED(<< ) + `BINOP_FIRST_SIGNED(>> ) + `BINOP_FIRST_SIGNED(<<<) + `BINOP_FIRST_SIGNED(>>>) + `BINOP_NEVER_SIGNED(== ) + `BINOP_NEVER_SIGNED(!= ) + `BINOP_NEVER_SIGNED(===) + `BINOP_NEVER_SIGNED(!==) + `BINOP_NEVER_SIGNED(==?) + `BINOP_NEVER_SIGNED(!=?) + `BINOP_NEVER_SIGNED(< ) + `BINOP_NEVER_SIGNED(<= ) + `BINOP_NEVER_SIGNED(> ) + `BINOP_NEVER_SIGNED(>= ) + + `ASSERT_UNSIGNED(4'('0)) + `ASSERT_UNSIGNED(3'('x)) + `ASSERT_SIGNED(2'(1'sb1)) + `ASSERT_SIGNED(10'(2'sb11)) + `ASSERT_UNSIGNED(10'(2'b11)) + `ASSERT_UNSIGNED(2'(1'b1)) + `ASSERT_SIGNED(2'(reg_signed)) + `ASSERT_UNSIGNED(2'(reg_unsigned)) + + `ASSERT_SIGNED(arr) + `ASSERT_UNSIGNED(arr[0]) + `ASSERT_UNSIGNED(arr[5:0]) + `ASSERT_UNSIGNED(arr[1+:2]) + `ASSERT_UNSIGNED(arr[1-:2]) +endmodule diff --git a/test/basic/typeof_signed.v b/test/basic/typeof_signed.v new file mode 100644 index 0000000..3078e7e --- /dev/null +++ b/test/basic/typeof_signed.v @@ -0,0 +1,30 @@ +`define MAKE_PRIM(typ, base, size) \ + base [size-1:0] typ``_unspecified = 1; \ + base unsigned [size-1:0] typ``_unsigned = 1; \ + base signed [size-1:0] typ``_signed = 1; + +module top; + wire signed x; + wire signed [1:0] y; + assign x = 0; + assign y = 2; + wire signed [1:0] z; + assign z = x % y; + wire [3:0] w; + assign w = z; + initial #1 $display("%b %b %b %b", x, y, z, w); + + `MAKE_PRIM(byte, reg, 8) + `MAKE_PRIM(shortint, reg, 16) + `MAKE_PRIM(int, reg, 32) + integer integer_unspecified = 1; + integer unsigned integer_unsigned = 1; + integer signed integer_signed = 1; + `MAKE_PRIM(longint, reg, 64) + + `MAKE_PRIM(bit, wire, 1) + `MAKE_PRIM(reg, reg, 1) + `MAKE_PRIM(logic, wire, 1) + + reg signed [5:0] arr; +endmodule diff --git a/test/lib/functions.sh b/test/lib/functions.sh index 390449e..6e56858 100644 --- a/test/lib/functions.sh +++ b/test/lib/functions.sh @@ -63,7 +63,7 @@ assertConverts() { assertFalse "conversion of $ac_file still contains dimension queries" $? echo "$filtered" | egrep "\s(int\|bit\|logic\|byte\|struct\|enum\|longint\|shortint)\s" assertFalse "conversion of $ac_file still contains SV types" $? - echo "$filtered" | grep "[^\$a-zA-Z_]unsigned" > /dev/null + echo "$filtered" | grep "[^\$a-zA-Z_]unsigned" | grep -v "integer unsigned" > /dev/null assertFalse "conversion of $ac_file still contains unsigned keyword" $? }