diff --git a/src/Convert/Simplify.hs b/src/Convert/Simplify.hs index 569761f..f217e69 100644 --- a/src/Convert/Simplify.hs +++ b/src/Convert/Simplify.hs @@ -49,9 +49,12 @@ traverseExprM = traverseNestedExprsM $ stately convertExpr convertExpr :: Info -> Expr -> Expr convertExpr info (Cast (Right c) e) = - if sized == e - then Cast (Right c') e - else sized + case c' of + Number _ -> + if sized == e + then Cast (Right c') e + else sized + _ -> Cast (Right c') e where c' = simplify $ traverseNestedExprs (substitute info) (simplify c) sized = sizedExpr "" c' e diff --git a/src/Convert/SizeCast.hs b/src/Convert/SizeCast.hs index ae7cda3..7d6ab26 100644 --- a/src/Convert/SizeCast.hs +++ b/src/Convert/SizeCast.hs @@ -15,7 +15,7 @@ import Convert.Traverse import Language.SystemVerilog.AST type TypeMap = Map.Map Identifier Type -type CastSet = Set.Set (Int, Signing) +type CastSet = Set.Set (Expr, Signing) type ST = StateT TypeMap (Writer CastSet) @@ -58,38 +58,42 @@ traverseExprM = traverseNestedExprsM convertExprM where convertExprM :: Expr -> ST Expr - convertExprM (Cast (Right (Number n)) e) = do + convertExprM (Cast (Right s) e) = do typeMap <- get - case (readNumber n, exprSigning typeMap e) of - (Just size, Just sg) -> do - lift $ tell $ Set.singleton (size, sg) - let f = castFnName size sg + case exprSigning typeMap e of + Just sg -> do + lift $ tell $ Set.singleton (s, sg) + let f = castFnName s sg let args = Args [Just e] [] return $ Call Nothing f args - _ -> return $ Cast (Right $ Number n) e + _ -> return $ Cast (Right s) e convertExprM other = return other -castFn :: Int -> Signing -> Description -castFn n sg = +castFn :: Expr -> Signing -> Description +castFn e sg = PackageItem $ Function (Just Automatic) t fnName [decl] [Return $ Ident inp] where inp = "inp" - r = (Number $ show (n - 1), Number "0") + r = (BinOp Sub e (Number "1"), Number "0") t = IntegerVector TLogic sg [r] - fnName = castFnName n sg + fnName = castFnName e sg decl = Variable Input t inp [] Nothing -castFnName :: Int -> Signing -> String -castFnName n sg = - if n <= 0 - then error $ "cannot have non-positive size cast: " ++ show n - else - if sg == Unspecified - then init name - else name - where name = "sv2v_cast_" ++ show n ++ "_" ++ show sg +castFnName :: Expr -> Signing -> String +castFnName e sg = + if sg == Unspecified + then init name + else name + where + sizeStr = case e of + Number n -> + case readNumber n of + Just v -> show v + _ -> shortHash e + _ -> shortHash e + name = "sv2v_cast_" ++ sizeStr ++ "_" ++ show sg exprSigning :: TypeMap -> Expr -> Maybe Signing exprSigning typeMap (Ident x) = diff --git a/test/basic/cast.sv b/test/basic/cast.sv index 97b5c3f..99fe1e4 100644 --- a/test/basic/cast.sv +++ b/test/basic/cast.sv @@ -1,4 +1,5 @@ module top; + parameter WIDTH = 32; initial begin logic [31:0] w = 1234; int x = -235; @@ -16,6 +17,10 @@ module top; $display("%b %b", x, 40'(x)); $display("%b %b", y, 40'(y)); $display("%b %b", z, 40'(z)); + $display("%0d %0d", w, ($clog2(WIDTH))'(w)); + $display("%0d %0d", x, ($clog2(WIDTH))'(x)); + $display("%0d %0d", y, ($clog2(WIDTH))'(y)); + $display("%0d %0d", z, ($clog2(WIDTH))'(z)); end localparam bit foo = '0; localparam logic [31:0] bar = 32'(foo); diff --git a/test/basic/cast.v b/test/basic/cast.v index 6834033..99fd8aa 100644 --- a/test/basic/cast.v +++ b/test/basic/cast.v @@ -20,6 +20,10 @@ module top; $display("%b %b", x, {8'hFF, x}); $display("%b %b", y, {8'b0, y}); $display("%b %b", z, {35'b0, z}); + $display("%0d %0d", w, w[4:0]); + $display("%0d %0d", x, $signed(x[4:0])); + $display("%0d %0d", y, $signed(y[4:0])); + $display("%0d %0d", z, z[4:0]); end localparam [0:0] foo = 0; localparam [31:0] bar = 32'b0;