adapt sdc writer utils

This commit is contained in:
tangxifan 2020-02-27 19:36:28 -07:00
parent 8322b1623d
commit 78476ca774
3 changed files with 284 additions and 0 deletions

View File

@ -0,0 +1,20 @@
#ifndef SDC_WRITER_NAMING_H
#define SDC_WRITER_NAMING_H
/* begin namespace openfpga */
namespace openfpga {
constexpr char* SDC_FILE_NAME_POSTFIX = ".sdc";
constexpr char* SDC_GLOBAL_PORTS_FILE_NAME = "global_ports.sdc";
constexpr char* SDC_BENCHMARK_ANALYSIS_FILE_NAME= "fpga_top_analysis.sdc";
constexpr char* SDC_DISABLE_CONFIG_MEM_OUTPUTS_FILE_NAME = "disable_configurable_memory_outputs.sdc";
constexpr char* SDC_DISABLE_MUX_OUTPUTS_FILE_NAME = "disable_routing_multiplexer_outputs.sdc";
constexpr char* SDC_DISABLE_SB_OUTPUTS_FILE_NAME = "disable_sb_outputs.sdc";
constexpr char* SDC_CB_FILE_NAME = "cb.sdc";
constexpr char* SDC_ANALYSIS_FILE_NAME = "fpga_top_analysis.sdc";
} /* end namespace openfpga */
#endif

View File

@ -0,0 +1,202 @@
/********************************************************************
* This file include most utilized functions to be used in SDC writers
*******************************************************************/
#include <chrono>
#include <ctime>
#include <iomanip>
/* Headers from openfpgautil library */
#include "openfpga_digest.h"
#include "sdc_writer_utils.h"
/* begin namespace openfpga */
namespace openfpga {
/********************************************************************
* Write a head (description) in SDC file
*******************************************************************/
void print_sdc_file_header(std::fstream& fp,
const std::string& usage) {
valid_file_stream(fp);
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
fp << "#############################################" << std::endl;
fp << "#\tSynopsys Design Constraints (SDC)" << std::endl;
fp << "#\tFor FPGA fabric " << std::endl;
fp << "#\tDescription: " << usage << std::endl;
fp << "#\tAuthor: Xifan TANG " << std::endl;
fp << "#\tOrganization: University of Utah " << std::endl;
fp << "#\tDate: " << std::ctime(&end_time);
fp << "#############################################" << std::endl;
fp << std::endl;
}
/********************************************************************
* Write a port in SDC format
*******************************************************************/
std::string generate_sdc_port(const BasicPort& port) {
std::string sdc_line;
std::string size_str = "[" + std::to_string(port.get_lsb()) + ":" + std::to_string(port.get_msb()) + "]";
/* Only connection require a format of <port_name>[<lsb>:<msb>]
* others require a format of <port_type> [<lsb>:<msb>] <port_name>
*/
/* When LSB == MSB, we can use a simplified format <port_type>[<lsb>]*/
if ( 1 == port.get_width()) {
size_str = "[" + std::to_string(port.get_lsb()) + "]";
}
sdc_line = port.get_name() + size_str;
return sdc_line;
}
/********************************************************************
* Constrain a path between two ports of a module with a given maximum timing value
*******************************************************************/
void print_pnr_sdc_constrain_max_delay(std::fstream& fp,
const std::string& src_instance_name,
const std::string& src_port_name,
const std::string& des_instance_name,
const std::string& des_port_name,
const float& delay) {
/* Validate file stream */
valid_file_stream(fp);
fp << "set_max_delay";
fp << " -from ";
if (!src_instance_name.empty()) {
fp << src_instance_name << "/";
}
fp << src_port_name;
fp << " -to ";
if (!des_instance_name.empty()) {
fp << des_instance_name << "/";
}
fp << des_port_name;
fp << " " << std::setprecision(10) << delay;
fp << std::endl;
}
/********************************************************************
* Constrain a path between two ports of a module with a given timing value
* Note: this function uses set_max_delay !!!
*******************************************************************/
void print_pnr_sdc_constrain_module_port2port_timing(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& input_parent_module_id,
const ModulePortId& module_input_port_id,
const ModuleId& output_parent_module_id,
const ModulePortId& module_output_port_id,
const float& tmax) {
print_pnr_sdc_constrain_max_delay(fp,
module_manager.module_name(input_parent_module_id),
generate_sdc_port(module_manager.module_port(input_parent_module_id, module_input_port_id)),
module_manager.module_name(output_parent_module_id),
generate_sdc_port(module_manager.module_port(output_parent_module_id, module_output_port_id)),
tmax);
}
/********************************************************************
* Constrain a path between two ports of a module with a given timing value
* This function will NOT output the module name
* Note: this function uses set_max_delay !!!
*******************************************************************/
void print_pnr_sdc_constrain_port2port_timing(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& input_parent_module_id,
const ModulePortId& module_input_port_id,
const ModuleId& output_parent_module_id,
const ModulePortId& module_output_port_id,
const float& tmax) {
print_pnr_sdc_constrain_max_delay(fp,
std::string(),
generate_sdc_port(module_manager.module_port(input_parent_module_id, module_input_port_id)),
std::string(),
generate_sdc_port(module_manager.module_port(output_parent_module_id, module_output_port_id)),
tmax);
}
/********************************************************************
* Disable timing for a port
*******************************************************************/
void print_sdc_disable_port_timing(std::fstream& fp,
const BasicPort& port) {
/* Validate file stream */
valid_file_stream(fp);
fp << "set_disable_timing ";
fp << generate_sdc_port(port);
fp << std::endl;
}
/********************************************************************
* Set the input delay for a port in SDC format
* Note that the input delay will be bounded by a clock port
*******************************************************************/
void print_sdc_set_port_input_delay(std::fstream& fp,
const BasicPort& port,
const BasicPort& clock_port,
const float& delay) {
/* Validate file stream */
valid_file_stream(fp);
fp << "set_input_delay ";
fp << "-clock ";
fp << generate_sdc_port(clock_port);
fp << " -max ";
fp << std::setprecision(10) << delay;
fp << " ";
fp << generate_sdc_port(port);
fp << std::endl;
}
/********************************************************************
* Set the output delay for a port in SDC format
* Note that the output delay will be bounded by a clock port
*******************************************************************/
void print_sdc_set_port_output_delay(std::fstream& fp,
const BasicPort& port,
const BasicPort& clock_port,
const float& delay) {
/* Validate file stream */
valid_file_stream(fp);
fp << "set_output_delay ";
fp << "-clock ";
fp << generate_sdc_port(clock_port);
fp << " -max ";
fp << std::setprecision(10) << delay;
fp << " ";
fp << generate_sdc_port(port);
fp << std::endl;
}
} /* end namespace openfpga */

View File

@ -0,0 +1,62 @@
#ifndef SDC_WRITER_UTILS_H
#define SDC_WRITER_UTILS_H
/********************************************************************
* Include header files that are required by function declaration
*******************************************************************/
#include <fstream>
#include <string>
#include "openfpga_port.h"
#include "module_manager.h"
/********************************************************************
* Function declaration
*******************************************************************/
/* begin namespace openfpga */
namespace openfpga {
void print_sdc_file_header(std::fstream& fp,
const std::string& usage);
std::string generate_sdc_port(const BasicPort& port);
void print_pnr_sdc_constrain_max_delay(std::fstream& fp,
const std::string& src_instance_name,
const std::string& src_port_name,
const std::string& des_instance_name,
const std::string& des_port_name,
const float& delay);
void print_pnr_sdc_constrain_module_port2port_timing(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& input_parent_module_id,
const ModulePortId& module_input_port_id,
const ModuleId& output_parent_module_id,
const ModulePortId& module_output_port_id,
const float& tmax);
void print_pnr_sdc_constrain_port2port_timing(std::fstream& fp,
const ModuleManager& module_manager,
const ModuleId& input_parent_module_id,
const ModulePortId& module_input_port_id,
const ModuleId& output_parent_module_id,
const ModulePortId& module_output_port_id,
const float& tmax);
void print_sdc_disable_port_timing(std::fstream& fp,
const BasicPort& port);
void print_sdc_set_port_input_delay(std::fstream& fp,
const BasicPort& port,
const BasicPort& clock_port,
const float& delay);
void print_sdc_set_port_output_delay(std::fstream& fp,
const BasicPort& port,
const BasicPort& clock_port,
const float& delay);
} /* end namespace openfpga */
#endif