Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reintroduce configure time SystemC and UVM-SystemC build scripts #95

Merged
merged 1 commit into from
Oct 26, 2024
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: 7 additions & 0 deletions SoCMakeConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,10 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/riscv/sail/sail_install.cmake")
# ====== Tmake =======================
# ====================================
include("${CMAKE_CURRENT_LIST_DIR}/cmake/tmake/tmake.cmake")


# ====================================
# ====== Build scripts ===============
# ====================================
include("${CMAKE_CURRENT_LIST_DIR}/cmake/build_scripts/systemc/systemc_build.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/build_scripts/uvm-systemc/uvm-systemc_build.cmake")
24 changes: 24 additions & 0 deletions cmake/build_scripts/systemc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.25)
project(systemc_build)

include("../../utils/option.cmake")

set(SYSTEMC_VERSIONS 3.0.0 2.3.4 2.3.3 2.3.2 2.3.1a 2.3.0a)
option_enum(VERSION "Version of SystemC to build" "${SYSTEMC_VERSIONS}" "3.0.0")
option_enum(CMAKE_CXX_STANDARD "C++ Standard" "98;11;14;17;20;23;26" "17")

include(GNUInstallDirs)
include(ExternalProject)

ExternalProject_Add(systemc
URL https://github.com/accellera-official/systemc/archive/refs/tags/${VERSION}.tar.gz
PREFIX ${PROJECT_BINARY_DIR}
INSTALL_DIR ${PREFIX}
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
-DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_LIBDIR}
-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
-DENABLE_PHASE_CALLBACKS_TRACING=OFF
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
)
56 changes: 56 additions & 0 deletions cmake/build_scripts/systemc/systemc_build.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

function(systemc_build)
cmake_parse_arguments(ARG "EXACT_VERSION" "VERSION;INSTALL_DIR" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}")
endif()

include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../utils/colours.cmake")

unset(CMAKE_ARG_VERSION)
if(ARG_VERSION)
set(CMAKE_ARG_VERSION "-DVERSION=${ARG_VERSION}")
endif()

if(NOT ARG_INSTALL_DIR)
if(FETCHCONTENT_BASE_DIR)
set(ARG_INSTALL_DIR ${FETCHCONTENT_BASE_DIR}/systemc)
else()
set(ARG_INSTALL_DIR ${PROJECT_BINARY_DIR}/systemc)
endif()
endif()

find_package(SystemCLanguage ${ARG_VERSION} CONFIG
HINTS ${ARG_INSTALL_DIR}
)

if(ARG_EXACT_VERSION)
if(NOT "${SystemCLanguage_VERSION_MAJOR}.${SystemCLanguage_VERSION_MINOR}.${SystemCLanguage_VERSION_PATCH}" STREQUAL ${ARG_VERSION})
set(SystemCLanguage_FOUND FALSE)
endif()
endif()

if(NOT SystemCLanguage_FOUND)
message(STATUS "${Magenta}[SystemC Not Found]${ColourReset}")
message(STATUS "${Magenta}[Building SystemC]${ColourReset}")
execute_process(COMMAND ${CMAKE_COMMAND}
-S ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
-B ${CMAKE_BINARY_DIR}/systemc-build
${CMAKE_ARG_VERSION}
-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}
COMMAND_ECHO STDOUT
)

execute_process(COMMAND ${CMAKE_COMMAND}
--build ${CMAKE_BINARY_DIR}/systemc-build
--parallel
)
endif()

find_package(SystemCLanguage ${ARG_VERSION} CONFIG REQUIRED
HINTS ${ARG_INSTALL_DIR}
)

message(STATUS "${Green}[Found SystemC]${ColourReset}: ${SystemCLanguage_VERSION} in ${SystemCLanguage_DIR}")

endfunction()
67 changes: 67 additions & 0 deletions cmake/build_scripts/uvm-systemc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.25)
project(uvm-systemc_build)

include("../../utils/option.cmake")

set(UVM-SYSTEMC_VERSIONS 1.0-beta6 1.0-beta5 1.0-beta3 1.0-beta1 1.0-alpha1)
option_enum(VERSION "Version of UVM-SystemC to build" "${UVM-SYSTEMC_VERSIONS}" "1.0-beta6")
option_enum(CMAKE_CXX_STANDARD "C++ Standard" "98;11;14;17;20;23;26" "17")
option_string(SYSTEMC_HOME "SystemC install directory" " ")

if(SYSTEMC_HOME STREQUAL " ")
message(FATAL_ERROR "Please specify SYSTEMC_HOME variable")
endif()


include(GNUInstallDirs)
include(ExternalProject)

ExternalProject_Add(uvm-systemc
URL https://www.accellera.org/images/downloads/drafts-review/uvm-systemc-${VERSION}.tar.gz
PREFIX ${PROJECT_BINARY_DIR}
INSTALL_DIR ${CMAKE_INSTALL_PREFIX}

CONFIGURE_COMMAND autoreconf -fiv <SOURCE_DIR> &&
<SOURCE_DIR>/configure
CC=${CMAKE_C_COMPILER}
CXX=${CMAKE_CXX_COMPILER}
CXXFLAGS=-std=c++${CMAKE_CXX_STANDARD}
--with-systemc=${SYSTEMC_HOME}
--with-arch-suffix=
--prefix=${CMAKE_INSTALL_PREFIX}
)


file(MAKE_DIRECTORY "${CMAKE_INSTALL_PREFIX}/include")

add_library(uvm-systemc_shared INTERFACE)
target_link_libraries(uvm-systemc_shared INTERFACE "${CMAKE_INSTALL_PREFIX}/lib/libuvm-systemc.so")
target_include_directories(uvm-systemc_shared INTERFACE "${CMAKE_INSTALL_PREFIX}/include")
set_property(TARGET uvm-systemc_shared PROPERTY EXPORT_NAME shared)

add_library(uvm-systemc_static INTERFACE)
target_link_libraries(uvm-systemc_static INTERFACE "${CMAKE_INSTALL_PREFIX}/lib/libuvm-systemc.a")
target_include_directories(uvm-systemc_static INTERFACE "${CMAKE_INSTALL_PREFIX}/include")
set_property(TARGET uvm-systemc_static PROPERTY EXPORT_NAME static)

install(TARGETS uvm-systemc_shared uvm-systemc_static
EXPORT UVM-SystemCTargets
FILE_SET HEADERS
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"UVM-SystemCConfigVersion.cmake"
VERSION ${VERSION}
COMPATIBILITY AnyNewerVersion)

install(EXPORT UVM-SystemCTargets
FILE UVM-SystemCTargets.cmake
NAMESPACE UVM-SystemC::
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/UVM-SystemC)

install(FILES "UVM-SystemCConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/UVM-SystemCConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/cmake/UVM-SystemC)
4 changes: 4 additions & 0 deletions cmake/build_scripts/uvm-systemc/UVM-SystemCConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include(CMakeFindDependencyMacro)
# find_dependency(xx 2.0)
# find_package(SystemCLanguage CONFIG REQUIRED)
include(${CMAKE_CURRENT_LIST_DIR}/UVM-SystemCTargets.cmake)
60 changes: 60 additions & 0 deletions cmake/build_scripts/uvm-systemc/uvm-systemc_build.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

function(uvm_systemc_build)
cmake_parse_arguments(ARG "EXACT_VERSION" "VERSION;INSTALL_DIR" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}")
endif()

include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../utils/colours.cmake")

unset(CMAKE_ARG_VERSION)
if(ARG_VERSION)
set(CMAKE_ARG_VERSION "-DVERSION=${ARG_VERSION}")
endif()

if(NOT ARG_INSTALL_DIR)
if(FETCHCONTENT_BASE_DIR)
set(ARG_INSTALL_DIR ${FETCHCONTENT_BASE_DIR}/uvm-systemc)
else()
set(ARG_INSTALL_DIR ${PROJECT_BINARY_DIR}/uvm-systemc)
endif()
endif()

# TODO ARG_VERSION cannot be used as its not following major.minor.patch
find_package(UVM-SystemC CONFIG
HINTS ${ARG_INSTALL_DIR}
)
get_target_property(SYSTEMC_INC_DIR SystemC::systemc INTERFACE_INCLUDE_DIRECTORIES)
set(SYSTEMC_HOME "${SYSTEMC_INC_DIR}/../")

if(NOT SystemCLanguage_DIR)
message(FATAL_ERROR "Please provide SystemC library using \"systemc_build()\" or \"find_package()\" ")
endif()

if(NOT UVM-SystemC_FOUND)
message(STATUS "${Magenta}[UVM-SystemC Not Found]${ColourReset}")
message(STATUS "${Magenta}[Building UVM-SystemC]${ColourReset}")
execute_process(COMMAND ${CMAKE_COMMAND}
-S ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
-B ${CMAKE_BINARY_DIR}/uvm-systemc-build
${CMAKE_ARG_VERSION}
-DSYSTEMC_HOME=${SYSTEMC_HOME}
-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}
COMMAND_ECHO STDOUT
)

execute_process(COMMAND ${CMAKE_COMMAND}
--build ${CMAKE_BINARY_DIR}/uvm-systemc-build
--parallel
--target install
)
endif()

find_package(UVM-SystemC CONFIG REQUIRED
HINTS ${ARG_INSTALL_DIR}
)

message(STATUS "${Green}[Found UVM-SystemC]${ColourReset}: ${UVM-SystemC_VERSION} in ${UVM-SystemC_DIR}")

endfunction()

15 changes: 15 additions & 0 deletions examples/systemc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.25)
project(systemc_example CXX)

include("../../SoCMakeConfig.cmake")

set(FETCHCONTENT_BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/deps/_deps)

systemc_build(VERSION 3.0.0 EXACT_VERSION)

add_executable(systemc_example
sc_main.cpp
)

target_link_libraries(systemc_example PUBLIC
SystemC::systemc)
23 changes: 23 additions & 0 deletions examples/systemc/sc_main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Learn with Examples, 2020, MIT license
#include <systemc> // include the systemC header file
using namespace sc_core; // use namespace

void hello1() { // a normal c++ function
std::cout << "Hello world using approach 1" << std::endl;
}

struct HelloWorld : sc_module { // define a systemC module
SC_CTOR(HelloWorld) {// constructor function, to be explained later
SC_METHOD(hello2); // register a member function to the kernel
}
void hello2(void) { // a function for systemC simulation kernel, void inside () can be omitted
std::cout << "Hello world using approach 2" << std::endl;
}
};

int sc_main(int, char*[]) { // entry point
hello1(); // approach #1: manually invoke a normal function
HelloWorld helloworld("helloworld"); // approach #2, instantiate a systemC module
sc_start(); // let systemC simulation kernel to invoke helloworld.hello2();
return 0;
}
20 changes: 20 additions & 0 deletions examples/uvm-systemc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.25)
project(uvm-systemc_example CXX)

include("../../SoCMakeConfig.cmake")

set(FETCHCONTENT_BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/deps/_deps)

systemc_build(VERSION 3.0.0 EXACT_VERSION)
uvm_systemc_build(VERSION 1.0-beta6)

add_executable(systemc_example
hello_world.cpp
)
target_include_directories(systemc_example PUBLIC
.
)

target_link_libraries(systemc_example PUBLIC
SystemC::systemc
UVM-SystemC::shared)
90 changes: 90 additions & 0 deletions examples/uvm-systemc/consumer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//----------------------------------------------------------------------
// Copyright 2014 NXP B.V.
// Copyright 2007-2010 Mentor Graphics Corporation
// Copyright 2007-2011 Cadence Design Systems, Inc.
// Copyright 2010-2011 Synopsys, Inc.
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
//----------------------------------------------------------------------

#ifndef CONSUMER_H_
#define CONSUMER_H_

#include <systemc>
#include <uvm>

#include "packet.h"

template <typename T = packet>
class consumer : public uvm::uvm_component
{
public:
uvm::uvm_blocking_put_imp<T,consumer<T> > in;
uvm::uvm_get_port<T> out;

consumer( uvm::uvm_component_name name )
: uvm::uvm_component(name),
in("in", this),
out("out"),
count(0)
{}

UVM_COMPONENT_UTILS(consumer<T>);

virtual void run_phase(uvm::uvm_phase& phase)
{
T p;
while(out.size())
{
out->get(p);
put(p);
}
}

void put(const T& p)
{
m.lock(); //lock.get();

count++;

accept_tr(p);
sc_core::wait(10, sc_core::SC_US);

begin_tr(p);

sc_core::wait(30, sc_core::SC_US);
end_tr(p);

std::ostringstream str;
str << "Received "
<< p
<< " local_count="
<< count;

UVM_INFO("consumer", str.str(), uvm::UVM_MEDIUM);

if( uvm::uvm_report_enabled( uvm::UVM_HIGH, uvm::UVM_INFO, ""))
p.print();

m.unlock(); //lock.put();
}

private:
int count;
sc_core::sc_mutex m; // semaphore lock
};

#endif /* CONSUMER_H_ */
Loading
Loading