sv2v/src/Convert/Logic.hs

66 lines
2.3 KiB
Haskell
Raw Normal View History

{- sv2v
- Author: Zachary Snow <zach@zachjs.com>
-
- Conversion for `logic`
-}
-- Regarding `logic` conversion: The SystemVerilog grammar has the concept of a
-- `data_declaration`, which seems to cover things much more generally. While
-- obviously `logic` can appear as module items or ports, they can also be
-- function arguments, for example.
-- It seems like logic only becomes reg if it is assigned to in an always block.
module Convert.Logic (convert) where
2019-02-25 22:19:55 +01:00
import Control.Monad.Writer
import qualified Data.Set as Set
2019-02-25 22:19:55 +01:00
import Convert.Traverse
import Language.SystemVerilog.AST
type RegIdents = Set.Set String
2019-02-18 09:59:17 +01:00
convert :: AST -> AST
2019-02-25 22:19:55 +01:00
convert = traverseDescriptions convertDescription
2019-02-18 09:59:17 +01:00
convertDescription :: Description -> Description
2019-03-27 04:51:31 +01:00
convertDescription orig =
if shouldConvert
then traverseModuleItems conversion orig
else orig
where
2019-03-27 04:51:31 +01:00
shouldConvert = case orig of
Part _ Interface _ _ _ _ -> False
Part _ Module _ _ _ _ -> True
PackageItem _ -> True
Directive _ -> False
conversion = traverseDecls convertDecl . convertModuleItem
2019-02-25 22:19:55 +01:00
idents = execWriter (collectModuleItemsM regIdents orig)
convertModuleItem :: ModuleItem -> ModuleItem
convertModuleItem (MIDecl (Variable dir (IntegerVector TLogic sg mr) ident a me)) =
2019-02-25 22:19:55 +01:00
MIDecl $ Variable dir (t mr) ident a me
where
t = if sg /= Unspecified || Set.member ident idents
then IntegerVector TReg sg
else Net TWire
2019-02-25 22:19:55 +01:00
convertModuleItem other = other
-- all other logics (i.e. inside of functions) become regs
convertDecl :: Decl -> Decl
convertDecl (Variable d (IntegerVector TLogic sg rs) x a me) =
Variable d (IntegerVector TReg sg rs) x a me
convertDecl other = other
2019-02-25 22:19:55 +01:00
regIdents :: ModuleItem -> Writer RegIdents ()
regIdents (AlwaysC _ stmt) =
collectStmtLHSsM (collectNestedLHSsM idents) $
traverseNestedStmts removeTimings stmt
where
2019-02-25 22:19:55 +01:00
idents :: LHS -> Writer RegIdents ()
idents (LHSIdent vx ) = tell $ Set.singleton vx
idents _ = return () -- the collector recurses for us
removeTimings :: Stmt -> Stmt
removeTimings (Timing _ s) = s
removeTimings other = other
2019-02-25 22:19:55 +01:00
regIdents _ = return ()