iurt_lib.vhd
来自「ERC32 经典的sparc v7 cpu」· VHDL 代码 · 共 1,551 行 · 第 1/5 页
VHD
1,551 行
TrapVector(RESTART_IMPRECISE) := TRUE; DPARviol := FALSE; end if; if FIPARviol then TrapVector(NON_RESTART_IMPRECISE) := TRUE; FIPARviol := FALSE; end if; end if; if ParBitViolCount >= 0 and EX.Mnemo /= IOP then ParBitViolCount := ParBitViolCount - 1; end if; if (FIPAR /= OddParityOf(FEXC_N & FCC & FCCVvar & FHOLD_Nvar) and FIPAR /= 'Z' and FEXC_N /= 'Z' and FCC /= "ZZ" and FCCVvar /= 'Z' and FHOLD_Nvar /= 'Z' and ParBitViolCount = -1) then ParBitViolCount := 2; FIPARviol := TRUE; end if; if DPAR /= OddParityOf(D) and DPAR /= 'Z' and D /= TRI_STATE32 and ParBitViolCount = -1 and not(WR.Mnemo = LDFSR or WR.Mnemo = LDF or WR.Mnemo = LDDF or WR1.Mnemo = LDDF or IsStoreInst(WR.Mnemo) or IsStoreInst(WR1.Mnemo) or IsStoreDoubleInst(WR2.Mnemo) or WR1.Mnemo = LDSTUB or WR1.Mnemo = LDSTUBA or WR2.Mnemo = LDSTUB or WR2.Mnemo = LDSTUBA or WR1.Mnemo = SWAP or WR1.Mnemo = SWAPA or WR2.Mnemo = SWAP or WR2.Mnemo = SWAPA ) then ParBitViolCount := 2; DPARviol := TRUE; end if; end if; --...................... TRAPS .................................. TrapHandler(EX, WR, WR1, WR2, pIRLvar, IRLvar, TBR, PSR, TrapVector, Mode, TrapMode, pPrevAddr, PrevAddr, CurrentAddr, RegFile); if Mode = ERROR_MODE then -- This "if" is for a spec. bug fix! Mode := EXECUTE_MODE; PendingERROR := TRUE; elsif PendingERROR then PendingERROR := FALSE; Mode := ERROR_MODE; TrigERRcountdown := 2; end if; if TrapVector(DETECTED_TRAP) then if tt = TrapTypeTable(FP_EXCEPTION) then TriggerFXACK := TRUE; end if; TriggerFLUSH := TRUE;------------------------------------------------------------------------ Moved generation of INTACK one clock forward (bug in spec!)-- Jiri Gaisler, 30-01-96 TriggerINTACK := TRUE; -- Flag for INTACK signal---------------------------------------------------------------------- -- Reset trap vector to FALSE: the trap has been serviced in -- TrapHandler. TrapVector := (others => FALSE); pTOpSizeVar := pSizeVar; pSizeVar := SizeVar; pTOpASIvar := pASIvar; pASIvar := ASIvar; -- Disable next checksum comparison for PFC. ChecksumCompare := FALSE; else --......... Actions related to Instruction Fetch cycle ............ -- '''''''' conditional fetch. '''''''''' nIDisValid := FALSE; if not(ID.Annul) then if INSTvar = '1' then nID := Transcribe(D); -- Fetches the bus only if it is an -- instr. nID.Address := PrevAddr; -- Address of the instr. in nID. -- NextAddress of instr. in nID will be loaded later in the -- pipeline. See parts "Nominal increment of address" and -- "pipeline progression". nIDisValid := TRUE; -- following the one that is -- in nID. end if; else -- No fetching if delay slot inst. is annulled. Note: -- in this case, ID.Mnemo MUST BE a branching instruction. nID.Mnemo := ANNULLED; nID.Annul := FALSE; nID.Address := PrevAddr; -- here dequeue from InstBuf. the delay slot instruction if any. if Buf1IsValid then GetFromBufferQueue(Buf1IsValid, InstBuffer1, Buf2IsValid, InstBuffer2, nIDTemp); -- nIDTemp is annulled in this -- case: nothing is done with it. if Buf2IsValid then -- for debugging purposes assert FALSE report "(IURTGen architecture): error in VHDL " & "model; the FIFO should be EMPTY!!!" severity error; end if; end if; end if; --'''''' IOP scheduling. WARNING: DELICATE mechanism here!!!''''''' IOPscheduling(InstBuffer1, nID, ID, EX, WR, IOPcase); -- IOPcase flag is used in next IF. if IOPcase then if nIDisValid then PutInBufferQueue(nID, Buf1IsValid, InstBuffer1, Buf2IsValid, InstBuffer2); end if; nID.Mnemo := IOP; nID.Address := ID.Address; -- This is used for of memory -- exception: MEXC_N (not clear). else if Buf1IsValid then GetFromBufferQueue(Buf1IsValid, InstBuffer1, Buf2IsValid, InstBuffer2, nIDTemp); if nIDisValid then PutInBufferQueue(nID, Buf1IsValid, InstBuffer1, Buf2IsValid, InstBuffer2); end if; nID := nIDTemp; end if; end if; -- '''''''' Assignment of field NextAddress of ID + '''''''''' -- '''''''' Nominal increment of CurrentAddr '''''''''' -- '''''''' + ASI assignment '''''''''' -- Address of inst. following the inst. that is in EX -- in next cycle: NextAddressForTraps is used in part -- pipeline progression for EX. NextAddressForTraps := PrevAddr; pPrevAddr := PrevAddr; PrevAddr := CurrentAddr; CurrentAddr := CurrentAddr + 4; pTOpSizeVar := pSizeVar; pSizeVar := SizeVar; -- SizeVar is modified when data xfer, if any. pTOpASIvar := pASIvar; pASIvar := ASIvar; if ( not(IsLoadDoubleInst(EX.Mnemo)) and not(IsStoreInst(EX.Mnemo)) and not(IsStoreDoubleInst(WR.Mnemo)) and EX.Mnemo /= LDSTUB and EX.Mnemo /= LDSTUBA and WR.Mnemo /= LDSTUB and WR.Mnemo /= LDSTUBA and EX.Mnemo /= SWAP and EX.Mnemo /= SWAPA and WR.Mnemo /= SWAP and WR.Mnemo /= SWAPA and EX.Mnemo /= WRPSR and not((ID.Mnemo = JMPL or EX.Mnemo = JMPL) and InstBuffer1.Mnemo = RETT) and not(WR.Mnemo = JMPL and ID.Mnemo = RETT) ) then if S = '0' then ASIvar := USER_INST; elsif S = '1' then ASIvar := SUPERVISOR_INST; else ASIvar := 0; assert FALSE report "(IURTGen architecture): unknown value " & "for S bit!" severity warning; end if; end if; -- particular case for ASI generation if (ID.Mnemo = JMPL and InstBuffer1.Mnemo = RETT) then if PS = '1' then ASIvar := SUPERVISOR_INST; elsif PS = '0' then ASIvar := USER_INST; end if; end if; --+++++++++++++++++++++++++++++++++++++++++++ -- Addr. remains unchanged when EX=JMPL and an IOP is scheduled or -- when WR=load and ID=IOP i.e LDsingle w/ dep.or -- when (WR1.Mnemo=LDdouble) i.e LDdouble w/ dep. or -- when EX=CALL and ID=IOP i.e CALL w/ dep.or -- when EX=storeInst or -- when EX=loadstoreORswap inst. or -- when WR=loadstoreORswap inst. if ( (EX.Mnemo = JMPL and IOPcase) or (IsLoadSingleInst(WR.Mnemo) and ID.Mnemo = IOP) or (IsLoadDoubleInst(WR1.Mnemo) and ID.Mnemo = IOP) or (EX.Mnemo = CALL and ID.Mnemo = IOP) or IsStoreInst(EX.Mnemo) or (EX.Mnemo = LDSTUB or EX.Mnemo = LDSTUBA) or (EX.Mnemo = SWAP or EX.Mnemo = SWAPA) or (WR.Mnemo = LDSTUB or WR.Mnemo = LDSTUBA) or (WR.Mnemo = SWAP or WR.Mnemo = SWAPA) ) then CurrentAddr := PrevAddr; end if; --+++++++++++++++++++++++++++++++++++++++++++ -- ''''''' OPcc "anticipated" execution. ''''''''' if IsOPcc(ID.Mnemo) then ExecuteOPcc(ID, RegFile, CWP, icc, Y, ResultOPcc, iccTemp, YTemp); end if; SA1CurrentAddr := CurrentAddr; -- ''''''''' Bicc, FBicc "anticipated" execution. ''''''''''' -- ''''''''' CBicc are not implemented. '''''''''''' if IsBicc(nID.Mnemo) then ExecuteBicc(iccTemp, icc, nID, CurrentAddr, TakenBr); end if; if (IsFBfcc(nID.Mnemo) and FP_N = '0' and EF = '1' and not(IsFCMP(EX.Mnemo)) ) then -- if trap condition (FP_N=1 or EF=0), does nothing here. ExecuteFBfcc(FCC, nID, CurrentAddr, TakenBr); end if; -- '''''''''' Instruction CALL "anticipated" execution. ''''''''''' -- '''''''''' Address calculation. ''''''''''''' if nID.Mnemo = CALL then CurrentAddr := nID.Address + (nID.disp30 & "00"); end if; -- DO NOT FORGET the paranthesis in the line above!!! --......... Actions related to Instruction Decode cycle ........... -- '''''''' Load case: data address generation. ''''''' if IsLoadInst(ID.Mnemo) then SaveCurrentAddr := CurrentAddr; -- Save current address. Preserve_SavePrevAddr := SavePrevAddr; SavePrevAddr := PrevAddr; -- Save previous address. if S = '0' then ASIvar := USER_DATA; else ASIvar := SUPERVISOR_DATA; end if; if IsLoadInstASI(ID.Mnemo) then ASIvar := ID.asi; end if; if IsLoadByteInst(ID.Mnemo) then SizeVar := BYTE; elsif IsLoadHalfwordInst(ID.Mnemo) then SizeVar := HALFWORD; elsif IsLoadDoubleInst(ID.Mnemo) then SizeVar := DOUBLEWORD; else SizeVar := WORDTYPE; end if; CurrentAddr := LoadORStoreORSwapAddrCalc(ID, CWP, RegFile); LoadDataAddr := CurrentAddr; LDdataAD1 := CurrentAddr; end if; if IsLoadDoubleInst(EX.Mnemo) then LoadDataAddr := LoadDataAddr + 4; end if; if (IsLoadSingleInst(EX.Mnemo) or (IsLoadDoubleInst(WR.Mnemo) and EX.Mnemo /= ANNULLED) ) then if ( not((IsBicc(nID.Mnemo) or IsFBfcc(nID.Mnemo)) and TakenBr) and nID.Mnemo /= CALL ) then CurrentAddr := SaveCurrentAddr; -- Restore values of instruction -- address unless nID=Bicc or -- nID=FBfcc or nID=CALL end if; if S = '0' then ASIvar := USER_INST; else ASIvar := SUPERVISOR_INST; end if; SizeVar := WORDTYPE; end if; -- '''''''' Store case: data address generation. ''''''' if IsStoreInst(ID.Mnemo) then SaveCurrentAddr := CurrentAddr; Preserve_SavePrevAddr := SavePrevAddr; SavePrevAddr := PrevAddr; if S = '0' then ASIvar := USER_DATA; else ASIvar := SUPERVISOR_DATA; end if; if IsStoreInstASI(ID.Mnemo) then ASIvar := ID.asi; end if;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?