diff --git a/src/finn/qnn-data/cpp/verilator_fifosim.cpp b/src/finn/qnn-data/cpp/verilator_fifosim.cpp new file mode 100644 index 0000000000000000000000000000000000000000..535a81005ca69bcc2998ee0c1d0a1845747647b7 --- /dev/null +++ b/src/finn/qnn-data/cpp/verilator_fifosim.cpp @@ -0,0 +1,165 @@ +/* Copyright (C) 2022, Advanced Micro Devices, Inc. +All rights reserved. +# +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +# +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +# +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +# +* Neither the name of FINN nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. +# +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/* +verilator -Wno-fatal -Mdir . -y /data/finn/sickag/vivado_stitch_proj_k9817tc7 --CFLAGS "--std=c++11" -O3 --x-assign fast --x-initial fast --noassert --cc finn_design_wrapper.v --top-module finn_design_wrapper --exe sim-semseg.cpp --threads 4 + +make OPT_FAST="-O3 -march=native" -j4 -C $(pwd) -f Vfinn_design_wrapper.mk Vfinn_design_wrapper +*/ + +#include <iostream> +#include <fstream> +#include <cstddef> +#include <chrono> +#include "verilated.h" +#include "verilated_vcd_c.h" +#include "Vfinn_design_wrapper.h" + +using namespace std; + +Vfinn_design_wrapper * top; + +// code taken from pyverilator_wrapper.cpp generated by PyVerilator + +// this is required by verilator for verilog designs using $time +// main_time is incremented in eval +double main_time = 0; + +double sc_time_stamp() { +return main_time; +} +// function definitions +// helper functions for basic verilator tasks +extern "C" { //Open an extern C closed below +Vfinn_design_wrapper* construct() { + Verilated::commandArgs(0, (const char**) nullptr); + Vfinn_design_wrapper* top = new Vfinn_design_wrapper(); + return top; +} +int eval(Vfinn_design_wrapper* top) { + top->eval(); + main_time++; + return 0; +} +int destruct(Vfinn_design_wrapper* top) { + if (top != nullptr) { + delete top; + top = nullptr; + } + return 0; +} +} + +// end of code taken from pyverilator_wrapper.cpp generated by PyVerilator + +inline void toggle_clk() { + eval(top); + top->ap_clk = 1; + eval(top); + top->ap_clk = 0; +} + +void reset() { + top->ap_rst_n = 0; + for(unsigned i = 0; i < 10; i++) { + toggle_clk(); + } + top->ap_rst_n = 1; +} + +int main(int argc, char *argv[]) { + top = construct(); + + unsigned n_iters_per_input = @ITERS_PER_INPUT@; + unsigned n_iters_per_output = @ITERS_PER_OUTPUT@; + unsigned n_inputs = @N_INPUTS@; + unsigned max_iters = @MAX_ITERS@; + + reset(); + + top->m_axis_0_tready = 1; + top->s_axis_0_tvalid = 1; + + unsigned n_in_txns = 0, n_out_txns = 0, iters = 0; + unsigned latency = 0; + + bool exit_criterion = false; + + cout << "Simulation starting" << endl; + cout << "Number of inputs to write " << n_iters_per_input * n_inputs << endl; + cout << "Number of outputs to expect " << n_iters_per_output * n_inputs << endl; + cout << "Timeout clock cycles " << max_iters << endl; + + chrono::steady_clock::time_point begin = chrono::steady_clock::now(); + + while(!exit_criterion) { + if(top->s_axis_0_tready == 1) { + n_in_txns++; + if(n_in_txns == n_iters_per_input * n_inputs) { + top->s_axis_0_tvalid = 0; + cout << "All inputs written at cycle " << iters << endl; + } + } + if(top->m_axis_0_tvalid == 1) { + n_out_txns++; + if(n_out_txns == n_iters_per_output) { + latency = iters; + } + } + toggle_clk(); + iters++; + if(iters % 1000 == 0) { + cout << "Elapsed iters " << iters << " inps " << n_in_txns << " outs " << n_out_txns << endl; + chrono::steady_clock::time_point end = chrono::steady_clock::now(); + cout << "Elapsed since last report = " << chrono::duration_cast<chrono::seconds>(end - begin).count() << "[s]" << endl; + begin = end; + } + + exit_criterion = ((n_in_txns >= n_iters_per_input * n_inputs) && (n_out_txns >= n_iters_per_output * n_inputs)) || (iters > max_iters); + } + + cout << "Simulation finished" << endl; + cout << "Number of inputs consumed " << n_in_txns << endl; + cout << "Number of outputs produced " << n_out_txns << endl; + cout << "Number of clock cycles " << iters << endl; + + ofstream results_file; + results_file.open("results.txt", ios::out | ios::trunc); + results_file << "N_IN_TXNS" << "\t" << n_in_txns << endl; + results_file << "N_OUT_TXNS" << "\t" << n_out_txns << endl; + results_file << "N_CYCLES" << "\t" << iters << endl; + results_file << "LATENCY" << "\t" << latency << endl; +@FIFO_DEPTH_LOGGING@ + results_file.close(); + + + + destruct(top); + + return 0; +}