mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
Verilator testbench for unit tests
This commit is contained in:
parent
4de75fad31
commit
eee74a25cd
7 changed files with 178 additions and 259 deletions
|
@ -1,159 +0,0 @@
|
|||
`timescale 1ns/1ps
|
||||
|
||||
module VX_tb_divide();
|
||||
|
||||
`ifdef TRACE
|
||||
initial
|
||||
begin
|
||||
$dumpfile("trace.vcd");
|
||||
$dumpvars(0,test);
|
||||
end
|
||||
`endif
|
||||
|
||||
reg clk;
|
||||
reg rst;
|
||||
|
||||
reg [31:0] numer, denom;
|
||||
|
||||
wire [31:0] o_div[0:7], o_rem[0:7];
|
||||
|
||||
for (genvar i = 0; i < 8; i++) begin
|
||||
VX_divide#(
|
||||
.WIDTHN(32),
|
||||
.WIDTHD(32),
|
||||
.WIDTHQ(32),
|
||||
.WIDTHR(32),
|
||||
.PIPELINE(i)
|
||||
) div(
|
||||
.clock(clk),
|
||||
.aclr(rst),
|
||||
.clken(1'b1),
|
||||
.numer(numer),
|
||||
.denom(denom),
|
||||
.quotient(o_div[i]),
|
||||
.remainder(o_rem[i])
|
||||
);
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk = 0; rst = 0;
|
||||
|
||||
numer = 56;
|
||||
denom = 11;
|
||||
|
||||
$display("56 / 11 #0");
|
||||
if (o_div[0] != 5 || o_rem[0] != 1) begin
|
||||
$display("PIPE0: div=", o_div[0], " rem=", o_rem[0]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[1] != 1'bx || o_rem[1] != 1'bx) begin
|
||||
$display("PIPE1: div=", o_div[1], " rem=", o_rem[1]);
|
||||
$display("expected x,x EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[2] != 1'bx || o_rem[2] != 1'bx) begin
|
||||
$display("PIPE2: div=", o_div[2], " rem=", o_rem[2]);
|
||||
$display("expected x,x EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[3] != 1'bx || o_rem[3] != 1'bx) begin
|
||||
$display("PIPE3: div=", o_div[3], " rem=", o_rem[3]);
|
||||
$display("expected x,x EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
#2;
|
||||
|
||||
$display("56 / 11 #2");
|
||||
if (o_div[0] != 5 || o_rem[0] != 1) begin
|
||||
$display("PIPE0: div=", o_div[0], " rem=", o_rem[0]);
|
||||
$display("expected 5,1, EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[1] != 5 || o_rem[1] != 1) begin
|
||||
$display("PIPE1: div=", o_div[1], " rem=", o_rem[1]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[2] != 1'bx || o_rem[2] != 1'bx) begin
|
||||
$display("PIPE2: div=", o_div[2], " rem=", o_rem[2]);
|
||||
$display("expected x,x EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[3] != 1'bx || o_rem[3] != 1'bx) begin
|
||||
$display("PIPE3: div=", o_div[3], " rem=", o_rem[3]);
|
||||
$display("expected x,x EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
#2;
|
||||
|
||||
$display("56 / 11 #4");
|
||||
if (o_div[0] != 5 || o_rem[0] != 1) begin
|
||||
$display("PIPE0: div=", o_div[0], " rem=", o_rem[0]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[1] != 5 || o_rem[1] != 1) begin
|
||||
$display("PIPE1: div=", o_div[1], " rem=", o_rem[1]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[2] != 5 || o_rem[2] != 1) begin
|
||||
$display("PIPE2: div=", o_div[2], " rem=", o_rem[2]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[3] != 1'bx || o_rem[3] != 1'bx) begin
|
||||
$display("PIPE3: div=", o_div[3], " rem=", o_rem[3]);
|
||||
$display("expected x,x EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
#2;
|
||||
|
||||
$display("56 / 11 #6");
|
||||
|
||||
if (o_div[0] != 5 || o_rem[0] != 1) begin
|
||||
$display("PIPE0: div=", o_div[0], " rem=", o_rem[0]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[1] != 5 || o_rem[1] != 1) begin
|
||||
$display("PIPE1: div=", o_div[1], " rem=", o_rem[1]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[2] != 5 || o_rem[2] != 1) begin
|
||||
$display("PIPE2: div=", o_div[2], " rem=", o_rem[2]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
if (o_div[3] != 5 || o_rem[3] != 1) begin
|
||||
$display("PIPE3: div=", o_div[3], " rem=", o_rem[3]);
|
||||
$display("expected 5,1 EXITING");
|
||||
$finish();
|
||||
end
|
||||
|
||||
$display("PASS");
|
||||
|
||||
$finish();
|
||||
end
|
||||
|
||||
always #1
|
||||
clk = !clk;
|
||||
|
||||
endmodule
|
32
hw/unit_tests/cache/Makefile
vendored
32
hw/unit_tests/cache/Makefile
vendored
|
@ -1,46 +1,30 @@
|
|||
PARAM += -DCACHE_SIZE=4096 -DWORD_SIZE=4 -DCACHE_LINE_SIZE=16 -DNUM_BANKS=4 -DCREQ_SIZE=4 -DMRVQ_SIZE=16 -DDFPQ_SIZE=16 -DSNRQ_SIZE=16 -DCWBQ_SIZE=4 -DDWBQ_SIZE=4 -DFQQ_SIZE=4
|
||||
|
||||
TOP = VX_cache
|
||||
|
||||
PARAMS += -DCACHE_SIZE=4096 -DWORD_SIZE=4 -DCACHE_LINE_SIZE=16 -DNUM_BANKS=4 -DCREQ_SIZE=4 -DMRVQ_SIZE=16 -DDFPQ_SIZE=16 -DSNRQ_SIZE=16 -DCWBQ_SIZE=4 -DDWBQ_SIZE=4 -DFQQ_SIZE=4
|
||||
|
||||
# control RTL debug print states
|
||||
DBG_PRINT_FLAGS = -DDBG_PRINT_CORE_ICACHE \
|
||||
-DDBG_PRINT_CORE_DCACHE \
|
||||
-DDBG_PRINT_CACHE_BANK \
|
||||
-DDBG_PRINT_CACHE_SNP \
|
||||
-DDBG_PRINT_CACHE_MSHR \
|
||||
-DDBG_PRINT_CACHE_TAG \
|
||||
-DDBG_PRINT_CACHE_DATA \
|
||||
-DDBG_PRINT_DRAM \
|
||||
-DDBG_PRINT_OPAE \
|
||||
-DDBG_PRINT_AVS
|
||||
|
||||
#DBG_PRINT=$(DBG_PRINT_FLAGS)
|
||||
|
||||
INCLUDE = -I../../rtl/ -I../../rtl/cache -I../../rtl/libs
|
||||
|
||||
INCLUDE = -I../../rtl/ -I../../rtl/libs -I../../rtl/cache
|
||||
|
||||
SRCS = cachesim.cpp testbench.cpp
|
||||
|
||||
all: build
|
||||
|
||||
CF += -std=c++11 -fms-extensions -I../..
|
||||
CF += $(PARAMS)
|
||||
|
||||
VF += --language 1800-2009 --assert -Wall --trace #-Wpedantic
|
||||
VF += -Wno-DECLFILENAME
|
||||
VF += --x-initial unique
|
||||
VF += -exe $(SRCS) $(INCLUDE)
|
||||
|
||||
DBG += -DVCD_OUTPUT $(DBG_PRINT)
|
||||
|
||||
VF += $(PARAMS)
|
||||
|
||||
gen:
|
||||
verilator $(VF) -DNDEBUG -cc VX_cache.v $(PARAM) -CFLAGS '$(CF) -DNDEBUG $(PARAM)' --exe $(SRCS)
|
||||
verilator $(VF) -cc $(TOP).v -CFLAGS '$(CF)' --exe $(SRCS)
|
||||
|
||||
build: gen
|
||||
(cd obj_dir && make -j -f VVX_cache.mk)
|
||||
(cd obj_dir && make -j -f V$(TOP).mk)
|
||||
|
||||
run: build
|
||||
(cd obj_dir && ./VVX_cache)
|
||||
(cd obj_dir && ./V$(TOP))
|
||||
|
||||
clean:
|
||||
rm -rf obj_dir
|
||||
|
|
10
hw/unit_tests/cache/cachesim.cpp
vendored
10
hw/unit_tests/cache/cachesim.cpp
vendored
|
@ -173,10 +173,10 @@ void CacheSim::stall_dram(){
|
|||
}
|
||||
|
||||
void CacheSim::send_snoop_req(){
|
||||
cache_->snp_req_valid = 1;
|
||||
/*cache_->snp_req_valid = 1;
|
||||
cache_->snp_req_addr = 0x12222222;
|
||||
cache_->snp_req_invalidate = 1;
|
||||
cache_->snp_req_tag = 0xff;
|
||||
cache_->snp_req_tag = 0xff; */
|
||||
}
|
||||
|
||||
void CacheSim::eval_dram_bus() {
|
||||
|
@ -274,9 +274,9 @@ bool CacheSim::assert_equal(unsigned int* data, unsigned int tag){
|
|||
//DEBUG
|
||||
|
||||
void CacheSim::display_miss(){
|
||||
int i = (unsigned int)cache_->miss_vec;
|
||||
std::bitset<8> x(i);
|
||||
if (i) std::cout << "Miss Vec " << x << std::endl;
|
||||
//int i = (unsigned int)cache_->miss_vec;
|
||||
//std::bitset<8> x(i);
|
||||
//if (i) std::cout << "Miss Vec " << x << std::endl;
|
||||
//std::cout << "Miss Vec 0" << cache_->miss_vec[0] << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
58
hw/unit_tests/generic_queue/main.cpp
Normal file
58
hw/unit_tests/generic_queue/main.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
#include "vl_simulator.h"
|
||||
#include "VVX_fifo_queue.h"
|
||||
#include "VVX_fifo_queue__Syms.h"
|
||||
|
||||
static const uint32_t MAX_TICKS = 10000000;
|
||||
static const uint32_t NUM_ITERATIONS = 20000;
|
||||
|
||||
using Device = VVX_fifo_queue;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Initialize Verilators variables
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
vl_simulator<Device> sim;
|
||||
|
||||
auto start_time = std::chrono::system_clock::now();
|
||||
|
||||
// run simulation
|
||||
unit64_t ticks = sim.reset(0);
|
||||
|
||||
for (;;) {
|
||||
//sim->io_in_valid = (in_sample < num_iterations * FFT_SIZE);
|
||||
//sim->io_out_ready = (out_sample < num_iterations * FFT_SIZE);
|
||||
|
||||
// enqueue data
|
||||
//if (sim->io_in_valid && sim->io_in_ready) {
|
||||
//std::cout << "t" << std::dec << ticks << std::hex << " input: re=" << re << ", im=" << im << std::endl;
|
||||
//sim->io_in_data = sample;
|
||||
//}
|
||||
|
||||
// dequeue data
|
||||
//if (sim->io_out_valid && sim->io_out_ready) {
|
||||
//std::cout << "t" << std::dec << ticks << std::hex << " output: re=" << re << ", im=" << im << std::endl;
|
||||
//test_outputs[out_sample++] = sample;
|
||||
//}
|
||||
|
||||
// check for completion
|
||||
|
||||
|
||||
// advance clock
|
||||
ticks = sim.step(ticks, 2);
|
||||
}
|
||||
|
||||
auto end_time = std::chrono::system_clock::now();
|
||||
auto latency = end_time - start_time;
|
||||
std::cout << "Average elapsed time = "
|
||||
<< std::chrono::duration<double, std::milli>(latency).count()
|
||||
<< " ms" << std::endl;
|
||||
|
||||
std::cout << "Simulation run time: " << std::dec << ticks/2 << " cycles" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
`timescale 1ns/1ns
|
||||
`include "VX_fifo_queue.v"
|
||||
|
||||
`define check(x, y) if ((x == y) !== 1) if ((x == y) === 0) $error("x=%h, expected=%h", x, y); else $warning("x=%h, expected=%h", x, y)
|
||||
|
||||
module testbench();
|
||||
|
||||
reg clk;
|
||||
reg reset;
|
||||
reg[3:0] data_in;
|
||||
reg push;
|
||||
reg pop;
|
||||
wire[3:0] data_out;
|
||||
wire full;
|
||||
wire empty;
|
||||
|
||||
VX_fifo_queue #(
|
||||
.DATAW(4),
|
||||
.SIZE(4)
|
||||
) dut (
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
.data_in(data_in),
|
||||
.push(push),
|
||||
.pop(pop),
|
||||
.data_out(data_out),
|
||||
.empty(empty),
|
||||
.full(full),
|
||||
`UNUSED_PIN (alm_empty),
|
||||
`UNUSED_PIN (alm_full),
|
||||
`UNUSED_VAR (size)
|
||||
);
|
||||
|
||||
always begin
|
||||
#1 clk = !clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
$monitor ("%d: clk=%b rst=%b push=%b, pop=%b, din=%h, empty=%b, full=%b, dout=%h",
|
||||
$time, clk, reset, push, pop, data_in, empty, full, data_out);
|
||||
#0 clk=0; reset=1; pop=0; push=0;
|
||||
#2 reset=0; data_in=4'ha; pop=0; push=1;
|
||||
#2 `check(full, 0); `check(data_out, 4'ha); `check(empty, 0);
|
||||
#0 data_in=4'hb;
|
||||
#2 `check(full, 0); `check(data_out, 4'ha); `check(empty, 0);
|
||||
#0 data_in=4'hc;
|
||||
#2 `check(full, 0); `check(data_out, 4'ha); `check(empty, 0);
|
||||
#0 data_in=4'hd;
|
||||
#2 `check(full, 1); `check(data_out, 4'ha); `check(empty, 0);
|
||||
#0 push=0; pop=1;
|
||||
#2 `check(full, 0); `check(data_out, 4'hb); `check(empty, 0);
|
||||
#2 `check(full, 0); `check(data_out, 4'hc); `check(empty, 0);
|
||||
#2 `check(full, 0); `check(data_out, 4'hd); `check(empty, 0);
|
||||
#2 `check(full, 0); `check(data_out, 4'ha); `check(empty, 1);
|
||||
#0 data_in=4'he; push=1; pop=0;
|
||||
#2 `check(full, 0); `check(data_out, 4'he); `check(empty, 0);
|
||||
#0 data_in=4'hf; pop=1;
|
||||
#2 `check(full, 0); `check(data_out, 4'hf); `check(empty, 0);
|
||||
#0 push=0;
|
||||
#2 `check(full, 0); `check(data_out, 4'hc); `check(empty, 1);
|
||||
#1 $finish;
|
||||
end
|
||||
|
||||
endmodule
|
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;
|
||||
}
|
||||
|
||||
auto 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue