blob: eb6474cd219dbe97e146806e5ffcbc99169637ba [file] [log] [blame]
/*
* 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.
*
* Authors: John Kalamatianos,
* Mark Wyse
*/
#include "gpu-compute/register_file.hh"
#include <sstream>
#include <string>
#include "base/intmath.hh"
#include "base/logging.hh"
#include "debug/GPURF.hh"
#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_dyn_inst.hh"
#include "gpu-compute/shader.hh"
#include "gpu-compute/wavefront.hh"
#include "params/RegisterFile.hh"
RegisterFile::RegisterFile(const RegisterFileParams *p)
: SimObject(p), simdId(p->simd_id), _numRegs(p->num_regs)
{
fatal_if((_numRegs % 2) != 0, "VRF size is illegal\n");
fatal_if(simdId < 0, "Illegal SIMD id for VRF");
busy.clear();
busy.resize(_numRegs, 0);
}
RegisterFile::~RegisterFile()
{
}
void
RegisterFile::setParent(ComputeUnit *_computeUnit)
{
computeUnit = _computeUnit;
}
std::string
RegisterFile::dump() const
{
std::stringstream ss;
ss << "Busy: ";
for (int i = 0; i < busy.size(); i++) {
ss << (int)busy[i];
}
ss << "\n";
return ss.str();
}
// Scoreboard functions
bool
RegisterFile::operandsReady(Wavefront *w, GPUDynInstPtr ii) const
{
return true;
}
bool
RegisterFile::regBusy(int idx) const
{
return busy.at(idx);
}
void
RegisterFile::markReg(int regIdx, bool value)
{
DPRINTF(GPURF, "SIMD[%d] markReg(): physReg[%d] = %d\n",
simdId, regIdx, (int)value);
busy.at(regIdx) = value;
}
void
RegisterFile::enqRegFreeEvent(uint32_t regIdx, uint64_t delay)
{
DPRINTF(GPURF, "SIMD[%d] enqRegFreeEvent physReg[%d] at %llu\n",
simdId, regIdx, curTick() + delay);
schedule(new MarkRegFreeScbEvent(this, regIdx),
curTick() + delay);
}
void
RegisterFile::enqRegBusyEvent(uint32_t regIdx, uint64_t delay)
{
DPRINTF(GPURF, "SIMD[%d] enqRegBusyEvent physReg[%d] at %llu\n",
simdId, regIdx, curTick() + delay);
schedule(new MarkRegBusyScbEvent(this, regIdx),
curTick() + delay);
}
// Schedule functions
bool
RegisterFile::canScheduleReadOperands(Wavefront *w, GPUDynInstPtr ii)
{
return true;
}
void
RegisterFile::scheduleReadOperands(Wavefront *w, GPUDynInstPtr ii)
{
}
bool
RegisterFile::canScheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii)
{
return true;
}
void
RegisterFile::scheduleWriteOperands(Wavefront *w, GPUDynInstPtr ii)
{
}
bool
RegisterFile::canScheduleWriteOperandsFromLoad(Wavefront *w, GPUDynInstPtr ii)
{
return true;
}
void
RegisterFile::scheduleWriteOperandsFromLoad(Wavefront *w, GPUDynInstPtr ii)
{
}
bool
RegisterFile::operandReadComplete(Wavefront *w, GPUDynInstPtr ii)
{
return true;
}
// Exec functions
void
RegisterFile::exec()
{
}
void
RegisterFile::waveExecuteInst(Wavefront *w, GPUDynInstPtr ii)
{
}
RegisterFile*
RegisterFileParams::create()
{
return new RegisterFile(this);
}
// Events
// Mark a register as free in the scoreboard/busy vector
void
RegisterFile::MarkRegFreeScbEvent::process()
{
rf->markReg(regIdx, false);
}
// Mark a register as busy in the scoreboard/busy vector
void
RegisterFile::MarkRegBusyScbEvent::process()
{
rf->markReg(regIdx, true);
}
void
RegisterFile::dispatchInstruction(GPUDynInstPtr ii)
{
}
void
RegisterFile::regStats()
{
registerReads
.name(name() + ".register_reads")
.desc("Total number of DWORDs read from register file")
;
registerWrites
.name(name() + ".register_writes")
.desc("Total number of DWORDS written to register file")
;
sramReads
.name(name() + ".sram_reads")
.desc("Total number of register file bank SRAM activations for reads")
;
sramWrites
.name(name() + ".sram_writes")
.desc("Total number of register file bank SRAM activations for writes")
;
}