blob: aa05c8c2663cd545aa801ebd78ad58269ea4f4a2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <vta/dpi/tsim.h>
#if VM_TRACE
#include <verilated_vcd_c.h>
#endif
#if VM_TRACE
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
#endif
static VTAContextHandle _ctx = nullptr;
static VTAMemDPIFunc _mem_dpi = nullptr;
static VTAHostDPIFunc _host_dpi = nullptr;
void VTAHostDPI(dpi8_t* exit,
dpi8_t* req_valid,
dpi8_t* req_opcode,
dpi8_t* req_addr,
dpi32_t* req_value,
dpi8_t req_deq,
dpi8_t resp_valid,
dpi32_t resp_value) {
assert(_host_dpi != nullptr);
(*_host_dpi)(_ctx, exit, req_valid, req_opcode,
req_addr, req_value, req_deq,
resp_valid, resp_value);
}
void VTAMemDPI(dpi8_t req_valid,
dpi8_t req_opcode,
dpi8_t req_len,
dpi64_t req_addr,
dpi8_t wr_valid,
dpi64_t wr_value,
dpi8_t* rd_valid,
dpi64_t* rd_value,
dpi8_t rd_ready) {
assert(_mem_dpi != nullptr);
(*_mem_dpi)(_ctx, req_valid, req_opcode, req_len,
req_addr, wr_valid, wr_value,
rd_valid, rd_value, rd_ready);
}
void VTADPIInit(VTAContextHandle handle,
VTAHostDPIFunc host_dpi,
VTAMemDPIFunc mem_dpi) {
_ctx = handle;
_host_dpi = host_dpi;
_mem_dpi = mem_dpi;
}
// Override Verilator finish definition
// VL_USER_FINISH needs to be defined when compiling Verilator code
void vl_finish(const char* filename, int linenum, const char* hier) {
Verilated::gotFinish(true);
}
int VTADPISim(uint64_t max_cycles) {
uint64_t trace_count = 0;
Verilated::flushCall();
Verilated::gotFinish(false);
#if VM_TRACE
uint64_t start = 0;
#endif
VL_TSIM_NAME* top = new VL_TSIM_NAME;
#if VM_TRACE
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
top->trace(tfp, 99);
tfp->open(STRINGIZE_VALUE_OF(TSIM_TRACE_FILE));
#endif
// reset
for (int i = 0; i < 10; i++) {
top->reset = 1;
top->clock = 0;
top->eval();
#if VM_TRACE
if (trace_count >= start)
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
#endif
top->clock = 1;
top->eval();
#if VM_TRACE
if (trace_count >= start)
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
#endif
trace_count++;
}
top->reset = 0;
// start simulation
while (!Verilated::gotFinish() && trace_count < max_cycles) {
top->clock = 0;
top->eval();
#if VM_TRACE
if (trace_count >= start)
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
#endif
top->clock = 1;
top->eval();
#if VM_TRACE
if (trace_count >= start)
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
#endif
trace_count++;
}
#if VM_TRACE
tfp->close();
#endif
delete top;
return 0;
}