Commit 73a9cc67 by Zachary Snow

logic conversion handles tf output ports

parent 1c902773
......@@ -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
traverseModuleItemM :: ModuleItem -> ST ModuleItem
traverseModuleItemM = traverseNodesM traverseExprM return return return return
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
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 Type 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
affirm reg signed [31:0] x;
affirm reg signed [31:0] y;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment