Skip to content

Commit

Permalink
Issue chipsalliance#817 Use Python as build scripting tool
Browse files Browse the repository at this point in the history
Swap out tcl in favor of Python. Notable changes in transition include the
following:

* Unlike previous tcl based implementation, only the classes account towards
  UHDM ids. This assures that introducing new declarations in existing models
  do not jumble everything.
* Order of the following is now identical to the order of declarations in
  model file
  ** Variable & function declarations in header files
  ** Order of callbacks in vpi_visitor, VpiListener & Serializer
* Introducing two new outputs
  ** VpiListenerTracer - Prints formatted ordered callbacks to assist
     in debugging
  ** class_hiearchy - A simple formatted text file that list all models
     in OO hierarchy
* In applicable generated files (uhdm_types, uhdm_forward_decl, containers,
  and alike) the output is sorted
* Each individual script is independently executable
  • Loading branch information
hs-apotell committed Sep 16, 2021
1 parent 32d9ea3 commit 417f63f
Show file tree
Hide file tree
Showing 36 changed files with 3,593 additions and 147 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
with:
msystem: MSYS
update: true
install: make cmake ninja gcc
install: make cmake ninja gcc python
env:
MSYS2_PATH_TYPE: inherit

Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
# Environment cache folders & files
__pycache__
.vs
.vscode
*.user

# Build directories
build
out
CMakeBuilds
51 changes: 35 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ option(
"Building with clang++ and libc++(in Linux). To enable with: -DWITH_LIBCXX=On"
On)
option(UHDM_BUILD_TESTS "Enable testing." ON)
option(WITH_PYTHON_GENERATOR "Use Python generator instead of TCL." OFF)

project(UHDM)

# NOTE: Policy changes has to happen before adding any subprojects
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

find_package(Python3 REQUIRED COMPONENTS Interpreter)
message(STATUS "Python3_EXECUTABLE = ${Python3_EXECUTABLE}")

set(BUILD_TESTING OFF CACHE BOOL "Don't build capnproto tests")
add_subdirectory(third_party/capnproto EXCLUDE_FROM_ALL)

Expand All @@ -47,7 +51,7 @@ if(MSVC)
"${CMAKE_CXX_FLAGS_DEBUG} ${TCMALLOC_COMPILE_OPTIONS} /W3 /bigobj ${MY_CXX_WARNING_FLAGS}"
)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELEASE} ${TCMALLOC_COMPILE_OPTIONS} /W3 /bigobj ${MY_CXX_WARNING_FLAGS}"
"${CMAKE_CXX_FLAGS_RELEASE} ${TCMALLOC_COMPILE_OPTIONS} /Zi /W3 /bigobj ${MY_CXX_WARNING_FLAGS}"
)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${TCMALLOC_COMPILE_OPTIONS} /W3 /bigobj ${MY_CXX_WARNING_FLAGS}"
Expand All @@ -62,7 +66,9 @@ else()
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} ${TCMALLOC_COMPILE_OPTIONS} -Wall -O0 -g ${MSYS_COMPILE_OPTIONS} ${MY_CXX_WARNING_FLAGS}"
)

set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${TCMALLOC_COMPILE_OPTIONS} -Wall -O3 -g ${MSYS_COMPILE_OPTIONS} ${MY_CXX_WARNING_FLAGS}"
)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${TCMALLOC_COMPILE_OPTIONS} -Wall -O3 -DNDEBUG ${MSYS_COMPILE_OPTIONS} ${MY_CXX_WARNING_FLAGS}"
)
Expand All @@ -81,25 +87,38 @@ endif()

# All the files the generator depends on.
file(GLOB yaml_SRC ${PROJECT_SOURCE_DIR}/model/*.yaml)

file(GLOB templates_SRC ${PROJECT_SOURCE_DIR}/templates/*.h
${PROJECT_SOURCE_DIR}/templates/*.cpp)

set(model-GENERATED_UHDM ${GENDIR}/src/UHDM.capnp)
set_source_files_properties(${model-GENERATED_UHDM} PROPERTIES GENERATED TRUE)
add_custom_command(
OUTPUT ${model-GENERATED_UHDM}
COMMAND tclsh ${PROJECT_SOURCE_DIR}/model_gen/model_gen.tcl
${PROJECT_SOURCE_DIR}/model/models.lst ${CMAKE_CURRENT_BINARY_DIR}
${GENDIR}
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
DEPENDS ${PROJECT_SOURCE_DIR}/model_gen/model_gen.tcl
${PROJECT_SOURCE_DIR}/model_gen/generate_elaborator.tcl
${PROJECT_SOURCE_DIR}/model_gen/parse_model.tcl
${PROJECT_SOURCE_DIR}/model/models.lst
${PROJECT_SOURCE_DIR}/templates/UHDM.capnp
${yaml_SRC}
${templates_SRC})

if (WITH_PYTHON_GENERATOR)
file(GLOB py_SRC ${PROJECT_SOURCE_DIR}/scripts/*.py)
add_custom_command(
OUTPUT ${model-GENERATED_UHDM}
COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/generate.py --source-dirpath=${UHDM_SOURCE_DIR} -output-dirpath=${GENDIR}
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
DEPENDS ${PROJECT_SOURCE_DIR}/model/models.lst
${PROJECT_SOURCE_DIR}/templates/UHDM.capnp
${py_SRC}
${yaml_SRC}
${templates_SRC})
else()
add_custom_command(
OUTPUT ${model-GENERATED_UHDM}
COMMAND tclsh ${PROJECT_SOURCE_DIR}/model_gen/model_gen.tcl
${PROJECT_SOURCE_DIR}/model/models.lst ${CMAKE_CURRENT_BINARY_DIR}
${GENDIR}
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
DEPENDS ${PROJECT_SOURCE_DIR}/model_gen/model_gen.tcl
${PROJECT_SOURCE_DIR}/model_gen/generate_elaborator.tcl
${PROJECT_SOURCE_DIR}/model_gen/parse_model.tcl
${PROJECT_SOURCE_DIR}/model/models.lst
${PROJECT_SOURCE_DIR}/templates/UHDM.capnp
${yaml_SRC}
${templates_SRC})
endif()

set(model-GENERATED_SRC ${GENDIR}/src/UHDM.capnp.h
${GENDIR}/src/UHDM.capnp.c++)
Expand Down
50 changes: 25 additions & 25 deletions model_gen/model_gen.tcl
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ proc printMethods { classname type vpi card {real_type ""} } {
while (parent) {
const BaseClass* actual_parent = parent->VpiParent();
if (parent->UhdmType() == uhdmdesign) break;
if (parent->UhdmType() == uhdmpackage || parent->UhdmType() == uhdmclass_defn) column = true;
if ((parent->UhdmType() == uhdmpackage) || (parent->UhdmType() == uhdmclass_defn)) column = true;
const std::string\\& name = (!parent->VpiName().empty()) ? parent->VpiName() : parent->VpiDefName();
UHDM_OBJECT_TYPE parent_type = (parent != nullptr) ? parent->UhdmType() : uhdmunsupported_stmt;
UHDM_OBJECT_TYPE actual_parent_type = (actual_parent != nullptr) ? actual_parent->UhdmType() : uhdmunsupported_stmt;
Expand Down Expand Up @@ -171,7 +171,7 @@ proc printMethods { classname type vpi card {real_type ""} } {
unsigned int index = names.size() -1;
while(1) {
fullName += names\[index\];
if (index > 0) fullName += (column) ? \"::\" : \".\";
if (index > 0) fullName += column ? \"::\" : \".\";
if (index == 0) break;
index--;
}
Expand Down Expand Up @@ -274,7 +274,7 @@ proc printIterateBody { name classname vpi card } {
set vpi_iterate_body ""
if {$card == "any"} {
append vpi_iterate_body "
if (handle->type == uhdm${classname} \\&\\& type == $vpi) {
if ((handle->type == uhdm${classname}) \\&\\& (type == $vpi)) {
if ((($classname*)(object))->[string toupper ${name} 0 0]())
return NewHandle(uhdm${name}, (($classname*)(object))->[string toupper ${name} 0 0]());
else return 0;
Expand Down Expand Up @@ -379,7 +379,7 @@ proc printGetHandleBody { classname type vpi object card } {
set casted_object2 "(($classname*)(object))"
}
append vpi_get_handle_body "
if (handle->type == uhdm${classname} \\&\\& type == $vpi) {
if ((handle->type == uhdm${classname}) \\&\\& (type == $vpi)) {
if ($casted_object1->[string toupper ${object} 0 0]()))
return NewHandle($casted_object1->[string toupper ${object} 0 0]())->UhdmType(), $casted_object2->[string toupper ${object} 0 0]());
else return 0;
Expand All @@ -393,7 +393,7 @@ proc printGetStrVisitor {classname type vpi card} {
set vpi_get_str_body ""
if {($card == 1) && ($type == "string") && ($vpi != "vpiFile")} {
append vpi_get_str_body " if (const char* s = vpi_get_str($vpi, obj_h))
stream_indent(out, indent) << \"|$vpi:\" << s << \"\\n\";
stream_indent(out, indent) << \"|$vpi:\" << s << std::endl;
"
}
return $vpi_get_str_body
Expand All @@ -420,7 +420,7 @@ proc printGetVisitor {classname type vpi card} {
"
} elseif {($card == 1) && ($type != "string") && ($vpi != "vpiLineNo") && ($vpi != "vpiColumnNo") && ($vpi != "vpiEndLineNo") && ($vpi != "vpiEndColumnNo") && ($vpi != "vpiType")} {
append vpi_get_body " if (const int n = vpi_get($vpi, obj_h))
stream_indent(out, indent) << \"|$vpi:\" << n << \"\\n\";
stream_indent(out, indent) << \"|$vpi:\" << n << std::endl;
"
}
return $vpi_get_body
Expand All @@ -436,15 +436,15 @@ proc printGetStrBody {classname type vpi card} {
if {$card == 1 && ($type == "string")} {
if {$vpi == "vpiFullName"} {
append vpi_get_str_body "
if (handle->type == uhdm${classname} \\&\\& property == $vpi) {
if ((handle->type == uhdm${classname}) \\&\\& (property == $vpi)) {
const $classname* const o = (const $classname*)(obj);
return (o->[string toupper ${vpi} 0 0]().empty() || o->[string toupper ${vpi} 0 0]() == o->VpiName())
? 0
: (PLI_BYTE8*) o->[string toupper ${vpi} 0 0]().c_str();
}"
} else {
append vpi_get_str_body "
if (handle->type == uhdm${classname} \\&\\& property == $vpi) {
if ((handle->type == uhdm${classname}) \\&\\& (property == $vpi)) {
const $classname* const o = (const $classname*)(obj);
return (PLI_BYTE8*) (o->[string toupper ${vpi} 0 0]().empty() ? 0 : o->[string toupper ${vpi} 0 0]().c_str());
}"
Expand Down Expand Up @@ -549,15 +549,15 @@ proc printVpiVisitor {classname vpi card} {
global VISITOR_RELATIONS

set vpi_visitor ""
if ![info exist VISITOR_RELATIONS($classname)] {
set vpi_visitor " vpiHandle itr;
"
} else {
if ![regexp "vpiHandle itr;" $VISITOR_RELATIONS($classname)] {
set vpi_visitor " vpiHandle itr;
"
}
}
# if ![info exist VISITOR_RELATIONS($classname)] {
# set vpi_visitor " vpiHandle itr;
#"
# } else {
# if ![regexp "vpiHandle itr;" $VISITOR_RELATIONS($classname)] {
# set vpi_visitor " vpiHandle itr;
#"
# }
# }

if {($vpi == "vpiParent") && ($classname !="part_select")} {
return
Expand All @@ -577,7 +577,7 @@ proc printVpiVisitor {classname vpi card} {
# Prevent loop in Standard VPI
if {($vpi != "vpiModule") && ($vpi != "vpiInterface")} {
append vpi_visitor " itr = vpi_handle($vpi,obj_h);
visit_object(itr, subobject_indent, \"$vpi\", visited, out $shallowVisit);
visit_object(itr, subobject_indent, \"$vpi\", visited, out$shallowVisit);
release_handle(itr);
"
}
Expand All @@ -590,7 +590,7 @@ proc printVpiVisitor {classname vpi card} {
if {$vpi != "vpiUse"} {
append vpi_visitor " itr = vpi_iterate($vpi,obj_h);
while (vpiHandle obj = vpi_scan(itr) ) {
visit_object(obj, subobject_indent, \"$vpi\", visited, out $shallowVisit);
visit_object(obj, subobject_indent, \"$vpi\", visited, out$shallowVisit);
release_handle(obj);
}
release_handle(itr);
Expand Down Expand Up @@ -1246,8 +1246,8 @@ proc generate_code { models } {
regsub -all {<DISABLE_OBJECT_FACTORY>} $template "#if 0 // This class cannot be instantiated" template
regsub -all {<END_DISABLE_OBJECT_FACTORY>} $template "#endif" template
} else {
regsub -all {<FINAL_CLASS>} $template "final" template
regsub -all {<FINAL_DESTRUCTOR>} $template "final" template
regsub -all {<FINAL_CLASS>} $template " final" template
regsub -all {<FINAL_DESTRUCTOR>} $template " final" template
regsub -all {<VIRTUAL>} $template "virtual " template
regsub -all {<OVERRIDE_OR_FINAL>} $template "final" template
regsub -all {<DISABLE_OBJECT_FACTORY>} $template "" template
Expand Down Expand Up @@ -1291,7 +1291,7 @@ proc generate_code { models } {

if {$modeltype == "class_def"} {
# DeepClone() not implemented for class_def; just declare to narrow the covariant return type.
append methods($classname) "\n ${classname}* DeepClone(Serializer* serializer, ElaboratorListener* elab_listener, BaseClass* parent) const override = 0;\n"
append methods($classname) "\n virtual ${classname}* DeepClone(Serializer* serializer, ElaboratorListener* elab_listener, BaseClass* parent) const override = 0;\n"
} else {
# Builtin properties do not need to be specified in each models
# Builtins: "vpiParent, Parent type, vpiFile, Id" method and field
Expand All @@ -1305,9 +1305,9 @@ proc generate_code { models } {
append methods($classname) [printMethods $classname "unsigned int" uhdmId 1]
append members($classname) [printMembers "unsigned int" uhdmId 1]
if [regexp {_call} ${classname}] {
append methods($classname) "\n tf_call* DeepClone(Serializer* serializer, ElaboratorListener* elab_listener, BaseClass* parent) const override;\n"
append methods($classname) "\n virtual tf_call* DeepClone(Serializer* serializer, ElaboratorListener* elab_listener, BaseClass* parent) const override;\n"
} else {
append methods($classname) "\n ${classname}* DeepClone(Serializer* serializer, ElaboratorListener* elab_listener, BaseClass* parent) const override;\n"
append methods($classname) "\n virtual ${classname}* DeepClone(Serializer* serializer, ElaboratorListener* elab_listener, BaseClass* parent) const override;\n"
}
append vpi_handle_body($classname) [printGetHandleBody $classname BaseClass vpiParent vpiParent 1]
lappend capnp_schema($classname) [list vpiParent UInt64]
Expand Down Expand Up @@ -1506,7 +1506,7 @@ proc generate_code { models } {

if {($type_specified == 0) && ($modeltype == "obj_def")} {
set vpiclasstype [makeVpiName $classname]
append methods($classname) "\n unsigned int VpiType() const final { return $vpiclasstype; }\n"
append methods($classname) "\n virtual unsigned int VpiType() const final { return $vpiclasstype; }\n"
lappend vpi_get_body_inst($classname) [list $classname "unsigned int" vpiType 1]

}
Expand Down
Loading

0 comments on commit 417f63f

Please sign in to comment.