add module usage types for future FPGA-SPICE development
This commit is contained in:
parent
ece262f544
commit
83e26adf90
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue