refactoring analysis sdc generation

This commit is contained in:
tangxifan 2019-11-10 16:08:49 -07:00
parent 1f368abfbe
commit 67b3b25bea
4 changed files with 120 additions and 74 deletions

View File

@ -18,6 +18,7 @@
#include "sdc_writer_naming.h"
#include "sdc_writer_utils.h"
#include "sdc_memory_utils.h"
#include "analysis_sdc_writer.h"
@ -56,8 +57,9 @@ void print_analysis_sdc_io_delays(std::fstream& fp,
continue;
}
/* Update the operating port list */
operating_clock_ports.push_back(BasicPort(circuit_lib.port_prefix(clock_port), circuit_lib.port_size(clock_port)));
/* Find the module port and Update the operating port list */
ModulePortId module_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(clock_port));
operating_clock_ports.push_back(module_manager.module_port(top_module, module_port));
}
for (const BasicPort& operating_clock_port : operating_clock_ports) {
@ -151,6 +153,37 @@ void print_analysis_sdc_io_delays(std::fstream& fp,
fp << std::endl;
}
/********************************************************************
* Disable the timing for all the global port except the operating clock ports
*******************************************************************/
static
void print_analysis_sdc_disable_global_ports(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& top_module,
const CircuitLibrary& circuit_lib,
const std::vector<CircuitPortId>& global_ports) {
/* Validate file stream */
check_file_handler(fp);
/* Print comments */
fp << "##################################################" << std::endl;
fp << "# Disable timing for global ports " << std::endl;
fp << "##################################################" << std::endl;
for (const CircuitPortId& global_port : global_ports) {
/* Skip operating clock here! */
if ( (SPICE_MODEL_PORT_CLOCK == circuit_lib.port_type(global_port))
&& (false == circuit_lib.port_is_prog(global_port)) ) {
continue;
}
ModulePortId module_port = module_manager.find_module_port(top_module, circuit_lib.port_prefix(global_port));
BasicPort port_to_disable = module_manager.module_port(top_module, module_port);
print_sdc_disable_port_timing(fp, port_to_disable);
}
}
/********************************************************************
* Top-level function outputs a SDC file
* that constrain a FPGA fabric (P&Red netlist) using a benchmark
@ -197,27 +230,18 @@ void print_analysis_sdc(const std::string& sdc_dir,
circuit_lib, global_ports,
critical_path_delay);
/* TODO: Disable the timing for global ports */
/*
verilog_generate_sdc_disable_global_ports(fp);
*/
/* Disable the timing for global ports */
print_analysis_sdc_disable_global_ports(fp,
module_manager, top_module,
circuit_lib, global_ports);
/* Disable the timing for configuration cells */
rec_print_pnr_sdc_disable_configurable_memory_module_output(fp,
module_manager, top_module,
format_dir_path(module_manager.module_name(top_module)));
/* TODO: Disable the timing for configuration cells */
/*
verilog_generate_sdc_disable_sram_orgz(fp, cur_sram_orgz_info);
*/
/* TODO: Disable timing for un-used resources */
/* Apply to Routing Channels */
/*
if (TRUE == compact_routing_hierarchy) {
verilog_generate_sdc_disable_unused_routing_channels(fp, LL_nx, LL_ny);
} else {
verilog_generate_sdc_disable_unused_routing_channels(fp, LL_nx, LL_ny,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices);
}
*/
/* TODO: Apply to Connection blocks */
/*

View File

@ -23,6 +23,7 @@
#include "sdc_writer_naming.h"
#include "sdc_writer_utils.h"
#include "sdc_memory_utils.h"
#include "pnr_sdc_routing_writer.h"
#include "pnr_sdc_grid_writer.h"
#include "pnr_sdc_writer.h"
@ -142,60 +143,6 @@ void print_pnr_sdc_global_ports(const std::string& sdc_dir,
run_time_sec);
}
/********************************************************************
* Print SDC commands to disable outputs of all the configurable memory modules
* in a given module
* This function will be executed in a recursive way,
* using a Depth-First Search (DFS) strategy
* It will iterate over all the configurable children under each module
* and print a SDC command to disable its outputs
*******************************************************************/
static
void rec_print_pnr_sdc_disable_configurable_memory_module_output(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& parent_module,
const std::string& parent_module_path) {
/* For each configurable child, we will go one level down in priority */
for (size_t child_index = 0; child_index < module_manager.configurable_children(parent_module).size(); ++child_index) {
std::string child_module_path = parent_module_path;
ModuleId child_module_id = module_manager.configurable_children(parent_module)[child_index];
size_t child_instance_id = module_manager.configurable_child_instances(parent_module)[child_index];
if (true == module_manager.instance_name(parent_module, child_module_id, child_instance_id).empty()) {
/* Give a default name <module_name>_<instance_id>_ */
child_module_path += module_manager.module_name(child_module_id);
child_module_path += "_";
child_module_path += std::to_string(child_instance_id);
child_module_path += "_";
} else {
child_module_path += module_manager.instance_name(parent_module, child_module_id, child_instance_id);
}
child_module_path = format_dir_path(child_module_path);
rec_print_pnr_sdc_disable_configurable_memory_module_output(fp, module_manager,
child_module_id,
child_module_path);
}
/* If there is no configurable children any more, this is a leaf module, print a SDC command for disable timing */
if (0 < module_manager.configurable_children(parent_module).size()) {
return;
}
/* Validate file stream */
check_file_handler(fp);
/* Disable timing for each output port of this module */
for (const BasicPort& output_port : module_manager.module_ports_by_type(parent_module, ModuleManager::MODULE_OUTPUT_PORT)) {
for (const size_t& pin : output_port.pins()) {
BasicPort output_pin(output_port.get_name(), pin, pin);
fp << "set_disable_timing ";
fp << parent_module_path << generate_sdc_port(output_pin);
fp << std::endl;
}
}
}
/********************************************************************
* Break combinational loops in FPGA fabric, which mainly come from
* configurable memory cells.

View File

@ -0,0 +1,62 @@
/********************************************************************
* Most utilized function used to constrain memory cells in FPGA
* fabric using SDC commands
*******************************************************************/
#include "fpga_x2p_utils.h"
#include "sdc_writer_utils.h"
#include "sdc_memory_utils.h"
/********************************************************************
* Print SDC commands to disable outputs of all the configurable memory modules
* in a given module
* This function will be executed in a recursive way,
* using a Depth-First Search (DFS) strategy
* It will iterate over all the configurable children under each module
* and print a SDC command to disable its outputs
*******************************************************************/
void rec_print_pnr_sdc_disable_configurable_memory_module_output(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& parent_module,
const std::string& parent_module_path) {
/* For each configurable child, we will go one level down in priority */
for (size_t child_index = 0; child_index < module_manager.configurable_children(parent_module).size(); ++child_index) {
std::string child_module_path = parent_module_path;
ModuleId child_module_id = module_manager.configurable_children(parent_module)[child_index];
size_t child_instance_id = module_manager.configurable_child_instances(parent_module)[child_index];
if (true == module_manager.instance_name(parent_module, child_module_id, child_instance_id).empty()) {
/* Give a default name <module_name>_<instance_id>_ */
child_module_path += module_manager.module_name(child_module_id);
child_module_path += "_";
child_module_path += std::to_string(child_instance_id);
child_module_path += "_";
} else {
child_module_path += module_manager.instance_name(parent_module, child_module_id, child_instance_id);
}
child_module_path = format_dir_path(child_module_path);
rec_print_pnr_sdc_disable_configurable_memory_module_output(fp, module_manager,
child_module_id,
child_module_path);
}
/* If there is no configurable children any more, this is a leaf module, print a SDC command for disable timing */
if (0 < module_manager.configurable_children(parent_module).size()) {
return;
}
/* Validate file stream */
check_file_handler(fp);
/* Disable timing for each output port of this module */
for (const BasicPort& output_port : module_manager.module_ports_by_type(parent_module, ModuleManager::MODULE_OUTPUT_PORT)) {
for (const size_t& pin : output_port.pins()) {
BasicPort output_pin(output_port.get_name(), pin, pin);
fp << "set_disable_timing ";
fp << parent_module_path << generate_sdc_port(output_pin);
fp << std::endl;
}
}
}

View File

@ -0,0 +1,13 @@
#ifndef SDC_MEMORY_UTILS_H
#define SDC_MEMORY_UTILS_H
#include <fstream>
#include <string>
#include "module_manager.h"
void rec_print_pnr_sdc_disable_configurable_memory_module_output(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& parent_module,
const std::string& parent_module_path);
#endif