-
Notifications
You must be signed in to change notification settings - Fork 76
Netlist
A netlist comprises of gates and nets and describes the connectivity of an electronic circuit. In hardware reverse engineering, a netlist may either be extracted from the images taken of each layer of an integrated circuit (IC) or from the bitstream of a field-programmable gate array (FPGA). The netlist itself can be interpreted as a graph with the gates representing its nodes and the nets representing their connections. Commonly, the netlist is stored as a Verilog or VHDL file. It can be parsed into HAL by using either the provided netlist parsers or writing a new one.
Furthermore, HAL provides the reverse engineer with the ability to add structure to the netlist during reversing. Therefore, modules provide an easy way for modularization and hierarchization of the design. Additionally, groupings can be used to temporarily store unordered sets of gates, nets, and modules during the reversing process.
In HAL, a netlist holds its ID, the path to the file the netlist has been read from, the name of the design, and the name of the targeted device. Additionally, it holds information about the underlying gate library and keeps track of all its gates and nets. From within Python, the currently opened netlist is simply available via netlist
. The ID can be retrieved using get_id
and set using set_id
. To get or set the path to the input file, use get_input_filename
or set_input_filename
respectively. Access to the design name and target device is provided by get_design_name
, set_design_name
, get_device_name
, and set_device_name
. The gate library can be retrieved using get_gate_library
.
id = netlist.get_id() # get the id of the netlist
name = netlist.get_design_name() # get the name of the design
netlist.set_device_name("example_chip") # set the name of the target device
gl = netlist.get_gate_library() # get the underlying gate library
Gates, nets, modules and groupings are technically part of the netlist and may be managed through functions provided by the netlist. These functions enable the creation, deletion, and retrieval of gates, nets, modules, and grouping. they are described in more detail below. Note that whenever an asterisk *
is present within the description, the keywords gate
, net
, module
, or grouping
may be used in its place.
A new element of the netlist may be created using create_*
with the parameters being different for each kind of element. Calling this function will create the respective element and assign a unique ID to it such that it can be unambiguously identified by the ID. Further, an element can be deleted from the netlist using delete_*
which always takes the element itself as input. To check whether an element is part of the netlist, the function is_*_in_netlist
may be used. A single element can be retrieved from the netlist by calling get_*_by_id
and providing the element's unique ID. A list of elements of the same kind can be requested from the netlist using get_*s
. To narrow down the returned elements, a filter may be applied in form of a lambda function.
gate_1 = netlist.create_gate(example_type, "example") # create a new gate of type 'example_type' going by the name 'example'
print(netlist.is_gate_in_netlist(gate_1)) # prints True as the gate is part of the netlist
net_1 = netlist.get_net_by_id(10) # retrieves the net with ID 10 from the netlist
lut6_gates = netlist.get_gates(lambda g : g.get_type().get_name() == "LUT6") # retrieves all gates of the gate type with name 'LUT6'
netlist.delete_module(netlist.get_module_by_id(3)) # removes module with ID 3 from the netlist
As VCC and GND gates are handled a bit differently in HAL and are generally considered to be the source of constant 0
and 1
nets, HAL offers some designated functions to check for and operate on GND and VCC gates. In the following, the asterisk *
may be replaced with either gnd
or vcc
.
Using is_*_gate
, one can check whether the provided gate is internal considered to be a VCC or GND gate. To retrieve all GND or VCC gates within the netlist, the function get_*_gates
may be used. Note that the user can also mark and unmark GND and VCC gates using mark_*_gate
and unmark_*_gate
. However, this functionality should be used carefully as it can lead to inconsistencies otherwise.
netlist.is_vcc_gate(some_gate) # returns True for a VCC gate
gnd_gate_list = netlist.get_gnd_gates() # returns a list of all GND gates
Global input and output nets to the netlist are internally annotated accordingly to make them distinguishable from purely internal nets. These nets correspond to external inputs or outputs to the netlist and may hence not have a source or destination. In the following, the asterisk *
may be replaced with either input
or output
.
To check whether a net ist a global input or output, is_global_*_net
may be called. All nets of the netlist that are annotated as global inputs or outputs may be accessed as a list using get_global_*_nets
. Again, the user can mark and unmark global inputs and outputs on their own using mark_global_*_net
and unmark_global_*_net
, but should be careful when doing so.
netlist.is_global_input_net(some_net) # returns True for a global output net
global_out_list = netlist.get_global_output_nets() # returns a list of all global output nets
The top module, i.e., the module that contains all gates of the netlist, either directly or in sub-modules, can be retrieved using get_top_module
.
top_mod = netlist.get_top_module() # returns the top module