fixed new AFU Driver bugs - now functional

This commit is contained in:
Blaise Tine
2020-09-09 17:05:48 -04:00
parent bf7b0cf340
commit fba2fa03c7
28 changed files with 325 additions and 169 deletions

View File

@@ -4,6 +4,7 @@
#include <iomanip>
#define CCI_LATENCY 8
#define CCI_RAND_MOD 8
#define CCI_RQ_SIZE 16
#define CCI_WQ_SIZE 16
@@ -26,7 +27,6 @@ opae_sim::opae_sim() {
// Turn off assertion before reset
Verilated::assertOn(false);
stop_ = false;
vortex_afu_ = new Vvortex_afu_shim();
#ifdef VCD_OUTPUT
@@ -34,14 +34,17 @@ opae_sim::opae_sim() {
trace_ = new VerilatedVcdC();
vortex_afu_->trace(trace_, 99);
trace_->open("trace.vcd");
#endif
#endif
future_ = std::async(std::launch::async, [&]{
this->reset();
while (stop_) {
this->reset();
stop_ = false;
future_ = std::async(std::launch::async, [&]{
while (!stop_) {
std::lock_guard<std::mutex> guard(mutex_);
this->step();
}
});
});
}
opae_sim::~opae_sim() {
@@ -55,44 +58,68 @@ opae_sim::~opae_sim() {
delete vortex_afu_;
}
void opae_sim::prepare_buffer(uint64_t len, void **buf_addr, uint64_t *wsid, int flags) {
host_alloc_t alloc;
alloc.data = new uint8_t[len];
alloc.size = len;
*wsid = host_allocs_.size();
host_allocs_.push_back(alloc);
int opae_sim::prepare_buffer(uint64_t len, void **buf_addr, uint64_t *wsid, int flags) {
auto alloc = aligned_alloc(CACHE_BLOCK_SIZE, len);
if (alloc == NULL)
return -1;
host_buffer_t buffer;
buffer.data = (uint64_t*)alloc;
buffer.size = len;
buffer.ioaddr = intptr_t(alloc) / CACHE_BLOCK_SIZE;
auto index = host_buffers_.size();
host_buffers_.push_back(buffer);
*buf_addr = alloc;
*wsid = index;
return 0;
}
void opae_sim::release_buffer(uint64_t wsid) {
delete [] host_allocs_[wsid].data;
host_allocs_.erase(host_allocs_.begin() + wsid);
free(host_buffers_[wsid].data);
host_buffers_.erase(host_buffers_.begin() + wsid);
}
void opae_sim::get_io_address(uint64_t wsid, uint64_t *ioaddr) {
*ioaddr = (intptr_t)host_allocs_[wsid].data / GLOBAL_BLOCK_SIZE;
*ioaddr = host_buffers_[wsid].ioaddr * CACHE_BLOCK_SIZE;
}
void opae_sim::write_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t value) {
std::lock_guard<std::mutex> guard(mutex_);
vortex_afu_->vcp2af_sRxPort_c0_mmioWrValid = 1;
vortex_afu_->vcp2af_sRxPort_c0_hdr_resp_type = offset;
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_address = offset / 4;
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_length = 1;
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_tid = 0;
memcpy(vortex_afu_->vcp2af_sRxPort_c0_data, &value, 8);
this->step();
assert(!vortex_afu_->vcp2af_sRxPort_c0_mmioWrValid);
}
void opae_sim::read_mmio64(uint32_t mmio_num, uint64_t offset, uint64_t *value) {
std::lock_guard<std::mutex> guard(mutex_);
vortex_afu_->vcp2af_sRxPort_c0_mmioRdValid = 1;
vortex_afu_->vcp2af_sRxPort_c0_hdr_resp_type = offset;
while (0 == vortex_afu_->af2cp_sTxPort_c2_mmioRdValid);
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_address = offset / 4;
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_length = 1;
vortex_afu_->vcp2af_sRxPort_c0_ReqMmioHdr_tid = 0;
this->step();
assert(!vortex_afu_->vcp2af_sRxPort_c0_mmioRdValid);
assert(vortex_afu_->af2cp_sTxPort_c2_mmioRdValid);
*value = vortex_afu_->af2cp_sTxPort_c2_data;
}
void opae_sim::flush() {
// flush pending CCI requests
}
///////////////////////////////////////////////////////////////////////////////
void opae_sim::reset() {
vortex_afu_->clk = 0;
this->eval();
vortex_afu_->reset = 1;
this->step();
vortex_afu_->reset = 0;
vortex_afu_->clk = 1;
this->eval();
// Turn on assertion after reset
Verilated::assertOn(true);
}
void opae_sim::step() {
@@ -144,7 +171,7 @@ void opae_sim::sRxPort_bus() {
vortex_afu_->vcp2af_sRxPort_c0_rspValid = 0;
if (cci_rd_index != -1) {
vortex_afu_->vcp2af_sRxPort_c0_rspValid = 1;
memcpy(vortex_afu_->vcp2af_sRxPort_c0_data, cci_reads_[cci_rd_index].block.data(), GLOBAL_BLOCK_SIZE);
memcpy(vortex_afu_->vcp2af_sRxPort_c0_data, cci_reads_[cci_rd_index].block.data(), CACHE_BLOCK_SIZE);
vortex_afu_->vcp2af_sRxPort_c0_hdr_mdata = cci_reads_[cci_rd_index].mdata;
cci_reads_.erase(cci_reads_.begin() + cci_rd_index);
}
@@ -172,20 +199,20 @@ void opae_sim::sTxPort_bus() {
// process read requests
if (vortex_afu_->af2cp_sTxPort_c0_valid && !vortex_afu_->vcp2af_sRxPort_c0_TxAlmFull) {
cci_rd_req_t cci_req;
cci_req.cycles_left = CCI_LATENCY;
cci_req.cycles_left = CCI_LATENCY + (timestamp % CCI_RAND_MOD);
cci_req.mdata = vortex_afu_->af2cp_sTxPort_c0_hdr_mdata;
auto host_ptr = this->find_host_ptr(vortex_afu_->af2cp_sTxPort_c0_hdr_address);
memcpy(cci_req.block.data(), host_ptr, GLOBAL_BLOCK_SIZE);
auto host_ptr = this->to_host_ptr(vortex_afu_->af2cp_sTxPort_c0_hdr_address);
memcpy(cci_req.block.data(), host_ptr, CACHE_BLOCK_SIZE);
cci_reads_.push_back(cci_req);
}
// process write requests
if (vortex_afu_->af2cp_sTxPort_c1_valid && !vortex_afu_->vcp2af_sRxPort_c1_TxAlmFull) {
cci_wr_req_t cci_req;
cci_req.cycles_left = CCI_LATENCY;
cci_req.cycles_left = CCI_LATENCY + (timestamp % CCI_RAND_MOD);
cci_req.mdata = vortex_afu_->af2cp_sTxPort_c1_hdr_mdata;
auto host_ptr = this->find_host_ptr(vortex_afu_->af2cp_sTxPort_c1_hdr_address);
memcpy(host_ptr, vortex_afu_->af2cp_sTxPort_c1_data, GLOBAL_BLOCK_SIZE);
auto host_ptr = this->to_host_ptr(vortex_afu_->af2cp_sTxPort_c1_hdr_address);
memcpy(host_ptr, vortex_afu_->af2cp_sTxPort_c1_data, CACHE_BLOCK_SIZE);
cci_writes_.push_back(cci_req);
}
}
@@ -207,7 +234,7 @@ void opae_sim::avs_bus() {
vortex_afu_->avs_readdatavalid = 0;
if (dram_rd_index != -1) {
vortex_afu_->avs_readdatavalid = 1;
memcpy(vortex_afu_->avs_readdata, dram_reads_[dram_rd_index].block.data(), GLOBAL_BLOCK_SIZE);
memcpy(vortex_afu_->avs_readdata, dram_reads_[dram_rd_index].block.data(), CACHE_BLOCK_SIZE);
dram_reads_.erase(dram_reads_.begin() + dram_rd_index);
}
@@ -227,9 +254,9 @@ void opae_sim::avs_bus() {
if (vortex_afu_->avs_write) {
assert(0 == vortex_afu_->mem_bank_select);
uint64_t byteen = vortex_afu_->avs_byteenable;
unsigned base_addr = (vortex_afu_->avs_address * GLOBAL_BLOCK_SIZE);
unsigned base_addr = (vortex_afu_->avs_address * CACHE_BLOCK_SIZE);
uint8_t* data = (uint8_t*)(vortex_afu_->avs_writedata);
for (int i = 0; i < GLOBAL_BLOCK_SIZE; i++) {
for (int i = 0; i < CACHE_BLOCK_SIZE; i++) {
if ((byteen >> i) & 0x1) {
ram_[base_addr + i] = data[i];
}
@@ -239,7 +266,8 @@ void opae_sim::avs_bus() {
assert(0 == vortex_afu_->mem_bank_select);
dram_rd_req_t dram_req;
dram_req.cycles_left = DRAM_LATENCY;
ram_.read(vortex_afu_->avs_address * GLOBAL_BLOCK_SIZE, GLOBAL_BLOCK_SIZE, dram_req.block.data());
unsigned base_addr = (vortex_afu_->avs_address * CACHE_BLOCK_SIZE);
ram_.read(base_addr, CACHE_BLOCK_SIZE, dram_req.block.data());
dram_reads_.push_back(dram_req);
}
}
@@ -247,15 +275,14 @@ void opae_sim::avs_bus() {
vortex_afu_->avs_waitrequest = dram_stalled;
}
uint8_t* opae_sim::find_host_ptr(uint64_t addr) {
auto b_addr = addr * GLOBAL_BLOCK_SIZE;
for (auto& host_alloc : host_allocs_) {
auto alloc_addr = (intptr_t)host_alloc.data;
if (b_addr >= alloc_addr
&& b_addr < (alloc_addr + host_alloc.size)) {
return (uint8_t*)b_addr;
uint64_t* opae_sim::to_host_ptr(uint64_t ioaddr) {
for (auto& buffer : host_buffers_) {
if (ioaddr >= buffer.ioaddr
&& ioaddr < (buffer.ioaddr + buffer.size)) {
return buffer.data + (ioaddr - buffer.ioaddr) * (CACHE_BLOCK_SIZE / 8);
}
}
assert(false);
printf("error: to_host_ptr(0x%lx) failed\n", ioaddr);
std::abort();
return nullptr;
}