DIRECTORY CacheMicroMachine; CacheMicroCodeA: CEDAR PROGRAM IMPORTS CacheMicroMachine = BEGIN OPEN CacheMicroMachine; LogicBlock["MCtlCAMCtl"]; NewDecode[A, $MDataIToMatchReg]; -- causes MDataToMatch. NewDecode[A, $GetAdrRefresh]; -- (MCtlEntryCtl) same as GetAddress. NewDecode[A, $GetAddress]; -- (MCtlEntryCtl) causes the command on GetAdrCmd to be interpreted and the resulting address to be loaded into the access register: NewDecode[B, $PageAccessToMDataI]; -- causes the access register to be driven onto MDataI[0..23]. NewDecode[B, $LowBitsAccessToMDataI]; -- causes the access register to be driven onto MDataI[24..29] and PAdrLow and PAdrHigh to be driven onto MDataI[31] and MDataI[30] respectively. NewDecode[B, $LowBitsZeroToMDataI]; -- causes the access register to be driven onto MDataI[24..29] and zero to be driven onto MDataI[30..31]. NewDecode[A, $AccessToMatch]; -- causes the match register to be loaded from the access register. NewDecode[A, $MatchToAccess]; -- causes the access register to be loaded from the match register. NewDecode[A, $VirtualAddressToAccess]; -- causes the access register to be loaded from the virtual match lines. NewDecode[A, $DriveCAMAccess]; -- causes the CAM page and block access lines to be driven from the access register. LogicBlock["MCtlRAMCtl"]; NewDecode[A, $MDataIToMRAMReg]; -- causes SenseMDataI. NewDecode[A, $MBitsToMRAMReg]; -- causes SenseMBits. It is possible that this line and the next could be turned into one decode. NewDecode[A, $MRAMRegToMDataI]; -- causes MRamRegToMDataI. NewDecode[A, $MRAMRegToMBits]; -- causes MBitsDrive. NewDecode[A, $MRAMRegToMBitsNoOrphan]; -- causes MBitsDrive if there is no orphan. NewDecode[B, $PBitsToMRAMReg]; -- puts the PBits selected by PAdrHigh into the MRamReg. NewDecode[B, $LeftPBitsToMRAMReg]; -- puts the left PBits into the MRamReg. NewDecode[A, $MRAMRegToPBits]; -- causes PBits to be driven by the contents of MRAMReg during the following PhB. LogicBlock["MCtlFlagCtl"]; NewDecode[A, $SetShared]; -- sets the shared flag bit line. NewDecode[A, $RPDirtyVPValid]; -- causes the RPDirty and VPValid bits sampled from MData to be driven onto the flag access lines. NewDecode[A, $FlagLatch]; -- latch the flag bits from MDataI. NewDecode[A, $ResetVPValid]; -- causes the vpvalid access lines to put a zero into the selected vpvalid bit. NewDecode[A, $SetFlags]; -- causes VPValid to be set, RPValid to be set, RPDirty to be set from IsClean, Master to be reset, Shared to be set from the latch written by SenseShared, TIP to be reset, and Victim and Broken to be refreshed. NewDecode[A, $SetTIP]; -- sets the TIP flag bit selected. NewDecode[A, $ResetTIP]; -- resets the TIP flag bit selected. NewDecode[A, $ResetMaster]; -- resets the master flag bit selected. LogicBlock["MCtlEntryCtl"]; NewDecode[A, $MDataIToMAdrCtr]; -- causes the two low order bits of the address to be loaded into the address counter. NewDecode[BA, $GetAddress]; -- (MCtlCAMCtl) assembles an address. NewDecode[BA, $GetAdrRefresh]; -- (MCtlCAMCtl) assembles an address or does a refresh cycle. NewDecode[BA, $Refresh]; -- does a refresh cycle. NewDecode[BA, $MAdrCtrToMAdr]; -- causes the bits in the address counter to be applied to MAdrHigh and MAdrLow. NewDecode[B, $IncMAdrCtr]; -- causes the bits in the incremented address counter to be applied to MAdrHigh and MAdrLow. NewDecode[B, $ZeroMAdrCtr]; -- causes the bits in the address counter to be zeroed and applied to MAdrHigh and MAdrLow. NewDecode[B, $PAdrToMAdrCtr]; -- causes address counter to be loaded from the address bits supplied by the P controller. NewDecode[B, $LowBitsAccessToMDataI]; -- causes the address counter to be driven onto MDataI[30..31]. NewDecode[A, $SelRealData]; -- causes the cell matching the page and block match registers to be selected. NewDecode[A, $SelPageFlag]; -- causes the RPDirty and VPValid bits of the entries which match the page match register to be selected. NewDecode[A, $SelVictimData]; -- causes the cell with the victim bit to select a data word and its flag bits. NewDecode[A, $SelectVictimOrOrphan]; -- causes SelVictimData if there is no orphan, otherwise SelRealData. If GetAddress is not present then SelVictimAdr and SelRealAdr are selected similiarly. NewDecode[B, $VirtualAccess]; -- forces the appropriate select line to do its thing so that only the virtual page and block bits are selected. NewDecode[B, $nVirtualAccess]; -- forces the appropriate select line to do its thing so that only the real page is selected. NewDecode[BA, $ShiftVictim]; -- causes the victim shift register to advance one entry. NewDecode[BA, $FinishSharedStore]; -- causes a store into a shared entry to complete. LogicBlock["MCtlSequencer"]; NewDecode[B, $SampleRealMatch]; -- causes the nRealMatch line to be sampled. NewDecode[A, $MDataIToFaults]; -- causes the three low order bits of the data bus to be loaded into the fault type register. NewDecode[C, $MDataToMDataI]; -- causes MData to be driven onto MDataI. NewDecode[C, $DriveShared]; -- enables MNShared to be driven low if some cell matched on the block address. NewDecode[B, $PrechargeMNShared]; -- causes MNShared to be precharged. Note that this happens for only half a cycle. Also note that everything hanging on the MBus precharges this line so that should not be any problem. NewDecode[B, $MDataIToMData]; -- causes the pipeline in the pad data register to be bypassed so that the register loaded during PhB is loaded directly from MDataI. Every PhA the pad data register is loaded from MDataI. Every PhB the first stage register is moved into the second stage register. The thought is that the data will transfer to the actual pad enables at about the same time in every cache when doing a slave ReadQuad so that no set of caches are ever pulling in opposite directions on the bus. NewDecode[C, $DriveMData]; -- causes MData to be driven from the pad register if the RealMatch register is true or the cache is the bus master. NewDecode[AB, $DriveMDataDelayed]; -- enables DriveMData for the following cycle. NewDecode[C, $DriveMCmd]; -- causes MCmd to be driven from the command being output by the entry point sequencer. It was previously placed on MCmdOut, this line need only assert MCmdDrive. NewDecode[C, $DriveMCmdToDataTransport]; -- causes MCmd to be driven to DataTransport. NewDecode[C, $DriveMCmdToNoOp]; -- causes MCmd to be driven to NoOp. NewDecode[B, $CheckParity]; -- causes the check of the parity bit from MRAMReg to be latched. The error latch is set if the check is bad on the following PhA. NewDecode[AB, $DCheckParity]; -- causes a parity check during the following PhB instead of during the current PhB. NewDecode[A, $Done]; -- causes the cycle to be forced to zeros and a new set of sequence bits to be latched. NewDecode[AB, $ForceIdle]; -- causes the sequence to be forced to idle, i.e. lowest order bit. NewDecode[AB, $SuppressPSample]; -- causes the master sequencer to ignore the bits coming in from P. NewDecode[B, $MapBitsToMDataI]; -- causes the appropriate bits to get the correct map operation done to be placed on MDataI[24..31]. NewDecode[A, $ForceSlave]; -- causes slave to be sent in the state even though the cache is retaining the M bus. NewDecode[A, $CheckFaults]; -- causes the fault lines to P to be driven from the bits latched from MDataI and if there is a fault causes the entry point sequencer to go idle, i.e. forces MasterCmd to a noop. NewDecode[AB, $MDone]; -- causes MDone to be sent to the P controller if the entry point sequencer is idle. Note that NextCmd always occurs the cycle after MDone does. Consider enforcing this constraint in the microassembler or in the hardware by removing the NextCmd decode. NewDecode[B, $SetWantWS]; -- causes WantWriteSingle to be set if LatchShared is true and the P command is a store. NewDecode[A, $StopPipeNoReady]; -- causes the write quad pipe to stop if not ready by suppressing address counter increment and data pad pipe transfer during the following PhB. NewDecode[A, $SenseReady]; -- causes the state machine to feedback the same state for the following cycle if MReady was false during this cycles PhA. NewDecode[BA, $ReleaseMBus]; -- causes the request to go away during the PhB that this is decoded if the entry point sequencer has NoOp as its output. This must always be followed by a cycle with Done in it since the grant may change and so the command sequence must terminate. Perhaps enforce that timing constraint in the microassembler. NewDecode[A, $SenseShared]; -- causes MShared to be sampled into a latch. END. p[Indigo]Cache>Rosemary>Cache.df=>CacheMicroCodeA.Mesa Last Edited by: Barth, May 31, 1984 5:18:41 pm PDT The first letter in each registration indicates the timing of the line. A => the decoder emits a pulse with timing identical to PhA. B => the decoder emits a pulse with timing identical to PhB. C => the decoder emits a pulse which starts on the rising edge of PhB and ends on the falling edge of PhA. BA => the decoder emits a level which changes on the rising edge of PhB. AB => the decoder emits a level which changes on the rising edge of PhA. Note that GetAdrRefresh and GetAddress have timing A in MCtlCAMCtl and timing BA in MCtlEntryCtl. The circuit for implementing a ROM of this type is sketched in CacheROM.sil. VictimReal => page and block access lines RefRealMap => page and block match register RefRealAssemble => page access lines and block virtual lines RefVirtual => page and block virtual lines If GetAddress or (GetAdrRefresh selected GetAddress) then causes the command on GetAdrCmd to be interpreted and the appropriate select lines to the cells to be asserted: VictimReal => not VirtualAccess, SelVictimAdr RefRealMap => none RefRealAssemble => not VirtualAccess, SelMapAdr RefVirtual => none If Refresh or (GetAdrRefresh selected Refresh) then causes SelCell. On cycles where both GetAddress and Refresh occur GetAddress has precedence unless the signal DoRefresh is asserted or the MasterCmd is a NoOp in which case Refresh wins. DoRefresh is driven by a counter which counts cycles since the last refresh, it is reset each time a refresh actually occurs. This means that a GetAddress may not have happened when a master is about to start, if this is the case then the cycle counter will be set to zero instead of one and $GetAddress should be asserted. If grant is seen during a PhA that Done is asserted and ForceSlave is not asserted then the cycle depends upon whether GetAddress was successful in loading the master commands address into the access register of the MCAMDriver. If it was then the cycle is set to 1 else it is set to 0. The sequence is forced to be whatever the entry point sequencer is saying it ought to be regardless of ForceIdle. When Done is asserted and ForceSlave is true and IOReadDone is seen then Master is combinatorially set true, the sequence is set back to whatever the entry point sequencer is set to and the cycle is set to 2. Κρ– "cedar" style˜Jšœ=™=Jšœ2™2J˜IcodešΟk œ˜K˜šΠbxœœ˜Kšœ˜—K˜Kšœœ˜K˜šœI™IKšœ<™˜aJšœ œŸ‘˜·Jšœ œŸi˜Jšœ œŸC˜aJšœ œŸC˜aJšœ œŸH˜oJšœ œŸT˜s—šœ˜Icedaršœ œŸ˜6Jšœ œŸb˜Jšœ œŸ˜:Jšœ œŸ˜4Jšœ œŸ+˜RJšœ œŸ8˜WJšœ œŸ(˜KJšœ œŸQ˜p—šœ˜Jšœ œŸ!˜;Jšœ œŸb˜Jšœ œŸ#˜=Jšœ œŸO˜lJšœ œŸΣ˜μJšœ œ Ÿ"˜9Jšœ œŸ$˜=Jšœ œŸ'˜C—šœ˜Jšœ œŸV˜vJšœ œŸœŸ˜AJšœ œŸ=˜\Jšœ œ Ÿ˜1šœͺ™ͺJšœ-™-Jšœ™Jšœ/™/Jšœ™—JšœΆ™ΆJšœ œŸP˜oJšœ œŸ\˜wJšœ œŸ[˜wJšœ œŸZ˜xJšœ œŸ?˜eJšœ œŸN˜jJšœ œŸi˜…Jšœ œŸO˜mJšœ œŸ˜ΒJšœ œŸp˜ŽJšœ œŸ]˜|Jšœ œŸ9˜WJšœ œŸ2˜V—šœ˜Jšœ œŸ,˜LJšœ œŸ]˜|Jšœ œŸ+˜IJšœ œŸO˜kJšœ œŸΊ˜άJšœ œŸί˜ύJšœ œŸt˜Jšœ œŸ.˜QJšœ œŸ£˜½Jšœ œŸ-˜VJšœ œŸ$˜DJšœ œŸƒ˜ŸJšœ œŸT˜ršœ œ ŸW˜lJšœ‘™‘JšŸœ"ŸœŸžœ™Π—Jšœ œŸC˜^Jšœ œŸC˜dJšœ œŸd˜„Jšœ œŸU˜pJšœ œŸ³˜ΟJšœ œ Ÿώ˜•Jšœ œŸX˜rJšœ œŸ˜°Jšœ œŸz˜•Jšœ œŸΈ˜ΥJšœ œŸ-˜I—K˜Kšœ˜—…—!/ρ