19 std::ostringstream
cpp;
47#include <verilated_fst_c.h>
49#include <verilated_vcd_c.h>
55#include "verilator_sim.h"
57std::unique_ptr<mm_magic_t> memories[)"
59// ======== Entry point for calling kernel from host device (C code) ========
63 // initialize memories before verilator
64 master = std::make_unique<mmio_t>(CTRL_BEAT_BYTES);)"
67 for (
size_t i = 0;
i <
kernel.GetOperation().type().Arguments().size(); ++
i)
75 cpp <<
" memories[" <<
m <<
"] = std::make_unique<mm_magic_t>();" << std::endl;
76 cpp <<
" memories[" <<
m <<
"]->init((uint8_t *) a" <<
i <<
", 1UL << 31, " << size
77 <<
", 64, MEMORY_LATENCY);" << std::endl;
84 verilator_init(0, nullptr);
88 // initialize struct with control addresses
89 RHLSAXI_substruct_create
90 // wait for accelerator to be ready
91 while (!read(RHLSAXI_substruct->ready));
93 // use relative addressing for now - i.e. skip pointer arguments
98 auto type =
kernel.GetOperation().type().Arguments()[
i].get();
102 cpp <<
" write(RHLSAXI_substruct->i_data_" <<
i <<
", a" <<
i <<
");" << std::endl;
108 // start the accelerator
109 write(RHLSAXI_substruct->start, 1);
110 size_t start_cycles = get_cycles();
112 // wait for computation to be done
113 while (!read(RHLSAXI_substruct->done));
114 size_t end_cycles = get_cycles();
117 cpp <<
"auto result = read(RHLSAXI_substruct->o_data_0);" << std::endl;
119 std::cerr << "Accelerator took " << end_cycles - start_cycles << " cycles" << std::endl;
120 write(RHLSAXI_substruct->finish, 1);
127extern "C" void reference_load(void *addr, uint64_t width) {
130extern "C" void reference_store(void *addr, uint64_t width) {
133extern uint64_t main_time;
134uint64_t clock_cycles = 0;
135extern std::unique_ptr<mmio_t> master;
139extern VerilatedFstC *tfp;
141extern VerilatedVcdC *tfp;
146 assert(m = dynamic_cast<mmio_t *>(master.get()));
148 // ASSUMPTION: All models have *no* combinational paths through I/O
149 // Step 1: Clock lo -> propagate signals between DUT and software models
150 AXI_LITE_SLAVE_CONNECT_VERILATOR_POS(top, io_s_ctrl, m, CTRL_BEAT_BYTES)
162 cpp <<
" AXI_FULL_MM_CONNECT_VERILATOR_POS(top, io_m_write_" <<
m_write++ <<
", memories["
163 <<
i <<
"], " << size <<
")" << std::endl;
167 cpp <<
" AXI_FULL_READ_ONLY_MM_CONNECT_VERILATOR_POS(top, io_m_read_" <<
m_read++
168 <<
", memories[" <<
i <<
"], " << size <<
")" << std::endl;
175 tfp->dump((double)main_time);
183 top->eval(); // This shouldn't do much
186 tfp->dump((double)main_time);
193 // Step 2: Clock high, tick all software models and evaluate DUT with posedge
194 AXI_LITE_SLAVE_CONNECT_VERILATOR_POS_EDGE(top, io_s_ctrl, m)
205 cpp <<
" AXI_FULL_MM_CONNECT_VERILATOR_POS_EDGE(top, io_m_write_" <<
m_write++
206 <<
", memories[" <<
i <<
"])" << std::endl;
210 cpp <<
" AXI_FULL_READ_ONLY_MM_CONNECT_VERILATOR_POS_EDGE(top, io_m_read_" <<
m_read++
211 <<
", memories[" <<
i <<
"])" << std::endl;
std::vector< rvsdg::RegionResult * > get_mem_reqs(const rvsdg::LambdaNode &lambda)
std::vector< rvsdg::RegionArgument * > get_reg_args(const rvsdg::LambdaNode &lambda)
static int JlmSize(const jlm::rvsdg::Type *type)
const rvsdg::LambdaNode * get_hls_lambda(llvm::LlvmRvsdgModule &rm)
std::vector< rvsdg::RegionArgument * > get_mem_resps(const rvsdg::LambdaNode &lambda)
std::string GetText(llvm::LlvmRvsdgModule &rm) override
std::tuple< size_t, std::string, std::string > GetParameterListAsC(const rvsdg::LambdaNode &kernel)
std::optional< std::string > GetReturnTypeAsC(const rvsdg::LambdaNode &kernel)
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.