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 September 17, 1987 3:00:06 pm PDT
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
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.