blob: 2147c8557ed3c1a9670d5c45dc5e6a137fb7201f [file] [log] [blame]
#ifndef CLUSTERED_NETLIST_H
#define CLUSTERED_NETLIST_H
/*
* Summary
* ========
* This file defines the ClusteredNetlist class in the ClusteredContext created during
* pre-placement stages of the VTR flow (packing & clustering), and used downstream.
*
* Overview
* ========
* The ClusteredNetlist is derived from the Netlist class, and contains some
* separate information on Blocks, Pins, and Nets. It does not make use of Ports.
*
* Blocks
* ------
* The pieces of unique block information are:
* block_pbs_: Physical block describing the clustering and internal hierarchy
* structure of each CLB.
* block_types_: The type of physical block the block is mapped to, e.g. logic
* block, RAM, DSP (Can be user-defined types).
* block_nets_: Based on the block's pins (indexed from [0...num_pins - 1]),
* lists which pins are used/unused with the net using it.
* block_pin_nets_: Returns the index of a pin relative to the net, when given a block and a pin's
* index on that block (from the type descriptor).
* Differs from block_nets_.
*
* Differences between block_nets_ & block_pin_nets_
* --------------------------------------------------
* +-----------+
* 0-->| |-->3
* 1-->| Block |-->4
* 2-->| |-->5
* +-----------+
*
* block_nets_ tracks all pins on a block, and returns the ClusterNetId to which a pin is connected to.
* If the pin is unused/open, ClusterNetId::INVALID() is stored.
*
* block_pin_nets_ tracks whether the nets connected to the block are drivers/receivers of that net.
* Driver/receiver nets are determined by the pin_class of the block's pin.
* A net connected to a driver pin in the block has a 0 is stored. A net connected to a receiver
* has a counter (from [1...num_sinks - 1]).
*
* The net is connected to multiple blocks. Each block_pin_nets_ has a unique number in that net.
*
* E.g.
* +-----------+ +-----------+
* 0-->| |-->3 Net A 0-->| |-->3
* 1-->| Block 1 |---4---------->1-->| Block 2 |-->4
* 2-->| |-->5 2-->| |-->5
* +-----------+ | +-----------+
* |
* | +-----------+
* | | |-->1
* 0-->| Block 3 |
* | |-->2
* +-----------+
*
* In the example, Net A is driven by Block 1, and received by Blocks 2 & 3.
* For Block 1, block_pin_nets_ of pin 4 returns 0, as it is the driver.
* For Block 2, block_pin_nets_ of pin 1 returns 1 (or 2), non-zero as it is a receiver.
* For Block 3, block_pin_nets_ of pin 0 returns 2 (or 1), non-zero as it is also a receiver.
*
* The block_pin_nets_ data structure exists for quick indexing, rather than using a linear search
* with the available functions from the base Netlist, into the net_delay_ structure in the
* PostClusterDelayCalculator of inter_cluster_delay(). net_delay_ is a 2D array, where the indexing
* scheme is [net_id] followed by [pin_index on net].
*
* Pins
* ----
* The only piece of unique pin information is:
* physical_pin_index_
*
* Example of physical_pin_index_
* ---------------------
* Given a ClusterPinId, physical_pin_index_ will return the index of the pin within its block
* relative to the t_logical_block_type (physical description of the block).
*
* +-----------+
* 0-->|O X|-->3
* 1-->|O Block O|-->4
* 2-->|X O|-->5 (e.g. ClusterPinId = 92)
* +-----------+
*
* The index skips over unused pins, e.g. CLB has 6 pins (3 in, 3 out, numbered [0...5]), where
* the first two ins, and last two outs are used. Indices [0,1] represent the ins, and [4,5]
* represent the outs. Indices [2,3] are unused. Therefore, physical_pin_index_[92] = 5.
*
* Nets
* ----
* The pieces of unique net information stored are:
* net_global_: Boolean mapping whether the net is global
* net_fixed_: Boolean mapping whether the net is fixed (i.e. constant)
*
* Implementation
* ==============
* For all create_* functions, the ClusteredNetlist 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 "vpr_types.h"
#include "vpr_utils.h"
#include "vtr_util.h"
#include "netlist.h"
#include "clustered_netlist_fwd.h"
class ClusteredNetlist : public Netlist<ClusterBlockId, ClusterPortId, ClusterPinId, ClusterNetId> {
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)
ClusteredNetlist(std::string name = "", std::string id = "");
public: //Public Accessors
/*
* Blocks
*/
//Returns the physical block
t_pb* block_pb(const ClusterBlockId id) const;
//Returns the type of CLB (Logic block, RAM, DSP, etc.)
t_logical_block_type_ptr block_type(const ClusterBlockId id) const;
//Returns the net of the block attached to the specific pin index
ClusterNetId block_net(const ClusterBlockId blk_id, const int pin_index) const;
//Returns the count on the net of the block attached
int block_pin_net_index(const ClusterBlockId blk_id, const int pin_index) const;
//Returns the logical pin Id associated with the specified block and physical pin index
ClusterPinId block_pin(const ClusterBlockId blk, const int phys_pin_index) const;
//Returns true if the specified block contains a primary input (e.g. BLIF .input primitive)
bool block_contains_primary_input(const ClusterBlockId blk) const;
//Returns true if the specified block contains a primary output (e.g. BLIF .output primitive)
bool block_contains_primary_output(const ClusterBlockId blk) const;
/*
* Pins
*/
//Returns the physical pin index (i.e. pin index on the
//t_logical_block_type) of the specified logical pin
int pin_physical_index(const ClusterPinId id) const;
//Finds the net_index'th net pin (e.g. the 6th pin of the net) and
//returns the physical pin index (i.e. pin index on the t_logical_block_type)
//of the block to which the pin belongs
// net_id : The net
// net_pin_index : The index of the pin in the net
int net_pin_physical_index(const ClusterNetId net_id, int net_pin_index) const;
/*
* Nets
*/
//Returns whether the net is ignored i.e. not routed
bool net_is_ignored(const ClusterNetId id) const;
//Returns whether the net is global
bool net_is_global(const ClusterNetId id) const;
public: //Public Mutators
//Create or return an existing block in the netlist
// name : The unique name of the block
// pb : The physical representation of the block
// t_logical_block_type_ptr : The type of the CLB
ClusterBlockId create_block(const char* name, t_pb* pb, t_logical_block_type_ptr type);
//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)
// width : The width (number of bits) of the port
// type : The type of the port (INPUT, OUTPUT, or CLOCK)
ClusterPortId create_port(const ClusterBlockId blk_id, const std::string name, BitIndex width, PortType type);
//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)
// pin_index : The index of the pin relative to its block, excluding OPEN pins)
// is_const : Indicates whether the pin holds a constant value (e. g. vcc/gnd)
ClusterPinId create_pin(const ClusterPortId port_id, BitIndex port_bit, const ClusterNetId net_id, const PinType pin_type, int pin_index, bool is_const = false);
//Sets the mapping of a ClusterPinId to the block's type descriptor's pin index
// pin_id : The pin to be set
// index : The new index to set the pin to
void set_pin_physical_index(const ClusterPinId pin_id, const int index);
//Create an empty, or return an existing net in the netlist
// name : The unique name of the net
ClusterNetId create_net(const std::string name);
//Sets the flag in net_ignored_ = state
void set_net_is_ignored(ClusterNetId net_id, bool state);
//Sets the flag in net_is_global_ = state
void set_net_is_global(ClusterNetId net_id, bool state);
private: //Private Members
/*
* Netlist compression/optimization
*/
//Removes invalid components and reorders them
void clean_blocks_impl(const vtr::vector_map<ClusterBlockId, ClusterBlockId>& block_id_map) override;
void clean_ports_impl(const vtr::vector_map<ClusterPortId, ClusterPortId>& port_id_map) override;
void clean_pins_impl(const vtr::vector_map<ClusterPinId, ClusterPinId>& pin_id_map) override;
void clean_nets_impl(const vtr::vector_map<ClusterNetId, ClusterNetId>& net_id_map) override;
//Shrinks internal data structures to required size to reduce memory consumption
void shrink_to_fit_impl() override;
/*
* Component removal
*/
//Removes a block from the netlist. This will also remove the associated ports and pins.
// blk_id : The block to be removed
void remove_block_impl(const ClusterBlockId blk_id) override;
void remove_port_impl(const ClusterPortId port_id) override;
void remove_pin_impl(const ClusterPinId pin_id) override;
void remove_net_impl(const ClusterNetId net_id) override;
void rebuild_block_refs_impl(const vtr::vector_map<ClusterPinId, ClusterPinId>& pin_id_map, const vtr::vector_map<ClusterPortId, ClusterPortId>& port_id_map) override;
void rebuild_port_refs_impl(const vtr::vector_map<ClusterBlockId, ClusterBlockId>& block_id_map, const vtr::vector_map<ClusterPinId, ClusterPinId>& pin_id_map) override;
void rebuild_pin_refs_impl(const vtr::vector_map<ClusterPortId, ClusterPortId>& port_id_map, const vtr::vector_map<ClusterNetId, ClusterNetId>& net_id_map) override;
void rebuild_net_refs_impl(const vtr::vector_map<ClusterPinId, ClusterPinId>& pin_id_map) 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
//Blocks
vtr::vector_map<ClusterBlockId, t_pb*> block_pbs_; //Physical block representing the clustering & internal hierarchy of each CLB
vtr::vector_map<ClusterBlockId, t_logical_block_type_ptr> block_types_; //The type of physical block this user circuit block is mapped to
vtr::vector_map<ClusterBlockId, std::vector<ClusterPinId>> block_logical_pins_; //The logical pin associated with each physical block pin
//Pins
vtr::vector_map<ClusterPinId, int> pin_physical_index_; //The physical pin index (i.e. pin index
//in t_logical_block_type) of logical pins
//Nets
vtr::vector_map<ClusterNetId, bool> net_is_ignored_; //Boolean mapping indicating if the net is ignored
vtr::vector_map<ClusterNetId, bool> net_is_global_; //Boolean mapping indicating if the net is global
};
#endif