BankedArray.cc revision 9105
111986Sandreas.sandberg@arm.com
211986Sandreas.sandberg@arm.com
311986Sandreas.sandberg@arm.com#include <vector>
411986Sandreas.sandberg@arm.com
511986Sandreas.sandberg@arm.com#include "base/intmath.hh"
611986Sandreas.sandberg@arm.com#include "mem/ruby/common/TypeDefines.hh"
711986Sandreas.sandberg@arm.com#include "mem/ruby/system/BankedArray.hh"
811986Sandreas.sandberg@arm.com#include "sim/eventq.hh"
911986Sandreas.sandberg@arm.com
1011986Sandreas.sandberg@arm.comBankedArray::BankedArray(unsigned int banks, unsigned int accessLatency, unsigned int startIndexBit) :
1111986Sandreas.sandberg@arm.com    EventManager(&mainEventQueue)
1211986Sandreas.sandberg@arm.com{
1311986Sandreas.sandberg@arm.com    this->banks = banks;
1411986Sandreas.sandberg@arm.com    this->accessLatency = accessLatency;
1511986Sandreas.sandberg@arm.com    this->startIndexBit = startIndexBit;
1611986Sandreas.sandberg@arm.com
1711986Sandreas.sandberg@arm.com    if (banks != 0) {
1811986Sandreas.sandberg@arm.com        bankBits = floorLog2(banks);
1911986Sandreas.sandberg@arm.com    }
2011986Sandreas.sandberg@arm.com
2111986Sandreas.sandberg@arm.com    busyBanks.resize(banks);
2211986Sandreas.sandberg@arm.com}
2311986Sandreas.sandberg@arm.com
2411986Sandreas.sandberg@arm.combool
2511986Sandreas.sandberg@arm.comBankedArray::tryAccess(Index idx)
2611986Sandreas.sandberg@arm.com{
2711986Sandreas.sandberg@arm.com    if (accessLatency == 0)
2811986Sandreas.sandberg@arm.com        return true;
2911986Sandreas.sandberg@arm.com
3011986Sandreas.sandberg@arm.com    unsigned int bank = mapIndexToBank(idx);
3111986Sandreas.sandberg@arm.com    assert(bank < banks);
3211986Sandreas.sandberg@arm.com
3311986Sandreas.sandberg@arm.com    if (busyBanks[bank].scheduled()) {
3411986Sandreas.sandberg@arm.com        if (!(busyBanks[bank].startAccess == curTick() && busyBanks[bank].idx == idx)) {
3511986Sandreas.sandberg@arm.com            return false;
3611986Sandreas.sandberg@arm.com        } else {
3711986Sandreas.sandberg@arm.com            return true;  // We tried to allocate resources twice in the same cycle for the same addr
3811986Sandreas.sandberg@arm.com        }
3911986Sandreas.sandberg@arm.com    }
4011986Sandreas.sandberg@arm.com
4111986Sandreas.sandberg@arm.com    busyBanks[bank].idx = idx;
4211986Sandreas.sandberg@arm.com    busyBanks[bank].startAccess = curTick();
4311986Sandreas.sandberg@arm.com
4411986Sandreas.sandberg@arm.com    // substract 1 so that next cycle the resource available
4511986Sandreas.sandberg@arm.com    schedule(busyBanks[bank], curTick()+accessLatency-1);
4611986Sandreas.sandberg@arm.com
4711986Sandreas.sandberg@arm.com    return true;
4811986Sandreas.sandberg@arm.com}
4911986Sandreas.sandberg@arm.com
5011986Sandreas.sandberg@arm.comunsigned int
5111986Sandreas.sandberg@arm.comBankedArray::mapIndexToBank(Index idx)
5211986Sandreas.sandberg@arm.com{
5311986Sandreas.sandberg@arm.com    if (banks == 1) {
5411986Sandreas.sandberg@arm.com        return 0;
5511986Sandreas.sandberg@arm.com    }
5611986Sandreas.sandberg@arm.com    return idx % banks;
57}
58