<> <> <> <<>> <> <<>> DIRECTORY Core, CoreClasses, CoreCreate, Dyn, Ports, Rope, Rosemary, RosemaryUser, PCConex, PCEmul; PCConexImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, Ports, PCEmul, Rosemary EXPORTS PCConex ~ BEGIN OPEN PCConex; <> PCEDef: PUBLIC PROC [] RETURNS [ct: CellType] ~ { <> public: Wire _ CoreCreate.WireList[ LIST[ CoreCreate.Seq["Address",20], CoreCreate.Seq["DataOut",16], "nIOWPC", "nIORPC", CoreCreate.Seq["DataIn",16], "CkIn" ]]; <> ct _ CoreClasses.CreateUnspecified[public: public]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: PCConnexion]; <> <<>> Ports.InitPorts[ct, ls, drive,"Address"]; Ports.InitPorts[ct, ls, drive,"DataOut"]; Ports.InitPorts[ct, l, drive,"nIOWPC"]; Ports.InitPorts[ct, l, drive,"nIORPC"]; Ports.InitPorts[ct, ls, none,"DataIn"]; Ports.InitPorts[ct, l, none,"CkIn"]; }; PCEInit: PUBLIC Rosemary.InitProc = { <<--PROC [cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY _ NIL] RETURNS [stateAny: REF ANY _ NIL]-- >> <> pcemul: PCEmulState_ IF oldStateAny=NIL THEN NEW[PCEmulRec] ELSE NARROW[oldStateAny, PCEmulState]; <> pcemul.address _ NEW[Ports.LevelSequenceRec[20]]; pcemul.dataout _ NEW[Ports.LevelSequenceRec[16]]; pcemul.datain _ NEW[Ports.LevelSequenceRec[16]]; <> Ports.SetLS[pcemul.address, X]; Ports.SetLS[pcemul.dataout, X]; pcemul.nIOWPC _ X; pcemul.nIORPC _ X; <> [pcemul.ADDRESS] _ Ports.PortIndexes[cellType.public,"Address"]; [pcemul.DATAOUT] _ Ports.PortIndexes[cellType.public,"DataOut"]; [pcemul.NIOWPC] _ Ports.PortIndexes[cellType.public,"nIOWPC"]; [pcemul.NIORPC] _ Ports.PortIndexes[cellType.public,"nIORPC"]; [pcemul.DATAIN] _ Ports.PortIndexes[cellType.public,"DataIn"]; [pcemul.CKIN] _ Ports.PortIndexes[cellType.public,"CkIn"]; <<>> pcemul.countcycle_0; --is used for loops inside procs pcemul.labelcycle_0; --is used for detecting edge of ckin pcemul.testProcList _ NIL; stateAny_ pcemul; }; PCEEval: PUBLIC Rosemary.EvalProc = { <<--PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL]-->> pcemul: PCEmulState _ NARROW[stateAny]; <> pcemul.ckin _ p[pcemul.CKIN].l; Ports.CopyLS[from: p[pcemul.DATAIN].ls, to: pcemul.datain]; IF ~clockEval AND pcemul.ckin=L AND pcemul.labelcycle=1 THEN pcemul.labelcycle _ 0; -- for detecting positive edge of ckin IF ~clockEval AND pcemul.ckin=H AND pcemul.labelcycle=0 THEN{ pcemul.labelcycle _ 1; PCEmul.Emul[pcemul]; }; <> Ports.CopyLS[from: pcemul.address, to: p[pcemul.ADDRESS].ls]; Ports.CopyLS[from: pcemul.dataout, to: p[pcemul.DATAOUT].ls]; p[pcemul.NIOWPC].l _ pcemul.nIOWPC; p[pcemul.NIORPC].l _ pcemul.nIORPC; IF pcemul.nIORPC=L THEN p[pcemul.DATAOUT].d_none ELSE p[pcemul.DATAOUT].d_drive; }; PCConnexion: Core.ROPE = Rosemary.Register[roseClassName: "PCEDef", init: PCEInit, evalSimple: PCEEval, scheduleIfClockEval: TRUE]; END. <<>> <<>> <<>> <<>>