DIRECTORY CoreClasses, CoreCreate, IO, Logic, LogicUtils, Ports, Rosemary; LogicRegsImpl: CEDAR PROGRAM IMPORTS CoreCreate, IO, LogicUtils, Ports EXPORTS Logic = BEGIN OPEN LogicUtils, CoreCreate; RegRef: TYPE = REF RegRec; -- state information for registers RegRec: TYPE = RECORD [ ck, in, out, nOut, enable, reset: NAT _ LAST[NAT], master, slave: Ports.LevelSequence]; RegisterRoseClass: ROPE = RoseClass["Register", RegInit, RegSimple, TRUE]; Register: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["Register b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of register"]; ct _ Extract["register.sch", LIST[["b", b]]]; SimulateMacro[ct, RegisterRoseClass]; Ports.InitPorts[ct, l, none, "CK", "en"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output", "nOutput"]; CacheStore[fullName, ct]; }; RegInit: Rosemary.InitProc = { state: RegRef _ IF oldStateAny=NIL THEN NEW[RegRec] ELSE NARROW[oldStateAny]; b: NAT; [state.ck, state.in, state.out, state.nOut, state.enable] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output", "nOutput", "en"]; b _ p[state.in].ls.size; state.master _ NEW[Ports.LevelSequenceRec[b]]; state.slave _ NEW[Ports.LevelSequenceRec[b]]; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[p[state.out].ls, X]; Ports.SetLS[p[state.nOut].ls, X]; stateAny _ state; }; RegSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; IF ~clockEval THEN SELECT p[state.ck].l FROM L => { -- load each master bit in: Ports.LevelSequence = p[state.in].ls; en: Ports.Level = p[state.enable].l; nEn: Ports.Level = Ports.NotL[en]; FOR i: NAT IN [0..in.size) DO state.master[i] _ Ports.OrL[Ports.AndL[in[i], en], Ports.AndL[state.slave[i], nEn]]; ENDLOOP; }; H => Ports.CopyLS[from: state.master, to: state.slave]; -- load slave bits ENDCASE => {Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]}; -- conservative Ports.CopyLS[from: state.slave, to: p[state.out].ls]; Ports.NotLS[p[state.out].ls, p[state.nOut].ls]; }; RegisterRRoseClass: ROPE = RoseClass["RegisterR", RegRInit, RegRSimple, TRUE]; RegisterR: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["RegisterR b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of register with reset"]; ct _ Extract["registerWithReset.sch", LIST[["b", b]]]; SimulateMacro[ct, RegisterRRoseClass]; Ports.InitPorts[ct, l, none, "CK", "en", "r"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output", "nOutput"]; CacheStore[fullName, ct]; }; RegRInit: Rosemary.InitProc = { state: RegRef _ IF oldStateAny=NIL THEN NEW[RegRec] ELSE NARROW[oldStateAny]; b: NAT; [state.ck, state.in, state.out, state.nOut, state.enable, state.reset] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output", "nOutput", "en", "r"]; b _ p[state.in].ls.size; state.master _ NEW[Ports.LevelSequenceRec[b]]; state.slave _ NEW[Ports.LevelSequenceRec[b]]; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[p[state.out].ls, X]; Ports.SetLS[p[state.nOut].ls, X]; stateAny _ state; }; RegRSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; IF ~clockEval THEN SELECT p[state.ck].l FROM L => { -- load each master bit in: Ports.LevelSequence = p[state.in].ls; en: Ports.Level = p[state.enable].l; nEn: Ports.Level = Ports.NotL[en]; nReset: Ports.Level = Ports.NotL[p[state.reset].l]; FOR i: NAT IN [0..in.size) DO state.master[i] _ Ports.AndL[Ports.OrL[Ports.AndL[in[i], en], Ports.AndL[state.slave[i], nEn]], nReset]; ENDLOOP; }; H => Ports.CopyLS[from: state.master, to: state.slave]; -- load slave bits ENDCASE => {Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]}; -- conservative Ports.CopyLS[from: state.slave, to: p[state.out].ls]; Ports.NotLS[p[state.out].ls, p[state.nOut].ls]; }; RegisterSimpleRoseClass: ROPE = RoseClass["RegisterSimple", RegSInit, RegSSimple, TRUE]; RegisterSimple: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { registerSimpleName: ROPE = "RegisterSimple"; fullName: ROPE = IO.PutFR["RegisterSimple b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of register"]; ct _ SequenceCell[name: registerSimpleName, baseCell: Extract["reg1BSimple.sch"], count: b, sequencePorts: Wires["Input", "Output", "nOutput"]]; SimulateMacro[ct, RegisterSimpleRoseClass]; Ports.InitPorts[ct, l, none, "CK"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output", "nOutput"]; CacheStore[fullName, ct]; }; RegSInit: Rosemary.InitProc = { state: RegRef _ IF oldStateAny=NIL THEN NEW[RegRec] ELSE NARROW[oldStateAny]; b: NAT; [state.ck, state.in, state.out, state.nOut] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output", "nOutput"]; b _ p[state.in].ls.size; state.master _ NEW[Ports.LevelSequenceRec[b]]; state.slave _ NEW[Ports.LevelSequenceRec[b]]; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[p[state.out].ls, X]; Ports.SetLS[p[state.nOut].ls, X]; stateAny _ state; }; RegSSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; IF ~clockEval THEN SELECT p[state.ck].l FROM L => Ports.CopyLS[from: p[state.in].ls, to: state.master]; -- load master bits H => Ports.CopyLS[from: state.master, to: state.slave]; -- load slave bits ENDCASE => {Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]}; -- conservative Ports.CopyLS[from: state.slave, to: p[state.out].ls]; Ports.NotLS[p[state.out].ls, p[state.nOut].ls]; }; LatchRoseClass: ROPE = RoseClass["Latch", LatchInit, LatchSimple]; Latch: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] ~ { fullName: ROPE = IO.PutFR["Latch b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of latch"]; ct _ SequenceCell[name: "Latch", baseCell: Extract["latch1B.sch"], count: b, sequencePorts: Wires["Input", "Output"]]; SimulateMacro[ct, LatchRoseClass]; Ports.InitPorts[ct, l, none, "CK"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output"]; CacheStore[fullName, ct]; }; LatchInit: Rosemary.InitProc = { state: RegRef _ IF oldStateAny=NIL THEN NEW[RegRec] ELSE NARROW[oldStateAny]; [state.ck, state.in, state.out] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output"]; state.master _ NEW[Ports.LevelSequenceRec[p[state.in].ls.size]]; Ports.SetLS[state.master, X]; Ports.SetLS[p[state.out].ls, X]; stateAny _ state; }; LatchSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; SELECT p[state.ck].l FROM H => Ports.CopyLS[from: p[state.in].ls, to: state.master]; X => Ports.SetLS[state.master, X]; ENDCASE => NULL; Ports.CopyLS[from: state.master, to: p[state.out].ls]; }; TstState: TYPE = REF TstStateRec; TstStateRec: TYPE = RECORD [in, out, enable: NAT _ LAST[NAT]]; TstBufferAllInit: Rosemary.InitProc = { state: TstState _ IF oldStateAny=NIL THEN NEW[TstStateRec] ELSE NARROW[oldStateAny]; [state.in, state.out, state.enable] _ Ports.PortIndexes[cellType.public, "Input", "Output", "enable"]; stateAny _ state; }; TstBufferInvRoseClass: ROPE = RoseClass["TstBufferInv", TstBufferAllInit, TstBufferInvSimple]; TristateBufferInv: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["TristateBufferInv b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of inverting tristate buffer"]; ct _ Extract["3BufferP.sch", LIST[["b", b]]]; SimulateMacro[ct, TstBufferInvRoseClass]; Ports.InitPorts[ct, l, none, "enable"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, none, "Output"]; CacheStore[fullName, ct]; }; TstBufferInvSimple: Rosemary.EvalProc = { state: TstState _ NARROW[stateAny]; SELECT p[state.enable].l FROM H => {p[state.out].d _ drive; Ports.NotLS[p[state.in].ls, p[state.out].ls]}; L => p[state.out].d _ none; ENDCASE => {p[state.out].d _ drive; Ports.SetLS[p[state.out].ls, X]}; }; TstBufferRoseClass: ROPE = RoseClass["TstBuffer", TstBufferAllInit, TstBufferSimple]; TristateBuffer: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["TristateBuffer b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of tristate buffer"]; ct _ Extract["3Buffer.sch", LIST[["b", b]]]; SimulateMacro[ct, TstBufferRoseClass]; Ports.InitPorts[ct, l, none, "enable"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, none, "Output"]; CacheStore[fullName, ct]; }; TstBufferSimple: Rosemary.EvalProc = { state: TstState _ NARROW[stateAny]; SELECT p[state.enable].l FROM H => {p[state.out].d _ drive; Ports.CopyLS[from: p[state.in].ls, to: p[state.out].ls]}; L => p[state.out].d _ none; ENDCASE => {p[state.out].d _ drive; Ports.SetLS[p[state.out].ls, X]}; }; END. δLogicRegsImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier September 30, 1987 7:07:54 pm PDT Jean-Marc Frailong October 21, 1987 10:10:30 pm PDT Christian LeCocq October 14, 1986 2:10:45 pm PDT Barth, October 10, 1986 5:30:59 pm PDT Registers Shared types Register with Enable Register with Enable and Reset Basic Register ( no Enable, no Reset) Latch Tristate Buffers Shared types Inverting TS buffer Non-inverting TS buffer Κ A– "cedar" style˜codešœ™Kšœ Οmœ1™K™3K™0K™&K™—KšΟk œžœ%˜JK˜•StartOfExpansion[]šΟn œžœž˜Kšžœ žœ˜)Kšžœ˜ Kšœžœžœ˜$—head™ ™ Kšœžœžœ Οc"˜=šœžœžœ˜Kšœ"žœžœžœ˜2Kšœ$˜$——™KšŸœžœ-žœ˜Jš Ÿœžœžœžœžœ˜9Kšœ žœžœžœ ˜6K˜Kšžœžœžœžœ˜Kšžœžœ*˜5Kšœžœ ˜-Kšœ%˜%Kšœ)˜)Kšœ\˜\Kšœ˜Kšœ˜K˜—šŸœ˜Kš œžœ žœžœžœ žœžœ˜MKšœžœ˜Kšœ‰˜‰Kšœ˜Kšœžœ˜.Kšœžœ˜-Kšœ˜Kšœ˜Kšœ ˜ Kšœ!˜!Kšœ˜Kšœ˜—šŸ œ˜ Kšœžœ ˜!šžœ žœžœž˜,šœ ˜Kšœ)˜)Kšœ$˜$Kšœ"˜"šžœžœžœž˜KšœT˜TKšžœ˜—Kšœ˜—Kšœ8 ˜JKšžœA ˜W—Kšœ5˜5Kšœ/˜/Kšœ˜——™KšŸœžœ0žœ˜Nš Ÿ œžœžœžœžœ˜:Kšœ žœžœžœ ˜7K˜Kšžœžœžœžœ˜Kšžœžœ5˜@Kšœ&žœ ˜6Kšœ&˜&Kšœ.˜.Kšœ\˜\Kšœ˜Kšœ˜K˜—šŸœ˜Kš œžœ žœžœžœ žœžœ˜MKšœžœ˜Kšœ›˜›Kšœ˜Kšœžœ˜.Kšœžœ˜-Kšœ˜Kšœ˜Kšœ ˜ Kšœ!˜!Kšœ˜Kšœ˜—šŸ œ˜!Kšœžœ ˜!šžœ žœžœž˜,šœ ˜Kšœ)˜)Kšœ$˜$Kšœ"˜"Kšœ3˜3šžœžœžœž˜Kšœh˜hKšžœ˜—Kšœ˜—Kšœ8 ˜JKšžœA ˜W—Kšœ5˜5Kšœ/˜/Kšœ˜——™%KšŸœžœ5žœ˜Xš Ÿœžœžœžœžœ˜?Kšœžœ˜,Kšœ žœžœžœ ˜K˜—šŸœ˜'Kš œžœ žœžœžœžœžœ˜UKšœf˜fKšœ˜Kšœ˜——™KšŸœžœC˜^š Ÿœžœžœžœžœ˜BKšœ žœžœ!žœ ˜?K˜Kšžœžœžœžœ˜Kšžœžœ;˜FKšœžœ ˜-Kšœ)˜)Kšœ'˜'KšœP˜PKšœ˜Kšœ˜K˜—šŸœ˜)Kšœžœ ˜#šžœž˜KšœL˜LKšœ˜Kšžœ>˜E—Kšœ˜——™KšŸœžœ=˜Uš Ÿœžœžœžœžœ˜?Kšœ žœžœžœ ˜˜E—Kšœ˜———K˜Kšžœ˜—…—"Ύ-γ