Skip to content

Commit

Permalink
updated readme, fixed gui log not showing multiple spaces, added pyth…
Browse files Browse the repository at this point in the history
…on bindings for quine mccluskey plugin
  • Loading branch information
not-a-trojan committed May 6, 2019
1 parent 03235ac commit 4c26368
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 58 deletions.
82 changes: 73 additions & 9 deletions README.md
Expand Up @@ -4,22 +4,86 @@

[HAL](http://eprint.iacr.org/2017/783) [/hel/] is a comprehensive reverse engineering and manipulation framework for gate-level netlists focusing on efficiency, extendability and portability. HAL comes with a fully-fledged plugin system, allowing to introduce arbitrary functionalities to the core.

## Features

HAL transforms a netlist from VHDL or Verilog format into a graph representation and vice versa. HAL provides...
![alt text](https://github.com/emsec/hal/hal_screenshot.png "HAL Screenshot")

- Natural graphical representation of netlist elements and their connections
## Features
- Natural directed graph representation of netlist elements and their connections
- Support for custom gate libraries
- Superior performance thanks to our optimized C++ graph library
- High performance thanks to optimized C++ core
- Modularity: write your own C++ Plugins for efficient netlist analysis and manipulation (e.g. via graph algorithms)
- A feature-rich GUI allowing for visual netlist inspection and interactive analysis
- An integrated Python shell to exploratively interact with netlist elements and to interface plugins from the GUI

## Citation
## API Documentation

The C++ documentation is available [here](https://doc.hal.emsec.rub.de/).
The Python documentation can be found [here](https://py-doc.hal.emsec.rub.de/).

## Quick Start

Install or build HAL and start the GUI via `hal -g`. You can list all available options via `hal [--help|-h]`.
We included some example netlists in `examples` together with the implementation of the respective example gate library in `plugins/example_gate_library`.
For instructions to create your own gate library and other useful tutorials, take a look at the [wiki](https://github.com/emsec/hal/wiki).

Load a library from the `examples` directory and start exploring the graphical representation.
Use the integrated Python shell or the Python script window to interact. Both feature (limited) autocomplete functionality.

Let's list all lookup tables and print their Boolean functions:
```python
from hal_plugins import libquine_mccluskey

qm_plugin = libquine_mccluskey.quine_mccluskey()

for gate in netlist.get_gates():
if "LUT" in gate.type:
print(gate.name + " (id "+str(gate.id) + ", type " + gate.type + ")")
print(" " + str(len(gate.input_pin_types)) + "-to-" + str(len(gate.output_pin_types)) + " LUT")
boolean_functions = qm_plugin.get_boolean_function_str(gate, False)
for pin in boolean_functions:
print(" " + pin + ": "+boolean_functions[pin])
print("")
```
For the example netlist `fsm.vhd` this prints:
```
FSM_sequential_STATE_REG_1_i_2_inst (id 5, type LUT6)
6-to-1 LUT
O: (~I0 I1 ~I2 I3 I4 ~I5) + (I0 ~I2 I3 I4 I5)
FSM_sequential_STATE_REG_0_i_2_inst (id 3, type LUT6)
6-to-1 LUT
O: (I2 I3 I4 ~I5) + (I1 I2) + (I0 I1) + (I1 ~I3) + (I1 ~I4) + (I1 ~I5)
If you use HAL, please cite the original [paper](http://eprint.iacr.org/2017/783) using the reference below:
FSM_sequential_STATE_REG_0_i_3_inst (id 4, type LUT6)
6-to-1 LUT
O: (~I1 ~I2 I3 ~I4 I5) + (I0 I5) + (I0 I4) + (I0 I3) + (I0 I1) + (I0 ~I2)
OUTPUT_BUF_0_inst_i_1_inst (id 18, type LUT1)
1-to-1 LUT
O: (~I0)
OUTPUT_BUF_1_inst_i_1_inst (id 20, type LUT2)
2-to-1 LUT
O: (~I0 I1) + (I0 ~I1)
FSM_sequential_STATE_REG_1_i_3_inst (id 6, type LUT6)
6-to-1 LUT
O: (I0 I2 I4) + (~I1 I2 I4) + (I0 ~I3 I4) + (~I1 ~I3 I4) + (I0 I4 ~I5) + (~I1 I4 ~I5) + (I2 I5) + (I2 I3) + (I1 I5) + (I1 I3) + (I0 I1) + (~I0 I5) + (~I0 I3) + (~I0 ~I1) + (I1 ~I2) + (~I0 ~I2) + (~I3 I5) + (~I2 ~I3) + (~I4 I5) + (I3 ~I4) + (I1 ~I4)
```

## Citation

If you use HAL in an academic context, please cite the framework using the reference below:
```latex
@misc{hal,
author = {Marc Fyrbiak and Sebastian Wallat and Max Hoffmann},
title = {{HAL - The Hardware Analyzer}},
year = {2019},
howpublished = {\url{https://github.com/emsec/hal}},
}
```

Feel free to also include the original [paper](http://eprint.iacr.org/2017/783)
```latex
@article{2018:Fyrbiak:HAL,
author = {Marc Fyrbiak and
Sebastian Wallat and
Expand Down Expand Up @@ -47,11 +111,11 @@ Please contact us via Gitter: https://gitter.im/emsec-hal

### Ubuntu

We plan to publish releases via it's own ppa. You will be able to find it here: [ppa:sebastian-wallat/hal](https://launchpad.net/~sebastian-wallat/+archive/ubuntu/hal)
HAL releases are available via it's own ppa. You can find it here: [ppa:sebastian-wallat/hal](https://launchpad.net/~sebastian-wallat/+archive/ubuntu/hal)

### macOS

We plan to provide a [homebrew](https://brew.sh/index_de) tap.
A [homebrew](https://brew.sh/index_de) tap is coming soon...

## Build Instructions

Expand Down
Binary file added hal_screenshot.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions include/gui/welcome_screen/get_in_touch_widget.h
Expand Up @@ -42,7 +42,8 @@ class get_in_touch_widget : public QFrame

public Q_SLOTS:
void handle_about_item_clicked();
void handle_documentation_item_clicked();
void handle_cpp_documentation_item_clicked();
void handle_py_documentation_item_clicked();
void handle_ticket_item_clicked();

private:
Expand All @@ -51,7 +52,8 @@ public Q_SLOTS:
get_in_touch_item* m_about_item;
get_in_touch_item* m_news_item;
get_in_touch_item* m_forum_item;
get_in_touch_item* m_documentation_item;
get_in_touch_item* m_cpp_documentation_item;
get_in_touch_item* m_py_documentation_item;
get_in_touch_item* m_ticket_item;

// QFrame* m_line;
Expand Down
6 changes: 2 additions & 4 deletions plugins/graph_algorithm/CMakeLists.txt
@@ -1,18 +1,16 @@
option(PL_GRAPH_ALGORITHM "PL_GRAPH_ALGORITHM" ON)
if(PL_GRAPH_ALGORITHM OR BUILD_ALL_PLUGINS)
include_directories(${BUDDY_INCLUDE_DIR})
include_directories(SYSTEM ${PYBIND11_INCLUDE_DIR}
SYSTEM ${PYTHON_INCLUDE_DIRS})
include_directories(AFTER "${CMAKE_CURRENT_SOURCE_DIR}/include")
include_directories(SYSTEM ${PYBIND11_INCLUDE_DIR} SYSTEM ${PYTHON_INCLUDE_DIRS})
include_directories(AFTER "${CMAKE_CURRENT_SOURCE_DIR}/include")

file(GLOB_RECURSE GRAPH_ALGORITHM_INC ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
file(GLOB_RECURSE GRAPH_ALGORITHM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE PYTHON_BINDING_LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/python/python_definitions.cpp)

add_library(graph_algorithm SHARED ${GRAPH_ALGORITHM_SRC} ${PYTHON_BINDING_LIB_SRC} ${GRAPH_ALGORITHM_INC})

#Set shared library suffix for MacOS; Used for boost_python support
#Set shared library suffix for MacOS
if(APPLE AND CMAKE_HOST_APPLE)
set_target_properties(graph_algorithm PROPERTIES SUFFIX ".so")
endif(APPLE AND CMAKE_HOST_APPLE)
Expand Down
22 changes: 11 additions & 11 deletions plugins/quine_mccluskey/CMakeLists.txt
@@ -1,20 +1,20 @@
option(PL_QUINE_MCCLUSKEY "PL_QUINE_MCCLUSKEY" OFF)
if(PL_QUINE_MCCLUSKEY OR BUILD_ALL_PLUGINS)
include_directories(${BUDDY_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(SYSTEM ${PYBIND11_INCLUDE_DIR} SYSTEM ${PYTHON_INCLUDE_DIRS})

set(QUINE_MCCLUSKEY_INC
${CMAKE_CURRENT_SOURCE_DIR}/include/factory_quine_mccluskey.h
${CMAKE_CURRENT_SOURCE_DIR}/include/plugin_quine_mccluskey.h
)

set(QUINE_MCCLUSKEY_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/factory_quine_mccluskey.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/plugin_quine_mccluskey.cpp
)
file(GLOB_RECURSE QUINE_MCCLUSKEY_INC ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
file(GLOB_RECURSE QUINE_MCCLUSKEY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
file(GLOB_RECURSE PYTHON_BINDING_LIB_SRC ${CMAKE_CURRENT_SOURCE_DIR}/python/python_definitions.cpp)

add_library(quine_mccluskey SHARED ${QUINE_MCCLUSKEY_SRC} ${QUINE_MCCLUSKEY_INC})
set_target_properties(quine_mccluskey PROPERTIES DEFINE_SYMBOL PLUGIN)
target_link_libraries(quine_mccluskey ${LINK_LIBS})
add_library(quine_mccluskey SHARED ${QUINE_MCCLUSKEY_SRC} ${PYTHON_BINDING_LIB_SRC} ${QUINE_MCCLUSKEY_INC})

#Set shared library suffix for MacOS
if(APPLE AND CMAKE_HOST_APPLE)
set_target_properties(graph_algorithm PROPERTIES SUFFIX ".so")
endif(APPLE AND CMAKE_HOST_APPLE)
target_link_libraries(quine_mccluskey ${LINK_LIBS} ${PYTHON_LIBRARIES} pybind11::pybind11 ${BUDDY_LIBRARY})
install(TARGETS quine_mccluskey LIBRARY DESTINATION ${PLUGIN_LIBRARY_INSTALL_DIRECTORY} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE INCLUDES DESTINATION ${PLUGIN_INCLUDE_INSTALL_DIRECTORY})
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${PLUGIN_INCLUDE_INSTALL_DIRECTORY}/quine_mccluskey/)
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
Expand Down
26 changes: 12 additions & 14 deletions plugins/quine_mccluskey/include/plugin_quine_mccluskey.h
Expand Up @@ -17,10 +17,10 @@ class gate;
/**
* Struct to store simplified Boolean function
* function - stores encoded Boolean function as string of bytes (size = num_of_clauses * num_of_literals)
* function[x] = 0 means literal is false in clause
* function[x] = 0 means literal is false in clause
* function[x] = 1 means literal is true in clause
* function[x] = -1 means literal is not relevant in clause
* num_of_clauses - stores number of clauses
* num_of_clauses - stores number of clauses
* num_of_literals - stores number of literals (= different variables)
*/
struct boolean_function_t
Expand Down Expand Up @@ -51,17 +51,17 @@ class plugin_quine_mccluskey : virtual public i_base
* plugin specific functions
*/

/**
* Returns simplified Boolean function
*
/**
* Returns simplified Boolean function
*
* @param[in] table - Boolean function as std::vector<u8> (table[0] refers to input for all zero input)
* @return Tuple of simplified table as Boolean vector, number of clauses, and number of literals
*/
boolean_function_t get_boolean_function(const std::vector<bool>& table);

/**
/**
* Returns Boolean logic function string for given table
*
*
* @param[in] bf - Boolean function struct
* @return Boolean function as string.
*/
Expand All @@ -70,20 +70,16 @@ class plugin_quine_mccluskey : virtual public i_base
/**
* Returns Boolean logic function string for each output pin for given gate.
*
* @param[in] g - Gate
* @param[in] gui - Switch to enable/disable richtext and CSS in Boolean function string (default = false)
* @param[in] g - Gate
* @param[in] css_beautified - Switch to enable/disable richtext and CSS in Boolean function string (default = false)
* @returns Boolean function as string for each output pin.
*/
std::map<std::string, std::string> get_boolean_function_str(std::shared_ptr<gate> const g, const bool gui = false);
std::map<std::string, std::string> get_boolean_function_str(std::shared_ptr<gate> const g, bool css_beautified = false);

// TODO: declare private later
/** returns true if the formula of the function table can be computed */
bool simplify(const bool* table, u32 num_of_literals, u8** formula, u32* num_of_clauses);

// TODO: declare private later
/** returns the string of the computed formula */
std::string formula_to_string(u8* formula, u32 num_of_clauses, u32 num_of_literals);

private:
int minterm[PLUGIN_QUINE_MCCLUSKEY_MAX][PLUGIN_QUINE_MCCLUSKEY_MAX];

Expand All @@ -95,6 +91,8 @@ class plugin_quine_mccluskey : virtual public i_base
int wprim[PLUGIN_QUINE_MCCLUSKEY_MAX]; // essential prime implicant (true/false)
int nwprim[PLUGIN_QUINE_MCCLUSKEY_MAX]; // needed not essential prime implicant


std::string formula_to_string(u8* formula, u32 num_of_clauses, u32 num_of_literals);
void clear_member_variables();

std::map<std::string, std::string> get_boolean_function_str_bdd(std::shared_ptr<gate> const g);
Expand Down
64 changes: 64 additions & 0 deletions plugins/quine_mccluskey/python/python_definitions.cpp
@@ -0,0 +1,64 @@
#include "core/log.h"
#include "core/utils.h"
#include "netlist/gate.h"
#include "netlist/net.h"
#include "netlist/netlist.h"
#include "pybind11/operators.h"
#include "pybind11/pybind11.h"
#include "pybind11/stl.h"
#include "pybind11/stl_bind.h"
#include "def.h"
#include "plugin_quine_mccluskey.h"

namespace py = pybind11;

#ifdef PYBIND11_MODULE
PYBIND11_MODULE(libquine_mccluskey, m)
{
m.doc() = "hal libquine_mccluskey python bindings";
#else
PYBIND11_PLUGIN(libquine_mccluskey)
{
py::module m("libquine_mccluskey", "hal quine mccluskey python bindings");
#endif // ifdef PYBIND11_MODULE

py::class_<boolean_function_t>(m, "boolean_function_t")
.def_readwrite("function", &boolean_function_t::function)
.def_readwrite("num_of_clauses", &boolean_function_t::num_of_clauses)
.def_readwrite("num_of_literals", &boolean_function_t::num_of_literals)
;

py::class_<plugin_quine_mccluskey, std::shared_ptr<plugin_quine_mccluskey>>(m, "quine_mccluskey")
.def(py::init<>())
.def_property_readonly("name", &plugin_quine_mccluskey::get_name, R"(
Get the name of the plugin.
:returns: Plugin name.
:rtype: str
)")
.def("get_name", &plugin_quine_mccluskey::get_name, R"(
Get the name of the plugin.
:returns: Plugin name.
:rtype: str
)")
.def_property_readonly("version", &plugin_quine_mccluskey::get_version, R"(
Get the version of the plugin.
:returns: Plugin version.
:rtype: str
)")
.def("get_version", &plugin_quine_mccluskey::get_version, R"(
Get the version of the plugin.
:returns: Plugin version.
:rtype: str
)")
.def("get_boolean_function", py::overload_cast<const std::vector<bool>&>(&plugin_quine_mccluskey::get_boolean_function))
.def("get_boolean_function_str", py::overload_cast<std::shared_ptr<gate> const, bool>(&plugin_quine_mccluskey::get_boolean_function_str), py::arg("gate"), py::arg("css_beautified") = false)
;

#ifndef PYBIND11_MODULE
return m.ptr();
#endif // PYBIND11_MODULE
}
7 changes: 4 additions & 3 deletions plugins/quine_mccluskey/src/plugin_quine_mccluskey.cpp
Expand Up @@ -421,7 +421,7 @@ std::string plugin_quine_mccluskey::get_boolean_function_str(const boolean_funct
return str;
}

std::map<std::string, std::string> plugin_quine_mccluskey::get_boolean_function_str(std::shared_ptr<gate> const g, const bool gui)
std::map<std::string, std::string> plugin_quine_mccluskey::get_boolean_function_str(std::shared_ptr<gate> const g, bool css_beautified)
{
if (g == nullptr)
{
Expand All @@ -440,13 +440,14 @@ std::map<std::string, std::string> plugin_quine_mccluskey::get_boolean_function_
// replace pin names
int variable_cnt = 0;
for (const auto& pin : g->get_input_pin_types())
str = core_utils::replace(str, "A" + std::to_string(variable_cnt++), pin);
str = core_utils::replace(str, "A" + std::to_string(variable_cnt++), pin + " ");

// add brackets
str = "(" + str + ")";
str = core_utils::replace(str, " + ", ") + (");
str = core_utils::replace(str, " )", ")");

if (gui)
if (css_beautified)
{
// replace commas with AND and OR symbols
for (const auto& pin : g->get_input_pin_types())
Expand Down
8 changes: 5 additions & 3 deletions src/gui/hal_logger/hal_logger_marshall.cpp
Expand Up @@ -24,6 +24,8 @@ void hal_logger_marshall::append_log(spdlog::level::level_enum t, const QString&
static const QString intermediateHTML = "\">";
static const QString endHTML = "</font></p>";

QString html_ready_msg = msg.toHtmlEscaped().replace(" ", "&nbsp;");

QString color;

switch (t)
Expand Down Expand Up @@ -52,7 +54,7 @@ void hal_logger_marshall::append_log(spdlog::level::level_enum t, const QString&
}
QString msg_to_print;
if (!filter)
msg_to_print = beginHTML + color + intermediateHTML + msg.toHtmlEscaped() + endHTML;
msg_to_print = beginHTML + color + intermediateHTML + html_ready_msg + endHTML;
else
{
hal_filter_item::rule rule;
Expand Down Expand Up @@ -119,12 +121,12 @@ void hal_logger_marshall::append_log(spdlog::level::level_enum t, const QString&
color = logger_qss_adapter::instance()->default_highlight().name();
break;
}
msg_to_print = beginHTML + color + intermediateHTML + msg.toHtmlEscaped() + endHTML;
msg_to_print = beginHTML + color + intermediateHTML + html_ready_msg + endHTML;
}
else
{
if (rule == hal_filter_item::rule::ShowAll)
msg_to_print = beginHTML + color + intermediateHTML + msg.toHtmlEscaped() + endHTML;
msg_to_print = beginHTML + color + intermediateHTML + html_ready_msg + endHTML;
else
return;
}
Expand Down

0 comments on commit 4c26368

Please sign in to comment.