/* Copyright 2023 (C) Peter McGoron * This file is a part of Upsilon, a free and open source software project. * For license terms, refer to the files in `doc/copying` in the Upsilon * source distribution. */ /* TODO: impleement reset for dma and test both separetely */ #include #include "Vwaveform_sim.h" #include "../testbench.hpp" class WaveformTestbench : public TB { private: void refresh_posedge(); void spi_posedge(); public: std::array ram_refresh_data; int cur_ind; void posedge() override; void refresh_data(); WaveformTestbench(int _bailout = 0) : TB(_bailout) , ram_refresh_data{} , cur_ind{0} {} }; void WaveformTestbench::refresh_data() { for (size_t i = 0; i < WORD_AMNT; i++) { uint32_t val = mask_extend(rand(), 20); ram_refresh_data[i] = val; mod.backing_store[i*2] = val & 0xFFFF; mod.backing_store[i*2+1] = val >> 16; } mod.refresh_start = 1; mod.start_addr = 0x12340; } void WaveformTestbench::refresh_posedge() { if (mod.refresh_finished) { mod.refresh_start = 0; } } void WaveformTestbench::spi_posedge() { if (mod.finished) { mod.rdy = 0; // Check for proper DAC register. my_assert(mod.from_master >> 20 == 0x1, "%d", mod.from_master >> 20); uint32_t val = mask_extend(mod.from_master & 0xFFFFF, 20); my_assert(val == ram_refresh_data[cur_ind], "(%d) %X != %X", cur_ind, val, ram_refresh_data[cur_ind]); cur_ind++; if (cur_ind == WORD_AMNT) cur_ind = 0; } else if (!mod.finished && !mod.rdy) { mod.rdy = 1; } } void WaveformTestbench::posedge() { refresh_posedge(); spi_posedge(); } WaveformTestbench *tb; int main(int argc, char *argv[]) { int j = 0; Verilated::commandArgs(argc, argv); // Verilated::traceEverOn(true); Verilated::fatalOnError(false); tb = new WaveformTestbench(); tb->mod.rdy = 1; tb->mod.rst_L = 1; tb->refresh_data(); tb->mod.time_to_wait = 10; tb->mod.halt_on_finish = 1; tb->mod.arm = 1; do { tb->run_clock(); } while (!tb->mod.refresh_finished); printf("first run\n"); do { tb->run_clock(); } while (!tb->mod.waveform_finished); printf("waveform finished\n"); tb->mod.halt_on_finish = 0; tb->mod.arm = 0; tb->run_clock(); tb->mod.arm = 1; tb->mod.halt_on_finish = 1; printf("second run\n"); do { tb->run_clock(); } while (!tb->mod.waveform_finished); tb->mod.rdy = 0; tb->mod.halt_on_finish = 0; tb->mod.refresh_start = 1; do { tb->run_clock(); } while (!tb->mod.refresh_finished); tb->mod.rdy = 1; tb->mod.halt_on_finish = 1; printf("third run\n"); do { tb->run_clock(); } while (!tb->mod.waveform_finished); delete tb; return 0; }