Skip to content

Commit

Permalink
Merge branch 'master' into feature/simulation-wizard
Browse files Browse the repository at this point in the history
  • Loading branch information
joern274 authored Jun 27, 2024
2 parents ed28db5 + 60ea67a commit d379840
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 37 deletions.
31 changes: 16 additions & 15 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,23 @@ All notable changes to this project will be documented in this file.
* changed `xilinx_toolbox` plugin
* added `split_shift_registers` function to split `SRL16E` gates into multiple flip-flops
* changed Python bindings for better usability
* netlist
* module pins
* added qualifier for `pin_changed` core events telling receiver details about the recent modification
* added event scope and stacking classes so that `pin_changed` events can be collected and prioritized
* added specific GUI handler for every `pin_changed` event thus replacing the reload-entire-pingroup-tree policy
* core
* pin (groups)
* added optional flag to determine whether a pin group has an inherent order (defaults to `false`)
* added `GateType::delete_pin_group` and `GateType::assign_pin_to_group` to enable more operations on pin groups of gate pins
* added parameter `force_name` to enforce pin (group) renaming to `Module::set_pin_name`, `Module::set_pin_group_name`, `Module::create_pin`, and `Module::create_pin_group`
* added pin types `status`, `error`, `error_detection`, `done`, and `control`
* added qualifier for module `pin_changed` core events telling receiver details about the recent modification
* added event scope and stacking classes so that module `pin_changed` events can be collected and prioritized
* added specific GUI handler for every module `pin_changed` event thus replacing the reload-entire-pingroup-tree policy
* added class `ActionPingroup` so that UNDO function works for all pin / pin group actions issued from GUI
* decorators
* added `NetlistTraversalDecorator` to ease exploration of a netlist
* added `get_next_matching_gates` to get successor/predecessor gates matching a certain condition
* added `get_next_matching_gates_until` to get successor/predecessor gates until a certain condition is fulfilled
* added `get_next_matching_gates_until_depth` to get successor/predecessor gates up to a certain depth
* added `get_next_sequential_gates` and `get_next_sequential_gates_map` to get the next layer of sequential successors/predecessors
* added `get_next_combinational_gates` to get all combinational gates until the next non-combinational gates are reached
* decorators
* added `NetlistTraversalDecorator` to ease exploration of a netlist
* added `get_next_matching_gates` to get successor/predecessor gates matching a certain condition
* added `get_next_matching_gates_until` to get successor/predecessor gates until a certain condition is fulfilled
* added `get_next_matching_gates_until_depth` to get successor/predecessor gates up to a certain depth
* added `get_next_sequential_gates` and `get_next_sequential_gates_map` to get the next layer of sequential successors/predecessors
* added `get_next_combinational_gates` to get all combinational gates until the next non-combinational gates are reached
* miscellaneous
* added support for Ubuntu 24.04 LTS
* added INIT field declaration to FF-gate-types in example library
Expand All @@ -66,12 +70,9 @@ All notable changes to this project will be documented in this file.
* added GUI PluginParameter types `Module` and `Gated` for parameters that can be requested from plugin
* added `Show content` button to `Groupings` widget to show content of grouping as a list
* added flag which Python editor tab is active when serializing project
* added `GateType::delete_pin_group` and `GateType::assign_pin_to_group` to enable more operations on pin groups of gate pins
* added extended gate library picker when importing a netlist
* added keyboard shortcut for delete-item action from toolbar
* added parameter `force_name` to enforce pin (group) renaming to `Module::set_pin_name`, `Module::set_pin_group_name`, `Module::create_pin`, and `Module::create_pin_group`
* added gate type properties `fifo` and `shift_register`
* added pin types `status`, `error`, `error_detection`, `done`, and `control`
* added optional filter to `Net::get_num_of_sources` and `Net::get_num_of_destinations`
* added function `unify_ff_outputs` to netlist preprocessing plugin
* added function `replace_gate_type` to gate library
Expand Down
43 changes: 32 additions & 11 deletions include/hal_core/netlist/pins/pin_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
#pragma once

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

#include <list>
#include <string>
Expand Down Expand Up @@ -57,9 +57,10 @@ namespace hal
* @param[in] type - The type of the pin group.
* @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] start_index - The start index of the pin group. Defaults to `0`.
* @param[in] ordered - Set `true` if the pin group features an inherent order, `false` otherwise. Defaults to `false`.
*/
PinGroup(const u32 id, const std::string& name, PinDirection direction, PinType type, bool ascending = true, u32 start_index = 0)
: m_id(id), m_name(name), m_direction(direction), m_type(type), m_ascending(ascending), m_start_index(start_index), m_next_index(start_index)
PinGroup(const u32 id, const std::string& name, PinDirection direction, PinType type, bool ascending = true, u32 start_index = 0, bool ordered = false)
: m_id(id), m_name(name), m_direction(direction), m_type(type), m_ascending(ascending), m_start_index(start_index), m_next_index(start_index), m_ordered(ordered)
{
}

Expand All @@ -74,7 +75,7 @@ namespace hal
bool operator==(const PinGroup<T>& other) const
{
if (m_id != other.get_id() || m_name != other.get_name() || m_direction != other.get_direction() || m_type != other.get_type() || m_start_index != other.get_start_index()
|| m_ascending != other.is_ascending())
|| m_ascending != other.is_ascending() || m_ordered != other.is_ordered())
{
return false;
}
Expand Down Expand Up @@ -270,7 +271,7 @@ namespace hal
/**
* Check whether the pin order of a pin group comprising n pins is ascending (from 0 to n-1) or descending (from n-1 to 0).
*
* @returns True for ascending bit order, false otherwise.
* @returns `true` for ascending bit order, `false` otherwise.
*/
bool is_ascending() const
{
Expand All @@ -289,6 +290,26 @@ namespace hal
return m_start_index;
}

/**
* Check whether the pin group features an inherent order.
*
* @returns `true` if the pin group is inherently ordered, `false` otherwise.
*/
bool is_ordered() const
{
return m_ordered;
}

/**
* Set whether the pin group features an inherent order.
*
* @param[in] ordered - Set `true` if the pin group is inherently ordered, `false` otherwise. Defaults to `true`.
*/
void set_ordered(bool ordered = true)
{
m_ordered = ordered;
}

/**
* Check whether the pin group is empty, i.e., contains no pins.
*
Expand Down Expand Up @@ -319,8 +340,7 @@ namespace hal
{
if (pin == nullptr)
{
log_warning("pin_group", "'nullptr' given instead of a pin when trying to assign a pin to pin group '{}' with ID {}",
m_name, m_id);
log_warning("pin_group", "'nullptr' given instead of a pin when trying to assign a pin to pin group '{}' with ID {}", m_name, m_id);
return false;
}

Expand All @@ -336,7 +356,7 @@ namespace hal
{
// special case empty pin group
index = m_start_index;
-- m_next_index;
--m_next_index;
}
else
{
Expand Down Expand Up @@ -456,22 +476,22 @@ namespace hal
}
else
{
if (m_pins.size()==1)
if (m_pins.size() == 1)
{
m_pins.clear();
m_next_index++;
}
else
{
auto it = m_pins.begin();
for (int i=m_start_index; i>index;i--)
for (int i = m_start_index; i > index; i--)
{
std::get<1>((*(it++))->m_group)--;
}
m_pins.erase(it);
--m_start_index;
}
}
}

return true;
}
Expand Down Expand Up @@ -506,6 +526,7 @@ namespace hal
bool m_ascending;
i32 m_start_index;
i32 m_next_index;
bool m_ordered;

PinGroup(const PinGroup&) = delete;
PinGroup(PinGroup&&) = delete;
Expand Down
2 changes: 1 addition & 1 deletion plugins/hgl_parser/include/hgl_parser/hgl_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace hal
Result<std::unique_ptr<GateLibrary>> parse(const std::filesystem::path& file_path) override;

private:
const u32 HGL_FORMAT_VERSION = 3;
const u32 HGL_FORMAT_VERSION = 4;
u32 file_version = 1;

struct PinCtx
Expand Down
8 changes: 7 additions & 1 deletion plugins/hgl_parser/src/hgl_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ namespace hal
}
bool ascending = pg_val["ascending"].GetBool();

bool ordered = false;
if (pg_val.HasMember("ordered") && pg_val["ordered"].IsBool())
{
ordered = pg_val["ordered"].GetBool();
}

if (!pg_val.HasMember("start_index") || !pg_val["start_index"].IsUint())
{
return ERR("could not parse pin group '" + pg_name + "': missing or start index");
Expand Down Expand Up @@ -354,7 +360,7 @@ namespace hal
}
}

auto pg_res = gt->create_pin_group(pg_name, pins, pg_direction, pg_type, ascending, start_index);
auto pg_res = gt->create_pin_group(pg_name, pins, pg_direction, pg_type, ascending, start_index, ordered);
if (pg_res.is_error())
{
return ERR_APPEND(pg_res.get_error(),
Expand Down
2 changes: 1 addition & 1 deletion plugins/hgl_writer/include/hgl_writer/hgl_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace hal
bool write(const GateLibrary* gate_lib, const std::filesystem::path& file_path) override;

private:
const u32 HGL_FORMAT_VERSION = 3;
const u32 HGL_FORMAT_VERSION = 4;

struct PinCtx
{
Expand Down
1 change: 1 addition & 0 deletions plugins/hgl_writer/src/hgl_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ namespace hal
pg_val.AddMember("type", enum_to_string(group->get_type()), allocator);
pg_val.AddMember("ascending", group->is_ascending(), allocator);
pg_val.AddMember("start_index", group->get_start_index(), allocator);
pg_val.AddMember("ordered", group->is_ordered(), allocator);

// pins of group
rapidjson::Value p_array(rapidjson::kArrayType);
Expand Down
14 changes: 12 additions & 2 deletions src/netlist/persistent/netlist_serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace hal
// serializing functions
namespace
{
const int SERIALIZATION_FORMAT_VERSION = 13;
const int SERIALIZATION_FORMAT_VERSION = 14;
int encoded_format_version;

// Ver 12 : location of gates
Expand Down Expand Up @@ -66,6 +66,7 @@ namespace hal
std::vector<PinInformation> pins;
bool ascending = false;
u32 start_index = 0;
bool ordered = false;
};

} // namespace
Expand Down Expand Up @@ -443,6 +444,7 @@ namespace hal
json_pin_group.AddMember("direction", enum_to_string(pin_group->get_direction()), allocator);
json_pin_group.AddMember("type", enum_to_string(pin_group->get_type()), allocator);
json_pin_group.AddMember("ascending", pin_group->is_ascending(), allocator);
json_pin_group.AddMember("ordered", pin_group->is_ordered(), allocator);
json_pin_group.AddMember("start_index", pin_group->get_start_index(), allocator);
rapidjson::Value json_pins(rapidjson::kArrayType);
for (const ModulePin* pin : pin_group->get_pins())
Expand Down Expand Up @@ -544,6 +546,14 @@ namespace hal
{
pin_group.type = PinType::none;
}
if (json_pin_group.HasMember("ordered"))
{
pin_group.ordered = json_pin_group["ordered"].GetBool();
}
else
{
pin_group.type = PinType::none;
}
pin_group.ascending = json_pin_group["ascending"].GetBool();
pin_group.start_index = json_pin_group["start_index"].GetUint();

Expand Down Expand Up @@ -616,7 +626,7 @@ namespace hal
}
}
u32 pgid = (pg.id > 0) ? (u32)pg.id : sm->get_unique_pin_group_id();
if (auto res = sm->create_pin_group(pgid, pg.name, pins, pg.direction, pg.type, pg.ascending, pg.start_index); res.is_error())
if (auto res = sm->create_pin_group(pgid, pg.name, pins, pg.direction, pg.type, pg.ascending, pg.start_index, pg.ordered); res.is_error())
{
log_error("netlist_persistent",
"could not deserialize pin group '" + pg.name + "' of module '" + sm->get_name() + "' with ID " + std::to_string(sm->get_id())
Expand Down
20 changes: 16 additions & 4 deletions src/python_bindings/bindings/gate_pin_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ namespace hal
:rtype: hal_py.PinType
)");

py_gate_pin_group.def_property_readonly(
"pins", [](const PinGroup<GatePin>& self) -> std::vector<GatePin*> { return self.get_pins(nullptr); }, R"(
py_gate_pin_group.def_property_readonly("pins", [](const PinGroup<GatePin>& self) -> std::vector<GatePin*> { return self.get_pins(nullptr); }, R"(
The (ordered) pins of the pin groups.
:type: list[hal_py.GatePin]
Expand Down Expand Up @@ -152,15 +151,15 @@ namespace hal
)");

py_gate_pin_group.def_property_readonly("ascending", &PinGroup<GatePin>::is_ascending, R"(
True if the pin order of a pin group comprising n pins is ascending (from 0 to n-1), False if it is descending (from n-1 to 0).
``True`` if the pin order of a pin group comprising n pins is ascending (from 0 to n-1), ``False`` if it is descending (from n-1 to 0).
:type: bool
)");

py_gate_pin_group.def("is_ascending", &PinGroup<GatePin>::is_ascending, R"(
Check whether the pin order of a pin group comprising n pins is ascending (from 0 to n-1) or descending (from n-1 to 0).
:returns: True for ascending bit order, False otherwise.
:returns: ``True`` for ascending bit order, ``False`` otherwise.
:rtype: bool
)");

Expand All @@ -181,6 +180,19 @@ namespace hal
:rtype: int
)");

py_gate_pin_group.def_property_readonly("ordered", &PinGroup<GatePin>::is_ordered, R"(
``True`` if the pin group is inherently ordered, ``False`` otherwise.
:type: bool
)");

py_gate_pin_group.def("is_ordered", &PinGroup<GatePin>::is_ordered, R"(
Check whether the pin group features an inherent order.
:returns: ``True`` if the pin group is inherently ordered, ``False`` otherwise.
:rtype: bool
)");

py_gate_pin_group.def("empty", &PinGroup<GatePin>::empty, R"(
Check whether the pin group is empty, i.e., contains no pins.
Expand Down
22 changes: 20 additions & 2 deletions src/python_bindings/bindings/module_pin_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ namespace hal
:rtype: hal_py.PinType
)");

py_module_pin_group.def_property_readonly(
"pins", [](const PinGroup<ModulePin>& self) -> std::vector<ModulePin*> { return self.get_pins(nullptr); }, R"(
py_module_pin_group.def_property_readonly("pins", [](const PinGroup<ModulePin>& self) -> std::vector<ModulePin*> { return self.get_pins(nullptr); }, R"(
The (ordered) pins of the pin groups.
:type: list[hal_py.ModulePin]
Expand Down Expand Up @@ -181,6 +180,25 @@ namespace hal
:rtype: int
)");

py_module_pin_group.def_property_readonly("ordered", &PinGroup<ModulePin>::is_ordered, R"(
``True`` if the pin group is inherently ordered, ``False`` otherwise.
:type: bool
)");

py_module_pin_group.def("is_ordered", &PinGroup<ModulePin>::is_ordered, R"(
Check whether the pin group features an inherent order.
:returns: ``True`` if the pin group is inherently ordered, ``False`` otherwise.
:rtype: bool
)");

py_module_pin_group.def("set_ordered", &PinGroup<ModulePin>::set_ordered, py::arg("ordered") = true, R"(
Set whether the pin group features an inherent order.
:param bool ordered: Set ``True`` if the pin group is inherently ordered, ``False`` otherwise. Defaults to ``True``.
)");

py_module_pin_group.def("empty", &PinGroup<ModulePin>::empty, R"(
Check whether the pin group is empty, i.e., contains no pins.
Expand Down

0 comments on commit d379840

Please sign in to comment.