blob: f49bc4af0797e248b545a31940d59d1f49a2b4d8 [file] [log] [blame]
#ifndef ATOM_NETLIST_H
#define ATOM_NETLIST_H
/*
* Summary
* ========
* This file defines the AtomNetlist class used to store and manipulate the primitive (or atom) netlist.
*
*
* Overview
* ========
* The AtomNetlist is derived from the Netlist class, and contains information on the primitives.
* This includes basic components (Blocks, Ports, Pins, & Nets), and physical descriptions (t_model)
* of the primitives.
*
* Most of the functionality relevant to components and their accessors/cross-accessors
* is implemented in the Netlist class. Refer to netlist.(h|tpp) for more information.
*
*
* Components
* ==========
* There are 4 components in the Netlist: Blocks, Ports, Pins, and Nets.
* Each component has a unique ID in the netlist, as well as various associations to their
* related components (e.g. A pin knows which port it belongs to, and what net it connects to)
*
* Blocks
* ------
* Blocks refer to the atoms (AKA primitives) that are in the the netlist. Each block contains
* input/output/clock ports. Blocks have names, and various functionalities (LUTs, FFs, RAMs, ...)
* Each block has an associated t_model, describing the physical properties.
*
* Ports
* -----
* Ports are composed of a set of pins that have specific directionality (INPUT, OUTPUT, or CLOCK).
* The ports in the AtomNetlist are respective to the atoms. (i.e. the AtomNetlist does not contain
* ports of a Clustered Logic Block). Each port has an associated t_model_port, describing the
* physical properties.
*
* Pins
* ----
* Pins are single-wire input/outputs. They are part of a port, and are connected to a single net.
*
* Nets
* ----
* Nets in the AtomNetlist track the wiring connections between the atoms.
*
* Models
* ------
* There are two main models, the primitive itself (t_model) and the ports of that primitive (t_model_ports).
* The models are created from the architecture file, and describe the physical properties of the atom.
*
* Truth Table
* -----------
* The AtomNetlist also contains a TruthTable for each block, which indicates what the LUTs contain.
*
*
* Implementation
* ==============
* For all create_* functions, the AtomNetlist will wrap and call the Netlist's version as it contains
* additional information that the base Netlist does not know about.
*
* All functions with suffix *_impl() follow the Non-Virtual Interface (NVI) idiom.
* They are called from the base Netlist class to simplify pre/post condition checks and
* prevent Fragile Base Class (FBC) problems.
*
* Refer to netlist.h for more information.
*
*/
#include <vector>
#include <unordered_map>
#include "vtr_range.h"
#include "vtr_logic.h"
#include "vtr_vector_map.h"
#include "logic_types.h" //For t_model
#include "netlist.h"
#include "atom_netlist_fwd.h"
class AtomNetlist : public Netlist<AtomBlockId, AtomPortId, AtomPinId, AtomNetId> {
public:
//Constructs a netlist
// name: the name of the netlist (e.g. top-level module)
// id: a unique identifier for the netlist (e.g. a secure digest of the input file)
AtomNetlist(std::string name = "", std::string id = "");
public: //Public types
typedef std::vector<std::vector<vtr::LogicValue>> TruthTable;
public: //Public Accessors
/*
* Blocks
*/
//Returns the type of the specified block
AtomBlockType block_type(const AtomBlockId id) const;
//Returns the model associated with the block
const t_model* block_model(const AtomBlockId id) const;
//Returns the truth table associated with the block
// Note that this is only non-empty for LUTs and Flip-Flops/latches.
//
// For LUTs the truth table stores the single-output cover representing the
// logic function.
//
// For FF/Latches there is only a single entry representing the initial state
const TruthTable& block_truth_table(const AtomBlockId id) const;
/*
* Ports
*/
//Returns the model port of the specified port or nullptr if not
// id: The ID of the port to look for
const t_model_ports* port_model(const AtomPortId id) const;
/*
* Lookups
*/
//Returns the AtomPortId of the specifed port if it exists or AtomPortId::INVALID() if not
//Note that this method is typically more efficient than searching by name
// blk_id : The ID of the block who's ports will be checked
// model_port : The port model to look for
AtomPortId find_atom_port(const AtomBlockId blk_id, const t_model_ports* model_port) const;
//Returns the AtomBlockId of the atom driving the specified pin if it exists or AtomBlockId::INVALID() if not
// blk_id : The ID of the block whose ports will be checked
// model_port : The port model to look for
// port_bit : The pin number in this port
AtomBlockId find_atom_pin_driver(const AtomBlockId blk_id, const t_model_ports* model_port, const BitIndex port_bit) const;
public: //Public Mutators
/*
* Note: all create_*() functions will silently return the appropriate ID if it has already been created
*/
//Create or return an existing block in the netlist
// name : The unique name of the block
// model : The primitive type of the block
// truth_table : The single-output cover defining the block's logic function
// The truth_table is optional and only relevant for LUTs (where it describes the logic function)
// and Flip-Flops/latches (where it consists of a single entry defining the initial state).
AtomBlockId create_block(const std::string name, const t_model* model, const TruthTable truth_table = TruthTable());
//Create or return an existing port in the netlist
// blk_id : The block the port is associated with
// name : The name of the port (must match the name of a port in the block's model)
AtomPortId create_port(const AtomBlockId blk_id, const t_model_ports* model_port);
//Create or return an existing pin in the netlist
// port_id : The port this pin is associated with
// port_bit : The bit index of the pin in the port
// net_id : The net the pin drives/sinks
// pin_type : The type of the pin (driver/sink)
// is_const : Indicates whether the pin holds a constant value (e. g. vcc/gnd)
AtomPinId create_pin(const AtomPortId port_id, BitIndex port_bit, const AtomNetId net_id, const PinType pin_type, bool is_const = false);
//Create an empty, or return an existing net in the netlist
// name : The unique name of the net
AtomNetId create_net(const std::string name); //An empty or existing net
//Create a completely specified net from specified driver and sinks
// name : The name of the net (Note: must not already exist)
// driver : The net's driver pin
// sinks : The net's sink pins
AtomNetId add_net(const std::string name, AtomPinId driver, std::vector<AtomPinId> sinks);
private: //Private members
/*
* Component removal
*/
void remove_block_impl(const AtomBlockId blk_id) override;
void remove_port_impl(const AtomPortId port_id) override;
void remove_pin_impl(const AtomPinId pin_id) override;
void remove_net_impl(const AtomNetId net_id) override;
/*
* Netlist compression/optimization
*/
//Removes invalid components and reorders them
void clean_blocks_impl(const vtr::vector_map<AtomBlockId, AtomBlockId>& block_id_map) override;
void clean_ports_impl(const vtr::vector_map<AtomPortId, AtomPortId>& port_id_map) override;
void clean_pins_impl(const vtr::vector_map<AtomPinId, AtomPinId>& pin_id_map) override;
void clean_nets_impl(const vtr::vector_map<AtomNetId, AtomNetId>& net_id_map) override;
void rebuild_block_refs_impl(const vtr::vector_map<AtomPinId, AtomPinId>& pin_id_map, const vtr::vector_map<AtomPortId, AtomPortId>& port_id_map) override;
void rebuild_port_refs_impl(const vtr::vector_map<AtomBlockId, AtomBlockId>& block_id_map, const vtr::vector_map<AtomPinId, AtomPinId>& pin_id_map) override;
void rebuild_pin_refs_impl(const vtr::vector_map<AtomPortId, AtomPortId>& port_id_map, const vtr::vector_map<AtomNetId, AtomNetId>& net_id_map) override;
void rebuild_net_refs_impl(const vtr::vector_map<AtomPinId, AtomPinId>& pin_id_map) override;
//Shrinks internal data structures to required size to reduce memory consumption
void shrink_to_fit_impl() override;
/*
* Sanity checks
*/
//Verify the internal data structure sizes match
bool validate_block_sizes_impl(size_t num_blocks) const override;
bool validate_port_sizes_impl(size_t num_ports) const override;
bool validate_pin_sizes_impl(size_t num_pins) const override;
bool validate_net_sizes_impl(size_t num_nets) const override;
private: //Private data
//Block data
vtr::vector_map<AtomBlockId, const t_model*> block_models_; //Architecture model of each block
vtr::vector_map<AtomBlockId, TruthTable> block_truth_tables_; //Truth tables of each block
//Port data
vtr::vector_map<AtomPortId, const t_model_ports*> port_models_; //Architecture port models of each port
};
#include "atom_lookup.h"
#endif