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 + -
显示快捷键?