mirror of https://github.com/zachjs/sv2v.git
logic conversion handles tf output ports
This commit is contained in:
parent
1c902773b4
commit
73a9cc6750
|
|
@ -8,6 +8,8 @@
|
|||
### Bug Fixes
|
||||
|
||||
* Fixed `--write path/to/dir/` with directives like `` `default_nettype ``
|
||||
* Fixed `logic` incorrectly converted to `wire` even when provided to a task or
|
||||
function output port
|
||||
* Fixed `` `resetall `` not resetting the `` `default_nettype ``
|
||||
|
||||
### Other Enhancements
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
module Convert.Logic (convert) where
|
||||
|
||||
import Control.Monad (when)
|
||||
import Control.Monad (when, zipWithM)
|
||||
import Control.Monad.Writer.Strict
|
||||
import qualified Data.Map.Strict as Map
|
||||
import qualified Data.Set as Set
|
||||
|
|
@ -37,7 +37,8 @@ import Language.SystemVerilog.AST
|
|||
type Ports = Map.Map Identifier [(Identifier, Direction)]
|
||||
type Location = [Identifier]
|
||||
type Locations = Set.Set Location
|
||||
type ST = ScoperT Type (Writer Locations)
|
||||
type DT = (Direction, Type)
|
||||
type ST = ScoperT DT (Writer Locations)
|
||||
|
||||
convert :: [AST] -> [AST]
|
||||
convert =
|
||||
|
|
@ -70,16 +71,17 @@ convertDescription ports description =
|
|||
where
|
||||
locations = execWriter $ evalScoperT $ scopePart locScoper description
|
||||
-- write down which vars are procedurally assigned
|
||||
locScoper = scopeModuleItem traverseDeclM return return traverseStmtM
|
||||
locScoper = scopeModuleItem
|
||||
traverseDeclM traverseModuleItemM return traverseStmtM
|
||||
-- rewrite reg continuous assignments and output port connections
|
||||
conScoper = scopeModuleItem
|
||||
(rewriteDeclM locations) (traverseModuleItemM ports) return return
|
||||
(rewriteDeclM locations) (rewriteModuleItemM ports) return return
|
||||
|
||||
traverseModuleItemM :: Ports -> ModuleItem -> Scoper Type ModuleItem
|
||||
traverseModuleItemM ports = embedScopes $ traverseModuleItem ports
|
||||
rewriteModuleItemM :: Ports -> ModuleItem -> Scoper DT ModuleItem
|
||||
rewriteModuleItemM ports = embedScopes $ rewriteModuleItem ports
|
||||
|
||||
traverseModuleItem :: Ports -> Scopes Type -> ModuleItem -> ModuleItem
|
||||
traverseModuleItem ports scopes =
|
||||
rewriteModuleItem :: Ports -> Scopes DT -> ModuleItem -> ModuleItem
|
||||
rewriteModuleItem ports scopes =
|
||||
fixModuleItem
|
||||
where
|
||||
isReg :: LHS -> Bool
|
||||
|
|
@ -92,7 +94,7 @@ traverseModuleItem ports scopes =
|
|||
isReg' :: LHS -> Writer [Bool] ()
|
||||
isReg' lhs =
|
||||
case lookupElem scopes lhs of
|
||||
Just (_, _, t) -> tell [isRegType t]
|
||||
Just (_, _, (_, t)) -> tell [isRegType t]
|
||||
_ -> tell [False]
|
||||
|
||||
always_comb = AlwaysC Always . Timing (Event EventStar)
|
||||
|
|
@ -146,14 +148,18 @@ traverseModuleItem ports scopes =
|
|||
maybeModulePorts = Map.lookup moduleName ports
|
||||
fixModuleItem other = other
|
||||
|
||||
traverseDeclM :: Decl -> ST Decl
|
||||
traverseDeclM decl@(Variable _ t x _ _) =
|
||||
insertElem x t >> return decl
|
||||
traverseDeclM decl@(Net _ _ _ t x _ _) =
|
||||
insertElem x t >> return decl
|
||||
traverseDeclM decl = return decl
|
||||
traverseModuleItemM :: ModuleItem -> ST ModuleItem
|
||||
traverseModuleItemM = traverseNodesM traverseExprM return return return return
|
||||
|
||||
rewriteDeclM :: Locations -> Decl -> Scoper Type Decl
|
||||
traverseDeclM :: Decl -> ST Decl
|
||||
traverseDeclM decl = do
|
||||
case decl of
|
||||
Variable d t x _ _ -> insertElem x (d, t)
|
||||
Net d _ _ t x _ _ -> insertElem x (d, t)
|
||||
_ -> return ()
|
||||
traverseDeclNodesM return traverseExprM decl
|
||||
|
||||
rewriteDeclM :: Locations -> Decl -> Scoper DT Decl
|
||||
rewriteDeclM locations (Variable d (IntegerVector TLogic sg rs) x a e) = do
|
||||
accesses <- localAccessesM x
|
||||
let location = map accessName accesses
|
||||
|
|
@ -163,11 +169,11 @@ rewriteDeclM locations (Variable d (IntegerVector TLogic sg rs) x a e) = do
|
|||
then do
|
||||
let d' = if d == Inout then Output else d
|
||||
let t' = IntegerVector TReg sg rs
|
||||
insertElem accesses t'
|
||||
insertElem accesses (d', t')
|
||||
return $ Variable d' t' x a e
|
||||
else do
|
||||
let t' = Implicit sg rs
|
||||
insertElem accesses t'
|
||||
insertElem accesses (d, t')
|
||||
return $ Net d TWire DefaultStrength t' x a e
|
||||
rewriteDeclM locations decl@(Variable d t x a e) = do
|
||||
inProcedure <- withinProcedureM
|
||||
|
|
@ -178,12 +184,12 @@ rewriteDeclM locations decl@(Variable d t x a e) = do
|
|||
(Input, IntegerVector TReg sg rs, False) ->
|
||||
rewriteDeclM locations $ Variable Input t' x a e
|
||||
where t' = IntegerVector TLogic sg rs
|
||||
_ -> insertElem x t >> return decl
|
||||
_ -> insertElem x (d, t) >> return decl
|
||||
rewriteDeclM _ (Net d n s (IntegerVector _ sg rs) x a e) =
|
||||
insertElem x t >> return (Net d n s t x a e)
|
||||
insertElem x (d, t) >> return (Net d n s t x a e)
|
||||
where t = Implicit sg rs
|
||||
rewriteDeclM _ decl@(Net _ _ _ t x _ _) =
|
||||
insertElem x t >> return decl
|
||||
rewriteDeclM _ decl@(Net d _ _ t x _ _) =
|
||||
insertElem x (d, t) >> return decl
|
||||
rewriteDeclM _ (Param s (IntegerVector _ sg []) x e) =
|
||||
return $ Param s (Implicit sg [(zero, zero)]) x e
|
||||
where zero = RawNum 0
|
||||
|
|
@ -195,12 +201,37 @@ traverseStmtM :: Stmt -> ST Stmt
|
|||
traverseStmtM (Asgn op Just{} lhs expr) =
|
||||
-- ignore the timing LHSs
|
||||
traverseStmtM $ Asgn op Nothing lhs expr
|
||||
traverseStmtM stmt@(Subroutine (Ident f) (Args (_ : Ident x : _) [])) =
|
||||
when (f == "$readmemh" || f == "$readmemb") (collectLHSM $ LHSIdent x)
|
||||
>> return stmt
|
||||
traverseStmtM stmt@(Subroutine (Ident f) (Args (_ : Ident x : _) []))
|
||||
| f == "$readmemh" || f == "$readmemb" =
|
||||
collectLHSM (LHSIdent x) >> return stmt
|
||||
traverseStmtM (Subroutine fn (Args args [])) = do
|
||||
fn' <- traverseExprM fn
|
||||
args' <- traverseCall fn' args
|
||||
return $ Subroutine fn' $ Args args' []
|
||||
traverseStmtM stmt =
|
||||
collectStmtLHSsM (collectNestedLHSsM collectLHSM) stmt
|
||||
>> return stmt
|
||||
>> traverseStmtExprsM traverseExprM stmt
|
||||
|
||||
traverseExprM :: Expr -> ST Expr
|
||||
traverseExprM (Call fn (Args args [])) = do
|
||||
fn' <- traverseExprM fn
|
||||
args' <- traverseCall fn' args
|
||||
return $ Call fn' $ Args args' []
|
||||
traverseExprM other =
|
||||
traverseSinglyNestedExprsM traverseExprM other
|
||||
|
||||
traverseCall :: Expr -> [Expr] -> ST [Expr]
|
||||
traverseCall fn = zipWithM (traverseCallArg fn) [0..]
|
||||
|
||||
-- task and function ports might be outputs, thus requiring a given logic to be
|
||||
-- a reg rather than a wire
|
||||
traverseCallArg :: Expr -> Int -> Expr -> ST Expr
|
||||
traverseCallArg fn idx arg = do
|
||||
details <- lookupElemM $ Dot fn (show idx)
|
||||
case (details, exprToLHS arg) of
|
||||
(Just (_, _, (Output, _)), Just lhs) -> collectLHSM lhs
|
||||
_ -> return ()
|
||||
return arg -- no rewriting
|
||||
|
||||
collectLHSM :: LHS -> ST ()
|
||||
collectLHSM lhs = do
|
||||
|
|
|
|||
|
|
@ -40,4 +40,13 @@ module top;
|
|||
t2(1);
|
||||
$display("%b", t2l);
|
||||
end
|
||||
|
||||
logic l1, l2;
|
||||
task io_task;
|
||||
input inp;
|
||||
output out;
|
||||
out = ~inp;
|
||||
endtask
|
||||
assign l1 = 1;
|
||||
always_comb io_task(l1, l2);
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -44,4 +44,10 @@ module top;
|
|||
t2(1);
|
||||
$display("%b", t2l);
|
||||
end
|
||||
|
||||
wire l1;
|
||||
reg l2;
|
||||
assign l1 = 1;
|
||||
always @*
|
||||
l2 = ~l1;
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module top;
|
|||
f = x * 3;
|
||||
y = x * 5;
|
||||
endfunction
|
||||
integer x, y;
|
||||
logic signed [31:0] x, y;
|
||||
initial x = f(-1, y);
|
||||
initial $display(x, y);
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
affirm reg signed [31:0] x;
|
||||
affirm reg signed [31:0] y;
|
||||
Loading…
Reference in New Issue