add module usage types for future FPGA-SPICE development

This commit is contained in:
tangxifan 2020-07-04 22:33:54 -06:00
parent ece262f544
commit 83e26adf90
12 changed files with 118 additions and 2 deletions

View File

@ -219,6 +219,10 @@ void build_mux_local_decoder_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */ /* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = module_manager.add_module(module_name); ModuleId module_id = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(module_id)); VTR_ASSERT(true == module_manager.valid_module_id(module_id));
/* Label module usage */
module_manager.set_module_usage(module_id, ModuleManager::MODULE_CONFIG);
/* Add module ports */ /* Add module ports */
/* Add each input port */ /* Add each input port */
BasicPort addr_port(generate_mux_local_decoder_addr_port_name(), addr_size); BasicPort addr_port(generate_mux_local_decoder_addr_port_name(), addr_size);

View File

@ -215,6 +215,17 @@ void build_constant_generator_module(ModuleManager& module_manager,
/* Add one output port */ /* Add one output port */
BasicPort const_output_port(generate_const_value_module_output_port_name(const_value), 1); BasicPort const_output_port(generate_const_value_module_output_port_name(const_value), 1);
module_manager.add_port(const_module, const_output_port, ModuleManager::MODULE_OUTPUT_PORT); module_manager.add_port(const_module, const_output_port, ModuleManager::MODULE_OUTPUT_PORT);
/* Specify the usage of this module
* 1: VDD
* 0: GND
*/
if (1 == const_value) {
module_manager.set_module_usage(const_module, ModuleManager::MODULE_VDD);
} else {
VTR_ASSERT(0 == const_value);
module_manager.set_module_usage(const_module, ModuleManager::MODULE_VSS);
}
} }
/********************************************************************* /*********************************************************************

View File

@ -251,6 +251,9 @@ void build_primitive_block_module(ModuleManager& module_manager,
/* Ensure that the module has been created and thus unique! */ /* Ensure that the module has been created and thus unique! */
VTR_ASSERT(ModuleId::INVALID() != primitive_module); VTR_ASSERT(ModuleId::INVALID() != primitive_module);
/* Label module usage */
module_manager.set_module_usage(primitive_module, ModuleManager::MODULE_GRID);
/* Note: to cooperate with the pb_type hierarchy and connections, we add the port of primitive pb_type here. /* Note: to cooperate with the pb_type hierarchy and connections, we add the port of primitive pb_type here.
* Since we have linked pb_type ports to circuit models when setting up FPGA-X2P, * Since we have linked pb_type ports to circuit models when setting up FPGA-X2P,
* no ports of the circuit model will be missing here * no ports of the circuit model will be missing here
@ -858,6 +861,9 @@ void rec_build_logical_tile_modules(ModuleManager& module_manager,
ModuleId pb_module = module_manager.add_module(pb_module_name); ModuleId pb_module = module_manager.add_module(pb_module_name);
VTR_ASSERT(true == module_manager.valid_module_id(pb_module)); VTR_ASSERT(true == module_manager.valid_module_id(pb_module));
/* Label module usage */
module_manager.set_module_usage(pb_module, ModuleManager::MODULE_GRID);
/* Add ports to the Verilog module */ /* Add ports to the Verilog module */
add_pb_type_ports_to_module_manager(module_manager, pb_module, physical_pb_type); add_pb_type_ports_to_module_manager(module_manager, pb_module, physical_pb_type);

View File

@ -82,6 +82,10 @@ void build_lut_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */ /* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId lut_module = module_manager.add_module(circuit_lib.model_name(lut_model)); ModuleId lut_module = module_manager.add_module(circuit_lib.model_name(lut_model));
VTR_ASSERT(true == module_manager.valid_module_id(lut_module)); VTR_ASSERT(true == module_manager.valid_module_id(lut_module));
/* Label module usage */
module_manager.set_module_usage(lut_module, ModuleManager::MODULE_LUT);
/* Add module ports */ /* Add module ports */
/* Add each global port */ /* Add each global port */
for (const auto& port : lut_global_ports) { for (const auto& port : lut_global_ports) {

View File

@ -322,6 +322,9 @@ void build_memory_flatten_module(ModuleManager& module_manager,
/* Create a module and add to the module manager */ /* Create a module and add to the module manager */
ModuleId mem_module = module_manager.add_module(module_name); ModuleId mem_module = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
/* Label module usage */
module_manager.set_module_usage(mem_module, ModuleManager::MODULE_CONFIG);
/* Add module ports */ /* Add module ports */
/* Input: BL port */ /* Input: BL port */
@ -404,6 +407,9 @@ void build_memory_chain_module(ModuleManager& module_manager,
/* Create a module and add to the module manager */ /* Create a module and add to the module manager */
ModuleId mem_module = module_manager.add_module(module_name); ModuleId mem_module = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
/* Label module usage */
module_manager.set_module_usage(mem_module, ModuleManager::MODULE_CONFIG);
/* Add an input port, which is the head of configuration chain in the module */ /* Add an input port, which is the head of configuration chain in the module */
/* TODO: restriction!!! /* TODO: restriction!!!
@ -542,6 +548,9 @@ void build_frame_memory_module(ModuleManager& module_manager,
ModuleId mem_module = module_manager.add_module(module_name); ModuleId mem_module = module_manager.add_module(module_name);
VTR_ASSERT(true == module_manager.valid_module_id(mem_module)); VTR_ASSERT(true == module_manager.valid_module_id(mem_module));
/* Label module usage */
module_manager.set_module_usage(mem_module, ModuleManager::MODULE_CONFIG);
/* Find the specification of the decoder: /* Find the specification of the decoder:
* Size of address port and data input * Size of address port and data input
*/ */

View File

@ -1145,6 +1145,15 @@ void build_cmos_mux_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */ /* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId mux_module = module_manager.add_module(module_name); ModuleId mux_module = module_manager.add_module(module_name);
VTR_ASSERT(ModuleId::INVALID() != mux_module); VTR_ASSERT(ModuleId::INVALID() != mux_module);
/* Label module usage */
if (CIRCUIT_MODEL_MUX == circuit_lib.model_type(mux_model)) {
module_manager.set_module_usage(mux_module, ModuleManager::MODULE_INTERC);
} else {
VTR_ASSERT_SAFE(CIRCUIT_MODEL_LUT == circuit_lib.model_type(mux_model));
module_manager.set_module_usage(mux_module, ModuleManager::MODULE_LUT);
}
/* Add module ports */ /* Add module ports */
/* Add each input port /* Add each input port
* Treat MUX and LUT differently * Treat MUX and LUT differently
@ -1294,6 +1303,10 @@ void build_rram_mux_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */ /* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId module_id = module_manager.add_module(module_name); ModuleId module_id = module_manager.add_module(module_name);
VTR_ASSERT(ModuleId::INVALID() != module_id); VTR_ASSERT(ModuleId::INVALID() != module_id);
/* Label module usage */
module_manager.set_module_usage(module_id, ModuleManager::MODULE_INTERC);
/* Add module ports */ /* Add module ports */
/* Add each global port */ /* Add each global port */
for (const auto& port : mux_global_ports) { for (const auto& port : mux_global_ports) {

View File

@ -337,6 +337,9 @@ void build_switch_block_module(ModuleManager& module_manager,
vtr::Point<size_t> gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y()); vtr::Point<size_t> gsb_coordinate(rr_gsb.get_sb_x(), rr_gsb.get_sb_y());
ModuleId sb_module = module_manager.add_module(generate_switch_block_module_name(gsb_coordinate)); ModuleId sb_module = module_manager.add_module(generate_switch_block_module_name(gsb_coordinate));
/* Label module usage */
module_manager.set_module_usage(sb_module, ModuleManager::MODULE_SB);
VTR_LOGV(verbose, VTR_LOGV(verbose,
"Building module '%s'...", "Building module '%s'...",
generate_switch_block_module_name(gsb_coordinate).c_str()); generate_switch_block_module_name(gsb_coordinate).c_str());
@ -736,6 +739,9 @@ void build_connection_block_module(ModuleManager& module_manager,
/* Create a Verilog Module based on the circuit model, and add to module manager */ /* Create a Verilog Module based on the circuit model, and add to module manager */
ModuleId cb_module = module_manager.add_module(generate_connection_block_module_name(cb_type, gsb_coordinate)); ModuleId cb_module = module_manager.add_module(generate_connection_block_module_name(cb_type, gsb_coordinate));
/* Label module usage */
module_manager.set_module_usage(cb_module, ModuleManager::MODULE_CB);
VTR_LOGV(verbose, VTR_LOGV(verbose,
"Building module '%s'...", "Building module '%s'...",
generate_connection_block_module_name(cb_type, gsb_coordinate).c_str()); generate_connection_block_module_name(cb_type, gsb_coordinate).c_str());

View File

@ -341,6 +341,9 @@ void build_top_module(ModuleManager& module_manager,
std::string top_module_name = generate_fpga_top_module_name(); std::string top_module_name = generate_fpga_top_module_name();
ModuleId top_module = module_manager.add_module(top_module_name); ModuleId top_module = module_manager.add_module(top_module_name);
/* Label module usage */
module_manager.set_module_usage(top_module, ModuleManager::MODULE_TOP);
std::map<t_rr_type, vtr::Matrix<size_t>> cb_instance_ids; std::map<t_rr_type, vtr::Matrix<size_t>> cb_instance_ids;
/* Add sub modules, which are grid, SB and CBX/CBY modules as instances */ /* Add sub modules, which are grid, SB and CBX/CBY modules as instances */

View File

@ -119,6 +119,12 @@ std::string ModuleManager::module_name(const ModuleId& module_id) const {
return names_[module_id]; return names_[module_id];
} }
ModuleManager::e_module_usage_type ModuleManager::module_usage(const ModuleId& module_id) const {
/* Validate the module_id */
VTR_ASSERT(valid_module_id(module_id));
return usages_[module_id];
}
/* Get the string of a module port type */ /* Get the string of a module port type */
std::string ModuleManager::module_port_type_str(const enum e_module_port_type& port_type) const { std::string ModuleManager::module_port_type_str(const enum e_module_port_type& port_type) const {
std::array<const char*, NUM_MODULE_PORT_TYPES> MODULE_PORT_TYPE_STRING = {{"GLOBAL PORTS", "GPIN PORTS", "GPOUT PORTS", "GPIO PORTS", "INOUT PORTS", "INPUT PORTS", "OUTPUT PORTS", "CLOCK PORTS"}}; std::array<const char*, NUM_MODULE_PORT_TYPES> MODULE_PORT_TYPE_STRING = {{"GLOBAL PORTS", "GPIN PORTS", "GPOUT PORTS", "GPIO PORTS", "INOUT PORTS", "INPUT PORTS", "OUTPUT PORTS", "CLOCK PORTS"}};
@ -469,6 +475,7 @@ ModuleId ModuleManager::add_module(const std::string& name) {
/* Allocate other attributes */ /* Allocate other attributes */
names_.push_back(name); names_.push_back(name);
usages_.push_back(NUM_MODULE_USAGE_TYPES);
parents_.emplace_back(); parents_.emplace_back();
children_.emplace_back(); children_.emplace_back();
num_child_instances_.emplace_back(); num_child_instances_.emplace_back();
@ -553,6 +560,12 @@ void ModuleManager::set_module_name(const ModuleId& module, const std::string& n
names_[module] = name; names_[module] = name;
} }
void ModuleManager::set_module_usage(const ModuleId& module, const e_module_usage_type& usage) {
/* Validate the id of module */
VTR_ASSERT( valid_module_id(module) );
usages_[module] = usage;
}
/* Set a port to be a wire */ /* Set a port to be a wire */
void ModuleManager::set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire) { void ModuleManager::set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire) {
/* Find the port */ /* Find the port */

View File

@ -30,6 +30,10 @@ namespace openfpga {
******************************************************************************/ ******************************************************************************/
class ModuleManager { class ModuleManager {
public: /* Private data structures */ public: /* Private data structures */
/* A type to indicate the usage of ports
* Test bench generator use this to identify
* what signals to drive
*/
enum e_module_port_type { enum e_module_port_type {
MODULE_GLOBAL_PORT, /* Global inputs */ MODULE_GLOBAL_PORT, /* Global inputs */
MODULE_GPIN_PORT, /* General-purpose input */ MODULE_GPIN_PORT, /* General-purpose input */
@ -38,10 +42,29 @@ class ModuleManager {
MODULE_INOUT_PORT, /* Normal (non-global) inout ports */ MODULE_INOUT_PORT, /* Normal (non-global) inout ports */
MODULE_INPUT_PORT, /* Normal (non-global) input ports */ MODULE_INPUT_PORT, /* Normal (non-global) input ports */
MODULE_OUTPUT_PORT, /* Normal (non-global) output ports */ MODULE_OUTPUT_PORT, /* Normal (non-global) output ports */
MODULE_CLOCK_PORT, /* Nromal (non-global) clock ports*/ MODULE_CLOCK_PORT, /* Normal (non-global) clock ports*/
NUM_MODULE_PORT_TYPES NUM_MODULE_PORT_TYPES
}; };
/* A type to indicate the usage of module
* This helps FPGA-SPICE to identify which VDD/VSS
* port should be applied to modules
*/
enum e_module_usage_type {
MODULE_TOP, /* Top-level module */
MODULE_CONFIG, /* Configuration modules, i.e., decoders, sram etc. */
MODULE_INTERC, /* Programmable interconnection, e.g., routing multiplexer etc. */
MODULE_GRID, /* Grids (programmable blocks) */
MODULE_LUT, /* Look-Up Table (LUT) modules */
MODULE_HARD_IP, /* Hard IP modules */
MODULE_SB, /* Switch block modules */
MODULE_CB, /* Connection block modules */
MODULE_IO, /* I/O modules */
MODULE_VDD, /* Local VDD lines to generate constant voltages */
MODULE_VSS, /* Local VSS lines to generate constant voltages */
NUM_MODULE_USAGE_TYPES
};
public: /* Public Constructors */ public: /* Public Constructors */
public: /* Type implementations */ public: /* Type implementations */
@ -132,6 +155,7 @@ class ModuleManager {
size_t num_modules() const; size_t num_modules() const;
size_t num_nets(const ModuleId& module) const; size_t num_nets(const ModuleId& module) const;
std::string module_name(const ModuleId& module_id) const; std::string module_name(const ModuleId& module_id) const;
e_module_usage_type module_usage(const ModuleId& module_id) const;
std::string module_port_type_str(const enum e_module_port_type& port_type) 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; std::vector<BasicPort> module_ports_by_type(const ModuleId& module_id, const enum e_module_port_type& port_type) const;
std::vector<ModulePortId> module_port_ids_by_type(const ModuleId& module_id, const enum e_module_port_type& port_type) const; std::vector<ModulePortId> module_port_ids_by_type(const ModuleId& module_id, const enum e_module_port_type& port_type) const;
@ -199,6 +223,8 @@ class ModuleManager {
void set_module_port_name(const ModuleId& module, const ModulePortId& module_port, const std::string& port_name); void set_module_port_name(const ModuleId& module, const ModulePortId& module_port, const std::string& port_name);
/* Set a name for a module */ /* Set a name for a module */
void set_module_name(const ModuleId& module, const std::string& name); void set_module_name(const ModuleId& module, const std::string& name);
/* Set a usage for a module */
void set_module_usage(const ModuleId& module, const e_module_usage_type& usage);
/* Set a port to be a wire */ /* Set a port to be a wire */
void set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire); void set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire);
/* Set a port to be a register */ /* Set a port to be a register */
@ -266,7 +292,8 @@ class ModuleManager {
private: /* Internal data */ private: /* Internal data */
/* Module-level data */ /* Module-level data */
vtr::vector<ModuleId, ModuleId> ids_; /* Unique identifier for each Module */ 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::string> names_; /* Unique identifier for each Module */
vtr::vector<ModuleId, e_module_usage_type> usages_; /* Usage of each module */
vtr::vector<ModuleId, std::vector<ModuleId>> parents_; /* Parent modules that include the 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 */ vtr::vector<ModuleId, std::vector<ModuleId>> children_; /* Child modules that this module contain */
vtr::vector<ModuleId, std::vector<size_t>> num_child_instances_; /* Number of children instance in each child module */ vtr::vector<ModuleId, std::vector<size_t>> num_child_instances_; /* Number of children instance in each child module */

View File

@ -105,6 +105,26 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
ModuleId module = module_manager.add_module(module_name); ModuleId module = module_manager.add_module(module_name);
VTR_ASSERT(ModuleId::INVALID() != module); VTR_ASSERT(ModuleId::INVALID() != module);
/* Identify module usage based on circuit type:
* LUT, SRAM, CCFF, I/O have specific usages
* Others will be classified as hard IPs
*/
if (CIRCUIT_MODEL_LUT == circuit_lib.model_type(circuit_model)) {
module_manager.set_module_usage(module, ModuleManager::MODULE_LUT);
} else if (CIRCUIT_MODEL_SRAM == circuit_lib.model_type(circuit_model)) {
module_manager.set_module_usage(module, ModuleManager::MODULE_CONFIG);
} else if (CIRCUIT_MODEL_CCFF == circuit_lib.model_type(circuit_model)) {
module_manager.set_module_usage(module, ModuleManager::MODULE_CONFIG);
} else if (CIRCUIT_MODEL_IOPAD == circuit_lib.model_type(circuit_model)) {
module_manager.set_module_usage(module, ModuleManager::MODULE_IO);
} else if (CIRCUIT_MODEL_WIRE == circuit_lib.model_type(circuit_model)) {
module_manager.set_module_usage(module, ModuleManager::MODULE_INTERC);
} else if (CIRCUIT_MODEL_CHAN_WIRE == circuit_lib.model_type(circuit_model)) {
module_manager.set_module_usage(module, ModuleManager::MODULE_INTERC);
} else {
module_manager.set_module_usage(module, ModuleManager::MODULE_HARD_IP);
}
/* Add ports */ /* Add ports */
/* Find global ports and add one by one /* Find global ports and add one by one
* Non-I/O Global input ports will be considered as global port to be shorted wired in the context of module manager * Non-I/O Global input ports will be considered as global port to be shorted wired in the context of module manager

BIN
vpr/vpr

Binary file not shown.