Skip to content

Commit

Permalink
Merge remote branch 'seni/seni' into afterUniplate
Browse files Browse the repository at this point in the history
Conflicts:
	Language/Atom/Code.hs
  • Loading branch information
leepike@gmail.com committed Mar 7, 2011
2 parents d6a1775 + b1c3fdf commit 71ac927
Showing 1 changed file with 94 additions and 44 deletions.
138 changes: 94 additions & 44 deletions Language/Atom/Code.hs
Expand Up @@ -45,7 +45,7 @@ data Config = Config
} }


-- | Data associated with sampling a hardware clock. For the clock to work -- | Data associated with sampling a hardware clock. For the clock to work
-- correctly, you MUST assign @__global_clock@ the current time (accoring to -- correctly, you MUST assign @__global_clock@ the current time (accoring to
-- @clockName@) the first time you enter the main Atom-generated function -- @clockName@) the first time you enter the main Atom-generated function
-- calling your rules. -- calling your rules.
data Clock = Clock data Clock = Clock
Expand All @@ -55,7 +55,7 @@ data Clock = Clock
-- @clockType clockName(void)@. -- @clockType clockName(void)@.
, clockType :: Type -- ^ Clock type. Assumed to be one of Word8, , clockType :: Type -- ^ Clock type. Assumed to be one of Word8,
-- Word16, Word32, or Word64. It is permissible -- Word16, Word32, or Word64. It is permissible
-- for the clock to rollover. -- for the clock to rollover.
, delta :: Integer -- ^ Number of ticks in a phase. Must be greater than 0. , delta :: Integer -- ^ Number of ticks in a phase. Must be greater than 0.
, delay :: String -- ^ C function to delay/sleep. The function is , delay :: String -- ^ C function to delay/sleep. The function is
-- assumed to have the prototype @void -- assumed to have the prototype @void
Expand Down Expand Up @@ -181,7 +181,7 @@ type RuleCoverage = [(Name, Int, Int)]
-- Rule _ _ _ _ _ _ _ b -> b -- Rule _ _ _ _ _ _ _ b -> b
-- _ -> False -- _ -> False


writeC :: Name -> Config -> StateHierarchy -> [Rule] -> Schedule -> [Name] writeC :: Name -> Config -> StateHierarchy -> [Rule] -> Schedule -> [Name]
-> [Name] -> [(Name, Type)] -> IO RuleCoverage -> [Name] -> [(Name, Type)] -> IO RuleCoverage
writeC name config state rules (mp, schedule) assertionNames coverageNames probeNames = do writeC name config state rules (mp, schedule) assertionNames coverageNames probeNames = do
writeFile (name ++ ".c") c writeFile (name ++ ".c") c
Expand All @@ -198,10 +198,15 @@ writeC name config state rules (mp, schedule) assertionNames coverageNames probe
, preCode , preCode
, "" , ""
, "static " ++ globalType ++ " " ++ globalClk ++ " = 0;" , "static " ++ globalType ++ " " ++ globalClk ++ " = 0;"
, codeIf (cRuleCoverage config) $ "static const " ++ cType Word32 , ""
, case hardwareClock config of
Nothing -> ""
Just _ -> "static " ++ globalType ++ " " ++ phaseStartTime ++ ";"
, ""
, codeIf (cRuleCoverage config) $ "static const " ++ cType Word32
++ " __coverage_len = " ++ show covLen ++ ";" ++ " __coverage_len = " ++ show covLen ++ ";"
, codeIf (cRuleCoverage config) $ "static " ++ cType Word32 , codeIf (cRuleCoverage config) $ "static " ++ cType Word32
++ " __coverage[" ++ show covLen ++ "] = {" ++ " __coverage[" ++ show covLen ++ "] = {"
++ (concat $ intersperse ", " $ replicate covLen "0") ++ "};" ++ (concat $ intersperse ", " $ replicate covLen "0") ++ "};"
, codeIf (cRuleCoverage config) , codeIf (cRuleCoverage config)
("static " ++ cType Word32 ++ " __coverage_index = 0;") ("static " ++ cType Word32 ++ " __coverage_index = 0;")
Expand All @@ -210,39 +215,95 @@ writeC name config state rules (mp, schedule) assertionNames coverageNames probe
, codeAssertionChecks mp config assertionNames coverageNames rules , codeAssertionChecks mp config assertionNames coverageNames rules
, "void " ++ funcName ++ "() {" , "void " ++ funcName ++ "() {"
, swOrHwClock , swOrHwClock
, unlines [ swOrHwClock
, codePeriodPhases
, " " ++ globalClk ++ " = " ++ globalClk ++ " + 1;"
]
, "}" , "}"
, "" , ""
, postCode , postCode
] ]


codePeriodPhases = concatMap (codePeriodPhase config) schedule codePeriodPhases = concatMap (codePeriodPhase config) schedule


swOrHwClock = swOrHwClock =
case hardwareClock config of case hardwareClock config of
Nothing -> unlines [codePeriodPhases, " " ++ globalClk ++ " = " ++ globalClk ++ " + 1;"] Nothing -> ""
Just clkData -> unlines Just clkData -> unlines
[ "" [ ""
, codePeriodPhases
, " // In the following we sample the hardware clock, waiting for the next phase."
, ""
, " " ++ declareConst phaseConst clkDelta , " " ++ declareConst phaseConst clkDelta
, " " ++ declareConst maxConst maxVal , " " ++ declareConst maxConst maxVal
, " " ++ globalType ++ " " ++ setTime , " static " ++ globalType ++ " " ++ lastPhaseStartTime ++ ";"
, " static " ++ globalType ++ " " ++ lastTime ++ ";"
, " static bool __first_call = true;"
, " " ++ globalType ++ " " ++ currentTime ++ ";"
, "" , ""
, errCheck , " /* save the current time */"
, " " ++ setTime ++ " // Update the current time." , " " ++ setTime
, " // Wait until the phase has expired. If the current time hasn't" , ""
, " // overflowed, execute the first branch; otherwise, the second." , " /* initialize static variables on the first call */"
, " if (" ++ currentTime ++ " >= " ++ globalClk ++ ") {" , " if ( __first_call ) {"
, " " ++ delayFn ++ "(" ++ phaseConst ++ " - (" ++ currentTime , " " ++ lastPhaseStartTime ++ " = " ++ phaseStartTime ++ ";"
++ " - " ++ globalClk ++ "));" , " " ++ lastTime ++ " = " ++ currentTime ++ ";"
, " __first_call = false;"
, " }" , " }"
, " else {" , ""
, " " ++ delayFn ++ "(" ++ phaseConst ++ " - (" ++ currentTime ++ " + (" , " /* wait for the amount left for the phase start time to be reached,"
++ maxConst ++ " - " ++ globalClk ++ ")));" , " handle roll-overs of the system timer and the phase start time */"
, " if ( " ++ phaseStartTime ++ " >= " ++ lastPhaseStartTime ++ " ) {"
, " /* phase start time did not roll over */"
, " if ( " ++ currentTime ++ " >= " ++ lastTime ++ " ) {"
, " /* system time and the phase start time did not roll over */"
, " if ( " ++ phaseStartTime ++ " >= " ++ currentTime ++ " ) {"
, " " ++ delayFn ++ " ( " ++ phaseStartTime ++ " - " ++ currentTime ++ " );"
, " } else {"
, " /* we are late */"
, " " ++ errHandler
, " }"
, " } else {"
, " /* system time rolled over, the start time of the"
, " phase did not, i.e. we are not late if currentTime"
, " is already in between lastPhaseStartTime and phaseStartTime */"
, " if ( ( " ++ currentTime ++ " >= " ++ lastPhaseStartTime ++ " )"
, " && ( " ++ phaseStartTime ++ " >= " ++ currentTime ++ " ) ) {"
, " " ++ delayFn ++ " ( " ++ phaseStartTime ++ " - " ++ currentTime ++ " );"
, " } else {"
, " /* we are late */"
, " " ++ errHandler
, " }"
, " }"
, " } else {"
, " /* phase start time rolled over */"
, " if ( " ++ currentTime ++ " >= " ++ lastTime ++ " ) {"
, " /* current time did not yet roll over */"
, " if ( " ++ currentTime ++ " >= " ++ phaseStartTime ++ " ) {"
, " " ++ delayFn ++ " ( ( " ++ maxConst
++ " - ( " ++ currentTime
++ " - " ++ phaseStartTime ++ " ) + 1 )" ++ " );"
, " } else {"
, " /* this should not happen, since " ++ phaseConst ++ " should be"
, " smaller than " ++ maxConst ++ " and " ++ lastTime ++ " should"
, " be smaller than or equal to " ++ currentTime ++ " */"
, " " ++ errHandler
, " }"
, " } else {"
, " /* current time and phase start time rolled over"
, " equal to the first case */"
, " if ( " ++ phaseStartTime ++ " >= " ++ currentTime ++ " ) {"
, " " ++ delayFn ++ " ( " ++ phaseStartTime ++ " - " ++ currentTime ++ " );"
, " } else {"
, " /* we are late */"
, " " ++ errHandler
, " }"
, " }"
, " }" , " }"
, "" , ""
, " " ++ setGlobalClk clkData , ""
, " /* update to the next phase start time */"
, " " ++ lastPhaseStartTime ++ " = " ++ phaseStartTime ++ ";"
, " " ++ phaseStartTime ++ " = " ++ phaseStartTime ++ " + "
++ phaseConst ++ ";"
, " " ++ lastTime ++ " = " ++ currentTime ++ ";"
] ]
where where
delayFn = delay clkData delayFn = delay clkData
Expand All @@ -257,8 +318,9 @@ writeC name config state rules (mp, schedule) assertionNames coverageNames probe
++ " = " ++ showConst (constType c) ++ ";" ++ " = " ++ showConst (constType c) ++ ";"
setTime = currentTime ++ " = " ++ clockName clkData ++ "();" setTime = currentTime ++ " = " ++ clockName clkData ++ "();"
maxConst = "__max" maxConst = "__max"
phaseConst = "__phase_len" phaseConst = "__phase_len"
currentTime = "__curr_time" currentTime = "__curr_time"
lastTime = "__last_time"
clkDelta | d <= 0 clkDelta | d <= 0
= error $ "The delta " = error $ "The delta "
++ show d ++ show d
Expand All @@ -274,31 +336,18 @@ writeC name config state rules (mp, schedule) assertionNames coverageNames probe
| otherwise | otherwise
= d = d
where d = delta clkData where d = delta clkData
errCheck = errHandler =
case err clkData of case err clkData of
Nothing -> "" Nothing -> ""
Just errF -> unlines Just errF -> errF ++ " ();"
[ " // An error check for when the phase has already expired."
, " // The first disjunct is for when the current time has not overflowed,"
, " // and the second for when it has."
, " if ( ((" ++ currentTime ++ " >= " ++ globalClk ++ ") && ("
++ currentTime ++ " - " ++ globalClk
++ " > " ++ phaseConst ++ "))"
, " || (("
++ currentTime ++ " < " ++ globalClk ++ ") && ((" ++ maxConst
++ " - " ++ globalClk ++ ") + " ++ currentTime ++ " > "
++ phaseConst ++ "))) {"
, " " ++ errF ++ "();"
, " }"
]
constType :: Integer -> Const constType :: Integer -> Const
constType c = case clockType clkData of constType c = case clockType clkData of
Word8 -> CWord8 (fromInteger c :: Word8) Word8 -> CWord8 (fromInteger c :: Word8)
Word16 -> CWord16 (fromInteger c :: Word16) Word16 -> CWord16 (fromInteger c :: Word16)
Word32 -> CWord32 (fromInteger c :: Word32) Word32 -> CWord32 (fromInteger c :: Word32)
Word64 -> CWord64 (fromInteger c :: Word64) Word64 -> CWord64 (fromInteger c :: Word64)
_ -> clkTypeErr _ -> clkTypeErr

h = unlines h = unlines
[ "#include <stdbool.h>" [ "#include <stdbool.h>"
, "#include <stdint.h>" , "#include <stdint.h>"
Expand All @@ -316,7 +365,6 @@ writeC name config state rules (mp, schedule) assertionNames coverageNames probe
Word32 -> Word32 Word32 -> Word32
Word64 -> Word64 Word64 -> Word64
_ -> clkTypeErr) _ -> clkTypeErr)

clkTypeErr :: a clkTypeErr :: a
clkTypeErr = error "Clock type must be one of Word8, Word16, Word32, Word64." clkTypeErr = error "Clock type must be one of Word8, Word16, Word32, Word64."


Expand All @@ -327,7 +375,9 @@ writeC name config state rules (mp, schedule) assertionNames coverageNames probe


covLen = 1 + div (maximum $ map ruleId rules') 32 covLen = 1 + div (maximum $ map ruleId rules') 32


setGlobalClk clkData = globalClk ++ " = " ++ clockName clkData ++ "();" phaseStartTime = "__phase_start_time"
lastPhaseStartTime = "__last_phase_start_time"



codeIf :: Bool -> String -> String codeIf :: Bool -> String -> String
codeIf a b = if a then b else "" codeIf a b = if a then b else ""
Expand Down

0 comments on commit 71ac927

Please sign in to comment.