rebase master update
This commit is contained in:
@@ -1,11 +1,30 @@
|
||||
all: testbench.iv
|
||||
TOP = VX_fifo_queue
|
||||
|
||||
testbench.iv: testbench.v
|
||||
iverilog testbench.v -o testbench.iv -I ../../rtl/
|
||||
PARAMS ?=
|
||||
|
||||
run: testbench.iv
|
||||
! vvp testbench.iv | grep 'ERROR' || false
|
||||
INCLUDE = -I../../rtl/ -I../../rtl/libs
|
||||
|
||||
SRCS = main.cpp
|
||||
|
||||
all: build
|
||||
|
||||
CF += -std=c++11 -fms-extensions -I../..
|
||||
VF += $(PARAMS)
|
||||
|
||||
VF += --language 1800-2009 --assert -Wall --trace
|
||||
VF += -Wno-DECLFILENAME
|
||||
VF += --x-initial unique
|
||||
VF += -exe $(SRCS) $(INCLUDE)
|
||||
VF += $(PARAMS)
|
||||
|
||||
gen:
|
||||
verilator $(VF) -cc $(TOP).v -CFLAGS '$(CF)' --exe $(SRCS)
|
||||
|
||||
build: gen
|
||||
(cd obj_dir && make -j -f V$(TOP).mk)
|
||||
|
||||
run: build
|
||||
(cd obj_dir && ./V$(TOP))
|
||||
|
||||
clean:
|
||||
rm testbench.iv
|
||||
|
||||
rm -rf obj_dir
|
||||
|
||||
93
hw/unit_tests/generic_queue/main.cpp
Normal file
93
hw/unit_tests/generic_queue/main.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "vl_simulator.h"
|
||||
#include "VVX_fifo_queue.h"
|
||||
#include <iostream>
|
||||
|
||||
#define MAX_TICKS 20
|
||||
|
||||
#define CHECK(x) \
|
||||
do { \
|
||||
if (x) \
|
||||
break; \
|
||||
std::cout << "FAILED: " << #x << std::endl; \
|
||||
std::abort(); \
|
||||
} while (false)
|
||||
|
||||
uint64_t ticks = 0;
|
||||
|
||||
double sc_time_stamp() {
|
||||
return ticks;
|
||||
}
|
||||
|
||||
using Device = VVX_fifo_queue;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Initialize Verilators variables
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
vl_simulator<Device> sim;
|
||||
|
||||
// run test
|
||||
ticks = sim.reset(0);
|
||||
while (ticks < MAX_TICKS) {
|
||||
switch (ticks) {
|
||||
case 0:
|
||||
// initial values
|
||||
sim->pop = 0;
|
||||
sim->push = 0;
|
||||
ticks = sim.step(ticks, 2);
|
||||
break;
|
||||
case 2:
|
||||
// Verify outputs
|
||||
CHECK(sim->full == 0x0);
|
||||
CHECK(sim->empty == 0x1);
|
||||
// push 0xa
|
||||
sim->pop = 0;
|
||||
sim->push = 1;
|
||||
sim->data_in = 0xa;
|
||||
break;
|
||||
case 4:
|
||||
// verify outputs
|
||||
CHECK(sim->data_out == 0xa);
|
||||
CHECK(sim->full == 0x0);
|
||||
CHECK(sim->empty == 0x0);
|
||||
// push 0xb
|
||||
sim->pop = 0;
|
||||
sim->push = 1;
|
||||
sim->data_in = 0xb;
|
||||
break;
|
||||
case 6:
|
||||
// verify outputs
|
||||
CHECK(sim->data_out == 0xa);
|
||||
CHECK(sim->full == 0x1);
|
||||
CHECK(sim->empty == 0x0);
|
||||
// pop
|
||||
sim->pop = 1;
|
||||
sim->push = 0;
|
||||
break;
|
||||
case 8:
|
||||
// verify outputs
|
||||
CHECK(sim->data_out == 0xb);
|
||||
CHECK(sim->full == 0x0);
|
||||
CHECK(sim->empty == 0x0);
|
||||
// pop
|
||||
sim->pop = 1;
|
||||
sim->push = 0;
|
||||
break;
|
||||
case 10:
|
||||
// verify outputs
|
||||
CHECK(sim->full == 0x0);
|
||||
CHECK(sim->empty == 0x1);
|
||||
sim->pop = 0;
|
||||
sim->push = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// advance clock
|
||||
ticks = sim.step(ticks, 2);
|
||||
}
|
||||
|
||||
std::cout << "PASSED!" << std::endl;
|
||||
std::cout << "Simulation time: " << std::dec << ticks/2 << " cycles" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
81
hw/unit_tests/generic_queue/vl_simulator.h
Normal file
81
hw/unit_tests/generic_queue/vl_simulator.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include "verilated.h"
|
||||
|
||||
#ifdef VM_TRACE
|
||||
#include <verilated_vcd_c.h> // Trace file format header
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
class vl_simulator {
|
||||
private:
|
||||
|
||||
T top_;
|
||||
#ifdef VM_TRACE
|
||||
VerilatedVcdC tfp_;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
vl_simulator() {
|
||||
top_.clk = 0;
|
||||
top_.reset = 0;
|
||||
#ifdef VM_TRACE
|
||||
Verilated::traceEverOn(true);
|
||||
top_.trace(&tfp_, 99);
|
||||
tfp_.open("trace.vcd");
|
||||
#endif
|
||||
}
|
||||
|
||||
~vl_simulator() {
|
||||
#ifdef VM_TRACE
|
||||
tfp_.close();
|
||||
#endif
|
||||
top_.final();
|
||||
}
|
||||
|
||||
uint64_t reset(uint64_t ticks) {
|
||||
top_.reset = 1;
|
||||
ticks = this->step(ticks, 2);
|
||||
top_.reset = 0;
|
||||
return ticks;
|
||||
}
|
||||
|
||||
uint64_t step(uint64_t ticks, uint32_t count = 1) {
|
||||
while (count--) {
|
||||
top_.eval();
|
||||
#ifdef VM_TRACE
|
||||
tfp_.dump(ticks);
|
||||
#endif
|
||||
top_.clk = !top_.clk;
|
||||
++ticks;
|
||||
}
|
||||
return ticks;
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
return &top_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void vl_setw(uint32_t* sig, Args&&... args) {
|
||||
std::array<uint32_t, sizeof... (Args)> arr{static_cast<uint32_t>(std::forward<Args>(args))...};
|
||||
for (size_t i = 0; i < sizeof... (Args); ++i) {
|
||||
sig[i] = arr[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
int vl_cmpw(const uint32_t* sig, Args&&... args) {
|
||||
std::array<uint32_t, sizeof... (Args)> arr{static_cast<uint32_t>(std::forward<Args>(args))...};
|
||||
for (size_t i = 0; i < sizeof... (Args); ++i) {
|
||||
if (sig[i] < arr[i])
|
||||
return -1;
|
||||
if (sig[i] > arr[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user