2019-08-23 00:48:46 -05:00
/******************************************************************************
* This files includes data structures for module management .
* It keeps a list of modules that have been generated , the port map of the modules ,
* parents and children of each modules . This will ease instanciation of modules
* with explicit port map and outputting a hierarchy of modules
*
* Module includes the basic information :
* 1. unique identifier
* 2. module name : which should be unique
* 3. port list : basic information of all the ports belonging to the module
* 4. port types : types of each port , which will matter how we output the ports
* 5. parent modules : ids of parent modules
* 6. children modules : ids of child modules
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-08-20 16:14:28 -05:00
# ifndef MODULE_MANAGER_H
# define MODULE_MANAGER_H
# include <string>
2019-08-23 00:48:46 -05:00
# include <map>
2019-09-12 21:49:02 -05:00
# include "vtr_vector.h"
2019-08-20 16:14:28 -05:00
# include "module_manager_fwd.h"
# include "device_port.h"
class ModuleManager {
2019-08-23 13:52:01 -05:00
public : /* Private data structures */
2019-08-23 00:48:46 -05:00
enum e_module_port_type {
2019-10-13 17:23:22 -05:00
MODULE_GLOBAL_PORT , /* Global inputs */
MODULE_GPIO_PORT , /* General-purpose IOs, which are data IOs of the fabric */
MODULE_INOUT_PORT , /* Normal (non-global) inout ports */
MODULE_INPUT_PORT , /* Normal (non-global) input ports */
MODULE_OUTPUT_PORT , /* Normal (non-global) output ports */
MODULE_CLOCK_PORT , /* Nromal (non-global) clock ports*/
2019-08-23 00:48:46 -05:00
NUM_MODULE_PORT_TYPES
} ;
2019-10-10 15:43:32 -05:00
2019-08-23 00:48:46 -05:00
public : /* Public Constructors */
2019-10-10 15:43:32 -05:00
public : /* Types and ranges */
typedef vtr : : vector < ModuleId , ModuleId > : : const_iterator module_iterator ;
2019-10-13 17:23:22 -05:00
typedef vtr : : vector < ModulePortId , ModulePortId > : : const_iterator module_port_iterator ;
2019-10-10 15:43:32 -05:00
typedef vtr : : vector < ModuleNetId , ModuleNetId > : : const_iterator module_net_iterator ;
2019-10-10 21:09:55 -05:00
typedef vtr : : vector < ModuleNetSrcId , ModuleNetSrcId > : : const_iterator module_net_src_iterator ;
typedef vtr : : vector < ModuleNetSinkId , ModuleNetSinkId > : : const_iterator module_net_sink_iterator ;
2019-10-10 15:43:32 -05:00
typedef vtr : : Range < module_iterator > module_range ;
2019-10-13 17:23:22 -05:00
typedef vtr : : Range < module_port_iterator > module_port_range ;
2019-10-10 15:43:32 -05:00
typedef vtr : : Range < module_net_iterator > module_net_range ;
2019-10-10 21:09:55 -05:00
typedef vtr : : Range < module_net_src_iterator > module_net_src_range ;
typedef vtr : : Range < module_net_sink_iterator > module_net_sink_range ;
2019-10-10 15:43:32 -05:00
public : /* Public aggregators */
/* Find all the modules */
module_range modules ( ) const ;
2019-10-13 17:23:22 -05:00
/* Find all the ports belonging to a module */
module_port_range module_ports ( const ModuleId & module ) const ;
2019-10-10 15:43:32 -05:00
/* Find all the nets belonging to a module */
module_net_range module_nets ( const ModuleId & module ) const ;
/* Find all the child modules under a parent module */
std : : vector < ModuleId > child_modules ( const ModuleId & parent_module ) const ;
/* Find all the instances under a parent module */
std : : vector < size_t > child_module_instances ( const ModuleId & parent_module , const ModuleId & child_module ) const ;
2019-10-23 16:44:13 -05:00
/* Find all the configurable child modules under a parent module */
std : : vector < ModuleId > configurable_children ( const ModuleId & parent_module ) const ;
/* Find all the instances of configurable child modules under a parent module */
std : : vector < size_t > configurable_child_instances ( const ModuleId & parent_module ) const ;
2019-10-10 21:09:55 -05:00
/* Find the source ids of modules */
module_net_src_range module_net_sources ( const ModuleId & module , const ModuleNetId & net ) const ;
/* Find the sink ids of modules */
module_net_sink_range module_net_sinks ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
2019-08-23 18:39:29 -05:00
public : /* Public accessors */
2019-08-23 19:41:16 -05:00
size_t num_modules ( ) const ;
2019-10-10 15:43:32 -05:00
size_t num_nets ( const ModuleId & module ) const ;
2019-08-23 18:39:29 -05:00
std : : string module_name ( const ModuleId & module_id ) const ;
std : : string module_port_type_str ( const enum e_module_port_type & port_type ) const ;
std : : vector < BasicPort > module_ports_by_type ( const ModuleId & module_id , const enum e_module_port_type & port_type ) const ;
2019-10-10 21:09:55 -05:00
std : : vector < ModulePortId > module_port_ids_by_type ( const ModuleId & module_id , const enum e_module_port_type & port_type ) const ;
2019-09-05 00:54:53 -05:00
/* Find a port of a module by a given name */
ModulePortId find_module_port ( const ModuleId & module_id , const std : : string & port_name ) const ;
/* Find the Port information with a given port id */
BasicPort module_port ( const ModuleId & module_id , const ModulePortId & port_id ) const ;
/* Find a module by a given name */
2019-08-25 00:54:37 -05:00
ModuleId find_module ( const std : : string & name ) const ;
/* Find the number of instances of a child module in the parent module */
size_t num_instance ( const ModuleId & parent_module , const ModuleId & child_module ) const ;
2019-10-21 01:00:30 -05:00
/* Find the instance name of a child module */
std : : string instance_name ( const ModuleId & parent_module , const ModuleId & child_module ,
const size_t & instance_id ) const ;
/* Find the instance id of a given instance name */
size_t instance_id ( const ModuleId & parent_module , const ModuleId & child_module ,
const std : : string & instance_name ) const ;
2019-10-08 21:14:38 -05:00
/* Find if a port is a wire connection */
bool port_is_wire ( const ModuleId & module , const ModulePortId & port ) const ;
2019-09-10 16:16:29 -05:00
/* Find if a port is register */
bool port_is_register ( const ModuleId & module , const ModulePortId & port ) const ;
2019-09-23 21:25:53 -05:00
/* Return the pre-processing flag of a port */
std : : string port_preproc_flag ( const ModuleId & module , const ModulePortId & port ) const ;
2019-10-09 22:14:30 -05:00
/* Find a net from an instance of a module */
ModuleNetId module_instance_port_net ( const ModuleId & parent_module ,
const ModuleId & child_module , const size_t & child_instance ,
const ModulePortId & child_port , const size_t & child_pin ) const ;
/* Find the name of net */
std : : string net_name ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the source modules of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSrcId , ModuleId > net_source_modules ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the ids of source instances of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSrcId , size_t > net_source_instances ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the source ports of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSrcId , ModulePortId > net_source_ports ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the source pin indices of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSrcId , size_t > net_source_pins ( const ModuleId & module , const ModuleNetId & net ) const ;
2020-01-08 20:43:53 -06:00
/* Identify if a pin of a port in a module already exists in the net source list*/
bool net_source_exist ( const ModuleId & module , const ModuleNetId & net ,
const ModuleId & src_module , const size_t & instance_id ,
const ModulePortId & src_port , const size_t & src_pin ) ;
2019-10-10 21:09:55 -05:00
2019-10-10 15:43:32 -05:00
/* Find the sink modules of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSinkId , ModuleId > net_sink_modules ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the ids of sink instances of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSinkId , size_t > net_sink_instances ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the sink ports of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSinkId , ModulePortId > net_sink_ports ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-10-10 15:43:32 -05:00
/* Find the sink pin indices of a net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleNetSinkId , size_t > net_sink_pins ( const ModuleId & module , const ModuleNetId & net ) const ;
2020-01-08 20:43:53 -06:00
/* Identify if a pin of a port in a module already exists in the net sink list*/
bool net_sink_exist ( const ModuleId & module , const ModuleNetId & net ,
const ModuleId & sink_module , const size_t & instance_id ,
const ModulePortId & sink_port , const size_t & sink_pin ) ;
2019-10-21 01:00:30 -05:00
private : /* Private accessors */
size_t find_child_module_index_in_parent_module ( const ModuleId & parent_module , const ModuleId & child_module ) const ;
2019-08-23 00:48:46 -05:00
public : /* Public mutators */
/* Add a module */
ModuleId add_module ( const std : : string & name ) ;
/* Add a port to a module */
ModulePortId add_port ( const ModuleId & module ,
const BasicPort & port_info , const enum e_module_port_type & port_type ) ;
2019-11-05 16:41:59 -06:00
/* Set a name for a module port */
void set_module_port_name ( const ModuleId & module , const ModulePortId & module_port , const std : : string & port_name ) ;
2019-09-12 21:49:02 -05:00
/* Set a name for a module */
void set_module_name ( const ModuleId & module , const std : : string & name ) ;
2019-10-08 21:14:38 -05:00
/* Set a port to be a wire */
void set_port_is_wire ( const ModuleId & module , const std : : string & port_name , const bool & is_wire ) ;
2019-09-10 16:16:29 -05:00
/* Set a port to be a register */
void set_port_is_register ( const ModuleId & module , const std : : string & port_name , const bool & is_register ) ;
2019-09-23 21:25:53 -05:00
/* Set the preprocessing flag for a port */
2019-09-23 22:15:45 -05:00
void set_port_preproc_flag ( const ModuleId & module , const ModulePortId & port , const std : : string & preproc_flag ) ;
2019-08-23 00:48:46 -05:00
/* Add a child module to a parent module */
void add_child_module ( const ModuleId & parent_module , const ModuleId & child_module ) ;
2019-10-21 01:00:30 -05:00
/* Set the instance name of a child module */
void set_child_instance_name ( const ModuleId & parent_module , const ModuleId & child_module , const size_t & instance_id , const std : : string & instance_name ) ;
2019-10-23 16:44:13 -05:00
/* Add a configurable child module to module */
void add_configurable_child ( const ModuleId & module , const ModuleId & child_module , const size_t & child_instance ) ;
2019-10-09 21:30:16 -05:00
/* Add a net to the connection graph of the module */
ModuleNetId create_module_net ( const ModuleId & module ) ;
2019-10-09 22:14:30 -05:00
/* Set the name of net */
void set_net_name ( const ModuleId & module , const ModuleNetId & net ,
const std : : string & name ) ;
2019-10-09 21:30:16 -05:00
/* Add a source to a net in the connection graph */
2019-10-10 21:09:55 -05:00
ModuleNetSrcId add_module_net_source ( const ModuleId & module , const ModuleNetId & net ,
const ModuleId & src_module , const size_t & instance_id ,
const ModulePortId & src_port , const size_t & src_pin ) ;
2019-10-09 21:30:16 -05:00
/* Add a sink to a net in the connection graph */
2019-10-10 21:09:55 -05:00
ModuleNetSinkId add_module_net_sink ( const ModuleId & module , const ModuleNetId & net ,
const ModuleId & sink_module , const size_t & instance_id ,
const ModulePortId & sink_port , const size_t & sink_pin ) ;
2019-09-26 21:59:19 -05:00
public : /* Public validators/invalidators */
2019-08-23 00:48:46 -05:00
bool valid_module_id ( const ModuleId & module ) const ;
bool valid_module_port_id ( const ModuleId & module , const ModulePortId & port ) const ;
2019-10-09 21:30:16 -05:00
bool valid_module_net_id ( const ModuleId & module , const ModuleNetId & net ) const ;
2019-09-26 21:59:19 -05:00
private : /* Private validators/invalidators */
2019-08-23 00:48:46 -05:00
void invalidate_name2id_map ( ) ;
void invalidate_port_lookup ( ) ;
2019-10-09 21:30:16 -05:00
void invalidate_net_lookup ( ) ;
2019-08-20 16:14:28 -05:00
private : /* Internal data */
2019-10-09 21:30:16 -05:00
/* Module-level data */
2019-08-23 00:48:46 -05:00
vtr : : vector < ModuleId , ModuleId > ids_ ; /* Unique identifier for each Module */
vtr : : vector < ModuleId , std : : string > names_ ; /* Unique identifier for each Module */
vtr : : vector < ModuleId , std : : vector < ModuleId > > parents_ ; /* Parent modules that include the module */
vtr : : vector < ModuleId , std : : vector < ModuleId > > children_ ; /* Child modules that this module contain */
2019-08-25 00:54:37 -05:00
vtr : : vector < ModuleId , std : : vector < size_t > > num_child_instances_ ; /* Number of children instance in each child module */
2019-10-21 01:00:30 -05:00
vtr : : vector < ModuleId , std : : vector < std : : vector < std : : string > > > child_instance_names_ ; /* Number of children instance in each child module */
2019-08-23 00:48:46 -05:00
2019-10-23 16:44:13 -05:00
/* Configurable child modules are used to record the position of configurable modules in bitstream
* The sequence of children in the list denotes which one is configured first , etc .
* Note that the sequence can be totally different from the children_ list
* This is really dependent how the configuration protocol is organized
* which should be made by users / designers
*/
vtr : : vector < ModuleId , std : : vector < ModuleId > > configurable_children_ ; /* Child modules with configurable memory bits that this module contain */
vtr : : vector < ModuleId , std : : vector < size_t > > configurable_child_instances_ ; /* Instances of child modules with configurable memory bits that this module contain */
2019-10-09 21:30:16 -05:00
/* Port-level data */
2019-08-23 00:48:46 -05:00
vtr : : vector < ModuleId , vtr : : vector < ModulePortId , ModulePortId > > port_ids_ ; /* List of ports for each Module */
vtr : : vector < ModuleId , vtr : : vector < ModulePortId , BasicPort > > ports_ ; /* List of ports for each Module */
vtr : : vector < ModuleId , vtr : : vector < ModulePortId , enum e_module_port_type > > port_types_ ; /* Type of ports */
2019-10-08 21:14:38 -05:00
vtr : : vector < ModuleId , vtr : : vector < ModulePortId , bool > > port_is_wire_ ; /* If the port is a wire, use for Verilog port definition. If enabled: <port_type> reg <port_name> */
2019-09-10 16:16:29 -05:00
vtr : : vector < ModuleId , vtr : : vector < ModulePortId , bool > > port_is_register_ ; /* If the port is a register, use for Verilog port definition. If enabled: <port_type> reg <port_name> */
2019-09-23 21:25:53 -05:00
vtr : : vector < ModuleId , vtr : : vector < ModulePortId , std : : string > > port_preproc_flags_ ; /* If a port is available only when a pre-processing flag is enabled. This is to record the pre-processing flags */
2019-08-23 00:48:46 -05:00
2019-10-09 21:30:16 -05:00
/* Graph-level data:
* We use nets to model the connection between pins of modules and instances .
* To avoid large memory footprint , we do NOT create pins ,
* To enable fast look - up on pins , we create a fast look - up
*/
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , ModuleNetId > > net_ids_ ; /* List of nets for each Module */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , std : : string > > net_names_ ; /* Name of net */
2019-10-10 21:09:55 -05:00
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSrcId , ModuleNetSrcId > > > net_src_ids_ ; /* Unique id of the source that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSrcId , ModuleId > > > net_src_module_ids_ ; /* Pin ids that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSrcId , size_t > > > net_src_instance_ids_ ; /* Pin ids that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSrcId , ModulePortId > > > net_src_port_ids_ ; /* Pin ids that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSrcId , size_t > > > net_src_pin_ids_ ; /* Pin ids that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSinkId , ModuleNetSinkId > > > net_sink_ids_ ; /* Unique ids of the sink that the net drives */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSinkId , ModuleId > > > net_sink_module_ids_ ; /* Pin ids that the net drives */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSinkId , size_t > > > net_sink_instance_ids_ ; /* Pin ids that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSinkId , ModulePortId > > > net_sink_port_ids_ ; /* Pin ids that drive the net */
vtr : : vector < ModuleId , vtr : : vector < ModuleNetId , vtr : : vector < ModuleNetSinkId , size_t > > > net_sink_pin_ids_ ; /* Pin ids that drive the net */
2019-10-09 21:30:16 -05:00
2019-08-23 00:48:46 -05:00
/* fast look-up for module */
std : : map < std : : string , ModuleId > name_id_map_ ;
/* fast look-up for ports */
typedef vtr : : vector < ModuleId , std : : vector < std : : vector < ModulePortId > > > PortLookup ;
mutable PortLookup port_lookup_ ; /* [module_ids][port_types][port_ids] */
2019-10-09 21:30:16 -05:00
/* fast look-up for nets */
typedef vtr : : vector < ModuleId , std : : map < ModuleId , std : : vector < std : : map < ModulePortId , std : : vector < ModuleNetId > > > > > NetLookup ;
mutable NetLookup net_lookup_ ; /* [module_ids][module_ids][instance_ids][port_ids][pin_ids] */
2019-08-20 16:14:28 -05:00
} ;
# endif