IOBLogic.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Jean-Marc Frailong, September 12, 1987 9:24:24 pm PDT
Support for new logic icons inside the IOB design. Most of them should migrate at some time into the standard Logic package.
DIRECTORY
BitOps,
Core,
CoreClasses,
CoreCreate,
CoreGeometry,
CoreOps,
Logic,
LogicUtils,
Rope,
Sinix,
Sisyph,
Static;
IOBLogic: CEDAR PROGRAM
IMPORTS BitOps, CoreCreate, CoreGeometry, CoreOps, Logic, LogicUtils, Sinix, Sisyph, Static
SHARES Sisyph
~ BEGIN OPEN LogicUtils, CoreCreate;
ROPE: TYPE ~ Rope.ROPE;
One shot
Provides a fixed-delay one-shot. The output remains active for "d" clock cycles after the last clock at which the input Trigger was active. The implementation is just a chain of flip-flops with an OR gate at the output.
OneShotName: ROPE = "OneShot";
OneShot: PROC [cx: Sisyph.Context, d: NAT] RETURNS [ct: CellType] = {
oneShot1B: CellType = Sisyph.ES["oneShot1B.sch", cx]; -- schematic for small d
insts: CoreClasses.CellInstances;
tmp: Core.Wire;
IF d=0 THEN LogicUtils.Error["Please provide the delay for the one-shot"];
insts ← LIST[
Instance[Logic.Nand[d], ["I", "nTmp"], ["X", "Output"]]];
tmp ← Seq["Tmp", d];
[] ← Static.UnconnectedOK[tmp[d-1]]; -- This is the only wire unused in the whole cell
FOR i: NAT IN [0..d) DO
insts ← CONS[
Instance[oneShot1B,
["D", IF i=0 THEN "Trigger" ELSE Index["Tmp", i-1]],
["Q", Index["Tmp", i]],
["nQ", Index["nTmp", i]]],
insts];
ENDLOOP;
ct ← Cell[
name: OneShotName,
public: Wires["Trigger", "Output", "Vdd", "Gnd", "CK"],
onlyInternal: Wires[Seq["nTmp", d], tmp],
instances: insts];
};
Constant
Provides direct ExtractProc for constant. Standard wire icons do not work here because Vdd and Gnd are well-known wires...
Constant: Sinix.ExtractProc = {
PROC [obj: Object, mode: Mode, properties: CD.PropList ← NIL, userData: REFNIL] RETURNS [result: REF, props: Properties ← NIL]
Evaluate parameters, recover b: number of bits, v: value (INT).
cx: Sisyph.Context = Sisyph.EvaluateParameters[userData, obj, properties];
iconCT: CellType = NARROW [Sinix.ExtractCell[obj, mode, NIL, cx].result];
gnd: Wire = CoreOps.CreateWire[name: "Gnd"];
vdd: Wire = CoreOps.CreateWire[name: "Vdd"];
output: Wire;
b: NAT;
v: INT;
vCard: CARD;
b ← Sisyph.FetchInt[cx, "b"].value;
v ← Sisyph.FetchInt[cx, "v"].value;
vCard ← LOOPHOLE[v];
IF b<=0 THEN LogicUtils.Error["Specify number of bits for Constant"];
output ← Seq[size: b];
IF b<=32 THEN FOR i: NAT IN [0..b) DO
output[i] ← IF BitOps.EBFD[vCard, i, b] THEN vdd ELSE gnd;
ENDLOOP
ELSE {
sign: Wire ← IF v<0 THEN vdd ELSE gnd;
FOR i: NAT IN [0..b-32) DO output[i] ← sign; ENDLOOP;
FOR i: NAT IN [b-32..b) DO
output[i] ← IF BitOps.EBFD[vCard, i-b+32, 32] THEN vdd ELSE gnd;
ENDLOOP;
};
CoreGeometry.PutIndirectLazyPins[mode.decoration, output, CoreOps.FindWire[iconCT.public, "Output"]];
result ← Wires[output, gnd, vdd];
};
Multiplexers with a constant
Mux2Constant: PROC [b: NAT, v: INT, inverting: BOOL] RETURNS [ct: Core.CellType] ~ {
Not correct yet...
Returns a multiplexer with a constant
Public => Input[b], Output[b], Force (when TRUE, select the constant)
Implementation is to AND (resp NAND) 0's in the constant, OR (resp NOR) 1's in the constant
vCard: CARD = LOOPHOLE[v];
one: Core.CellType = IF inverting THEN Logic.Nand[2] ELSE Logic.And[2];
zero: Core.CellType = IF inverting THEN Logic.Nor[2] ELSE Logic.Or[2];
instances: CoreCreate.CellInstances ← NIL;
input: Core.Wire ← CoreCreate.Seq["Input", b];
output: Core.Wire ← CoreCreate.Seq["Output", b];
IF b=0 THEN LogicUtils.Error["Please specify a number of bits for the constant comparator"];
FOR i: NAT IN [0..b) DO
instances ← CONS [
CoreCreate.Instance[
IF BitOps.EBFD[vCard, i, b] THEN one ELSE zero,
["I[0]", "nnForce"], ["I[1]", input[i]], ["X", output[i]]],
instances]
ENDLOOP;
instances ← CONS [CoreCreate.Instance[Logic.Buffer[2], ["I", "Force"], ["X", "nForce"]], instances];
instances ← CONS [CoreCreate.Instance[Logic.Buffer[Real.Round[Real.SqRt[b/2]]], ["I", "nForce"], ["X", "nnForce"]], instances];
ct ← CoreCreate.Cell[name: "Mux2Constant",
public: Wires[input, output, "Force"],
onlyInternal: Wires["nForce", "nnForce"],
instances: instances];
};
END.