DIRECTORY CoreClasses, CoreCreate, CoreOps, CoreProperties, IO, Logic, LogicUtils, Real; LogicVSimpleImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreOps, CoreProperties, IO, LogicUtils, Real EXPORTS Logic = BEGIN OPEN LogicUtils, CoreCreate; vTypeProp: ATOM = $VerilogType; vName: ATOM = $VerilogName; dirProp: ATOM = $VerilogDirection; nbGatesProp: ATOM = $LSIGates; Primitive: PROC [cacheName, name: ROPE, nbGates: INT, public: WireSeq, outputs: LIST OF ROPE] RETURNS [ct: CellType] ~ { ct _ MakePrimitive[cacheName, name, nbGates, public, outputs, $Leaf]; }; Module: PROC [cacheName, name: ROPE, nbGates: INT, public: WireSeq, outputs: LIST OF ROPE] RETURNS [ct: CellType] ~ { ct _ MakePrimitive[cacheName, name, nbGates, public, outputs, $Module]; }; MakePrimitive: PROC [cacheName, name: ROPE, nbGates: INT, public: WireSeq, outputs: LIST OF ROPE, vType: ATOM] RETURNS [ct: CellType] ~ { SetDirection: PROC [wire: Wire] ~ {CoreProperties.PutWireProp[wire, dirProp, $input]}; ct _ CacheFetch[cacheName]; IF ct#NIL THEN RETURN[ct]; ct _ CoreClasses.CreateUnspecified[public: public, name: cacheName]; [] _ CoreOps.VisitRootAtomics[ct.public, SetDirection]; FOR l: LIST OF ROPE _ outputs, l.rest WHILE l#NIL DO wire: Wire _ CoreOps.FindWire[ct.public, l.first]; IF wire=NIL THEN ERROR; -- where is this output? CoreProperties.PutWireProp[wire, dirProp, $output]; ENDLOOP; CoreProperties.PutCellTypeProp[ct, vTypeProp, vType]; CoreProperties.PutCellTypeProp[ct, vName, name]; CoreProperties.PutCellTypeProp[ct, nbGatesProp, NEW[INT _ nbGates]]; CacheStore[cacheName, ct]; }; Inv: PUBLIC PROC [buffered: BOOL _ FALSE] RETURNS [ct: CellType] = { logicName: ROPE = IF buffered THEN "InvB" ELSE "Inv"; ct _ Primitive[logicName, "not", 1, Wires["X", "I", "Vdd", "Gnd"], LIST["X"]]; }; And: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = {ct _ B4Large["and", n]}; Nand: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = {ct _ B4Large["nand", n]}; Or: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = {ct _ B4Large["or", n]}; Nor: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = {ct _ B4Large["nor", n]}; Xor2: PUBLIC PROC RETURNS [ct: CellType] = { ct _ Primitive["xor2", "xor", 3, Wires["X", "I-A", "I-B", "Vdd", "Gnd"], LIST["X"]];}; Xnor2: PUBLIC PROC RETURNS [ct: CellType] = { ct _ Primitive["xnor2", "xnor", 3, Wires["X", "I-A", "I-B", "Vdd", "Gnd"], LIST["X"]];}; FlatB4Large: PROC [opName: ROPE, n: NAT] RETURNS [ct: CellType] ~ { logicName: ROPE _ IO.PutFR["%g%g", IO.rope[opName], IO.int[n]]; public: WireSeq _ CoreOps.CreateWires[n+3]; public[0] _ CoreOps.CreateWire[name: "X"]; public[n+1] _ CoreOps.CreateWire[name: "Vdd"]; public[n+2] _ CoreOps.CreateWire[name: "Gnd"]; FOR i: NAT IN [0..n) DO public[i+1] _ CoreOps.CreateWire[name: IO.PutFR["I%g", IO.int[i]]]; ENDLOOP; ct _ Primitive[logicName, opName, n/2, public, LIST["X"]]; }; B4Large: PROC [opName: ROPE, n: NAT] RETURNS [ct: CellType] ~ { pas: LIST OF PA _ NIL; instances: CellInstances _ NIL; cacheName: ROPE _ IO.PutFR["Str%g%g", IO.rope[opName], IO.int[n]]; ct _ CacheFetch[cacheName]; IF ct#NIL THEN RETURN[ct]; pas _ LIST[["X", "X"]]; FOR i: NAT IN [0..n) DO pas _ CONS[ [IO.PutFR["I%g", IO.int[i]], IO.PutFR["I[%g]", IO.int[i]]], pas]; ENDLOOP; ct _ Cell[public: Wires["X", Seq["I", n], "Vdd", "Gnd"], name: cacheName, instances: LIST[InstanceList[type: FlatB4Large[opName, n], pas: pas]]]; CacheStore[cacheName, ct]; }; A22o2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ Primitive["A22o2i", "a22o2i", 2, Wires["X", "A", "B", "C", "D", "Vdd", "Gnd"], LIST["X"]];}; O22a2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ Primitive["O22a2i", "o22a2i", 2, Wires["X", "A", "B", "C", "D", "Vdd", "Gnd"], LIST["X"]];}; A21o2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ Primitive["A21o2i", "a21o2i", 2, Wires["X", "A", "B", "C", "Vdd", "Gnd"], LIST["X"]];}; O21a2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ Primitive["O21a2i", "o21a2i", 2, Wires["X", "A", "B", "C", "Vdd", "Gnd"], LIST["X"]];}; FlipFlop: PUBLIC PROC [metaStableResistant: BOOL _ FALSE] RETURNS [ct: CellType] = { ct _ Module["FF", "ff", 7, Wires["Q", "NQ", "CK", "D", "Vdd", "Gnd"], LIST["Q", "NQ"]]; }; FlipFlopEnable: PUBLIC PROC RETURNS [ct: CellType] = { ct _ Module["FFen", "ffen", 9, Wires["Q", "NQ", "CK", "D", "nEn", "en", "Vdd", "Gnd"], LIST["Q", "NQ"]]; }; DLatch: PUBLIC PROC RETURNS [ct: CellType] = { ct _ Module["DLatch", "dLatch", 5, Wires["Q", "D", "S", "Vdd", "Gnd"], LIST["Q"]]; }; TstDriver: PUBLIC PROC RETURNS [ct: CellType] = { ct _ Module["Tristate", "tristate", 2, Wires["X", "I", "EN", "NEN", "Vdd", "Gnd"], LIST["X"]]; }; Rec2V: PUBLIC PROC RETURNS [ct: CellType] ~ { instances: CellInstances _ NIL; cacheName: ROPE _ "rec2V"; ct _ CacheFetch[cacheName]; IF ct#NIL THEN RETURN[ct]; ct _ Cell[public: Wires["X", "I", "Vth", "Vdd", "Gnd"], name: cacheName, instances: LIST[Instance[Inv[], ["X", "X"], ["I", "I"]]]]; CacheStore[cacheName, ct]; }; Buffer: PUBLIC PROC[d: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["Buffer d=%g", IO.int[d]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF d=0 THEN Error["Please specify size of buffer"]; ct _ SequenceCell[name: "Buffer", baseCell: Inv[TRUE], count: MAX[(d+1)/2, 1]]; CacheStore[fullName, ct]; }; CKBuffer: PUBLIC PROC[d, numRows: NAT] RETURNS [ct: CellType] = { ct _ Buffer[d]; }; Driver: PUBLIC PROC [d: NAT] RETURNS [ct: CellType] ~ { fullName: ROPE = IO.PutFR["Driver d=%g", IO.int[d]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT d FROM <=0 => Error["Please specify strength of driver"]; <=4 => ct _ SCBlock[Extract["driver4.sch"]]; <=8 => ct _ SCBlock[Extract["driver8.sch"]]; ENDCASE => { -- use constant amplification in 2 stages, correct up to 64 n2: NAT = (d+3)/4; -- second stage: 1 inverter may drive 4, round up n1: NAT = Real.Round[Real.SqRt[n2]]; -- first stage, sqrt of second stage ct _ Extract["driver.sch", LIST[["n1", n1], ["n2", n2]]]; }; CacheStore[fullName, ct]; }; InvDriver: PUBLIC PROC [d: NAT] RETURNS [ct: CellType] ~ { fullName: ROPE = IO.PutFR["InvDriver d=%g", IO.int[d]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT d FROM <=0 => Error["Please specify strength of inverting driver"]; <=4 => ct _ SCBlock[Extract["invDriver4.sch"]]; <=8 => ct _ SCBlock[Extract["invDriver8.sch"]]; ENDCASE => ct _ Extract["invDriver.sch", LIST[["drv", d]]]; -- use direct driver CacheStore[fullName, ct]; }; SymDriver: PUBLIC PROC [d: NAT] RETURNS [ct: CellType] ~ { fullName: ROPE = IO.PutFR["SymDriver d=%g", IO.int[d]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT d FROM <=0 => Error["Please specify strength of symmetrical driver"]; <=3 => ct _ SCBlock[Extract["symDriver3.sch"]]; <=6 => ct _ SCBlock[Extract["symDriver6.sch"]]; ENDCASE => { -- use constant amplification in 3 stages, correct up to 64 n2: NAT = (d+3)/4; -- last inverting stage: 1 inverter may drive 4, round up d1: NAT = d+n2; -- logic drive of initial non-inverting driver ct _ Extract["symDriver.sch", LIST[["n2", n2], ["d1", d1]]]; }; CacheStore[fullName, ct]; }; TristateI: PUBLIC PROC RETURNS [ct: CellType] ~ { fullName: ROPE = "TristateI"; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; ct _ SCBlock[Extract["3BufferI.icon"]]; CacheStore[fullName, ct]; }; TristateNI: PUBLIC PROC RETURNS [ct: CellType] ~ { fullName: ROPE = "TristateNI"; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; ct _ SCBlock[Extract["3BufferNI.icon"]]; CacheStore[fullName, ct]; }; FlipFlopAsyncReset: PUBLIC PROC RETURNS [ct: CellType] = { name: ROPE = "FlipFlopAsyncReset"; ct _ CacheFetch[name]; IF ct#NIL THEN RETURN[ct]; ct _ SCBlock[Extract["ffAR.sch"]]; CacheStore[name, ct]; }; RecTTL: PUBLIC PROC RETURNS [ct: CellType] = {ERROR}; Tr2: PUBLIC PROC [type: ATOM] RETURNS [ct: CellType] = {ERROR}; PullUp: PUBLIC PROC [n: NAT] RETURNS [ct: CellType] = {ERROR}; Storage: PUBLIC PROC RETURNS [ct: CellType] = {ERROR}; RS: PUBLIC PROC RETURNS [ct: CellType] = {ERROR}; END. ΚLogicVSimpleImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Created by: Louis Monier October 14, 1988 2:53:02 pm PDT Last Edited by: Louis Monier October 17, 1988 11:09:33 am PDT A simplified version of Logic that relies on Verilog for simulation, and maps to LSILogic library Verilog leaves -- the order of ports is very important -- the outputs must be atomic wires!!! -- name must match a verilog primitive (i.e. defined by a table, and running like Hell) -- must correspond to a predefined module (in primitives.v) Simple gates: they match a Verilog primitive -- The vanilla inverter (optionally with double power output) with explicit layout Complex gates: a primitive is defined for each cell in primitive.v Predefined modules, not primitives (complex cell, or more than one output) -- the flop from LSILogic IS metastable-resistant Temporary hacks until people clean up their old designs Unchanged Not mapped in Verilog/LSILogic Κ F– "cedar" style˜codešœ™Kšœ<™˜>Kšœ/˜/Kšœ/˜/šœŸ;˜HKšœœ Ÿ9˜LKšœœ Ÿ.˜>Kšœœ˜Kš  œœœœœ˜6Kš œœœœœ˜1K˜—Kšœ˜—…—-&