Logic.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Last Edited by: Louis Monier October 28, 1987 11:58:35 am PST
Bertrand Serlet March 30, 1987 10:34:12 pm PST
Jean-Marc Frailong December 8, 1987 2:25:00 pm PST
Pradeep Sindhu July 20, 1987 2:28:08 pm PDT
This module provides the basic blocks for logic description and simulation of ICs. Every procedure corresponds to an icon in the library "Logic.dale"; extracting such an icon with Sisyph calls the corresponding procedure. The difference with a library like SSI is that there is no electrical notion attached to the cells, only logic behavior.
There are two types of cells in this library: the simple ones and the composite ones. Simple ones (inverter, nor4, ...) are similar to the cells in SSI and correspond to a single standard cell in most decent libraries. The composite ones (i.e. adder, counter) have a Core structure using cells of the first type as leaves, or a very specific layout (RAM, ROM, PLA). All types have a behavioral procedure for logic simulation using Rosemary.
DIRECTORY CD, Core, CoreCreate, CoreFlat, RosemaryUser, Ports;
Logic: CEDAR DEFINITIONS = BEGIN OPEN CoreCreate;
CutSets for simulation
logicCutSet, macroCutSet: ROPE; -- used by Rosemary
fast, macro, gate, transistor: CoreFlat.CutSet; -- use those for the CutSet property
fast collects all known simulation accelerators into a single cutset and need to be changed when new cutsets are added
macro enables only Logic macros and basic gates
gate enables only Logic basic gates (warning, very slow...)
transistors is in fact NIL, so everything is at transistor level except unimplemented celltypes
Very basic standard cells
Inv: PROC [buffered: BOOLFALSE] RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X"
Tr2: PROC [type: ATOM] RETURNS [ct: CellType]; -- $pd, $pdw, $pu, $puw accepted
"Vdd", "Gnd", "I", "X"
Rec2V: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X", "Vth"
RecTTL: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X"
Buffer: PROC[d: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X"
CKBuffer: PROC[d, numRows: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X"
TstDriver: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X", "EN", "NEN"
TristateI: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X", "EN"
TristateNI: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X", "EN"
And: PROC[n: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["I", n] "X"
Nand: PROC[n: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["I", n] "X"
Or: PROC[n: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["I", n] "X"
Nor: PROC[n: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["I", n] "X"
Xor2: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I-A", "I-B", "X"
Xnor2: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "I-A", "I-B", "X"
A22o2i: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "A", "B", "C", "D" ,"X"
O22a2i: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "A", "B", "C", "D" ,"X"
A21o2i: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "A", "B", "C" ,"X"
O21a2i: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "A", "B", "C" ,"X"
Driver: PROC [d: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X"
InvDriver: PROC [d: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "nX"
SymDriver: PROC [d: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "I", "X", "nX"
FlipFlop: PROC [metaStableResistant: BOOLFALSE] RETURNS [ct: CellType];
"Vdd", "Gnd", "D", "Q", "NQ", "CK"
FlipFlopEnable: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "D", "Q", "NQ", "CK", "en", "nEn"
FlipFlopAsyncReset: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "D", "Q", "NQ", "CK", "r"
DLatch: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "D", "Q", "S"
Not standard cells, but basic cells anyway
Storage: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "bit", "nbit"
RS: PROC RETURNS [ct: CellType];
"Vdd", "Gnd", "R", "S", "Q", "nQ"
Multiplexers
MuxDN1: PROC [n: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Select", n], Seq["In", n], "Output"
MuxD: PROC [n, b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Select", n], Seq["In", n, Seq[size: b]], Seq["Output", b]
MuxD2: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "Select0", "Select1", Seq["In0", b], Seq["In1", b], Seq["Output", b]
MuxD4: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "Select0", "Select1", "Select2", "Select3", Seq["In0", b], Seq["In1", b], Seq["In2", b], Seq["In3", b], Seq["Output", b]
MuxN1: PROC [n: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Select", s], Seq["In", n], "Output", with s=NbBits[n]
Mux: PROC [n, b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Select", s], Seq["In", n, Seq[size: b]], Seq["Output", b]
where s=NbBits[n]
Mux2: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "Select", Seq["In0", b], Seq["In1", b], Seq["Output", b]
Mux4: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Select", 2], Seq["In0", b], Seq["In1", b], Seq["In2", b], Seq["In3", b], Seq["Output", b]
InvMux: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "Select", Seq["In0", b], Seq["In1", b], Seq["nOut", b]
Tri-state Buffers
TristateBuffer : PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Input", b], Seq["Output", b], "enable"
TristateBufferInv : PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Input", b], Seq["Output", b], "enable"
Arithmetic
Adder: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "carryIn", Seq["A", b], Seq["B", b], Seq["Sum", b], "carryOut"
Constant: PROC [b: NAT, v: INT] RETURNS [ct: CellType];
Output is formed an Vdd and Gnd conections to generate the required constant pattern
Comparator: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["A", b], Seq["B", b], "AEqB"
EqConstant: PROC [b: NAT, v: INT] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["In", b], "out"
DecoderS: PROC [a: NAT, s: NAT ← 0] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Address", a], Seq["Select", s], with s=0 => s ← 2**a
Decoder: PROC [a: NAT, s: NAT ← 0] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Address", a], Seq["Select", s], "Enable", with s=0 => s ← 2**a
Macros with states
Register: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b], Seq["nOutput", b], "en"
RegisterR: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b], Seq["nOutput", b], "en", "r"
RegisterSimple: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b], Seq["nOutput", b]
CounterCLG: PROC [n: NAT] RETURNS [ct: CellType];
PIn[n], nCOut[n], CIn, COut (of the counter, enabled by CIn)
Carry lookahead generation for a counter (tree). Naive users, beware...
CounterUp: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "Load", "Count", "Cin", "Cout", "CK", Seq["Input", b], Seq["Output", b], Seq["nOutput", b].
Load has priority over Count. Uses a carry-lookahead scheme.
CounterUpDown: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "Load", "Up", "Down", "Cin", "Cout", "Bin", "Bout", "CK", Seq["Input", b], Seq["Output", b], Seq["nOutput", b] (Bin, Bout are the borrow signals).
Load has priority over Up and Down. If both Up and Down are set, results in NoOp. Uses a carry-lookahead scheme.
Latch: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b]
Useful wire icons
ReverseBits: PROC [b: NAT] RETURNS [public: Core.Wires];
Reverse the order of the bits of a b-bit bus
Transpose: PROC [b, w: NAT] RETURNS [public: Core.Wires];
Transform a bus of w words of b bits into a bus of b words of w bits
"wSide" has w words of b bits, "bSide" has b words of w bits
Interleave: PROC [b: NAT] RETURNS [public: Core.Wires];
Interleave 2 buses of b bits into a single bus of 2*b bits
"Even[b]", "Odd[b]", "Result[2*b]" Result[2*i]=Even[i], Result[2*i+1]=Odd[i]
Standard generators
Ram2: PROC [b, n: NAT, sameSide, short: BOOLFALSE] RETURNS [ct: CellType];
"Vdd", "Gnd", Seq["Input", b], Seq["Output", b], Seq["RAdr", a], Seq["WAdr", a], "enW"
Fifo: PROC [b, n, nbFreeNF: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b], "Load", "UnLoad", "Reset", "DataAv", "Full", "NF"
For the custom block: "Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b], "Read", "Write", "Reset"
For Rosemary simulation only (no layout)
Oracle: PROC [in, out, name: ROPE, log: BOOLFALSE] RETURNS [ct: CellType];
"In", "Out", "CK"
Disagreement: SIGNAL [shouldBe, is: Ports.Level, oracleName: ROPE, index: CARD];
-- see in Ports
SetOracleFileName: PROC [id, fileName: ROPE];
GetOracleFileName: PROC [id: ROPE] RETURNS [fileName: ROPE];
WaveForm: PROC [val: ROPE, freq: NAT, firstEdge: INT] RETURNS [ct: CellType];
"RosemaryLogicTime", "Out"
Default values on icon: freq𡤂, firstEdge𡤁
ClockGen: PROC [up, dn, firstEdge: INT, initLow: BOOL] RETURNS [ct: CellType];
"RosemaryLogicTime", "Clock"
Default values on icon: up𡤍n𡤏irstEdge𡤁 initLow←TRUE
Stop: PROC [] RETURNS [ct: CellType];
raises an error when its input "ShouldBeFalse" is true
PullUp: PROC [n: NAT] RETURNS [ct: CellType];
RunRosemary: PROC [cellType: CellType, design: CD.Design, cutSet: CoreFlat.CutSet ← NIL] RETURNS [tester: RosemaryUser.Tester];
If the cutset passed is defaulted to NIL, then get it from the $Simulation celltype property:
$Fast => macro level, $Transistors=transistor level, otherwise gate level.
Avoid these: will be replaced some day
Counter: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "s0", "s1", "Cin", "Cout", "CK", Seq["Input", b], Seq["Output", b]
s1=0, s0=0 => count down
s1=0, s0=1 => count up
s1=1, s0=0 => idle
s1=1, s0=1 => load input
ShiftReg: PROC [b: NAT] RETURNS [ct: CellType];
"Vdd", "Gnd", "s0", "s1", "CK", "inL", "inR", Seq["Input", b], Seq["Output", b]
s1=0, s0=0 => shift right
s1=0, s0=1 => shift left
s1=1, s0=0 => idle
s1=1, s0=1 => load input
END.