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