diff --git a/src/Convert/SystemTasks.hs b/src/Convert/SystemTasks.hs index 269d3c9..73c11e0 100644 --- a/src/Convert/SystemTasks.hs +++ b/src/Convert/SystemTasks.hs @@ -10,7 +10,39 @@ import Convert.Traverse import Language.SystemVerilog.AST convert :: [AST] -> [AST] -convert = map $ traverseDescriptions $ traverseModuleItems convertModuleItem +convert = map $ traverseDescriptions traverseDescription + +elaborationFatalIdent :: Identifier +elaborationFatalIdent = "_sv2v_elaboration_fatal" + +elaborationFatalCancelCode :: Expr +elaborationFatalCancelCode = RawNum (-1) + +elaborationFatalDecl :: ModuleItem +elaborationFatalDecl = MIPackageItem $ Decl $ Variable Local t elaborationFatalIdent [] elaborationFatalCancelCode + where t = IntegerAtom TInteger Unspecified + +elaborationFatalCheck :: ModuleItem +elaborationFatalCheck = Initial (Block Seq "" [] [ + zeroDelay, + If NoCheck checkCancelCode finishCall Null + ]) where + zeroDelay = Timing (Delay (RawNum 0)) Null + checkCancelCode = BinOpA Ne [] (Ident elaborationFatalIdent) elaborationFatalCancelCode + finishCall = Subroutine (Ident "$finish") (Args [(Ident elaborationFatalIdent)] []) + +traverseDescription :: Description -> Description +traverseDescription (Part att ext kw lif name pts items) = + traverseModuleItems convertModuleItem $ + Part att ext kw lif name pts $ + if hasElaborationFatal + then elaborationFatalDecl : items ++ [elaborationFatalCheck] + else items + where + hasElaborationFatal = any isElabTaskFatal items + isElabTaskFatal (ElabTask SeverityFatal _) = True + isElabTaskFatal _ = False +traverseDescription description = traverseModuleItems convertModuleItem description convertModuleItem :: ModuleItem -> ModuleItem diff --git a/src/Language/SystemVerilog/AST/Number.hs b/src/Language/SystemVerilog/AST/Number.hs index 6744590..ebaecb6 100644 --- a/src/Language/SystemVerilog/AST/Number.hs +++ b/src/Language/SystemVerilog/AST/Number.hs @@ -322,7 +322,7 @@ numberBitLength (Based size _ _ _ _) = then max 32 $ negate size else size --- get whether or not a number is signed +-- get whether or not a number is sized numberIsSized :: Number -> Bool numberIsSized UnbasedUnsized{} = False numberIsSized (Decimal size _ _) = size > 0 @@ -359,9 +359,7 @@ instance Show Number where show (UnbasedUnsized bit) = '\'' : show bit show (Decimal (-32) True value) = - if value < 0 - then error $ "illegal decimal: " ++ show value - else show value + show value show (Decimal size signed value) = if size == 0 then error $ "illegal decimal literal: "