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
2 changes: 1 addition & 1 deletion .github/workflows/macOS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
cd build
export PATH="$(brew --prefix qt)/bin:$PATH"
export LDFLAGS="-L$(brew --prefix qt)/lib -Wl,-rpath,$(brew --prefix llvm)/lib"
cmake -G Ninja .. -DQt5_DIR="$(brew --prefix qt)/lib/cmake" -DCMAKE_BUILD_TYPE=Debug -DBUILD_ALL_PLUGINS=ON -DBUILD_TESTS=ON -DPL_GUI=ON
cmake -G Ninja .. -DQt6_DIR="$(brew --prefix qt)/lib/cmake/Qt6" -DCMAKE_BUILD_TYPE=Debug -DBUILD_ALL_PLUGINS=ON -DBUILD_TESTS=ON -DPL_GUI=ON
env:
HAL_BASE_PATH: ${{runner.workspace}}/hal/build
CCACHE_DIR: ${{runner.workspace}}/.ccache
Expand Down
1 change: 0 additions & 1 deletion Brewfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,3 @@ brew "z3"
brew "boost"
brew "readline"
brew "verilator"
brew "graphviz"
299 changes: 183 additions & 116 deletions CHANGELOG.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions include/hal_core/netlist/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ namespace hal
* @param[in] pins - The pins to be assigned to the pin group. Defaults to an empty vector.
* @param[in] direction - The direction of the pin group, if any. Defaults to `PinDirection::none`.
* @param[in] type - The type of the pin group, if any. Defaults to `PinType::none`.
* @param[in] ascending - Set `true` for ascending pin order (from 0 to n-1), `false` otherwise (from n-1 to 0). Defaults to `true`.
* @param[in] ascending - Set `true` for ascending pin order (from 0 to n-1), `false` otherwise (from n-1 to 0). Defaults to `false`.
* @param[in] start_index - The start index of the pin group. Defaults to `0`.
* @param[in] delete_empty_groups - Set `true` to delete groups that are empty after the pins have been assigned to the new group, `false` to keep empty groups. Defaults to `true`.
* @param[in] force_name - Set `true` to enforce the name, `false` otherwise. If a pin group with the same name already exists, the existing pin group will be renamed. Defaults to `false`.
Expand All @@ -495,7 +495,7 @@ namespace hal
const std::vector<ModulePin*> pins = {},
PinDirection direction = PinDirection::none,
PinType type = PinType::none,
bool ascending = true,
bool ascending = false,
u32 start_index = 0,
bool delete_empty_groups = true,
bool force_name = false);
Expand All @@ -508,7 +508,7 @@ namespace hal
* @param[in] pins - The pins to be assigned to the pin group. Defaults to an empty vector.
* @param[in] direction - The direction of the pin group, if any. Defaults to `PinDirection::none`.
* @param[in] type - The type of the pin group, if any. Defaults to `PinType::none`.
* @param[in] ascending - Set `true` for ascending pin order (from 0 to n-1), `false` otherwise (from n-1 to 0). Defaults to `true`.
* @param[in] ascending - Set `true` for ascending pin order (from 0 to n-1), `false` otherwise (from n-1 to 0). Defaults to `false`.
* @param[in] start_index - The start index of the pin group. Defaults to `0`.
* @param[in] delete_empty_groups - Set `true` to delete groups that are empty after the pins have been assigned to the new group, `false` to keep empty groups. Defaults to `true`.
* @param[in] force_name - Set `true` to enforce the name, `false` otherwise. If a pin group with the same name already exists, the existing pin group will be renamed. Defaults to `false`.
Expand Down
32 changes: 16 additions & 16 deletions install_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,45 @@ if [[ "$platform" == 'macOS' ]]; then
pip3 install -r requirements.txt
BREW_PREFIX=$(brew --prefix)
if [ -n "$($SHELL -c 'echo $ZSH_VERSION')" ]; then
grep -Fxq 'export PATH="$BREW_PREFIX/opt/qt/bin:$PATH"' ~/.zshrc
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/qt/bin:\$PATH\"" ~/.zshrc
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/qt/bin:$PATH"' >> ~/.zshrc
echo "export PATH=\"$BREW_PREFIX/opt/qt/bin:\$PATH\"" >> ~/.zshrc
fi

grep -Fxq 'export PATH="$BREW_PREFIX/opt/llvm@14/bin:$PATH"' ~/.zshrc
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/llvm@14/bin:\$PATH\"" ~/.zshrc
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/llvm@14/bin:$PATH"' >> ~/.zshrc
echo "export PATH=\"$BREW_PREFIX/opt/llvm@14/bin:\$PATH\"" >> ~/.zshrc
fi

grep -Fxq 'export PATH="$BREW_PREFIX/opt/flex/bin:$PATH"' ~/.zshrc
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/flex/bin:\$PATH\"" ~/.zshrc
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/flex/bin:$PATH"' >> ~/.zshrc
echo "export PATH=\"$BREW_PREFIX/opt/flex/bin:\$PATH\"" >> ~/.zshrc
fi

grep -Fxq 'export PATH="$BREW_PREFIX/opt/bison/bin:$PATH"' ~/.zshrc
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/bison/bin:\$PATH\"" ~/.zshrc
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/bison/bin:$PATH"' >> ~/.zshrc
echo "export PATH=\"$BREW_PREFIX/opt/bison/bin:\$PATH\"" >> ~/.zshrc
fi
source ~/.zshrc
elif [ -n "$($SHELL -c 'echo $BASH_VERSION')" ]; then
grep -Fxq 'export PATH="$BREW_PREFIX/opt/qt/bin:$PATH"' ~/.bash_profile
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/qt/bin:\$PATH\"" ~/.bash_profile
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/qt/bin:$PATH"' >> ~/.bash_profile
echo "export PATH=\"$BREW_PREFIX/opt/qt/bin:\$PATH\"" >> ~/.bash_profile
fi

grep -Fxq 'export PATH="$BREW_PREFIX/opt/llvm@14/bin:$PATH"' ~/.bash_profile
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/llvm@14/bin:\$PATH\"" ~/.bash_profile
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/llvm@14/bin:$PATH"' >> ~/.bash_profile
echo "export PATH=\"$BREW_PREFIX/opt/llvm@14/bin:\$PATH\"" >> ~/.bash_profile
fi

grep -Fxq 'export PATH="$BREW_PREFIX/opt/flex/bin:$PATH"' ~/.bash_profile
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/flex/bin:\$PATH\"" ~/.bash_profile
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/flex/bin:$PATH"' >> ~/.bash_profile
echo "export PATH=\"$BREW_PREFIX/opt/flex/bin:\$PATH\"" >> ~/.bash_profile
fi

grep -Fxq 'export PATH="$BREW_PREFIX/opt/bison/bin:$PATH"' ~/.bash_profile
grep -Fxq "export PATH=\"$BREW_PREFIX/opt/bison/bin:\$PATH\"" ~/.bash_profile
if ! [[ $? -eq 0 ]]; then
echo 'export PATH="$BREW_PREFIX/opt/bison/bin:$PATH"' >> ~/.bash_profile
echo "export PATH=\"$BREW_PREFIX/opt/bison/bin:\$PATH\"" >> ~/.bash_profile
fi
source ~/.bash_profile
else
Expand Down
2 changes: 2 additions & 0 deletions plugins/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
!bitorder_propagation/**/*
!boolean_influence*
!boolean_influence/**/*
!clock_tree_extractor*
!clock_tree_extractor/**/*
!dataflow_analysis*
!dataflow_analysis/**/*
!dot_viewer*
Expand Down
3 changes: 2 additions & 1 deletion plugins/clock_tree_extractor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ if(PL_CLOCK_TREE_EXTRACTOR OR BUILD_ALL_PLUGINS)
HEADER ${CLOCK_TREE_EXTRACTOR_INC}
SOURCES ${CLOCK_TREE_EXTRACTOR_SRC} ${CLOCK_TREE_EXTRACTOR_PYTHON_SRC}
LINK_LIBRARIES graph_algorithm
COMPILE_OPTIONS "-march=native"
)

add_subdirectory(test)

endif()
114 changes: 100 additions & 14 deletions plugins/clock_tree_extractor/python/python_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ namespace hal
:rtype: set[str]
)" );

py::class_<cte::ClockTree>( m, "ClockTree", R"()" )
py::class_<cte::ClockTree>( m, "ClockTree", R"(
The clock distribution network of a netlist as a directed graph whose vertices are gates and nets.
)" )
.def_static(
"from_netlist",
[]( const Netlist *netlist ) -> std::unique_ptr<cte::ClockTree> {
Expand All @@ -137,7 +139,16 @@ namespace hal
},
py::arg( "netlist" ),
py::return_value_policy::move,
R"()" )
py::keep_alive<0, 1>(),
R"(
Extract the clock tree of a netlist.

Starting at the clock pin of every flip-flop, the extraction walks against the signal direction through buffers, inverters, delay gates, clock gates and toggle flip-flops up to the global input nets that drive them.

:param hal_py.Netlist netlist: The netlist.
:returns: The clock tree on success, ``None`` otherwise.
:rtype: clock_tree_extractor.ClockTree or None
)" )
.def(
"export",
[]( const cte::ClockTree &self, const std::string &pathname ) -> bool {
Expand All @@ -151,7 +162,13 @@ namespace hal
return false;
},
py::arg( "pathname" ),
R"()" )
R"(
Write the clock tree to a DOT file.

:param str pathname: The path of the file to write.
:returns: ``True`` on success, ``False`` otherwise.
:rtype: bool
)" )
.def(
"get_subtree",
[]( const cte::ClockTree &self,
Expand All @@ -169,7 +186,16 @@ namespace hal
py::arg( "ptr" ),
py::arg( "parent" ) = false,
py::return_value_policy::move,
R"()" )
py::keep_alive<0, 1>(),
R"(
Get the clock tree below a gate or net as a clock tree of its own.

:param ptr: The gate or net.
:type ptr: hal_py.Gate or hal_py.Net
:param bool parent: Set ``True`` to start one level up, at the parent of the given object, if it has exactly one. Defaults to ``False``.
:returns: The subtree on success, ``None`` otherwise.
:rtype: clock_tree_extractor.ClockTree or None
)" )
.def(
"get_all",
[]( const cte::ClockTree &self ) -> py::list {
Expand All @@ -189,7 +215,12 @@ namespace hal
return result;
},
borrowed(),
R"()" )
R"(
Get all gates and nets of the clock tree.

:returns: A list of gates and nets.
:rtype: list[hal_py.Gate or hal_py.Net]
)" )
.def(
"get_vertex_from_ptr",
[]( const cte::ClockTree &self, const void *ptr ) -> py::object {
Expand All @@ -202,7 +233,14 @@ namespace hal
return py::none();
},
py::arg( "ptr" ),
R"()" )
R"(
Get the igraph vertex ID of a gate or net of the clock tree.

:param ptr: The gate or net.
:type ptr: hal_py.Gate or hal_py.Net
:returns: The vertex ID on success, ``None`` otherwise.
:rtype: int or None
)" )
.def(
"get_ptr_from_vertex",
[]( const cte::ClockTree &self, const igraph_integer_t vertex ) -> py::object {
Expand All @@ -225,7 +263,13 @@ namespace hal
},
py::arg( "vertex" ),
borrowed(),
R"()" )
R"(
Get the gate or net behind an igraph vertex ID of the clock tree.

:param int vertex: The vertex ID.
:returns: The gate or net on success, ``None`` otherwise.
:rtype: hal_py.Gate or hal_py.Net or None
)" )
.def(
"get_vertices_from_ptrs",
[]( const cte::ClockTree &self, const std::vector<const void *> &ptrs ) -> py::list {
Expand All @@ -238,7 +282,13 @@ namespace hal
return py::none();
},
py::arg( "ptrs" ),
R"()" )
R"(
Get the igraph vertex IDs of gates and nets of the clock tree.

:param list[hal_py.Gate or hal_py.Net] ptrs: The gates and nets.
:returns: The vertex IDs on success, ``None`` otherwise.
:rtype: list[int] or None
)" )
.def(
"get_ptrs_from_vertices",
[]( const cte::ClockTree &self, const std::vector<igraph_integer_t> &vertices ) -> py::list {
Expand Down Expand Up @@ -268,7 +318,14 @@ namespace hal
return py::none();
},
py::arg( "vertices" ),
R"()" )
borrowed(),
R"(
Get the gates and nets behind igraph vertex IDs of the clock tree.

:param list[int] vertices: The vertex IDs.
:returns: The gates and nets on success, ``None`` otherwise.
:rtype: list[hal_py.Gate or hal_py.Net] or None
)" )
.def(
"get_parents",
[]( const cte::ClockTree &self, const void *ptr ) -> py::list {
Expand Down Expand Up @@ -299,7 +356,14 @@ namespace hal
},
py::arg( "ptr" ),
borrowed(),
R"()" )
R"(
Get the gates and nets directly upstream of a gate or net in the clock tree.

:param ptr: The gate or net.
:type ptr: hal_py.Gate or hal_py.Net
:returns: The neighbors on success, ``None`` otherwise.
:rtype: list[hal_py.Gate or hal_py.Net] or None
)" )
.def(
"get_childs",
[]( const cte::ClockTree &self, const void *ptr ) -> py::list {
Expand Down Expand Up @@ -330,10 +394,32 @@ namespace hal
},
py::arg( "ptr" ),
borrowed(),
R"()" )
.def( "get_gates", &cte::ClockTree::get_gates, borrowed(), R"()" )
.def( "get_nets", &cte::ClockTree::get_nets, borrowed(), R"()" )
.def( "get_netlist", &cte::ClockTree::get_netlist, borrowed(), R"()" );
R"(
Get the gates and nets directly downstream of a gate or net in the clock tree.

:param ptr: The gate or net.
:type ptr: hal_py.Gate or hal_py.Net
:returns: The neighbors on success, ``None`` otherwise.
:rtype: list[hal_py.Gate or hal_py.Net] or None
)" )
.def( "get_gates", &cte::ClockTree::get_gates, borrowed(), R"(
Get all gates of the clock tree.

:returns: The gates.
:rtype: list[hal_py.Gate]
)" )
.def( "get_nets", &cte::ClockTree::get_nets, borrowed(), R"(
Get all nets of the clock tree.

:returns: The nets.
:rtype: list[hal_py.Net]
)" )
.def( "get_netlist", &cte::ClockTree::get_netlist, borrowed(), R"(
Get the netlist the clock tree was extracted from.

:returns: The netlist.
:rtype: hal_py.Netlist
)" );

#ifndef PYBIND11_MODULE
return m.ptr();
Expand Down
2 changes: 2 additions & 0 deletions plugins/clock_tree_extractor/src/clock_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,10 @@ namespace hal
}
else if( clk->is_global_input_net() )
{
// the flip-flop is clocked straight from the outside: the net is the root and the flip-flop its only child
vertices.insert( (void *) clk );
ptrs_to_type[(void *) clk] = PtrType::NET;
edges.insert( { (void *) clk, (void *) ff } );
continue;
}
else if( clk->get_num_of_sources() == 0 )
Expand Down
13 changes: 13 additions & 0 deletions plugins/clock_tree_extractor/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
if(BUILD_TESTS)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/tests ${CMAKE_SOURCE_DIR}/plugins/clock_tree_extractor/include ${CMAKE_SOURCE_DIR}/plugins/graph_algorithm/include)

add_executable(runTest-clock_tree_extractor clock_tree_extractor.cpp)

target_link_libraries(runTest-clock_tree_extractor clock_tree_extractor graph_algorithm pthread gtest hal::core hal::netlist test_utils)

add_test(runTest-clock_tree_extractor ${CMAKE_BINARY_DIR}/bin/hal_plugins/runTest-clock_tree_extractor --gtest_output=xml:${CMAKE_BINARY_DIR}/gtestresults-runBasicTests.xml)

if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
add_sanitizers(runTest-clock_tree_extractor)
endif()
endif()
Loading
Loading