Wired-0.1: Analysis/STA.hs
{-# OPTIONS_GHC -fno-warn-missing-fields #-}
module Analysis.STA
( TransitionTime
, Timing (..)
, STALibrary
, Prop
, analyzeTiming
) where
import Control.Arrow ((***))
import Control.Monad
import Data.Hardware
import Lava.Internal
import Analysis.STA.Library
data Prop = Prop
{ riseTiming :: Timing
, fallTiming :: Timing
, capacitance :: Capacitance
}
addTiming :: Timing -> Timing -> Timing
addTiming (Timing ar1 tr1) (Timing ar2 tr2) = Timing (ar1+ar2) (tr1+tr2)
addProp :: Prop -> Prop -> Prop
addProp (Prop timR1 timF1 cap1) (Prop timR2 timF2 cap2) =
Prop (addTiming timR1 timR2) (addTiming timF1 timF2) (cap1+cap2)
timing0 = Timing 0 0
prop0 = Prop timing0 timing0 0
propCap cap = prop0 {capacitance = cap}
propRiseFall timR timF = prop0 {riseTiming = timR, fallTiming = timF}
getDelay :: Prop -> Delay
getDelay (Prop timR timF _) = maxArrival timR timF
interpTiming :: STALibrary lib => Interpretation lib Prop
interpTiming = Interp
{ defaultVal = prop0
, accumulator = addProp
, propagator = propagate
}
where
propagate cell ss = outs' ++ ins'
where
no = numOuts cell
(outs,ins) = splitAt no ss
propagatePath oPin oCap (iPin, Prop iTimR iTimF _) = (oTimR,oTimF)
where
oTimR = maximumByArrival
[ delay cell iPin oPin Rising oCap iTimR
, delay cell iPin oPin Rising oCap iTimF
]
oTimF = maximumByArrival
[ delay cell iPin oPin Falling oCap iTimF
, delay cell iPin oPin Falling oCap iTimR
]
ins' = map (Just . propCap) (loadCaps cell)
outs' = do
(oPin, Prop _ _ oCap) <- zip [0..] outs
let (timRs,timFs) =
unzip $ map (propagatePath oPin oCap) $ zip [icast no ..] ins
return $ Just $ propRiseFall
(maximumByArrival timRs)
(maximumByArrival timFs)
analyzeTiming
:: ( STALibrary lib
, PortStruct ps Signal t
, PortStruct pd Delay t
)
=> Lava lib ps -> (pd, InterpDesignDB lib Prop)
analyzeTiming = (unport . fmap getDelay *** id) . interpret_ interpTiming [] . liftM port
-- *** Check for loop.
-- *** Add wire loads.