HAL  v4.5.0-83-g30c8f0afc
The Hardware Analyzer - a comprehensive reverse engineering and manipulation framework for gate-level netlists.
python_bindings.cpp
Go to the documentation of this file.
2 
5 #include "pybind11/operators.h"
6 #include "pybind11/pybind11.h"
7 #include "pybind11/stl.h"
8 #include "pybind11/stl_bind.h"
9 
10 namespace py = pybind11;
11 
12 namespace hal
13 {
14 #ifdef PYBIND11_MODULE
15  PYBIND11_MODULE(netlist_simulator, m)
16  {
17  m.doc() = "hal NetlistSimulatorPlugin python bindings";
18 #else
19  PYBIND11_PLUGIN(netlist_simulator)
20  {
21  py::module m("hal_simulator", "hal NetlistSimulatorPlugin python bindings");
22 #endif // ifdef PYBIND11_MODULE
23 
24  py::class_<NetlistSimulatorPlugin, RawPtrWrapper<NetlistSimulatorPlugin>, BasePluginInterface>(m, "NetlistSimulatorPlugin")
25  .def_property_readonly("name", &NetlistSimulatorPlugin::get_name, R"(
26  The name of the plugin.
27 
28  :type: str
29  )")
30 
31  .def("get_name", &NetlistSimulatorPlugin::get_name, R"(
32  Get the name of the plugin.
33 
34  :returns: The name of the plugin.
35  :rtype: str
36  )")
37 
38  .def_property_readonly("version", &NetlistSimulatorPlugin::get_version, R"(
39  The version of the plugin.
40 
41  :type: str
42  )")
43 
44  .def("get_version", &NetlistSimulatorPlugin::get_version, R"(
45  Get the version of the plugin.
46 
47  :returns: The version of the plugin.
48  :rtype: str
49  )");
50 
51  py::class_<NetlistSimulator>(m, "NetlistSimulator")
52  /*
53  .def("add_gates", &NetlistSimulator::add_gates, py::arg("gates"), R"(
54  Add gates to the simulation set.
55  Only elements in the simulation set are considered during simulation.
56 
57  :param list[hal_py.Gate] gates: The gates to add.
58  )")
59 
60  .def("add_clock_frequency", &NetlistSimulator::add_clock_frequency, py::arg("clock_net"), py::arg("frequency"), py::arg("start_at_zero") = true, R"(
61  Specify a net that carries the clock signal and set the clock frequency in hertz.
62 
63  :param hal_py.Net clock_net: The net that carries the clock signal.
64  :param int frequency: The clock frequency in hertz.
65  :param bool start_at_zero: Initial clock state is 0 if ``True``, 1 otherwise.
66  )")
67 
68  .def("add_clock_period", &NetlistSimulator::add_clock_period, py::arg("clock_net"), py::arg("period"), py::arg("start_at_zero") = true, R"(
69  Specify a net that carries the clock signal and set the clock period in picoseconds.
70 
71  :param hal_py.Net clock_net: The net that carries the clock signal.
72  :param int period: The clock period from rising edge to rising edge in picoseconds.
73  :param bool start_at_zero: Initial clock state is 0 if ``True``, 1 otherwise.
74  )")
75 
76  .def("get_gates", &NetlistSimulator::get_gates, R"(
77  Get all gates that are in the simulation set.
78 
79  :returns: The name.
80  :rtype: set[hal_py.Gate]
81  )")
82 
83  .def("get_input_nets", &NetlistSimulator::get_input_nets, R"(
84  Get all nets that are considered inputs, i.e., not driven by a gate in the simulation set or global inputs.
85 
86  :returns: The input nets.
87  :rtype: list[hal_py.Net]
88  )")
89 
90  .def("get_output_nets", &NetlistSimulator::get_output_nets, R"(
91  Get all output nets of gates in the simulation set that have a destination outside of the set or that are global outputs.
92 
93  :returns: The output nets.
94  :rtype: list[hal_py.Net]
95  )")
96 */
97  .def("set_input", &NetlistSimulator::set_input, py::arg("net"), py::arg("value"), R"(
98  Set the signal for a specific wire to control input signals between simulation cycles.
99 
100  :param hal_py.Net net: The net to set a signal value for.
101  :param hal_py.BooleanFunction.Value value: The value to set.
102  )")
103 
104  .def("initialize_sequential_gates", py::overload_cast<const std::function<bool(const Gate*)>&>(&NetlistSimulator::initialize_sequential_gates), py::arg("filter") = nullptr, R"(
105  Configure the sequential gates matching the (optional) user-defined filter condition with initialization data specified within the netlist.
106  Schedules the respective gates for initialization, the actual configuration is applied during initialization of the simulator.
107  This function can only be called before the simulation has started.
108 
109  :param lambda filter: The optional filter to be applied before initialization.
110  )")
111 
112  .def("initialize_sequential_gates",
113  py::overload_cast<BooleanFunction::Value, const std::function<bool(const Gate*)>&>(&NetlistSimulator::initialize_sequential_gates),
114  py::arg("value"),
115  py::arg("filter") = nullptr,
116  R"(
117  Configure the sequential gates matching the (optional) user-defined filter condition with the specified value.
118  Schedules the respective gates for initialization, the actual configuration is applied during initialization of the simulator.
119  This function can only be called before the simulation has started.
120 
121  :param hal_py.BooleanFunction.Value value: The value to initialize the selected gates with.
122  :param lambda filter: The optional filter to be applied before initialization.
123  )")
124 
125  .def("load_initial_values", &NetlistSimulator::load_initial_values, py::arg("value"), R"(
126  Load the specified initial value into the current state of all sequential elements.
127 
128  :param hal_py.BooleanFunction.Value value: The initial value to load.
129  )")
130 
131  .def("load_initial_values_from_netlist", &NetlistSimulator::load_initial_values_from_netlist, R"(
132  Load the initial value specified within the netlist file into the current state of all sequential elements.
133  This is especially relevant for FPGA netlists, since these may provide initial values to load on startup.
134  )")
135 
136  .def("initialize", &NetlistSimulator::initialize, R"(
137  Initialize the simulation.
138  No additional gates or clocks can be added after this point.
139  )")
140 
141  .def("simulate", &NetlistSimulator::simulate, py::arg("picoseconds"), R"(
142  Simulate for a specific period, advancing the internal state.
143  Automatically initializes the simulation if 'initialize' has not yet been called.
144  Use \p set_input to control specific signals.
145 
146  :param int picoseconds: The duration to simulate.
147  )")
148 
149  .def("reset", &NetlistSimulator::reset, R"(
150  Reset the simulator state, i.e., treat all signals as unknown.
151  Does not remove gates/nets from the simulation set.
152  )")
153 
154  .def("set_simulation_state", &NetlistSimulator::set_simulation_state, py::arg("state"), R"(
155  Set the simulator state, i.e., net signals, to a given state.
156  Does not influence gates/nets added to the simulation set.
157 
158  :param netlist_simulator.Simulation state: The state to apply.
159  )")
160 
161  .def("get_simulation_state", &NetlistSimulator::get_simulation_state, R"(
162  Get the current simulation state.
163 
164  :returns: The current simulation state.
165  :rtype: libnetlist_simulator.Simulation
166  )")
167 
168  .def("set_iteration_timeout", &NetlistSimulator::set_iteration_timeout, py::arg("iterations"), R"(
169  Set the iteration timeout, i.e., the maximum number of events processed for a single point in time.
170  Useful to abort in case of infinite loops.
171  A value of 0 disables the timeout.
172 
173  :param int iterations: The iteration timeout.
174  )")
175 
176  .def("get_simulation_timeout", &NetlistSimulator::get_simulation_timeout, R"(
177  Get the current iteration timeout value.
178 
179  :returns: The iteration timeout.
180  :rtype: int
181  )")
182 
183  .def("generate_vcd", &NetlistSimulator::generate_vcd, py::arg("path"), py::arg("start_time"), py::arg("end_time"), py::arg("nets") = std::set<u32>(), R"(
184  Generates the a VCD file for parts the simulated netlist.
185 
186  :param pathlib.Path path: The path to the VCD file.
187  :param int start_time: Start of the timeframe to write to the file (in picoseconds).
188  :param int end_time: End of the timeframe to write to the file (in picoseconds).
189  :param set[hal_py.Net] nets: Nets to include in the VCD file.
190  :returns: ``True`` if the file gerneration was successful, ``False`` otherwise.
191  :rtype: bool
192  )");
193 
194  py::class_<Simulation>(m, "Simulation")
195  .def(py::init<>())
196 
197  .def("get_net_value", &Simulation::get_net_value, py::arg("net"), py::arg("time"), R"(
198  Get the signal value of a specific net at a specific point in time specified in picoseconds.
199 
200  :param hal_py.Net net: The net to inspect.
201  :param int time: The time in picoseconds.
202  :returns: The net's signal value.
203  :rtype: hal_py.BooleanFunction.Value
204  )")
205 
206  .def("add_event", &Simulation::add_event, py::arg("event"), R"(
207  Adds a custom event to the simulation.
208 
209  :param netlist_simulator.Event event: The event to add.
210  )")
211 
212  .def("get_events", &Simulation::get_events, R"(
213  Get all events of the simulation.
214 
215  :returns: A map from net to associated events for that net sorted by time.
216  )");
217 
218 #ifndef PYBIND11_MODULE
219  return m.ptr();
220 #endif // PYBIND11_MODULE
221  }
222 } // namespace hal
Value
represents the type of the node
Definition: gate.h:58
void set_iteration_timeout(u64 iterations)
void simulate(u64 picoseconds)
void initialize_sequential_gates(const std::function< bool(const Gate *)> &filter=nullptr)
void set_simulation_state(const Simulation &state)
void load_initial_values(BooleanFunction::Value value)
const Simulation & get_simulation_state() const
bool generate_vcd(const std::filesystem::path &path, u32 start_time, u32 end_time, std::set< const Net * > nets={}) const
void set_input(const Net *net, BooleanFunction::Value value)
std::string get_name() const override
std::string get_version() const override
BooleanFunction::Value get_net_value(const Net *net, u64 time) const
Definition: simulation.cpp:8
std::unordered_map< const Net *, std::vector< WaveEvent > > get_events() const
Definition: simulation.cpp:31
void add_event(const WaveEvent &event)
Definition: simulation.cpp:26
const Module * module(const Gate *g, const NodeBoxes &boxes)
Definition: defines.h:45
PYBIND11_PLUGIN(hal_py)