Initial commit
This commit is contained in:
commit
a67cca5aa8
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/*
|
||||
!.gitignore
|
||||
!_template_iverilog
|
||||
!_template_verilator
|
||||
28
_template_iverilog/Makefile
Normal file
28
_template_iverilog/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
TESTBENCH ?= testbench
|
||||
SOURCES ?= testbench.sv
|
||||
INCLUDE ?=
|
||||
|
||||
COMPILE_FLAGS += -DTESTBENCH -g2012
|
||||
PLUSARGS = -fst
|
||||
|
||||
.SILENT:
|
||||
|
||||
all: clean run
|
||||
|
||||
dump: COMPILE_FLAGS += -DDUMP
|
||||
dump: all
|
||||
|
||||
$(TESTBENCH).vvp: $(SOURCES)
|
||||
iverilog $(COMPILE_FLAGS) $(INCLUDE) -s $(TESTBENCH) -o $(TESTBENCH).vvp $(SOURCES)
|
||||
|
||||
run: $(TESTBENCH).vvp
|
||||
vvp $(TESTBENCH).vvp $(PLUSARGS)
|
||||
|
||||
preprocess: $(SORCES)
|
||||
iverilog -E $(COMPILE_FLAGS) $(INCLUDE) -s $(TESTBENCH) -o $(TESTBENCH)_preprocessed.sv $(SOURCES)
|
||||
|
||||
clean:
|
||||
rm -rf *.vvp
|
||||
rm -rf *.fst
|
||||
rm -rf *.vcd
|
||||
rm -rf *.csv
|
||||
9
_template_iverilog/shell-latest.nix
Normal file
9
_template_iverilog/shell-latest.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
with pkgs;
|
||||
let
|
||||
iverilog-latest = callPackage /etc/nixos/programs/iverilog-latest.nix {};
|
||||
in
|
||||
mkShell {
|
||||
packages = [ iverilog-latest gnumake ];
|
||||
}
|
||||
5
_template_iverilog/shell.nix
Normal file
5
_template_iverilog/shell.nix
Normal file
@ -0,0 +1,5 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
with pkgs; mkShell {
|
||||
packages = [ verilog gnumake ];
|
||||
}
|
||||
13
_template_iverilog/testbench.sv
Normal file
13
_template_iverilog/testbench.sv
Normal file
@ -0,0 +1,13 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
/* verilator lint_off DECLFILENAME */
|
||||
/* verilator lint_off MULTITOP */
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off INFINITELOOP */
|
||||
/* verilator lint_off INITIALDLY */
|
||||
|
||||
module testbench;
|
||||
initial begin
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
38
_template_verilator/.clang-format
Normal file
38
_template_verilator/.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
|
||||
1
_template_verilator/.gitignore
vendored
Normal file
1
_template_verilator/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
compile_flags.txt
|
||||
23
_template_verilator/Makefile
Normal file
23
_template_verilator/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
TOP_MODULE = top
|
||||
|
||||
SOURCES = top.sv top.cpp clock_generator.cpp
|
||||
INCLUDES =
|
||||
|
||||
## Parameters example:
|
||||
# PARAM_INPUT_WIDTH ?= 15
|
||||
# PARAM_FFT_LENGTH ?= 256
|
||||
# PARAM_REJECTOR_K_WIDTH ?= 8
|
||||
|
||||
FLAGS = -Wno-WIDTH -cc --top-module $(TOP_MODULE) +1800-2017ext+sv --timing --trace --Mdir $(TOP_MODULE)
|
||||
FLAGS += $(foreach V,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(V))=$($(V)))
|
||||
|
||||
all: $(SOURCES)
|
||||
verilator $(FLAGS) --exe --build $(INCLUDES) $(SOURCES)
|
||||
|
||||
pre:
|
||||
verilator $(FLAGS) $(INCLUDES) $(SOURCES)
|
||||
|
||||
clean:
|
||||
rm -rf obj_dir
|
||||
rm -rf datapath
|
||||
rm -rf *.vcd
|
||||
95
_template_verilator/clock_generator.cpp
Normal file
95
_template_verilator/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
_template_verilator/clock_generator.hpp
Normal file
31
_template_verilator/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
|
||||
20
_template_verilator/shell.nix
Normal file
20
_template_verilator/shell.nix
Normal file
@ -0,0 +1,20 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
|
||||
with pkgs;
|
||||
let
|
||||
unstable = import <unstable> {};
|
||||
flags-file = "compile_flags.txt";
|
||||
in
|
||||
mkShell {
|
||||
packages = [ gnumake unstable.verilator ];
|
||||
|
||||
shellHook = ''
|
||||
echo -n > ${flags-file}
|
||||
echo -DVM_TRACE=1 >> ${flags-file}
|
||||
echo -xc++ >> ${flags-file}
|
||||
echo -I./obj_dir >> ${flags-file}
|
||||
echo -I${unstable.verilator}/share/verilator/include >> ${flags-file}
|
||||
echo -I${clang}/resource-root/include >> ${flags-file}
|
||||
echo -I${glibc.dev}/include >> ${flags-file}
|
||||
'';
|
||||
}
|
||||
72
_template_verilator/top.cpp
Normal file
72
_template_verilator/top.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include "Vtop.h"
|
||||
#include "clock_generator.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <verilated.h>
|
||||
#include <verilated_vcd_c.h>
|
||||
|
||||
#define DUMPFILE "test.vcd"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
VerilatedContext *ctx = new VerilatedContext;
|
||||
ctx->commandArgs(argc, argv);
|
||||
|
||||
/* Create model instance */
|
||||
Vtop *top = new Vtop(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();
|
||||
|
||||
/* Initial */
|
||||
top->reset = 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)) {
|
||||
printf("-- posedge clock @ %lu\n", ctx->time());
|
||||
}
|
||||
|
||||
/* Eval */
|
||||
top->eval();
|
||||
|
||||
/* Put input values (after clock edge)*/
|
||||
if (clk->is_posegde(top->clock)) {
|
||||
top->reset = !top->reset;
|
||||
}
|
||||
|
||||
/* Trace steady-state values */
|
||||
#if (VM_TRACE == 1)
|
||||
if (vcd) vcd->dump(ctx->time());
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
22
_template_verilator/top.sv
Normal file
22
_template_verilator/top.sv
Normal file
@ -0,0 +1,22 @@
|
||||
`timescale 1ps/1ps
|
||||
|
||||
/* -verilator lint_off DECLFILENAME */
|
||||
/* -verilator lint_off MULTITOP */
|
||||
/* -verilator lint_off STMTDLY */
|
||||
/* -verilator lint_off INFINITELOOP */
|
||||
/* -verilator lint_off INITIALDLY */
|
||||
|
||||
module top
|
||||
(input wire clock,
|
||||
input wire reset);
|
||||
|
||||
initial begin
|
||||
for (int n = 0; n < 10; n += 1) begin
|
||||
$display("R@%0t: %0b\n", $time, reset);
|
||||
@(posedge clock);
|
||||
end
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // top
|
||||
Loading…
x
Reference in New Issue
Block a user