Add old (without --timing) verilator test
This commit is contained in:
38
test-verilator4/.clang-format
Normal file
38
test-verilator4/.clang-format
Normal file
@@ -0,0 +1,38 @@
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
UseTab: false
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveMacros: true
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: Align
|
||||
|
||||
AlignTrailingComments: true
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: WithoutElse
|
||||
|
||||
BinPackArguments: true
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterControlStatement: MultiLine
|
||||
AfterFunction: true
|
||||
AfterStruct: true
|
||||
BeforeElse: true
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
|
||||
IncludeBlocks: Regroup
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesBeforeTrailingComments: 4
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
2
test-verilator4/.gitignore
vendored
Normal file
2
test-verilator4/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
testbench
|
||||
compile_flags.txt
|
||||
19
test-verilator4/Makefile
Normal file
19
test-verilator4/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
TOP_MODULE = testbench
|
||||
|
||||
SOURCES = top.cpp clock_generator.cpp
|
||||
FLAGS_FILE = ../source/sources.f
|
||||
INCLUDES =
|
||||
PARAMS :=
|
||||
THREADS := 1
|
||||
|
||||
FLAGS = -Wno-WIDTH -cc --top-module $(TOP_MODULE) +1800-2017ext+sv \
|
||||
--Mdir $(TOP_MODULE) -o $(TOP_MODULE) -f $(FLAGS_FILE) \
|
||||
$(PARAMS) --timescale "1ps/1ps" --threads $(THREADS) -j 16
|
||||
|
||||
# FLAGS += --trace
|
||||
|
||||
all: $(SOURCES)
|
||||
verilator $(FLAGS) --exe --build $(INCLUDES) $(SOURCES)
|
||||
|
||||
clean:
|
||||
rm -rf $(TOP_MODULE)
|
||||
7
test-verilator4/__build.sh
Executable file
7
test-verilator4/__build.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
. ../scripts/sim_vars.sh
|
||||
|
||||
make clean
|
||||
make OPT_FAST="-Os -march=native" VM_PARALLEL_BUILDS=0 PARAMS="-GCPU_COUNT=$CPU_COUNT" THREADS=$THREADS
|
||||
5
test-verilator4/__run.sh
Executable file
5
test-verilator4/__run.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
. ../scripts/sim_vars.sh
|
||||
|
||||
./testbench/testbench +dlen=$BLOCK_SIZE
|
||||
95
test-verilator4/clock_generator.cpp
Normal file
95
test-verilator4/clock_generator.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "clock_generator.hpp"
|
||||
|
||||
ClockGenerator::~ClockGenerator()
|
||||
{
|
||||
while (clocks) {
|
||||
clock *next = clocks->next;
|
||||
delete clocks;
|
||||
clocks = next;
|
||||
}
|
||||
};
|
||||
|
||||
void ClockGenerator::add_clock(uint8_t &net, uint64_t period, uint64_t skew)
|
||||
{
|
||||
if (skew >= period) throw "The skew value cannot exceed the period";
|
||||
|
||||
clock *clk = new clock(net, period, skew);
|
||||
net = (clk->position < clk->period / 2) ? 0 : 1;
|
||||
|
||||
if (clocks == NULL)
|
||||
clocks = clk;
|
||||
else {
|
||||
clock *last = clocks;
|
||||
while (last->next)
|
||||
last = last->next;
|
||||
last->next = clk;
|
||||
}
|
||||
};
|
||||
|
||||
uint64_t ClockGenerator::next_event(void)
|
||||
{
|
||||
uint64_t time_to_next = UINT64_MAX;
|
||||
clock *clk = clocks;
|
||||
|
||||
while (clk) {
|
||||
uint64_t ttn;
|
||||
|
||||
if (clk->position < clk->period / 2)
|
||||
ttn = clk->period / 2 - clk->position;
|
||||
else
|
||||
ttn = clk->period - clk->position;
|
||||
|
||||
if (time_to_next > ttn) time_to_next = ttn;
|
||||
|
||||
clk = clk->next;
|
||||
}
|
||||
|
||||
clk = clocks;
|
||||
while (clk) {
|
||||
uint8_t next_val;
|
||||
|
||||
clk->position += time_to_next;
|
||||
if (clk->position >= clk->period) clk->position -= clk->period;
|
||||
|
||||
next_val = (clk->position < clk->period / 2) ? 0 : 1;
|
||||
clk->posedge = (next_val == 1 && clk->net == 0) ? true : false;
|
||||
clk->negedge = (next_val == 0 && clk->net == 1) ? true : false;
|
||||
clk->net = next_val;
|
||||
|
||||
clk = clk->next;
|
||||
}
|
||||
|
||||
return time_to_next;
|
||||
};
|
||||
|
||||
bool ClockGenerator::is_posegde(uint8_t &net)
|
||||
{
|
||||
clock *clk = clocks;
|
||||
bool posedge = false;
|
||||
|
||||
while (clk) {
|
||||
if (std::addressof(net) == std::addressof(clk->net)) {
|
||||
posedge = clk->posedge;
|
||||
break;
|
||||
}
|
||||
clk = clk->next;
|
||||
}
|
||||
|
||||
return posedge;
|
||||
};
|
||||
|
||||
bool ClockGenerator::is_negedge(uint8_t &net)
|
||||
{
|
||||
clock *clk = clocks;
|
||||
bool negedge = false;
|
||||
|
||||
while (clk) {
|
||||
if (std::addressof(net) == std::addressof(clk->net)) {
|
||||
negedge = clk->negedge;
|
||||
break;
|
||||
}
|
||||
clk = clk->next;
|
||||
}
|
||||
|
||||
return negedge;
|
||||
};
|
||||
31
test-verilator4/clock_generator.hpp
Normal file
31
test-verilator4/clock_generator.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef _CLOCK_GENERATOR_HPP
|
||||
#define _CLOCK_GENERATOR_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
class ClockGenerator
|
||||
{
|
||||
protected:
|
||||
struct clock {
|
||||
clock(uint8_t &net, uint64_t period, uint64_t position) :
|
||||
net(net), period(period), position(position), next(NULL),
|
||||
posedge(false), negedge(false) {};
|
||||
|
||||
uint8_t &net;
|
||||
uint64_t period;
|
||||
uint64_t position;
|
||||
bool posedge;
|
||||
bool negedge;
|
||||
clock *next;
|
||||
} *clocks = NULL;
|
||||
|
||||
public:
|
||||
~ClockGenerator();
|
||||
void add_clock(uint8_t &net, uint64_t period, uint64_t skew);
|
||||
uint64_t next_event(void);
|
||||
bool is_posegde(uint8_t &net);
|
||||
bool is_negedge(uint8_t &net);
|
||||
};
|
||||
|
||||
#endif // _CLOCK_GENERATOR_HPP
|
||||
19
test-verilator4/shell.nix
Normal file
19
test-verilator4/shell.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
with pkgs;
|
||||
let
|
||||
flags-file = "compile_flags.txt";
|
||||
in
|
||||
mkShell {
|
||||
packages = [ gnumake verilator ];
|
||||
|
||||
shellHook = ''
|
||||
echo -n > ${flags-file}
|
||||
echo -DVM_TRACE=1 >> ${flags-file}
|
||||
echo -xc++ >> ${flags-file}
|
||||
echo -I./testbench >> ${flags-file}
|
||||
echo -I${verilator}/share/verilator/include >> ${flags-file}
|
||||
echo -I${clang}/resource-root/include >> ${flags-file}
|
||||
echo -I${glibc.dev}/include >> ${flags-file}
|
||||
'';
|
||||
}
|
||||
74
test-verilator4/top.cpp
Normal file
74
test-verilator4/top.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "Vtestbench.h"
|
||||
#include "clock_generator.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_c.h>
|
||||
|
||||
#define DUMPFILE "testbench.vcd"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
VerilatedContext *ctx = new VerilatedContext;
|
||||
ctx->commandArgs(argc, argv);
|
||||
|
||||
/* Create model instance */
|
||||
Vtestbench *top = new Vtestbench(ctx);
|
||||
|
||||
#if (VM_TRACE == 1)
|
||||
VerilatedVcdC *vcd = new VerilatedVcdC;
|
||||
ctx->traceEverOn(true);
|
||||
top->trace(vcd, 99);
|
||||
vcd->open(DUMPFILE);
|
||||
#endif
|
||||
|
||||
/* Create clock source */
|
||||
ClockGenerator *clk = new ClockGenerator;
|
||||
|
||||
/* Add clocks and go to first event */
|
||||
clk->add_clock(top->clock, 10000, 0);
|
||||
clk->next_event();
|
||||
|
||||
/* Cycle counter */
|
||||
uint64_t cycle = 0;
|
||||
|
||||
/* ---- Evaluation loop ---- */
|
||||
while (!ctx->gotFinish()) {
|
||||
/* Clock event */
|
||||
ctx->timeInc(clk->next_event());
|
||||
|
||||
/* Get output values (before clock edge) */
|
||||
if (clk->is_posegde(top->clock)) {
|
||||
// NOP
|
||||
}
|
||||
|
||||
/* Eval */
|
||||
top->eval();
|
||||
|
||||
/* Put input values (after clock edge)*/
|
||||
if (clk->is_posegde(top->clock)) {
|
||||
// NOP
|
||||
}
|
||||
|
||||
/* Trace steady-state values */
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd) vcd->dump(ctx->time());
|
||||
#endif
|
||||
|
||||
cycle ++;
|
||||
}
|
||||
|
||||
top->final();
|
||||
printf("[%lu] Stop simulation\n", ctx->time());
|
||||
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd) {
|
||||
vcd->close();
|
||||
delete vcd;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete top;
|
||||
delete ctx;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user