Commit 69e66a21 by Zachary Snow

fix inefficiencies in logic conversion

- don't evaluate AST after procedural assignment collection
- don't use State monad during rewrite
- use Writer rather than State for procedural assignment collection
- use Scoper access generation shortcut utility
- cleanup as-patterns and legacy logic
parent 5b2165d7
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
module Convert.Logic (convert) where module Convert.Logic (convert) where
import Control.Monad.State.Strict
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 +36,7 @@ import Language.SystemVerilog.AST ...@@ -37,7 +36,7 @@ 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 (State Locations) type ST = ScoperT Type (Writer Locations)
convert :: [AST] -> [AST] convert :: [AST] -> [AST]
convert = convert =
...@@ -46,7 +45,7 @@ convert = ...@@ -46,7 +45,7 @@ convert =
(traverseDescriptions . convertDescription) (traverseDescriptions . convertDescription)
where where
collectPortsM :: Description -> Writer Ports () collectPortsM :: Description -> Writer Ports ()
collectPortsM (orig @ (Part _ _ _ _ name portNames _)) = collectPortsM orig@(Part _ _ _ _ name portNames _) =
tell $ Map.singleton name ports tell $ Map.singleton name ports
where where
ports = zip portNames (map lookupDir portNames) ports = zip portNames (map lookupDir portNames)
...@@ -58,34 +57,24 @@ convert = ...@@ -58,34 +57,24 @@ convert =
Nothing -> Inout Nothing -> Inout
collectPortsM _ = return () collectPortsM _ = return ()
collectDeclDirsM :: ModuleItem -> Writer [(Identifier, Direction)] () collectDeclDirsM :: ModuleItem -> Writer [(Identifier, Direction)] ()
collectDeclDirsM (MIPackageItem (Decl (Variable dir t ident _ _))) = collectDeclDirsM (MIPackageItem (Decl (Variable dir _ ident _ _))) =
case (dir, t) of when (dir /= Local) $ tell [(ident, dir)]
(_, InterfaceT{}) -> tell [(ident, Local)] collectDeclDirsM (MIPackageItem (Decl (Net dir _ _ _ ident _ _))) =
(Local, _) -> return () when (dir /= Local) $ tell [(ident, dir)]
_ -> tell [(ident, dir)]
collectDeclDirsM (MIPackageItem (Decl net @ Net{})) =
collectNetAsVarM (collectDeclDirsM . MIPackageItem . Decl) net
collectDeclDirsM _ = return () collectDeclDirsM _ = return ()
convertDescription :: Ports -> Description -> Description convertDescription :: Ports -> Description -> Description
convertDescription ports (description @ (Part _ _ Module _ _ _ _)) = convertDescription ports description@(Part _ _ Module _ _ _ _) =
evalState (operation description) Set.empty -- rewrite reg continuous assignments and output port connections
partScoper (rewriteDeclM locations) (traverseModuleItemM ports)
return return description
where where
operation = -- write down which vars are procedurally assigned
-- log then rewrite locations = execWriter $ partScoperT
partScoperT td tm tg ts >=> traverseDeclM return return traverseStmtM description
partScoperT rd tm tg ts
td = traverseDeclM
rd = rewriteDeclM
tm = traverseModuleItemM ports
tg = traverseGenItemM
ts = traverseStmtM
convertDescription _ other = other convertDescription _ other = other
traverseGenItemM :: GenItem -> ST GenItem traverseModuleItemM :: Ports -> ModuleItem -> Scoper Type ModuleItem
traverseGenItemM = return
traverseModuleItemM :: Ports -> ModuleItem -> ST ModuleItem
traverseModuleItemM ports = embedScopes $ traverseModuleItem ports traverseModuleItemM ports = embedScopes $ traverseModuleItem ports
traverseModuleItem :: Ports -> Scopes Type -> ModuleItem -> ModuleItem traverseModuleItem :: Ports -> Scopes Type -> ModuleItem -> ModuleItem
...@@ -162,65 +151,58 @@ traverseModuleItem ports scopes = ...@@ -162,65 +151,58 @@ traverseModuleItem ports scopes =
fixModuleItem other = other fixModuleItem other = other
traverseDeclM :: Decl -> ST Decl traverseDeclM :: Decl -> ST Decl
traverseDeclM (decl @ (Variable _ t x _ _)) = traverseDeclM decl@(Variable _ t x _ _) =
insertElem x t >> return decl insertElem x t >> return decl
traverseDeclM (decl @ (Net _ _ _ t x _ _)) = traverseDeclM decl@(Net _ _ _ t x _ _) =
insertElem x t >> return decl insertElem x t >> return decl
traverseDeclM decl = return decl traverseDeclM decl = return decl
rewriteDeclM :: Decl -> ST Decl rewriteDeclM :: Locations -> Decl -> Scoper Type Decl
rewriteDeclM (Variable d (t @ (IntegerVector TLogic sg rs)) x a e) = do rewriteDeclM locations (Variable d (IntegerVector TLogic sg rs) x a e) = do
insertElem x t accesses <- localAccessesM x
details <- lookupElemM x
let Just (accesses, _, _) = details
let location = map accessName accesses let location = map accessName accesses
usedAsReg <- lift $ gets $ Set.member location let usedAsReg = Set.member location locations
blockLogic <- withinProcedureM blockLogic <- withinProcedureM
if usedAsReg || blockLogic || e /= Nil if blockLogic || usedAsReg || e /= Nil
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 x t' insertElem accesses 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 x t' insertElem accesses t'
return $ Net d TWire DefaultStrength t' x a e return $ Net d TWire DefaultStrength t' x a e
rewriteDeclM (decl @ (Variable _ t x _ _)) = rewriteDeclM _ decl@(Variable _ t x _ _) =
insertElem x t >> return decl insertElem x 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 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 _ _ _ t x _ _) =
insertElem x t >> return decl insertElem x 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
rewriteDeclM (Param s (IntegerVector _ sg rs) x e) = rewriteDeclM _ (Param s (IntegerVector _ sg rs) x e) =
return $ Param s (Implicit sg rs) x e return $ Param s (Implicit sg rs) x e
rewriteDeclM decl = return decl rewriteDeclM _ decl = return decl
traverseStmtM :: Stmt -> ST Stmt traverseStmtM :: Stmt -> ST Stmt
traverseStmtM (Timing timing stmt) = traverseStmtM stmt@Timing{} =
-- ignore the timing LHSs -- ignore the timing LHSs
return $ Timing timing stmt
traverseStmtM (Subroutine (Ident f) args) = do
case args of
Args (_ : Ident x : _) [] ->
if f == "$readmemh" || f == "$readmemb"
then collectLHSM $ LHSIdent x
else return ()
_ -> return ()
return $ Subroutine (Ident f) args
traverseStmtM stmt = do
collectStmtLHSsM (collectNestedLHSsM collectLHSM) stmt
return stmt return stmt
traverseStmtM stmt@(Subroutine (Ident f) (Args (_ : Ident x : _) [])) =
when (f == "$readmemh" || f == "$readmemb") (collectLHSM $ LHSIdent x)
>> return stmt
traverseStmtM stmt =
collectStmtLHSsM (collectNestedLHSsM collectLHSM) stmt
>> return stmt
collectLHSM :: LHS -> ST () collectLHSM :: LHS -> ST ()
collectLHSM lhs = do collectLHSM lhs = do
details <- lookupElemM lhs details <- lookupElemM lhs
case details of case details of
Just (accesses, _, _) -> do Just (accesses, _, _) ->
let location = map accessName accesses lift $ tell $ Set.singleton location
lift $ modify $ Set.insert location where location = map accessName accesses
Nothing -> return () Nothing -> return ()
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