Skip to content

Commit

Permalink
Feature/resynthesis (#583)
Browse files Browse the repository at this point in the history
* cleanup and new load_netlist function that takes gate library pointer

* documentation cleanup

* fixed docs

* boolean function fixes

* fixed the fixes

* added use_net_variables parameetr

* utils update

* use c++17 and activate insertion of braces

* fixed standard

* fixes

* fixed const 1 and 0 nets

* create empty plugin

* allow to control labeling of global I/O for copied netlists

* move resynthesis functions

* docu fixes

* resynthesis completed

* changelog update
  • Loading branch information
SJulianS authored Jul 16, 2024
1 parent c827850 commit 7575227
Show file tree
Hide file tree
Showing 14 changed files with 1,926 additions and 42 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
* **WARNING:** this release breaks the API of the `bitorder_propagation` plugin
* plugins
* added `resynthesis` plugin
* moved `decompose_gate` and `decompose_gates_of_type` from `netlist_preprocessing` plugin and slightly changed their API
* added functions for logic re-synthesis that write out parts of the current netlist and call Yosys as an open-source synthesizer to produce a new gate-level netlist based on a user-defined gate library
* changed `bitorder_propagation` plugin
* changed API so that no instance of the plugin needs to be created anymore to apply its algorithms
* changed propagation logic for better results
Expand All @@ -14,7 +17,8 @@ All notable changes to this project will be documented in this file.
* added `use_net_variables` parameter to `Gate::get_resolved_boolean_function` to choose whether to use input pins or nets as variable names
* added `utils::get_unique_temp_directory`
* added `base` parameter to `utils::wrapped_stoull` and `utils::wrapped_stoul`
* added datatype 'ExistingFile' to plugin parameter
* added `all_global_io` parameter to `SubgraphNetlistDecorator::copy_subgraph_netlist` to configure labeling of global inputs and outputs
* added datatype `ExistingFile` to plugin parameter
* added helper gate libraries needed for resynthesis; this is a dirty hack, expect more changes later
* changed MUX data input and output pins in all gate libraries to `PinType::data`
* bugfixes
Expand All @@ -24,7 +28,7 @@ All notable changes to this project will be documented in this file.
* fixed VCD writer of `netlist_simulation_controller` plugin
* fixed handling of const `0` and `1` nets in `verilog_parser`, `vhdl_parser`, and `verilog_writer` plugins
* fixed layout bug which occured when leftmost node had no inputs
* fixed missing sort indicator when sorting entries in 'Views' widget
* fixed missing sort indicator when sorting entries in `Views` widget
* fixed bug loading simulation data by cleaning map before loading controller from project

## [4.3.0](v4.3.0) - 2024-07-02 13:42:55+02:00 (urgency: medium)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,28 @@ namespace hal
* Get a deep copy of a netlist subgraph including all of its gates and nets, but excluding modules and groupings.
*
* @param[in] subgraph_gates - The gates making up the subgraph that shall be copied from the netlist.
* @param[in] all_global_io - Set `true` to mark all nets as global input or output that lost at least one source or destination in the copied netlist, `false` to only mark them if all sources or destinations were removed. Global inputs and outputs of the parent netlist will always also be annotated as global inputs or outputs. Defaults to `false`.
* @return The copied subgraph netlist on success, an error otherwise.
*/
Result<std::unique_ptr<Netlist>> copy_subgraph_netlist(const std::vector<const Gate*>& subgraph_gates) const;
Result<std::unique_ptr<Netlist>> copy_subgraph_netlist(const std::vector<const Gate*>& subgraph_gates, const bool all_global_io = false) const;

/**
* Get a deep copy of a netlist subgraph including all of its gates and nets, but excluding modules and groupings.
*
* @param[in] subgraph_gates - The gates making up the subgraph that shall be copied from the netlist.
* @param[in] all_global_io - Set `true` to mark all nets as global input or output that lost at least one source or destination in the copied netlist, `false` to only mark them if all sources or destinations were removed. Global inputs and outputs of the parent netlist will always also be annotated as global inputs or outputs. Defaults to `false`.
* @return The copied subgraph netlist on success, an error otherwise.
*/
Result<std::unique_ptr<Netlist>> copy_subgraph_netlist(const std::vector<Gate*>& subgraph_gates) const;
Result<std::unique_ptr<Netlist>> copy_subgraph_netlist(const std::vector<Gate*>& subgraph_gates, const bool all_global_io = false) const;

/**
* Get a deep copy of a netlist subgraph including all of its gates and nets, but excluding modules and groupings.
*
* @param[in] subgraph_module - The module making up the subgraph that shall be copied from the netlist.
* @param[in] all_global_io - Set `true` to mark all nets as global input or output that lost at least one source or destination in the copied netlist, `false` to only mark them if all sources or destinations were removed. Global inputs and outputs of the parent netlist will always also be annotated as global inputs or outputs. Defaults to `false`.
* @return The copied subgraph netlist on success, an error otherwise.
*/
Result<std::unique_ptr<Netlist>> copy_subgraph_netlist(const Module* subgraph_module) const;
Result<std::unique_ptr<Netlist>> copy_subgraph_netlist(const Module* subgraph_module, const bool all_global_io = false) const;

/**
* Get the combined Boolean function of a subgraph of combinational gates starting at the source of the provided subgraph output net.
Expand Down
2 changes: 2 additions & 0 deletions plugins/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
!netlist_preprocessing/**/*
!python_shell*
!python_shell/**/*
!resynthesis*
!resynthesis/**/*
!simulator
!solve_fsm*
!solve_fsm/**/*
Expand Down
15 changes: 15 additions & 0 deletions plugins/resynthesis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
option(PL_RESYNTHESIS "PL_RESYNTHESIS" OFF)

if(PL_RESYNTHESIS OR BUILD_ALL_PLUGINS)

file(GLOB_RECURSE RESYNTHESIS_INC ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
file(GLOB_RECURSE RESYNTHESIS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE RESYNTHESIS_PYTHON_SRC ${CMAKE_CURRENT_SOURCE_DIR}/python/*.cpp)

hal_add_plugin(resynthesis
SHARED
HEADER ${RESYNTHESIS_INC}
SOURCES ${RESYNTHESIS_SRC} ${RESYNTHESIS_PYTHON_SRC}
PYDOC SPHINX_DOC_INDEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/documentation/resynthesis.rst
)
endif()
8 changes: 8 additions & 0 deletions plugins/resynthesis/documentation/resynthesis.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Resynthesis
==========================

.. automodule:: resynthesis
:members:

.. autoclass:: resynthesis.ResynthesisPlugin
:members:
86 changes: 86 additions & 0 deletions plugins/resynthesis/include/resynthesis/plugin_resynthesis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// MIT License
//
// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

/**
* @file plugin_resynthesis.h
* @brief This file contains all functions related to the HAL plugin API.
*/

#pragma once

#include "hal_core/plugin_system/plugin_interface_base.h"

namespace hal
{
class Netlist;

/**
* @class ResynthesisPlugin
* @brief Plugin interface for the netlist resynthesis plugin.
*
* This class provides an interface to integrate the netlist resynthesis as a plugin within the HAL framework.
*/
class PLUGIN_API ResynthesisPlugin : public BasePluginInterface
{
public:
/**
* @brief Default constructor for `ResynthesisPlugin`.
*/
ResynthesisPlugin() = default;

/**
* @brief Default destructor for `ResynthesisPlugin`.
*/
~ResynthesisPlugin() = default;

/**
* @brief Get the name of the plugin.
*
* @returns The name of the plugin.
*/
std::string get_name() const override;

/**
* @brief Get the version of the plugin.
*
* @returns The version of the plugin.
*/
std::string get_version() const override;

/**
* @brief Get a short description of the plugin.
*
* @returns The short description of the plugin.
*/
std::string get_description() const override;

/**
* @brief Get the plugin dependencies.
*
* @returns A set of plugin names that this plugin depends on.
*/
std::set<std::string> get_dependencies() const override;
};
} // namespace hal
151 changes: 151 additions & 0 deletions plugins/resynthesis/include/resynthesis/resynthesis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@

// MIT License
//
// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved.
// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved.
// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved.
// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

/**
* @file resynthesis.h
* @brief This file contains functions to decompose or re-synthesize combinational parts of a gate-level netlist.
*/

#pragma once

#include "hal_core/defines.h"
#include "hal_core/utilities/result.h"

namespace hal
{
class Netlist;
class Gate;
class GateType;
class GateLibrary;

namespace resynthesis
{
/**
* Decompose a combinational gate into a small circuit of AND, OR, XOR, and INVERT gates.
* For each output pin, the resolved Boolean function (only dependent on input pins) is determined.
* All these Boolean functions are then converted into a netlist using the previously mentioned primitive gates.
* The target gate is then replaced in the original netlist with the circuit that was just generated.
* The target gate is only deleted if `delete_gate` is set to `true`.
* Gate replacement will fail if the gate library of the netlist does not contain suitable AND, OR, XOR, and INVERT gate types.
*
* @param[in] nl - The netlist to operate on.
* @param[in] gate - The gate to decompose.
* @param[in] delete_gate - Set `true` to delete the original gate, `false` to keep it in the netlist. Defaults to `true`.
* @return OK() on success, an error otherwise.
*/
Result<std::monostate> decompose_gate(Netlist* nl, Gate* gate, const bool delete_gate = true);

/**
* Decompose all combinational gates of the specified types into small circuits of AND, OR, XOR, and INVERT gates.
* For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
* All these Boolean functions are then converted into a circuit using the previously mentioned primitive gates.
* The target gates are then replaced (and thereby deleted) in the original netlist with the circuit that was just generated.
* Gate replacement will fail if the gate library of the netlist does not contain suitable AND, OR, XOR, and INVERT gate types.
*
* @param[in] nl - The netlist to operate on.
* @param[in] gate_types - The gate types to be decomposed.
* @return OK() and the number of decomposed gates on success, an error otherwise.
*/
Result<u32> decompose_gates_of_type(Netlist* nl, const std::vector<const GateType*>& gate_types);

/**
* Re-synthesize a combinational gate by calling Yosys on a functional description of the gate using a reduced gate library.
* For each output pin, the resolved Boolean function (only dependent on input pins) is determined.
* All these Boolean functions are then written to an HDL file that is functionally equivalent to the target gate.
* This file is fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
* The provided gate library should be a subset of the gate library that was used to parse the netlist.
* The target gate is then replaced in the original netlist with the circuit that was just generated.
* The target gate is only deleted if `delete_gate` is set to `true`.
*
* @param[in] nl - The netlist to operate on.
* @param[in] gate - The gate to re-synthesize.
* @param[in] target_gl - The gate library that is a subset of the gate library used to parse the netlist.
* @param[in] delete_gate - Set `true` to delete the original gate, `false` to keep it in the netlist. Defaults to `true`.
* @return OK() on success, an error otherwise.
*/
Result<std::monostate> resynthesize_gate(Netlist* nl, Gate* gate, GateLibrary* target_gl, const bool delete_gate = true);

/**
* Re-synthesize all specified combinational gates by calling Yosys on a functional description of the gates using a reduced gate library.
* For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
* All Boolean functions of a gate are then written to an HDL file that is functionally equivalent to the gate.
* These files are fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
* The provided gate library should be a subset of the gate library that was used to parse the netlist.
* The gates are then replaced in the original netlist with the circuits that were just generated.
* This process is repeated for every gate, hence they are re-synthesized in isolation.
*
* @param[in] nl - The netlist to operate on.
* @param[in] gates - The gates to re-synthesize.
* @param[in] target_gl - The gate library that is a subset of the gate library used to parse the netlist.
* @return OK() and the number of re-synthesized gates on success, an error otherwise.
*/
Result<u32> resynthesize_gates(Netlist* nl, const std::vector<Gate*>& gates, GateLibrary* target_gl);

/**
* Re-synthesize all combinational gates of the specified types by calling Yosys on a functional description of the gates using a reduced gate library.
* For all output pins of each gate, the resolved Boolean function (only dependent on input pins) is determined.
* All Boolean functions of a gate are then written to an HDL file that is functionally equivalent to the gate.
* These files are fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
* The provided gate library should be a subset of the gate library that was used to parse the netlist.
* The gates are then replaced in the original netlist with the circuits that were just generated.
* This process is repeated for every gate, hence they are re-synthesized in isolation.
*
* @param[in] nl - The netlist to operate on.
* @param[in] gate_types - The gate types to be re-synthesized.
* @param[in] target_gl - The gate library that is a subset of the gate library used to parse the netlist.
* @return OK() and the number of re-synthesized gates on success, an error otherwise.
*/
Result<u32> resynthesize_gates_of_type(Netlist* nl, const std::vector<const GateType*>& gate_types, GateLibrary* target_gl);

// TODO update docs below

/**
* Re-synthesize the combinational gates of the subgraph by calling Yosys on a Verilog netlist representation of the subgraph using a reduced gate library.
* All gates of the subgraph are written to a Verilog netlist file which is then fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
* The provided gate library should be a subset of the gate library that was used to parse the netlist.
* The gates are then replaced in the original netlist with the circuit that was just generated.
*
* @param[in] nl - The netlist to operate on.
* @param[in] subgraph - The subgraph to re-synthesize.
* @param[in] target_gl - The gate library that is a subset of the gate library used to parse the netlist.
* @return OK() and the number of re-synthesized gates on success, an error otherwise.
*/
Result<u32> resynthesize_subgraph(Netlist* nl, const std::vector<Gate*>& subgraph, GateLibrary* target_gl);

/**
* Re-synthesize the combinational gates of the specified types as a subgraph by calling Yosys on a Verilog netlist representation of the subgraph induced by these gates using a reduced gate library.
* All gates of the subgraph are written to a Verilog netlist file which is then fed to Yosys and subsequently synthesized to a netlist again by using the provided gate library.
* The provided gate library should be a subset of the gate library that was used to parse the netlist.
* The gates are then replaced in the original netlist with the circuit that was just generated.
*
* @param[in] nl - The netlist to operate on.
* @param[in] gate_types - The gate types to be re-synthesized.
* @param[in] target_gl - The gate library that is a subset of the gate library used to parse the netlist.
* @return OK() and the number of re-synthesized gates on success, an error otherwise.
*/
Result<u32> resynthesize_subgraph_of_type(Netlist* nl, const std::vector<const GateType*>& gate_types, GateLibrary* target_gl);
} // namespace resynthesis
} // namespace hal
Loading

0 comments on commit 7575227

Please sign in to comment.