| /* |
| * Copyright (c) 2015-2017 Advanced Micro Devices, Inc. |
| * All rights reserved. |
| * |
| * For use for simulation and test purposes only |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2. 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. |
| * |
| * 3. Neither the name of the copyright holder 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 HOLDER 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. |
| */ |
| |
| #ifndef __REGISTER_FILE_HH__ |
| #define __REGISTER_FILE_HH__ |
| |
| #include <limits> |
| #include <vector> |
| |
| #include "base/statistics.hh" |
| #include "base/types.hh" |
| #include "gpu-compute/misc.hh" |
| #include "sim/sim_object.hh" |
| |
| namespace gem5 |
| { |
| |
| class ComputeUnit; |
| class Shader; |
| class PoolManager; |
| class Wavefront; |
| |
| struct RegisterFileParams; |
| |
| // Abstract Register File |
| // This register file class can be inherited from to create both |
| // scalar and vector register files. |
| class RegisterFile : public SimObject |
| { |
| public: |
| RegisterFile(const RegisterFileParams &p); |
| virtual ~RegisterFile(); |
| virtual void setParent(ComputeUnit *_computeUnit); |
| int numRegs() const { return _numRegs; } |
| |
| // State functions |
| |
| // Scoreboard functions |
| virtual bool operandsReady(Wavefront *w, GPUDynInstPtr ii) const; |
| virtual bool regBusy(int idx) const; |
| virtual void markReg(int regIdx, bool value); |
| |
| // Abstract Register Event |
| class RegisterEvent : public Event |
| { |
| protected: |
| RegisterFile *rf; |
| int regIdx; |
| |
| public: |
| RegisterEvent(RegisterFile *_rf, int _regIdx) |
| : rf(_rf), regIdx(_regIdx) { setFlags(AutoDelete); } |
| }; |
| |
| // Register Event to mark a register as free in the scoreboard/busy vector |
| class MarkRegFreeScbEvent : public RegisterEvent |
| { |
| public: |
| MarkRegFreeScbEvent(RegisterFile *_rf, int _regIdx) |
| : RegisterEvent(_rf, _regIdx) { } |
| void process(); |
| }; |
| |
| // Register Event to mark a register as busy in the scoreboard/busy vector |
| class MarkRegBusyScbEvent : public RegisterEvent |
| { |
| public: |
| MarkRegBusyScbEvent(RegisterFile *_rf, int _regIdx) |
| : RegisterEvent(_rf, _regIdx) { } |
| void process(); |
| }; |
| |
| // Schedule an event to mark a register as free/busy in |
| // the scoreboard/busy vector. Delay is already in Ticks |
| virtual void enqRegFreeEvent(uint32_t regIdx, uint64_t delay); |
| virtual void enqRegBusyEvent(uint32_t regIdx, uint64_t delay); |
| |
| // Schedule functions |
| |
| // The following functions are called by the SCH stage when attempting |
| // to move a wave from the readyList to the schList. |
| // canSchedule* checks if the RF is ready to provide operands for |
| // the instruction, while schedule* requests the RF to begin reading |
| // and writing of operands. Calling schedule* may only occur |
| // immediately after canSchedule* was called and returned True |
| virtual bool canScheduleReadOperands(Wavefront *w, GPUDynInstPtr ii); |
| virtual bool canScheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii); |
| virtual void scheduleReadOperands(Wavefront *w, GPUDynInstPtr ii); |
| virtual void scheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii); |
| |
| // The following function is called to check if all operands |
| // have been read for the given instruction |
| virtual bool operandReadComplete(Wavefront *w, GPUDynInstPtr ii); |
| |
| // The following two functions are only called by returning loads to |
| // check if the register file can support the incoming writes |
| virtual bool canScheduleWriteOperandsFromLoad(Wavefront *w, |
| GPUDynInstPtr ii); |
| // Queue the register writes. Assumes canScheduleWriteOperandsFromLoad |
| // was called immediately prior and returned True |
| virtual void scheduleWriteOperandsFromLoad(Wavefront *w, |
| GPUDynInstPtr ii); |
| |
| // ExecRF is invoked every cycle by the compute unit and may be |
| // used to model detailed timing of the register file. |
| virtual void exec(); |
| |
| // Called to inform RF that an instruction is executing |
| // to schedule events for writeback, etc., as needed |
| virtual void waveExecuteInst(Wavefront *w, GPUDynInstPtr ii); |
| |
| // Debug functions |
| virtual std::string dump() const; |
| |
| virtual void dispatchInstruction(GPUDynInstPtr ii); |
| |
| protected: |
| ComputeUnit* computeUnit; |
| int simdId; |
| |
| // flag indicating if a register is busy |
| std::vector<bool> busy; |
| |
| // numer of registers in this register file |
| int _numRegs; |
| |
| struct RegisterFileStats : public statistics::Group |
| { |
| RegisterFileStats(statistics::Group *parent); |
| |
| // Total number of register reads per DWORD per thread |
| statistics::Scalar registerReads; |
| // Total number of register writes per DWORD per thread |
| statistics::Scalar registerWrites; |
| |
| // Number of register file SRAM activations for reads. |
| // The register file may be implemented with multiple SRAMs. This stat |
| // tracks how many times the SRAMs are accessed for reads. |
| statistics::Scalar sramReads; |
| // Number of register file SRAM activations for writes |
| statistics::Scalar sramWrites; |
| } stats; |
| }; |
| |
| } // namespace gem5 |
| |
| #endif // __REGISTER_FILE_HH__ |