mirror of https://github.com/zachjs/sv2v.git
preliminary conversion for size casts
This commit is contained in:
parent
df3620d3a0
commit
ba4cf805ff
|
|
@ -32,6 +32,7 @@ import qualified Convert.ParamType
|
|||
import qualified Convert.RemoveComments
|
||||
import qualified Convert.Return
|
||||
import qualified Convert.Simplify
|
||||
import qualified Convert.SizeCast
|
||||
import qualified Convert.StarPort
|
||||
import qualified Convert.StmtBlock
|
||||
import qualified Convert.Stream
|
||||
|
|
@ -58,6 +59,7 @@ phases excludes =
|
|||
, Convert.PackedArray.convert
|
||||
, Convert.DimensionQuery.convert
|
||||
, Convert.ParamType.convert
|
||||
, Convert.SizeCast.convert
|
||||
, Convert.Simplify.convert
|
||||
, Convert.StarPort.convert
|
||||
, Convert.StmtBlock.convert
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
{- sv2v
|
||||
- Author: Zachary Snow <zach@zachjs.com>
|
||||
-
|
||||
- Conversion of size casts on non-constant expressions.
|
||||
-}
|
||||
|
||||
module Convert.SizeCast (convert) where
|
||||
|
||||
import Control.Monad.State
|
||||
import Control.Monad.Writer
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
||||
import Convert.Traverse
|
||||
import Language.SystemVerilog.AST
|
||||
|
||||
type TypeMap = Map.Map Identifier Type
|
||||
type CastSet = Set.Set (Int, Signing)
|
||||
|
||||
type ST = StateT TypeMap (Writer CastSet)
|
||||
|
||||
convert :: [AST] -> [AST]
|
||||
convert = map convertFile
|
||||
|
||||
convertFile :: AST -> AST
|
||||
convertFile descriptions =
|
||||
descriptions' ++ map (uncurry castFn) funcs
|
||||
where
|
||||
results = map convertDescription descriptions
|
||||
descriptions' = map fst results
|
||||
funcs = Set.toList $ Set.unions $ map snd results
|
||||
|
||||
convertDescription :: Description -> (Description, CastSet)
|
||||
convertDescription description =
|
||||
(description', info)
|
||||
where
|
||||
(description', info) =
|
||||
runWriter $
|
||||
scopedConversionM traverseDeclM traverseModuleItemM traverseStmtM
|
||||
Map.empty description
|
||||
|
||||
traverseDeclM :: Decl -> ST Decl
|
||||
traverseDeclM decl = do
|
||||
case decl of
|
||||
Variable _ t x _ _ -> modify $ Map.insert x t
|
||||
Param _ t x _ -> modify $ Map.insert x t
|
||||
ParamType _ _ _ -> return ()
|
||||
return decl
|
||||
|
||||
traverseModuleItemM :: ModuleItem -> ST ModuleItem
|
||||
traverseModuleItemM item = traverseExprsM traverseExprM item
|
||||
|
||||
traverseStmtM :: Stmt -> ST Stmt
|
||||
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
|
||||
|
||||
traverseExprM :: Expr -> ST Expr
|
||||
traverseExprM =
|
||||
traverseNestedExprsM convertExprM
|
||||
where
|
||||
convertExprM :: Expr -> ST Expr
|
||||
convertExprM (Cast (Right (Number n)) 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
|
||||
let args = Args [Just e] []
|
||||
return $ Call Nothing f args
|
||||
_ -> return $ Cast (Right $ Number n) e
|
||||
convertExprM other = return other
|
||||
|
||||
|
||||
castFn :: Int -> Signing -> Description
|
||||
castFn n sg =
|
||||
PackageItem $
|
||||
Function (Just Automatic) t fnName [decl] [Return $ Ident inp]
|
||||
where
|
||||
inp = "inp"
|
||||
r = (Number $ show (n - 1), Number "0")
|
||||
t = IntegerVector TLogic sg [r]
|
||||
fnName = castFnName n 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
|
||||
|
||||
exprSigning :: TypeMap -> Expr -> Maybe Signing
|
||||
exprSigning typeMap (Ident x) =
|
||||
case Map.lookup x typeMap of
|
||||
Just t -> typeSigning t
|
||||
Nothing -> Just Unspecified
|
||||
exprSigning typeMap (BinOp op e1 e2) =
|
||||
combiner sg1 sg2
|
||||
where
|
||||
sg1 = exprSigning typeMap e1
|
||||
sg2 = exprSigning typeMap e2
|
||||
combiner = case op of
|
||||
BitAnd -> combineSigning
|
||||
BitXor -> combineSigning
|
||||
BitXnor -> combineSigning
|
||||
BitOr -> combineSigning
|
||||
Mul -> combineSigning
|
||||
Div -> combineSigning
|
||||
Add -> combineSigning
|
||||
Sub -> combineSigning
|
||||
Mod -> curry fst
|
||||
Pow -> curry fst
|
||||
ShiftAL -> curry fst
|
||||
ShiftAR -> curry fst
|
||||
_ -> \_ _ -> Just Unspecified
|
||||
exprSigning _ _ = Just Unspecified
|
||||
|
||||
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 Unsigned) _ = Just Unsigned
|
||||
|
||||
typeSigning :: Type -> Maybe Signing
|
||||
typeSigning (Net _ sg _) = Just sg
|
||||
typeSigning (Implicit sg _) = Just sg
|
||||
typeSigning (IntegerVector _ sg _) = Just sg
|
||||
typeSigning _ = Nothing
|
||||
|
|
@ -78,11 +78,13 @@ module Convert.Traverse
|
|||
, collectNestedLHSsM
|
||||
, traverseScopesM
|
||||
, scopedConversion
|
||||
, scopedConversionM
|
||||
, stately
|
||||
, traverseFilesM
|
||||
, traverseFiles
|
||||
) where
|
||||
|
||||
import Data.Functor.Identity (runIdentity)
|
||||
import Control.Monad.State
|
||||
import Control.Monad.Writer
|
||||
import Language.SystemVerilog.AST
|
||||
|
|
@ -1009,10 +1011,11 @@ collectNestedExprsM = collectify traverseNestedExprsM
|
|||
-- statements recursively, as we add a recursive wrapper here.
|
||||
traverseScopesM
|
||||
:: (Eq s, Show s)
|
||||
=> MapperM (State s) Decl
|
||||
-> MapperM (State s) ModuleItem
|
||||
-> MapperM (State s) Stmt
|
||||
-> MapperM (State s) ModuleItem
|
||||
=> Monad m
|
||||
=> MapperM (StateT s m) Decl
|
||||
-> MapperM (StateT s m) ModuleItem
|
||||
-> MapperM (StateT s m) Stmt
|
||||
-> MapperM (StateT s m) ModuleItem
|
||||
traverseScopesM declMapper moduleItemMapper stmtMapper =
|
||||
fullModuleItemMapper
|
||||
where
|
||||
|
|
@ -1072,7 +1075,19 @@ scopedConversion
|
|||
-> Description
|
||||
-> Description
|
||||
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM s description =
|
||||
evalState (initialTraverse description >>= scopedTraverse) s
|
||||
runIdentity $ scopedConversionM traverseDeclM traverseModuleItemM traverseStmtM s description
|
||||
|
||||
scopedConversionM
|
||||
:: (Eq s, Show s)
|
||||
=> Monad m
|
||||
=> MapperM (StateT s m) Decl
|
||||
-> MapperM (StateT s m) ModuleItem
|
||||
-> MapperM (StateT s m) Stmt
|
||||
-> s
|
||||
-> Description
|
||||
-> m Description
|
||||
scopedConversionM traverseDeclM traverseModuleItemM traverseStmtM s description =
|
||||
evalStateT (initialTraverse description >>= scopedTraverse) s
|
||||
where
|
||||
initialTraverse = traverseModuleItemsM traverseMIPackageItemDecl
|
||||
scopedTraverse = traverseModuleItemsM $
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ executable sv2v
|
|||
Convert.RemoveComments
|
||||
Convert.Return
|
||||
Convert.Simplify
|
||||
Convert.SizeCast
|
||||
Convert.StarPort
|
||||
Convert.StmtBlock
|
||||
Convert.Stream
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
module top;
|
||||
initial begin
|
||||
logic [31:0] w = 1234;
|
||||
int x = -235;
|
||||
int y = 1234;
|
||||
logic [4:0] z = y;
|
||||
$display("%0d %0d", w, 5'(w));
|
||||
$display("%0d %0d", x, 5'(x));
|
||||
$display("%0d %0d", y, 5'(y));
|
||||
$display("%0d %0d", z, 5'(z));
|
||||
$display("%0d %0d", w+1, 5'(w+1));
|
||||
$display("%0d %0d", x+1, 5'(x+1));
|
||||
$display("%0d %0d", y+1, 5'(y+1));
|
||||
$display("%0d %0d", z+1, 5'(z+1));
|
||||
$display("%b %b", w, 40'(w));
|
||||
$display("%b %b", x, 40'(x));
|
||||
$display("%b %b", y, 40'(y));
|
||||
$display("%b %b", z, 40'(z));
|
||||
end
|
||||
localparam bit foo = '0;
|
||||
localparam logic [31:0] bar = 32'(foo);
|
||||
initial $display("%b %b", foo, bar);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
module top;
|
||||
initial begin : foo_block
|
||||
reg [31:0] w;
|
||||
reg signed [31:0] x;
|
||||
reg signed [31:0] y;
|
||||
reg [4:0] z;
|
||||
w = 1234;
|
||||
x = -235;
|
||||
y = 1234;
|
||||
z = y;
|
||||
$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]);
|
||||
$display("%0d %0d", w+1, w[4:0]+1);
|
||||
$display("%0d %0d", x+1, $signed(x[4:0])+1);
|
||||
$display("%0d %0d", y+1, $signed(y[4:0])+1);
|
||||
$display("%0d %0d", z+1, z[4:0]+1);
|
||||
$display("%b %b", w, {8'b0, w});
|
||||
$display("%b %b", x, {8'hFF, x});
|
||||
$display("%b %b", y, {8'b0, y});
|
||||
$display("%b %b", z, {35'b0, z});
|
||||
end
|
||||
localparam foo = 0;
|
||||
localparam [31:0] bar = 32'b0;
|
||||
initial $display("%b %b", foo, bar);
|
||||
endmodule
|
||||
Loading…
Reference in New Issue