<> <> <> DIRECTORY Core, CoreFlat, CoreName, IFUSim, Rosemary, Ports, Rope; IFUSimFetchBuf: CEDAR PROGRAM IMPORTS CoreFlat, CoreName, IFUSim, Rosemary, Ports, Rope EXPORTS IFUSim = BEGIN ROPE: TYPE = Core.ROPE; CellType: TYPE = Core.CellType; Signal: SIGNAL = CODE; fetchBuf: ROPE _ Rosemary.Register[CoreName.RopeNm["FetchBuf"], FetchBufInit, FetchBufEval]; FetchBufWtWd: ROPE _ CoreName.RopeNm["FetchBufWtWd"]; FetchBufRdByte: ROPE _ CoreName.RopeNm["FetchBufRdByte"]; IPData: ROPE _ CoreName.RopeNm["IPData"]; Op: ROPE _ CoreName.RopeNm["Op"]; Alpha: ROPE _ CoreName.RopeNm["Alpha"]; Beta: ROPE _ CoreName.RopeNm["Beta"]; Gamma: ROPE _ CoreName.RopeNm["Gamma"]; Delta: ROPE _ CoreName.RopeNm["Delta"]; FetchBufState: TYPE = REF FetchBufStateRec; FetchBufStateRec: TYPE = RECORD[ bytes: FetchBufBytes, ipData: FetchWdPins, op: FetchBytePins, alpha: FetchBytePins, beta: FetchBytePins, gamma: FetchBytePins, delta: FetchBytePins, rdByte: FetchRowPins, wtWd: FetchQRowPins ]; FetchBufBytes: TYPE = PACKED ARRAY [0..16) OF ARRAY [0..8) OF Ports.Level _ ALL[ALL[L]]; FetchWdPins: TYPE = ARRAY [0..32) OF CARDINAL; FetchBytePins: TYPE = ARRAY [0..08) OF CARDINAL; FetchRowPins: TYPE = ARRAY [0..16) OF CARDINAL; FetchQRowPins: TYPE = ARRAY [0..04) OF CARDINAL; FetchBufInitPort: PUBLIC PROC [cell: CellType] = { []_Rosemary.BindCellType [cell, fetchBuf]; []_CoreFlat.CellTypeCutLabels [cell, "UpOneLevel"]; FOR i: INT IN [0..cell.public.size) DO name: ROPE _ CoreName.WireNm[cell.public[i]].n; sig: CoreName.SigRec _ CoreName.NameSig[name]; IF (cell.public[i].size#0) OR (name.Length[]=0) THEN Signal[]; SELECT sig.root FROM Op, Alpha, Beta, Gamma, Delta => []_Ports.InitPort[wire: cell.public[i], levelType: l, initDrive: drive]; IPData => []_Ports.InitPort[wire: cell.public[i], levelType: l, initDrive: none]; ENDCASE => []_Ports.InitPort[wire: cell.public[i], levelType: b, initDrive: none]; ENDLOOP}; FetchBufInit: Rosemary.InitProc = { s: FetchBufState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[FetchBufStateRec]; FOR bit: INT IN [0..cellType.public.size) DO name: ROPE _ CoreName.WireNm[cellType.public[bit]].n; sig: CoreName.SigRec _ CoreName.NameSig[name]; SELECT sig.root FROM IPData => s.ipData [ IFUSim.Adj[sig.idx] ] _ bit; -- octal indexes Op => s.op [ sig.idx ] _ bit; Alpha => s.alpha [ sig.idx ] _ bit; Beta => s.beta [ sig.idx ] _ bit; Gamma => s.gamma [ sig.idx ] _ bit; Delta => s.delta [ sig.idx ] _ bit; FetchBufRdByte => s.rdByte [ sig.idx ] _ bit; FetchBufWtWd => s.wtWd [ sig.idx ] _ bit; ENDCASE ENDLOOP; RETURN[s]}; FetchBufEval: Rosemary.EvalProc = { PullDown: PROC[byte: [0..16), bit: [0..8), old: Ports.Level] RETURNS[Ports.Level] = {RETURN[SELECT s.bytes[byte][bit] FROM L => L, X => X, ENDCASE => old]}; s: FetchBufState _ NARROW[stateAny]; lastRd: CARDINAL _ 0; cntRd: CARDINAL _ 0; FOR wd: CARDINAL IN [0..4) DO IF p[s.wtWd[wd]].b THEN FOR byte: CARDINAL IN [0..4) DO FOR bit: CARDINAL IN [0..8) DO s.bytes[(wd*4+byte) MOD 16][bit] _ p[ s.ipData[byte*8+bit] ].l ENDLOOP ENDLOOP ENDLOOP; FOR row: CARDINAL IN [0..16) DO IF p[s.rdByte[row]].b THEN {cntRd _ cntRd + 1; lastRd _ row} ENDLOOP; FOR bit: CARDINAL IN [0..8) DO p[s.op [bit] ].d _ p[s.alpha [bit] ].d _ p[s.beta [bit] ].d _ p[s.gamma [bit] ].d _ p[s.delta [bit] ].d _ (IF cntRd=0 THEN none ELSE drive); SELECT cntRd FROM 0 => {}; 1 => { p[s.op [bit] ].l _ PullDown[(lastRd+0) MOD 16, bit, p[s.op [bit] ].l]; p[s.alpha [bit] ].l _ PullDown[(lastRd+1) MOD 16, bit, p[s.alpha [bit] ].l]; p[s.beta [bit] ].l _ PullDown[(lastRd+2) MOD 16, bit, p[s.beta [bit] ].l]; p[s.gamma [bit] ].l _ PullDown[(lastRd+3) MOD 16, bit, p[s.gamma [bit] ].l]; p[s.delta [bit] ].l _ PullDown[(lastRd+4) MOD 16, bit, p[s.delta [bit] ].l]}; ENDCASE => { p[s.op [bit] ].l _ p[s.alpha [bit] ].l _ p[s.beta [bit] ].l _ p[s.gamma [bit] ].l _ p[s.delta [bit] ].l _ X}; ENDLOOP}; END.