Commit 73a9cc67 by Zachary Snow

logic conversion handles tf output ports

parent 1c902773
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
### Bug Fixes ### Bug Fixes
* Fixed `--write path/to/dir/` with directives like `` `default_nettype `` * 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 `` * Fixed `` `resetall `` not resetting the `` `default_nettype ``
### Other Enhancements ### Other Enhancements
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
module Convert.Logic (convert) where module Convert.Logic (convert) where
import Control.Monad (when) import Control.Monad (when, zipWithM)
import Control.Monad.Writer.Strict import Control.Monad.Writer.Strict
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set
...@@ -37,7 +37,8 @@ import Language.SystemVerilog.AST ...@@ -37,7 +37,8 @@ import Language.SystemVerilog.AST
type Ports = Map.Map Identifier [(Identifier, Direction)] type Ports = Map.Map Identifier [(Identifier, Direction)]
type Location = [Identifier] type Location = [Identifier]
type Locations = Set.Set Location 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 :: [AST] -> [AST]
convert = convert =
...@@ -70,16 +71,17 @@ convertDescription ports description = ...@@ -70,16 +71,17 @@ convertDescription ports description =
where where
locations = execWriter $ evalScoperT $ scopePart locScoper description locations = execWriter $ evalScoperT $ scopePart locScoper description
-- write down which vars are procedurally assigned -- 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 -- rewrite reg continuous assignments and output port connections
conScoper = scopeModuleItem conScoper = scopeModuleItem
(rewriteDeclM locations) (traverseModuleItemM ports) return return (rewriteDeclM locations) (rewriteModuleItemM ports) return return
traverseModuleItemM :: Ports -> ModuleItem -> Scoper Type ModuleItem rewriteModuleItemM :: Ports -> ModuleItem -> Scoper DT ModuleItem
traverseModuleItemM ports = embedScopes $ traverseModuleItem ports rewriteModuleItemM ports = embedScopes $ rewriteModuleItem ports
traverseModuleItem :: Ports -> Scopes Type -> ModuleItem -> ModuleItem rewriteModuleItem :: Ports -> Scopes DT -> ModuleItem -> ModuleItem
traverseModuleItem ports scopes = rewriteModuleItem ports scopes =
fixModuleItem fixModuleItem
where where
isReg :: LHS -> Bool isReg :: LHS -> Bool
...@@ -92,7 +94,7 @@ traverseModuleItem ports scopes = ...@@ -92,7 +94,7 @@ traverseModuleItem ports scopes =
isReg' :: LHS -> Writer [Bool] () isReg' :: LHS -> Writer [Bool] ()
isReg' lhs = isReg' lhs =
case lookupElem scopes lhs of case lookupElem scopes lhs of
Just (_, _, t) -> tell [isRegType t] Just (_, _, (_, t)) -> tell [isRegType t]
_ -> tell [False] _ -> tell [False]
always_comb = AlwaysC Always . Timing (Event EventStar) always_comb = AlwaysC Always . Timing (Event EventStar)
...@@ -146,14 +148,18 @@ traverseModuleItem ports scopes = ...@@ -146,14 +148,18 @@ traverseModuleItem ports scopes =
maybeModulePorts = Map.lookup moduleName ports maybeModulePorts = Map.lookup moduleName ports
fixModuleItem other = other fixModuleItem other = other
traverseModuleItemM :: ModuleItem -> ST ModuleItem
traverseModuleItemM = traverseNodesM traverseExprM return return return return
traverseDeclM :: Decl -> ST Decl traverseDeclM :: Decl -> ST Decl
traverseDeclM decl@(Variable _ t x _ _) = traverseDeclM decl = do
insertElem x t >> return decl case decl of
traverseDeclM decl@(Net _ _ _ t x _ _) = Variable d t x _ _ -> insertElem x (d, t)
insertElem x t >> return decl Net d _ _ t x _ _ -> insertElem x (d, t)
traverseDeclM decl = return decl _ -> 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 rewriteDeclM locations (Variable d (IntegerVector TLogic sg rs) x a e) = do
accesses <- localAccessesM x accesses <- localAccessesM x
let location = map accessName accesses let location = map accessName accesses
...@@ -163,11 +169,11 @@ rewriteDeclM locations (Variable d (IntegerVector TLogic sg rs) x a e) = do ...@@ -163,11 +169,11 @@ rewriteDeclM locations (Variable d (IntegerVector TLogic sg rs) x a e) = do
then do then do
let d' = if d == Inout then Output else d let d' = if d == Inout then Output else d
let t' = IntegerVector TReg sg rs let t' = IntegerVector TReg sg rs
insertElem accesses t' insertElem accesses (d', t')
return $ Variable d' t' x a e return $ Variable d' t' x a e
else do else do
let t' = Implicit sg rs let t' = Implicit sg rs
insertElem accesses t' insertElem accesses (d, t')
return $ Net d TWire DefaultStrength t' x a e return $ Net d TWire DefaultStrength t' x a e
rewriteDeclM locations decl@(Variable d t x a e) = do rewriteDeclM locations decl@(Variable d t x a e) = do
inProcedure <- withinProcedureM inProcedure <- withinProcedureM
...@@ -178,12 +184,12 @@ rewriteDeclM locations decl@(Variable d t x a e) = do ...@@ -178,12 +184,12 @@ rewriteDeclM locations decl@(Variable d t x a e) = do
(Input, IntegerVector TReg sg rs, False) -> (Input, IntegerVector TReg sg rs, False) ->
rewriteDeclM locations $ Variable Input t' x a e rewriteDeclM locations $ Variable Input t' x a e
where t' = IntegerVector TLogic sg rs 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) = 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 where t = Implicit sg rs
rewriteDeclM _ decl@(Net _ _ _ t x _ _) = rewriteDeclM _ decl@(Net d _ _ t x _ _) =
insertElem x t >> return decl insertElem x (d, t) >> return decl
rewriteDeclM _ (Param s (IntegerVector _ sg []) x e) = rewriteDeclM _ (Param s (IntegerVector _ sg []) x e) =
return $ Param s (Implicit sg [(zero, zero)]) x e return $ Param s (Implicit sg [(zero, zero)]) x e
where zero = RawNum 0 where zero = RawNum 0
...@@ -195,12 +201,37 @@ traverseStmtM :: Stmt -> ST Stmt ...@@ -195,12 +201,37 @@ traverseStmtM :: Stmt -> ST Stmt
traverseStmtM (Asgn op Just{} lhs expr) = traverseStmtM (Asgn op Just{} lhs expr) =
-- ignore the timing LHSs -- ignore the timing LHSs
traverseStmtM $ Asgn op Nothing lhs expr traverseStmtM $ Asgn op Nothing lhs expr
traverseStmtM stmt@(Subroutine (Ident f) (Args (_ : Ident x : _) [])) = traverseStmtM stmt@(Subroutine (Ident f) (Args (_ : Ident x : _) []))
when (f == "$readmemh" || f == "$readmemb") (collectLHSM $ LHSIdent x) | f == "$readmemh" || f == "$readmemb" =
>> return stmt 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 = traverseStmtM stmt =
collectStmtLHSsM (collectNestedLHSsM collectLHSM) 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 -> ST ()
collectLHSM lhs = do collectLHSM lhs = do
......
...@@ -40,4 +40,13 @@ module top; ...@@ -40,4 +40,13 @@ module top;
t2(1); t2(1);
$display("%b", t2l); $display("%b", t2l);
end end
logic l1, l2;
task io_task;
input inp;
output out;
out = ~inp;
endtask
assign l1 = 1;
always_comb io_task(l1, l2);
endmodule endmodule
...@@ -44,4 +44,10 @@ module top; ...@@ -44,4 +44,10 @@ module top;
t2(1); t2(1);
$display("%b", t2l); $display("%b", t2l);
end end
wire l1;
reg l2;
assign l1 = 1;
always @*
l2 = ~l1;
endmodule endmodule
...@@ -5,7 +5,7 @@ module top; ...@@ -5,7 +5,7 @@ module top;
f = x * 3; f = x * 3;
y = x * 5; y = x * 5;
endfunction endfunction
integer x, y; logic signed [31:0] x, y;
initial x = f(-1, y); initial x = f(-1, y);
initial $display(x, y); initial $display(x, y);
endmodule 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