simX updates
This commit is contained in:
@@ -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 main(int argc, char **argv) {
|
||||||
|
|
||||||
int exitcode = 0;
|
int exitcode = 0;
|
||||||
@@ -46,7 +53,17 @@ int main(int argc, char **argv) {
|
|||||||
RAM ram;
|
RAM ram;
|
||||||
Simulator simulator;
|
Simulator simulator;
|
||||||
simulator.attach_ram(&ram);
|
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();
|
exitcode = simulator.run();
|
||||||
|
|
||||||
if (riscv_test) {
|
if (riscv_test) {
|
||||||
|
|||||||
@@ -114,15 +114,19 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
}
|
}
|
||||||
DPN(2, std::endl);
|
DPN(2, std::endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool rd_write = false;
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case NOP:
|
case NOP:
|
||||||
break;
|
break;
|
||||||
case LUI_INST:
|
case LUI_INST:
|
||||||
rddata = (immsrc << 12) & 0xfffff000;
|
rddata = (immsrc << 12) & 0xfffff000;
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case AUIPC_INST:
|
case AUIPC_INST:
|
||||||
rddata = ((immsrc << 12) & 0xfffff000) + PC_;
|
rddata = ((immsrc << 12) & 0xfffff000) + PC_;
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case R_INST: {
|
case R_INST: {
|
||||||
if (func7 & 0x1) {
|
if (func7 & 0x1) {
|
||||||
@@ -245,6 +249,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rd_write = true;
|
||||||
} break;
|
} break;
|
||||||
case I_INST:
|
case I_INST:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
@@ -290,6 +295,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case B_INST:
|
case B_INST:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
@@ -338,12 +344,14 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
nextPC = PC_ + immsrc;
|
nextPC = PC_ + immsrc;
|
||||||
pipeline->stall_warp = true;
|
pipeline->stall_warp = true;
|
||||||
runOnce = true;
|
runOnce = true;
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case JALR_INST:
|
case JALR_INST:
|
||||||
rddata = nextPC;
|
rddata = nextPC;
|
||||||
nextPC = rsdata[0] + immsrc;
|
nextPC = rsdata[0] + immsrc;
|
||||||
pipeline->stall_warp = true;
|
pipeline->stall_warp = true;
|
||||||
runOnce = true;
|
runOnce = true;
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case L_INST: {
|
case L_INST: {
|
||||||
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
|
Word memAddr = ((rsdata[0] + immsrc) & 0xFFFFFFFC); // word aligned
|
||||||
@@ -374,6 +382,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
default:
|
default:
|
||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
rd_write = true;
|
||||||
} break;
|
} break;
|
||||||
case S_INST: {
|
case S_INST: {
|
||||||
Word memAddr = rsdata[0] + immsrc;
|
Word memAddr = rsdata[0] + immsrc;
|
||||||
@@ -409,31 +418,37 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
// CSRRW
|
// CSRRW
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, rsdata[0], t, id_);
|
core_->set_csr(csr_addr, rsdata[0], t, id_);
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// CSRRS
|
// CSRRS
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_);
|
core_->set_csr(csr_addr, csr_value | rsdata[0], t, id_);
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// CSRRC
|
// CSRRC
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_);
|
core_->set_csr(csr_addr, csr_value & ~rsdata[0], t, id_);
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// CSRRWI
|
// CSRRWI
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, rsrc0, t, id_);
|
core_->set_csr(csr_addr, rsrc0, t, id_);
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
// CSRRSI
|
// CSRRSI
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value | rsrc0, t, id_);
|
core_->set_csr(csr_addr, csr_value | rsrc0, t, id_);
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// CSRRCI
|
// CSRRCI
|
||||||
rddata = csr_value;
|
rddata = csr_value;
|
||||||
core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_);
|
core_->set_csr(csr_addr, csr_value & ~rsrc0, t, id_);
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -475,6 +490,7 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
rd_write = true;
|
||||||
break;
|
break;
|
||||||
case (FS | VS):
|
case (FS | VS):
|
||||||
if (func3 == 0x2) {
|
if (func3 == 0x2) {
|
||||||
@@ -764,7 +780,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
rd_write = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case FMADD:
|
case FMADD:
|
||||||
case FMSUB:
|
case FMSUB:
|
||||||
@@ -811,8 +828,8 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
|
|
||||||
rddata = floatToBin(fpDest);
|
rddata = floatToBin(fpDest);
|
||||||
}
|
}
|
||||||
}
|
rd_write = true;
|
||||||
break;
|
} break;
|
||||||
case GPGPU:
|
case GPGPU:
|
||||||
switch (func3) {
|
switch (func3) {
|
||||||
case 0: {
|
case 0: {
|
||||||
@@ -1767,20 +1784,22 @@ void Warp::execute(const Instr &instr, Pipeline *pipeline) {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
int rdt = instr.getRDType();
|
if (rd_write) {
|
||||||
switch (rdt) {
|
int rdt = instr.getRDType();
|
||||||
case 1:
|
switch (rdt) {
|
||||||
if (rdest) {
|
case 1:
|
||||||
D(2, "[" << std::dec << t << "] Dest Regs: r" << rdest << "=0x" << std::hex << std::hex << rddata);
|
if (rdest) {
|
||||||
iregs[rdest] = rddata;
|
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);
|
Decoder decoder(arch);
|
||||||
MemoryUnit mu(0, arch.wsize(), true);
|
MemoryUnit mu(0, arch.wsize(), true);
|
||||||
|
|
||||||
RAM old_ram((1<<12), (1<<20));
|
RAM ram((1<<12), (1<<20));
|
||||||
old_ram.loadHexImage(imgFileName.c_str());
|
|
||||||
|
|
||||||
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;
|
struct stat hello;
|
||||||
fstat(0, &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) {
|
void RAM::loadBinImage(const char* path) {
|
||||||
if (c >= 'A' && c <= 'F')
|
std::ifstream ifs(path);
|
||||||
return c - 'A' + 10;
|
if (!ifs) {
|
||||||
if (c >= 'a' && c <= 'f')
|
std::cout << "error: " << path << " not found" << std::endl;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
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();
|
this->clear();
|
||||||
FILE *fp = fopen(&path[0], "r");
|
this->write(STARTUP_ADDR, content.data(), size);
|
||||||
if (fp == 0) {
|
}
|
||||||
std::cout << path << " not found" << std::endl;
|
|
||||||
|
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);
|
ifs.seekg(0, ifs.end);
|
||||||
uint32_t size = ftell(fp);
|
uint32_t size = ifs.tellg();
|
||||||
fseek(fp, 0, SEEK_SET);
|
std::vector<char> content(size);
|
||||||
char *content = new char[size];
|
ifs.seekg(0, ifs.beg);
|
||||||
int x = fread(content, 1, size, fp);
|
ifs.read(content.data(), size);
|
||||||
if (!x) {
|
|
||||||
std::cout << "COULD NOT READ FILE\n";
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
char *line = content;
|
char *line = content.data();
|
||||||
|
|
||||||
while (1) {
|
this->clear();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
if (line[0] == ':') {
|
if (line[0] == ':') {
|
||||||
uint32_t byteCount = hToI_old(line + 1, 2);
|
uint32_t byteCount = hToI(line + 1, 2);
|
||||||
uint32_t nextAddr = hToI_old(line + 3, 4) + offset;
|
uint32_t nextAddr = hToI(line + 3, 4) + offset;
|
||||||
uint32_t key = hToI_old(line + 7, 2);
|
uint32_t key = hToI(line + 7, 2);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 0:
|
case 0:
|
||||||
for (uint32_t i = 0; i < byteCount; i++) {
|
for (uint32_t i = 0; i < byteCount; i++) {
|
||||||
unsigned add = nextAddr + i;
|
uint32_t addr = nextAddr + i;
|
||||||
*this->get(add) = hToI_old(line + 9 + i * 2, 2);
|
uint32_t value = hToI(line + 9 + i * 2, 2);
|
||||||
|
*this->get(addr) = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
offset = hToI_old(line + 9, 4) << 4;
|
offset = hToI(line + 9, 4) << 4;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
offset = hToI_old(line + 9, 4) << 16;
|
offset = hToI(line + 9, 4) << 16;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (*line != '\n' && size != 0) {
|
while (*line != '\n' && size != 0) {
|
||||||
line++;
|
++line;
|
||||||
size--;
|
--size;
|
||||||
}
|
}
|
||||||
if (size <= 1)
|
if (size <= 1)
|
||||||
break;
|
break;
|
||||||
line++;
|
++line;
|
||||||
size--;
|
--size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content)
|
|
||||||
delete[] content;
|
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,9 @@ public:
|
|||||||
void read(Addr addr, void *data, Size size) override;
|
void read(Addr addr, void *data, Size size) override;
|
||||||
void write(Addr addr, const 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:
|
private:
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <string.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -177,4 +178,11 @@ uint8_t vortex::fpBinIsInf(uint32_t din) {
|
|||||||
return 2; // positive infinity
|
return 2; // positive infinity
|
||||||
}
|
}
|
||||||
return 0; // not 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
|
// check floating-point number in binary format is infinity
|
||||||
uint8_t fpBinIsInf(uint32_t din);
|
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. */
|
/* Fetch and decode. */
|
||||||
|
|
||||||
Word fetched = core_->icache_fetch(PC_);
|
Word fetched = core_->icache_fetch(PC_);
|
||||||
auto instr = core_->decoder().decode(fetched);
|
auto instr = core_->decoder().decode(fetched, PC_);
|
||||||
|
|
||||||
// Update pipeline
|
// Update pipeline
|
||||||
pipeline->valid = true;
|
pipeline->valid = true;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ struct vtype {
|
|||||||
int vsew;
|
int vsew;
|
||||||
int vlmul;
|
int vlmul;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Warp {
|
class Warp {
|
||||||
public:
|
public:
|
||||||
Warp(Core *core, Word id);
|
Warp(Core *core, Word id);
|
||||||
|
|||||||
Reference in New Issue
Block a user