module Analysis.Timing.Library where
import Data.Function
import Data.List
import Foreign.C
import Data.Hardware.Internal
import Lava
import Wired.Model
data Slope = Rising | Falling
deriving (Eq, Show)
data Timing = Timing
{ arrivalTime :: Time
, transitionTime :: TransitionTime
}
deriving (Eq, Show)
data LayerProps = LayerProps
{ layerWidth :: Width
, capPerArea :: Double
, edgeCap :: Double
}
deriving (Eq, Show)
class CellLibrary lib => TimingLibrary lib
where
loadCaps :: lib -> [Capacitance]
delay
:: lib
-> InPin
-> OutPin
-> Slope
-> Capacitance
-> Timing
-> Timing
class TimingLibrary lib => WireTimingLibrary lib
where
layerProps :: Layer_ -> Res lib LayerProps
maximumByArrival :: [Timing] -> Timing
maximumByArrival = maximumBy (compare `on` arrivalTime)
linearDelay
:: Delay
-> Double
-> Double
-> Resistance
-> Resistance
-> Capacitance
-> Timing
-> Timing
linearDelay intrDel kAr kTr resAr resTr cap (Timing ar tr) = Timing
(ar + intrDel + timeCast (kAr><tr) + resAr><cap)
(kTr><tr + timeCast (resTr><cap))
tableDelay
:: Table2D CInt TransitionTime Capacitance Time
-> Table2D CInt TransitionTime Capacitance TransitionTime
-> (Capacitance -> Timing -> Timing)
tableDelay arLut trLut cap (Timing ar tr) = Timing ar' tr'
where
ar' = bilinInterpolate arLut tr cap + ar
tr' = bilinInterpolate trLut tr cap
mkTimingTable
:: ( Fractional x
, Fractional y
, Fractional q
)
=> CInt
-> CInt
-> (CInt -> CDouble)
-> (CInt -> CDouble)
-> (CInt -> CInt -> CDouble)
-> Table2D CInt x y q
mkTimingTable xLen yLen xAxis yAxis vals = Table2D
xLen
yLen
(realToFrac . xAxis)
(realToFrac . yAxis)
(\i1 i2 -> realToFrac (vals i1 i2))
wireCap
:: forall lib . WireTimingLibrary lib
=> Layer_ -> Length -> Res lib Capacitance
wireCap lay len = R $ dcast
$ cArea * l*w
+ (cEdge * 2 * (l+w))
where
LayerProps wit cArea cEdge = result (layerProps lay :: Res lib LayerProps)
l = fromRational $ value len
w = fromRational $ value wit