Fix Physical Memory to allow memory sizes bigger than 128MB.
Kinda port DRAM to new memory system. The code is *really* ugly (not my fault) and right now something about the stats it uses causes a simulator segfault. src/SConscript: Add dram.cc to sconscript src/mem/physical.cc: src/mem/physical.hh: Add params struct to physical memory, use params, make latency function be virtual src/python/m5/objects/PhysicalMemory.py: Add DRAMMemory python class --HG-- extra : convert_revision : 5bd9f2e071c62da89e8efa46fa016f342c01535d
This commit is contained in:
parent
bb6af8eb8a
commit
2f145ac54a
6 changed files with 2991 additions and 41 deletions
|
@ -94,6 +94,7 @@ base_sources = Split('''
|
||||||
|
|
||||||
mem/bridge.cc
|
mem/bridge.cc
|
||||||
mem/bus.cc
|
mem/bus.cc
|
||||||
|
mem/dram.cc
|
||||||
mem/mem_object.cc
|
mem/mem_object.cc
|
||||||
mem/packet.cc
|
mem/packet.cc
|
||||||
mem/physical.cc
|
mem/physical.cc
|
||||||
|
|
2746
src/mem/dram.cc
Normal file
2746
src/mem/dram.cc
Normal file
File diff suppressed because it is too large
Load diff
172
src/mem/dram.hh
Normal file
172
src/mem/dram.hh
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2004 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: Ron Dreslinski
|
||||||
|
* Ali Saidi
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Derrive a class from PhysicalMemory that support DRAM like timing access.
|
||||||
|
*/
|
||||||
|
#ifndef __MEM_DRAM_HH__
|
||||||
|
#define __MEM_DRAM_HH__
|
||||||
|
|
||||||
|
#include "base/statistics.hh"
|
||||||
|
#include "mem/physical.hh"
|
||||||
|
|
||||||
|
class DRAMMemory : public PhysicalMemory
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/* added for dram support */
|
||||||
|
const int cpu_ratio; // ratio between CPU speed and memory bus speed
|
||||||
|
const int bus_width; // memory access bus width (in bytes)
|
||||||
|
/* memory access latency (<first_chunk> <inter_chunk>) */
|
||||||
|
const std::string mem_type;
|
||||||
|
const std::string mem_actpolicy;
|
||||||
|
const std::string memctrladdr_type;
|
||||||
|
const int act_lat;
|
||||||
|
const int cas_lat;
|
||||||
|
const int war_lat;
|
||||||
|
const int pre_lat;
|
||||||
|
const int dpl_lat;
|
||||||
|
const int trc_lat;
|
||||||
|
const int num_banks;
|
||||||
|
const int num_cpus;
|
||||||
|
|
||||||
|
int bank_size;
|
||||||
|
int num_rows;
|
||||||
|
int *active_row;
|
||||||
|
int last_bank;
|
||||||
|
int last_row;
|
||||||
|
Tick *busy_until;
|
||||||
|
int last_dev;
|
||||||
|
bool lastCmdIsRead;
|
||||||
|
int precharge;
|
||||||
|
|
||||||
|
/* memory access statistics */
|
||||||
|
int same_row_read_access;
|
||||||
|
int srr_after_read;
|
||||||
|
int srr_after_write;
|
||||||
|
int same_row_write_access;
|
||||||
|
int srw_after_read;
|
||||||
|
int srw_after_write;
|
||||||
|
|
||||||
|
int same_bank_read_access;
|
||||||
|
int sbr_after_read;
|
||||||
|
int sbr_after_write;
|
||||||
|
int same_bank_write_access;
|
||||||
|
int sbw_after_read;
|
||||||
|
int sbw_after_write;
|
||||||
|
|
||||||
|
int other_bank_read_access_hit;
|
||||||
|
int obr_after_read_hit;
|
||||||
|
int obr_after_write_hit;
|
||||||
|
int other_bank_write_access_hit;
|
||||||
|
int obw_after_read_hit;
|
||||||
|
int obw_after_write_hit;
|
||||||
|
// DR
|
||||||
|
// int other_bank_read_access_miss;
|
||||||
|
int obr_after_read_miss;
|
||||||
|
int obr_after_write_miss;
|
||||||
|
// DR
|
||||||
|
// int other_bank_write_access_miss;
|
||||||
|
int obw_after_read_miss;
|
||||||
|
int obw_after_write_miss;
|
||||||
|
|
||||||
|
int total_access;
|
||||||
|
|
||||||
|
int adjacent_access;
|
||||||
|
int adjacent_read;
|
||||||
|
int adjacent_write;
|
||||||
|
int command_overlapping;
|
||||||
|
int best_case;
|
||||||
|
int in_between_case;
|
||||||
|
int worst_case;
|
||||||
|
int full_overlapping;
|
||||||
|
int partial_overlapping;
|
||||||
|
|
||||||
|
int mem_access_details;
|
||||||
|
int memctrlpipe_enable;
|
||||||
|
|
||||||
|
Tick time_last_access;
|
||||||
|
|
||||||
|
|
||||||
|
Stats::Vector<> accesses;
|
||||||
|
Stats::Vector<> bytesRequested;
|
||||||
|
Stats::Vector<> bytesSent;
|
||||||
|
Stats::Vector<> compressedAccesses;
|
||||||
|
|
||||||
|
Stats::Vector<> cycles_nCKE;
|
||||||
|
Stats::Vector<> cycles_all_precharge_CKE;
|
||||||
|
Stats::Vector<> cycles_all_precharge_nCKE;
|
||||||
|
Stats::Vector<> cycles_bank_active_nCKE;
|
||||||
|
Stats::Vector<> cycles_avg_ACT;
|
||||||
|
Stats::Vector<> cycles_read_out;
|
||||||
|
Stats::Vector<> cycles_write_in;
|
||||||
|
Stats::Vector<> cycles_between_misses;
|
||||||
|
Stats::Vector<> other_bank_read_access_miss;
|
||||||
|
Stats::Vector<> other_bank_write_access_miss;
|
||||||
|
Stats::Scalar<> total_latency;
|
||||||
|
Stats::Scalar<> total_icache_req;
|
||||||
|
Stats::Scalar<> total_arb_latency;
|
||||||
|
Stats::Formula avg_latency;
|
||||||
|
Stats::Formula avg_arb_latency;
|
||||||
|
Stats::Vector2d<> bank_access_profile;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Tick calculateLatency(Packet *pkt);
|
||||||
|
int prechargeBanksAround(int bank);
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct Params : public PhysicalMemory::Params
|
||||||
|
{
|
||||||
|
/* additional params for dram protocol*/
|
||||||
|
int cpu_ratio;
|
||||||
|
int bus_width;
|
||||||
|
|
||||||
|
std::string mem_type; /* DRDRAM, SDRAM */
|
||||||
|
std::string mem_actpolicy; /* closed, open */
|
||||||
|
std::string memctrladdr_type; /* interleaved, anythingelse */
|
||||||
|
|
||||||
|
int act_lat;
|
||||||
|
int cas_lat;
|
||||||
|
int war_lat;
|
||||||
|
int pre_lat;
|
||||||
|
int dpl_lat;
|
||||||
|
int trc_lat;
|
||||||
|
int num_banks;
|
||||||
|
int num_cpus;
|
||||||
|
|
||||||
|
};
|
||||||
|
virtual void regStats();
|
||||||
|
DRAMMemory(Params *p);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif// __MEM_DRAM_HH__
|
||||||
|
|
|
@ -54,25 +54,22 @@ using namespace std;
|
||||||
using namespace TheISA;
|
using namespace TheISA;
|
||||||
|
|
||||||
|
|
||||||
PhysicalMemory::PhysicalMemory(const string &n, Tick latency)
|
PhysicalMemory::PhysicalMemory(Params *p)
|
||||||
: MemObject(n),base_addr(0), pmem_addr(NULL), port(NULL), lat(latency)
|
: MemObject(p->name), pmemAddr(NULL), port(NULL), lat(p->latency), _params(p)
|
||||||
{
|
{
|
||||||
// Hardcoded to 128 MB for now.
|
if (params()->addrRange.size() % TheISA::PageBytes != 0)
|
||||||
pmem_size = 1 << 27;
|
|
||||||
|
|
||||||
if (pmem_size % TheISA::PageBytes != 0)
|
|
||||||
panic("Memory Size not divisible by page size\n");
|
panic("Memory Size not divisible by page size\n");
|
||||||
|
|
||||||
int map_flags = MAP_ANON | MAP_PRIVATE;
|
int map_flags = MAP_ANON | MAP_PRIVATE;
|
||||||
pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE,
|
pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE,
|
||||||
map_flags, -1, 0);
|
map_flags, -1, 0);
|
||||||
|
|
||||||
if (pmem_addr == (void *)MAP_FAILED) {
|
if (pmemAddr == (void *)MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap");
|
||||||
fatal("Could not mmap!\n");
|
fatal("Could not mmap!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
page_ptr = 0;
|
pagePtr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -85,18 +82,18 @@ PhysicalMemory::init()
|
||||||
|
|
||||||
PhysicalMemory::~PhysicalMemory()
|
PhysicalMemory::~PhysicalMemory()
|
||||||
{
|
{
|
||||||
if (pmem_addr)
|
if (pmemAddr)
|
||||||
munmap(pmem_addr, pmem_size);
|
munmap(pmemAddr, params()->addrRange.size());
|
||||||
//Remove memPorts?
|
//Remove memPorts?
|
||||||
}
|
}
|
||||||
|
|
||||||
Addr
|
Addr
|
||||||
PhysicalMemory::new_page()
|
PhysicalMemory::new_page()
|
||||||
{
|
{
|
||||||
Addr return_addr = page_ptr << LogVMPageSize;
|
Addr return_addr = pagePtr << LogVMPageSize;
|
||||||
return_addr += base_addr;
|
return_addr += params()->addrRange.start;
|
||||||
|
|
||||||
++page_ptr;
|
++pagePtr;
|
||||||
return return_addr;
|
return return_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,20 +104,25 @@ PhysicalMemory::deviceBlockSize()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tick
|
||||||
|
PhysicalMemory::calculateLatency(Packet *pkt)
|
||||||
|
{
|
||||||
|
return lat;
|
||||||
|
}
|
||||||
|
|
||||||
Tick
|
Tick
|
||||||
PhysicalMemory::doFunctionalAccess(Packet *pkt)
|
PhysicalMemory::doFunctionalAccess(Packet *pkt)
|
||||||
{
|
{
|
||||||
assert(pkt->getAddr() + pkt->getSize() < pmem_size);
|
assert(pkt->getAddr() + pkt->getSize() < params()->addrRange.size());
|
||||||
|
|
||||||
switch (pkt->cmd) {
|
switch (pkt->cmd) {
|
||||||
case Packet::ReadReq:
|
case Packet::ReadReq:
|
||||||
memcpy(pkt->getPtr<uint8_t>(),
|
memcpy(pkt->getPtr<uint8_t>(),
|
||||||
pmem_addr + pkt->getAddr() - base_addr,
|
pmemAddr + pkt->getAddr() - params()->addrRange.start,
|
||||||
pkt->getSize());
|
pkt->getSize());
|
||||||
break;
|
break;
|
||||||
case Packet::WriteReq:
|
case Packet::WriteReq:
|
||||||
memcpy(pmem_addr + pkt->getAddr() - base_addr,
|
memcpy(pmemAddr + pkt->getAddr() - params()->addrRange.start,
|
||||||
pkt->getPtr<uint8_t>(),
|
pkt->getPtr<uint8_t>(),
|
||||||
pkt->getSize());
|
pkt->getSize());
|
||||||
// temporary hack: will need to add real LL/SC implementation
|
// temporary hack: will need to add real LL/SC implementation
|
||||||
|
@ -134,7 +136,7 @@ PhysicalMemory::doFunctionalAccess(Packet *pkt)
|
||||||
}
|
}
|
||||||
|
|
||||||
pkt->result = Packet::Success;
|
pkt->result = Packet::Success;
|
||||||
return lat;
|
return calculateLatency(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Port *
|
Port *
|
||||||
|
@ -181,7 +183,7 @@ PhysicalMemory::getAddressRanges(AddrRangeList &resp, AddrRangeList &snoop)
|
||||||
{
|
{
|
||||||
snoop.clear();
|
snoop.clear();
|
||||||
resp.clear();
|
resp.clear();
|
||||||
resp.push_back(RangeSize(base_addr, pmem_size));
|
resp.push_back(RangeSize(params()->addrRange.start, params()->addrRange.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -232,7 +234,6 @@ PhysicalMemory::serialize(ostream &os)
|
||||||
gzFile compressedMem;
|
gzFile compressedMem;
|
||||||
string filename = name() + ".physmem";
|
string filename = name() + ".physmem";
|
||||||
|
|
||||||
SERIALIZE_SCALAR(pmem_size);
|
|
||||||
SERIALIZE_SCALAR(filename);
|
SERIALIZE_SCALAR(filename);
|
||||||
|
|
||||||
// write memory file
|
// write memory file
|
||||||
|
@ -248,7 +249,7 @@ PhysicalMemory::serialize(ostream &os)
|
||||||
fatal("Insufficient memory to allocate compression state for %s\n",
|
fatal("Insufficient memory to allocate compression state for %s\n",
|
||||||
filename);
|
filename);
|
||||||
|
|
||||||
if (gzwrite(compressedMem, pmem_addr, pmem_size) != pmem_size) {
|
if (gzwrite(compressedMem, pmemAddr, params()->addrRange.size()) != params()->addrRange.size()) {
|
||||||
fatal("Write failed on physical memory checkpoint file '%s'\n",
|
fatal("Write failed on physical memory checkpoint file '%s'\n",
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
@ -269,12 +270,8 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string §ion)
|
||||||
const int chunkSize = 16384;
|
const int chunkSize = 16384;
|
||||||
|
|
||||||
|
|
||||||
// unmap file that was mmaped in the constructor
|
|
||||||
munmap(pmem_addr, pmem_size);
|
|
||||||
|
|
||||||
string filename;
|
string filename;
|
||||||
|
|
||||||
UNSERIALIZE_SCALAR(pmem_size);
|
|
||||||
UNSERIALIZE_SCALAR(filename);
|
UNSERIALIZE_SCALAR(filename);
|
||||||
|
|
||||||
filename = cp->cptDir + "/" + filename;
|
filename = cp->cptDir + "/" + filename;
|
||||||
|
@ -291,11 +288,15 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string §ion)
|
||||||
fatal("Insufficient memory to allocate compression state for %s\n",
|
fatal("Insufficient memory to allocate compression state for %s\n",
|
||||||
filename);
|
filename);
|
||||||
|
|
||||||
|
// unmap file that was mmaped in the constructor
|
||||||
|
// This is done here to make sure that gzip and open don't muck with our
|
||||||
|
// nice large space of memory before we reallocate it
|
||||||
|
munmap(pmemAddr, params()->addrRange.size());
|
||||||
|
|
||||||
pmem_addr = (uint8_t *)mmap(NULL, pmem_size, PROT_READ | PROT_WRITE,
|
pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE,
|
||||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||||
|
|
||||||
if (pmem_addr == (void *)MAP_FAILED) {
|
if (pmemAddr == (void *)MAP_FAILED) {
|
||||||
perror("mmap");
|
perror("mmap");
|
||||||
fatal("Could not mmap physical memory!\n");
|
fatal("Could not mmap physical memory!\n");
|
||||||
}
|
}
|
||||||
|
@ -306,19 +307,19 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string §ion)
|
||||||
fatal("Unable to malloc memory to read file %s\n", filename);
|
fatal("Unable to malloc memory to read file %s\n", filename);
|
||||||
|
|
||||||
/* Only copy bytes that are non-zero, so we don't give the VM system hell */
|
/* Only copy bytes that are non-zero, so we don't give the VM system hell */
|
||||||
while (curSize < pmem_size) {
|
while (curSize < params()->addrRange.size()) {
|
||||||
bytesRead = gzread(compressedMem, tempPage, chunkSize);
|
bytesRead = gzread(compressedMem, tempPage, chunkSize);
|
||||||
if (bytesRead != chunkSize && bytesRead != pmem_size - curSize)
|
if (bytesRead != chunkSize && bytesRead != params()->addrRange.size() - curSize)
|
||||||
fatal("Read failed on physical memory checkpoint file '%s'"
|
fatal("Read failed on physical memory checkpoint file '%s'"
|
||||||
" got %d bytes, expected %d or %d bytes\n",
|
" got %d bytes, expected %d or %d bytes\n",
|
||||||
filename, bytesRead, chunkSize, pmem_size-curSize);
|
filename, bytesRead, chunkSize, params()->addrRange.size()-curSize);
|
||||||
|
|
||||||
assert(bytesRead % sizeof(long) == 0);
|
assert(bytesRead % sizeof(long) == 0);
|
||||||
|
|
||||||
for (int x = 0; x < bytesRead/sizeof(long); x++)
|
for (int x = 0; x < bytesRead/sizeof(long); x++)
|
||||||
{
|
{
|
||||||
if (*(tempPage+x) != 0) {
|
if (*(tempPage+x) != 0) {
|
||||||
pmem_current = (long*)(pmem_addr + curSize + x * sizeof(long));
|
pmem_current = (long*)(pmemAddr + curSize + x * sizeof(long));
|
||||||
*pmem_current = *(tempPage+x);
|
*pmem_current = *(tempPage+x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,8 +353,11 @@ END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory)
|
||||||
|
|
||||||
CREATE_SIM_OBJECT(PhysicalMemory)
|
CREATE_SIM_OBJECT(PhysicalMemory)
|
||||||
{
|
{
|
||||||
|
PhysicalMemory::Params *p = new PhysicalMemory::Params;
|
||||||
return new PhysicalMemory(getInstanceName(), latency);
|
p->name = getInstanceName();
|
||||||
|
p->addrRange = range;
|
||||||
|
p->latency = latency;
|
||||||
|
return new PhysicalMemory(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory)
|
REGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory)
|
||||||
|
|
|
@ -80,19 +80,28 @@ class PhysicalMemory : public MemObject
|
||||||
const PhysicalMemory &operator=(const PhysicalMemory &specmem);
|
const PhysicalMemory &operator=(const PhysicalMemory &specmem);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Addr base_addr;
|
uint8_t *pmemAddr;
|
||||||
Addr pmem_size;
|
|
||||||
uint8_t *pmem_addr;
|
|
||||||
MemoryPort *port;
|
MemoryPort *port;
|
||||||
int page_ptr;
|
int pagePtr;
|
||||||
Tick lat;
|
Tick lat;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Addr new_page();
|
Addr new_page();
|
||||||
uint64_t size() { return pmem_size; }
|
uint64_t size() { return params()->addrRange.size(); }
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
Range<Addr> addrRange;
|
||||||
|
Tick latency;
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Params *_params;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PhysicalMemory(const std::string &n, Tick latency);
|
const Params *params() const { return _params; }
|
||||||
|
PhysicalMemory(Params *p);
|
||||||
virtual ~PhysicalMemory();
|
virtual ~PhysicalMemory();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -102,9 +111,9 @@ class PhysicalMemory : public MemObject
|
||||||
void virtual init();
|
void virtual init();
|
||||||
unsigned int drain(Event *de);
|
unsigned int drain(Event *de);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
Tick doFunctionalAccess(Packet *pkt);
|
Tick doFunctionalAccess(Packet *pkt);
|
||||||
|
virtual Tick calculateLatency(Packet *pkt);
|
||||||
void recvStatusChange(Port::Status status);
|
void recvStatusChange(Port::Status status);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -7,3 +7,21 @@ class PhysicalMemory(MemObject):
|
||||||
range = Param.AddrRange("Device Address")
|
range = Param.AddrRange("Device Address")
|
||||||
file = Param.String('', "memory mapped file")
|
file = Param.String('', "memory mapped file")
|
||||||
latency = Param.Latency(Parent.clock, "latency of an access")
|
latency = Param.Latency(Parent.clock, "latency of an access")
|
||||||
|
|
||||||
|
class DRAMMemory(PhysicalMemory):
|
||||||
|
type = 'DRAMMemory'
|
||||||
|
# Many of these should be observed from the configuration
|
||||||
|
cpu_ratio = Param.Int(5,"ratio between CPU speed and memory bus speed")
|
||||||
|
mem_type = Param.String("SDRAM", "Type of DRAM (DRDRAM, SDRAM)")
|
||||||
|
mem_actpolicy = Param.String("open", "Open/Close policy")
|
||||||
|
memctrladdr_type = Param.String("interleaved", "Mapping interleaved or direct")
|
||||||
|
bus_width = Param.Int(16, "")
|
||||||
|
act_lat = Param.Int(2, "RAS to CAS delay")
|
||||||
|
cas_lat = Param.Int(1, "CAS delay")
|
||||||
|
war_lat = Param.Int(2, "write after read delay")
|
||||||
|
pre_lat = Param.Int(2, "precharge delay")
|
||||||
|
dpl_lat = Param.Int(2, "data in to precharge delay")
|
||||||
|
trc_lat = Param.Int(6, "row cycle delay")
|
||||||
|
num_banks = Param.Int(4, "Number of Banks")
|
||||||
|
num_cpus = Param.Int(4, "Number of CPUs connected to DRAM")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue