upsilon/gateware/rtl/testbench.hpp

56 lines
1.1 KiB
C++
Raw Normal View History

2023-06-15 12:24:35 -04:00
/* 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.
*/
2023-01-27 17:27:20 -05:00
#pragma once
2023-01-27 17:58:29 -05:00
#include <verilated.h>
2023-01-30 08:07:34 -05:00
#include "util.hpp"
2023-01-27 17:27:20 -05:00
/* https://zipcpu.com/blog/2017/06/21/looking-at-verilator.html */
template <class TOP> class TB {
int tick_count;
int bailout;
2023-01-27 17:58:29 -05:00
public:
TOP mod;
2023-01-30 08:07:34 -05:00
2023-03-14 11:42:41 -04:00
TB(int _bailout = 0) : mod(), bailout(_bailout) {
2023-01-27 17:27:20 -05:00
mod.clk = 0;
tick_count = 0;
}
virtual ~TB() {
mod.final();
}
2024-03-03 17:35:19 -05:00
/* This function is called at the positive edge of ever clock
* cycle.
*
* It's intended use is for glue code, like a bus handler.
*
* The bulk of the simulation code (driving external inputs into the
* simulated module and observing results) should be done outside of
* this function.
*/
2023-02-25 16:17:04 -05:00
virtual void posedge() {}
2023-01-30 08:07:34 -05:00
void run_clock() {
2023-01-27 17:27:20 -05:00
mod.clk = !mod.clk;
mod.eval();
Verilated::timeInc(1);
2023-02-25 16:17:04 -05:00
posedge();
2023-01-30 08:07:34 -05:00
2023-01-27 17:27:20 -05:00
mod.clk = !mod.clk;
mod.eval();
Verilated::timeInc(1);
2023-01-27 17:27:20 -05:00
tick_count++;
2023-03-15 02:24:28 -04:00
if (bailout > 0 && tick_count >= bailout) {
2023-01-27 17:27:20 -05:00
exit(1);
2023-03-15 02:24:28 -04:00
} if (Verilated::gotError()) {
exit(1);
2023-03-15 02:24:28 -04:00
}
2023-01-27 17:27:20 -05:00
}
};