add pre-processing flag support for module manager

This commit is contained in:
tangxifan 2019-09-23 20:25:53 -06:00
parent feddcbcb21
commit e1742b68ef
4 changed files with 95 additions and 0 deletions

View File

@ -106,6 +106,13 @@ bool ModuleManager::port_is_register(const ModuleId& module, const ModulePortId&
return port_is_register_[module][port];
}
/* Return the pre-processing flag of a port */
std::string ModuleManager::port_preproc_flag(const ModuleId& module, const ModulePortId& port) const {
/* validate both module id and port id*/
VTR_ASSERT(valid_module_port_id(module, port));
return port_preproc_flags_[module][port];
}
/******************************************************************************
* Public Mutators
******************************************************************************/
@ -131,6 +138,7 @@ ModuleId ModuleManager::add_module(const std::string& name) {
ports_.emplace_back();
port_types_.emplace_back();
port_is_register_.emplace_back();
port_preproc_flags_.emplace_back();
/* Register in the name-to-id map */
name_id_map_[name] = module;
@ -155,6 +163,7 @@ ModulePortId ModuleManager::add_port(const ModuleId& module,
ports_[module].push_back(port_info);
port_types_[module].push_back(port_type);
port_is_register_[module].push_back(false);
port_preproc_flags_[module].emplace_back(); /* Create an empty string for the pre-processing flags */
/* Update fast look-up for port */
port_lookup_[module][port_type].push_back(port);
@ -178,6 +187,15 @@ void ModuleManager::set_port_is_register(const ModuleId& module, const std::stri
port_is_register_[module][port] = is_register;
}
/* Set the preprocessing flag for a port */
void ModuleManager::set_port_preproc_flag(const ModuleId& module, const std::string& port_name, const std::string& preproc_flag) {
/* Find the port */
ModulePortId port = find_module_port(module, port_name);
/* Must find something, otherwise drop an error */
VTR_ASSERT(ModulePortId::INVALID() != port);
port_preproc_flags_[module][port] = preproc_flag;
}
/* Add a child module to a parent module */
void ModuleManager::add_child_module(const ModuleId& parent_module, const ModuleId& child_module) {
/* Validate the id of both parent and child modules */

View File

@ -48,6 +48,8 @@ class ModuleManager {
size_t num_instance(const ModuleId& parent_module, const ModuleId& child_module) const;
/* Find if a port is register */
bool port_is_register(const ModuleId& module, const ModulePortId& port) const;
/* Return the pre-processing flag of a port */
std::string port_preproc_flag(const ModuleId& module, const ModulePortId& port) const;
public: /* Public mutators */
/* Add a module */
ModuleId add_module(const std::string& name);
@ -58,6 +60,8 @@ class ModuleManager {
void set_module_name(const ModuleId& module, const std::string& name);
/* Set a port to be a register */
void set_port_is_register(const ModuleId& module, const std::string& port_name, const bool& is_register);
/* Set the preprocessing flag for a port */
void set_port_preproc_flag(const ModuleId& module, const std::string& port_name, const std::string& preproc_flag);
/* Add a child module to a parent module */
void add_child_module(const ModuleId& parent_module, const ModuleId& child_module);
private: /* Private validators/invalidators */
@ -76,6 +80,7 @@ class ModuleManager {
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 */
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> */
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 */
/* fast look-up for module */
std::map<std::string, ModuleId> name_id_map_;

View File

@ -70,6 +70,25 @@ void print_verilog_comment(std::fstream& fp,
fp << "// " << comment << std::endl;
}
/************************************************
* Print the declaration of a Verilog preprocessing flag
***********************************************/
void print_verilog_preprocessing_flag(std::fstream& fp,
const std::string& preproc_flag) {
check_file_handler(fp);
fp << "`ifdef " << preproc_flag << std::endl;
}
/************************************************
* Print the endif of a Verilog preprocessing flag
***********************************************/
void print_verilog_endif(std::fstream& fp) {
check_file_handler(fp);
fp << "endif" << std::endl;
}
/************************************************
* Print a Verilog module definition
* We use the following format:
@ -100,6 +119,18 @@ void print_verilog_module_definition(std::fstream& fp,
/* Do not dump a comma for the first port */
fp << "," << std::endl;
}
ModulePortId port_id = module_manager.find_module_port(module_id, port.get_name());
VTR_ASSERT(ModulePortId::INVALID() != port_id);
/* Print pre-processing flag for a port, if defined */
std::string preproc_flag = module_manager.port_preproc_flag(module_id, port_id);
if (false == preproc_flag.empty()) {
/* Start a new line because an ifdef line will be outputted */
fp << std::endl;
/* Print an ifdef Verilog syntax */
print_verilog_preprocessing_flag(fp, preproc_flag);
}
/* Create a space for "module <module_name>" except the first line! */
if (0 != port_cnt) {
std::string port_whitespace(module_head_line.length(), ' ');
@ -107,6 +138,15 @@ void print_verilog_module_definition(std::fstream& fp,
}
/* Print port: only the port name is enough */
fp << port.get_name();
if (false == preproc_flag.empty()) {
/* Start a new line because an endif line will be outputted */
fp << std::endl;
/* Print an endif to pair the ifdef */
print_verilog_endif(fp);
}
/* Increase the counter */
port_cnt++;
}
}
@ -131,10 +171,24 @@ void print_verilog_module_ports(std::fstream& fp,
/* Port sequence: global, inout, input, output and clock ports, */
for (const auto& kv : port_type2type_map) {
for (const auto& port : module_manager.module_ports_by_type(module_id, kv.first)) {
ModulePortId port_id = module_manager.find_module_port(module_id, port.get_name());
VTR_ASSERT(ModulePortId::INVALID() != port_id);
/* Print pre-processing flag for a port, if defined */
std::string preproc_flag = module_manager.port_preproc_flag(module_id, port_id);
if (false == preproc_flag.empty()) {
/* Print an ifdef Verilog syntax */
print_verilog_preprocessing_flag(fp, preproc_flag);
}
/* Print port */
fp << "//----- " << module_manager.module_port_type_str(kv.first) << " -----" << std::endl;
fp << generate_verilog_port(kv.second, port);
fp << ";" << std::endl;
if (false == preproc_flag.empty()) {
/* Print an endif to pair the ifdef */
print_verilog_endif(fp);
}
}
}
@ -149,9 +203,22 @@ void print_verilog_module_ports(std::fstream& fp,
if (false == module_manager.port_is_register(module_id, port_id)) {
continue;
}
/* Print pre-processing flag for a port, if defined */
std::string preproc_flag = module_manager.port_preproc_flag(module_id, port_id);
if (false == preproc_flag.empty()) {
/* Print an ifdef Verilog syntax */
print_verilog_preprocessing_flag(fp, preproc_flag);
}
/* Print port */
fp << generate_verilog_port(VERILOG_PORT_REG, port);
fp << ";" << std::endl;
if (false == preproc_flag.empty()) {
/* Print an endif to pair the ifdef */
print_verilog_endif(fp);
}
}
}
fp << "//----- END Registered ports -----" << std::endl;

View File

@ -26,6 +26,11 @@ void print_verilog_include_defines_preproc_file(std::fstream& fp,
void print_verilog_comment(std::fstream& fp,
const std::string& comment);
void print_verilog_preprocessing_flag(std::fstream& fp,
const std::string& preproc_flag);
void print_verilog_endif(std::fstream& fp);
void print_verilog_module_definition(std::fstream& fp,
const ModuleManager& module_manager, const ModuleId& module_id);