Initial commit
This commit is contained in:
commit
36e067cbf6
12
.clang-format
Normal file
12
.clang-format
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
BasedOnStyle: GNU
|
||||||
|
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||||
|
PointerAlignment: Left
|
||||||
|
UseTab: Never
|
||||||
|
IndentWidth: 2
|
||||||
|
ContinuationIndentWidth: 2
|
||||||
|
ConstructorInitializerIndentWidth: 2
|
||||||
|
BreakAfterReturnType: Automatic
|
||||||
|
BreakConstructorInitializers: AfterColon
|
||||||
|
PackConstructorInitializers: Never
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.cache/
|
||||||
|
build/
|
||||||
13
CMakeLists.txt
Normal file
13
CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
|
project(vcppd)
|
||||||
|
|
||||||
|
add_library(vcppd src/vcd.cpp src/builder.cpp)
|
||||||
|
target_include_directories(vcppd PUBLIC include)
|
||||||
|
set_target_properties(vcppd PROPERTIES CXX_STANDARD 20)
|
||||||
|
|
||||||
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
|
add_executable(vcppd-test test/test.cpp)
|
||||||
|
target_link_libraries(vcppd-test PUBLIC vcppd)
|
||||||
|
set_target_properties(vcppd-test PROPERTIES CXX_STANDARD 20)
|
||||||
|
endif()
|
||||||
42
include/vcppd/builder.h
Normal file
42
include/vcppd/builder.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef VCPPD_VCD_BUILDER_H
|
||||||
|
#define VCPPD_VCD_BUILDER_H
|
||||||
|
|
||||||
|
#include "vcppd/vcd.h"
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
namespace vcppd
|
||||||
|
{
|
||||||
|
|
||||||
|
class Builder
|
||||||
|
{
|
||||||
|
friend Vcd;
|
||||||
|
friend Scope<Builder>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Builder(std::ostream& stream);
|
||||||
|
|
||||||
|
Vcd build() const;
|
||||||
|
|
||||||
|
Scope<Builder> scope(const std::string& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename U>
|
||||||
|
void trace(const std::string& name, const U& ref,
|
||||||
|
const std::string& short_name)
|
||||||
|
{
|
||||||
|
stream << std::format("$var wire {} {} {} $end", sizeof(U) * 8, name,
|
||||||
|
short_name)
|
||||||
|
<< std::endl;
|
||||||
|
variables[name] = detail::variable_entry{ &ref, sizeof(U) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void unscope();
|
||||||
|
|
||||||
|
std::ostream& stream;
|
||||||
|
detail::variable_map variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VCPPD_VCD_BUILDER_H
|
||||||
57
include/vcppd/scope.h
Normal file
57
include/vcppd/scope.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef VCPPD_VCD_SCOPE_H
|
||||||
|
#define VCPPD_VCD_SCOPE_H
|
||||||
|
|
||||||
|
#include "vcppd/vcd.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace vcppd
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T> class Scope
|
||||||
|
{
|
||||||
|
friend T;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Scope(const Scope&) = delete;
|
||||||
|
Scope& operator=(const Scope&) = delete;
|
||||||
|
|
||||||
|
Scope<Scope> scope(const std::string& name)
|
||||||
|
{
|
||||||
|
return Scope<Scope>(name, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
T& unscope()
|
||||||
|
{
|
||||||
|
parent.unscope();
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U> Scope& trace(const std::string& name, const U& ref)
|
||||||
|
{
|
||||||
|
parent.trace(this->name + "_" + name, ref, name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Scope(const std::string& name, T& parent) :
|
||||||
|
name(name),
|
||||||
|
parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
Scope& trace(const std::string& name, const U& ref,
|
||||||
|
const std::string& short_name)
|
||||||
|
{
|
||||||
|
parent.trace(this->name + "_" + name, ref, short_name);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
T& parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VCPPD_VCD_SCOPE_H
|
||||||
45
include/vcppd/vcd.h
Normal file
45
include/vcppd/vcd.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef VCPPD_VCD_H
|
||||||
|
#define VCPPD_VCD_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace vcppd
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct variable_entry
|
||||||
|
{
|
||||||
|
const void* ref;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
using variable_map = std::unordered_map<std::string, variable_entry>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> class Scope;
|
||||||
|
class Builder;
|
||||||
|
|
||||||
|
class Vcd
|
||||||
|
{
|
||||||
|
friend Builder;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~Vcd();
|
||||||
|
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vcd(const Builder&);
|
||||||
|
|
||||||
|
std::ostream& stream;
|
||||||
|
unsigned int current_time;
|
||||||
|
detail::variable_map variables;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VCPPD_VCD_H
|
||||||
8
include/vcppd/vcppd.h
Normal file
8
include/vcppd/vcppd.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef VCPPD_H
|
||||||
|
#define VCPPD_H
|
||||||
|
|
||||||
|
#include "vcppd/builder.h"
|
||||||
|
#include "vcppd/scope.h"
|
||||||
|
#include "vcppd/vcd.h"
|
||||||
|
|
||||||
|
#endif // VCPPD_H
|
||||||
34
src/builder.cpp
Normal file
34
src/builder.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "vcppd/builder.h"
|
||||||
|
|
||||||
|
#include "vcppd/scope.h"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
using namespace vcppd;
|
||||||
|
|
||||||
|
Builder::Builder(std::ostream& stream) :
|
||||||
|
stream(stream)
|
||||||
|
{
|
||||||
|
auto t = std::time(nullptr);
|
||||||
|
auto tm = *std::localtime(&t);
|
||||||
|
|
||||||
|
stream << "$version Generated by vcppd $end" << std::endl;
|
||||||
|
stream << "$date " << std::put_time(&tm, "%A %B %e %T %Y") << " $end"
|
||||||
|
<< std::endl;
|
||||||
|
stream << "$timescale 1ns $end" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vcd Builder::build() const
|
||||||
|
{
|
||||||
|
stream << "$enddefinitions $end" << std::endl;
|
||||||
|
return Vcd(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scope<Builder> Builder::scope(const std::string& name)
|
||||||
|
{
|
||||||
|
stream << "$scope module " << name << " $end" << std::endl;
|
||||||
|
return Scope<Builder>(name, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::unscope() { stream << "$upscope $end" << std::endl; }
|
||||||
37
src/vcd.cpp
Normal file
37
src/vcd.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "vcppd/vcd.h"
|
||||||
|
|
||||||
|
#include "vcppd/builder.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
using namespace vcppd;
|
||||||
|
|
||||||
|
Vcd::Vcd(const Builder& builder) :
|
||||||
|
stream(builder.stream),
|
||||||
|
variables(builder.variables),
|
||||||
|
current_time(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Vcd::~Vcd() { stream << std::format("#{}", current_time) << std::endl; }
|
||||||
|
|
||||||
|
void Vcd::tick()
|
||||||
|
{
|
||||||
|
stream << std::format("#{}", current_time) << std::endl;
|
||||||
|
|
||||||
|
for (const auto& [name, entry] : variables)
|
||||||
|
{
|
||||||
|
stream << "b";
|
||||||
|
for (int i = 0; i < entry.size; i++)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
memcpy(&byte, static_cast<const uint8_t*>(entry.ref), 1);
|
||||||
|
stream << std::format("{0:b}", byte);
|
||||||
|
}
|
||||||
|
stream << " " << name << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_time += 1;
|
||||||
|
}
|
||||||
22
test/test.cpp
Normal file
22
test/test.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "vcppd/vcppd.h"
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
uint8_t eae = 0;
|
||||||
|
uint8_t eae2 = 0;
|
||||||
|
|
||||||
|
auto vcd = vcppd::Builder(std::cout)
|
||||||
|
.scope("TOP")
|
||||||
|
.trace("eae", eae)
|
||||||
|
.trace("eae2", eae2)
|
||||||
|
.unscope()
|
||||||
|
.build();
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
vcd.tick();
|
||||||
|
eae += 1;
|
||||||
|
eae2 += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user