Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .bazelrc

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/bazel-*
/build
.DS_Store
1 change: 0 additions & 1 deletion BUILD

This file was deleted.

153 changes: 153 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
cmake_minimum_required(VERSION 3.31.6)

project(googletest-verilog
VERSION 0.2.0
LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 20)

#
# GoogleTest Library
#

# download google test
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/releases/download/v1.17.0/googletest-1.17.0.tar.gz
)

# prevent googletest from overriding our compiler/linker options
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

#
# Verilator library
#

# based on verilator documentation
# https://veripool.org/guide/latest/verilating.html#cmake

find_package(verilator REQUIRED HINTS $ENV{VERILATOR_ROOT})

message(STATUS "VERILATOR_ROOT = ${VERILATOR_ROOT}")
message(STATUS "VERILATOR_BIN = ${VERILATOR_BIN}")

#
# googletest-verilog test bench generation
#

find_package(Python3 COMPONENTS Interpreter REQUIRED)

function(googletest_verilog_testbench TB_TARGET)
cmake_parse_arguments(
TB # prefix
"" # list of options (true / false based on whether option is present or not)
"SOURCE" # single value keywords
"INCLUDE_DIRS" # multi-value keywords
${ARGN} # arguments provided to the function
)

message(STATUS "SOURCE = ${TB_SOURCE}")
message(STATUS "TARGET = ${TB_TARGET}")
message(STATUS "INCLUDE_DIRS = ${TB_INCLUDE_DIRS}")

get_filename_component(TB_SOURCE_BASENAME "${TB_SOURCE}" NAME_WE)
set(TB_TESTBENCH "${TB_SOURCE_BASENAME}TestBench")

set(TB_VERILATED_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/verilated/${TB_TESTBENCH})
set(TB_TESTBENCH_HEADER "${TB_VERILATED_OUTPUT_DIR}/${TB_TESTBENCH}.h")
set(TB_TESTBENCH_SOURCE "${TB_VERILATED_OUTPUT_DIR}/${TB_TESTBENCH}.cpp")

message(STATUS "TB_TESTBENCH = ${TB_TESTBENCH}")
message(STATUS "TB_VERILATED_OUTPUT_DIR = ${TB_VERILATED_OUTPUT_DIR}")
message(STATUS "TB_TESTBENCH_HEADER = ${TB_TESTBENCH_HEADER}")
message(STATUS "TB_TESTBENCH_SOURCE = ${TB_TESTBENCH_SOURCE}")
message(STATUS "CMAKE_BINARY_DIR = " ${CMAKE_BINARY_DIR})
message(STATUS "CMAKE_CURRENT_BINARY_DIR = " ${CMAKE_CURRENT_BINARY_DIR})

# 1. verilate the verilog module

verilate(${TB_TARGET} SOURCES ${TB_SOURCE} INCLUDE_DIRS ${TB_INCLUDE_DIRS} DIRECTORY ${TB_VERILATED_OUTPUT_DIR})

# 2. generate test bench
set(TOOL_GENERATE_TESTBENCH ${CMAKE_SOURCE_DIR}/tools/generate_testbench.py)

add_custom_command(
OUTPUT ${TB_TESTBENCH_HEADER} ${TB_TESTBENCH_SOURCE}
COMMAND ${Python3_EXECUTABLE} ${TOOL_GENERATE_TESTBENCH} --name ${TB_TESTBENCH} --verilated-header-dir ${TB_VERILATED_OUTPUT_DIR} --output-header ${TB_TESTBENCH_HEADER} --output-source ${TB_TESTBENCH_SOURCE}
DEPENDS ${TOOL_GENERATE_TESTBENCH} ${TB_SOURCE}
)

target_sources(${TB_TARGET} PRIVATE ${TB_TESTBENCH_HEADER} ${TB_TESTBENCH_SOURCE})

set(TB_TESTBENCH_TARGET "googletest_verilog_testbench-${TB_TESTBENCH}")

# 3. use a custom target to force cmake to create testbench first, before compiling TARGET

add_custom_target(${TB_TESTBENCH_TARGET}
DEPENDS ${TB_TESTBENCH_HEADER} ${TB_TESTBENCH_SOURCE}
)

add_dependencies(${TB_TARGET} ${TB_TESTBENCH_TARGET})

endfunction()

#
# googletest-verilog static library
#

include_directories(include)

add_library(googletest-verilog
src/ConsoleColour.cpp
src/MatchesTrace.cpp
src/PortDescription.cpp
src/Step.cpp
src/Trace.cpp
src/TraceBuilder.cpp
)

# add googletest/googlemock includes, without linking to gtest
get_target_property(GTEST_INCLUDES GTest::gtest INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(GMOCK_INCLUDES GTest::gmock INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(googletest-verilog PUBLIC ${GTEST_INCLUDES} ${GMOCK_INCLUDES})

#
# googletest-verilog internal Unit Tests
#

add_executable(googletest-verilog-test
test/main.cpp
test/MatchesTrace.test.cpp
test/Step.test.cpp
test/TestBench.test.cpp
test/Trace.test.cpp
test/TraceBuilder.test.cpp
)

target_link_libraries(googletest-verilog-test
gtest
gmock
googletest-verilog
)

#
# googletest-verilog Example Usage
#

add_executable(googletest-verilog-example
example/main.cpp
example/Counter.test.cpp
)

googletest_verilog_testbench(googletest-verilog-example SOURCE example/Counter.v)

target_link_libraries(googletest-verilog-example PRIVATE
googletest-verilog
gtest
gmock
)

target_include_directories(googletest-verilog-example PRIVATE ${VERILATOR_INCLUDE_DIRS})
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
- bazel build //gtestverilog:test && ./bazel-bin/gtestverilog/test --gtest_filter="*"
# googletest-verilog

- bazel build //gtestverilog:example --incompatible_require_linker_input_cc_api=false && ./bazel-bin/gtestverilog/example --gtest_filter="*"
Add support for writing C++ unit-tests for verilog modules with [googletest](https://github.com/google/googletest).

Unit-tests are run in simulation with [verilator](https://github.com/verilator/verilator).

# Dependencies

MacOS - to install with homebrew:

``` brew
brew install verilator cmake
```
42 changes: 0 additions & 42 deletions WORKSPACE

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include <gtest/gtest.h>
using namespace testing;

#include "gtestverilog/gtestverilog.h"
#include "gtest-verilog/gtest-verilog.h"
using namespace gtestverilog;

#include "gtestverilog/CounterTestBench.h"
#include "CounterTestBench.h"
using namespace countertestbench;

namespace {
Expand Down Expand Up @@ -88,4 +88,4 @@ TEST_F(Counter, ShouldHandleLargeTraces) {
.port(i_simulate_sequential).signal( "10" ).repeat(1001);

ASSERT_THAT(testBench.trace, MatchesTrace(traceExpected));
}
}
File renamed without changes.
File renamed without changes.
64 changes: 0 additions & 64 deletions gtestverilog/BUILD

This file was deleted.

45 changes: 0 additions & 45 deletions gtestverilog/defs.bzl

This file was deleted.

5 changes: 0 additions & 5 deletions gtestverilog/gtestverilog.h

This file was deleted.

File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "Trace.h"

#ifndef MATCHER_P
#error "matcher_p is not defined here"
#endif

namespace gtestverilog {

namespace matches_trace {
bool compare(const Trace& a, const Trace& b, ::testing::MatchResultListener& listener);
}

MATCHER_P(MatchesTrace, trace, "") {
MATCHER_P(MatchesTrace, trace, "Matches Trace") {
if (!matches_trace::compare(arg, trace, *result_listener)) {
return false;
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 5 additions & 0 deletions include/gtest-verilog/gtest-verilog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "MatchesTrace.h"
#include "TestBench.h"
#include "TraceBuilder.h"
Loading