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 */
ModuleId module_id = module_manager.add_module(module_name);
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 each input port */
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 */
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);
/* 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! */
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.
* 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
@ -858,6 +861,9 @@ void rec_build_logical_tile_modules(ModuleManager& module_manager,
ModuleId pb_module = module_manager.add_module(pb_module_name);
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_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 */
ModuleId lut_module = module_manager.add_module(circuit_lib.model_name(lut_model));
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 each global port */
for (const auto& port : lut_global_ports) {

View File

@ -323,6 +323,9 @@ void build_memory_flatten_module(ModuleManager& module_manager,
ModuleId mem_module = module_manager.add_module(module_name);
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 */
/* Input: BL port */
BasicPort bl_port(std::string(MEMORY_BL_PORT_NAME), num_mems);
@ -405,6 +408,9 @@ void build_memory_chain_module(ModuleManager& module_manager,
ModuleId mem_module = module_manager.add_module(module_name);
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 */
/* TODO: restriction!!!
* consider only the first input of the CCFF model as the D port,
@ -542,6 +548,9 @@ void build_frame_memory_module(ModuleManager& module_manager,
ModuleId mem_module = module_manager.add_module(module_name);
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:
* 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 */
ModuleId mux_module = module_manager.add_module(module_name);
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 each input port
* 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 */
ModuleId module_id = module_manager.add_module(module_name);
VTR_ASSERT(ModuleId::INVALID() != module_id);
/* Label module usage */
module_manager.set_module_usage(module_id, ModuleManager::MODULE_INTERC);
/* Add module ports */
/* Add each global port */
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());
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,
"Building module '%s'...",
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 */
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,
"Building module '%s'...",
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();
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;
/* 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];
}
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 */
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"}};
@ -469,6 +475,7 @@ ModuleId ModuleManager::add_module(const std::string& name) {
/* Allocate other attributes */
names_.push_back(name);
usages_.push_back(NUM_MODULE_USAGE_TYPES);
parents_.emplace_back();
children_.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;
}
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 */
void ModuleManager::set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire) {
/* Find the port */

View File

@ -30,6 +30,10 @@ namespace openfpga {
******************************************************************************/
class ModuleManager {
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 {
MODULE_GLOBAL_PORT, /* Global inputs */
MODULE_GPIN_PORT, /* General-purpose input */
@ -38,10 +42,29 @@ class ModuleManager {
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*/
MODULE_CLOCK_PORT, /* Normal (non-global) clock ports*/
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: /* Type implementations */
@ -132,6 +155,7 @@ class ModuleManager {
size_t num_modules() const;
size_t num_nets(const ModuleId& module) 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::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;
@ -199,6 +223,8 @@ class ModuleManager {
void set_module_port_name(const ModuleId& module, const ModulePortId& module_port, const std::string& port_name);
/* Set a name for a module */
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 */
void set_port_is_wire(const ModuleId& module, const std::string& port_name, const bool& is_wire);
/* Set a port to be a register */
@ -266,7 +292,8 @@ class ModuleManager {
private: /* Internal data */
/* Module-level data */
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>> 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 */

View File

@ -105,6 +105,26 @@ ModuleId add_circuit_model_to_module_manager(ModuleManager& module_manager,
ModuleId module = module_manager.add_module(module_name);
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 */
/* 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

BIN
vpr/vpr

Binary file not shown.