mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
simX updates
This commit is contained in:
parent
cfed87f416
commit
51673665b5
9 changed files with 136 additions and 66 deletions
|
@ -33,6 +33,13 @@ static void parse_args(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
inline const char* fileExtension(const char* filepath) {
|
||||
const char *ext = strrchr(filepath, '.');
|
||||
if (ext == NULL || ext == filepath)
|
||||
return "";
|
||||
return ext + 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int exitcode = 0;
|
||||
|
@ -46,7 +53,17 @@ int main(int argc, char **argv) {
|
|||
RAM ram;
|
||||
Simulator simulator;
|
||||
simulator.attach_ram(&ram);
|
||||
simulator.load_ihex(program);
|
||||
|
||||
std::string program_ext(fileExtension(program));
|
||||
if (program_ext == "bin") {
|
||||
simulator.load_bin(program);
|
||||
} else if (program_ext == "hex") {
|
||||
simulator.load_ihex(program);
|
||||
} else {
|
||||
std::cout << "*** error: only *.bin or *.hex images supported." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
exitcode = simulator.run();
|
||||
|
||||
if (riscv_test) {
|
||||
|
|
|
@ -114,15 +114,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
}
|
||||
DPN(2, std::endl);
|
||||
}
|
||||
|
||||
bool rd_write = false;
|
||||
|
||||
switch (opcode) {
|
||||
case NOP:
|
||||
break;
|
||||
case LUI_INST:
|
||||
rddata = (immsrc << 12) & 0xfffff000;
|
||||
rd_write = true;
|
||||
break;
|
||||
case AUIPC_INST:
|
||||
rddata = ((immsrc << 12) & 0xfffff000) + PC_;
|
||||
rd_write = true;
|
||||
break;
|
||||
case R_INST: {
|
||||
if (func7 & 0x1) {
|
||||
|
@ -245,6 +249,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
std::abort();
|
||||
}
|
||||
}
|
||||
rd_write = true;
|
||||
} break;
|
||||
case I_INST:
|
||||
switch (func3) {
|
||||
|
@ -290,6 +295,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
default:
|
||||
std::abort();
|
||||
}
|
||||
rd_write = true;
|
||||
break;
|
||||
case B_INST:
|
||||
switch (func3) {
|
||||
|
@ -338,12 +344,14 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
nextPC = PC_ + immsrc;
|
||||
pipeline->stall_warp = true;
|
||||
runOnce = true;
|
||||
rd_write = true;
|
||||
break;
|
||||
case JALR_INST:
|
||||
rddata = nextPC;
|
||||
nextPC = rsdata[0] + immsrc;
|
||||
pipeline->stall_warp = true;
|
||||
runOnce = true;
|
||||
rd_write = true;
|
||||
break;
|
||||
case L_INST: {
|
||||
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
|
||||
|
@ -374,6 +382,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
default:
|
||||
std::abort();
|
||||
}
|
||||
rd_write = true;
|
||||
} break;
|
||||
case S_INST: {
|
||||
Word memAddr = rsdata[0] + immsrc;
|
||||
|
@ -409,31 +418,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
// CSRRW
|
||||
rddata = csr_value;
|
||||
core_->set_csr(csr_addr, rsdata[0], t, id_);
|
||||
rd_write = true;
|
||||
break;
|
||||
case 2:
|
||||
// CSRRS
|
||||
rddata = csr_value;
|
||||
core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_);
|
||||
rd_write = true;
|
||||
break;
|
||||
case 3:
|
||||
// CSRRC
|
||||
rddata = csr_value;
|
||||
core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_);
|
||||
rd_write = true;
|
||||
break;
|
||||
case 5:
|
||||
// CSRRWI
|
||||
rddata = csr_value;
|
||||
core_->set_csr(csr_addr, rsrc0, t, id_);
|
||||
rd_write = true;
|
||||
break;
|
||||
case 6:
|
||||
// CSRRSI
|
||||
rddata = csr_value;
|
||||
core_->set_csr(csr_addr, csr_value | rsrc0, t, id_);
|
||||
rd_write = true;
|
||||
break;
|
||||
case 7:
|
||||
// CSRRCI
|
||||
rddata = csr_value;
|
||||
core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_);
|
||||
rd_write = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -475,6 +490,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
rd_write = true;
|
||||
break;
|
||||
case (FS | VS):
|
||||
if (func3 == 0x2) {
|
||||
|
@ -764,7 +780,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
rd_write = true;
|
||||
break;
|
||||
|
||||
case FMADD:
|
||||
case FMSUB:
|
||||
|
@ -811,8 +828,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
|
||||
rddata = floatToBin(fpDest);
|
||||
}
|
||||
}
|
||||
break;
|
||||
rd_write = true;
|
||||
} break;
|
||||
case GPGPU:
|
||||
switch (func3) {
|
||||
case 0: {
|
||||
|
@ -1767,20 +1784,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||
std::abort();
|
||||
}
|
||||
|
||||
int rdt = instr.getRDType();
|
||||
switch (rdt) {
|
||||
case 1:
|
||||
if (rdest) {
|
||||
D(2, "[" << std::dec << t << "] Dest Regs: r" << rdest << "=0x" << std::hex << std::hex << rddata);
|
||||
iregs[rdest] = rddata;
|
||||
if (rd_write) {
|
||||
int rdt = instr.getRDType();
|
||||
switch (rdt) {
|
||||
case 1:
|
||||
if (rdest) {
|
||||
D(2, "[" << std::dec << t << "] Dest Regs: r" << rdest << "=0x" << std::hex << std::hex << rddata);
|
||||
iregs[rdest] = rddata;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
D(2, "[" << std::dec << t << "] Dest Regs: fr" << rdest << "=0x" << std::hex << std::hex << rddata);
|
||||
fregs[rdest] = rddata;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
D(2, "[" << std::dec << t << "] Dest Regs: fr" << rdest << "=0x" << std::hex << std::hex << rddata);
|
||||
fregs[rdest] = rddata;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,10 +53,19 @@ int main(int argc, char **argv) {
|
|||
Decoder decoder(arch);
|
||||
MemoryUnit mu(0, arch.wsize(), true);
|
||||
|
||||
RAM old_ram((1<<12), (1<<20));
|
||||
old_ram.loadHexImage(imgFileName.c_str());
|
||||
RAM ram((1<<12), (1<<20));
|
||||
|
||||
mu.attach(old_ram, 0, 0xFFFFFFFF);
|
||||
std::string program_ext(fileExtension(imgFileName.c_str()));
|
||||
if (program_ext == "bin") {
|
||||
ram.loadBinImage(imgFileName.c_str());
|
||||
} else if (program_ext == "hex") {
|
||||
ram.loadHexImage(imgFileName.c_str());
|
||||
} else {
|
||||
std::cout << "*** error: only *.bin or *.hex images supported." << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mu.attach(ram, 0, 0xFFFFFFFF);
|
||||
|
||||
struct stat hello;
|
||||
fstat(0, &hello);
|
||||
|
|
99
simX/mem.cpp
99
simX/mem.cpp
|
@ -232,74 +232,85 @@ void RAM::write(Addr addr, const void *data, Size size) {
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t hti_old(char c) {
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return c - '0';
|
||||
}
|
||||
|
||||
static uint32_t hToI_old(char *c, uint32_t size) {
|
||||
uint32_t value = 0;
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
value += hti_old(c[i]) << ((size - i - 1) * 4);
|
||||
void RAM::loadBinImage(const char* path) {
|
||||
std::ifstream ifs(path);
|
||||
if (!ifs) {
|
||||
std::cout << "error: " << path << " not found" << std::endl;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void RAM::loadHexImage(std::string path) {
|
||||
ifs.seekg(0, ifs.end);
|
||||
auto size = ifs.tellg();
|
||||
std::vector<uint8_t> content(size);
|
||||
ifs.seekg(0, ifs.beg);
|
||||
ifs.read((char*)content.data(), size);
|
||||
|
||||
this->clear();
|
||||
FILE *fp = fopen(&path[0], "r");
|
||||
if (fp == 0) {
|
||||
std::cout << path << " not found" << std::endl;
|
||||
this->write(STARTUP_ADDR, content.data(), size);
|
||||
}
|
||||
|
||||
void RAM::loadHexImage(const char* path) {
|
||||
auto hti = [&](char c)->uint32_t {
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
return c - '0';
|
||||
};
|
||||
|
||||
auto hToI = [&](const char *c, uint32_t size)->uint32_t {
|
||||
uint32_t value = 0;
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
value += hti(c[i]) << ((size - i - 1) * 4);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
std::ifstream ifs(path);
|
||||
if (!ifs) {
|
||||
std::cout << "error: " << path << " not found" << std::endl;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
uint32_t size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *content = new char[size];
|
||||
int x = fread(content, 1, size, fp);
|
||||
if (!x) {
|
||||
std::cout << "COULD NOT READ FILE\n";
|
||||
std::abort();
|
||||
}
|
||||
ifs.seekg(0, ifs.end);
|
||||
uint32_t size = ifs.tellg();
|
||||
std::vector<char> content(size);
|
||||
ifs.seekg(0, ifs.beg);
|
||||
ifs.read(content.data(), size);
|
||||
|
||||
int offset = 0;
|
||||
char *line = content;
|
||||
|
||||
while (1) {
|
||||
char *line = content.data();
|
||||
|
||||
this->clear();
|
||||
|
||||
while (true) {
|
||||
if (line[0] == ':') {
|
||||
uint32_t byteCount = hToI_old(line + 1, 2);
|
||||
uint32_t nextAddr = hToI_old(line + 3, 4) + offset;
|
||||
uint32_t key = hToI_old(line + 7, 2);
|
||||
uint32_t byteCount = hToI(line + 1, 2);
|
||||
uint32_t nextAddr = hToI(line + 3, 4) + offset;
|
||||
uint32_t key = hToI(line + 7, 2);
|
||||
switch (key) {
|
||||
case 0:
|
||||
for (uint32_t i = 0; i < byteCount; i++) {
|
||||
unsigned add = nextAddr + i;
|
||||
*this->get(add) = hToI_old(line + 9 + i * 2, 2);
|
||||
uint32_t addr = nextAddr + i;
|
||||
uint32_t value = hToI(line + 9 + i * 2, 2);
|
||||
*this->get(addr) = value;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
offset = hToI_old(line + 9, 4) << 4;
|
||||
offset = hToI(line + 9, 4) << 4;
|
||||
break;
|
||||
case 4:
|
||||
offset = hToI_old(line + 9, 4) << 16;
|
||||
offset = hToI(line + 9, 4) << 16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (*line != '\n' && size != 0) {
|
||||
line++;
|
||||
size--;
|
||||
++line;
|
||||
--size;
|
||||
}
|
||||
if (size <= 1)
|
||||
break;
|
||||
line++;
|
||||
size--;
|
||||
++line;
|
||||
--size;
|
||||
}
|
||||
|
||||
if (content)
|
||||
delete[] content;
|
||||
}
|
|
@ -143,7 +143,9 @@ public:
|
|||
void read(Addr addr, void *data, Size size) override;
|
||||
void write(Addr addr, const void *data, Size size) override;
|
||||
|
||||
void loadHexImage(std::string path);
|
||||
void loadBinImage(const char* path);
|
||||
|
||||
void loadHexImage(const char* path);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdexcept>
|
||||
#include <math.h>
|
||||
#include <climits>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "types.h"
|
||||
#include "util.h"
|
||||
|
@ -177,4 +178,11 @@ uint8_t vortex::fpBinIsInf(uint32_t din) {
|
|||
return 2; // positive infinity
|
||||
}
|
||||
return 0; // not infinity
|
||||
}
|
||||
|
||||
const char* vortex::fileExtension(const char* filepath) {
|
||||
const char *ext = strrchr(filepath, '.');
|
||||
if (ext == NULL || ext == filepath)
|
||||
return "";
|
||||
return ext + 1;
|
||||
}
|
|
@ -45,4 +45,7 @@ uint8_t fpBinIsZero(uint32_t din);
|
|||
// check floating-point number in binary format is infinity
|
||||
uint8_t fpBinIsInf(uint32_t din);
|
||||
|
||||
// return file extension
|
||||
const char* fileExtension(const char* filepath);
|
||||
|
||||
}
|
|
@ -36,7 +36,7 @@ void Warp::step(Pipeline *pipeline) {
|
|||
/* Fetch and decode. */
|
||||
|
||||
Word fetched = core_->icache_fetch(PC_);
|
||||
auto instr = core_->decoder().decode(fetched);
|
||||
auto instr = core_->decoder().decode(fetched, PC_);
|
||||
|
||||
// Update pipeline
|
||||
pipeline->valid = true;
|
||||
|
|
|
@ -37,6 +37,7 @@ struct vtype {
|
|||
int vsew;
|
||||
int vlmul;
|
||||
};
|
||||
|
||||
class Warp {
|
||||
public:
|
||||
Warp(Core *core, Word id);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue