packages feed

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.