<> <> <> <> <<>> <> <<>> DIRECTORY Core, CoreClasses, IO, FS, Logic, LogicUtilsImpl, Mint, WriteCapa, Rope, Sisyph, ViewerIO, HashTable; LogicPerformance: CEDAR PROGRAM IMPORTS IO, CoreClasses, Sisyph, Mint, FS, WriteCapa, ViewerIO, HashTable, Rope, LogicUtilsImpl SHARES LogicUtilsImpl ~ BEGIN ROPE: TYPE ~ Rope.ROPE; <> TestCounters: PROC [initCx: Sisyph.Context] ~ { Test: PROC [nbits: NAT, mode: Logic.CounterType] ~ { ct: Core.CellType; area, delay: REAL; cx: Sisyph.Context _ Sisyph.Copy[initCx]; Sisyph.Store[cx, "sz", NEW [INT _ nbits]]; Sisyph.Store[cx, "mode", NEW [Logic.CounterType _ mode]]; ct _ Sisyph.ES["CounterTest.sch", cx]; -- Should re-extract each time area _ Area[ct, "Counter"]; delay _ Delay[ct]; size.PutF[" %g", IO.real[area]]; time.PutF[" %g", IO.real[delay]]; msg.PutF["%g counter %g bits: %f.3 mm2, %f.1 ns", IO.rope[IF mode=ripple THEN "Ripple" ELSE "Lookahead"], IO.int[nbits], IO.real[area], IO.real[delay]]; IO.Flush[msg]; }; msg: IO.STREAM _ ViewerIO.CreateMessageWindowStream[]; time: IO.STREAM _ FS.StreamOpen["///Temp/LogicUpCounterSpeed.list", create]; size: IO.STREAM _ FS.StreamOpen["///Temp/LogicUpCounterSize.list", create]; time.PutF["-- ///Temp/CounterSpeed.list\n-- Timing estimates for counters (Mint)\n\nVariables:\n\n NbBits Ripple Lookahead\n\nValues:\n\n"]; size.PutF["-- ///Temp/CounterSize.list\n-- Size estimates for counters (Mint)\n\nVariables:\n\n NbBits Ripple Lookahead\n\nValues:\n\n"]; FOR i: NAT IN [2..32] DO time.PutF[" %g", IO.int[i]]; size.PutF[" %g", IO.int[i]]; Test[i, ripple]; -- serial carry chain Test[i, lookahead]; -- carry lookahead by 2 with inversions time.PutF["\n"]; size.PutF["\n"]; ENDLOOP; }; <> Area: PROC [ct: Core.CellType, testName: ROPE _ NIL] RETURNS [area: REAL] ~ { <> table: HashTable.Table _ HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]; target: Core.CellType _ NIL; IF testName#NIL THEN { -- locate named instance in RCT record: CoreClasses.RecordCellType _ NARROW [ct.data]; FOR i: NAT IN [0..record.size) DO IF Rope.Equal[CoreClasses.GetCellInstanceName[record.instances[i]], testName] THEN target _ record.instances[i].type; ENDLOOP; IF target=NIL THEN ERROR; } ELSE target _ ct; -- use ct itself area _ LogicUtilsImpl.Size[target, table].size*1040.0/1000000.0; -- in sq mm }; Delay: PROC [ct: Core.CellType] RETURNS [delay: REAL] ~ { <> circuit: Mint.Circuit; clkList: Mint.NodeList; gndNode, vddNode: Mint.Node; WriteCapa.WriteWireCapa[ct]; circuit _ Mint.InputData[ct, FALSE]; vddNode _ Mint.NodeFromRope["public.Vdd", circuit]; Mint.SetNode[vddNode, TRUE]; gndNode _ Mint.NodeFromRope["public.Gnd", circuit]; Mint.SetNode[gndNode, FALSE]; Mint.PrepareSets[circuit, LIST[gndNode, vddNode]]; clkList _ LIST[ Mint.NodeFromRope["CK", circuit]]; delay _ Mint.MaxFreqEvaluate[circuit: circuit, clkList: clkList, numberOfPaths: 1, from: 0.0, histOk: FALSE].worst/1000.0; -- in ns Mint.KillCircuit[circuit]; }; END.