simx refactoring, fixed simple.hex, compatibility with rtlsim and vlsim complete, added to regression suite

This commit is contained in:
Blaise Tine 2021-03-08 23:58:33 -08:00
parent 71e9745e68
commit 907e6868cd
19 changed files with 88376 additions and 95959 deletions

View file

@ -8,6 +8,7 @@ set -e
./ci/test_riscv_isa.sh
./ci/test_opencl.sh
./ci/test_driver.sh
./ci/test_simx.sh
# Build tests disabling extensions
CONFIGS=-DEXT_M_DISABLE make -C hw/simulate

6
ci/test_riscv.sh Normal file
View file

@ -0,0 +1,6 @@
#!/bin/bash
# exit when any command fails
set -e
make -C simx run

View file

@ -23,8 +23,8 @@ DBG_FLAGS += -DDBG_CACHE_REQ_INFO
#CONFIGS ?= -DNUM_CLUSTERS=2 -DNUM_CORES=4 -DL2_ENABLE=1
#CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=4 -DL2_ENABLE=1
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0
#CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
#CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
CFLAGS += -fPIC

View file

@ -22,8 +22,8 @@ DBG_FLAGS += -DDBG_CACHE_REQ_INFO
#CONFIGS ?= -DNUM_CLUSTERS=2 -DNUM_CORES=4 -DL2_ENABLE=1
#CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=4 -DL2_ENABLE=1
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0
#CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
#CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=2 -DL2_ENABLE=0
CONFIGS ?= -DNUM_CLUSTERS=1 -DNUM_CORES=1
CFLAGS += $(CONFIGS)

View file

@ -79,7 +79,7 @@ public:
return 0;
}
int upload(void* src, size_t dest_addr, size_t size, size_t src_offset) {
int upload(const void* src, size_t dest_addr, size_t size, size_t src_offset) {
size_t asize = align_size(size, CACHE_BLOCK_SIZE);
if (dest_addr + asize > ram_.size())
return -1;
@ -93,11 +93,11 @@ public:
}
printf("\n");*/
ram_.write(dest_addr, asize, (uint8_t*)src + src_offset);
ram_.write(dest_addr, asize, (const uint8_t*)src + src_offset);
return 0;
}
int download(const void* dest, size_t src_addr, size_t size, size_t dest_offset) {
int download(void* dest, size_t src_addr, size_t size, size_t dest_offset) {
size_t asize = align_size(size, CACHE_BLOCK_SIZE);
if (src_addr + asize > ram_.size())
return -1;

View file

@ -96,12 +96,12 @@ public:
return 0;
}
int upload(void* src, size_t dest_addr, size_t size, size_t src_offset) {
int upload(const void* src, size_t dest_addr, size_t size, size_t src_offset) {
auto asize = align_size(size, CACHE_BLOCK_SIZE);
if (dest_addr + asize > ram_.size())
return -1;
ram_.write(dest_addr, asize, (uint8_t*)src + src_offset);
ram_.write(dest_addr, (const uint8_t*)src + src_offset, asize);
/*printf("VXDRV: upload %d bytes to 0x%x\n", size, dest_addr);
for (int i = 0; i < size; i += 4) {
@ -111,12 +111,12 @@ public:
return 0;
}
int download(const void* dest, size_t src_addr, size_t size, size_t dest_offset) {
int download(void* dest, size_t src_addr, size_t size, size_t dest_offset) {
size_t asize = align_size(size, CACHE_BLOCK_SIZE);
if (src_addr + asize > ram_.size())
return -1;
ram_.read(src_addr, asize, (uint8_t*)dest + dest_offset);
ram_.read(src_addr, (uint8_t*)dest + dest_offset, asize);
/*printf("VXDRV: download %d bytes from 0x%x\n", size, src_addr);
for (int i = 0; i < size; i += 4) {

View file

@ -20689,7 +20689,7 @@ Disassembly of section .rodata:
80013654: 6c69 lui s8,0x1a
80013656: 2065 jal 800136fe <zeroes.4448+0xe2>
80013658: 2522 fld fa0,8(sp)
8001365a: 202c2273 csrrs tp,hedeleg,s8
8001365a: 202c2273 csrrs tp,0x202,s8
8001365e: 696c flw fa1,84(a0)
80013660: 656e flw fa0,216(sp)
80013662: 2520 fld fs0,72(a0)

View file

@ -22939,7 +22939,7 @@ Disassembly of section .rodata:
80015918: 6c69 lui s8,0x1a
8001591a: 2065 jal 800159c2 <zeroes.4462+0xe2>
8001591c: 2522 fld fa0,8(sp)
8001591e: 202c2273 csrrs tp,hedeleg,s8
8001591e: 202c2273 csrrs tp,0x202,s8
80015922: 696c flw fa1,84(a0)
80015924: 656e flw fa0,216(sp)
80015926: 2520 fld fs0,72(a0)

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -27,8 +27,10 @@ all: $(PROJECT)
$(PROJECT): $(SRCS)
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
run: $(PROJECT)
./$(PROJECT)
run:
./test_rv32i.sh
./test_rv32f.sh
./test_runtime.sh
.depend: $(SRCS)
$(CXX) $(CXXFLAGS) -MM $^ > .depend;

View file

@ -311,31 +311,36 @@ void Core::barrier(int bar_id, int count, int warp_id) {
barrier.reset();
}
Word Core::icache_fetch(Addr addr, bool sup) {
return mem_.fetch(addr, sup);
Word Core::icache_fetch(Addr addr) {
Word data;
mem_.read(addr, &data, sizeof(Word), 0);
return data;
}
Word Core::dcache_read(Addr addr, bool sup) {
Word Core::dcache_read(Addr addr, Size size) {
++loads_;
Word data = 0;
#ifdef SM_ENABLE
if ((addr >= (SHARED_MEM_BASE_ADDR - SMEM_SIZE))
&& ((addr + 4) <= SHARED_MEM_BASE_ADDR)) {
return shared_mem_.read(addr & (SMEM_SIZE-1));
&& ((addr + 3) < SHARED_MEM_BASE_ADDR)) {
shared_mem_.read(addr & (SMEM_SIZE-1), &data, size);
return data;
}
#endif
return mem_.read(addr, sup);
mem_.read(addr, &data, size, 0);
return data;
}
void Core::dcache_write(Addr addr, Word data, bool sup, Size size) {
void Core::dcache_write(Addr addr, Word data, Size size) {
++stores_;
#ifdef SM_ENABLE
if ((addr >= (SHARED_MEM_BASE_ADDR - SMEM_SIZE))
&& ((addr + 4) <= SHARED_MEM_BASE_ADDR)) {
shared_mem_.write(addr & (SMEM_SIZE-1), data);
&& ((addr + 3) < SHARED_MEM_BASE_ADDR)) {
shared_mem_.write(addr & (SMEM_SIZE-1), &data, size);
return;
}
#endif
mem_.write(addr, data, sup, size);
mem_.write(addr, &data, size, 0);
}
bool Core::running() const {

View file

@ -64,11 +64,11 @@ public:
void barrier(int bar_id, int count, int warp_id);
Word icache_fetch(Addr, bool sup);
Word icache_fetch(Addr);
Word dcache_read(Addr, bool sup);
Word dcache_read(Addr, Size);
void dcache_write(Addr, Word, bool sup, Size);
void dcache_write(Addr, Word, Size);
private:

View file

@ -351,8 +351,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
case L_INST: {
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
Word shift_by = ((rsdata[0] + immsrc) & 0x00000003) * 8;
Word data_read = core_->dcache_read(memAddr, 0);
D(3, "LOAD MEM ADDRESS: " << std::hex << memAddr << ", DATA=0x" << data_read);
Word data_read = core_->dcache_read(memAddr, 4);
D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read);
switch (func3) {
case 0:
// LBI
@ -380,23 +380,23 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
} break;
case S_INST: {
Word memAddr = rsdata[0] + immsrc;
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
switch (func3) {
case 0:
// SB
core_->dcache_write(memAddr, rsdata[1] & 0x000000FF, 0, 1);
core_->dcache_write(memAddr, rsdata[1] & 0x000000FF, 1);
break;
case 1:
// SH
core_->dcache_write(memAddr, rsdata[1], 0, 2);
core_->dcache_write(memAddr, rsdata[1], 2);
break;
case 2:
// SW
core_->dcache_write(memAddr, rsdata[1], 0, 4);
core_->dcache_write(memAddr, rsdata[1], 4);
break;
default:
std::abort();
}
D(3, "STORE MEM ADDRESS: " << std::hex << memAddr);
} break;
case SYS_INST: {
Word csr_addr = immsrc & 0x00000FFF;
@ -452,8 +452,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
case (FL | VL):
if (func3 == 0x2) {
Word memAddr = rsdata[0] + immsrc;
Word data_read = core_->dcache_read(memAddr, 0);
D(3, "LOAD MEM ADDRESS: " << std::hex << memAddr << ", DATA=0x" << data_read);
Word data_read = core_->dcache_read(memAddr, 4);
D(3, "LOAD MEM: ADDRESS=0x" << std::hex << memAddr << ", DATA=0x" << data_read);
rddata = data_read;
} else {
D(3, "Executing vector load");
@ -465,14 +465,15 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
auto &vd = vRegFile_[rdest];
switch (instr.getVlsWidth()) {
case 6: { //load word and unit strided (not checking for unit stride)
case 6: {
//load word and unit strided (not checking for unit stride)
for (int i = 0; i < vl_; i++) {
Word memAddr = ((rsdata[0]) & 0xFFFFFFFC) + (i * vtype_.vsew / 8);
Word data_read = core_->dcache_read(memAddr, 0);
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
Word data_read = core_->dcache_read(memAddr, 4);
D(4, "Mem addr: " << std::hex << memAddr << " Data read " << data_read);
int *result_ptr = (int *)(vd.data() + i);
*result_ptr = data_read;
D(3, "STORE MEM ADDRESS: " << std::hex << memAddr);
}
} break;
default:
@ -484,22 +485,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
case (FS | VS):
if (func3 == 0x2) {
Word memAddr = rsdata[0] + immsrc;
core_->dcache_write(memAddr, rsdata[1], 0, 4);
D(3, "STORE MEM ADDRESS: " << std::hex << memAddr);
core_->dcache_write(memAddr, rsdata[1], 4);
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
} else {
for (int i = 0; i < vl_; i++) {
Word memAddr = rsdata[0] + (i * vtype_.vsew / 8);
D(3, "STORE MEM: ADDRESS=0x" << std::hex << memAddr);
switch (instr.getVlsWidth()) {
case 6: {
//store word and unit strided (not checking for unit stride)
uint32_t value = *(uint32_t *)(vRegFile_[instr.getVs3()].data() + i);
core_->dcache_write(memAddr, value, 0, 4);
core_->dcache_write(memAddr, value, 4);
D(4, "store: " << memAddr << " value:" << value);
} break;
default:
std::abort();
}
D(3, "STORE MEM ADDRESS: " << std::hex << memAddr);
}
}
break;

View file

@ -28,31 +28,52 @@ RamMemDevice::RamMemDevice(const char *filename, Size wordSize)
contents_.push_back(input.get());
} while (input);
while (contents_.size() % wordSize)
while (contents_.size() & (wordSize-1))
contents_.push_back(0x00);
}
RamMemDevice::RamMemDevice(Size size, Size wordSize)
: wordSize_(wordSize)
, contents_(size)
: contents_(size)
, wordSize_(wordSize)
{}
void RomMemDevice::write(Addr, Word) {
std::cout << "Attempt to write to ROM.\n";
void RamMemDevice::read(Addr addr, void *data, Size size) {
auto addr_end = addr + size;
if ((addr & (wordSize_-1))
|| (addr_end & (wordSize_-1))
|| (addr_end <= contents_.size())) {
std::cout << "lookup of 0x" << std::hex << (addr_end-1) << " failed.\n";
throw BadAddress();
}
const Byte *s = contents_.data() + addr;
for (Byte *d = (Byte*)data, *de = d + size; d != de;) {
*d++ = *s++;
}
}
void RamMemDevice::write(Addr addr, const void *data, Size size) {
auto addr_end = addr + size;
if ((addr & (wordSize_-1))
|| (addr_end & (wordSize_-1))
|| (addr_end <= contents_.size())) {
std::cout << "lookup of 0x" << std::hex << (addr_end-1) << " failed.\n";
throw BadAddress();
}
const Byte *s = (const Byte*)data;
for (Byte *d = contents_.data() + addr, *de = d + size; d != de;) {
*d++ = *s++;
}
}
///////////////////////////////////////////////////////////////////////////////
void RomMemDevice::write(Addr /*addr*/, const void* /*data*/, Size /*size*/) {
std::cout << "attempt to write to ROM.\n";
std::abort();
}
Word RamMemDevice::read(Addr addr) {
D(2, "RAM read, addr=0x" << std::hex << addr);
Word w = readWord(contents_, addr, wordSize_ - addr % wordSize_);
return w;
}
void RamMemDevice::write(Addr addr, Word w) {
D(2, "RAM write, addr=0x" << std::hex << addr);
writeWord(contents_, addr, wordSize_ - addr % wordSize_, w);
}
///////////////////////////////////////////////////////////////////////////////
bool MemoryUnit::ADecoder::lookup(Addr a, Size wordSize, mem_accessor_t* ma) {
@ -74,32 +95,22 @@ void MemoryUnit::ADecoder::map(Addr a, Addr e, MemDevice &m) {
entries_.emplace_back(entry);
}
Word MemoryUnit::ADecoder::read(Addr a, bool /*sup*/, Size wordSize) {
void MemoryUnit::ADecoder::read(Addr addr, void *data, Size size) {
mem_accessor_t ma;
if (!this->lookup(a, wordSize, &ma)) {
std::cout << "lookup of 0x" << std::hex << a << " failed.\n";
if (!this->lookup(addr, size, &ma)) {
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
throw BadAddress();
}
return ma.md->read(ma.addr);
ma.md->read(ma.addr, data, size);
}
void MemoryUnit::ADecoder::write(Addr a, Word w, bool /*sup*/, Size wordSize) {
void MemoryUnit::ADecoder::write(Addr addr, const void *data, Size size) {
mem_accessor_t ma;
if (!this->lookup(a, wordSize, &ma)) {
std::cout << "lookup of 0x" << std::hex << a << " failed.\n";
if (!this->lookup(addr, size, &ma)) {
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
throw BadAddress();
}
RAM *ram = (RAM *)ma.md;
switch (wordSize) {
case 1:
ram->writeByte(ma.addr, &w);
break;
case 2:
ram->writeHalf(ma.addr, &w);
break;
default:
ram->writeWord(ma.addr, &w);
}
ma.md->write(ma.addr, data, size);
}
///////////////////////////////////////////////////////////////////////////////
@ -132,44 +143,28 @@ MemoryUnit::TLBEntry MemoryUnit::tlbLookup(Addr vAddr, Word flagMask) {
}
}
Word MemoryUnit::read(Addr vAddr, bool sup) {
void MemoryUnit::read(Addr addr, void *data, Size size, bool sup) {
Addr pAddr;
if (disableVm_) {
pAddr = vAddr;
pAddr = addr;
} else {
Word flagMask = sup ? 8 : 1;
TLBEntry t = this->tlbLookup(vAddr, flagMask);
pAddr = t.pfn * pageSize_ + vAddr % pageSize_;
TLBEntry t = this->tlbLookup(addr, flagMask);
pAddr = t.pfn * pageSize_ + addr % pageSize_;
}
return decoder_.read(pAddr, sup, addrBytes_);
return decoder_.read(pAddr, data, size);
}
Word MemoryUnit::fetch(Addr vAddr, bool sup) {
void MemoryUnit::write(Addr addr, const void *data, Size size, bool sup) {
Addr pAddr;
if (disableVm_) {
pAddr = vAddr;
} else {
Word flagMask = sup ? 32 : 4;
TLBEntry t = this->tlbLookup(vAddr, flagMask);
pAddr = t.pfn * pageSize_ + vAddr % pageSize_;
}
Word instruction = decoder_.read(pAddr, sup, addrBytes_);
return instruction;
}
void MemoryUnit::write(Addr vAddr, Word w, bool sup, Size bytes) {
Addr pAddr;
if (disableVm_) {
pAddr = vAddr;
pAddr = addr;
} else {
Word flagMask = sup ? 16 : 2;
TLBEntry t = tlbLookup(vAddr, flagMask);
pAddr = t.pfn * pageSize_ + vAddr % pageSize_;
TLBEntry t = tlbLookup(addr, flagMask);
pAddr = t.pfn * pageSize_ + addr % pageSize_;
}
decoder_.write(pAddr, w, sup, bytes);
decoder_.write(pAddr, data, size);
}
void MemoryUnit::tlbAdd(Addr virt, Addr phys, Word flags) {
@ -182,70 +177,6 @@ void MemoryUnit::tlbRm(Addr va) {
tlb_.erase(tlb_.find(va / pageSize_));
}
void *vortex::consoleInputThread(void * /*arg_vp*/) {
//--
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////
DiskControllerMemDevice::DiskControllerMemDevice(Size wordSize, Size blockSize, Core &c)
: wordSize_(wordSize)
, blockSize_(blockSize)
, core_(c)
{}
Word DiskControllerMemDevice::read(Addr a) {
switch (a / 8) {
case 0:
return curDisk_;
case 1:
return curBlock_;
case 2:
return disks_[curDisk_].blocks * blockSize_;
case 3:
return physAddr_;
case 4:
return command_;
case 5:
return status_;
default:
std::cout << "Attempt to read invalid disk controller register.\n";
std::abort();
}
}
void DiskControllerMemDevice::write(Addr a, Word w) {
switch (a / 8) {
case 0:
if (w <= disks_.size()) {
curDisk_ = w;
status_ = OK;
} else {
status_ = INVALID_DISK;
}
break;
case 1:
if (w < disks_[curDisk_].blocks) {
curBlock_ = w;
} else {
status_ = INVALID_BLOCK;
}
break;
case 2:
nBlocks_ = w >= disks_[curDisk_].blocks ? disks_[curDisk_].blocks - 1 : w;
status_ = OK;
break;
case 3:
physAddr_ = w;
status_ = OK;
break;
case 4:
std::cout << "TODO: Implement disk read and write!\n";
break;
}
}
///////////////////////////////////////////////////////////////////////////////
RAM::RAM(uint32_t num_pages, uint32_t page_size)
@ -290,81 +221,20 @@ uint8_t *RAM::get(uint32_t address) {
return page + byte_offset;
}
void RAM::read(uint32_t address, uint32_t length, uint8_t *data) {
for (unsigned i = 0; i < length; i++) {
data[i] = *this->get(address + i);
void RAM::read(Addr addr, void *data, Size size) {
Byte* d = (Byte*)data;
for (unsigned i = 0; i < size; i++) {
d[i] = *this->get(addr + i);
}
}
void RAM::write(uint32_t address, uint32_t length, uint8_t *data) {
for (unsigned i = 0; i < length; i++) {
*this->get(address + i) = data[i];
void RAM::write(Addr addr, const void *data, Size size) {
const Byte* s = (const Byte*)data;
for (unsigned i = 0; i < size; i++) {
*this->get(addr + i) = s[i];
}
}
Byte *RAM::base() {
return (Byte *)this->get(0);
}
void RAM::getBlock(uint32_t address, uint8_t *data) {
uint32_t block_number = address & 0xffffff00; // To zero out block offset
uint32_t bytes_num = 256;
this->read(block_number, bytes_num, data);
}
void RAM::getWord(uint32_t address, uint32_t *data) {
data[0] = 0;
uint8_t first = *get(address + 0);
uint8_t second = *get(address + 1);
uint8_t third = *get(address + 2);
uint8_t fourth = *get(address + 3);
data[0] = (data[0] << 0) | fourth;
data[0] = (data[0] << 8) | third;
data[0] = (data[0] << 8) | second;
data[0] = (data[0] << 8) | first;
}
void RAM::writeWord(uint32_t address, uint32_t *data) {
uint32_t data_to_write = *data;
uint32_t byte_mask = 0xFF;
for (int i = 0; i < 4; i++) {
*this->get(address + i) = data_to_write & byte_mask;
data_to_write = data_to_write >> 8;
}
}
void RAM::writeHalf(uint32_t address, uint32_t *data) {
uint32_t data_to_write = *data;
uint32_t byte_mask = 0xFF;
for (int i = 0; i < 2; i++) {
*this->get(address + i) = data_to_write & byte_mask;
data_to_write = data_to_write >> 8;
}
}
void RAM::writeByte(uint32_t address, uint32_t *data) {
uint32_t data_to_write = *data;
uint32_t byte_mask = 0xFF;
*this->get(address) = data_to_write & byte_mask;
data_to_write = data_to_write >> 8;
}
void RAM::write(Addr addr, Word w) {
uint32_t word = (uint32_t)w;
writeWord(addr, &word);
}
Word RAM::read(Addr addr) {
uint32_t w;
getWord(addr, &w);
return (Word)w;
}
static uint32_t hti_old(char c) {
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;

View file

@ -7,18 +7,14 @@
#include "types.h"
namespace vortex {
void *consoleInputThread(void *);
struct BadAddress {};
class MemDevice {
public:
virtual ~MemDevice() {}
virtual Size size() const = 0;
virtual Word read(Addr) = 0;
virtual void write(Addr, Word) = 0;
virtual Byte *base() {
return NULL;
}
virtual void read(Addr addr, void *data, Size size) = 0;
virtual void write(Addr addr, const void *data, Size size) = 0;
};
///////////////////////////////////////////////////////////////////////////////
@ -29,20 +25,16 @@ public:
RamMemDevice(const char *filename, Size wordSize);
~RamMemDevice() {}
virtual Word read(Addr);
virtual void write(Addr, Word);
void read(Addr addr, void *data, Size size) override;
void write(Addr addr, const void *data, Size size) override;
virtual Size size() const {
return contents_.size();
};
virtual Byte *base() {
return &contents_[0];
}
protected:
Size wordSize_;
std::vector<Byte> contents_;
Size wordSize_;
};
///////////////////////////////////////////////////////////////////////////////
@ -59,65 +51,14 @@ public:
~RomMemDevice();
virtual void write(Addr, Word);
};
///////////////////////////////////////////////////////////////////////////////
class Core;
class DiskControllerMemDevice : public MemDevice {
public:
DiskControllerMemDevice(Size wordSize, Size blockSize, Core &c);
virtual Word read(Addr);
virtual void write(Addr, Word);
virtual Size size() const {
return uint64_t(wordSize_) * 6;
}
void addDisk(Byte *file, Size n) {
disks_.push_back(Disk(file, n));
}
private:
enum Status {
OK = 0,
INVALID_DISK,
INVALID_BLOCK
};
struct Disk {
Disk(Byte *f, Size n)
: file(f)
, blocks(n)
{}
Byte *file;
Size blocks;
};
Word curDisk_;
Word curBlock_;
Word nBlocks_;
Word physAddr_;
Word command_;
Word status_;
Size wordSize_;
Size blockSize_;
Core &core_;
std::vector<Disk> disks_;
void write(Addr addr, const void *data, Size size) override;
};
///////////////////////////////////////////////////////////////////////////////
class MemoryUnit {
public:
MemoryUnit(Size pageSize, Size addrBytes, bool disableVm = false);
void attach(MemDevice &m, Addr start, Addr end);
struct PageFault {
PageFault(Addr a, bool nf)
: faultAddr(a)
@ -127,24 +68,27 @@ public:
bool notFound;
};
Word read(Addr, bool sup);
Word fetch(Addr, bool sup);
void write(Addr, Word, bool sup, Size);
MemoryUnit(Size pageSize, Size addrBytes, bool disableVm = false);
void attach(MemDevice &m, Addr start, Addr end);
void read(Addr addr, void *data, Size size, bool sup);
void write(Addr addr, const void *data, Size size, bool sup);
void tlbAdd(Addr virt, Addr phys, Word flags);
void tlbRm(Addr va);
void tlbFlush() {
tlb_.clear();
}
private:
class ADecoder {
public:
ADecoder() {}
Word read(Addr a, bool sup, Size wordSize);
void write(Addr a, Word w, bool sup, Size wordSize);
void read(Addr addr, void *data, Size size);
void write(Addr addr, const void *data, Size size);
void map(Addr start, Addr end, MemDevice &md);
private:
@ -196,22 +140,8 @@ public:
void clear();
Size size() const override;
void write(Addr addr, Word w) override;
Word read(Addr addr) override;
Byte *base() override;
void read(uint32_t address, uint32_t length, uint8_t *data);
void write(uint32_t address, uint32_t length, uint8_t *data);
void writeWord(uint32_t address, uint32_t *data);
void writeHalf(uint32_t address, uint32_t *data);
void writeByte(uint32_t address, uint32_t *data);
void read(Addr addr, void *data, Size size) override;
void write(Addr addr, const void *data, Size size) override;
void loadHexImage(std::string path);
@ -219,10 +149,6 @@ private:
uint8_t *get(uint32_t address);
void getBlock(uint32_t address, uint8_t *data);
void getWord(uint32_t address, uint32_t *data);
std::vector<uint8_t*> mem_;
uint32_t page_bits_;
uint32_t size_;

View file

@ -11,4 +11,4 @@ make -C ../runtime/tests/simple
./simX -a rv32i -i ../runtime/tests/dev/vx_dev_main.hex
./simX -a rv32i -i ../runtime/tests/hello/hello.hex
./simX -a rv32i -i ../runtime/tests/nlTest/vx_nl_main.hex
./simX -a rv32i -i ../runtime/tests/simple/vx_simple_main.hex
./simX -a rv32i -i ../runtime/tests/simple/vx_simple.hex

View file

@ -32,7 +32,7 @@ void Warp::step(Pipeline *pipeline) {
/* Fetch and decode. */
Word fetched = core_->icache_fetch(PC_, 0);
Word fetched = core_->icache_fetch(PC_);
auto instr = core_->decoder().decode(fetched);
// Update pipeline