Files
gem5/src/cpu/o3/decode.hh
Korey Sewell 19ca97af79 This changeset gets the MIPS ISA pretty much working in the O3CPU. It builds, runs, and gets very very close to completing the hello world
succesfully but there are some minor quirks to iron out. Who would've known a DELAY SLOT introduces that much complexity?! arrgh!

Anyways, a lot of this stuff had to do with my project at MIPS and me needing to know how I was going to get this working for the MIPS
ISA. So I figured I would try to touch it up and throw it in here (I hate to introduce non-completely working components... )

src/arch/alpha/isa/mem.isa:
    spacing
src/arch/mips/faults.cc:
src/arch/mips/faults.hh:
    Gabe really authored this
src/arch/mips/isa/decoder.isa:
    add StoreConditional Flag to instruction
src/arch/mips/isa/formats/basic.isa:
    Steven really did this file
src/arch/mips/isa/formats/branch.isa:
    fix bug for uncond/cond control
src/arch/mips/isa/formats/mem.isa:
    Adjust O3CPU memory access to use new memory model interface.
src/arch/mips/isa/formats/util.isa:
    update LoadStoreBase template
src/arch/mips/isa_traits.cc:
    update SERIALIZE partially
src/arch/mips/process.cc:
src/arch/mips/process.hh:
    no need for this for NOW. ASID/Virtual addressing handles it
src/arch/mips/regfile/misc_regfile.hh:
    add in clear() function and comments for future usage of special misc. regs
src/cpu/base_dyn_inst.hh:
    add in nextNPC variable and supporting functions.

    add isCondDelaySlot function

    Update predTaken and mispredicted functions
src/cpu/base_dyn_inst_impl.hh:
    init nextNPC
src/cpu/o3/SConscript:
    add MIPS files to compile
src/cpu/o3/alpha/thread_context.hh:
    no need for my name on this file
src/cpu/o3/bpred_unit_impl.hh:
    Update RAS appropriately for MIPS
src/cpu/o3/comm.hh:
    add some extra communication variables to aid in handling the
    delay slots
src/cpu/o3/commit.hh:
    minor name fix for nextNPC functions.
src/cpu/o3/commit_impl.hh:
src/cpu/o3/decode_impl.hh:
src/cpu/o3/fetch_impl.hh:
src/cpu/o3/iew_impl.hh:
src/cpu/o3/inst_queue_impl.hh:
src/cpu/o3/rename_impl.hh:
    Fix necessary variables and functions for squashes with delay slots
src/cpu/o3/cpu.cc:
    Update function interface ...

    adjust removeInstsNotInROB function to recognize delay slots insts
src/cpu/o3/cpu.hh:
    update removeInstsNotInROB
src/cpu/o3/decode.hh:
    declare necessary variables for handling delay slot
src/cpu/o3/dyn_inst.hh:
    Add in MipsDynInst
src/cpu/o3/fetch.hh:
src/cpu/o3/iew.hh:
src/cpu/o3/rename.hh:
    declare necessary variables and adjust functions for handling delay slot
src/cpu/o3/inst_queue.hh:
src/cpu/simple/base.cc:
    no need for my name here
src/cpu/o3/isa_specific.hh:
    add in MIPS files
src/cpu/o3/scoreboard.hh:
    dont include alpha specific isa traits!
src/cpu/o3/thread_context.hh:
    no need for my name here, i just rearranged where the file goes
src/cpu/static_inst.hh:
    add isCondDelaySlot function
src/cpu/o3/mips/cpu.cc:
src/cpu/o3/mips/cpu.hh:
src/cpu/o3/mips/cpu_builder.cc:
src/cpu/o3/mips/cpu_impl.hh:
src/cpu/o3/mips/dyn_inst.cc:
src/cpu/o3/mips/dyn_inst.hh:
src/cpu/o3/mips/dyn_inst_impl.hh:
src/cpu/o3/mips/impl.hh:
src/cpu/o3/mips/params.hh:
src/cpu/o3/mips/thread_context.cc:
src/cpu/o3/mips/thread_context.hh:
    MIPS file for O3CPU...mirrors ALPHA definition

--HG--
extra : convert_revision : 9bb199b4085903e49ffd5a4c8ac44d11460d988c
2006-07-23 13:39:42 -04:00

317 lines
10 KiB
C++

/*
* Copyright (c) 2004-2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Kevin Lim
*/
#ifndef __CPU_O3_DECODE_HH__
#define __CPU_O3_DECODE_HH__
#include <queue>
#include "base/statistics.hh"
#include "base/timebuf.hh"
/**
* DefaultDecode class handles both single threaded and SMT
* decode. Its width is specified by the parameters; each cycles it
* tries to decode that many instructions. Because instructions are
* actually decoded when the StaticInst is created, this stage does
* not do much other than check any PC-relative branches.
*/
template<class Impl>
class DefaultDecode
{
private:
// Typedefs from the Impl.
typedef typename Impl::O3CPU O3CPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::Params Params;
typedef typename Impl::CPUPol CPUPol;
// Typedefs from the CPU policy.
typedef typename CPUPol::FetchStruct FetchStruct;
typedef typename CPUPol::DecodeStruct DecodeStruct;
typedef typename CPUPol::TimeStruct TimeStruct;
public:
/** Overall decode stage status. Used to determine if the CPU can
* deschedule itself due to a lack of activity.
*/
enum DecodeStatus {
Active,
Inactive
};
/** Individual thread status. */
enum ThreadStatus {
Running,
Idle,
StartSquash,
Squashing,
Blocked,
Unblocking
};
private:
/** Decode status. */
DecodeStatus _status;
/** Per-thread status. */
ThreadStatus decodeStatus[Impl::MaxThreads];
public:
/** DefaultDecode constructor. */
DefaultDecode(Params *params);
/** Returns the name of decode. */
std::string name() const;
/** Registers statistics. */
void regStats();
/** Sets CPU pointer. */
void setCPU(O3CPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
/** Sets pointer to time buffer used to communicate to the next stage. */
void setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr);
/** Sets pointer to time buffer coming from fetch. */
void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
/** Sets pointer to list of active threads. */
void setActiveThreads(std::list<unsigned> *at_ptr);
/** Drains the decode stage. */
bool drain();
/** Resumes execution after a drain. */
void resume() { }
/** Switches out the decode stage. */
void switchOut() { }
/** Takes over from another CPU's thread. */
void takeOverFrom();
/** Ticks decode, processing all input signals and decoding as many
* instructions as possible.
*/
void tick();
/** Determines what to do based on decode's current status.
* @param status_change decode() sets this variable if there was a status
* change (ie switching from from blocking to unblocking).
* @param tid Thread id to decode instructions from.
*/
void decode(bool &status_change, unsigned tid);
/** Processes instructions from fetch and passes them on to rename.
* Decoding of instructions actually happens when they are created in
* fetch, so this function mostly checks if PC-relative branches are
* correct.
*/
void decodeInsts(unsigned tid);
private:
/** Inserts a thread's instructions into the skid buffer, to be decoded
* once decode unblocks.
*/
void skidInsert(unsigned tid);
/** Returns if all of the skid buffers are empty. */
bool skidsEmpty();
/** Updates overall decode status based on all of the threads' statuses. */
void updateStatus();
/** Separates instructions from fetch into individual lists of instructions
* sorted by thread.
*/
void sortInsts();
/** Reads all stall signals from the backwards communication timebuffer. */
void readStallSignals(unsigned tid);
/** Checks all input signals and updates decode's status appropriately. */
bool checkSignalsAndUpdate(unsigned tid);
/** Checks all stall signals, and returns if any are true. */
bool checkStall(unsigned tid) const;
/** Returns if there any instructions from fetch on this cycle. */
inline bool fetchInstsValid();
/** Switches decode to blocking, and signals back that decode has
* become blocked.
* @return Returns true if there is a status change.
*/
bool block(unsigned tid);
/** Switches decode to unblocking if the skid buffer is empty, and
* signals back that decode has unblocked.
* @return Returns true if there is a status change.
*/
bool unblock(unsigned tid);
/** Squashes if there is a PC-relative branch that was predicted
* incorrectly. Sends squash information back to fetch.
*/
void squash(DynInstPtr &inst, unsigned tid);
public:
/** Squashes due to commit signalling a squash. Changes status to
* squashing and clears block/unblock signals as needed.
*/
unsigned squash(unsigned tid);
private:
// Interfaces to objects outside of decode.
/** CPU interface. */
O3CPU *cpu;
/** Time buffer interface. */
TimeBuffer<TimeStruct> *timeBuffer;
/** Wire to get rename's output from backwards time buffer. */
typename TimeBuffer<TimeStruct>::wire fromRename;
/** Wire to get iew's information from backwards time buffer. */
typename TimeBuffer<TimeStruct>::wire fromIEW;
/** Wire to get commit's information from backwards time buffer. */
typename TimeBuffer<TimeStruct>::wire fromCommit;
/** Wire to write information heading to previous stages. */
// Might not be the best name as not only fetch will read it.
typename TimeBuffer<TimeStruct>::wire toFetch;
/** Decode instruction queue. */
TimeBuffer<DecodeStruct> *decodeQueue;
/** Wire used to write any information heading to rename. */
typename TimeBuffer<DecodeStruct>::wire toRename;
/** Fetch instruction queue interface. */
TimeBuffer<FetchStruct> *fetchQueue;
/** Wire to get fetch's output from fetch queue. */
typename TimeBuffer<FetchStruct>::wire fromFetch;
/** Queue of all instructions coming from fetch this cycle. */
std::queue<DynInstPtr> insts[Impl::MaxThreads];
/** Skid buffer between fetch and decode. */
std::queue<DynInstPtr> skidBuffer[Impl::MaxThreads];
/** Variable that tracks if decode has written to the time buffer this
* cycle. Used to tell CPU if there is activity this cycle.
*/
bool wroteToTimeBuffer;
/** Source of possible stalls. */
struct Stalls {
bool rename;
bool iew;
bool commit;
};
/** Tracks which stages are telling decode to stall. */
Stalls stalls[Impl::MaxThreads];
/** Rename to decode delay, in ticks. */
unsigned renameToDecodeDelay;
/** IEW to decode delay, in ticks. */
unsigned iewToDecodeDelay;
/** Commit to decode delay, in ticks. */
unsigned commitToDecodeDelay;
/** Fetch to decode delay, in ticks. */
unsigned fetchToDecodeDelay;
/** The width of decode, in instructions. */
unsigned decodeWidth;
/** Index of instructions being sent to rename. */
unsigned toRenameIndex;
/** number of Active Threads*/
unsigned numThreads;
/** List of active thread ids */
std::list<unsigned> *activeThreads;
/** Number of branches in flight. */
unsigned branchCount[Impl::MaxThreads];
/** Maximum size of the skid buffer. */
unsigned skidBufferMax;
/** SeqNum of Squashing Branch Delay Instruction (used for MIPS)*/
Addr bdelayDoneSeqNum[Impl::MaxThreads];
/** Instruction used for squashing branch (used for MIPS)*/
DynInstPtr squashInst[Impl::MaxThreads];
/** Tells when their is a pending delay slot inst. to send
* to rename. If there is, then wait squash after the next
* instruction (used for MIPS).
*/
bool squashAfterDelaySlot[Impl::MaxThreads];
/** Stat for total number of idle cycles. */
Stats::Scalar<> decodeIdleCycles;
/** Stat for total number of blocked cycles. */
Stats::Scalar<> decodeBlockedCycles;
/** Stat for total number of normal running cycles. */
Stats::Scalar<> decodeRunCycles;
/** Stat for total number of unblocking cycles. */
Stats::Scalar<> decodeUnblockCycles;
/** Stat for total number of squashing cycles. */
Stats::Scalar<> decodeSquashCycles;
/** Stat for number of times a branch is resolved at decode. */
Stats::Scalar<> decodeBranchResolved;
/** Stat for number of times a branch mispredict is detected. */
Stats::Scalar<> decodeBranchMispred;
/** Stat for number of times decode detected a non-control instruction
* incorrectly predicted as a branch.
*/
Stats::Scalar<> decodeControlMispred;
/** Stat for total number of decoded instructions. */
Stats::Scalar<> decodeDecodedInsts;
/** Stat for total number of squashed instructions. */
Stats::Scalar<> decodeSquashedInsts;
};
#endif // __CPU_O3_DECODE_HH__