forked from OSchip/iEDA
commit
1d058137ad
|
|
@ -18,23 +18,15 @@
|
|||
cmake_minimum_required(VERSION 3.11)
|
||||
project(iEDA)
|
||||
|
||||
# option setting
|
||||
option(BUILD_PR_FLOW "If ON, build PR flow." ON)
|
||||
option(BUILD_STATIC_LIB "If ON, build static lib." ON)
|
||||
|
||||
if(NOT BUILD_STATIC_LIB)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
|
||||
option(BUILD_PYTHON "If ON, build python interface." OFF)
|
||||
# option(BUILD_PYTHON "If ON, build python lib." ON)
|
||||
if(BUILD_PYTHON)
|
||||
set(BUILD_STATIC_LIB OFF)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
option(BUILD_GUI "If ON, build GUI." ON)
|
||||
|
||||
# add_subdirectory(src/third_party/mt-kahypar)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_VERBOSE_MAKEFILE OFF)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
|
@ -42,12 +34,9 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
set(FORT_ENABLE_TESTING OFF CACHE INTERNAL "") # Disable building tests and examples in libfort project
|
||||
|
||||
# SET(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS} -fPIC")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
# set(CMAKE_BUILD_TYPE "Debug")
|
||||
#set(BUILD_SHARED_LIBS ON)
|
||||
|
||||
if(NOT DEFINED CMD_BUILD)
|
||||
set(SANITIZER OFF)
|
||||
|
|
@ -62,6 +51,11 @@ if(SANITIZER)
|
|||
message("address sanitizer load")
|
||||
endif()
|
||||
|
||||
set(USE_GPU OFF)
|
||||
if (USE_GPU)
|
||||
add_definitions(-DUSE_GPU)
|
||||
endif()
|
||||
|
||||
include(cmake/setting.cmake)
|
||||
include(cmake/third_party.cmake)
|
||||
include(cmake/operation/ista.cmake)
|
||||
|
|
|
|||
2
build.sh
2
build.sh
|
|
@ -123,7 +123,7 @@ install_dependencies_apt()
|
|||
apt-get update && apt-get install -y \
|
||||
g++-10 cmake ninja-build \
|
||||
tcl-dev libgflags-dev libgoogle-glog-dev libboost-all-dev libgtest-dev flex\
|
||||
libeigen3-dev libyaml-cpp-dev libunwind-dev libmetis-dev libgmp-dev bison rustc cargo\
|
||||
libeigen3-dev libunwind-dev libmetis-dev libgmp-dev bison rustc cargo\
|
||||
libhwloc-dev libcairo2-dev
|
||||
exit 0
|
||||
else
|
||||
|
|
|
|||
|
|
@ -44,5 +44,6 @@
|
|||
"number_of_decreasing_slack_iter": 5,
|
||||
"max_allowed_buffering_fanout": 20,
|
||||
"min_divide_fanout": 8,
|
||||
"optimize_endpoints_percent": 1.0
|
||||
"optimize_endpoints_percent": 1.0,
|
||||
"drv_optimize_iter_number": 5
|
||||
}
|
||||
|
|
@ -44,5 +44,6 @@
|
|||
"number_of_decreasing_slack_iter": 5,
|
||||
"max_allowed_buffering_fanout": 20,
|
||||
"min_divide_fanout": 8,
|
||||
"optimize_endpoints_percent": 1.0
|
||||
"optimize_endpoints_percent": 1.0,
|
||||
"drv_optimize_iter_number": 5
|
||||
}
|
||||
|
|
@ -44,5 +44,6 @@
|
|||
"number_of_decreasing_slack_iter": 5,
|
||||
"max_allowed_buffering_fanout": 20,
|
||||
"min_divide_fanout": 8,
|
||||
"optimize_endpoints_percent": 1.0
|
||||
"optimize_endpoints_percent": 1.0,
|
||||
"drv_optimize_iter_number": 5
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ def_init -path [expr {[info exists ::env(INPUT_DEF)]? $::env(INPUT_DEF) : $DEFAU
|
|||
## Full layer information instance:(-discard li/mcon/nwell/pwell/met/via)
|
||||
## use (-discard null) to choose all layer
|
||||
#===========================================================
|
||||
json_save -path $::env(GDS_JSON_FILE) -discard li
|
||||
json_save -path $::env(LAYOUT_JSON_FILE) -discard li
|
||||
|
||||
#===========================================================
|
||||
## Exit
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ source $::env(TCL_SCRIPT_DIR)/DB_script/db_init_lef.tcl
|
|||
#===========================================================
|
||||
## read def
|
||||
#===========================================================
|
||||
set DEFAULT_OUTPUT_DEF "$::env(RESULT_DIR)/iPL_lg_result.def"
|
||||
def_init -path [expr {[info exists ::env(OUTPUT_DEF)] ? $::env(OUTPUT_DEF) : $DEFAULT_OUTPUT_DEF}]
|
||||
set DEFAULT_INPUT_DEF "$::env(RESULT_DIR)/iPL_lg_result.def"
|
||||
def_init -path [expr {[info exists ::env(INPUT_DEF)] ? $::env(INPUT_DEF) : $DEFAULT_INPUT_DEF}]
|
||||
|
||||
#===========================================================
|
||||
## run Router
|
||||
|
|
|
|||
|
|
@ -423,11 +423,21 @@ void IdbPin::set_port_vias()
|
|||
for_each(_via_list.begin(), _via_list.end(), [](IdbVia*& via) { delete via; });
|
||||
_via_list.clear();
|
||||
|
||||
auto cloneVia = [](IdbVia* via, int32_t x_off = 0, int32_t y_off = 0) {
|
||||
auto cloneVia = [&](IdbVia* via, int32_t x_off = 0, int32_t y_off = 0) {
|
||||
auto* pin_via = via->clone();
|
||||
auto* coord = pin_via->get_coordinate();
|
||||
coord->get_x() += x_off;
|
||||
coord->get_y() += y_off;
|
||||
|
||||
if (!is_io_pin()) {
|
||||
IdbOrientTransform db_transform(_instance->get_orient(), _instance->get_coordinate(), _instance->get_cell_master()->get_width(),
|
||||
_instance->get_cell_master()->get_height());
|
||||
db_transform.transformCoordinate(coord);
|
||||
} else {
|
||||
IdbOrientTransform db_transform(this->get_orient(), this->get_location(), 0, 0);
|
||||
db_transform.transformCoordinate(coord);
|
||||
}
|
||||
|
||||
return pin_via;
|
||||
};
|
||||
if (is_io_pin()) {
|
||||
|
|
|
|||
|
|
@ -733,8 +733,11 @@ int32_t RustVerilogRead::build_components()
|
|||
net_name = rust_convert_verilog_id(net_id)->id;
|
||||
} else if (rust_is_bus_index_id(net_id)) {
|
||||
net_name = rust_convert_verilog_index_id(net_id)->id;
|
||||
} else {
|
||||
} else if (rust_is_bus_slice_id(net_id)) {
|
||||
net_name = rust_convert_verilog_slice_id(net_id)->id;
|
||||
} else {
|
||||
static int index = 0;
|
||||
net_name = ieda::Str::printf("IEDA_CONST_%d", index++);
|
||||
}
|
||||
add_pin(net_name, idb_pin);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
#include <string.h>
|
||||
// #include "/home/shuyuz/iEDA/src/platform/data_manager/idm.h"
|
||||
#include <fstream>
|
||||
#define sref_expension 1
|
||||
#define sref_expension 0
|
||||
namespace idb {
|
||||
|
||||
JsonTextWriter::JsonTextWriter()
|
||||
|
|
@ -519,9 +519,10 @@ void JsonTextWriter::write_struct_element(JsonElemBase* e,int i,bool out) const
|
|||
case JsonElemType::kPath:
|
||||
write_path(dynamic_cast<JsonPath*>(e),i+1,out);
|
||||
break;
|
||||
case JsonElemType::kSref:
|
||||
write_sref(dynamic_cast<JsonSref*>(e),i+1,out);
|
||||
break;
|
||||
// block sref printing for json
|
||||
// case JsonElemType::kSref:
|
||||
// write_sref(dynamic_cast<JsonSref*>(e),i+1,out);
|
||||
// break;
|
||||
case JsonElemType::kAref:
|
||||
write_aref(dynamic_cast<JsonAref*>(e),i+1,out);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -22,13 +22,12 @@
|
|||
* @date 2023-10-13
|
||||
*
|
||||
*/
|
||||
#include "LibParserRustC.hh"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "BTreeMap.hh"
|
||||
#include "BTreeSet.hh"
|
||||
#include "Lib.hh"
|
||||
#include "LibParserRustC.hh"
|
||||
#include "log/Log.hh"
|
||||
|
||||
namespace ista {
|
||||
|
|
@ -653,9 +652,14 @@ unsigned RustLibertyReader::visitComplexAttri(
|
|||
|
||||
if (process_attri.contains(attri_name)) {
|
||||
process_attri[attri_name]();
|
||||
} else {
|
||||
} else if (Str::startWith(attri_name, "index") ||
|
||||
Str::equal(attri_name, "values")) {
|
||||
is_ok = visitAxisOrValues(attri);
|
||||
}
|
||||
else {
|
||||
LOG_INFO_EVERY_N(10) << "unkown attri name: " << attri_name << " in "
|
||||
<< attri->file_name << " line no " << attri->line_no;
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
|
|
@ -1236,6 +1240,7 @@ unsigned RustLibertyReader::visitGroup(RustLibertyGroupStmt* group) {
|
|||
{"leakage_power",
|
||||
std::bind(&RustLibertyReader::visitLeakagePower, this, _1)},
|
||||
{"bus", std::bind(&RustLibertyReader::visitBus, this, _1)},
|
||||
{"bundle", std::bind(&RustLibertyReader::visitBus, this, _1)},
|
||||
{"pin", std::bind(&RustLibertyReader::visitPin, this, _1)},
|
||||
{"timing", std::bind(&RustLibertyReader::visitTiming, this, _1)},
|
||||
{"internal_power",
|
||||
|
|
@ -1277,13 +1282,12 @@ unsigned RustLibertyReader::readLib() {
|
|||
|
||||
LOG_INFO << "load liberty file " << _file_name << " success.";
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief link the lib to construct the data.
|
||||
*
|
||||
* @return unsigned
|
||||
*
|
||||
* @return unsigned
|
||||
*/
|
||||
unsigned RustLibertyReader::linkLib() {
|
||||
LOG_INFO << "link liberty file " << _file_name << " start.";
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ multiline_string = !{ "\\"? ~ oneline_string ~ ("," ~ "\\" ~ oneline_string)* }
|
|||
|
||||
semicolon = _{ ";" }
|
||||
|
||||
expr_operator = _{ "+" | "-" | "*" | "/" }
|
||||
expr_operator = { "+" | "-" | "*" | "/" | "!" }
|
||||
expr_token = ${ float ~ string? | string }
|
||||
simple_attribute_value = _{ expr_token ~ (expr_operator ~ expr_token)? }
|
||||
simple_attribute_value = _{ expr_operator? ~ expr_token ~ (expr_operator ~ expr_operator? ~ expr_token)* }
|
||||
|
||||
id = { lib_id ~ bus_index? ~ (bus_index | bus_slice)? }
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ fn process_multiline_string(
|
|||
fn process_string(pair: Pair<Rule>) -> Result<liberty_data::LibertyParserData, pest::error::Error<Rule>> {
|
||||
let pair_span = pair.as_span();
|
||||
|
||||
// let pair_clone = pair.clone();
|
||||
|
||||
// println!("Rule: {:?}", pair_clone.as_rule());
|
||||
// println!("Span: {:?}", pair_clone.as_span());
|
||||
// println!("Text: {}", pair_clone.as_str());
|
||||
|
|
@ -127,11 +129,28 @@ fn process_simple_attribute(
|
|||
let attribute_value = parser_queue.pop_front().unwrap();
|
||||
match attribute_value {
|
||||
liberty_data::LibertyParserData::String(s) => {
|
||||
// maybe more string value as expr.
|
||||
let mut expr_value = s.get_string_value().to_string();
|
||||
while !parser_queue.is_empty() {
|
||||
let string_value = parser_queue.pop_front().unwrap();
|
||||
|
||||
match string_value {
|
||||
liberty_data::LibertyParserData::String(more_str) => {
|
||||
expr_value = expr_value + more_str.get_string_value();
|
||||
}
|
||||
liberty_data::LibertyParserData::Float(more_str) => {
|
||||
let the_float_str_value = more_str.get_float_value().to_string();
|
||||
expr_value = expr_value + the_float_str_value.as_str();
|
||||
}
|
||||
_ => panic!("should be string type"),
|
||||
}
|
||||
}
|
||||
|
||||
let simple_stmt = liberty_data::LibertySimpleAttrStmt::new(
|
||||
file_name,
|
||||
line_no,
|
||||
lib_id,
|
||||
Box::new(s) as Box<dyn liberty_data::LibertyAttrValue>,
|
||||
Box::new(liberty_data::LibertyStringValue{value: expr_value}) as Box<dyn liberty_data::LibertyAttrValue>,
|
||||
);
|
||||
Ok(liberty_data::LibertyParserData::SimpleStmt(simple_stmt))
|
||||
}
|
||||
|
|
@ -236,6 +255,7 @@ fn process_pair(
|
|||
parser_queue.push_back(pair_result.unwrap());
|
||||
}
|
||||
|
||||
// let pair_clone = pair.clone();
|
||||
// println!("Rule: {:?}", pair_clone.as_rule());
|
||||
// println!("Span: {:?}", pair_clone.as_span());
|
||||
// println!("Text: {}", pair_clone.as_str());
|
||||
|
|
@ -248,6 +268,7 @@ fn process_pair(
|
|||
match pair.as_rule() {
|
||||
Rule::float => process_float(pair),
|
||||
Rule::string_text => process_string_text(pair),
|
||||
Rule::expr_operator => process_string(pair),
|
||||
Rule::id => process_string(pair),
|
||||
Rule::multiline_string => process_multiline_string(&mut substitute_queue),
|
||||
Rule::expr_token => process_expr_token(pair, &mut substitute_queue),
|
||||
|
|
@ -362,7 +383,7 @@ mod tests {
|
|||
Ok(pairs) => {
|
||||
for pair in pairs {
|
||||
let data = process_pair(pair, "tbd", &mut parser_queue);
|
||||
println!("Error: {:#?}", data);
|
||||
println!("OK: {:#?}", data);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
|
|
@ -468,7 +489,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_parse_simple_attribute() {
|
||||
let input_str = r#"leakage_power_unit : 1nW;"#;
|
||||
let input_str = r#"power_down_function : !VDD+!VDDD+VSSD;"#;
|
||||
let parse_result = LibertyParser::parse(Rule::simple_attribute, input_str);
|
||||
|
||||
test_process_parse_result(parse_result);
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ void rust_free_spef_net_cap_res(void*);
|
|||
|
||||
typedef struct RustSpefCoord
|
||||
{
|
||||
double _x;
|
||||
double _y;
|
||||
double _x = 0.0;
|
||||
double _y = 0.0;
|
||||
} RustSpefCoord;
|
||||
|
||||
enum RustConnectionDirection
|
||||
|
|
|
|||
|
|
@ -11,13 +11,16 @@ header_text = _{ (!"$" ~ ANY)+ }
|
|||
date_text = { header_text }
|
||||
date = _{ "$date" ~ date_text ~ "$end" }
|
||||
|
||||
version_text = { header_text }
|
||||
version = _{ "$version" ~ version_text ~ "$end" }
|
||||
|
||||
timescale = _{ "$timescale" ~ scale_text ~ "$end" }
|
||||
|
||||
comment_text = { header_text }
|
||||
vcd_comment = _{ "$comment" ~ comment_text ~ "$end" }
|
||||
|
||||
header_section = _{
|
||||
date ~ timescale ~ vcd_comment
|
||||
date ~ version? ~ timescale ~ vcd_comment?
|
||||
}
|
||||
|
||||
/* definition */
|
||||
|
|
@ -65,12 +68,12 @@ close_scope = { "$upscope" ~ "$end" }
|
|||
scope = _{ open_scope ~ (scope | variable)+ ~ close_scope }
|
||||
scopes = _{ scope+ }
|
||||
|
||||
variable_definition_section = _{ scopes ~ "$enddefinitions" ~ "$end" }
|
||||
variable_definition_section = _{ scopes ~ "$enddefinitions" ~ "$end" ~ vcd_comment?}
|
||||
|
||||
/* change */
|
||||
scalar_num = { "0" | "1" | "x" | "X" | "z" | "Z" }
|
||||
|
||||
bin_num_text = { scalar_num+ }
|
||||
bin_num_text = @{ scalar_num+ }
|
||||
bin_num = _{ ("b" | "B") ~ bin_num_text }
|
||||
real_num = {
|
||||
("r" | "R") ~ ("-")? ~ ASCII_DIGIT+ ~ (("e" | "E") ~ ("+" | "-")? ~ ASCII_DIGIT+)?
|
||||
|
|
@ -87,7 +90,7 @@ vector_value_change = _{ bitvector_value_change | real_value_change }
|
|||
signal_value_change = _{ scalar_value_change | vector_value_change }
|
||||
|
||||
value_change = _{
|
||||
simulation_time ~ simulation_keyword ~ (signal_value_change)* ~ "$end"
|
||||
simulation_time? ~ simulation_keyword ~ (signal_value_change)* ~ "$end"
|
||||
| simulation_time ~ (signal_value_change)*
|
||||
}
|
||||
value_change_section = _{ value_change+ }
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ fn process_date(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileParser)
|
|||
vcd_file.set_date(date_text);
|
||||
}
|
||||
|
||||
fn process_version(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileParser) {
|
||||
let version_text = pair.as_str().parse::<String>().unwrap();
|
||||
let vcd_file = vcd_file_parser.get_vcd_file();
|
||||
vcd_file.set_date(version_text);
|
||||
}
|
||||
|
||||
/// process scale number.
|
||||
fn process_scale_number(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileParser) {
|
||||
let scale_number = pair.as_str().parse::<u32>().unwrap();
|
||||
|
|
@ -63,6 +69,8 @@ fn process_open_scope(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileP
|
|||
let pair_module = inner_pairs.next_back().unwrap();
|
||||
let module_name = pair_module.as_str();
|
||||
|
||||
println!("scope module: {}", module_name);
|
||||
|
||||
let new_scope: Rc<RefCell<vcd_data::VCDScope>> = Rc::new(RefCell::new(
|
||||
vcd_data::VCDScope::new(String::from(module_name)),
|
||||
));
|
||||
|
|
@ -78,10 +86,12 @@ fn process_open_scope(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileP
|
|||
.set_parent_scope(Rc::clone(&*parent_scope));
|
||||
|
||||
parent_scope.borrow_mut().add_child_scope(new_scope);
|
||||
|
||||
scope_stack.push_back(new_scope_copy);
|
||||
} else {
|
||||
vcd_file_parser.set_root_scope(new_scope);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// process signal variable.
|
||||
|
|
@ -126,7 +136,10 @@ fn process_variable(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFilePar
|
|||
/// process close scope.
|
||||
fn process_close_scope(_pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileParser) {
|
||||
let scope_stack = vcd_file_parser.get_scope_stack();
|
||||
scope_stack.pop_back();
|
||||
if !scope_stack.is_empty() {
|
||||
scope_stack.pop_back();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// process simulate time.
|
||||
|
|
@ -146,7 +159,7 @@ fn process_scalar_value_change(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data:
|
|||
"1" => vcd_data::VCDBit::BitOne,
|
||||
"x" | "X" => vcd_data::VCDBit::BitX,
|
||||
"z" | "Z" => vcd_data::VCDBit::BitZ,
|
||||
_ => panic!("unkown value"),
|
||||
_ => panic!("unkown value {}", scalar_value_pair.as_str()),
|
||||
};
|
||||
let hash_pair = scalar_value_change_pairs.next_back().unwrap();
|
||||
let hash_str = String::from(hash_pair.as_str());
|
||||
|
|
@ -165,9 +178,16 @@ fn process_scalar_value_change(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data:
|
|||
|
||||
/// process vector value change.
|
||||
fn process_bitvector_value_change(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileParser) {
|
||||
let line_no = pair.line_col().0;
|
||||
// let pair_clone = pair.clone();
|
||||
// println!("Rule: {:?}", pair_clone.as_rule());
|
||||
// println!("Span: {:?}", pair_clone.as_span());
|
||||
// println!("Text: {}", pair_clone.as_str());
|
||||
|
||||
let mut bitvector_value_change_pairs = pair.into_inner().into_iter();
|
||||
let bitvector_value_pair = bitvector_value_change_pairs.next().unwrap();
|
||||
let bitvector_value_str = bitvector_value_pair.as_str();
|
||||
// println!("bitvector_value_str {} len {}", bitvector_value_str,bitvector_value_str.len());
|
||||
|
||||
let mut vcd_bit_vec: Vec<vcd_data::VCDBit> = Vec::with_capacity(bitvector_value_str.len());
|
||||
for bit in bitvector_value_str.chars() {
|
||||
|
|
@ -176,7 +196,7 @@ fn process_bitvector_value_change(pair: Pair<Rule>, vcd_file_parser: &mut vcd_da
|
|||
'1' => vcd_data::VCDBit::BitOne,
|
||||
'x' | 'X' => vcd_data::VCDBit::BitX,
|
||||
'z' | 'Z' => vcd_data::VCDBit::BitZ,
|
||||
_ => panic!("unkown value"),
|
||||
_ => panic!("unkown value {} in {}", bit, line_no),
|
||||
};
|
||||
|
||||
vcd_bit_vec.push(bit_value);
|
||||
|
|
@ -221,14 +241,15 @@ fn process_real_value_change(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::V
|
|||
|
||||
/// process vcd data.
|
||||
fn process_vcd(pair: Pair<Rule>, vcd_file_parser: &mut vcd_data::VCDFileParser) {
|
||||
let pair_clone = pair.clone();
|
||||
println!("Rule: {:?}", pair_clone.as_rule());
|
||||
println!("Span: {:?}", pair_clone.as_span());
|
||||
println!("Text: {}", pair_clone.as_str());
|
||||
// let pair_clone = pair.clone();
|
||||
// println!("Rule: {:?}", pair_clone.as_rule());
|
||||
// println!("Span: {:?}", pair_clone.as_span());
|
||||
// println!("Text: {}", pair_clone.as_str());
|
||||
|
||||
for inner_pair in pair.into_inner() {
|
||||
match inner_pair.as_rule() {
|
||||
Rule::date_text => process_date(inner_pair, vcd_file_parser),
|
||||
Rule::version_text => process_version(inner_pair, vcd_file_parser),
|
||||
Rule::scale_text => process_scale(inner_pair, vcd_file_parser),
|
||||
Rule::comment_text => process_comment(inner_pair, vcd_file_parser),
|
||||
Rule::open_scope => process_open_scope(inner_pair, vcd_file_parser),
|
||||
|
|
|
|||
|
|
@ -74,14 +74,19 @@ pub trait VcdCounter {
|
|||
return false;
|
||||
}
|
||||
|
||||
let default_bit_value = VCDBit::BitZero;
|
||||
|
||||
let pre_bit_value = match &pre_time_value.value {
|
||||
VCDValue::BitScalar(bit) => Ok(bit),
|
||||
VCDValue::BitVector(vec) => {
|
||||
if let Some(index) = bus_index {
|
||||
Ok(&vec[index as usize])
|
||||
VCDValue::BitVector(bit_vec) => {
|
||||
let index = bus_index.unwrap() as usize;
|
||||
|
||||
let bit_value = if index < bit_vec.len() {
|
||||
&bit_vec[index as usize]
|
||||
} else {
|
||||
Err("No bus index provided")
|
||||
}
|
||||
&default_bit_value
|
||||
};
|
||||
Ok(bit_value)
|
||||
}
|
||||
_ => Err("Unmatched value"),
|
||||
}
|
||||
|
|
@ -89,12 +94,15 @@ pub trait VcdCounter {
|
|||
|
||||
let cur_bit_value = match &cur_time_value.value {
|
||||
VCDValue::BitScalar(bit) => Ok(bit),
|
||||
VCDValue::BitVector(vec) => {
|
||||
if let Some(index) = bus_index {
|
||||
Ok(&vec[index as usize])
|
||||
VCDValue::BitVector(bit_vec) => {
|
||||
let index = bus_index.unwrap() as usize;
|
||||
|
||||
let bit_value = if index < bit_vec.len() {
|
||||
&bit_vec[index as usize]
|
||||
} else {
|
||||
Err("No bus index provided")
|
||||
}
|
||||
&default_bit_value
|
||||
};
|
||||
Ok(bit_value)
|
||||
}
|
||||
_ => Err("Unmatched value"),
|
||||
}
|
||||
|
|
@ -328,6 +336,7 @@ impl<'a> VcdBusCounter<'a> {
|
|||
let signal_time_values = self.vcd_file.get_signal_values().get(signal_hash);
|
||||
|
||||
let signal_name = self.signal.get_name().to_string();
|
||||
// println!("signal name {}", signal_name);
|
||||
|
||||
// count the toggle, if current signal value is rise transition or fall
|
||||
// transition, count add one.
|
||||
|
|
|
|||
|
|
@ -45,10 +45,22 @@ impl VCDValue {
|
|||
}
|
||||
|
||||
pub fn get_vector_bit(&self, index: usize) -> VCDBit {
|
||||
|
||||
match self {
|
||||
VCDValue::BitVector(vec) => vec[index],
|
||||
VCDValue::BitVector(bit_vec) => {
|
||||
let default_bit_value = VCDBit::BitZero;
|
||||
let bit_value = if index < bit_vec.len() {
|
||||
bit_vec[index as usize]
|
||||
} else {
|
||||
default_bit_value
|
||||
};
|
||||
|
||||
bit_value
|
||||
}
|
||||
_ => panic!("Not a BitVector"),
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +345,10 @@ impl VCDFile {
|
|||
self.date = date_text;
|
||||
}
|
||||
|
||||
pub fn set_version(&mut self, version_text: String) {
|
||||
self.version = version_text;
|
||||
}
|
||||
|
||||
pub fn set_time_unit(&mut self, time_unit: &str) {
|
||||
match time_unit {
|
||||
"s" => self.time_unit = VCDTimeUnit::UnitSecond,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ range_from = { decimal_digits+ }
|
|||
range_to = { decimal_digits+ }
|
||||
bus_slice = { "[" ~ range_from ~ ":" ~ range_to ~ "]" }
|
||||
|
||||
scalar_constant = { "1'b0" | "1'b1" | "1'B0" | "1'B1" | "'b0" | "'b1" | "'B0" | "'B1" | "1" | "0" }
|
||||
scalar_constant = { "1'b0" | "1'b1" | "1'B0" | "1'B1" | "'b0" | "'b1" | "'B0" | "'B1" | "1" | "0" | "2'b00"}
|
||||
|
||||
line_comment = _{ "//" ~ (!("\n") ~ ASCII)* ~ ("\n" | EOI) }
|
||||
multiline_comment = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" }
|
||||
|
|
|
|||
|
|
@ -325,6 +325,13 @@ fn process_first_port_connection_single_connect(
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_bitwidth_value(input: &str) -> Option<(u32, String)> {
|
||||
// Split the input string by the character `'` and collect into a tuple(2'b00->(2,b'00))
|
||||
input.split_once('\'').and_then(|(bw, val)| {
|
||||
bw.parse::<u32>().ok().map(|bit_width| (bit_width, val.to_string()))
|
||||
})
|
||||
}
|
||||
|
||||
fn process_first_port_connection_multiple_connect(
|
||||
pair: Pair<Rule>,
|
||||
) -> Result<Box<verilog_data::VerilogPortRefPortConnect>, pest::error::Error<Rule>> {
|
||||
|
|
@ -338,8 +345,13 @@ fn process_first_port_connection_multiple_connect(
|
|||
Rule::scalar_constant => {
|
||||
let net_connect_line_no = inner_pair.line_col().0;
|
||||
let net_connect = inner_pair.as_str();
|
||||
let verilog_id = verilog_data::VerilogID::new(net_connect);
|
||||
let verilog_virtual_base_id: Box<dyn verilog_data::VerilogVirtualBaseID> = Box::new(verilog_id);
|
||||
let verilog_constant_id: verilog_data::VerilogConstantID;
|
||||
if let Some((bit_width, value)) = extract_bitwidth_value(net_connect) {
|
||||
verilog_constant_id = verilog_data::VerilogConstantID::new(bit_width, &value);
|
||||
} else {
|
||||
panic!("Error: invalid format");
|
||||
}
|
||||
let verilog_virtual_base_id: Box<dyn verilog_data::VerilogVirtualBaseID> = Box::new(verilog_constant_id);
|
||||
let verilog_net_constant_expr =
|
||||
verilog_data::VerilogConstantExpr::new(net_connect_line_no, verilog_virtual_base_id);
|
||||
let verilog_virtual_base_net_expr: Box<dyn verilog_data::VerilogVirtualBaseNetExpr> =
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ pub trait VerilogVirtualBaseID: Debug + VerilogVirtualBaseIDClone {
|
|||
false
|
||||
}
|
||||
|
||||
fn is_constant_id(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &str {
|
||||
panic!("This is unknown value.");
|
||||
}
|
||||
|
|
@ -213,6 +217,56 @@ impl VerilogVirtualBaseID for VerilogSliceID {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VerilogConstantID {
|
||||
bit_width: u32,
|
||||
value: VerilogID,
|
||||
formatted_constant_id: String,
|
||||
}
|
||||
|
||||
impl VerilogConstantID {
|
||||
pub fn new(bit_width: u32, value: &str) -> VerilogConstantID {
|
||||
let formatted_constant_id = format!("{}'{}", bit_width, value);
|
||||
VerilogConstantID {
|
||||
bit_width: bit_width,
|
||||
value: VerilogID::new(value),
|
||||
formatted_constant_id: formatted_constant_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bit_width(&self) -> u32 {
|
||||
self.bit_width
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> &VerilogID {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
|
||||
impl VerilogVirtualBaseID for VerilogConstantID {
|
||||
fn is_constant_id(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &str {
|
||||
&self.formatted_constant_id
|
||||
}
|
||||
|
||||
fn get_base_name(&self) -> &str {
|
||||
&self.value.get_base_name()
|
||||
}
|
||||
|
||||
|
||||
fn set_base_name(&mut self, id: &str) {
|
||||
self.value.set_base_name(id);
|
||||
self.formatted_constant_id = format!("{}'{}", self.bit_width,self.value.get_base_name());
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub trait VerilogVirtualBaseNetExpr: Debug + VerilogVirtualBaseNetExprClone {
|
||||
fn is_id_expr(&self) -> bool {
|
||||
false
|
||||
|
|
@ -534,12 +588,23 @@ impl VerilogInst {
|
|||
// bus_range_max is the bus max beyond range.
|
||||
let mut bus_range_max = std::cmp::max(port_bus_wide_range.unwrap().0, port_bus_wide_range.unwrap().1) + 1;
|
||||
|
||||
let mut const_net_bit_index: Option<u32> = None;
|
||||
let mut net_index: Option<i32> = None;
|
||||
let mut connect_net_expr: Option<Box<dyn VerilogVirtualBaseNetExpr>> = None;
|
||||
|
||||
for expr_net in concat_expr_nets {
|
||||
if expr_net.get_verilog_id().is_bus_index_id() {
|
||||
bus_range_max -= 1;
|
||||
} else if expr_net.get_verilog_id().is_constant_id() {
|
||||
let mut bit_width = expr_net.get_verilog_id().as_any().downcast_ref::<VerilogConstantID>().unwrap().get_bit_width();
|
||||
while bit_width > 0 {
|
||||
bus_range_max -= 1;
|
||||
if bus_range_max == port_index {
|
||||
const_net_bit_index = Some(bit_width-1);
|
||||
break;
|
||||
}
|
||||
bit_width -= 1;
|
||||
}
|
||||
} else if expr_net.get_verilog_id().is_bus_slice_id() {
|
||||
let slice_id = expr_net.get_verilog_id().as_any().downcast_ref::<VerilogSliceID>().unwrap();
|
||||
let from = slice_id.get_range_from();
|
||||
|
|
@ -617,6 +682,17 @@ impl VerilogInst {
|
|||
let net_id_expr = VerilogNetIDExpr::new(0, dyn_index_verilog_id);
|
||||
let dyn_net_id_expr: Box<dyn VerilogVirtualBaseNetExpr> = Box::new(net_id_expr);
|
||||
dyn_net_id_expr
|
||||
} else if let Some(const_net_bit_index) = const_net_bit_index {
|
||||
let connect_net_id = connect_net_expr.as_ref().unwrap().get_verilog_id();
|
||||
let net_value = connect_net_id.get_base_name();
|
||||
let new_net_value = &net_value[1..];
|
||||
let bit_value = new_net_value.chars().nth(const_net_bit_index as usize).unwrap();
|
||||
let value= format!("{}{}", 'b', bit_value);
|
||||
let const_verilog_id = VerilogConstantID::new(1, &value);
|
||||
let dyn_const_verilog_id: Box<dyn VerilogVirtualBaseID> = Box::new(const_verilog_id);
|
||||
let net_id_expr = VerilogConstantExpr::new(0, dyn_const_verilog_id);
|
||||
let dyn_net_id_expr: Box<dyn VerilogVirtualBaseNetExpr> = Box::new(net_id_expr);
|
||||
dyn_net_id_expr
|
||||
} else {
|
||||
connect_net_expr.as_ref().unwrap().clone()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@ set(EVAL_SOURCE ${HOME_EVALUATION}/src)
|
|||
|
||||
## build
|
||||
add_subdirectory(${EVAL_API})
|
||||
add_subdirectory(${EVAL_APPS})
|
||||
# add_subdirectory(${EVAL_APPS})
|
||||
add_subdirectory(${EVAL_DATA})
|
||||
add_subdirectory(${EVAL_SOURCE})
|
||||
|
|
|
|||
|
|
@ -68,3 +68,21 @@ target_include_directories(eval_wirelength_api
|
|||
PUBLIC
|
||||
${EVAL_API}
|
||||
)
|
||||
|
||||
|
||||
# union API
|
||||
add_library(eval_union_api
|
||||
${EVAL_API}/union_api.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(eval_union_api
|
||||
PRIVATE
|
||||
eval_util_init_flute
|
||||
eval_util_init_egr
|
||||
eval_util_init_idb
|
||||
)
|
||||
|
||||
target_include_directories(eval_union_api
|
||||
PUBLIC
|
||||
${EVAL_DATA}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -40,96 +40,120 @@ void CongestionAPI::destroyInst()
|
|||
}
|
||||
}
|
||||
|
||||
EGRMapSummary CongestionAPI::egrMap()
|
||||
EGRMapSummary CongestionAPI::egrMap(std::string stage)
|
||||
{
|
||||
return egrMap(EVAL_CONGESTION_INST->getEGRDirPath());
|
||||
return egrMap(stage, EVAL_CONGESTION_INST->getEGRDirPath());
|
||||
}
|
||||
|
||||
EGRMapSummary CongestionAPI::egrMap(std::string rt_dir_path)
|
||||
EGRMapSummary CongestionAPI::egrMapPure(std::string stage)
|
||||
{
|
||||
return egrMapPure(stage, EVAL_CONGESTION_INST->getEGRDirPath());
|
||||
}
|
||||
|
||||
EGRMapSummary CongestionAPI::egrMap(std::string stage, std::string rt_dir_path)
|
||||
{
|
||||
EGRMapSummary egr_map_summary;
|
||||
|
||||
EVAL_CONGESTION_INST->initEGR();
|
||||
egr_map_summary.horizontal_sum = EVAL_CONGESTION_INST->evalHoriEGR(rt_dir_path);
|
||||
egr_map_summary.vertical_sum = EVAL_CONGESTION_INST->evalVertiEGR(rt_dir_path);
|
||||
egr_map_summary.union_sum = EVAL_CONGESTION_INST->evalUnionEGR(rt_dir_path);
|
||||
egr_map_summary.horizontal_sum = EVAL_CONGESTION_INST->evalHoriEGR(stage, rt_dir_path);
|
||||
egr_map_summary.vertical_sum = EVAL_CONGESTION_INST->evalVertiEGR(stage, rt_dir_path);
|
||||
egr_map_summary.union_sum = EVAL_CONGESTION_INST->evalUnionEGR(stage, rt_dir_path);
|
||||
EVAL_CONGESTION_INST->destroyEGR();
|
||||
|
||||
return egr_map_summary;
|
||||
}
|
||||
|
||||
RUDYMapSummary CongestionAPI::rudyMap(int32_t grid_size)
|
||||
EGRMapSummary CongestionAPI::egrMapPure(std::string stage, std::string rt_dir_path)
|
||||
{
|
||||
EGRMapSummary egr_map_summary;
|
||||
|
||||
egr_map_summary.horizontal_sum = EVAL_CONGESTION_INST->evalHoriEGR(stage, rt_dir_path);
|
||||
egr_map_summary.vertical_sum = EVAL_CONGESTION_INST->evalVertiEGR(stage, rt_dir_path);
|
||||
egr_map_summary.union_sum = EVAL_CONGESTION_INST->evalUnionEGR(stage, rt_dir_path);
|
||||
|
||||
return egr_map_summary;
|
||||
}
|
||||
|
||||
RUDYMapSummary CongestionAPI::rudyMap(std::string stage, int32_t grid_size)
|
||||
{
|
||||
RUDYMapSummary rudy_map_summary;
|
||||
|
||||
EVAL_CONGESTION_INST->initIDB();
|
||||
rudy_map_summary = rudyMap(EVAL_CONGESTION_INST->getCongestionNets(), EVAL_CONGESTION_INST->getCongestionRegion(),
|
||||
rudy_map_summary = rudyMap(stage, EVAL_CONGESTION_INST->getCongestionNets(), EVAL_CONGESTION_INST->getCongestionRegion(),
|
||||
grid_size * EVAL_CONGESTION_INST->getRowHeight());
|
||||
EVAL_CONGESTION_INST->destroyIDB();
|
||||
|
||||
return rudy_map_summary;
|
||||
}
|
||||
|
||||
RUDYMapSummary CongestionAPI::rudyMap(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
RUDYMapSummary CongestionAPI::rudyMapPure(std::string stage, int32_t grid_size)
|
||||
{
|
||||
RUDYMapSummary rudy_map_summary;
|
||||
rudy_map_summary = rudyMap(stage, EVAL_CONGESTION_INST->getCongestionNets(), EVAL_CONGESTION_INST->getCongestionRegion(),
|
||||
grid_size * EVAL_CONGESTION_INST->getRowHeight());
|
||||
return rudy_map_summary;
|
||||
}
|
||||
|
||||
RUDYMapSummary CongestionAPI::rudyMap(std::string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
RUDYMapSummary rudy_map_summary;
|
||||
|
||||
rudy_map_summary.rudy_horizontal = EVAL_CONGESTION_INST->evalHoriRUDY(nets, region, grid_size);
|
||||
rudy_map_summary.rudy_vertical = EVAL_CONGESTION_INST->evalVertiRUDY(nets, region, grid_size);
|
||||
rudy_map_summary.rudy_union = EVAL_CONGESTION_INST->evalUnionRUDY(nets, region, grid_size);
|
||||
rudy_map_summary.rudy_horizontal = EVAL_CONGESTION_INST->evalHoriRUDY(stage, nets, region, grid_size);
|
||||
rudy_map_summary.rudy_vertical = EVAL_CONGESTION_INST->evalVertiRUDY(stage, nets, region, grid_size);
|
||||
rudy_map_summary.rudy_union = EVAL_CONGESTION_INST->evalUnionRUDY(stage, nets, region, grid_size);
|
||||
|
||||
rudy_map_summary.lutrudy_horizontal = EVAL_CONGESTION_INST->evalHoriLUTRUDY(nets, region, grid_size);
|
||||
rudy_map_summary.lutrudy_vertical = EVAL_CONGESTION_INST->evalVertiLUTRUDY(nets, region, grid_size);
|
||||
rudy_map_summary.lutrudy_union = EVAL_CONGESTION_INST->evalUnionLUTRUDY(nets, region, grid_size);
|
||||
rudy_map_summary.lutrudy_horizontal = EVAL_CONGESTION_INST->evalHoriLUTRUDY(stage, nets, region, grid_size);
|
||||
rudy_map_summary.lutrudy_vertical = EVAL_CONGESTION_INST->evalVertiLUTRUDY(stage, nets, region, grid_size);
|
||||
rudy_map_summary.lutrudy_union = EVAL_CONGESTION_INST->evalUnionLUTRUDY(stage, nets, region, grid_size);
|
||||
|
||||
return rudy_map_summary;
|
||||
}
|
||||
|
||||
OverflowSummary CongestionAPI::egrOverflow()
|
||||
OverflowSummary CongestionAPI::egrOverflow(std::string stage)
|
||||
{
|
||||
return egrOverflow(EVAL_CONGESTION_INST->getEGRDirPath());
|
||||
return egrOverflow(stage, EVAL_CONGESTION_INST->getEGRDirPath());
|
||||
}
|
||||
|
||||
OverflowSummary CongestionAPI::egrOverflow(std::string rt_dir_path)
|
||||
OverflowSummary CongestionAPI::egrOverflow(std::string stage, std::string rt_dir_path)
|
||||
{
|
||||
OverflowSummary overflow_summary;
|
||||
|
||||
overflow_summary.total_overflow_horizontal = EVAL_CONGESTION_INST->evalHoriTotalOverflow(rt_dir_path);
|
||||
overflow_summary.total_overflow_vertical = EVAL_CONGESTION_INST->evalVertiTotalOverflow(rt_dir_path);
|
||||
overflow_summary.total_overflow_union = EVAL_CONGESTION_INST->evalUnionTotalOverflow(rt_dir_path);
|
||||
overflow_summary.total_overflow_horizontal = EVAL_CONGESTION_INST->evalHoriTotalOverflow(stage, rt_dir_path);
|
||||
overflow_summary.total_overflow_vertical = EVAL_CONGESTION_INST->evalVertiTotalOverflow(stage, rt_dir_path);
|
||||
overflow_summary.total_overflow_union = EVAL_CONGESTION_INST->evalUnionTotalOverflow(stage, rt_dir_path);
|
||||
|
||||
overflow_summary.max_overflow_horizontal = EVAL_CONGESTION_INST->evalHoriMaxOverflow(rt_dir_path);
|
||||
overflow_summary.max_overflow_vertical = EVAL_CONGESTION_INST->evalVertiMaxOverflow(rt_dir_path);
|
||||
overflow_summary.max_overflow_union = EVAL_CONGESTION_INST->evalUnionMaxOverflow(rt_dir_path);
|
||||
overflow_summary.max_overflow_horizontal = EVAL_CONGESTION_INST->evalHoriMaxOverflow(stage, rt_dir_path);
|
||||
overflow_summary.max_overflow_vertical = EVAL_CONGESTION_INST->evalVertiMaxOverflow(stage, rt_dir_path);
|
||||
overflow_summary.max_overflow_union = EVAL_CONGESTION_INST->evalUnionMaxOverflow(stage, rt_dir_path);
|
||||
|
||||
overflow_summary.weighted_average_overflow_horizontal = EVAL_CONGESTION_INST->evalHoriAvgOverflow(rt_dir_path);
|
||||
overflow_summary.weighted_average_overflow_vertical = EVAL_CONGESTION_INST->evalVertiAvgOverflow(rt_dir_path);
|
||||
overflow_summary.weighted_average_overflow_union = EVAL_CONGESTION_INST->evalUnionAvgOverflow(rt_dir_path);
|
||||
overflow_summary.weighted_average_overflow_horizontal = EVAL_CONGESTION_INST->evalHoriAvgOverflow(stage, rt_dir_path);
|
||||
overflow_summary.weighted_average_overflow_vertical = EVAL_CONGESTION_INST->evalVertiAvgOverflow(stage, rt_dir_path);
|
||||
overflow_summary.weighted_average_overflow_union = EVAL_CONGESTION_INST->evalUnionAvgOverflow(stage, rt_dir_path);
|
||||
|
||||
return overflow_summary;
|
||||
}
|
||||
|
||||
UtilizationSummary CongestionAPI::rudyUtilization(bool use_lut)
|
||||
UtilizationSummary CongestionAPI::rudyUtilization(std::string stage, bool use_lut)
|
||||
{
|
||||
UtilizationSummary utilization_summary;
|
||||
|
||||
std::string rudy_dir_path = EVAL_CONGESTION_INST->getDefaultOutputDir() + "/RUDY_map";
|
||||
utilization_summary = rudyUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary = rudyUtilization(stage, rudy_dir_path, use_lut);
|
||||
|
||||
return utilization_summary;
|
||||
}
|
||||
|
||||
UtilizationSummary CongestionAPI::rudyUtilization(std::string rudy_dir_path, bool use_lut)
|
||||
UtilizationSummary CongestionAPI::rudyUtilization(std::string stage, std::string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
UtilizationSummary utilization_summary;
|
||||
|
||||
utilization_summary.max_utilization_horizontal = EVAL_CONGESTION_INST->evalHoriMaxUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary.max_utilization_vertical = EVAL_CONGESTION_INST->evalVertiMaxUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary.max_utilization_union = EVAL_CONGESTION_INST->evalUnionMaxUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary.max_utilization_horizontal = EVAL_CONGESTION_INST->evalHoriMaxUtilization(stage, rudy_dir_path, use_lut);
|
||||
utilization_summary.max_utilization_vertical = EVAL_CONGESTION_INST->evalVertiMaxUtilization(stage, rudy_dir_path, use_lut);
|
||||
utilization_summary.max_utilization_union = EVAL_CONGESTION_INST->evalUnionMaxUtilization(stage, rudy_dir_path, use_lut);
|
||||
|
||||
utilization_summary.weighted_average_utilization_horizontal = EVAL_CONGESTION_INST->evalHoriAvgUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary.weighted_average_utilization_vertical = EVAL_CONGESTION_INST->evalVertiAvgUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary.weighted_average_utilization_union = EVAL_CONGESTION_INST->evalUnionAvgUtilization(rudy_dir_path, use_lut);
|
||||
utilization_summary.weighted_average_utilization_horizontal = EVAL_CONGESTION_INST->evalHoriAvgUtilization(stage, rudy_dir_path, use_lut);
|
||||
utilization_summary.weighted_average_utilization_vertical = EVAL_CONGESTION_INST->evalVertiAvgUtilization(stage, rudy_dir_path, use_lut);
|
||||
utilization_summary.weighted_average_utilization_union = EVAL_CONGESTION_INST->evalUnionAvgUtilization(stage, rudy_dir_path, use_lut);
|
||||
|
||||
return utilization_summary;
|
||||
}
|
||||
|
|
@ -141,6 +165,11 @@ void CongestionAPI::evalNetInfo()
|
|||
EVAL_CONGESTION_INST->destroyIDB();
|
||||
}
|
||||
|
||||
void CongestionAPI::evalNetInfoPure()
|
||||
{
|
||||
EVAL_CONGESTION_INST->evalNetInfo();
|
||||
}
|
||||
|
||||
int CongestionAPI::findPinNumber(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findPinNumber(net_name);
|
||||
|
|
@ -156,4 +185,49 @@ float CongestionAPI::findLness(std::string net_name)
|
|||
return EVAL_CONGESTION_INST->findLness(net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionAPI::findBBoxWidth(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxWidth(net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionAPI::findBBoxHeight(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxHeight(net_name);
|
||||
}
|
||||
|
||||
int64_t CongestionAPI::findBBoxArea(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxArea(net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionAPI::findBBoxLx(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxLx(net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionAPI::findBBoxLy(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxLy(net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionAPI::findBBoxUx(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxUx(net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionAPI::findBBoxUy(std::string net_name)
|
||||
{
|
||||
return EVAL_CONGESTION_INST->findBBoxUy(net_name);
|
||||
}
|
||||
|
||||
std::string CongestionAPI::egrUnionMap(std::string stage, std::string rt_dir_path)
|
||||
{
|
||||
EVAL_CONGESTION_INST->setEGRDirPath(rt_dir_path + "/rt/rt_temp_directory");
|
||||
EVAL_CONGESTION_INST->initEGR();
|
||||
std::string union_egr_map_path = EVAL_CONGESTION_INST->evalUnionEGR(stage, rt_dir_path + "/rt/rt_temp_directory");
|
||||
EVAL_CONGESTION_INST->destroyEGR();
|
||||
|
||||
return union_egr_map_path;
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
|
|||
|
|
@ -21,20 +21,33 @@ class CongestionAPI
|
|||
static CongestionAPI* getInst();
|
||||
static void destroyInst();
|
||||
|
||||
EGRMapSummary egrMap();
|
||||
OverflowSummary egrOverflow();
|
||||
RUDYMapSummary rudyMap(int32_t grid_size = 1);
|
||||
UtilizationSummary rudyUtilization(bool use_lut = false);
|
||||
EGRMapSummary egrMap(std::string stage);
|
||||
EGRMapSummary egrMapPure(std::string stage);
|
||||
OverflowSummary egrOverflow(std::string stage);
|
||||
RUDYMapSummary rudyMap(std::string stage, int32_t grid_size = 1);
|
||||
RUDYMapSummary rudyMapPure(std::string stage, int32_t grid_size = 1);
|
||||
UtilizationSummary rudyUtilization(std::string stage, bool use_lut = false);
|
||||
|
||||
EGRMapSummary egrMap(std::string rt_dir_path);
|
||||
OverflowSummary egrOverflow(std::string rt_dir_path);
|
||||
RUDYMapSummary rudyMap(CongestionNets congestion_nets, CongestionRegion region, int32_t grid_size);
|
||||
UtilizationSummary rudyUtilization(std::string rudy_dir_path, bool use_lut = false);
|
||||
EGRMapSummary egrMap(std::string stage, std::string rt_dir_path);
|
||||
EGRMapSummary egrMapPure(std::string stage, std::string rt_dir_path);
|
||||
OverflowSummary egrOverflow(std::string stage, std::string rt_dir_path);
|
||||
RUDYMapSummary rudyMap(std::string stage, CongestionNets congestion_nets, CongestionRegion region, int32_t grid_size);
|
||||
UtilizationSummary rudyUtilization(std::string stage, std::string rudy_dir_path, bool use_lut = false);
|
||||
|
||||
void evalNetInfo();
|
||||
void evalNetInfoPure();
|
||||
int findPinNumber(std::string net_name);
|
||||
int findAspectRatio(std::string net_name);
|
||||
float findLness(std::string net_name);
|
||||
int32_t findBBoxWidth(std::string net_name);
|
||||
int32_t findBBoxHeight(std::string net_name);
|
||||
int64_t findBBoxArea(std::string net_name);
|
||||
int32_t findBBoxLx(std::string net_name);
|
||||
int32_t findBBoxLy(std::string net_name);
|
||||
int32_t findBBoxUx(std::string net_name);
|
||||
int32_t findBBoxUy(std::string net_name);
|
||||
|
||||
std::string egrUnionMap(std::string stage, std::string rt_dir_path);
|
||||
|
||||
private:
|
||||
static CongestionAPI* _congestion_api_inst;
|
||||
|
|
|
|||
|
|
@ -40,87 +40,96 @@ void DensityAPI::destroyInst()
|
|||
}
|
||||
}
|
||||
|
||||
DensityMapSummary DensityAPI::densityMap(int32_t grid_size, bool neighbor)
|
||||
DensityMapSummary DensityAPI::densityMap(std::string stage, int32_t grid_size, bool neighbor)
|
||||
{
|
||||
DensityMapSummary density_map_summary;
|
||||
|
||||
EVAL_DENSITY_INST->initIDB();
|
||||
density_map_summary.cell_map_summary = cellDensityMap(grid_size);
|
||||
density_map_summary.pin_map_summary = pinDensityMap(grid_size, neighbor);
|
||||
density_map_summary.net_map_summary = netDensityMap(grid_size, neighbor);
|
||||
density_map_summary.cell_map_summary = cellDensityMap(stage, grid_size);
|
||||
density_map_summary.pin_map_summary = pinDensityMap(stage, grid_size, neighbor);
|
||||
density_map_summary.net_map_summary = netDensityMap(stage, grid_size, neighbor);
|
||||
EVAL_DENSITY_INST->destroyIDB();
|
||||
|
||||
return density_map_summary;
|
||||
}
|
||||
|
||||
CellMapSummary DensityAPI::cellDensityMap(int32_t grid_size)
|
||||
DensityMapSummary DensityAPI::densityMapPure(std::string stage, int32_t grid_size, bool neighbor)
|
||||
{
|
||||
DensityMapSummary density_map_summary;
|
||||
density_map_summary.cell_map_summary = cellDensityMap(stage, grid_size);
|
||||
density_map_summary.pin_map_summary = pinDensityMap(stage, grid_size, neighbor);
|
||||
density_map_summary.net_map_summary = netDensityMap(stage, grid_size, neighbor);
|
||||
return density_map_summary;
|
||||
}
|
||||
|
||||
CellMapSummary DensityAPI::cellDensityMap(std::string stage, int32_t grid_size)
|
||||
{
|
||||
CellMapSummary cell_map_summary;
|
||||
|
||||
EVAL_DENSITY_INST->initIDBRegion();
|
||||
EVAL_DENSITY_INST->initIDBCells();
|
||||
cell_map_summary = cellDensityMap(EVAL_DENSITY_INST->getDensityCells(), EVAL_DENSITY_INST->getDensityRegion(),
|
||||
grid_size * EVAL_DENSITY_INST->getRowHeight());
|
||||
grid_size * EVAL_DENSITY_INST->getRowHeight(), stage);
|
||||
|
||||
return cell_map_summary;
|
||||
}
|
||||
|
||||
PinMapSummary DensityAPI::pinDensityMap(int32_t grid_size, bool neighbor)
|
||||
PinMapSummary DensityAPI::pinDensityMap(std::string stage, int32_t grid_size, bool neighbor)
|
||||
{
|
||||
PinMapSummary pin_map_summary;
|
||||
|
||||
EVAL_DENSITY_INST->initIDBRegion();
|
||||
EVAL_DENSITY_INST->initIDBCells();
|
||||
pin_map_summary = pinDensityMap(EVAL_DENSITY_INST->getDensityPins(), EVAL_DENSITY_INST->getDensityRegion(),
|
||||
grid_size * EVAL_DENSITY_INST->getRowHeight(), neighbor);
|
||||
grid_size * EVAL_DENSITY_INST->getRowHeight(), stage, neighbor);
|
||||
|
||||
return pin_map_summary;
|
||||
}
|
||||
|
||||
NetMapSummary DensityAPI::netDensityMap(int32_t grid_size, bool neighbor)
|
||||
NetMapSummary DensityAPI::netDensityMap(std::string stage, int32_t grid_size, bool neighbor)
|
||||
{
|
||||
NetMapSummary net_map_summary;
|
||||
|
||||
EVAL_DENSITY_INST->initIDBRegion();
|
||||
EVAL_DENSITY_INST->initIDBNets();
|
||||
net_map_summary = netDensityMap(EVAL_DENSITY_INST->getDensityNets(), EVAL_DENSITY_INST->getDensityRegion(),
|
||||
grid_size * EVAL_DENSITY_INST->getRowHeight(), neighbor);
|
||||
grid_size * EVAL_DENSITY_INST->getRowHeight(), stage, neighbor);
|
||||
|
||||
return net_map_summary;
|
||||
}
|
||||
|
||||
CellMapSummary DensityAPI::cellDensityMap(DensityCells cells, DensityRegion region, int32_t grid_size)
|
||||
CellMapSummary DensityAPI::cellDensityMap(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage)
|
||||
{
|
||||
CellMapSummary cell_map_summary;
|
||||
|
||||
DensityEval density_eval;
|
||||
cell_map_summary.macro_density = density_eval.evalMacroDensity(cells, region, grid_size);
|
||||
cell_map_summary.stdcell_density = density_eval.evalStdCellDensity(cells, region, grid_size);
|
||||
cell_map_summary.allcell_density = density_eval.evalAllCellDensity(cells, region, grid_size);
|
||||
cell_map_summary.macro_density = density_eval.evalMacroDensity(cells, region, grid_size, stage);
|
||||
cell_map_summary.stdcell_density = density_eval.evalStdCellDensity(cells, region, grid_size, stage);
|
||||
cell_map_summary.allcell_density = density_eval.evalAllCellDensity(cells, region, grid_size, stage);
|
||||
|
||||
return cell_map_summary;
|
||||
}
|
||||
|
||||
PinMapSummary DensityAPI::pinDensityMap(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
PinMapSummary DensityAPI::pinDensityMap(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
PinMapSummary pin_map_summary;
|
||||
|
||||
DensityEval density_eval;
|
||||
pin_map_summary.macro_pin_density = density_eval.evalMacroPinDensity(pins, region, grid_size, neighbor);
|
||||
pin_map_summary.stdcell_pin_density = density_eval.evalStdCellPinDensity(pins, region, grid_size, neighbor);
|
||||
pin_map_summary.allcell_pin_density = density_eval.evalAllCellPinDensity(pins, region, grid_size, neighbor);
|
||||
pin_map_summary.macro_pin_density = density_eval.evalMacroPinDensity(pins, region, grid_size, stage, neighbor);
|
||||
pin_map_summary.stdcell_pin_density = density_eval.evalStdCellPinDensity(pins, region, grid_size, stage, neighbor);
|
||||
pin_map_summary.allcell_pin_density = density_eval.evalAllCellPinDensity(pins, region, grid_size, stage, neighbor);
|
||||
|
||||
return pin_map_summary;
|
||||
}
|
||||
|
||||
NetMapSummary DensityAPI::netDensityMap(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
NetMapSummary DensityAPI::netDensityMap(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
NetMapSummary net_map_summary;
|
||||
|
||||
DensityEval density_eval;
|
||||
net_map_summary.local_net_density = density_eval.evalLocalNetDensity(nets, region, grid_size, neighbor);
|
||||
net_map_summary.global_net_density = density_eval.evalGlobalNetDensity(nets, region, grid_size, neighbor);
|
||||
net_map_summary.allnet_density = density_eval.evalAllNetDensity(nets, region, grid_size, neighbor);
|
||||
net_map_summary.local_net_density = density_eval.evalLocalNetDensity(nets, region, grid_size, stage, neighbor);
|
||||
net_map_summary.global_net_density = density_eval.evalGlobalNetDensity(nets, region, grid_size, stage, neighbor);
|
||||
net_map_summary.allnet_density = density_eval.evalAllNetDensity(nets, region, grid_size, stage, neighbor);
|
||||
|
||||
return net_map_summary;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,14 +20,15 @@ class DensityAPI
|
|||
static DensityAPI* getInst();
|
||||
static void destroyInst();
|
||||
|
||||
DensityMapSummary densityMap(int32_t grid_size = 1, bool neighbor = false);
|
||||
CellMapSummary cellDensityMap(int32_t grid_size = 1);
|
||||
PinMapSummary pinDensityMap(int32_t grid_size = 1, bool neighbor = false);
|
||||
NetMapSummary netDensityMap(int32_t grid_size = 1, bool neighbor = false);
|
||||
DensityMapSummary densityMap(std::string stage, int32_t grid_size = 1, bool neighbor = false);
|
||||
DensityMapSummary densityMapPure(std::string stage, int32_t grid_size = 1, bool neighbor = false);
|
||||
CellMapSummary cellDensityMap(std::string stage, int32_t grid_size = 1);
|
||||
PinMapSummary pinDensityMap(std::string stage, int32_t grid_size = 1, bool neighbor = false);
|
||||
NetMapSummary netDensityMap(std::string stage, int32_t grid_size = 1, bool neighbor = false);
|
||||
|
||||
CellMapSummary cellDensityMap(DensityCells cells, DensityRegion region, int32_t grid_size);
|
||||
PinMapSummary pinDensityMap(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
NetMapSummary netDensityMap(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
CellMapSummary cellDensityMap(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage);
|
||||
PinMapSummary pinDensityMap(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
NetMapSummary netDensityMap(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
|
||||
MacroMarginSummary macroMarginMap(int32_t grid_size = 1);
|
||||
MacroMarginSummary macroMarginMap(DensityCells cells, DensityRegion die, DensityRegion core, int32_t grid_size);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ void TimingAPI::runSTA()
|
|||
EVAL_STA_INST->runSTA();
|
||||
}
|
||||
|
||||
void TimingAPI::evalTiming(const std::string& routing_type, const bool& rt_done)
|
||||
{
|
||||
EVAL_STA_INST->evalTiming(routing_type, rt_done);
|
||||
}
|
||||
|
||||
void TimingAPI::destroyInst()
|
||||
{
|
||||
ieval::TimingEval::destroyInst();
|
||||
|
|
@ -94,4 +99,9 @@ void TimingAPI::updateTiming(const std::vector<TimingNet*>& timing_net_list, con
|
|||
EVAL_STA_INST->updateTiming(timing_net_list, name_list, propagation_level, dbu_unit);
|
||||
}
|
||||
|
||||
bool TimingAPI::isClockNet(const std::string& net_name) const
|
||||
{
|
||||
return EVAL_STA_INST->isClockNet(net_name);
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -24,7 +24,8 @@ class TimingAPI
|
|||
|
||||
static TimingAPI* getInst();
|
||||
|
||||
static void runSTA();
|
||||
void runSTA();
|
||||
void evalTiming(const std::string& routing_type, const bool& rt_done = false);
|
||||
|
||||
static void destroyInst();
|
||||
|
||||
|
|
@ -45,6 +46,8 @@ class TimingAPI
|
|||
void updateTiming(const std::vector<TimingNet*>& timing_net_list, const std::vector<std::string>& name_list, const int& propagation_level,
|
||||
int32_t dbu_unit);
|
||||
|
||||
bool isClockNet(const std::string& net_name) const;
|
||||
|
||||
private:
|
||||
static TimingAPI* _timing_api;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* @FilePath: union_api.cpp
|
||||
* @Author: Yihang Qiu (qiuyihang23@mails.ucas.ac.cn)
|
||||
* @Date: 2024-10-11 15:37:27
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
#include "union_api.h"
|
||||
|
||||
#include "init_egr.h"
|
||||
#include "init_flute.h"
|
||||
#include "init_idb.h"
|
||||
|
||||
namespace ieval {
|
||||
|
||||
#define UNION_EVAL_INIT_IDB_INST (ieval::InitIDB::getInst())
|
||||
#define UNION_EVAL_INIT_FLUTE_INST (ieval::InitFlute::getInst())
|
||||
#define UNION_EVAL_INIT_EGR_INST (ieval::InitEGR::getInst())
|
||||
|
||||
UnionAPI* UnionAPI::_union_api_inst = nullptr;
|
||||
|
||||
UnionAPI::UnionAPI()
|
||||
{
|
||||
}
|
||||
|
||||
UnionAPI::~UnionAPI()
|
||||
{
|
||||
}
|
||||
|
||||
UnionAPI* UnionAPI::getInst()
|
||||
{
|
||||
if (_union_api_inst == nullptr) {
|
||||
_union_api_inst = new UnionAPI();
|
||||
}
|
||||
|
||||
return _union_api_inst;
|
||||
}
|
||||
|
||||
void UnionAPI::destroyInst()
|
||||
{
|
||||
if (_union_api_inst != nullptr) {
|
||||
delete _union_api_inst;
|
||||
_union_api_inst = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void UnionAPI::initIDB()
|
||||
{
|
||||
UNION_EVAL_INIT_IDB_INST->initPointSets();
|
||||
UNION_EVAL_INIT_IDB_INST->initDensityDB();
|
||||
UNION_EVAL_INIT_IDB_INST->initCongestionDB();
|
||||
}
|
||||
|
||||
void UnionAPI::initEGR(bool enable_timing)
|
||||
{
|
||||
UNION_EVAL_INIT_EGR_INST->runEGR(enable_timing);
|
||||
}
|
||||
|
||||
void UnionAPI::initFlute()
|
||||
{
|
||||
UNION_EVAL_INIT_FLUTE_INST->readLUT();
|
||||
}
|
||||
|
||||
void UnionAPI::destroyIDB()
|
||||
{
|
||||
UNION_EVAL_INIT_IDB_INST->destroyInst();
|
||||
}
|
||||
|
||||
void UnionAPI::destroyEGR()
|
||||
{
|
||||
UNION_EVAL_INIT_EGR_INST->destroyInst();
|
||||
}
|
||||
|
||||
void UnionAPI::destroyFlute()
|
||||
{
|
||||
UNION_EVAL_INIT_FLUTE_INST->destroyInst();
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* @FilePath: union_api.h
|
||||
* @Author: Yihang Qiu (qiuyihang23@mails.ucas.ac.cn)
|
||||
* @Date: 2024-10-11 15:37:27
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ieval {
|
||||
|
||||
#define UNION_API_INST (ieval::UnionAPI::getInst())
|
||||
|
||||
class UnionAPI
|
||||
{
|
||||
public:
|
||||
UnionAPI();
|
||||
~UnionAPI();
|
||||
static UnionAPI* getInst();
|
||||
static void destroyInst();
|
||||
|
||||
void initIDB();
|
||||
void initEGR(bool enable_timing = false);
|
||||
void initFlute();
|
||||
|
||||
void destroyIDB();
|
||||
void destroyEGR();
|
||||
void destroyFlute();
|
||||
|
||||
private:
|
||||
static UnionAPI* _union_api_inst;
|
||||
};
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -70,6 +70,19 @@ TotalWLSummary WirelengthAPI::totalWL()
|
|||
return total_wirelength_summary;
|
||||
}
|
||||
|
||||
TotalWLSummary WirelengthAPI::totalWLPure()
|
||||
{
|
||||
TotalWLSummary total_wirelength_summary;
|
||||
|
||||
total_wirelength_summary.HPWL = EVAL_WIRELENGTH_INST->evalTotalHPWL();
|
||||
total_wirelength_summary.FLUTE = EVAL_WIRELENGTH_INST->evalTotalFLUTE();
|
||||
total_wirelength_summary.HTree = EVAL_WIRELENGTH_INST->evalTotalHTree();
|
||||
total_wirelength_summary.VTree = EVAL_WIRELENGTH_INST->evalTotalVTree();
|
||||
total_wirelength_summary.GRWL = EVAL_WIRELENGTH_INST->evalTotalEGRWL() * EVAL_WIRELENGTH_INST->getDesignUnit();
|
||||
|
||||
return total_wirelength_summary;
|
||||
}
|
||||
|
||||
NetWLSummary WirelengthAPI::netWL(std::string net_name)
|
||||
{
|
||||
NetWLSummary net_wirelength_summary;
|
||||
|
|
@ -80,7 +93,7 @@ NetWLSummary WirelengthAPI::netWL(std::string net_name)
|
|||
|
||||
net_wirelength_summary = netWL(EVAL_WIRELENGTH_INST->getNetPointSet(net_name));
|
||||
net_wirelength_summary.GRWL
|
||||
= EVAL_WIRELENGTH_INST->evalNetEGRWL(EVAL_WIRELENGTH_INST->getEGRDirPath() + "/initial_router/route.guide", net_name)
|
||||
= EVAL_WIRELENGTH_INST->evalNetEGRWL(EVAL_WIRELENGTH_INST->getEGRDirPath() + "/early_router/route.guide", net_name)
|
||||
* EVAL_WIRELENGTH_INST->getDesignUnit();
|
||||
|
||||
EVAL_WIRELENGTH_INST->destroyIDB();
|
||||
|
|
@ -142,6 +155,11 @@ void WirelengthAPI::evalNetInfo()
|
|||
EVAL_WIRELENGTH_INST->destroyFlute();
|
||||
}
|
||||
|
||||
void WirelengthAPI::evalNetInfoPure()
|
||||
{
|
||||
EVAL_WIRELENGTH_INST->evalNetInfo();
|
||||
}
|
||||
|
||||
int32_t WirelengthAPI::findNetHPWL(std::string net_name)
|
||||
{
|
||||
return EVAL_WIRELENGTH_INST->findHPWL(net_name);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class WirelengthAPI
|
|||
static void destroyInst();
|
||||
|
||||
TotalWLSummary totalWL();
|
||||
TotalWLSummary totalWLPure();
|
||||
NetWLSummary netWL(std::string net_name);
|
||||
|
||||
TotalWLSummary totalWL(PointSets point_sets);
|
||||
|
|
@ -33,6 +34,7 @@ class WirelengthAPI
|
|||
float pathEGRWL(std::string guide_path, std::string net_name, std::string load_name);
|
||||
|
||||
void evalNetInfo();
|
||||
void evalNetInfoPure();
|
||||
int32_t findNetHPWL(std::string net_name);
|
||||
int32_t findNetFLUTE(std::string net_name);
|
||||
int32_t findNetGRWL(std::string net_name);
|
||||
|
|
|
|||
|
|
@ -71,3 +71,23 @@ target_include_directories(wirelength_app
|
|||
${HOME_EVALUATION}/database
|
||||
)
|
||||
|
||||
# Union Evaluation APP
|
||||
add_executable(union_app
|
||||
union_app.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(union_app
|
||||
PRIVATE
|
||||
eval_wirelength_api
|
||||
eval_timing_api
|
||||
eval_congestion_api
|
||||
eval_union_api
|
||||
idm
|
||||
)
|
||||
|
||||
target_include_directories(union_app
|
||||
PRIVATE
|
||||
${HOME_EVALUATION}/api
|
||||
${HOME_EVALUATION}/database
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,17 +13,17 @@ void TestEgrMap();
|
|||
void TestRudyMap();
|
||||
void TestEgrOverflow();
|
||||
void TestRudyUtilization();
|
||||
//void TestRudyMapFromIDB();
|
||||
// void TestRudyMapFromIDB();
|
||||
void TestRudyMapFromIDB(const std::string& file_path);
|
||||
void TestEgrMapFromIDB();
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// TestEgrMap();
|
||||
// TestRudyMap();
|
||||
// TestEgrOverflow();
|
||||
// TestRudyUtilization();
|
||||
|
||||
|
||||
if (argc > 1) {
|
||||
std::string map_path(argv[1]);
|
||||
std::cout << "map_path: " << map_path << std::endl;
|
||||
|
|
@ -39,8 +39,9 @@ void TestEgrMap()
|
|||
ieval::CongestionAPI congestion_api;
|
||||
|
||||
std::string map_path = "./rt_temp_directory";
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::EGRMapSummary egr_map_summary = congestion_api.egrMap(map_path);
|
||||
ieval::EGRMapSummary egr_map_summary = congestion_api.egrMap(stage, map_path);
|
||||
std::cout << "egr horizontal sum: " << egr_map_summary.horizontal_sum << std::endl;
|
||||
std::cout << "egr vertical sum: " << egr_map_summary.vertical_sum << std::endl;
|
||||
std::cout << "egr union sum: " << egr_map_summary.union_sum << std::endl;
|
||||
|
|
@ -83,8 +84,9 @@ void TestRudyMap()
|
|||
region.uy = 7;
|
||||
|
||||
int32_t grid_size = 2;
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::RUDYMapSummary rudy_map_summary = congestion_api.rudyMap(congestion_nets, region, grid_size);
|
||||
ieval::RUDYMapSummary rudy_map_summary = congestion_api.rudyMap(stage, congestion_nets, region, grid_size);
|
||||
std::cout << "rudy horizontal: " << rudy_map_summary.rudy_horizontal << std::endl;
|
||||
std::cout << "rudy vertical: " << rudy_map_summary.rudy_vertical << std::endl;
|
||||
std::cout << "rudy union: " << rudy_map_summary.rudy_union << std::endl;
|
||||
|
|
@ -98,9 +100,10 @@ void TestEgrOverflow()
|
|||
ieval::CongestionAPI congestion_api;
|
||||
|
||||
std::string map_path = "/home/yhqiu/benchmark/AiEDA/application/test/iEDA/rt_temp_directory";
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::OverflowSummary overflow_summary;
|
||||
overflow_summary = congestion_api.egrOverflow(map_path);
|
||||
overflow_summary = congestion_api.egrOverflow(stage, map_path);
|
||||
std::cout << "total overflow horizontal: " << overflow_summary.total_overflow_horizontal << std::endl;
|
||||
std::cout << "total overflow vertical: " << overflow_summary.total_overflow_vertical << std::endl;
|
||||
std::cout << "total overflow union: " << overflow_summary.total_overflow_union << std::endl;
|
||||
|
|
@ -115,10 +118,11 @@ void TestEgrOverflow()
|
|||
void TestRudyUtilization()
|
||||
{
|
||||
ieval::CongestionAPI congestion_api;
|
||||
std::string stage = "place";
|
||||
|
||||
std::string map_path = "/home/yhqiu/benchmark/AiEDA/third_party/iEDA/bin";
|
||||
ieval::UtilizationSummary utilization_summary;
|
||||
utilization_summary = congestion_api.rudyUtilization(map_path, false);
|
||||
utilization_summary = congestion_api.rudyUtilization(stage, map_path, false);
|
||||
std::cout << "max utilization horizontal: " << utilization_summary.max_utilization_horizontal << std::endl;
|
||||
std::cout << "max utilization vertical: " << utilization_summary.max_utilization_vertical << std::endl;
|
||||
std::cout << "max utilization union: " << utilization_summary.max_utilization_union << std::endl;
|
||||
|
|
@ -126,7 +130,7 @@ void TestRudyUtilization()
|
|||
std::cout << "average utilization vertical: " << utilization_summary.weighted_average_utilization_vertical << std::endl;
|
||||
std::cout << "average utilization union: " << utilization_summary.weighted_average_utilization_union << std::endl;
|
||||
|
||||
utilization_summary = congestion_api.rudyUtilization(map_path, true);
|
||||
utilization_summary = congestion_api.rudyUtilization(stage, map_path, true);
|
||||
std::cout << "max utilization horizontal: " << utilization_summary.max_utilization_horizontal << std::endl;
|
||||
std::cout << "max utilization vertical: " << utilization_summary.max_utilization_vertical << std::endl;
|
||||
std::cout << "max utilization union: " << utilization_summary.max_utilization_union << std::endl;
|
||||
|
|
@ -139,8 +143,10 @@ void TestRudyMapFromIDB(const std::string& file_path)
|
|||
{
|
||||
dmInst->init(file_path);
|
||||
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::CongestionAPI congestion_api;
|
||||
ieval::RUDYMapSummary rudy_map_summary = congestion_api.rudyMap();
|
||||
ieval::RUDYMapSummary rudy_map_summary = congestion_api.rudyMap(stage);
|
||||
|
||||
std::cout << "rudy horizontal: " << rudy_map_summary.rudy_horizontal << std::endl;
|
||||
std::cout << "rudy vertical: " << rudy_map_summary.rudy_vertical << std::endl;
|
||||
|
|
@ -150,7 +156,7 @@ void TestRudyMapFromIDB(const std::string& file_path)
|
|||
std::cout << "lut rudy union: " << rudy_map_summary.lutrudy_union << std::endl;
|
||||
|
||||
ieval::UtilizationSummary utilization_summary;
|
||||
utilization_summary = congestion_api.rudyUtilization(false);
|
||||
utilization_summary = congestion_api.rudyUtilization(stage, false);
|
||||
std::cout << ">> RUDY " << std::endl;
|
||||
std::cout << "max utilization horizontal: " << utilization_summary.max_utilization_horizontal << std::endl;
|
||||
std::cout << "max utilization vertical: " << utilization_summary.max_utilization_vertical << std::endl;
|
||||
|
|
@ -159,7 +165,7 @@ void TestRudyMapFromIDB(const std::string& file_path)
|
|||
std::cout << "average utilization vertical: " << utilization_summary.weighted_average_utilization_vertical << std::endl;
|
||||
std::cout << "average utilization union: " << utilization_summary.weighted_average_utilization_union << std::endl;
|
||||
|
||||
utilization_summary = congestion_api.rudyUtilization(true);
|
||||
utilization_summary = congestion_api.rudyUtilization(stage, true);
|
||||
std::cout << ">> LUTRUDY " << std::endl;
|
||||
std::cout << "max utilization horizontal: " << utilization_summary.max_utilization_horizontal << std::endl;
|
||||
std::cout << "max utilization vertical: " << utilization_summary.max_utilization_vertical << std::endl;
|
||||
|
|
@ -172,11 +178,12 @@ void TestRudyMapFromIDB(const std::string& file_path)
|
|||
void TestEgrMapFromIDB()
|
||||
{
|
||||
dmInst->init("/data/yhqiu/benchmark/AiEDA/application/benchmark/28nm/gcd/config/db_default_config_test.json");
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::CongestionAPI congestion_api;
|
||||
ieval::OverflowSummary overflow_summary;
|
||||
ieval::EGRMapSummary egr_map_summary = congestion_api.egrMap();
|
||||
overflow_summary = congestion_api.egrOverflow();
|
||||
ieval::EGRMapSummary egr_map_summary = congestion_api.egrMap(stage);
|
||||
overflow_summary = congestion_api.egrOverflow(stage);
|
||||
|
||||
std::cout << "egr horizontal sum: " << egr_map_summary.horizontal_sum << std::endl;
|
||||
std::cout << "egr vertical sum: " << egr_map_summary.vertical_sum << std::endl;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ int main()
|
|||
|
||||
void TestDensityMap()
|
||||
{
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::DensityAPI density_api;
|
||||
|
||||
ieval::DensityRegion region;
|
||||
|
|
@ -78,17 +80,17 @@ void TestDensityMap()
|
|||
nets.push_back(net1);
|
||||
nets.push_back(net2);
|
||||
|
||||
ieval::CellMapSummary cell_map_summary = density_api.cellDensityMap(cells, region, grid_size);
|
||||
ieval::CellMapSummary cell_map_summary = density_api.cellDensityMap(cells, region, grid_size, stage);
|
||||
std::cout << "Macro density: " << cell_map_summary.macro_density << std::endl;
|
||||
std::cout << "StdCell density: " << cell_map_summary.stdcell_density << std::endl;
|
||||
std::cout << "AllCell density: " << cell_map_summary.allcell_density << std::endl;
|
||||
|
||||
ieval::PinMapSummary pin_map_summary = density_api.pinDensityMap(pins, region, grid_size, neighbor);
|
||||
ieval::PinMapSummary pin_map_summary = density_api.pinDensityMap(pins, region, grid_size, stage, neighbor);
|
||||
std::cout << "Macro pin density: " << pin_map_summary.macro_pin_density << std::endl;
|
||||
std::cout << "StdCell pin density: " << pin_map_summary.stdcell_pin_density << std::endl;
|
||||
std::cout << "AllCell pin density: " << pin_map_summary.allcell_pin_density << std::endl;
|
||||
|
||||
ieval::NetMapSummary net_map_summary = density_api.netDensityMap(nets, region, grid_size, neighbor);
|
||||
ieval::NetMapSummary net_map_summary = density_api.netDensityMap(nets, region, grid_size, stage, neighbor);
|
||||
std::cout << "Local net density: " << net_map_summary.local_net_density << std::endl;
|
||||
std::cout << "Global net density: " << net_map_summary.global_net_density << std::endl;
|
||||
std::cout << "All net density: " << net_map_summary.allnet_density << std::endl;
|
||||
|
|
@ -98,9 +100,10 @@ void TestDensityMapFromIDB()
|
|||
{
|
||||
dmInst->init("/data/yhqiu/benchmark/AiEDA/application/benchmark/28nm/gcd/config/db_default_config_test.json");
|
||||
int32_t grid_size = 2000;
|
||||
std::string stage = "place";
|
||||
|
||||
ieval::DensityAPI density_api;
|
||||
ieval::DensityMapSummary density_map_summary = density_api.densityMap(grid_size);
|
||||
ieval::DensityMapSummary density_map_summary = density_api.densityMap(stage, grid_size);
|
||||
|
||||
std::cout << "Macro density: " << density_map_summary.cell_map_summary.macro_density << std::endl;
|
||||
std::cout << "StdCell density: " << density_map_summary.cell_map_summary.stdcell_density << std::endl;
|
||||
|
|
@ -112,7 +115,7 @@ void TestDensityMapFromIDB()
|
|||
std::cout << "Global net density: " << density_map_summary.net_map_summary.global_net_density << std::endl;
|
||||
std::cout << "All net density: " << density_map_summary.net_map_summary.allnet_density << std::endl;
|
||||
|
||||
ieval::NetMapSummary net_map = density_api.netDensityMap(grid_size);
|
||||
ieval::NetMapSummary net_map = density_api.netDensityMap(stage, grid_size);
|
||||
std::cout << "Local net density: " << net_map.local_net_density << std::endl;
|
||||
std::cout << "Global net density: " << net_map.global_net_density << std::endl;
|
||||
std::cout << "All net density: " << net_map.allnet_density << std::endl;
|
||||
|
|
|
|||
|
|
@ -27,21 +27,22 @@ void TestTiming()
|
|||
// iPLAPIInst.initAPI("/data/project_share/dataset_baseline/gcd/workspace/config/iEDA_config/pl_default_config.json",
|
||||
// dmInst->get_idb_builder());
|
||||
// iPLAPIInst.runFlow();
|
||||
|
||||
|
||||
dmInst->init("/home/liweiguo/project/AiEDA/application/benchmark/28nm/gcd/config/iEDA_config/db_default_config.json");
|
||||
dmInst->init("/data/project_share/dataset_baseline/s15850/workspace/config/iEDA_config/db_default_config.json");
|
||||
auto config = dmInst->get_config();
|
||||
config.set_output_path("/home/liweiguo/project/iEDA/scripts/design/eval/result");
|
||||
dmInst->readLef(std::vector<std::string>{config.get_tech_lef_path()}, true);
|
||||
dmInst->readLef(config.get_lef_paths());
|
||||
dmInst->readDef("/home/liweiguo/project/AiEDA/application/benchmark/28nm/gcd/output/iEDA/result/gcd_place.def");
|
||||
dmInst->readDef("/data/project_share/dataset_baseline/s15850/workspace/output/iEDA/result/s15850_place.def.gz");
|
||||
|
||||
|
||||
auto timing_api = ieval::TimingAPI::getInst();
|
||||
timing_api->runSTA();
|
||||
auto* timing_api = ieval::TimingAPI::getInst();
|
||||
// timing_api->runSTA();
|
||||
timing_api->evalTiming("FLUTE");
|
||||
auto summary = timing_api->evalDesign();
|
||||
LOG_INFO << ">> Design Timing Evaluation: ";
|
||||
for (auto routing_type : {"HPWL", "FLUTE", "SALT", "EGR", "DR"}) {
|
||||
if (summary.contains(routing_type) == false) {
|
||||
continue;
|
||||
}
|
||||
auto timing_summary = summary[routing_type];
|
||||
LOG_INFO << "Routing type: " << routing_type;
|
||||
for (auto& clock_timing : timing_summary.clock_timings) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "congestion_api.h"
|
||||
#include "idm.h"
|
||||
#include "timing_api.hh"
|
||||
#include "union_api.h"
|
||||
#include "wirelength_api.h"
|
||||
|
||||
void TestBuildNetEval();
|
||||
|
||||
int main()
|
||||
{
|
||||
TestBuildNetEval();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TestBuildNetEval()
|
||||
{
|
||||
dmInst->init("/data/project_share/dataset_baseline/jpeg_encoder/workspace/config/iEDA_config/db_default_config_tmp.json");
|
||||
UNION_API_INST->initIDB();
|
||||
UNION_API_INST->initEGR(true);
|
||||
UNION_API_INST->initFlute();
|
||||
|
||||
std::cout << "Building net evaluation data...\n";
|
||||
|
||||
auto* idb_builder = dmInst->get_idb_builder();
|
||||
idb::IdbDesign* idb_design = idb_builder->get_def_service()->get_design();
|
||||
|
||||
CONGESTION_API_INST->evalNetInfoPure();
|
||||
WIRELENGTH_API_INST->evalNetInfoPure();
|
||||
ieval::TimingAPI::getInst()->evalTiming("EGR", true);
|
||||
ieval::TimingAPI::getInst()->evalTiming("HPWL");
|
||||
ieval::TimingAPI::getInst()->evalTiming("FLUTE");
|
||||
auto net_power_data = ieval::TimingAPI::getInst()->evalNetPower();
|
||||
|
||||
for (size_t i = 0; i < idb_design->get_net_list()->get_net_list().size(); i++) {
|
||||
auto* idb_net = idb_design->get_net_list()->get_net_list()[i];
|
||||
std::string net_name = idb_net->get_net_name();
|
||||
std::string net_type;
|
||||
|
||||
|
||||
int pin_num = CONGESTION_API_INST->findPinNumber(net_name);
|
||||
if (pin_num < 4) {
|
||||
continue;
|
||||
}
|
||||
int aspect_ratio = CONGESTION_API_INST->findAspectRatio(net_name);
|
||||
float l_ness = CONGESTION_API_INST->findLness(net_name);
|
||||
int32_t bbox_width = CONGESTION_API_INST->findBBoxWidth(net_name);
|
||||
int32_t bbox_height = CONGESTION_API_INST->findBBoxHeight(net_name);
|
||||
int64_t bbox_area = CONGESTION_API_INST->findBBoxArea(net_name);
|
||||
int32_t bbox_lx = CONGESTION_API_INST->findBBoxLx(net_name);
|
||||
int32_t bbox_ly = CONGESTION_API_INST->findBBoxLy(net_name);
|
||||
int32_t bbox_ux = CONGESTION_API_INST->findBBoxUx(net_name);
|
||||
int32_t bbox_uy = CONGESTION_API_INST->findBBoxUy(net_name);
|
||||
|
||||
int32_t hpwl = WIRELENGTH_API_INST->findNetHPWL(net_name);
|
||||
int32_t flute = WIRELENGTH_API_INST->findNetFLUTE(net_name);
|
||||
int32_t grwl = WIRELENGTH_API_INST->findNetGRWL(net_name);
|
||||
|
||||
net_name.erase(std::remove(net_name.begin(), net_name.end(), '\\'), net_name.end());
|
||||
|
||||
if (ieval::TimingAPI::getInst()->isClockNet(net_name)) {
|
||||
net_type = "clock";
|
||||
} else {
|
||||
net_type = "signal";
|
||||
}
|
||||
if (net_power_data["HPWL"].find(net_name) == net_power_data["HPWL"].end()
|
||||
|| net_power_data["FLUTE"].find(net_name) == net_power_data["FLUTE"].end()
|
||||
|| net_power_data["EGR"].find(net_name) == net_power_data["EGR"].end()) {
|
||||
std::cerr << "Error: net_name '" << net_name << "' not found in net_power_data.\n";
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
double hpwl_power = net_power_data["HPWL"][net_name];
|
||||
double flute_power = net_power_data["FLUTE"][net_name];
|
||||
double egr_power = net_power_data["EGR"][net_name];
|
||||
|
||||
if (net_name == "InvalidSymbol") {
|
||||
std::cout << net_name << ',' << net_type << "," << pin_num << ',' << aspect_ratio << ',' << bbox_width << "," << bbox_height << ","
|
||||
<< bbox_area << "," << bbox_lx << "," << bbox_ly << "," << bbox_ux << "," << bbox_uy << "," << l_ness << ',' << hpwl << ','
|
||||
<< flute << ',' << grwl << ',' << hpwl_power << ',' << flute_power << "," << egr_power << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ int main(int argc, char* argv[])
|
|||
// TestTotalWirelength();
|
||||
// TestNetWirelength();
|
||||
// TestPathWirelength();
|
||||
// TestEgrWirelength("./rt_temp_directory/initial_router/route.guide");
|
||||
// TestEgrWirelength("./rt_temp_directory/early_router/route.guide");
|
||||
if (argc > 1) {
|
||||
std::string workspace_path(argv[1]);
|
||||
std::cout << "workspace_path: " << workspace_path << std::endl;
|
||||
|
|
|
|||
|
|
@ -53,201 +53,201 @@ void CongestionEval::destroyInst()
|
|||
}
|
||||
}
|
||||
|
||||
string CongestionEval::evalHoriEGR(string rt_dir_path)
|
||||
string CongestionEval::evalHoriEGR(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalEGR(rt_dir_path, "horizontal", "egr_horizontal_overflow.csv");
|
||||
return evalEGR(rt_dir_path, "horizontal", stage + "_egr_horizontal_overflow.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalVertiEGR(string rt_dir_path)
|
||||
string CongestionEval::evalVertiEGR(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalEGR(rt_dir_path, "vertical", "egr_vertical_overflow.csv");
|
||||
return evalEGR(rt_dir_path, "vertical", stage + "_egr_vertical_overflow.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalUnionEGR(string rt_dir_path)
|
||||
string CongestionEval::evalUnionEGR(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalEGR(rt_dir_path, "union", "egr_union_overflow.csv");
|
||||
return evalEGR(rt_dir_path, "union", stage + "_egr_union_overflow.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalHoriRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
string CongestionEval::evalHoriRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
return evalRUDY(nets, region, grid_size, "horizontal", "rudy_horizontal.csv");
|
||||
return evalRUDY(nets, region, grid_size, "horizontal", stage + "_rudy_horizontal.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalVertiRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
string CongestionEval::evalVertiRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
return evalRUDY(nets, region, grid_size, "vertical", "rudy_vertical.csv");
|
||||
return evalRUDY(nets, region, grid_size, "vertical", stage + "_rudy_vertical.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalUnionRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
string CongestionEval::evalUnionRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
return evalRUDY(nets, region, grid_size, "union", "rudy_union.csv");
|
||||
return evalRUDY(nets, region, grid_size, "union", stage + "_rudy_union.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalHoriLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
string CongestionEval::evalHoriLUTRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
return evalLUTRUDY(nets, region, grid_size, "horizontal", "lut_rudy_horizontal.csv");
|
||||
return evalLUTRUDY(nets, region, grid_size, "horizontal", stage + "_lut_rudy_horizontal.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalVertiLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
string CongestionEval::evalVertiLUTRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
return evalLUTRUDY(nets, region, grid_size, "vertical", "lut_rudy_vertical.csv");
|
||||
return evalLUTRUDY(nets, region, grid_size, "vertical", stage + "_lut_rudy_vertical.csv");
|
||||
}
|
||||
|
||||
string CongestionEval::evalUnionLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
string CongestionEval::evalUnionLUTRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size)
|
||||
{
|
||||
return evalLUTRUDY(nets, region, grid_size, "union", "lut_rudy_union.csv");
|
||||
return evalLUTRUDY(nets, region, grid_size, "union", stage + "_lut_rudy_union.csv");
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalHoriTotalOverflow(string rt_dir_path)
|
||||
int32_t CongestionEval::evalHoriTotalOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalTotalOverflow(rt_dir_path, "horizontal");
|
||||
return evalTotalOverflow(stage, rt_dir_path, "horizontal");
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalVertiTotalOverflow(string rt_dir_path)
|
||||
int32_t CongestionEval::evalVertiTotalOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalTotalOverflow(rt_dir_path, "vertical");
|
||||
return evalTotalOverflow(stage, rt_dir_path, "vertical");
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalUnionTotalOverflow(string rt_dir_path)
|
||||
int32_t CongestionEval::evalUnionTotalOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalTotalOverflow(rt_dir_path, "union");
|
||||
return evalTotalOverflow(stage, rt_dir_path, "union");
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalHoriMaxOverflow(string rt_dir_path)
|
||||
int32_t CongestionEval::evalHoriMaxOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalMaxOverflow(rt_dir_path, "horizontal");
|
||||
return evalMaxOverflow(stage, rt_dir_path, "horizontal");
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalVertiMaxOverflow(string rt_dir_path)
|
||||
int32_t CongestionEval::evalVertiMaxOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalMaxOverflow(rt_dir_path, "vertical");
|
||||
return evalMaxOverflow(stage, rt_dir_path, "vertical");
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalUnionMaxOverflow(string rt_dir_path)
|
||||
int32_t CongestionEval::evalUnionMaxOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalMaxOverflow(rt_dir_path, "union");
|
||||
return evalMaxOverflow(stage, rt_dir_path, "union");
|
||||
}
|
||||
|
||||
float CongestionEval::evalHoriAvgOverflow(string rt_dir_path)
|
||||
float CongestionEval::evalHoriAvgOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalAvgOverflow(rt_dir_path, "horizontal");
|
||||
return evalAvgOverflow(stage, rt_dir_path, "horizontal");
|
||||
}
|
||||
|
||||
float CongestionEval::evalVertiAvgOverflow(string rt_dir_path)
|
||||
float CongestionEval::evalVertiAvgOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalAvgOverflow(rt_dir_path, "vertical");
|
||||
return evalAvgOverflow(stage, rt_dir_path, "vertical");
|
||||
}
|
||||
|
||||
float CongestionEval::evalUnionAvgOverflow(string rt_dir_path)
|
||||
float CongestionEval::evalUnionAvgOverflow(string stage, string rt_dir_path)
|
||||
{
|
||||
return evalAvgOverflow(rt_dir_path, "union");
|
||||
return evalAvgOverflow(stage, rt_dir_path, "union");
|
||||
}
|
||||
|
||||
float CongestionEval::evalHoriMaxUtilization(string rudy_dir_path, bool use_lut)
|
||||
float CongestionEval::evalHoriMaxUtilization(string stage, string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
return evalMaxUtilization(rudy_dir_path, "horizontal", use_lut);
|
||||
return evalMaxUtilization(stage, rudy_dir_path, "horizontal", use_lut);
|
||||
}
|
||||
|
||||
float CongestionEval::evalVertiMaxUtilization(string rudy_dir_path, bool use_lut)
|
||||
float CongestionEval::evalVertiMaxUtilization(string stage, string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
return evalMaxUtilization(rudy_dir_path, "vertical", use_lut);
|
||||
return evalMaxUtilization(stage, rudy_dir_path, "vertical", use_lut);
|
||||
}
|
||||
|
||||
float CongestionEval::evalUnionMaxUtilization(string rudy_dir_path, bool use_lut)
|
||||
float CongestionEval::evalUnionMaxUtilization(string stage, string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
return evalMaxUtilization(rudy_dir_path, "union", use_lut);
|
||||
return evalMaxUtilization(stage, rudy_dir_path, "union", use_lut);
|
||||
}
|
||||
|
||||
float CongestionEval::evalHoriAvgUtilization(string rudy_dir_path, bool use_lut)
|
||||
float CongestionEval::evalHoriAvgUtilization(string stage, string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
return evalAvgUtilization(rudy_dir_path, "horizontal", use_lut);
|
||||
return evalAvgUtilization(stage, rudy_dir_path, "horizontal", use_lut);
|
||||
}
|
||||
|
||||
float CongestionEval::evalVertiAvgUtilization(string rudy_dir_path, bool use_lut)
|
||||
float CongestionEval::evalVertiAvgUtilization(string stage, string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
return evalAvgUtilization(rudy_dir_path, "vertical", use_lut);
|
||||
return evalAvgUtilization(stage, rudy_dir_path, "vertical", use_lut);
|
||||
}
|
||||
|
||||
float CongestionEval::evalUnionAvgUtilization(string rudy_dir_path, bool use_lut)
|
||||
float CongestionEval::evalUnionAvgUtilization(string stage, string rudy_dir_path, bool use_lut)
|
||||
{
|
||||
return evalAvgUtilization(rudy_dir_path, "union", use_lut);
|
||||
return evalAvgUtilization(stage, rudy_dir_path, "union", use_lut);
|
||||
}
|
||||
|
||||
string CongestionEval::evalEGR(string rt_dir_path, string egr_type, string output_filename)
|
||||
{
|
||||
std::unordered_map<std::string, LayerDirection> layer_directions
|
||||
= EVAL_INIT_EGR_INST->parseLayerDirection(rt_dir_path + "/initial_router/route.guide");
|
||||
= EVAL_INIT_EGR_INST->parseLayerDirection(rt_dir_path + "/early_router/route.guide");
|
||||
|
||||
// for (const auto& [layer, direction] : LayerDirections) {
|
||||
// std::cout << "Layer: " << layer << ", Direction: " << (direction == LayerDirection::Horizontal ? "Horizontal" : "Vertical")
|
||||
// << std::endl;
|
||||
// }
|
||||
std::vector<std::string> target_layers;
|
||||
std::string dir_path = rt_dir_path + "/initial_router/";
|
||||
std::string dir_path = rt_dir_path + "/early_router/";
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path out_file_path = parent_path / output_filename;
|
||||
|
||||
if (egr_type == "horizontal" || egr_type == "vertical") {
|
||||
LayerDirection target_direction = (egr_type == "horizontal") ? LayerDirection::Horizontal : LayerDirection::Vertical;
|
||||
|
||||
for (const auto& [layer, direction] : layer_directions) {
|
||||
if (direction == target_direction) {
|
||||
target_layers.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> sum_matrix;
|
||||
bool is_first_file = true;
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dir_path)) {
|
||||
std::string filename = entry.path().filename().string();
|
||||
if (filename.find("overflow_map_") != std::string::npos) {
|
||||
for (const auto& layer : target_layers) {
|
||||
if (filename.find(layer) != std::string::npos) {
|
||||
std::ifstream file(entry.path());
|
||||
std::string line;
|
||||
size_t row = 0;
|
||||
while (std::getline(file, line)) {
|
||||
std::istringstream iss(line);
|
||||
std::string value;
|
||||
int col = 0;
|
||||
while (std::getline(iss, value, ',')) {
|
||||
double num_value = std::stod(value);
|
||||
if (is_first_file) {
|
||||
if (row >= sum_matrix.size()) {
|
||||
sum_matrix.push_back(std::vector<double>());
|
||||
}
|
||||
sum_matrix[row].push_back(num_value);
|
||||
} else {
|
||||
sum_matrix[row][col] += num_value;
|
||||
}
|
||||
col++;
|
||||
}
|
||||
row++;
|
||||
}
|
||||
is_first_file = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream out_file(out_file_path);
|
||||
for (const auto& row : sum_matrix) {
|
||||
for (size_t i = 0; i < row.size(); ++i) {
|
||||
out_file << row[i];
|
||||
if (i < row.size() - 1) {
|
||||
out_file << ",";
|
||||
}
|
||||
}
|
||||
out_file << "\n";
|
||||
}
|
||||
out_file.close();
|
||||
} else if (egr_type == "union") {
|
||||
dir_path = rt_dir_path + "/topology_generator/";
|
||||
std::string source_file = dir_path + "overflow_map_planar.csv";
|
||||
std::filesystem::copy_file(source_file, out_file_path, std::filesystem::copy_options::overwrite_existing);
|
||||
for (const auto& [layer, direction] : layer_directions) {
|
||||
target_layers.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> sum_matrix;
|
||||
bool is_first_file = true;
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(dir_path)) {
|
||||
std::string filename = entry.path().filename().string();
|
||||
if (filename.find("overflow_map_") != std::string::npos) {
|
||||
for (const auto& layer : target_layers) {
|
||||
if (filename.find(layer) != std::string::npos) {
|
||||
std::ifstream file(entry.path());
|
||||
std::string line;
|
||||
size_t row = 0;
|
||||
while (std::getline(file, line)) {
|
||||
std::istringstream iss(line);
|
||||
std::string value;
|
||||
int col = 0;
|
||||
while (std::getline(iss, value, ',')) {
|
||||
double num_value = std::stod(value);
|
||||
if (is_first_file) {
|
||||
if (row >= sum_matrix.size()) {
|
||||
sum_matrix.push_back(std::vector<double>());
|
||||
}
|
||||
sum_matrix[row].push_back(num_value);
|
||||
} else {
|
||||
sum_matrix[row][col] += num_value;
|
||||
}
|
||||
col++;
|
||||
}
|
||||
row++;
|
||||
}
|
||||
is_first_file = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream out_file(out_file_path);
|
||||
for (const auto& row : sum_matrix) {
|
||||
for (size_t i = 0; i < row.size(); ++i) {
|
||||
out_file << row[i];
|
||||
if (i < row.size() - 1) {
|
||||
out_file << ",";
|
||||
}
|
||||
}
|
||||
out_file << "\n";
|
||||
}
|
||||
out_file.close();
|
||||
|
||||
return out_file_path.string();
|
||||
}
|
||||
|
||||
|
|
@ -371,13 +371,13 @@ string CongestionEval::evalLUTRUDY(CongestionNets nets, CongestionRegion region,
|
|||
int pin_num = net.pins.size();
|
||||
int aspect_ratio = 1;
|
||||
if (net_ux - net_lx >= net_uy - net_ly && net_uy - net_ly != 0) {
|
||||
aspect_ratio = std::round((net_ux - net_lx) / (net_uy - net_ly));
|
||||
aspect_ratio = std::round((net_ux - net_lx) / static_cast<double>(net_uy - net_ly));
|
||||
} else if (net_ux - net_lx < net_uy - net_ly && net_ux - net_lx != 0) {
|
||||
aspect_ratio = std::round((net_uy - net_ly) / (net_ux - net_lx));
|
||||
aspect_ratio = std::round((net_uy - net_ly) / static_cast<double>(net_ux - net_lx));
|
||||
}
|
||||
float l_ness = 0.f;
|
||||
double l_ness = 0.0;
|
||||
if (pin_num < 3) {
|
||||
l_ness = 1.f;
|
||||
l_ness = 1.0;
|
||||
} else if (pin_num <= 15) {
|
||||
std::vector<std::pair<int32_t, int32_t>> point_set;
|
||||
for (const auto& pin : net.pins) {
|
||||
|
|
@ -385,7 +385,7 @@ string CongestionEval::evalLUTRUDY(CongestionNets nets, CongestionRegion region,
|
|||
}
|
||||
l_ness = calculateLness(point_set, net_lx, net_ux, net_ly, net_uy);
|
||||
} else {
|
||||
l_ness = 0.5f;
|
||||
l_ness = 0.5;
|
||||
}
|
||||
|
||||
double hor_lutrudy = 0.0;
|
||||
|
|
@ -452,18 +452,18 @@ string CongestionEval::evalLUTRUDY(CongestionNets nets, CongestionRegion region,
|
|||
return getAbsoluteFilePath(output_path);
|
||||
}
|
||||
|
||||
float CongestionEval::calculateLness(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t net_lx, int32_t net_ux, int32_t net_ly,
|
||||
int32_t net_uy)
|
||||
double CongestionEval::calculateLness(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t net_lx, int32_t net_ux, int32_t net_ly,
|
||||
int32_t net_uy)
|
||||
{
|
||||
int32_t bbox = (net_ux - net_lx) * (net_uy - net_ly);
|
||||
int64_t bbox = static_cast<int64_t>(net_ux - net_lx) * static_cast<int64_t>(net_uy - net_ly);
|
||||
int32_t r1 = calcLowerLeftRP(point_set, net_lx, net_ly);
|
||||
int32_t r2 = calcLowerRightRP(point_set, net_ux, net_ly);
|
||||
int32_t r3 = calcUpperLeftRP(point_set, net_lx, net_uy);
|
||||
int32_t r4 = calcUpperRightRP(point_set, net_ux, net_uy);
|
||||
int32_t r = std::max({r1, r2, r3, r4});
|
||||
float l_ness;
|
||||
double l_ness;
|
||||
if (bbox != 0) {
|
||||
l_ness = r / bbox;
|
||||
l_ness = static_cast<double>(r) / static_cast<double>(bbox);
|
||||
} else {
|
||||
l_ness = 1.0;
|
||||
}
|
||||
|
|
@ -530,7 +530,7 @@ int32_t CongestionEval::calcUpperRightRP(std::vector<std::pair<int32_t, int32_t>
|
|||
return r;
|
||||
}
|
||||
|
||||
double CongestionEval::getLUT(int32_t pin_num, int32_t aspect_ratio, float l_ness)
|
||||
double CongestionEval::getLUT(int32_t pin_num, int32_t aspect_ratio, double l_ness)
|
||||
{
|
||||
int ar_index;
|
||||
if (aspect_ratio == 1) {
|
||||
|
|
@ -558,21 +558,21 @@ double CongestionEval::getLUT(int32_t pin_num, int32_t aspect_ratio, float l_nes
|
|||
return WIRELENGTH_LUT[ar_index][pin_index][l_index];
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalTotalOverflow(string rt_dir_path, string overflow_type)
|
||||
int32_t CongestionEval::evalTotalOverflow(string stage, string rt_dir_path, string overflow_type)
|
||||
{
|
||||
int32_t total_overflow = 0;
|
||||
std::string file_name;
|
||||
|
||||
if (overflow_type == "horizontal") {
|
||||
file_name = "egr_horizontal_overflow.csv";
|
||||
file_name = stage + "_egr_horizontal_overflow.csv";
|
||||
} else if (overflow_type == "vertical") {
|
||||
file_name = "egr_vertical_overflow.csv";
|
||||
file_name = stage + "_egr_vertical_overflow.csv";
|
||||
} else if (overflow_type == "union") {
|
||||
file_name = "egr_union_overflow.csv";
|
||||
file_name = stage + "_egr_union_overflow.csv";
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path file_path = parent_path / file_name;
|
||||
std::string file_path_str = file_path.string();
|
||||
|
||||
|
|
@ -594,21 +594,21 @@ int32_t CongestionEval::evalTotalOverflow(string rt_dir_path, string overflow_ty
|
|||
return total_overflow;
|
||||
}
|
||||
|
||||
int32_t CongestionEval::evalMaxOverflow(string rt_dir_path, string overflow_type)
|
||||
int32_t CongestionEval::evalMaxOverflow(string stage, string rt_dir_path, string overflow_type)
|
||||
{
|
||||
int32_t max_overflow = -1;
|
||||
std::string file_name;
|
||||
|
||||
if (overflow_type == "horizontal") {
|
||||
file_name = "egr_horizontal_overflow.csv";
|
||||
file_name = stage + "_egr_horizontal_overflow.csv";
|
||||
} else if (overflow_type == "vertical") {
|
||||
file_name = "egr_vertical_overflow.csv";
|
||||
file_name = stage + "_egr_vertical_overflow.csv";
|
||||
} else if (overflow_type == "union") {
|
||||
file_name = "egr_union_overflow.csv";
|
||||
file_name = stage + "_egr_union_overflow.csv";
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path file_path = parent_path / file_name;
|
||||
std::string file_path_str = file_path.string();
|
||||
|
||||
|
|
@ -631,21 +631,21 @@ int32_t CongestionEval::evalMaxOverflow(string rt_dir_path, string overflow_type
|
|||
return max_overflow;
|
||||
}
|
||||
|
||||
float CongestionEval::evalAvgOverflow(string rt_dir_path, string overflow_type)
|
||||
float CongestionEval::evalAvgOverflow(string stage, string rt_dir_path, string overflow_type)
|
||||
{
|
||||
float avg_overflow = 0.0f;
|
||||
std::string file_name;
|
||||
|
||||
if (overflow_type == "horizontal") {
|
||||
file_name = "egr_horizontal_overflow.csv";
|
||||
file_name = stage + "_egr_horizontal_overflow.csv";
|
||||
} else if (overflow_type == "vertical") {
|
||||
file_name = "egr_vertical_overflow.csv";
|
||||
file_name = stage + "_egr_vertical_overflow.csv";
|
||||
} else if (overflow_type == "union") {
|
||||
file_name = "egr_union_overflow.csv";
|
||||
file_name = stage + "_egr_union_overflow.csv";
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path parent_path = std::filesystem::path(rt_dir_path).parent_path();
|
||||
std::filesystem::path file_path = parent_path / file_name;
|
||||
std::string file_path_str = file_path.string();
|
||||
|
||||
|
|
@ -714,16 +714,16 @@ float CongestionEval::evalAvgOverflow(string rt_dir_path, string overflow_type)
|
|||
return avg_overflow;
|
||||
}
|
||||
|
||||
float CongestionEval::evalMaxUtilization(string map_path, string utilization_type, bool use_lut)
|
||||
float CongestionEval::evalMaxUtilization(string stage, string map_path, string utilization_type, bool use_lut)
|
||||
{
|
||||
float max_util = -1.0;
|
||||
std::string file_path;
|
||||
std::string file_name;
|
||||
|
||||
if (use_lut == true) {
|
||||
file_name = "/lut_rudy_";
|
||||
file_name = "/" + stage + "_lut_rudy_";
|
||||
} else {
|
||||
file_name = "/rudy_";
|
||||
file_name = "/" + stage + "_rudy_";
|
||||
}
|
||||
|
||||
if (utilization_type == "horizontal") {
|
||||
|
|
@ -755,16 +755,16 @@ float CongestionEval::evalMaxUtilization(string map_path, string utilization_typ
|
|||
return max_util;
|
||||
}
|
||||
|
||||
float CongestionEval::evalAvgUtilization(string rudy_dir_path, string utilization_type, bool use_lut)
|
||||
float CongestionEval::evalAvgUtilization(string stage, string rudy_dir_path, string utilization_type, bool use_lut)
|
||||
{
|
||||
float avg_util = 0.0f;
|
||||
std::string file_path;
|
||||
std::string file_name;
|
||||
|
||||
if (use_lut == true) {
|
||||
file_name = "/lut_rudy_";
|
||||
file_name = "/" + stage + "_lut_rudy_";
|
||||
} else {
|
||||
file_name = "/rudy_";
|
||||
file_name = "/" + stage + "_rudy_";
|
||||
}
|
||||
|
||||
if (utilization_type == "horizontal") {
|
||||
|
|
@ -900,14 +900,14 @@ void CongestionEval::evalNetInfo()
|
|||
|
||||
int aspect_ratio = 1;
|
||||
if (net_ux - net_lx >= net_uy - net_ly && net_uy - net_ly != 0) {
|
||||
aspect_ratio = std::round((net_ux - net_lx) / (net_uy - net_ly));
|
||||
aspect_ratio = std::round((net_ux - net_lx) / static_cast<double>(net_uy - net_ly));
|
||||
} else if (net_ux - net_lx < net_uy - net_ly && net_ux - net_lx != 0) {
|
||||
aspect_ratio = std::round((net_uy - net_ly) / (net_ux - net_lx));
|
||||
aspect_ratio = std::round((net_uy - net_ly) / static_cast<double>(net_ux - net_lx));
|
||||
}
|
||||
|
||||
float l_ness = 0.f;
|
||||
double l_ness = 0.0;
|
||||
if (pin_num < 3) {
|
||||
l_ness = 1.f;
|
||||
l_ness = 1.0;
|
||||
} else if (pin_num <= 15) {
|
||||
std::vector<std::pair<int32_t, int32_t>> point_set;
|
||||
for (const auto& pin : net.pins) {
|
||||
|
|
@ -915,12 +915,27 @@ void CongestionEval::evalNetInfo()
|
|||
}
|
||||
l_ness = calculateLness(point_set, net_lx, net_ux, net_ly, net_uy);
|
||||
} else {
|
||||
l_ness = 0.5f;
|
||||
l_ness = 0.5;
|
||||
}
|
||||
|
||||
int32_t bbox_width = net_ux - net_lx;
|
||||
int32_t bbox_height = net_uy - net_ly;
|
||||
int64_t bbox_area = static_cast<int64_t>(bbox_width) * static_cast<int64_t>(bbox_height);
|
||||
int32_t bbox_lx = net_lx;
|
||||
int32_t bbox_ly = net_ly;
|
||||
int32_t bbox_ux = net_ux;
|
||||
int32_t bbox_uy = net_uy;
|
||||
|
||||
_name_pin_numer.emplace(net.name, pin_num);
|
||||
_name_aspect_ratio.emplace(net.name, aspect_ratio);
|
||||
_name_lness.emplace(net.name, l_ness);
|
||||
_name_bbox_width.emplace(net.name, bbox_width);
|
||||
_name_bbox_height.emplace(net.name, bbox_height);
|
||||
_name_bbox_area.emplace(net.name, bbox_area);
|
||||
_name_bbox_lx.emplace(net.name, bbox_lx);
|
||||
_name_bbox_ly.emplace(net.name, bbox_ly);
|
||||
_name_bbox_ux.emplace(net.name, bbox_ux);
|
||||
_name_bbox_uy.emplace(net.name, bbox_uy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -942,7 +957,7 @@ int CongestionEval::findAspectRatio(std::string net_name)
|
|||
throw std::runtime_error("Aspect ratio not found for net: " + net_name);
|
||||
}
|
||||
|
||||
float CongestionEval::findLness(std::string net_name)
|
||||
double CongestionEval::findLness(std::string net_name)
|
||||
{
|
||||
auto it = _name_lness.find(net_name);
|
||||
if (it != _name_lness.end()) {
|
||||
|
|
@ -951,6 +966,69 @@ float CongestionEval::findLness(std::string net_name)
|
|||
throw std::runtime_error("Lness not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionEval::findBBoxWidth(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_width.find(net_name);
|
||||
if (it != _name_bbox_width.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox width not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionEval::findBBoxHeight(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_height.find(net_name);
|
||||
if (it != _name_bbox_height.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox height not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int64_t CongestionEval::findBBoxArea(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_area.find(net_name);
|
||||
if (it != _name_bbox_area.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox area not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionEval::findBBoxLx(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_lx.find(net_name);
|
||||
if (it != _name_bbox_lx.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox lx not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionEval::findBBoxLy(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_ly.find(net_name);
|
||||
if (it != _name_bbox_ly.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox ly not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionEval::findBBoxUx(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_ux.find(net_name);
|
||||
if (it != _name_bbox_ux.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox ux not found for net: " + net_name);
|
||||
}
|
||||
|
||||
int32_t CongestionEval::findBBoxUy(std::string net_name)
|
||||
{
|
||||
auto it = _name_bbox_uy.find(net_name);
|
||||
if (it != _name_bbox_uy.end()) {
|
||||
return it->second;
|
||||
}
|
||||
throw std::runtime_error("BBox uy not found for net: " + net_name);
|
||||
}
|
||||
|
||||
std::string CongestionEval::getEGRDirPath()
|
||||
{
|
||||
return EVAL_INIT_EGR_INST->getEGRDirPath();
|
||||
|
|
@ -961,4 +1039,9 @@ std::string CongestionEval::getDefaultOutputDir()
|
|||
return getDefaultOutputPath();
|
||||
}
|
||||
|
||||
void CongestionEval::setEGRDirPath(std::string egr_dir_path)
|
||||
{
|
||||
EVAL_INIT_EGR_INST->setEGRDirPath(egr_dir_path);
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -22,37 +22,37 @@ class CongestionEval
|
|||
static CongestionEval* getInst();
|
||||
static void destroyInst();
|
||||
|
||||
string evalHoriEGR(string rt_dir_path);
|
||||
string evalVertiEGR(string rt_dir_path);
|
||||
string evalUnionEGR(string rt_dir_path);
|
||||
string evalHoriEGR(string stage, string rt_dir_path);
|
||||
string evalVertiEGR(string stage, string rt_dir_path);
|
||||
string evalUnionEGR(string stage, string rt_dir_path);
|
||||
|
||||
string evalHoriRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalVertiRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalUnionRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalHoriRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalVertiRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalUnionRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
|
||||
string evalHoriLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalVertiLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalUnionLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalHoriLUTRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalVertiLUTRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
string evalUnionLUTRUDY(string stage, CongestionNets nets, CongestionRegion region, int32_t grid_size);
|
||||
|
||||
int32_t evalHoriTotalOverflow(string rt_dir_path);
|
||||
int32_t evalVertiTotalOverflow(string rt_dir_path);
|
||||
int32_t evalUnionTotalOverflow(string rt_dir_path);
|
||||
int32_t evalHoriTotalOverflow(string stage, string rt_dir_path);
|
||||
int32_t evalVertiTotalOverflow(string stage, string rt_dir_path);
|
||||
int32_t evalUnionTotalOverflow(string stage, string rt_dir_path);
|
||||
|
||||
int32_t evalHoriMaxOverflow(string rt_dir_path);
|
||||
int32_t evalVertiMaxOverflow(string rt_dir_path);
|
||||
int32_t evalUnionMaxOverflow(string rt_dir_path);
|
||||
int32_t evalHoriMaxOverflow(string stage, string rt_dir_path);
|
||||
int32_t evalVertiMaxOverflow(string stage, string rt_dir_path);
|
||||
int32_t evalUnionMaxOverflow(string stage, string rt_dir_path);
|
||||
|
||||
float evalHoriAvgOverflow(string rt_dir_path);
|
||||
float evalVertiAvgOverflow(string rt_dir_path);
|
||||
float evalUnionAvgOverflow(string rt_dir_path);
|
||||
float evalHoriAvgOverflow(string stage, string rt_dir_path);
|
||||
float evalVertiAvgOverflow(string stage, string rt_dir_path);
|
||||
float evalUnionAvgOverflow(string stage, string rt_dir_path);
|
||||
|
||||
float evalHoriMaxUtilization(string rudy_dir_path, bool use_lut = false);
|
||||
float evalVertiMaxUtilization(string rudy_dir_path, bool use_lut = false);
|
||||
float evalUnionMaxUtilization(string rudy_dir_path, bool use_lut = false);
|
||||
float evalHoriMaxUtilization(string stage, string rudy_dir_path, bool use_lut = false);
|
||||
float evalVertiMaxUtilization(string stage, string rudy_dir_path, bool use_lut = false);
|
||||
float evalUnionMaxUtilization(string stage, string rudy_dir_path, bool use_lut = false);
|
||||
|
||||
float evalHoriAvgUtilization(string rudy_dir_path, bool use_lut = false);
|
||||
float evalVertiAvgUtilization(string rudy_dir_path, bool use_lut = false);
|
||||
float evalUnionAvgUtilization(string rudy_dir_path, bool use_lut = false);
|
||||
float evalHoriAvgUtilization(string stage, string rudy_dir_path, bool use_lut = false);
|
||||
float evalVertiAvgUtilization(string stage, string rudy_dir_path, bool use_lut = false);
|
||||
float evalUnionAvgUtilization(string stage, string rudy_dir_path, bool use_lut = false);
|
||||
|
||||
void initEGR();
|
||||
void destroyEGR();
|
||||
|
|
@ -65,32 +65,47 @@ class CongestionEval
|
|||
void evalNetInfo();
|
||||
int findPinNumber(std::string net_name);
|
||||
int findAspectRatio(std::string net_name);
|
||||
float findLness(std::string net_name);
|
||||
double findLness(std::string net_name);
|
||||
int32_t findBBoxWidth(std::string net_name);
|
||||
int32_t findBBoxHeight(std::string net_name);
|
||||
int64_t findBBoxArea(std::string net_name);
|
||||
int32_t findBBoxLx(std::string net_name);
|
||||
int32_t findBBoxLy(std::string net_name);
|
||||
int32_t findBBoxUx(std::string net_name);
|
||||
int32_t findBBoxUy(std::string net_name);
|
||||
|
||||
int32_t getRowHeight();
|
||||
std::string getEGRDirPath();
|
||||
std::string getDefaultOutputDir();
|
||||
void setEGRDirPath(std::string egr_dir_path);
|
||||
|
||||
private:
|
||||
static CongestionEval* _congestion_eval;
|
||||
|
||||
std::map<std::string, int> _name_pin_numer;
|
||||
std::map<std::string, int> _name_aspect_ratio;
|
||||
std::map<std::string, float> _name_lness;
|
||||
std::map<std::string, double> _name_lness;
|
||||
std::map<std::string, int32_t> _name_bbox_width;
|
||||
std::map<std::string, int32_t> _name_bbox_height;
|
||||
std::map<std::string, int64_t> _name_bbox_area;
|
||||
std::map<std::string, int32_t> _name_bbox_lx;
|
||||
std::map<std::string, int32_t> _name_bbox_ly;
|
||||
std::map<std::string, int32_t> _name_bbox_ux;
|
||||
std::map<std::string, int32_t> _name_bbox_uy;
|
||||
|
||||
string evalEGR(string rt_dir_path, string egr_type, string output_filename);
|
||||
string evalRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size, string rudy_type, string output_filename);
|
||||
string evalLUTRUDY(CongestionNets nets, CongestionRegion region, int32_t grid_size, string lutrudy_type, string output_filename);
|
||||
float calculateLness(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t net_lx, int32_t net_ux, int32_t net_ly, int32_t net_uy);
|
||||
double calculateLness(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t net_lx, int32_t net_ux, int32_t net_ly, int32_t net_uy);
|
||||
int32_t calcLowerLeftRP(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t x_min, int32_t y_min);
|
||||
int32_t calcLowerRightRP(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t x_max, int32_t y_min);
|
||||
int32_t calcUpperLeftRP(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t x_min, int32_t y_max);
|
||||
int32_t calcUpperRightRP(std::vector<std::pair<int32_t, int32_t>> point_set, int32_t x_max, int32_t y_max);
|
||||
double getLUT(int32_t pin_num, int32_t aspect_ratio, float l_ness);
|
||||
int32_t evalTotalOverflow(string rt_dir_path, string overflow_type);
|
||||
int32_t evalMaxOverflow(string rt_dir_path, string overflow_type);
|
||||
float evalAvgOverflow(string rt_dir_path, string overflow_type);
|
||||
float evalMaxUtilization(string rudy_dir_path, string utilization_type, bool use_lut = false);
|
||||
float evalAvgUtilization(string rudy_dir_path, string utilization_type, bool use_lut = false);
|
||||
double getLUT(int32_t pin_num, int32_t aspect_ratio, double l_ness);
|
||||
int32_t evalTotalOverflow(string stage, string rt_dir_path, string overflow_type);
|
||||
int32_t evalMaxOverflow(string stage, string rt_dir_path, string overflow_type);
|
||||
float evalAvgOverflow(string stage, string rt_dir_path, string overflow_type);
|
||||
float evalMaxUtilization(string stage, string rudy_dir_path, string utilization_type, bool use_lut = false);
|
||||
float evalAvgUtilization(string stage, string rudy_dir_path, string utilization_type, bool use_lut = false);
|
||||
};
|
||||
} // namespace ieval
|
||||
|
|
@ -49,49 +49,49 @@ void DensityEval::destroyInst()
|
|||
}
|
||||
}
|
||||
|
||||
std::string DensityEval::evalMacroDensity(DensityCells cells, DensityRegion region, int32_t grid_size)
|
||||
std::string DensityEval::evalMacroDensity(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage)
|
||||
{
|
||||
return evalDensity(cells, region, grid_size, "macro", "macro_density.csv");
|
||||
return evalDensity(cells, region, grid_size, "macro", stage + "_macro_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalStdCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size)
|
||||
std::string DensityEval::evalStdCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage)
|
||||
{
|
||||
return evalDensity(cells, region, grid_size, "stdcell", "stdcell_density.csv");
|
||||
return evalDensity(cells, region, grid_size, "stdcell", stage + "_stdcell_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalAllCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size)
|
||||
std::string DensityEval::evalAllCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage)
|
||||
{
|
||||
return evalDensity(cells, region, grid_size, "all", "allcell_density.csv");
|
||||
return evalDensity(cells, region, grid_size, "all", stage + "_allcell_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalMacroPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
std::string DensityEval::evalMacroPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
return evalPinDensity(pins, region, grid_size, neighbor, "macro", "macro_pin_density.csv");
|
||||
return evalPinDensity(pins, region, grid_size, neighbor, "macro", stage + "_macro_pin_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalStdCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
std::string DensityEval::evalStdCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
return evalPinDensity(pins, region, grid_size, neighbor, "stdcell", "stdcell_pin_density.csv");
|
||||
return evalPinDensity(pins, region, grid_size, neighbor, "stdcell", stage + "_stdcell_pin_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalAllCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
std::string DensityEval::evalAllCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
return evalPinDensity(pins, region, grid_size, neighbor, "all", "allcell_pin_density.csv");
|
||||
return evalPinDensity(pins, region, grid_size, neighbor, "all", stage + "_allcell_pin_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalLocalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
std::string DensityEval::evalLocalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
return evalNetDensity(nets, region, grid_size, neighbor, "local", "local_net_density.csv");
|
||||
return evalNetDensity(nets, region, grid_size, neighbor, "local", stage + "_local_net_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalGlobalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
std::string DensityEval::evalGlobalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
return evalNetDensity(nets, region, grid_size, neighbor, "global", "global_net_density.csv");
|
||||
return evalNetDensity(nets, region, grid_size, neighbor, "global", stage + "_global_net_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalAllNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor)
|
||||
std::string DensityEval::evalAllNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor)
|
||||
{
|
||||
return evalNetDensity(nets, region, grid_size, neighbor, "all", "allnet_density.csv");
|
||||
return evalNetDensity(nets, region, grid_size, neighbor, "all", stage + "_allnet_density.csv");
|
||||
}
|
||||
|
||||
std::string DensityEval::evalHorizonMargin(DensityCells cells, DensityRegion die, DensityRegion core, int32_t grid_size)
|
||||
|
|
|
|||
|
|
@ -27,17 +27,17 @@ class DensityEval
|
|||
static DensityEval* getInst();
|
||||
static void destroyInst();
|
||||
|
||||
std::string evalMacroDensity(DensityCells cells, DensityRegion region, int32_t grid_size);
|
||||
std::string evalStdCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size);
|
||||
std::string evalAllCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size);
|
||||
std::string evalMacroDensity(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage);
|
||||
std::string evalStdCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage);
|
||||
std::string evalAllCellDensity(DensityCells cells, DensityRegion region, int32_t grid_size, std::string stage);
|
||||
|
||||
std::string evalMacroPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
std::string evalStdCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
std::string evalAllCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
std::string evalMacroPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
std::string evalStdCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
std::string evalAllCellPinDensity(DensityPins pins, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
|
||||
std::string evalLocalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
std::string evalGlobalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
std::string evalAllNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, bool neighbor);
|
||||
std::string evalLocalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
std::string evalGlobalNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
std::string evalAllNetDensity(DensityNets nets, DensityRegion region, int32_t grid_size, std::string stage, bool neighbor);
|
||||
|
||||
std::string evalHorizonMargin(DensityCells cells, DensityRegion die, DensityRegion core, int32_t grid_size);
|
||||
std::string evalVerticalMargin(DensityCells cells, DensityRegion die, DensityRegion core, int32_t grid_size);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ void TimingEval::runSTA()
|
|||
EVAL_INIT_STA_INST->runSTA();
|
||||
}
|
||||
|
||||
void TimingEval::evalTiming(const std::string& routing_type, const bool& rt_done)
|
||||
{
|
||||
EVAL_INIT_STA_INST->evalTiming(routing_type, rt_done);
|
||||
}
|
||||
|
||||
void TimingEval::destroyInst()
|
||||
{
|
||||
delete _timing_eval;
|
||||
|
|
@ -111,4 +116,9 @@ void TimingEval::updateTiming(const std::vector<TimingNet*>& timing_net_list, co
|
|||
EVAL_INIT_STA_INST->updateTiming(timing_net_list, name_list, propagation_level, dbu_unit);
|
||||
}
|
||||
|
||||
bool TimingEval::isClockNet(const std::string& net_name) const
|
||||
{
|
||||
return EVAL_INIT_STA_INST->isClockNet(net_name);
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -5,6 +5,9 @@
|
|||
* @date 2024-08-28
|
||||
* @brief evaluation with timing & power
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
|
@ -23,7 +26,8 @@ class TimingEval
|
|||
~TimingEval() = default;
|
||||
static TimingEval* getInst();
|
||||
|
||||
static void runSTA();
|
||||
void runSTA();
|
||||
void evalTiming(const std::string& routing_type, const bool& rt_done = false);
|
||||
|
||||
static void destroyInst();
|
||||
|
||||
|
|
@ -44,6 +48,8 @@ class TimingEval
|
|||
void updateTiming(const std::vector<TimingNet*>& timing_net_list, const std::vector<std::string>& name_list, const int& propagation_level,
|
||||
int32_t dbu_unit);
|
||||
|
||||
bool isClockNet(const std::string& net_name) const;
|
||||
|
||||
private:
|
||||
static TimingEval* _timing_eval;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ int32_t WirelengthEval::evalTotalVTree()
|
|||
|
||||
int32_t WirelengthEval::evalTotalEGRWL()
|
||||
{
|
||||
return evalTotalEGRWL(EVAL_INIT_EGR_INST->getEGRDirPath() + "/initial_router/route.guide");
|
||||
return evalTotalEGRWL(EVAL_INIT_EGR_INST->getEGRDirPath() + "/early_router/route.guide");
|
||||
}
|
||||
|
||||
int32_t WirelengthEval::evalNetHPWL(PointSet point_set)
|
||||
|
|
@ -429,10 +429,11 @@ void WirelengthEval::destroyFlute()
|
|||
void WirelengthEval::evalNetInfo()
|
||||
{
|
||||
auto name_pointset = getNamePointSet();
|
||||
EVAL_INIT_EGR_INST->parseGuideFile(EVAL_INIT_EGR_INST->getEGRDirPath() + "/early_router/route.guide");
|
||||
for (const auto& [net_name, point_set] : name_pointset) {
|
||||
_name_hpwl[net_name] = evalNetHPWL(point_set);
|
||||
_name_flute[net_name] = evalNetFLUTE(point_set);
|
||||
_name_grwl[net_name] = evalNetEGRWL(EVAL_INIT_EGR_INST->getEGRDirPath() + "/initial_router/route.guide", net_name) * getDesignUnit();
|
||||
_name_grwl[net_name] = EVAL_INIT_EGR_INST->getNetEGRWL(net_name) * getDesignUnit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,12 +48,21 @@ void InitEGR::destroyInst()
|
|||
}
|
||||
}
|
||||
|
||||
void InitEGR::runEGR()
|
||||
void InitEGR::runEGR(bool enable_timing)
|
||||
{
|
||||
irt::RTInterface& rt_interface = irt::RTInterface::getInst();
|
||||
auto* idb_layout = dmInst->get_idb_lef_service()->get_layout();
|
||||
auto routing_layers = idb_layout->get_layers()->get_routing_layers();
|
||||
auto logic_layer_name = routing_layers.size() >= 2 ? routing_layers[1]->get_name() : routing_layers[0]->get_name();
|
||||
auto clock_layer_name = routing_layers.size() >= 4 ? routing_layers[routing_layers.size() - 4]->get_name() : logic_layer_name;
|
||||
std::map<std::string, std::any> config_map;
|
||||
config_map.insert({"-temp_directory_path", _egr_dir_path});
|
||||
config_map.insert({"-output_inter_result", 1});
|
||||
config_map.insert({"-bottom_routing_layer", logic_layer_name}); // only for 28nm
|
||||
config_map.insert({"-top_routing_layer", clock_layer_name}); // only for 28nm
|
||||
if (enable_timing == true) {
|
||||
config_map.insert({"-enable_timing", 1});
|
||||
}
|
||||
rt_interface.initRT(config_map);
|
||||
rt_interface.runEGR();
|
||||
rt_interface.destroyRT();
|
||||
|
|
@ -61,18 +70,25 @@ void InitEGR::runEGR()
|
|||
|
||||
float InitEGR::parseEGRWL(std::string guide_path)
|
||||
{
|
||||
float egr_wl = 0;
|
||||
parseGuideFile(guide_path);
|
||||
float total_egr_wl = 0.0;
|
||||
for (const auto& net : _net_lengths) {
|
||||
total_egr_wl += net.second;
|
||||
}
|
||||
return total_egr_wl;
|
||||
}
|
||||
|
||||
void InitEGR::parseGuideFile(const std::string& guide_path)
|
||||
{
|
||||
_net_lengths.clear();
|
||||
|
||||
std::ifstream file(guide_path);
|
||||
std::string line;
|
||||
std::map<std::string, float> net_lengths;
|
||||
std::string current_net;
|
||||
|
||||
struct Wire
|
||||
{
|
||||
int gx1, gy1, gx2, gy2;
|
||||
float rx1, ry1, rx2, ry2;
|
||||
std::string layer;
|
||||
};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
|
|
@ -86,24 +102,18 @@ float InitEGR::parseEGRWL(std::string guide_path)
|
|||
|
||||
if (type == "guide") {
|
||||
iss >> current_net;
|
||||
if (net_lengths.find(current_net) == net_lengths.end()) {
|
||||
net_lengths[current_net] = 0.0;
|
||||
if (_net_lengths.find(current_net) == _net_lengths.end()) {
|
||||
_net_lengths[current_net] = 0.0;
|
||||
}
|
||||
} else if (type == "wire") {
|
||||
Wire wire;
|
||||
iss >> wire.gx1 >> wire.gy1 >> wire.gx2 >> wire.gy2 >> wire.rx1 >> wire.ry1 >> wire.rx2 >> wire.ry2 >> wire.layer;
|
||||
float wire_length = fabs(wire.rx1 - wire.rx2) + fabs(wire.ry1 - wire.ry2);
|
||||
net_lengths[current_net] += wire_length;
|
||||
int gx1, gy1, gx2, gy2;
|
||||
std::string layer;
|
||||
iss >> gx1 >> gy1 >> gx2 >> gy2 >> wire.rx1 >> wire.ry1 >> wire.rx2 >> wire.ry2 >> layer;
|
||||
float wire_length = std::abs(wire.rx1 - wire.rx2) + std::abs(wire.ry1 - wire.ry2);
|
||||
_net_lengths[current_net] += wire_length;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& net : net_lengths) {
|
||||
// std::cout << "Net " << net.first << " wire length: " << net.second << std::endl;
|
||||
egr_wl += net.second;
|
||||
}
|
||||
|
||||
// std::cout << "Total wire length for all nets: " << egr_wl << std::endl;
|
||||
return egr_wl;
|
||||
}
|
||||
|
||||
float InitEGR::parseNetEGRWL(std::string guide_path, std::string net_name)
|
||||
|
|
@ -274,4 +284,13 @@ std::unordered_map<std::string, LayerDirection> InitEGR::parseLayerDirection(std
|
|||
return layer_directions;
|
||||
}
|
||||
|
||||
float InitEGR::getNetEGRWL(std::string net_name)
|
||||
{
|
||||
auto it = _net_lengths.find(net_name);
|
||||
if (it != _net_lengths.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -26,9 +26,12 @@ class InitEGR
|
|||
static InitEGR* getInst();
|
||||
static void destroyInst();
|
||||
|
||||
void runEGR();
|
||||
void runEGR(bool enable_timing = false);
|
||||
std::string getEGRDirPath() { return _egr_dir_path; }
|
||||
void setEGRDirPath(std::string egr_dir_path) { _egr_dir_path = egr_dir_path; }
|
||||
float getNetEGRWL(std::string net_name);
|
||||
|
||||
void parseGuideFile(const std::string& guide_path);
|
||||
float parseEGRWL(std::string guide_path);
|
||||
float parseNetEGRWL(std::string guide_path, std::string net_name);
|
||||
float parsePathEGRWL(std::string guide_path, std::string net_name, std::string load_name);
|
||||
|
|
@ -37,8 +40,8 @@ class InitEGR
|
|||
|
||||
private:
|
||||
static InitEGR* _init_egr;
|
||||
|
||||
std::string _egr_dir_path;
|
||||
std::unordered_map<std::string, float> _net_lengths;
|
||||
};
|
||||
|
||||
} // namespace ieval
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "api/PowerEngine.hh"
|
||||
#include "api/TimingEngine.hh"
|
||||
#include "api/TimingIDBAdapter.hh"
|
||||
#include "feature_irt.h"
|
||||
#include "idm.h"
|
||||
#include "salt/base/flute.h"
|
||||
#include "salt/salt.h"
|
||||
|
|
@ -62,10 +61,6 @@ void InitSTA::destroyInst()
|
|||
|
||||
void InitSTA::runSTA()
|
||||
{
|
||||
if (_sta_init) {
|
||||
return;
|
||||
}
|
||||
_sta_init = true;
|
||||
// auto routing_type_list = {"WLM", "HPWL", "FLUTE", "SALT", "EGR", "DR"}
|
||||
initStaEngine();
|
||||
auto routing_type_list = {"HPWL", "FLUTE", "SALT", "EGR", "DR"};
|
||||
|
|
@ -79,6 +74,136 @@ void InitSTA::runSTA()
|
|||
});
|
||||
}
|
||||
|
||||
void InitSTA::evalTiming(const std::string& routing_type, const bool& rt_done)
|
||||
{
|
||||
initStaEngine();
|
||||
if (routing_type == "EGR" || routing_type == "DR") {
|
||||
if (!rt_done) {
|
||||
callRT(routing_type);
|
||||
}
|
||||
} else {
|
||||
buildRCTree(routing_type);
|
||||
}
|
||||
|
||||
updateResult(routing_type);
|
||||
}
|
||||
|
||||
void InitSTA::leaglization(const std::vector<std::shared_ptr<salt::Pin>>& pins)
|
||||
{
|
||||
if (pins.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<std::pair<double, double>> loc_set;
|
||||
bool is_legal = true;
|
||||
for (size_t i = 0; i < pins.size(); ++i) {
|
||||
if (loc_set.contains(std::make_pair(pins[i]->loc.x, pins[i]->loc.y))) {
|
||||
is_legal = false;
|
||||
break;
|
||||
}
|
||||
loc_set.insert(std::make_pair(pins[i]->loc.x, pins[i]->loc.y));
|
||||
}
|
||||
if (is_legal) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find all duplicated locations, and move them to a new location, objective: no duplicated locations and minimum total movement
|
||||
// x: pin->loc.x
|
||||
// y: pin->loc.y
|
||||
// Step 1: Group pins by their (x, y) locations
|
||||
std::map<std::pair<int, int>, std::vector<std::shared_ptr<salt::Pin>>> loc_map;
|
||||
for (const auto& pin : pins) {
|
||||
std::pair<int, int> coord = {pin->loc.x, pin->loc.y};
|
||||
loc_map[coord].push_back(pin);
|
||||
}
|
||||
|
||||
// Step 2: Initialize a set to keep track of occupied locations
|
||||
std::unordered_set<long long> occupied;
|
||||
// Helper lambda to encode (x, y) into a unique key
|
||||
auto encode = [](int x, int y) -> long long {
|
||||
// Assuming x and y are within reasonable bounds to prevent overflow
|
||||
return static_cast<long long>(x) * 100000000 + y;
|
||||
};
|
||||
|
||||
// Populate the occupied set with initial locations
|
||||
for (const auto& [coord, pin_list] : loc_map) {
|
||||
occupied.insert(encode(coord.first, coord.second));
|
||||
}
|
||||
|
||||
// Step 3: Collect all pins that need to be moved
|
||||
std::vector<std::shared_ptr<salt::Pin>> pins_to_move;
|
||||
for (const auto& [coord, pin_list] : loc_map) {
|
||||
if (pin_list.size() > 1) {
|
||||
// Keep the first pin, move the rest
|
||||
for (size_t i = 1; i < pin_list.size(); ++i) {
|
||||
pins_to_move.push_back(pin_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Define directions for BFS (8-connected grid)
|
||||
const std::vector<std::pair<int, int>> directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
|
||||
|
||||
// Step 5: For each pin to move, find the nearest available location
|
||||
for (const auto& pin : pins_to_move) {
|
||||
int start_x = pin->loc.x;
|
||||
int start_y = pin->loc.y;
|
||||
|
||||
// BFS initialization
|
||||
std::queue<std::pair<int, int>> q;
|
||||
std::unordered_set<long long> visited;
|
||||
q.push({start_x, start_y});
|
||||
visited.insert(encode(start_x, start_y));
|
||||
|
||||
bool found = false;
|
||||
int new_x = start_x;
|
||||
int new_y = start_y;
|
||||
|
||||
while (!q.empty() && !found) {
|
||||
int current_level_size = q.size();
|
||||
for (int i = 0; i < current_level_size; ++i) {
|
||||
auto [x, y] = q.front();
|
||||
q.pop();
|
||||
|
||||
// Explore all directions
|
||||
for (const auto& [dx, dy] : directions) {
|
||||
int nx = x + dx;
|
||||
int ny = y + dy;
|
||||
long long key = encode(nx, ny);
|
||||
|
||||
if (visited.find(key) == visited.end()) {
|
||||
// Check if the location is free
|
||||
if (occupied.find(key) == occupied.end()) {
|
||||
// Found a free location
|
||||
new_x = nx;
|
||||
new_y = ny;
|
||||
occupied.insert(key);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
// Mark as visited and add to queue for further exploration
|
||||
visited.insert(key);
|
||||
q.push({nx, ny});
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// If no free location found in the immediate vicinity, expand the search
|
||||
// This can be optimized or have a maximum search radius
|
||||
// For simplicity, we'll assign a far away location
|
||||
LOG_FATAL << "No free location found for pin x=" << start_x << ", y=" << start_y;
|
||||
}
|
||||
|
||||
// Update the pin's location
|
||||
pin->loc.x = new_x;
|
||||
pin->loc.y = new_y;
|
||||
}
|
||||
}
|
||||
|
||||
void InitSTA::initStaEngine()
|
||||
{
|
||||
if (STA_INST->isBuildGraph()) {
|
||||
|
|
@ -100,8 +225,8 @@ void InitSTA::callRT(const std::string& routing_type)
|
|||
auto* idb_layout = dmInst->get_idb_lef_service()->get_layout();
|
||||
auto routing_layers = idb_layout->get_layers()->get_routing_layers();
|
||||
auto logic_layer_name = routing_layers.size() >= 2 ? routing_layers[1]->get_name() : routing_layers[0]->get_name();
|
||||
auto clock_layer_name = routing_layers.size() >= 3 ? routing_layers[routing_layers.size() - 3]->get_name() : logic_layer_name;
|
||||
// Hard Code, consider the clock layer is the last 3rd layer
|
||||
auto clock_layer_name = routing_layers.size() >= 4 ? routing_layers[routing_layers.size() - 4]->get_name() : logic_layer_name;
|
||||
// Hard Code, consider the clock layer is the last 4rd layer
|
||||
const std::string temp_path = dmInst->get_config().get_output_path() + "/rt/rt_temp_directory";
|
||||
config_map.insert({"-temp_directory_path", temp_path});
|
||||
config_map.insert({"-bottom_routing_layer", logic_layer_name});
|
||||
|
|
@ -143,7 +268,7 @@ void InitSTA::buildRCTree(const std::string& routing_type)
|
|||
auto routing_layers = idb_layout->get_layers()->get_routing_layers();
|
||||
auto logic_layer = routing_layers.size() >= 2 ? 2 : 1;
|
||||
auto clock_layer
|
||||
= routing_layers.size() >= 3 ? routing_layers.size() - 3 : logic_layer; // Hard Code, consider the clock layer is the last 3rd layer
|
||||
= routing_layers.size() >= 4 ? routing_layers.size() - 4 : logic_layer; // Hard Code, consider the clock layer is the last 3rd layer
|
||||
auto calc_res = [&](const bool& is_clock, const double& wirelength) {
|
||||
if (!is_clock) {
|
||||
return idb_adapter->getResistance(logic_layer, wirelength, width);
|
||||
|
|
@ -166,13 +291,17 @@ void InitSTA::buildRCTree(const std::string& routing_type)
|
|||
// WLM
|
||||
if (routing_type == "WLM") {
|
||||
LOG_ERROR << "STA does not support WLM, TBD...";
|
||||
auto loads = sta_net->getLoads();
|
||||
|
||||
if (loads.empty()) {
|
||||
continue;
|
||||
}
|
||||
auto* driver = sta_net->getDriver();
|
||||
auto front_node = STA_INST->makeOrFindRCTreeNode(driver);
|
||||
|
||||
double res = 0; // rc TBD
|
||||
double cap = 0; // rc TBD
|
||||
|
||||
auto loads = sta_net->getLoads();
|
||||
for (auto load : loads) {
|
||||
auto back_node = STA_INST->makeOrFindRCTreeNode(load);
|
||||
STA_INST->makeResistor(sta_net, front_node, back_node, res);
|
||||
|
|
@ -182,11 +311,16 @@ void InitSTA::buildRCTree(const std::string& routing_type)
|
|||
}
|
||||
|
||||
if (routing_type == "HPWL") {
|
||||
auto loads = sta_net->getLoads();
|
||||
|
||||
if (loads.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* driver = sta_net->getDriver();
|
||||
auto driver_loc = idb_adapter->idbLocation(driver);
|
||||
auto front_node = STA_INST->makeOrFindRCTreeNode(driver);
|
||||
|
||||
auto loads = sta_net->getLoads();
|
||||
for (auto load : loads) {
|
||||
auto load_loc = idb_adapter->idbLocation(load);
|
||||
auto wirelength = calc_length(driver_loc->get_x(), driver_loc->get_y(), load_loc->get_x(), load_loc->get_y());
|
||||
|
|
@ -202,7 +336,9 @@ void InitSTA::buildRCTree(const std::string& routing_type)
|
|||
if (routing_type == "FLUTE" || routing_type == "SALT") {
|
||||
std::vector<ista::DesignObject*> pin_ports = {sta_net->getDriver()};
|
||||
std::ranges::copy(sta_net->getLoads(), std::back_inserter(pin_ports));
|
||||
|
||||
if (pin_ports.size() < 2) {
|
||||
continue;
|
||||
}
|
||||
// makr rc node
|
||||
auto make_rc_node = [&](const std::shared_ptr<salt::TreeNode>& salt_node) {
|
||||
if (salt_node->pin) {
|
||||
|
|
@ -222,6 +358,7 @@ void InitSTA::buildRCTree(const std::string& routing_type)
|
|||
auto pin = std::make_shared<salt::Pin>(idb_loc->get_x(), idb_loc->get_y(), i);
|
||||
salt_pins.push_back(pin);
|
||||
}
|
||||
leaglization(salt_pins);
|
||||
salt::Net salt_net;
|
||||
salt_net.init(0, sta_net->get_name(), salt_pins);
|
||||
|
||||
|
|
@ -562,4 +699,9 @@ void InitSTA::updateTiming(const std::vector<TimingNet*>& timing_net_list, const
|
|||
STA_INST->updateTiming();
|
||||
}
|
||||
|
||||
bool InitSTA::isClockNet(const std::string& net_name) const
|
||||
{
|
||||
return STA_INST->isClockNet(net_name.c_str());
|
||||
}
|
||||
|
||||
} // namespace ieval
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
|
@ -31,6 +32,9 @@
|
|||
namespace ista {
|
||||
enum class AnalysisMode;
|
||||
}
|
||||
namespace salt {
|
||||
class Pin;
|
||||
}
|
||||
namespace ieval {
|
||||
|
||||
struct TimingNet;
|
||||
|
|
@ -43,6 +47,7 @@ class InitSTA
|
|||
static InitSTA* getInst();
|
||||
static void destroyInst();
|
||||
void runSTA();
|
||||
void evalTiming(const std::string& routing_type, const bool& rt_done = false);
|
||||
|
||||
std::map<std::string, std::map<std::string, std::map<std::string, double>>> getTiming() const { return _timing; }
|
||||
std::map<std::string, std::map<std::string, double>> getPower() const { return _power; }
|
||||
|
|
@ -62,7 +67,10 @@ class InitSTA
|
|||
void updateTiming(const std::vector<TimingNet*>& timing_net_list, const std::vector<std::string>& name_list, const int& propagation_level,
|
||||
int32_t dbu_unit);
|
||||
|
||||
bool isClockNet(const std::string& net_name) const;
|
||||
|
||||
private:
|
||||
void leaglization(const std::vector<std::shared_ptr<salt::Pin>>& pins);
|
||||
void initStaEngine();
|
||||
void callRT(const std::string& routing_type);
|
||||
void buildRCTree(const std::string& routing_type);
|
||||
|
|
@ -72,7 +80,6 @@ class InitSTA
|
|||
|
||||
static InitSTA* _init_sta;
|
||||
|
||||
bool _sta_init = false;
|
||||
std::map<std::string, std::map<std::string, std::map<std::string, double>>> _timing;
|
||||
std::map<std::string, std::map<std::string, double>> _power;
|
||||
std::map<std::string, std::unordered_map<std::string, double>> _net_power;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ add_library(feature_builder
|
|||
feature_eval_congestion.cpp
|
||||
feature_eval_density.cpp
|
||||
feature_eval_timing.cc
|
||||
|
||||
feature_eval_union.cpp
|
||||
)
|
||||
|
||||
target_include_directories(feature_builder
|
||||
|
|
@ -30,4 +32,5 @@ target_link_libraries(feature_builder
|
|||
eval_density_api
|
||||
eval_wirelength_api
|
||||
eval_timing_api
|
||||
eval_union_api
|
||||
)
|
||||
|
|
@ -63,6 +63,13 @@ class FeatureBuilder
|
|||
DensityMapSummary buildDensityEvalSummary(int32_t grid_size);
|
||||
CongestionSummary buildCongestionEvalSummary(int32_t grid_size);
|
||||
TimingEvalSummary buildTimingEvalSummary();
|
||||
TimingEvalSummary buildTimingUnionEvalSummary();
|
||||
void evalTiming(const std::string& routing_type, const bool& rt_done = false);
|
||||
|
||||
bool initEvalTool();
|
||||
UnionEvalSummary buildUnionEvalSummary(int32_t grid_size, std::string stage);
|
||||
bool buildNetEval(std::string csv_path);
|
||||
bool destroyEvalTool();
|
||||
|
||||
bool buildRouteData(RouteAnalyseData* data);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ PlaceSummary FeatureBuilder::buildPLSummary(std::string step)
|
|||
|
||||
RTSummary FeatureBuilder::buildRTSummary()
|
||||
{
|
||||
RTSummary summary = RTI.outputSummary();
|
||||
// RTSummary summary = RTI.getSummary();
|
||||
|
||||
return summary;
|
||||
// return summary;
|
||||
}
|
||||
|
||||
CTSSummary FeatureBuilder::buildCTSSummary()
|
||||
|
|
@ -71,7 +71,7 @@ NetOptSummary FeatureBuilder::buildNetOptSummary()
|
|||
TimingOptSummary FeatureBuilder::buildTimingOptSummary()
|
||||
{
|
||||
TimingOptSummary summary = ToApiInst.outputSummary();
|
||||
|
||||
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,51 +14,52 @@ CongestionSummary FeatureBuilder::buildCongestionEvalSummary(int32_t grid_size)
|
|||
{
|
||||
CongestionSummary congestion_summary;
|
||||
|
||||
ieval::EGRMapSummary eval_egr_map_summary = CONGESTION_API_INST->egrMap();
|
||||
congestion_summary.egr_map_summary.horizontal_sum = eval_egr_map_summary.horizontal_sum;
|
||||
congestion_summary.egr_map_summary.vertical_sum = eval_egr_map_summary.vertical_sum;
|
||||
congestion_summary.egr_map_summary.union_sum = eval_egr_map_summary.union_sum;
|
||||
// ieval::EGRMapSummary eval_egr_map_summary = CONGESTION_API_INST->egrMap();
|
||||
// congestion_summary.egr_map_summary.horizontal_sum = eval_egr_map_summary.horizontal_sum;
|
||||
// congestion_summary.egr_map_summary.vertical_sum = eval_egr_map_summary.vertical_sum;
|
||||
// congestion_summary.egr_map_summary.union_sum = eval_egr_map_summary.union_sum;
|
||||
|
||||
ieval::RUDYMapSummary eval_rudy_map_summary = CONGESTION_API_INST->rudyMap(grid_size);
|
||||
congestion_summary.rudy_map_summary.rudy_horizontal = eval_rudy_map_summary.rudy_horizontal;
|
||||
congestion_summary.rudy_map_summary.rudy_vertical = eval_rudy_map_summary.rudy_vertical;
|
||||
congestion_summary.rudy_map_summary.rudy_union = eval_rudy_map_summary.rudy_union;
|
||||
congestion_summary.rudy_map_summary.lutrudy_horizontal = eval_rudy_map_summary.lutrudy_horizontal;
|
||||
congestion_summary.rudy_map_summary.lutrudy_vertical = eval_rudy_map_summary.lutrudy_vertical;
|
||||
congestion_summary.rudy_map_summary.lutrudy_union = eval_rudy_map_summary.lutrudy_union;
|
||||
// ieval::RUDYMapSummary eval_rudy_map_summary = CONGESTION_API_INST->rudyMap(grid_size);
|
||||
// congestion_summary.rudy_map_summary.rudy_horizontal = eval_rudy_map_summary.rudy_horizontal;
|
||||
// congestion_summary.rudy_map_summary.rudy_vertical = eval_rudy_map_summary.rudy_vertical;
|
||||
// congestion_summary.rudy_map_summary.rudy_union = eval_rudy_map_summary.rudy_union;
|
||||
// congestion_summary.rudy_map_summary.lutrudy_horizontal = eval_rudy_map_summary.lutrudy_horizontal;
|
||||
// congestion_summary.rudy_map_summary.lutrudy_vertical = eval_rudy_map_summary.lutrudy_vertical;
|
||||
// congestion_summary.rudy_map_summary.lutrudy_union = eval_rudy_map_summary.lutrudy_union;
|
||||
|
||||
ieval::OverflowSummary eval_overflow_summary = CONGESTION_API_INST->egrOverflow();
|
||||
congestion_summary.overflow_summary.total_overflow_horizontal = eval_overflow_summary.total_overflow_horizontal;
|
||||
congestion_summary.overflow_summary.total_overflow_vertical = eval_overflow_summary.total_overflow_vertical;
|
||||
congestion_summary.overflow_summary.total_overflow_union = eval_overflow_summary.total_overflow_union;
|
||||
congestion_summary.overflow_summary.max_overflow_horizontal = eval_overflow_summary.max_overflow_horizontal;
|
||||
congestion_summary.overflow_summary.max_overflow_vertical = eval_overflow_summary.max_overflow_vertical;
|
||||
congestion_summary.overflow_summary.max_overflow_union = eval_overflow_summary.max_overflow_union;
|
||||
congestion_summary.overflow_summary.weighted_average_overflow_horizontal = eval_overflow_summary.weighted_average_overflow_horizontal;
|
||||
congestion_summary.overflow_summary.weighted_average_overflow_vertical = eval_overflow_summary.weighted_average_overflow_vertical;
|
||||
congestion_summary.overflow_summary.weighted_average_overflow_union = eval_overflow_summary.weighted_average_overflow_union;
|
||||
// ieval::OverflowSummary eval_overflow_summary = CONGESTION_API_INST->egrOverflow();
|
||||
// congestion_summary.overflow_summary.total_overflow_horizontal = eval_overflow_summary.total_overflow_horizontal;
|
||||
// congestion_summary.overflow_summary.total_overflow_vertical = eval_overflow_summary.total_overflow_vertical;
|
||||
// congestion_summary.overflow_summary.total_overflow_union = eval_overflow_summary.total_overflow_union;
|
||||
// congestion_summary.overflow_summary.max_overflow_horizontal = eval_overflow_summary.max_overflow_horizontal;
|
||||
// congestion_summary.overflow_summary.max_overflow_vertical = eval_overflow_summary.max_overflow_vertical;
|
||||
// congestion_summary.overflow_summary.max_overflow_union = eval_overflow_summary.max_overflow_union;
|
||||
// congestion_summary.overflow_summary.weighted_average_overflow_horizontal =
|
||||
// eval_overflow_summary.weighted_average_overflow_horizontal; congestion_summary.overflow_summary.weighted_average_overflow_vertical =
|
||||
// eval_overflow_summary.weighted_average_overflow_vertical; congestion_summary.overflow_summary.weighted_average_overflow_union =
|
||||
// eval_overflow_summary.weighted_average_overflow_union;
|
||||
|
||||
ieval::UtilizationSummary eval_utilization_summary = CONGESTION_API_INST->rudyUtilization(false);
|
||||
congestion_summary.rudy_utilization_summary.max_utilization_horizontal = eval_utilization_summary.max_utilization_horizontal;
|
||||
congestion_summary.rudy_utilization_summary.max_utilization_vertical = eval_utilization_summary.max_utilization_vertical;
|
||||
congestion_summary.rudy_utilization_summary.max_utilization_union = eval_utilization_summary.max_utilization_union;
|
||||
congestion_summary.rudy_utilization_summary.weighted_average_utilization_horizontal
|
||||
= eval_utilization_summary.weighted_average_utilization_horizontal;
|
||||
congestion_summary.rudy_utilization_summary.weighted_average_utilization_vertical
|
||||
= eval_utilization_summary.weighted_average_utilization_vertical;
|
||||
congestion_summary.rudy_utilization_summary.weighted_average_utilization_union
|
||||
= eval_utilization_summary.weighted_average_utilization_union;
|
||||
// ieval::UtilizationSummary eval_utilization_summary = CONGESTION_API_INST->rudyUtilization(false);
|
||||
// congestion_summary.rudy_utilization_summary.max_utilization_horizontal = eval_utilization_summary.max_utilization_horizontal;
|
||||
// congestion_summary.rudy_utilization_summary.max_utilization_vertical = eval_utilization_summary.max_utilization_vertical;
|
||||
// congestion_summary.rudy_utilization_summary.max_utilization_union = eval_utilization_summary.max_utilization_union;
|
||||
// congestion_summary.rudy_utilization_summary.weighted_average_utilization_horizontal
|
||||
// = eval_utilization_summary.weighted_average_utilization_horizontal;
|
||||
// congestion_summary.rudy_utilization_summary.weighted_average_utilization_vertical
|
||||
// = eval_utilization_summary.weighted_average_utilization_vertical;
|
||||
// congestion_summary.rudy_utilization_summary.weighted_average_utilization_union
|
||||
// = eval_utilization_summary.weighted_average_utilization_union;
|
||||
|
||||
ieval::UtilizationSummary eval_lut_utilization_summary = CONGESTION_API_INST->rudyUtilization(true);
|
||||
congestion_summary.lutrudy_utilization_summary.max_utilization_horizontal = eval_lut_utilization_summary.max_utilization_horizontal;
|
||||
congestion_summary.lutrudy_utilization_summary.max_utilization_vertical = eval_lut_utilization_summary.max_utilization_vertical;
|
||||
congestion_summary.lutrudy_utilization_summary.max_utilization_union = eval_lut_utilization_summary.max_utilization_union;
|
||||
congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_horizontal
|
||||
= eval_lut_utilization_summary.weighted_average_utilization_horizontal;
|
||||
congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_vertical
|
||||
= eval_lut_utilization_summary.weighted_average_utilization_vertical;
|
||||
congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_union
|
||||
= eval_lut_utilization_summary.weighted_average_utilization_union;
|
||||
// ieval::UtilizationSummary eval_lut_utilization_summary = CONGESTION_API_INST->rudyUtilization(true);
|
||||
// congestion_summary.lutrudy_utilization_summary.max_utilization_horizontal = eval_lut_utilization_summary.max_utilization_horizontal;
|
||||
// congestion_summary.lutrudy_utilization_summary.max_utilization_vertical = eval_lut_utilization_summary.max_utilization_vertical;
|
||||
// congestion_summary.lutrudy_utilization_summary.max_utilization_union = eval_lut_utilization_summary.max_utilization_union;
|
||||
// congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_horizontal
|
||||
// = eval_lut_utilization_summary.weighted_average_utilization_horizontal;
|
||||
// congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_vertical
|
||||
// = eval_lut_utilization_summary.weighted_average_utilization_vertical;
|
||||
// congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_union
|
||||
// = eval_lut_utilization_summary.weighted_average_utilization_union;
|
||||
|
||||
return congestion_summary;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,21 +14,21 @@ DensityMapSummary FeatureBuilder::buildDensityEvalSummary(int32_t grid_size)
|
|||
{
|
||||
DensityMapSummary density_map_summary;
|
||||
|
||||
ieval::DensityMapSummary eval_density_map_summary = DENSITY_API_INST->densityMap(grid_size);
|
||||
density_map_summary.cell_map_summary.macro_density = eval_density_map_summary.cell_map_summary.macro_density;
|
||||
density_map_summary.cell_map_summary.stdcell_density = eval_density_map_summary.cell_map_summary.stdcell_density;
|
||||
density_map_summary.cell_map_summary.allcell_density = eval_density_map_summary.cell_map_summary.allcell_density;
|
||||
density_map_summary.pin_map_summary.macro_pin_density = eval_density_map_summary.pin_map_summary.macro_pin_density;
|
||||
density_map_summary.pin_map_summary.stdcell_pin_density = eval_density_map_summary.pin_map_summary.stdcell_pin_density;
|
||||
density_map_summary.pin_map_summary.allcell_pin_density = eval_density_map_summary.pin_map_summary.allcell_pin_density;
|
||||
density_map_summary.net_map_summary.local_net_density = eval_density_map_summary.net_map_summary.local_net_density;
|
||||
density_map_summary.net_map_summary.global_net_density = eval_density_map_summary.net_map_summary.global_net_density;
|
||||
density_map_summary.net_map_summary.allnet_density = eval_density_map_summary.net_map_summary.allnet_density;
|
||||
|
||||
ieval::MacroMarginSummary eval_macro_margin_summary = DENSITY_API_INST->macroMarginMap(grid_size);
|
||||
density_map_summary.macro_margin_summary.horizontal_margin = eval_macro_margin_summary.horizontal_margin;
|
||||
density_map_summary.macro_margin_summary.vertical_margin = eval_macro_margin_summary.vertical_margin;
|
||||
density_map_summary.macro_margin_summary.union_margin = eval_macro_margin_summary.union_margin;
|
||||
// ieval::DensityMapSummary eval_density_map_summary = DENSITY_API_INST->densityMap(grid_size);
|
||||
// density_map_summary.cell_map_summary.macro_density = eval_density_map_summary.cell_map_summary.macro_density;
|
||||
// density_map_summary.cell_map_summary.stdcell_density = eval_density_map_summary.cell_map_summary.stdcell_density;
|
||||
// density_map_summary.cell_map_summary.allcell_density = eval_density_map_summary.cell_map_summary.allcell_density;
|
||||
// density_map_summary.pin_map_summary.macro_pin_density = eval_density_map_summary.pin_map_summary.macro_pin_density;
|
||||
// density_map_summary.pin_map_summary.stdcell_pin_density = eval_density_map_summary.pin_map_summary.stdcell_pin_density;
|
||||
// density_map_summary.pin_map_summary.allcell_pin_density = eval_density_map_summary.pin_map_summary.allcell_pin_density;
|
||||
// density_map_summary.net_map_summary.local_net_density = eval_density_map_summary.net_map_summary.local_net_density;
|
||||
// density_map_summary.net_map_summary.global_net_density = eval_density_map_summary.net_map_summary.global_net_density;
|
||||
// density_map_summary.net_map_summary.allnet_density = eval_density_map_summary.net_map_summary.allnet_density;
|
||||
|
||||
// ieval::MacroMarginSummary eval_macro_margin_summary = DENSITY_API_INST->macroMarginMap(grid_size);
|
||||
// density_map_summary.macro_margin_summary.horizontal_margin = eval_macro_margin_summary.horizontal_margin;
|
||||
// density_map_summary.macro_margin_summary.vertical_margin = eval_macro_margin_summary.vertical_margin;
|
||||
// density_map_summary.macro_margin_summary.union_margin = eval_macro_margin_summary.union_margin;
|
||||
|
||||
return density_map_summary;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,4 +77,74 @@ TimingEvalSummary FeatureBuilder::buildTimingEvalSummary()
|
|||
|
||||
return timing_eval_summary;
|
||||
}
|
||||
TimingEvalSummary FeatureBuilder::buildTimingUnionEvalSummary()
|
||||
{
|
||||
TimingEvalSummary timing_eval_summary;
|
||||
auto timing_summary = EVAL_STA_API_INST->evalDesign();
|
||||
if (timing_summary.contains("WLM")) {
|
||||
WlmTimingEvalSummary wlm_timing_eval_summary;
|
||||
auto wlm_timing_summary = timing_summary.at("WLM");
|
||||
std::ranges::for_each(wlm_timing_summary.clock_timings, [&wlm_timing_eval_summary](const auto& clock_timing) {
|
||||
wlm_timing_eval_summary.clock_timings.push_back({clock_timing.clock_name, clock_timing.setup_tns, clock_timing.setup_wns,
|
||||
clock_timing.hold_tns, clock_timing.hold_wns, clock_timing.suggest_freq});
|
||||
});
|
||||
wlm_timing_eval_summary.power_info = {wlm_timing_summary.static_power, wlm_timing_summary.dynamic_power};
|
||||
timing_eval_summary.wlm_timing_eval_summary = wlm_timing_eval_summary;
|
||||
}
|
||||
if (timing_summary.contains("HPWL")) {
|
||||
HpwlTimingEvalSummary hpwl_timing_eval_summary;
|
||||
auto hpwl_timing_summary = timing_summary.at("HPWL");
|
||||
std::ranges::for_each(hpwl_timing_summary.clock_timings, [&hpwl_timing_eval_summary](const auto& clock_timing) {
|
||||
hpwl_timing_eval_summary.clock_timings.push_back({clock_timing.clock_name, clock_timing.setup_tns, clock_timing.setup_wns,
|
||||
clock_timing.hold_tns, clock_timing.hold_wns, clock_timing.suggest_freq});
|
||||
});
|
||||
hpwl_timing_eval_summary.power_info = {hpwl_timing_summary.static_power, hpwl_timing_summary.dynamic_power};
|
||||
timing_eval_summary.hpwl_timing_eval_summary = hpwl_timing_eval_summary;
|
||||
}
|
||||
if (timing_summary.contains("FLUTE")) {
|
||||
FluteTimingEvalSummary flute_timing_eval_summary;
|
||||
auto flute_timing_summary = timing_summary.at("FLUTE");
|
||||
std::ranges::for_each(flute_timing_summary.clock_timings, [&flute_timing_eval_summary](const auto& clock_timing) {
|
||||
flute_timing_eval_summary.clock_timings.push_back({clock_timing.clock_name, clock_timing.setup_tns, clock_timing.setup_wns,
|
||||
clock_timing.hold_tns, clock_timing.hold_wns, clock_timing.suggest_freq});
|
||||
});
|
||||
flute_timing_eval_summary.power_info = {flute_timing_summary.static_power, flute_timing_summary.dynamic_power};
|
||||
timing_eval_summary.flute_timing_eval_summary = flute_timing_eval_summary;
|
||||
}
|
||||
if (timing_summary.contains("SALT")) {
|
||||
SaltTimingEvalSummary salt_timing_eval_summary;
|
||||
auto salt_timing_summary = timing_summary.at("SALT");
|
||||
std::ranges::for_each(salt_timing_summary.clock_timings, [&salt_timing_eval_summary](const auto& clock_timing) {
|
||||
salt_timing_eval_summary.clock_timings.push_back({clock_timing.clock_name, clock_timing.setup_tns, clock_timing.setup_wns,
|
||||
clock_timing.hold_tns, clock_timing.hold_wns, clock_timing.suggest_freq});
|
||||
});
|
||||
salt_timing_eval_summary.power_info = {salt_timing_summary.static_power, salt_timing_summary.dynamic_power};
|
||||
timing_eval_summary.salt_timing_eval_summary = salt_timing_eval_summary;
|
||||
}
|
||||
if (timing_summary.contains("EGR")) {
|
||||
EgrTimingEvalSummary egr_timing_eval_summary;
|
||||
auto egr_timing_summary = timing_summary.at("EGR");
|
||||
std::ranges::for_each(egr_timing_summary.clock_timings, [&egr_timing_eval_summary](const auto& clock_timing) {
|
||||
egr_timing_eval_summary.clock_timings.push_back({clock_timing.clock_name, clock_timing.setup_tns, clock_timing.setup_wns,
|
||||
clock_timing.hold_tns, clock_timing.hold_wns, clock_timing.suggest_freq});
|
||||
});
|
||||
egr_timing_eval_summary.power_info = {egr_timing_summary.static_power, egr_timing_summary.dynamic_power};
|
||||
timing_eval_summary.egr_timing_eval_summary = egr_timing_eval_summary;
|
||||
}
|
||||
if (timing_summary.contains("DR")) {
|
||||
DrTimingEvalSummary dr_timing_eval_summary;
|
||||
auto dr_timing_summary = timing_summary.at("DR");
|
||||
std::ranges::for_each(dr_timing_summary.clock_timings, [&dr_timing_eval_summary](const auto& clock_timing) {
|
||||
dr_timing_eval_summary.clock_timings.push_back({clock_timing.clock_name, clock_timing.setup_tns, clock_timing.setup_wns,
|
||||
clock_timing.hold_tns, clock_timing.hold_wns, clock_timing.suggest_freq});
|
||||
});
|
||||
dr_timing_eval_summary.power_info = {dr_timing_summary.static_power, dr_timing_summary.dynamic_power};
|
||||
timing_eval_summary.dr_timing_eval_summary = dr_timing_eval_summary;
|
||||
}
|
||||
return timing_eval_summary;
|
||||
}
|
||||
void FeatureBuilder::evalTiming(const std::string& routing_type, const bool& rt_done)
|
||||
{
|
||||
EVAL_STA_API_INST->evalTiming(routing_type, rt_done);
|
||||
}
|
||||
} // namespace ieda_feature
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* @FilePath: feature_eval_union.cpp
|
||||
* @Author: Yihang Qiu (qiuyihang23@mails.ucas.ac.cn)
|
||||
* @Date: 2024-10-11 11:00:07
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "congestion_api.h"
|
||||
#include "density_api.h"
|
||||
#include "feature_builder.h"
|
||||
#include "idm.h"
|
||||
#include "timing_api.hh"
|
||||
#include "union_api.h"
|
||||
#include "wirelength_api.h"
|
||||
|
||||
namespace ieda_feature {
|
||||
|
||||
UnionEvalSummary FeatureBuilder::buildUnionEvalSummary(int32_t grid_size, std::string stage)
|
||||
{
|
||||
UnionEvalSummary union_eval_summary;
|
||||
|
||||
TotalWLSummary total_wl_summary;
|
||||
ieval::TotalWLSummary eval_total_wl_summary = WIRELENGTH_API_INST->totalWLPure();
|
||||
total_wl_summary.HPWL = eval_total_wl_summary.HPWL;
|
||||
total_wl_summary.FLUTE = eval_total_wl_summary.FLUTE;
|
||||
total_wl_summary.HTree = eval_total_wl_summary.HTree;
|
||||
total_wl_summary.VTree = eval_total_wl_summary.VTree;
|
||||
total_wl_summary.GRWL = eval_total_wl_summary.GRWL;
|
||||
|
||||
DensityMapSummary density_map_summary;
|
||||
ieval::DensityMapSummary eval_density_map_summary = DENSITY_API_INST->densityMapPure(stage, grid_size);
|
||||
density_map_summary.cell_map_summary.macro_density = eval_density_map_summary.cell_map_summary.macro_density;
|
||||
density_map_summary.cell_map_summary.stdcell_density = eval_density_map_summary.cell_map_summary.stdcell_density;
|
||||
density_map_summary.cell_map_summary.allcell_density = eval_density_map_summary.cell_map_summary.allcell_density;
|
||||
density_map_summary.pin_map_summary.macro_pin_density = eval_density_map_summary.pin_map_summary.macro_pin_density;
|
||||
density_map_summary.pin_map_summary.stdcell_pin_density = eval_density_map_summary.pin_map_summary.stdcell_pin_density;
|
||||
density_map_summary.pin_map_summary.allcell_pin_density = eval_density_map_summary.pin_map_summary.allcell_pin_density;
|
||||
density_map_summary.net_map_summary.local_net_density = eval_density_map_summary.net_map_summary.local_net_density;
|
||||
density_map_summary.net_map_summary.global_net_density = eval_density_map_summary.net_map_summary.global_net_density;
|
||||
density_map_summary.net_map_summary.allnet_density = eval_density_map_summary.net_map_summary.allnet_density;
|
||||
if (stage == "place") {
|
||||
ieval::MacroMarginSummary eval_macro_margin_summary = DENSITY_API_INST->macroMarginMap(grid_size);
|
||||
density_map_summary.macro_margin_summary.horizontal_margin = eval_macro_margin_summary.horizontal_margin;
|
||||
density_map_summary.macro_margin_summary.vertical_margin = eval_macro_margin_summary.vertical_margin;
|
||||
density_map_summary.macro_margin_summary.union_margin = eval_macro_margin_summary.union_margin;
|
||||
}
|
||||
|
||||
CongestionSummary congestion_summary;
|
||||
ieval::EGRMapSummary eval_egr_map_summary = CONGESTION_API_INST->egrMapPure(stage);
|
||||
congestion_summary.egr_map_summary.horizontal_sum = eval_egr_map_summary.horizontal_sum;
|
||||
congestion_summary.egr_map_summary.vertical_sum = eval_egr_map_summary.vertical_sum;
|
||||
congestion_summary.egr_map_summary.union_sum = eval_egr_map_summary.union_sum;
|
||||
ieval::RUDYMapSummary eval_rudy_map_summary = CONGESTION_API_INST->rudyMapPure(stage, grid_size);
|
||||
congestion_summary.rudy_map_summary.rudy_horizontal = eval_rudy_map_summary.rudy_horizontal;
|
||||
congestion_summary.rudy_map_summary.rudy_vertical = eval_rudy_map_summary.rudy_vertical;
|
||||
congestion_summary.rudy_map_summary.rudy_union = eval_rudy_map_summary.rudy_union;
|
||||
congestion_summary.rudy_map_summary.lutrudy_horizontal = eval_rudy_map_summary.lutrudy_horizontal;
|
||||
congestion_summary.rudy_map_summary.lutrudy_vertical = eval_rudy_map_summary.lutrudy_vertical;
|
||||
congestion_summary.rudy_map_summary.lutrudy_union = eval_rudy_map_summary.lutrudy_union;
|
||||
ieval::OverflowSummary eval_overflow_summary = CONGESTION_API_INST->egrOverflow(stage);
|
||||
congestion_summary.overflow_summary.total_overflow_horizontal = eval_overflow_summary.total_overflow_horizontal;
|
||||
congestion_summary.overflow_summary.total_overflow_vertical = eval_overflow_summary.total_overflow_vertical;
|
||||
congestion_summary.overflow_summary.total_overflow_union = eval_overflow_summary.total_overflow_union;
|
||||
congestion_summary.overflow_summary.max_overflow_horizontal = eval_overflow_summary.max_overflow_horizontal;
|
||||
congestion_summary.overflow_summary.max_overflow_vertical = eval_overflow_summary.max_overflow_vertical;
|
||||
congestion_summary.overflow_summary.max_overflow_union = eval_overflow_summary.max_overflow_union;
|
||||
congestion_summary.overflow_summary.weighted_average_overflow_horizontal = eval_overflow_summary.weighted_average_overflow_horizontal;
|
||||
congestion_summary.overflow_summary.weighted_average_overflow_vertical = eval_overflow_summary.weighted_average_overflow_vertical;
|
||||
congestion_summary.overflow_summary.weighted_average_overflow_union = eval_overflow_summary.weighted_average_overflow_union;
|
||||
ieval::UtilizationSummary eval_utilization_summary = CONGESTION_API_INST->rudyUtilization(stage, false);
|
||||
congestion_summary.rudy_utilization_summary.max_utilization_horizontal = eval_utilization_summary.max_utilization_horizontal;
|
||||
congestion_summary.rudy_utilization_summary.max_utilization_vertical = eval_utilization_summary.max_utilization_vertical;
|
||||
congestion_summary.rudy_utilization_summary.max_utilization_union = eval_utilization_summary.max_utilization_union;
|
||||
congestion_summary.rudy_utilization_summary.weighted_average_utilization_horizontal
|
||||
= eval_utilization_summary.weighted_average_utilization_horizontal;
|
||||
congestion_summary.rudy_utilization_summary.weighted_average_utilization_vertical
|
||||
= eval_utilization_summary.weighted_average_utilization_vertical;
|
||||
congestion_summary.rudy_utilization_summary.weighted_average_utilization_union
|
||||
= eval_utilization_summary.weighted_average_utilization_union;
|
||||
ieval::UtilizationSummary eval_lut_utilization_summary = CONGESTION_API_INST->rudyUtilization(stage, true);
|
||||
congestion_summary.lutrudy_utilization_summary.max_utilization_horizontal = eval_lut_utilization_summary.max_utilization_horizontal;
|
||||
congestion_summary.lutrudy_utilization_summary.max_utilization_vertical = eval_lut_utilization_summary.max_utilization_vertical;
|
||||
congestion_summary.lutrudy_utilization_summary.max_utilization_union = eval_lut_utilization_summary.max_utilization_union;
|
||||
congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_horizontal
|
||||
= eval_lut_utilization_summary.weighted_average_utilization_horizontal;
|
||||
congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_vertical
|
||||
= eval_lut_utilization_summary.weighted_average_utilization_vertical;
|
||||
congestion_summary.lutrudy_utilization_summary.weighted_average_utilization_union
|
||||
= eval_lut_utilization_summary.weighted_average_utilization_union;
|
||||
|
||||
union_eval_summary.total_wl_summary = total_wl_summary;
|
||||
union_eval_summary.density_map_summary = density_map_summary;
|
||||
union_eval_summary.congestion_summary = congestion_summary;
|
||||
|
||||
return union_eval_summary;
|
||||
}
|
||||
|
||||
bool FeatureBuilder::initEvalTool()
|
||||
{
|
||||
UNION_API_INST->initIDB();
|
||||
UNION_API_INST->initEGR(true);
|
||||
UNION_API_INST->initFlute();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FeatureBuilder::destroyEvalTool()
|
||||
{
|
||||
UNION_API_INST->destroyIDB();
|
||||
UNION_API_INST->destroyEGR();
|
||||
UNION_API_INST->destroyFlute();
|
||||
UNION_API_INST->destroyInst();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FeatureBuilder::buildNetEval(std::string csv_path)
|
||||
{
|
||||
std::cout << "Building net evaluation data...\n";
|
||||
|
||||
auto* idb_builder = dmInst->get_idb_builder();
|
||||
idb::IdbDesign* idb_design = idb_builder->get_def_service()->get_design();
|
||||
|
||||
CONGESTION_API_INST->evalNetInfoPure();
|
||||
WIRELENGTH_API_INST->evalNetInfoPure();
|
||||
auto net_power_data = ieval::TimingAPI::getInst()->evalNetPower();
|
||||
|
||||
std::ofstream csv_file(csv_path, std::ios::out | std::ios::binary);
|
||||
if (!csv_file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
csv_file << "net_name,net_type,pin_num,aspect_ratio,bbox_width,bbox_height,bbox_area,lx,ly,ux,uy,lness,hpwl,rsmt,grwl,hpwl_power,flute_"
|
||||
"power,egr_power\n";
|
||||
|
||||
const size_t buffer_size = 1024 * 1024; // 1MB buffer
|
||||
std::vector<char> buffer(buffer_size);
|
||||
csv_file.rdbuf()->pubsetbuf(buffer.data(), buffer_size);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss.str().reserve(buffer_size); // Pre-allocate memory
|
||||
|
||||
for (size_t i = 0; i < idb_design->get_net_list()->get_net_list().size(); i++) {
|
||||
auto* idb_net = idb_design->get_net_list()->get_net_list()[i];
|
||||
std::string net_name = idb_net->get_net_name();
|
||||
std::string net_type;
|
||||
|
||||
int pin_num = CONGESTION_API_INST->findPinNumber(net_name);
|
||||
if (pin_num < 4) {
|
||||
continue;
|
||||
}
|
||||
int aspect_ratio = CONGESTION_API_INST->findAspectRatio(net_name);
|
||||
float l_ness = CONGESTION_API_INST->findLness(net_name);
|
||||
int32_t bbox_width = CONGESTION_API_INST->findBBoxWidth(net_name);
|
||||
int32_t bbox_height = CONGESTION_API_INST->findBBoxHeight(net_name);
|
||||
int64_t bbox_area = CONGESTION_API_INST->findBBoxArea(net_name);
|
||||
int32_t bbox_lx = CONGESTION_API_INST->findBBoxLx(net_name);
|
||||
int32_t bbox_ly = CONGESTION_API_INST->findBBoxLy(net_name);
|
||||
int32_t bbox_ux = CONGESTION_API_INST->findBBoxUx(net_name);
|
||||
int32_t bbox_uy = CONGESTION_API_INST->findBBoxUy(net_name);
|
||||
|
||||
int32_t hpwl = WIRELENGTH_API_INST->findNetHPWL(net_name);
|
||||
int32_t flute = WIRELENGTH_API_INST->findNetFLUTE(net_name);
|
||||
int32_t grwl = WIRELENGTH_API_INST->findNetGRWL(net_name);
|
||||
|
||||
// Remove backslashes in net_name to match timing && power evaluation data
|
||||
net_name.erase(std::remove(net_name.begin(), net_name.end(), '\\'), net_name.end());
|
||||
|
||||
if (ieval::TimingAPI::getInst()->isClockNet(net_name)) {
|
||||
net_type = "clock";
|
||||
} else {
|
||||
net_type = "signal";
|
||||
}
|
||||
|
||||
if (net_power_data["HPWL"].find(net_name) == net_power_data["HPWL"].end()
|
||||
|| net_power_data["FLUTE"].find(net_name) == net_power_data["FLUTE"].end()
|
||||
|| net_power_data["EGR"].find(net_name) == net_power_data["EGR"].end()) {
|
||||
std::cerr << "Error: net_name '" << net_name << "' not found in net_power_data.\n";
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
double hpwl_power = net_power_data["HPWL"][net_name];
|
||||
double flute_power = net_power_data["FLUTE"][net_name];
|
||||
double egr_power = net_power_data["EGR"][net_name];
|
||||
|
||||
csv_file << net_name << ',' << net_type << "," << pin_num << ',' << aspect_ratio << ',' << bbox_width << "," << bbox_height << ","
|
||||
<< bbox_area << "," << bbox_lx << "," << bbox_ly << "," << bbox_ux << "," << bbox_uy << "," << l_ness << ',' << hpwl << ','
|
||||
<< flute << ',' << grwl << ',' << hpwl_power << ',' << flute_power << "," << egr_power << '\n';
|
||||
|
||||
if (oss.tellp() >= buffer_size / 2) {
|
||||
csv_file << oss.str();
|
||||
oss.str("");
|
||||
oss.clear();
|
||||
}
|
||||
}
|
||||
if (oss.tellp() > 0) {
|
||||
csv_file << oss.str();
|
||||
}
|
||||
csv_file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ieda_feature
|
||||
|
|
@ -114,35 +114,28 @@ struct CongestionSummary
|
|||
UtilizationSummary rudy_utilization_summary;
|
||||
UtilizationSummary lutrudy_utilization_summary;
|
||||
};
|
||||
struct WlmTimingEvalSummary
|
||||
struct TimingEvalSummaryBase
|
||||
{
|
||||
std::vector<ClockTiming> clock_timings;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
struct HpwlTimingEvalSummary
|
||||
struct WlmTimingEvalSummary : TimingEvalSummaryBase
|
||||
{
|
||||
std::vector<ClockTiming> clock_timings;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
struct FluteTimingEvalSummary
|
||||
struct HpwlTimingEvalSummary : TimingEvalSummaryBase
|
||||
{
|
||||
std::vector<ClockTiming> clock_timings;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
struct SaltTimingEvalSummary
|
||||
struct FluteTimingEvalSummary : TimingEvalSummaryBase
|
||||
{
|
||||
std::vector<ClockTiming> clock_timings;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
struct EgrTimingEvalSummary
|
||||
struct SaltTimingEvalSummary : TimingEvalSummaryBase
|
||||
{
|
||||
std::vector<ClockTiming> clock_timings;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
struct DrTimingEvalSummary
|
||||
struct EgrTimingEvalSummary : TimingEvalSummaryBase
|
||||
{
|
||||
};
|
||||
struct DrTimingEvalSummary : TimingEvalSummaryBase
|
||||
{
|
||||
std::vector<ClockTiming> clock_timings;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
struct TimingEvalSummary
|
||||
{
|
||||
|
|
@ -154,4 +147,12 @@ struct TimingEvalSummary
|
|||
DrTimingEvalSummary dr_timing_eval_summary;
|
||||
};
|
||||
|
||||
struct UnionEvalSummary
|
||||
{
|
||||
TotalWLSummary total_wl_summary;
|
||||
DensityMapSummary density_map_summary;
|
||||
CongestionSummary congestion_summary;
|
||||
TimingEvalSummary timing_eval_summary;
|
||||
};
|
||||
|
||||
} // namespace ieda_feature
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@ namespace ieda_feature {
|
|||
struct PLCommonSummary
|
||||
{
|
||||
float place_density;
|
||||
float pin_density;
|
||||
int64_t HPWL;
|
||||
int64_t STWL;
|
||||
int64_t GRWL;
|
||||
// float pin_density;
|
||||
// int64_t HPWL;
|
||||
// int64_t STWL;
|
||||
// int64_t GRWL;
|
||||
|
||||
int32_t egr_tof;
|
||||
int32_t egr_mof;
|
||||
float egr_ace;
|
||||
// int32_t egr_tof;
|
||||
// int32_t egr_mof;
|
||||
// float egr_ace;
|
||||
|
||||
float tns;
|
||||
float wns;
|
||||
float suggest_freq;
|
||||
// float tns;
|
||||
// float wns;
|
||||
// float suggest_freq;
|
||||
};
|
||||
|
||||
struct LGSummary
|
||||
|
|
|
|||
|
|
@ -39,7 +39,30 @@ struct SASummary
|
|||
int32_t total_supply = 0;
|
||||
};
|
||||
|
||||
struct IRSummary
|
||||
struct TGSummary
|
||||
{
|
||||
int32_t total_demand = 0;
|
||||
int32_t total_overflow = 0;
|
||||
double total_wire_length = 0;
|
||||
std::vector<ClockTiming> clocks_timing;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
|
||||
struct LASummary
|
||||
{
|
||||
std::map<int32_t, int32_t> routing_demand_map;
|
||||
int32_t total_demand = 0;
|
||||
std::map<int32_t, int32_t> routing_overflow_map;
|
||||
int32_t total_overflow = 0;
|
||||
std::map<int32_t, double> routing_wire_length_map;
|
||||
double total_wire_length = 0;
|
||||
std::map<int32_t, int32_t> cut_via_num_map;
|
||||
int32_t total_via_num = 0;
|
||||
std::vector<ClockTiming> clocks_timing;
|
||||
PowerInfo power_info;
|
||||
};
|
||||
|
||||
struct ERSummary
|
||||
{
|
||||
std::map<int32_t, int32_t> routing_demand_map;
|
||||
int32_t total_demand = 0;
|
||||
|
|
@ -93,7 +116,9 @@ struct RTSummary
|
|||
{
|
||||
PASummary pa_summary;
|
||||
SASummary sa_summary;
|
||||
IRSummary ir_summary;
|
||||
TGSummary tg_summary;
|
||||
LASummary la_summary;
|
||||
ERSummary er_summary;
|
||||
std::map<int32_t, GRSummary> iter_gr_summary_map;
|
||||
TASummary ta_summary;
|
||||
std::map<int32_t, DRSummary> iter_dr_summary_map;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,103 @@ bool FeatureManager::save_eval_summary(std::string path, int32_t grid_size)
|
|||
return feature_parser.buildSummaryEvalJsonl(path);
|
||||
}
|
||||
|
||||
bool FeatureManager::save_eval_union(std::string jsonl_path, std::string csv_path, int32_t grid_size)
|
||||
{
|
||||
FeatureBuilder builder;
|
||||
|
||||
bool is_init_eval_tool = builder.initEvalTool();
|
||||
if (!is_init_eval_tool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// auto union_db = builder.buildUnionEvalSummary(grid_size);
|
||||
// _summary->set_wirelength_eval(union_db.total_wl_summary);
|
||||
// _summary->set_density_eval(union_db.density_map_summary);
|
||||
// _summary->set_congestion_eval(union_db.congestion_summary);
|
||||
|
||||
bool csv_success = builder.buildNetEval(csv_path);
|
||||
// bool csv_success = true;
|
||||
|
||||
// FeatureParser feature_parser(_summary);
|
||||
// bool jsonl_success = feature_parser.buildSummaryEvalJsonl(jsonl_path);
|
||||
bool jsonl_success = true;
|
||||
|
||||
builder.destroyEvalTool();
|
||||
|
||||
return jsonl_success && csv_success;
|
||||
}
|
||||
|
||||
bool FeatureManager::save_pl_eval_union(std::string jsonl_path, std::string csv_path, int32_t grid_size)
|
||||
{
|
||||
// EGR
|
||||
FeatureBuilder builder;
|
||||
|
||||
bool is_init_eval_tool = builder.initEvalTool();
|
||||
if (!is_init_eval_tool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string stage = "place";
|
||||
|
||||
auto union_db = builder.buildUnionEvalSummary(grid_size, stage);
|
||||
_summary->set_wirelength_eval(union_db.total_wl_summary);
|
||||
_summary->set_density_eval(union_db.density_map_summary);
|
||||
_summary->set_congestion_eval(union_db.congestion_summary);
|
||||
|
||||
builder.evalTiming("EGR", true);
|
||||
|
||||
builder.evalTiming("HPWL");
|
||||
builder.evalTiming("FLUTE");
|
||||
builder.evalTiming("SALT");
|
||||
|
||||
auto union_timing_db = builder.buildTimingUnionEvalSummary();
|
||||
_summary->set_timing_eval(union_timing_db);
|
||||
|
||||
FeatureParser feature_parser(_summary);
|
||||
bool jsonl_success = feature_parser.buildSummaryEvalJsonl(jsonl_path);
|
||||
bool csv_success = builder.buildNetEval(csv_path);
|
||||
|
||||
builder.destroyEvalTool();
|
||||
|
||||
return jsonl_success && csv_success;
|
||||
}
|
||||
|
||||
bool FeatureManager::save_cts_eval_union(std::string jsonl_path, std::string csv_path, int32_t grid_size)
|
||||
{
|
||||
// EGR
|
||||
FeatureBuilder builder;
|
||||
|
||||
bool is_init_eval_tool = builder.initEvalTool();
|
||||
if (!is_init_eval_tool) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string stage = "cts";
|
||||
|
||||
auto union_db = builder.buildUnionEvalSummary(grid_size, stage);
|
||||
_summary->set_wirelength_eval(union_db.total_wl_summary);
|
||||
_summary->set_density_eval(union_db.density_map_summary);
|
||||
_summary->set_congestion_eval(union_db.congestion_summary);
|
||||
|
||||
builder.evalTiming("EGR", true);
|
||||
|
||||
builder.evalTiming("HPWL");
|
||||
builder.evalTiming("FLUTE");
|
||||
builder.evalTiming("SALT");
|
||||
|
||||
auto union_timing_db = builder.buildTimingUnionEvalSummary();
|
||||
_summary->set_timing_eval(union_timing_db);
|
||||
|
||||
FeatureParser feature_parser(_summary);
|
||||
bool jsonl_success = feature_parser.buildSummaryEvalJsonl(jsonl_path);
|
||||
|
||||
bool csv_success = builder.buildNetEval(csv_path);
|
||||
|
||||
builder.destroyEvalTool();
|
||||
|
||||
return jsonl_success && csv_success;
|
||||
}
|
||||
|
||||
bool FeatureManager::save_timing_eval_summary(std::string path)
|
||||
{
|
||||
FeatureBuilder builder;
|
||||
|
|
@ -102,9 +199,7 @@ bool FeatureManager::save_tools(std::string path, std::string step)
|
|||
|
||||
_summary->set_ito_optsetup(db);
|
||||
} else if (step == "route") {
|
||||
auto db = builder.buildRTSummary();
|
||||
|
||||
_summary->set_irt(db);
|
||||
// skip
|
||||
} else {
|
||||
}
|
||||
|
||||
|
|
@ -139,4 +234,9 @@ bool FeatureManager::read_route_data(std::string path)
|
|||
return feature_parser.readRouteData(path, &_route_data);
|
||||
}
|
||||
|
||||
bool FeatureManager::save_cong_map(std::string stage, std::string csv_dir)
|
||||
{
|
||||
FeatureParser feature_parser;
|
||||
return feature_parser.buildCongMap(stage, csv_dir);
|
||||
}
|
||||
} // namespace ieda_feature
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ class FeatureManager
|
|||
bool save_summary(std::string path);
|
||||
bool save_tools(std::string path, std::string step);
|
||||
bool save_eval_map(std::string path, int bin_cnt_x, int bin_cnt_y);
|
||||
bool save_cong_map(std::string stage, std::string csv_dir);
|
||||
bool save_net_eval(std::string path);
|
||||
// route data
|
||||
bool save_route_data(std::string path);
|
||||
|
|
@ -63,6 +64,9 @@ class FeatureManager
|
|||
// evaluation
|
||||
bool save_eval_summary(std::string path, int32_t grid_size);
|
||||
bool save_timing_eval_summary(std::string path);
|
||||
bool save_eval_union(std::string jsonl_path, std::string csv_path, int32_t grid_size);
|
||||
bool save_pl_eval_union(std::string jsonl_path, std::string csv_path, int32_t grid_size);
|
||||
bool save_cts_eval_union(std::string jsonl_path, std::string csv_path, int32_t grid_size);
|
||||
|
||||
private:
|
||||
static FeatureManager* _instance;
|
||||
|
|
|
|||
|
|
@ -228,7 +228,6 @@ bool FeatureParser::buildSummaryEval(std::string json_path)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FeatureParser::buildSummaryEvalJsonl(std::string jsonl_path)
|
||||
{
|
||||
std::ofstream& file_stream = ieda::getOutputFileStream(jsonl_path);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ class FeatureParser
|
|||
bool buildSummaryEvalJsonl(std::string jsonl_path);
|
||||
bool buildSummaryTimingEval(std::string json_path);
|
||||
bool buildNetEval(std::string csv_path);
|
||||
bool buildCongMap(std::string stage, std::string csv_dir);
|
||||
|
||||
private:
|
||||
IdbLayout* _layout = nullptr;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,15 @@ bool FeatureParser::buildSummaryMap(std::string csv_path, int bin_cnt_x, int bin
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FeatureParser::buildCongMap(std::string stage, std::string csv_dir)
|
||||
{
|
||||
if (CONGESTION_API_INST->egrUnionMap(stage, csv_dir) != "") {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FeatureParser::buildNetEval(std::string csv_path)
|
||||
{
|
||||
auto* idb_builder = dmInst->get_idb_builder();
|
||||
|
|
@ -227,13 +236,26 @@ json FeatureParser::buildSummaryTiming()
|
|||
};
|
||||
|
||||
auto routing_timing_summary = _summary->get_summary_timing_eval();
|
||||
// TBD
|
||||
// add_routing_timing("WLM", routing_timing_summary.wlm_timing_eval_summary.clock_timings);
|
||||
add_routing_timing("HPWL", routing_timing_summary.hpwl_timing_eval_summary.clock_timings);
|
||||
add_routing_timing("FLUTE", routing_timing_summary.flute_timing_eval_summary.clock_timings);
|
||||
add_routing_timing("SALT", routing_timing_summary.salt_timing_eval_summary.clock_timings);
|
||||
add_routing_timing("EGR", routing_timing_summary.egr_timing_eval_summary.clock_timings);
|
||||
add_routing_timing("DR", routing_timing_summary.dr_timing_eval_summary.clock_timings);
|
||||
|
||||
if (routing_timing_summary.wlm_timing_eval_summary.clock_timings.size() > 0) {
|
||||
add_routing_timing("WLM", routing_timing_summary.wlm_timing_eval_summary.clock_timings);
|
||||
}
|
||||
if (routing_timing_summary.hpwl_timing_eval_summary.clock_timings.size() > 0) {
|
||||
add_routing_timing("HPWL", routing_timing_summary.hpwl_timing_eval_summary.clock_timings);
|
||||
}
|
||||
if (routing_timing_summary.flute_timing_eval_summary.clock_timings.size() > 0) {
|
||||
add_routing_timing("FLUTE", routing_timing_summary.flute_timing_eval_summary.clock_timings);
|
||||
}
|
||||
if (routing_timing_summary.salt_timing_eval_summary.clock_timings.size() > 0) {
|
||||
add_routing_timing("SALT", routing_timing_summary.salt_timing_eval_summary.clock_timings);
|
||||
}
|
||||
if (routing_timing_summary.egr_timing_eval_summary.clock_timings.size() > 0) {
|
||||
add_routing_timing("EGR", routing_timing_summary.egr_timing_eval_summary.clock_timings);
|
||||
}
|
||||
if (routing_timing_summary.dr_timing_eval_summary.clock_timings.size() > 0) {
|
||||
add_routing_timing("DR", routing_timing_summary.dr_timing_eval_summary.clock_timings);
|
||||
}
|
||||
|
||||
return timing;
|
||||
}
|
||||
|
||||
|
|
@ -247,13 +269,24 @@ json FeatureParser::buildSummaryPower()
|
|||
|
||||
auto timing_summary = _summary->get_summary_timing_eval();
|
||||
|
||||
// TBD
|
||||
// add_routing_power("WLM", timing_summary.wlm_timing_eval_summary.power_info);
|
||||
add_routing_power("HPWL", timing_summary.hpwl_timing_eval_summary.power_info);
|
||||
add_routing_power("FLUTE", timing_summary.flute_timing_eval_summary.power_info);
|
||||
add_routing_power("SALT", timing_summary.salt_timing_eval_summary.power_info);
|
||||
add_routing_power("EGR", timing_summary.egr_timing_eval_summary.power_info);
|
||||
add_routing_power("DR", timing_summary.dr_timing_eval_summary.power_info);
|
||||
if (timing_summary.wlm_timing_eval_summary.power_info.static_power > 0) {
|
||||
add_routing_power("WLM", timing_summary.wlm_timing_eval_summary.power_info);
|
||||
}
|
||||
if (timing_summary.hpwl_timing_eval_summary.power_info.static_power > 0) {
|
||||
add_routing_power("HPWL", timing_summary.hpwl_timing_eval_summary.power_info);
|
||||
}
|
||||
if (timing_summary.flute_timing_eval_summary.power_info.static_power > 0) {
|
||||
add_routing_power("FLUTE", timing_summary.flute_timing_eval_summary.power_info);
|
||||
}
|
||||
if (timing_summary.salt_timing_eval_summary.power_info.static_power > 0) {
|
||||
add_routing_power("SALT", timing_summary.salt_timing_eval_summary.power_info);
|
||||
}
|
||||
if (timing_summary.egr_timing_eval_summary.power_info.static_power > 0) {
|
||||
add_routing_power("EGR", timing_summary.egr_timing_eval_summary.power_info);
|
||||
}
|
||||
if (timing_summary.dr_timing_eval_summary.power_info.static_power > 0) {
|
||||
add_routing_power("DR", timing_summary.dr_timing_eval_summary.power_info);
|
||||
}
|
||||
|
||||
return power;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,41 +62,92 @@ json FeatureParser::buildSummaryRT()
|
|||
}
|
||||
json_rt["SA"] = json_sa;
|
||||
|
||||
/// IR
|
||||
json json_ir;
|
||||
json_ir["total_demand"] = rt_sum.ir_summary.total_demand;
|
||||
for (auto demand : rt_sum.ir_summary.routing_demand_map) {
|
||||
json_ir["routing_demand_map"][std::to_string(demand.first)] = demand.second;
|
||||
// TG
|
||||
json json_tg;
|
||||
json_tg["total_demand"] = rt_sum.tg_summary.total_demand;
|
||||
json_tg["total_overflow"] = rt_sum.tg_summary.total_overflow;
|
||||
json_tg["total_wire_length"] = rt_sum.tg_summary.total_wire_length;
|
||||
|
||||
for (int i = 0; i < (int) rt_sum.tg_summary.clocks_timing.size(); i++) {
|
||||
auto clock_timing = rt_sum.tg_summary.clocks_timing[i];
|
||||
json_tg["clocks_timing"][i]["clock_name"] = clock_timing.clock_name;
|
||||
json_tg["clocks_timing"][i]["setup_tns"] = clock_timing.setup_tns;
|
||||
json_tg["clocks_timing"][i]["setup_wns"] = clock_timing.setup_wns;
|
||||
json_tg["clocks_timing"][i]["suggest_freq"] = clock_timing.suggest_freq;
|
||||
}
|
||||
json_tg["static_power"] = rt_sum.tg_summary.power_info.static_power;
|
||||
json_tg["dynamic_power"] = rt_sum.tg_summary.power_info.dynamic_power;
|
||||
json_rt["TG"] = json_tg;
|
||||
|
||||
/// LA
|
||||
json json_la;
|
||||
json_la["total_demand"] = rt_sum.la_summary.total_demand;
|
||||
for (auto demand : rt_sum.la_summary.routing_demand_map) {
|
||||
json_la["routing_demand_map"][std::to_string(demand.first)] = demand.second;
|
||||
}
|
||||
|
||||
json_ir["total_overflow"] = rt_sum.ir_summary.total_overflow;
|
||||
for (auto routing_overflow : rt_sum.ir_summary.routing_overflow_map) {
|
||||
json_ir["routing_overflow_map"][std::to_string(routing_overflow.first)] = routing_overflow.second;
|
||||
json_la["total_overflow"] = rt_sum.la_summary.total_overflow;
|
||||
for (auto routing_overflow : rt_sum.la_summary.routing_overflow_map) {
|
||||
json_la["routing_overflow_map"][std::to_string(routing_overflow.first)] = routing_overflow.second;
|
||||
}
|
||||
|
||||
json_ir["total_wire_length"] = rt_sum.ir_summary.total_wire_length;
|
||||
for (auto routing_wire_length : rt_sum.ir_summary.routing_wire_length_map) {
|
||||
json_ir["routing_wire_length_map"][std::to_string(routing_wire_length.first)] = routing_wire_length.second;
|
||||
json_la["total_wire_length"] = rt_sum.la_summary.total_wire_length;
|
||||
for (auto routing_wire_length : rt_sum.la_summary.routing_wire_length_map) {
|
||||
json_la["routing_wire_length_map"][std::to_string(routing_wire_length.first)] = routing_wire_length.second;
|
||||
}
|
||||
|
||||
json_ir["total_via_num"] = rt_sum.ir_summary.total_via_num;
|
||||
for (auto cut_via_num : rt_sum.ir_summary.cut_via_num_map) {
|
||||
json_ir["cut_via_num_map"][std::to_string(cut_via_num.first)] = cut_via_num.second;
|
||||
json_la["total_via_num"] = rt_sum.la_summary.total_via_num;
|
||||
for (auto cut_via_num : rt_sum.la_summary.cut_via_num_map) {
|
||||
json_la["cut_via_num_map"][std::to_string(cut_via_num.first)] = cut_via_num.second;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int) rt_sum.ir_summary.clocks_timing.size(); i++) {
|
||||
auto clock_timing = rt_sum.ir_summary.clocks_timing[i];
|
||||
json_ir["clocks_timing"][i]["clock_name"] = clock_timing.clock_name;
|
||||
json_ir["clocks_timing"][i]["setup_tns"] = clock_timing.setup_tns;
|
||||
json_ir["clocks_timing"][i]["setup_wns"] = clock_timing.setup_wns;
|
||||
json_ir["clocks_timing"][i]["suggest_freq"] = clock_timing.suggest_freq;
|
||||
for (int i = 0; i < (int) rt_sum.la_summary.clocks_timing.size(); i++) {
|
||||
auto clock_timing = rt_sum.la_summary.clocks_timing[i];
|
||||
json_la["clocks_timing"][i]["clock_name"] = clock_timing.clock_name;
|
||||
json_la["clocks_timing"][i]["setup_tns"] = clock_timing.setup_tns;
|
||||
json_la["clocks_timing"][i]["setup_wns"] = clock_timing.setup_wns;
|
||||
json_la["clocks_timing"][i]["suggest_freq"] = clock_timing.suggest_freq;
|
||||
}
|
||||
json_ir["static_power"] = rt_sum.ir_summary.power_info.static_power;
|
||||
json_ir["dynamic_power"] = rt_sum.ir_summary.power_info.dynamic_power;
|
||||
json_la["static_power"] = rt_sum.la_summary.power_info.static_power;
|
||||
json_la["dynamic_power"] = rt_sum.la_summary.power_info.dynamic_power;
|
||||
|
||||
json_rt["IR"] = json_ir;
|
||||
json_rt["LA"] = json_la;
|
||||
|
||||
// // GR
|
||||
// ER
|
||||
json json_er;
|
||||
json_er["total_demand"] = rt_sum.la_summary.total_demand;
|
||||
for (auto demand : rt_sum.la_summary.routing_demand_map) {
|
||||
json_er["routing_demand_map"][std::to_string(demand.first)] = demand.second;
|
||||
}
|
||||
|
||||
json_er["total_overflow"] = rt_sum.la_summary.total_overflow;
|
||||
for (auto routing_overflow : rt_sum.la_summary.routing_overflow_map) {
|
||||
json_er["routing_overflow_map"][std::to_string(routing_overflow.first)] = routing_overflow.second;
|
||||
}
|
||||
|
||||
json_er["total_wire_length"] = rt_sum.la_summary.total_wire_length;
|
||||
for (auto routing_wire_length : rt_sum.la_summary.routing_wire_length_map) {
|
||||
json_er["routing_wire_length_map"][std::to_string(routing_wire_length.first)] = routing_wire_length.second;
|
||||
}
|
||||
|
||||
json_er["total_via_num"] = rt_sum.la_summary.total_via_num;
|
||||
for (auto cut_via_num : rt_sum.la_summary.cut_via_num_map) {
|
||||
json_er["cut_via_num_map"][std::to_string(cut_via_num.first)] = cut_via_num.second;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int) rt_sum.la_summary.clocks_timing.size(); i++) {
|
||||
auto clock_timing = rt_sum.la_summary.clocks_timing[i];
|
||||
json_er["clocks_timing"][i]["clock_name"] = clock_timing.clock_name;
|
||||
json_er["clocks_timing"][i]["setup_tns"] = clock_timing.setup_tns;
|
||||
json_er["clocks_timing"][i]["setup_wns"] = clock_timing.setup_wns;
|
||||
json_er["clocks_timing"][i]["suggest_freq"] = clock_timing.suggest_freq;
|
||||
}
|
||||
json_er["static_power"] = rt_sum.la_summary.power_info.static_power;
|
||||
json_er["dynamic_power"] = rt_sum.la_summary.power_info.dynamic_power;
|
||||
|
||||
json_rt["ER"] = json_er;
|
||||
|
||||
// GR
|
||||
json json_gr_list;
|
||||
for (auto [id, gr_sum] : rt_sum.iter_gr_summary_map) {
|
||||
json json_gr;
|
||||
|
|
@ -197,32 +248,32 @@ json FeatureParser::buildSummaryPL(std::string step)
|
|||
|
||||
if (step == "place") {
|
||||
summary_pl["gplace"]["place_density"] = pl_summary.gplace.place_density;
|
||||
summary_pl["gplace"]["pin_density"] = pl_summary.gplace.pin_density;
|
||||
summary_pl["gplace"]["HPWL"] = pl_summary.gplace.HPWL;
|
||||
summary_pl["gplace"]["STWL"] = pl_summary.gplace.STWL;
|
||||
summary_pl["gplace"]["GRWL"] = pl_summary.gplace.GRWL;
|
||||
// summary_pl["gplace"]["pin_density"] = pl_summary.gplace.pin_density;
|
||||
// summary_pl["gplace"]["HPWL"] = pl_summary.gplace.HPWL;
|
||||
// summary_pl["gplace"]["STWL"] = pl_summary.gplace.STWL;
|
||||
// summary_pl["gplace"]["GRWL"] = pl_summary.gplace.GRWL;
|
||||
|
||||
summary_pl["gplace"]["egr_tof"] = pl_summary.gplace.egr_tof;
|
||||
summary_pl["gplace"]["egr_mof"] = pl_summary.gplace.egr_mof;
|
||||
summary_pl["gplace"]["egr_ace"] = pl_summary.gplace.egr_ace;
|
||||
// summary_pl["gplace"]["egr_tof"] = pl_summary.gplace.egr_tof;
|
||||
// summary_pl["gplace"]["egr_mof"] = pl_summary.gplace.egr_mof;
|
||||
// summary_pl["gplace"]["egr_ace"] = pl_summary.gplace.egr_ace;
|
||||
|
||||
summary_pl["gplace"]["tns"] = pl_summary.gplace.tns;
|
||||
summary_pl["gplace"]["wns"] = pl_summary.gplace.wns;
|
||||
summary_pl["gplace"]["suggest_freq"] = pl_summary.gplace.suggest_freq;
|
||||
// summary_pl["gplace"]["tns"] = pl_summary.gplace.tns;
|
||||
// summary_pl["gplace"]["wns"] = pl_summary.gplace.wns;
|
||||
// summary_pl["gplace"]["suggest_freq"] = pl_summary.gplace.suggest_freq;
|
||||
|
||||
summary_pl["dplace"]["place_density"] = pl_summary.dplace.place_density;
|
||||
summary_pl["dplace"]["pin_density"] = pl_summary.dplace.pin_density;
|
||||
summary_pl["dplace"]["HPWL"] = pl_summary.dplace.HPWL;
|
||||
summary_pl["dplace"]["STWL"] = pl_summary.dplace.STWL;
|
||||
summary_pl["dplace"]["GRWL"] = pl_summary.dplace.GRWL;
|
||||
// summary_pl["dplace"]["pin_density"] = pl_summary.dplace.pin_density;
|
||||
// summary_pl["dplace"]["HPWL"] = pl_summary.dplace.HPWL;
|
||||
// summary_pl["dplace"]["STWL"] = pl_summary.dplace.STWL;
|
||||
// summary_pl["dplace"]["GRWL"] = pl_summary.dplace.GRWL;
|
||||
|
||||
summary_pl["dplace"]["egr_tof"] = pl_summary.dplace.egr_tof;
|
||||
summary_pl["dplace"]["egr_mof"] = pl_summary.dplace.egr_mof;
|
||||
summary_pl["dplace"]["egr_ace"] = pl_summary.dplace.egr_ace;
|
||||
// summary_pl["dplace"]["egr_tof"] = pl_summary.dplace.egr_tof;
|
||||
// summary_pl["dplace"]["egr_mof"] = pl_summary.dplace.egr_mof;
|
||||
// summary_pl["dplace"]["egr_ace"] = pl_summary.dplace.egr_ace;
|
||||
|
||||
summary_pl["dplace"]["tns"] = pl_summary.dplace.tns;
|
||||
summary_pl["dplace"]["wns"] = pl_summary.dplace.wns;
|
||||
summary_pl["dplace"]["suggest_freq"] = pl_summary.dplace.suggest_freq;
|
||||
// summary_pl["dplace"]["tns"] = pl_summary.dplace.tns;
|
||||
// summary_pl["dplace"]["wns"] = pl_summary.dplace.wns;
|
||||
// summary_pl["dplace"]["suggest_freq"] = pl_summary.dplace.suggest_freq;
|
||||
|
||||
summary_pl["instance_cnt"] = pl_summary.instance_cnt;
|
||||
summary_pl["fix_inst_cnt"] = pl_summary.fix_inst_cnt;
|
||||
|
|
@ -237,18 +288,18 @@ json FeatureParser::buildSummaryPL(std::string step)
|
|||
// 3: Data parameters required for legalization.
|
||||
else if (step == "legalization") {
|
||||
summary_pl["legalization"]["place_density"] = pl_summary.lg_summary.pl_common_summary.place_density;
|
||||
summary_pl["legalization"]["pin_density"] = pl_summary.lg_summary.pl_common_summary.pin_density;
|
||||
summary_pl["legalization"]["HPWL"] = pl_summary.lg_summary.pl_common_summary.HPWL;
|
||||
summary_pl["legalization"]["STWL"] = pl_summary.lg_summary.pl_common_summary.STWL;
|
||||
summary_pl["legalization"]["GRWL"] = pl_summary.lg_summary.pl_common_summary.GRWL;
|
||||
// summary_pl["legalization"]["pin_density"] = pl_summary.lg_summary.pl_common_summary.pin_density;
|
||||
// summary_pl["legalization"]["HPWL"] = pl_summary.lg_summary.pl_common_summary.HPWL;
|
||||
// summary_pl["legalization"]["STWL"] = pl_summary.lg_summary.pl_common_summary.STWL;
|
||||
// summary_pl["legalization"]["GRWL"] = pl_summary.lg_summary.pl_common_summary.GRWL;
|
||||
|
||||
summary_pl["legalization"]["egr_tof"] = pl_summary.lg_summary.pl_common_summary.egr_tof;
|
||||
summary_pl["legalization"]["egr_mof"] = pl_summary.lg_summary.pl_common_summary.egr_mof;
|
||||
summary_pl["legalization"]["egr_ace"] = pl_summary.lg_summary.pl_common_summary.egr_ace;
|
||||
// summary_pl["legalization"]["egr_tof"] = pl_summary.lg_summary.pl_common_summary.egr_tof;
|
||||
// summary_pl["legalization"]["egr_mof"] = pl_summary.lg_summary.pl_common_summary.egr_mof;
|
||||
// summary_pl["legalization"]["egr_ace"] = pl_summary.lg_summary.pl_common_summary.egr_ace;
|
||||
|
||||
summary_pl["legalization"]["tns"] = pl_summary.lg_summary.pl_common_summary.tns;
|
||||
summary_pl["legalization"]["wns"] = pl_summary.lg_summary.pl_common_summary.wns;
|
||||
summary_pl["legalization"]["suggest_freq"] = pl_summary.lg_summary.pl_common_summary.suggest_freq;
|
||||
// summary_pl["legalization"]["tns"] = pl_summary.lg_summary.pl_common_summary.tns;
|
||||
// summary_pl["legalization"]["wns"] = pl_summary.lg_summary.pl_common_summary.wns;
|
||||
// summary_pl["legalization"]["suggest_freq"] = pl_summary.lg_summary.pl_common_summary.suggest_freq;
|
||||
|
||||
summary_pl["legalization"]["total_movement"] = pl_summary.lg_summary.lg_total_movement;
|
||||
summary_pl["legalization"]["max_movement"] = pl_summary.lg_summary.lg_max_movement;
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-error=deprecated-declarations -Wno-deprecated-declarations ")
|
||||
|
||||
if(BUILD_PR_FLOW)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${HOME_BUILD}/lib/iGUI)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${HOME_BUILD}/lib/iGUI)
|
||||
if(NOT DEFINED CMD_BUILD)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${HOME_BUILD}/lib/iGUI)
|
||||
endif()
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${HOME_BUILD}/lib/iGUI)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${HOME_BUILD}/lib/iGUI)
|
||||
if(NOT DEFINED CMD_BUILD)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${HOME_BUILD}/lib/iGUI)
|
||||
endif()
|
||||
|
||||
|
||||
|
|
@ -181,82 +179,41 @@ set(headers
|
|||
|
||||
include(${HOME_CMAKE}/operation/idb.cmake)
|
||||
|
||||
if(BUILD_PR_FLOW)
|
||||
message("Build iGUI lib")
|
||||
|
||||
add_library(iGUI
|
||||
${headers}
|
||||
${sources}
|
||||
)
|
||||
|
||||
target_link_libraries(iGUI Qt5${QT_VERSION_MAJOR}::Widgets Qt5${QT_VERSION_MAJOR}::Xml Qt5${QT_VERSION_MAJOR}::Core)
|
||||
# target_link_libraries(iGUI idrc_api file_manager_cts file_manager_drc file_manager_placement tool_api_ipl OpenMP::OpenMP_CXX)
|
||||
target_link_libraries(iGUI
|
||||
file_manager_cts
|
||||
file_manager_drc
|
||||
file_manager_placement
|
||||
tool_api_ipl
|
||||
idrc_pro_violation
|
||||
ieda_feature
|
||||
)
|
||||
|
||||
if(OpenMP_CXX_FOUND)
|
||||
target_link_libraries(iGUI
|
||||
OpenMP::OpenMP_CXX
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/graphicsitem)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guiaction)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guicontroltree)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guiDB)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guiparser)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/designitem)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/utilityitem)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/utility)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guispeedupitems)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interface)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/config)
|
||||
|
||||
|
||||
target_include_directories(iGUI
|
||||
PUBLIC
|
||||
# ${HOME_PLATFORM}/
|
||||
# ${HOME_PLATFORM}//tool_api
|
||||
# ${HOME_PLATFORM}//tool_api/irt_io
|
||||
)
|
||||
|
||||
else()
|
||||
message("Build iGUI exe")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/graphicsitem)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/guiaction)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/guicontroltree)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/guiDB)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/guiparser)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/designitem)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/utilityitem)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/utility)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/guispeedupitems)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/interface)
|
||||
|
||||
set(exe_sources
|
||||
src/main.cpp
|
||||
${sources}
|
||||
)
|
||||
add_executable(iGUI
|
||||
${headers}
|
||||
${exe_sources}
|
||||
${samples}
|
||||
)
|
||||
|
||||
target_link_libraries(iGUI Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Xml Qt${QT_VERSION_MAJOR}::Core)
|
||||
target_link_libraries(iGUI idb IdbBuilder def_service lef_service )
|
||||
add_library(iGUI
|
||||
${headers}
|
||||
${sources}
|
||||
)
|
||||
target_link_libraries(iGUI Qt5${QT_VERSION_MAJOR}::Widgets Qt5${QT_VERSION_MAJOR}::Xml Qt5${QT_VERSION_MAJOR}::Core)
|
||||
# target_link_libraries(iGUI idrc_api file_manager_cts file_manager_drc file_manager_placement tool_api_ipl OpenMP::OpenMP_CXX)
|
||||
target_link_libraries(iGUI
|
||||
file_manager_cts
|
||||
file_manager_drc
|
||||
file_manager_placement
|
||||
tool_api_ipl
|
||||
idrc_pro_violation
|
||||
ieda_feature
|
||||
)
|
||||
if(OpenMP_CXX_FOUND)
|
||||
target_link_libraries(iGUI
|
||||
OpenMP::OpenMP_CXX
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
# add_subdirectory(${IDB_HOME} idb.out)
|
||||
SET(CMAKE_BUILD_TYPE "debug")
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/graphicsitem)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guiaction)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guicontroltree)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guiDB)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guiparser)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/designitem)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/utilityitem)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/utility)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/guispeedupitems)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/interface)
|
||||
target_include_directories(iGUI PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/config)
|
||||
target_include_directories(iGUI
|
||||
PUBLIC
|
||||
# ${HOME_PLATFORM}/
|
||||
# ${HOME_PLATFORM}//tool_api
|
||||
# ${HOME_PLATFORM}//tool_api/irt_io
|
||||
)
|
||||
|
|
|
|||
|
|
@ -55,6 +55,21 @@ bool feature_eval_summary(const std::string& path, int32_t grid_size)
|
|||
return featureInst->save_eval_summary(path, grid_size);
|
||||
}
|
||||
|
||||
bool feature_eval_union(const std::string& jsonl_path, const std::string& csv_path, int32_t grid_size)
|
||||
{
|
||||
return featureInst->save_eval_union(jsonl_path, csv_path, grid_size);
|
||||
}
|
||||
|
||||
bool feature_pl_eval_union(const std::string& jsonl_path, const std::string& csv_path, int32_t grid_size)
|
||||
{
|
||||
return featureInst->save_pl_eval_union(jsonl_path, csv_path, grid_size);
|
||||
}
|
||||
|
||||
bool feature_cts_eval_union(const std::string& jsonl_path, const std::string& csv_path, int32_t grid_size)
|
||||
{
|
||||
return featureInst->save_cts_eval_union(jsonl_path, csv_path, grid_size);
|
||||
}
|
||||
|
||||
bool feature_timing_eval_summary(const std::string& path)
|
||||
{
|
||||
return featureInst->save_timing_eval_summary(path);
|
||||
|
|
|
|||
|
|
@ -28,5 +28,8 @@ bool feature_route_read(const std::string& path);
|
|||
bool feature_eval_summary(const std::string& path, int32_t grid_size);
|
||||
bool feature_timing_eval_summary(const std::string& path);
|
||||
bool feature_net_eval(const std::string& path);
|
||||
bool feature_eval_union(const std::string& jsonl_path, const std::string& csv_path, int32_t grid_size);
|
||||
bool feature_pl_eval_union(const std::string& jsonl_path, const std::string& csv_path, int32_t grid_size);
|
||||
bool feature_cts_eval_union(const std::string& jsonl_path, const std::string& csv_path, int32_t grid_size);
|
||||
|
||||
} // namespace python_interface
|
||||
|
|
@ -32,6 +32,9 @@ void register_feature(py::module& m)
|
|||
m.def("feature_eval_summary", feature_eval_summary, py::arg("path"), py::arg("grid_size"));
|
||||
m.def("feature_timing_eval_summary", feature_timing_eval_summary, py::arg("path"));
|
||||
m.def("feature_net_eval", feature_net_eval, py::arg("path"));
|
||||
m.def("feature_eval_union", feature_eval_union, py::arg("jsonl_path"), py::arg("csv_path"), py::arg("grid_size"));
|
||||
m.def("feature_pl_eval_union", feature_pl_eval_union, py::arg("jsonl_path"), py::arg("csv_path"), py::arg("grid_size"));
|
||||
m.def("feature_cts_eval_union", feature_cts_eval_union, py::arg("jsonl_path"), py::arg("csv_path"), py::arg("grid_size"));
|
||||
}
|
||||
|
||||
} // namespace python_interface
|
||||
|
|
@ -32,7 +32,8 @@ void register_idb(py::module& m)
|
|||
m.def("def_init", initDef, py::arg("def_path"));
|
||||
m.def("verilog_init", initVerilog, py::arg("verilog_path"), py::arg("top_module"));
|
||||
m.def("def_save", saveDef, py::arg("def_name"));
|
||||
m.def("netlist_save", saveNetList, py::arg("netlist_path"), py::arg("exclude_cell_names") = std::set<std::string>{});
|
||||
m.def("netlist_save", saveNetList, py::arg("netlist_path"), py::arg("exclude_cell_names") = std::set<std::string>{},
|
||||
py::arg("is_add_space_for_escape_name") = false);
|
||||
m.def("gds_save", saveGDSII, py::arg("gds_name"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,11 @@ build_connection_map(std::vector<std::set<std::string>> clusters, std::set<std::
|
|||
|
||||
std::vector<ipower::MacroConnection> build_macro_connection_map(unsigned max_hop) {
|
||||
auto* power_engine = ipower::PowerEngine::getOrCreatePowerEngine();
|
||||
#ifdef USE_GPU
|
||||
return power_engine->buildMacroConnectionMapWithGPU(max_hop);
|
||||
#else
|
||||
return power_engine->buildMacroConnectionMap(max_hop);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace python_interface
|
||||
|
|
@ -47,7 +47,7 @@ CmdFeatureSummary::CmdFeatureSummary(const char* cmd_name) : TclCmd(cmd_name)
|
|||
unsigned CmdFeatureSummary::check()
|
||||
{
|
||||
TclOption* path_option = getOptionOrArg(TCL_PATH);
|
||||
//TclOption* step_option = getOptionOrArg(TCL_STEP);
|
||||
// TclOption* step_option = getOptionOrArg(TCL_STEP);
|
||||
LOG_FATAL_IF(!path_option);
|
||||
// LOG_FATAL_IF(!step_option);
|
||||
return 1;
|
||||
|
|
@ -226,4 +226,50 @@ unsigned CmdFeatureRouteRead::exec()
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* feature_cong_map -dir "/your/dir/path/"
|
||||
*/
|
||||
CmdFeatureCongMap::CmdFeatureCongMap(const char* cmd_name) : TclCmd(cmd_name)
|
||||
{
|
||||
auto* dir_option = new TclStringOption(TCL_DIRECTORY, 1, nullptr);
|
||||
auto* step_option = new TclStringOption(TCL_STEP, 1, nullptr);
|
||||
addOption(dir_option);
|
||||
addOption(step_option);
|
||||
}
|
||||
|
||||
unsigned CmdFeatureCongMap::check()
|
||||
{
|
||||
TclOption* dir_option = getOptionOrArg(TCL_DIRECTORY);
|
||||
TclOption* step_option = getOptionOrArg(TCL_STEP);
|
||||
|
||||
LOG_FATAL_IF(!dir_option);
|
||||
LOG_FATAL_IF(!step_option);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned CmdFeatureCongMap::exec()
|
||||
{
|
||||
if (!check()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TclOption* option = getOptionOrArg(TCL_DIRECTORY);
|
||||
auto dir_path = option->getStringVal();
|
||||
|
||||
std::string stage = "";
|
||||
TclOption* step_option = getOptionOrArg(TCL_STEP);
|
||||
if (step_option->getStringVal() != nullptr) {
|
||||
stage = step_option->getStringVal();
|
||||
}
|
||||
|
||||
featureInst->save_cong_map(stage, dir_path);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace tcl
|
||||
|
|
|
|||
|
|
@ -119,4 +119,18 @@ class CmdFeatureEvalSummary : public TclCmd
|
|||
// private data
|
||||
};
|
||||
|
||||
class CmdFeatureCongMap : public TclCmd
|
||||
{
|
||||
public:
|
||||
explicit CmdFeatureCongMap(const char* cmd_name);
|
||||
~CmdFeatureCongMap() override = default;
|
||||
|
||||
unsigned check() override;
|
||||
unsigned exec() override;
|
||||
|
||||
private:
|
||||
// private function
|
||||
// private data
|
||||
};
|
||||
|
||||
} // namespace tcl
|
||||
|
|
@ -38,6 +38,7 @@ int registerCmdFeature()
|
|||
registerTclCmd(CmdFeatureEvalMap, "feature_eval_map");
|
||||
registerTclCmd(CmdFeatureRoute, "feature_route");
|
||||
registerTclCmd(CmdFeatureRouteRead, "feature_route_read");
|
||||
registerTclCmd(CmdFeatureCongMap, "feature_cong_map");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ CmdTOConfig::CmdTOConfig(const char* cmd_name) : TclCmd(cmd_name)
|
|||
_config_list.push_back(std::make_pair("-min_divide_fanoutt", ValueType::kInt));
|
||||
// optimize_endpoints_percent double
|
||||
_config_list.push_back(std::make_pair("-optimize_endpoints_percent", ValueType::kDouble));
|
||||
// drv_optimize_iter_number int
|
||||
_config_list.push_back(std::make_pair("-drv_optimize_iter_number", ValueType::kInt));
|
||||
|
||||
TclUtil::addOption(this, _config_list);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -602,11 +602,17 @@ icts::CtsCellLib* CTSAPI::getCellLib(const std::string& cell_master, const std::
|
|||
y_slew.emplace_back(slew_mid_value[i * cap_out.size() + j]);
|
||||
}
|
||||
}
|
||||
LOG_FATAL_IF(x_slew_in.empty() || x_cap_out.empty() || y_delay.empty() || y_slew.empty())
|
||||
<< "No feasible work value, please check "
|
||||
"the config parameter: \"max_buf_tran\", \"max_sink_tran\" and "
|
||||
"\"max_cap\" with the liberty "
|
||||
<< cell_master;
|
||||
if (x_slew_in.empty() || x_cap_out.empty() || y_delay.empty() || y_slew.empty()) {
|
||||
LOG_WARNING << "No feasible work value, please check "
|
||||
"the config parameter: \"max_buf_tran\", \"max_sink_tran\" and "
|
||||
"\"max_cap\" with the liberty "
|
||||
<< cell_master;
|
||||
// use all value
|
||||
x_slew_in = slew_in;
|
||||
x_cap_out = cap_out;
|
||||
y_delay = delay_mid_value;
|
||||
y_slew = slew_mid_value;
|
||||
}
|
||||
std::vector<std::vector<double>> x_delay = {x_slew_in, x_cap_out};
|
||||
lib->set_delay_coef(_model_factory->cppLinearModel(x_delay, y_delay));
|
||||
|
||||
|
|
|
|||
|
|
@ -46,12 +46,14 @@ void GDSPloter::plotDesign(const std::string& path)
|
|||
head(ofs);
|
||||
|
||||
for (auto& clk_net : clk_nets) {
|
||||
size_t wire_id = 0;
|
||||
auto net_name = clk_net->get_net_name();
|
||||
|
||||
for (const auto& wire : clk_net->get_signal_wires()) {
|
||||
auto wire_name = "WIRE_" + net_name + "_" + std::to_string(wire_id++);
|
||||
auto first = wire.get_first().point;
|
||||
auto second = wire.get_second().point;
|
||||
insertWire(ofs, first, second, clk_net->get_driver_inst()->get_level());
|
||||
insertWire(ofs, first, second, wire_name, clk_net->get_driver_inst()->get_level());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +106,14 @@ void GDSPloter::plotDesign(const std::string& path)
|
|||
}
|
||||
}
|
||||
refPolygon(ofs, "core");
|
||||
refPolygon(ofs, "WIRE");
|
||||
for (auto& clk_net : clk_nets) {
|
||||
auto net_name = clk_net->get_net_name();
|
||||
|
||||
for (size_t i = 0; i < clk_net->get_signal_wires().size(); ++i) {
|
||||
auto wire_name = "WIRE_" + net_name + "_" + std::to_string(i);
|
||||
refPolygon(ofs, wire_name);
|
||||
}
|
||||
}
|
||||
strEnd(ofs);
|
||||
|
||||
tail(ofs);
|
||||
|
|
@ -129,9 +138,11 @@ void GDSPloter::plotFlyLine(const std::string& path)
|
|||
head(ofs);
|
||||
|
||||
for (auto& clk_net : clk_nets) {
|
||||
auto driver = clk_net->get_driver_inst();
|
||||
for (auto load : clk_net->get_load_insts()) {
|
||||
insertWire(ofs, driver->get_location(), load->get_location(), driver->get_level());
|
||||
auto* driver = clk_net->get_driver_inst();
|
||||
size_t wire_id = 0;
|
||||
for (auto* load : clk_net->get_load_insts()) {
|
||||
auto wire_name = "WIRE_" + clk_net->get_net_name() + "_" + std::to_string(wire_id++);
|
||||
insertWire(ofs, driver->get_location(), load->get_location(), wire_name, driver->get_level());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -184,7 +195,13 @@ void GDSPloter::plotFlyLine(const std::string& path)
|
|||
}
|
||||
}
|
||||
refPolygon(ofs, "core");
|
||||
refPolygon(ofs, "WIRE");
|
||||
|
||||
for (auto& clk_net : clk_nets) {
|
||||
for (size_t i = 0; i < clk_net->get_load_insts().size(); ++i) {
|
||||
auto wire_name = "WIRE_" + clk_net->get_net_name() + "_" + std::to_string(i);
|
||||
refPolygon(ofs, wire_name);
|
||||
}
|
||||
}
|
||||
strEnd(ofs);
|
||||
|
||||
tail(ofs);
|
||||
|
|
@ -392,10 +409,11 @@ void GDSPloter::insertInstance(std::fstream& log_ofs, CtsInstance* inst)
|
|||
insertPolygon(log_ofs, rect, name, layer);
|
||||
}
|
||||
|
||||
void GDSPloter::insertWire(std::fstream& log_ofs, const Point& begin, const Point& end, const int& layer, const int& width)
|
||||
void GDSPloter::insertWire(std::fstream& log_ofs, const Point& begin, const Point& end, const string& name, const int& layer,
|
||||
const int& width)
|
||||
{
|
||||
log_ofs << "BGNSTR" << std::endl;
|
||||
log_ofs << "STRNAME WIRE" << std::endl;
|
||||
log_ofs << "STRNAME " << name << std::endl;
|
||||
log_ofs << "PATH" << std::endl;
|
||||
log_ofs << "LAYER " + std::to_string(layer) << std::endl;
|
||||
log_ofs << "DATATYPE 0" << std::endl;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ class GDSPloter
|
|||
|
||||
static void insertPolygon(std::fstream& log_ofs, IdbRect& poly, const string& name = "polygon", int layer = 0, const int& type = 1);
|
||||
|
||||
static void insertWire(std::fstream& log_ofs, const Point& begin, const Point& end, const int& layer = 0, const int& width = 80);
|
||||
static void insertWire(std::fstream& log_ofs, const Point& begin, const Point& end, const string& name = "WIRE", const int& layer = 0,
|
||||
const int& width = 80);
|
||||
|
||||
static void head(std::fstream& log_ofs);
|
||||
static void tail(std::fstream& log_ofs);
|
||||
|
|
|
|||
|
|
@ -8,16 +8,12 @@ add_subdirectory(api)
|
|||
add_subdirectory(source)
|
||||
# add_subdirectory(test)
|
||||
|
||||
if(BUILD_PR_FLOW)
|
||||
# ADD_EXECUTABLE(run_drc ${IDRC_TESTS}/run_drc.cpp)
|
||||
# TARGET_LINK_LIBRARIES(run_drc DRC)
|
||||
else(BUILD_PR_FLOW)
|
||||
ADD_EXECUTABLE(run_drc ${IDRC_TESTS}/run_drc.cpp)
|
||||
TARGET_LINK_LIBRARIES(run_drc DRC)
|
||||
|
||||
ADD_EXECUTABLE(conflict_graph ${IDRC_TESTS}/conflict_graph.cpp)
|
||||
TARGET_LINK_LIBRARIES(conflict_graph DRC)
|
||||
|
||||
add_executable(test_boost ${IDRC_TESTS}/test_boost.cpp)
|
||||
target_link_libraries(test_boost DRC)
|
||||
endif(BUILD_PR_FLOW)
|
||||
|
||||
# ADD_EXECUTABLE(run_drc ${IDRC_TESTS}/run_drc.cpp)
|
||||
# TARGET_LINK_LIBRARIES(run_drc DRC)
|
||||
|
||||
# ADD_EXECUTABLE(conflict_graph ${IDRC_TESTS}/conflict_graph.cpp)
|
||||
# TARGET_LINK_LIBRARIES(conflict_graph DRC)
|
||||
|
||||
# add_executable(test_boost ${IDRC_TESTS}/test_boost.cpp)
|
||||
# target_link_libraries(test_boost DRC)
|
||||
|
|
@ -377,13 +377,13 @@ void PLAPI::runFlow()
|
|||
{
|
||||
// runMP();
|
||||
runGP();
|
||||
printHPWLInfo();
|
||||
printTimingInfo();
|
||||
notifyPLWLInfo(0);
|
||||
if (isSTAStarted()) {
|
||||
notifyPLCongestionInfo(0);
|
||||
notifyPLTimingInfo(0);
|
||||
}
|
||||
// printHPWLInfo();
|
||||
// printTimingInfo();
|
||||
// notifyPLWLInfo(0);
|
||||
// if (isSTAStarted()) {
|
||||
// notifyPLCongestionInfo(0);
|
||||
// notifyPLTimingInfo(0);
|
||||
// }
|
||||
|
||||
if (PlacerDBInst.get_placer_config()->get_buffer_config().isMaxLengthOpt()) {
|
||||
std::cout << std::endl;
|
||||
|
|
@ -398,13 +398,13 @@ void PLAPI::runFlow()
|
|||
|
||||
std::cout << std::endl;
|
||||
runLG();
|
||||
printHPWLInfo();
|
||||
printTimingInfo();
|
||||
notifyPLWLInfo(1);
|
||||
if (isSTAStarted()) {
|
||||
notifyPLCongestionInfo(1);
|
||||
notifyPLTimingInfo(1);
|
||||
}
|
||||
// printHPWLInfo();
|
||||
// printTimingInfo();
|
||||
// notifyPLWLInfo(1);
|
||||
// if (isSTAStarted()) {
|
||||
// notifyPLCongestionInfo(1);
|
||||
// notifyPLTimingInfo(1);
|
||||
// }
|
||||
|
||||
std::cout << std::endl;
|
||||
if (isSTAStarted()) {
|
||||
|
|
@ -412,14 +412,14 @@ void PLAPI::runFlow()
|
|||
} else {
|
||||
runDP();
|
||||
}
|
||||
printHPWLInfo();
|
||||
printTimingInfo();
|
||||
// printHPWLInfo();
|
||||
// printTimingInfo();
|
||||
|
||||
notifyPLWLInfo(2);
|
||||
if (isSTAStarted()) {
|
||||
notifyPLCongestionInfo(2);
|
||||
notifyPLTimingInfo(2);
|
||||
}
|
||||
// notifyPLWLInfo(2);
|
||||
// if (isSTAStarted()) {
|
||||
// notifyPLCongestionInfo(2);
|
||||
// notifyPLTimingInfo(2);
|
||||
// }
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
|
|
@ -950,46 +950,46 @@ ieda_feature::PlaceSummary PLAPI::outputSummary(std::string step)
|
|||
|
||||
// 1:全局布局、详细布局、合法化都需要存储的数据参数,需要根据step存储不同的值
|
||||
auto place_density = PlacerDBInst.place_density;
|
||||
auto pin_density = PlacerDBInst.pin_density;
|
||||
auto HPWL = PlacerDBInst.PL_HPWL;
|
||||
auto STWL = PlacerDBInst.PL_STWL;
|
||||
auto GRWL = PlacerDBInst.PL_GRWL;
|
||||
// auto pin_density = PlacerDBInst.pin_density;
|
||||
// auto HPWL = PlacerDBInst.PL_HPWL;
|
||||
// auto STWL = PlacerDBInst.PL_STWL;
|
||||
// auto GRWL = PlacerDBInst.PL_GRWL;
|
||||
|
||||
auto egr_tof = PlacerDBInst.egr_tof;
|
||||
auto egr_mof = PlacerDBInst.egr_mof;
|
||||
auto egr_ace = PlacerDBInst.egr_ace;
|
||||
// auto egr_tof = PlacerDBInst.egr_tof;
|
||||
// auto egr_mof = PlacerDBInst.egr_mof;
|
||||
// auto egr_ace = PlacerDBInst.egr_ace;
|
||||
|
||||
auto tns = PlacerDBInst.tns;
|
||||
auto wns = PlacerDBInst.wns;
|
||||
auto suggest_freq = PlacerDBInst.suggest_freq;
|
||||
// auto tns = PlacerDBInst.tns;
|
||||
// auto wns = PlacerDBInst.wns;
|
||||
// auto suggest_freq = PlacerDBInst.suggest_freq;
|
||||
|
||||
// 2:全局布局、详细布局需要存储的数据参数
|
||||
if (step == "place") {
|
||||
summary.gplace.place_density = place_density[0];
|
||||
summary.gplace.pin_density = pin_density[0];
|
||||
summary.gplace.HPWL = HPWL[0];
|
||||
summary.gplace.STWL = STWL[0];
|
||||
summary.gplace.GRWL = GRWL[0];
|
||||
// summary.gplace.pin_density = pin_density[0];
|
||||
// summary.gplace.HPWL = HPWL[0];
|
||||
// summary.gplace.STWL = STWL[0];
|
||||
// summary.gplace.GRWL = GRWL[0];
|
||||
|
||||
summary.gplace.egr_tof = egr_tof[0];
|
||||
summary.gplace.egr_mof = egr_mof[0];
|
||||
summary.gplace.egr_ace = egr_ace[0];
|
||||
summary.gplace.tns = tns[0];
|
||||
summary.gplace.wns = wns[0];
|
||||
summary.gplace.suggest_freq = suggest_freq[0];
|
||||
// summary.gplace.egr_tof = egr_tof[0];
|
||||
// summary.gplace.egr_mof = egr_mof[0];
|
||||
// summary.gplace.egr_ace = egr_ace[0];
|
||||
// summary.gplace.tns = tns[0];
|
||||
// summary.gplace.wns = wns[0];
|
||||
// summary.gplace.suggest_freq = suggest_freq[0];
|
||||
|
||||
summary.dplace.place_density = place_density[1];
|
||||
summary.dplace.pin_density = pin_density[1];
|
||||
summary.dplace.HPWL = HPWL[1];
|
||||
summary.dplace.STWL = STWL[1];
|
||||
summary.dplace.GRWL = GRWL[1];
|
||||
// summary.dplace.pin_density = pin_density[1];
|
||||
// summary.dplace.HPWL = HPWL[1];
|
||||
// summary.dplace.STWL = STWL[1];
|
||||
// summary.dplace.GRWL = GRWL[1];
|
||||
|
||||
summary.dplace.egr_tof = egr_tof[1];
|
||||
summary.dplace.egr_mof = egr_mof[1];
|
||||
summary.dplace.egr_ace = egr_ace[1];
|
||||
summary.dplace.tns = tns[1];
|
||||
summary.dplace.wns = wns[1];
|
||||
summary.dplace.suggest_freq = suggest_freq[1];
|
||||
// summary.dplace.egr_tof = egr_tof[1];
|
||||
// summary.dplace.egr_mof = egr_mof[1];
|
||||
// summary.dplace.egr_ace = egr_ace[1];
|
||||
// summary.dplace.tns = tns[1];
|
||||
// summary.dplace.wns = wns[1];
|
||||
// summary.dplace.suggest_freq = suggest_freq[1];
|
||||
|
||||
auto* pl_design = PlacerDBInst.get_design();
|
||||
summary.instance_cnt = pl_design->get_instances_range();
|
||||
|
|
@ -1014,17 +1014,17 @@ ieda_feature::PlaceSummary PLAPI::outputSummary(std::string step)
|
|||
// 3:合法化需要存储的数据参数
|
||||
else if (step == "legalization") {
|
||||
summary.lg_summary.pl_common_summary.place_density = place_density[2];
|
||||
summary.lg_summary.pl_common_summary.pin_density = pin_density[2];
|
||||
summary.lg_summary.pl_common_summary.HPWL = HPWL[2];
|
||||
summary.lg_summary.pl_common_summary.STWL = STWL[2];
|
||||
summary.lg_summary.pl_common_summary.GRWL = GRWL[2];
|
||||
// summary.lg_summary.pl_common_summary.pin_density = pin_density[2];
|
||||
// summary.lg_summary.pl_common_summary.HPWL = HPWL[2];
|
||||
// summary.lg_summary.pl_common_summary.STWL = STWL[2];
|
||||
// summary.lg_summary.pl_common_summary.GRWL = GRWL[2];
|
||||
|
||||
summary.lg_summary.pl_common_summary.egr_tof = egr_tof[2];
|
||||
summary.lg_summary.pl_common_summary.egr_mof = egr_mof[2];
|
||||
summary.lg_summary.pl_common_summary.egr_ace = egr_ace[2];
|
||||
summary.lg_summary.pl_common_summary.tns = tns[2];
|
||||
summary.lg_summary.pl_common_summary.wns = wns[2];
|
||||
summary.lg_summary.pl_common_summary.suggest_freq = suggest_freq[2];
|
||||
// summary.lg_summary.pl_common_summary.egr_tof = egr_tof[2];
|
||||
// summary.lg_summary.pl_common_summary.egr_mof = egr_mof[2];
|
||||
// summary.lg_summary.pl_common_summary.egr_ace = egr_ace[2];
|
||||
// summary.lg_summary.pl_common_summary.tns = tns[2];
|
||||
// summary.lg_summary.pl_common_summary.wns = wns[2];
|
||||
// summary.lg_summary.pl_common_summary.suggest_freq = suggest_freq[2];
|
||||
|
||||
summary.lg_summary.lg_total_movement = PlacerDBInst.lg_total_movement;
|
||||
summary.lg_summary.lg_max_movement = PlacerDBInst.lg_max_movement;
|
||||
|
|
|
|||
|
|
@ -175,14 +175,14 @@ ieval::TotalWLSummary ExternalAPI::evalproIDBWL()
|
|||
|
||||
ieval::OverflowSummary ExternalAPI::evalproCongestion()
|
||||
{
|
||||
CONGESTION_API_INST->egrMap();
|
||||
CONGESTION_API_INST->egrMap("place");
|
||||
|
||||
return CONGESTION_API_INST->egrOverflow();
|
||||
return CONGESTION_API_INST->egrOverflow("place");
|
||||
}
|
||||
|
||||
float ExternalAPI::obtainPeakAvgPinDens()
|
||||
{
|
||||
ieval::PinMapSummary pin_map_summary = DENSITY_API_INST->pinDensityMap();
|
||||
ieval::PinMapSummary pin_map_summary = DENSITY_API_INST->pinDensityMap("place");
|
||||
|
||||
std::string file_path = pin_map_summary.allcell_pin_density;
|
||||
std::ifstream file(file_path);
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@
|
|||
#include <vector>
|
||||
|
||||
#include "GridManager.hh"
|
||||
#include "TopologyManager.hh"
|
||||
#include "Parameter.hh"
|
||||
#include "NesInstance.hh"
|
||||
#include "Parameter.hh"
|
||||
#include "TopologyManager.hh"
|
||||
|
||||
namespace ipl {
|
||||
|
||||
|
|
@ -72,17 +72,17 @@ class BinGrid
|
|||
int64_t get_overflow_area_without_filler() const { return _overflow_area_wofiller; }
|
||||
|
||||
void set_thread_nums(int32_t thread_nums) { _thread_nums = thread_nums; }
|
||||
void set_route_cap_h(int num) {_route_cap_h = num;}
|
||||
void set_route_cap_v(int num) {_route_cap_v = num;}
|
||||
void set_partial_route_cap_h(int num) {_partial_route_cap_h = num;}
|
||||
void set_partial_route_cap_v(int num) {_partial_route_cap_v = num;}
|
||||
void set_route_cap_h(int num) { _route_cap_h = num; }
|
||||
void set_route_cap_v(int num) { _route_cap_v = num; }
|
||||
void set_partial_route_cap_h(int num) { _partial_route_cap_h = num; }
|
||||
void set_partial_route_cap_v(int num) { _partial_route_cap_v = num; }
|
||||
|
||||
void initNesInstanceTypeList(std::vector<NesInstance*>& nInst_list);
|
||||
|
||||
void updateBinGrid(std::vector<NesInstance*>& nInst_list, int32_t thread_num);
|
||||
void updataOverflowArea(std::vector<NesInstance*>& nInst_list, int32_t thread_num);
|
||||
|
||||
void evalRouteDem(const std::vector<NetWork*>& network_list,int32_t thread_num);
|
||||
void evalRouteDem(const std::vector<NetWork*>& network_list, int32_t thread_num);
|
||||
void evalRouteCap(int32_t thread_num);
|
||||
void evalRouteUtil();
|
||||
void plotRouteCap();
|
||||
|
|
@ -96,7 +96,7 @@ class BinGrid
|
|||
|
||||
std::vector<Grid*> obtainOccupiedBinList(NesInstance* nInst); // TODO.
|
||||
std::vector<NesInstance*> obtainOccupiednInstList(Grid* bin); // TODO.
|
||||
GridManager* get_grid_manager() const {return _grid_manager;}
|
||||
GridManager* get_grid_manager() const { return _grid_manager; }
|
||||
|
||||
private:
|
||||
GridManager* _grid_manager;
|
||||
|
|
@ -114,7 +114,7 @@ class BinGrid
|
|||
int32_t _bin_cnt_y;
|
||||
int32_t _bin_size_x;
|
||||
int32_t _bin_size_y;
|
||||
|
||||
|
||||
int _route_cap_h;
|
||||
int _route_cap_v;
|
||||
int _partial_route_cap_h;
|
||||
|
|
@ -125,7 +125,7 @@ class BinGrid
|
|||
|
||||
void resetBinToArea();
|
||||
|
||||
float calcLness(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t xmax, int32_t ymin, int32_t ymax);
|
||||
double calcLness(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t xmax, int32_t ymin, int32_t ymax);
|
||||
int64_t calcLowerLeftRP(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t ymin);
|
||||
int64_t calcLowerRightRP(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmax, int32_t ymin);
|
||||
int64_t calcUpperLeftRP(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t ymax);
|
||||
|
|
@ -164,7 +164,7 @@ inline void BinGrid::initNesInstanceTypeList(std::vector<NesInstance*>& nInst_li
|
|||
{
|
||||
for (auto* nInst : nInst_list) {
|
||||
if (nInst->isFixed()) {
|
||||
if (nInst->isMacro()){
|
||||
if (nInst->isMacro()) {
|
||||
_route_macro_inst_list.push_back(nInst);
|
||||
}
|
||||
continue;
|
||||
|
|
@ -258,34 +258,34 @@ inline void BinGrid::updataOverflowArea(std::vector<NesInstance*>& nInst_list, i
|
|||
_overflow_area_wofiller = overflow_area_wofiller;
|
||||
}
|
||||
|
||||
inline void BinGrid::evalRouteDem(const std::vector<NetWork*>& network_list,int32_t thread_num)
|
||||
inline void BinGrid::evalRouteDem(const std::vector<NetWork*>& network_list, int32_t thread_num)
|
||||
{
|
||||
_grid_manager->clearRUDY();
|
||||
int wire_space_h = _bin_size_y / (_route_cap_h / _bin_cnt_y);
|
||||
int wire_space_h = _bin_size_y / (_route_cap_h / _bin_cnt_y);
|
||||
int wire_space_v = _bin_size_x / (_route_cap_v / _bin_cnt_x);
|
||||
float dm_h = 4;
|
||||
float dm_v = 4;
|
||||
|
||||
#pragma omp parallel for num_threads(thread_num)
|
||||
for (auto* network : network_list) {
|
||||
if (network->isIgnoreNetwork()){
|
||||
if (network->isIgnoreNetwork()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
auto net_shape = std::move(network->obtainNetWorkShape());
|
||||
if (net_shape.get_ll_x() > net_shape.get_ur_x()){
|
||||
if (net_shape.get_ll_x() > net_shape.get_ur_x()) {
|
||||
continue;
|
||||
}
|
||||
if (net_shape.get_ur_x() > _grid_manager->get_shape().get_ur_x()){
|
||||
if (net_shape.get_ur_x() > _grid_manager->get_shape().get_ur_x()) {
|
||||
net_shape.set_upper_right(_grid_manager->get_shape().get_ur_x(), net_shape.get_ur_y());
|
||||
}
|
||||
if (net_shape.get_ur_y() > _grid_manager->get_shape().get_ur_y()){
|
||||
if (net_shape.get_ur_y() > _grid_manager->get_shape().get_ur_y()) {
|
||||
net_shape.set_upper_right(net_shape.get_ur_x(), _grid_manager->get_shape().get_ur_y());
|
||||
}
|
||||
if (net_shape.get_ll_x() < _grid_manager->get_shape().get_ll_x()){
|
||||
net_shape.set_lower_left(_grid_manager->get_shape().get_ll_x(),net_shape.get_ll_y());
|
||||
if (net_shape.get_ll_x() < _grid_manager->get_shape().get_ll_x()) {
|
||||
net_shape.set_lower_left(_grid_manager->get_shape().get_ll_x(), net_shape.get_ll_y());
|
||||
}
|
||||
if (net_shape.get_ll_y() < _grid_manager->get_shape().get_ll_y()){
|
||||
if (net_shape.get_ll_y() < _grid_manager->get_shape().get_ll_y()) {
|
||||
net_shape.set_lower_left(net_shape.get_ll_x(), _grid_manager->get_shape().get_ll_y());
|
||||
}
|
||||
|
||||
|
|
@ -295,31 +295,31 @@ inline void BinGrid::evalRouteDem(const std::vector<NetWork*>& network_list,int3
|
|||
|
||||
int32_t aspect_ratio = 1;
|
||||
if (net_width >= net_height && net_height != 0) {
|
||||
aspect_ratio = std::round(net_width / net_height);
|
||||
aspect_ratio = std::round(net_width / static_cast<double>(net_height));
|
||||
} else if (net_width < net_height && net_width != 0) {
|
||||
aspect_ratio = std::round(net_height / net_width);
|
||||
aspect_ratio = std::round(net_height / static_cast<double>(net_width));
|
||||
}
|
||||
|
||||
float l_ness = 0.0;
|
||||
if (pin_num <= 3){
|
||||
double l_ness = 0.0;
|
||||
if (pin_num <= 3) {
|
||||
l_ness = 1.0;
|
||||
}else if (pin_num <= 15){
|
||||
} else if (pin_num <= 15) {
|
||||
std::vector<std::pair<int32_t, int32_t>> point_set;
|
||||
point_set.reserve(pin_num);
|
||||
for (int i = 0; i < pin_num; ++i){
|
||||
for (int i = 0; i < pin_num; ++i) {
|
||||
const int32_t pin_x = network->get_node_list()[i]->get_location().get_x();
|
||||
const int32_t pin_y = network->get_node_list()[i]->get_location().get_y();
|
||||
point_set.emplace_back(std::make_pair(pin_x,pin_y));
|
||||
point_set.emplace_back(std::make_pair(pin_x, pin_y));
|
||||
}
|
||||
l_ness = calcLness(point_set, net_shape.get_ll_x(), net_shape.get_ur_x(), net_shape.get_ll_y(), net_shape.get_ur_y());
|
||||
}else{
|
||||
} else {
|
||||
l_ness = 0.5;
|
||||
}
|
||||
l_ness = netWiringDistributionMapWeight(pin_num, aspect_ratio, l_ness);
|
||||
|
||||
|
||||
std::vector<Grid*> overlap_grid_list;
|
||||
_grid_manager->obtainOverlapGridList(overlap_grid_list, net_shape);
|
||||
for (auto* grid : overlap_grid_list){
|
||||
for (auto* grid : overlap_grid_list) {
|
||||
auto& grid_h_cong = grid->h_cong;
|
||||
auto& grid_v_cong = grid->v_cong;
|
||||
|
||||
|
|
@ -336,10 +336,10 @@ inline void BinGrid::evalRouteDem(const std::vector<NetWork*>& network_list,int3
|
|||
|
||||
float tmp_h_cong = 0.0;
|
||||
float tmp_v_cong = 0.0;
|
||||
if (net_shape.get_height()!= 0){
|
||||
if (net_shape.get_height() != 0) {
|
||||
tmp_h_cong = l_ness * overlap_area * wire_space_h * dm_h / static_cast<float>(net_shape.get_height());
|
||||
}
|
||||
if (net_shape.get_width() != 0){
|
||||
if (net_shape.get_width() != 0) {
|
||||
tmp_v_cong = l_ness * overlap_area * wire_space_v * dm_v / static_cast<float>(net_shape.get_width());
|
||||
}
|
||||
|
||||
|
|
@ -356,26 +356,24 @@ inline void BinGrid::fastGaussianBlur()
|
|||
_grid_manager->blurRouteDemand();
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline float BinGrid::calcLness(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t xmax, int32_t ymin, int32_t ymax)
|
||||
inline double BinGrid::calcLness(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t xmax, int32_t ymin,
|
||||
int32_t ymax)
|
||||
{
|
||||
int64_t bbox = (xmax - xmin) * (ymax - ymin);
|
||||
int64_t R1 = calcLowerLeftRP(point_set, xmin, ymin);
|
||||
int64_t R2 = calcLowerRightRP(point_set, xmax, ymin);
|
||||
int64_t R3 = calcUpperLeftRP(point_set, xmin, ymax);
|
||||
int64_t R4 = calcUpperRightRP(point_set, xmax, ymax);
|
||||
int64_t R = std::max({R1, R2, R3, R4});
|
||||
float l_ness;
|
||||
int64_t bbox = static_cast<int64_t>(xmax - xmin) * static_cast<int64_t>(ymax - ymin);
|
||||
int64_t r1 = calcLowerLeftRP(point_set, xmin, ymin);
|
||||
int64_t r2 = calcLowerRightRP(point_set, xmax, ymin);
|
||||
int64_t r3 = calcUpperLeftRP(point_set, xmin, ymax);
|
||||
int64_t r4 = calcUpperRightRP(point_set, xmax, ymax);
|
||||
int64_t r = std::max({r1, r2, r3, r4});
|
||||
double l_ness;
|
||||
if (bbox != 0) {
|
||||
l_ness = R / bbox;
|
||||
l_ness = static_cast<double>(r) / static_cast<double>(bbox);
|
||||
} else {
|
||||
l_ness = 1.0;
|
||||
}
|
||||
return l_ness;
|
||||
}
|
||||
|
||||
|
||||
inline int64_t BinGrid::calcLowerLeftRP(std::vector<std::pair<int32_t, int32_t>>& point_set, int32_t xmin, int32_t ymin)
|
||||
{
|
||||
std::sort(point_set.begin(), point_set.end()); // Sort point_set with x-coordinates in ascending order
|
||||
|
|
@ -436,25 +434,22 @@ inline int64_t BinGrid::calcUpperRightRP(std::vector<std::pair<int32_t, int32_t>
|
|||
return R;
|
||||
}
|
||||
|
||||
|
||||
inline void BinGrid::evalRouteCap(int32_t thread_num)
|
||||
{
|
||||
int32_t bin_capa_h = _bin_size_x * _bin_size_y;
|
||||
int32_t bin_capa_v = bin_capa_h;
|
||||
_grid_manager->initRouteCap(bin_capa_h, bin_capa_v);
|
||||
|
||||
float util_h = _partial_route_cap_h / (float)_route_cap_h ;
|
||||
float util_v = _partial_route_cap_v / (float)_route_cap_v ;
|
||||
|
||||
float util_h = _partial_route_cap_h / (float) _route_cap_h;
|
||||
float util_v = _partial_route_cap_v / (float) _route_cap_v;
|
||||
|
||||
#pragma omp parallel for num_threads(thread_num)
|
||||
for(size_t i = 0; i < _route_macro_inst_list.size(); ++i)
|
||||
{
|
||||
for (size_t i = 0; i < _route_macro_inst_list.size(); ++i) {
|
||||
auto macro_shape = _route_macro_inst_list[i]->get_origin_shape();
|
||||
|
||||
std::vector<Grid*> overlap_grid_list;
|
||||
_grid_manager->obtainOverlapGridList(overlap_grid_list, macro_shape);
|
||||
for (auto* grid : overlap_grid_list)
|
||||
{
|
||||
for (auto* grid : overlap_grid_list) {
|
||||
auto& grid_h_cap = grid->h_cap;
|
||||
auto& grid_v_cap = grid->v_cap;
|
||||
|
||||
|
|
@ -476,7 +471,6 @@ inline void BinGrid::evalRouteCap(int32_t thread_num)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
inline void BinGrid::evalRouteUtil()
|
||||
{
|
||||
_grid_manager->evalRouteUtil();
|
||||
|
|
@ -495,22 +489,21 @@ inline void BinGrid::plotOverflowUtil(float sum_overflow, int32_t iter_num)
|
|||
// plot_h << feed_h.str() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
inline void BinGrid::plotRouteCap()
|
||||
{
|
||||
_grid_manager->plotRouteCap();
|
||||
}
|
||||
|
||||
inline void BinGrid::plotRouteDem(){
|
||||
inline void BinGrid::plotRouteDem()
|
||||
{
|
||||
_grid_manager->plotRouteDem();
|
||||
}
|
||||
|
||||
inline void BinGrid::plotRouteUtil(int32_t iter_num){
|
||||
inline void BinGrid::plotRouteUtil(int32_t iter_num)
|
||||
{
|
||||
_grid_manager->plotRouteUtil(iter_num);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline int64_t BinGrid::obtainOverflowAreaWithoutFiller()
|
||||
{
|
||||
int64_t overflow_area = 0;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
|
|||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(SANITIZER OFF)
|
||||
|
||||
if(SANITIZER)
|
||||
add_compile_options("-fsanitize=thread")
|
||||
link_libraries("-fsanitize=thread")
|
||||
|
|
@ -32,6 +31,12 @@ include_directories(${PROJECT_SOURCE_DIR}/src/operation/iPW/source/module)
|
|||
|
||||
include_directories(${HOME_THIRDPARTY}/pybind11)
|
||||
|
||||
|
||||
if (USE_GPU)
|
||||
message("power use gpu mode.")
|
||||
add_subdirectory(source/gpu-kernel)
|
||||
endif()
|
||||
|
||||
add_subdirectory(api)
|
||||
add_subdirectory(source/module/core)
|
||||
add_subdirectory(source/module/ops/annotate_toggle_sp)
|
||||
|
|
@ -45,6 +50,7 @@ add_subdirectory(source/module/ops/read_vcd)
|
|||
add_subdirectory(source/module/ops/plot_power)
|
||||
add_subdirectory(source/shell-cmd)
|
||||
add_subdirectory(source/python-api)
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
add_executable(iPower main.cc)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,12 @@ aux_source_directory(./ SRC)
|
|||
|
||||
add_library(power ${SRC})
|
||||
|
||||
if (USE_GPU)
|
||||
target_link_libraries(power power-gpu core vcd_wrapper build_graph propagate_toggle_sp levelize dump calc_power plot_power)
|
||||
else ()
|
||||
target_link_libraries(power core vcd_wrapper build_graph propagate_toggle_sp levelize dump calc_power plot_power)
|
||||
endif()
|
||||
|
||||
target_include_directories(power
|
||||
PUBLIC
|
||||
${PROJECT_SOURCE_DIR}/src/operation/iPW/source/module
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
#include "PowerEngine.hh"
|
||||
#include "ThreadPool/ThreadPool.h"
|
||||
#include "gpu-kernel/kernel_common.h"
|
||||
#ifdef USE_GPU
|
||||
#include "gpu-kernel/power_kernel.cuh"
|
||||
#endif
|
||||
#include "usage/usage.hh"
|
||||
|
||||
namespace ipower {
|
||||
|
|
@ -235,49 +239,57 @@ std::vector<MacroConnection> PowerEngine::buildMacroConnectionMap(
|
|||
// dfs macro connecton from one seq vertex.
|
||||
std::function<void(PwrSeqVertex*, PwrSeqVertex*, std::vector<unsigned>&,
|
||||
unsigned)>
|
||||
dfs_from_src_seq_vertex =
|
||||
[¯o_connections, &connection_mutex, &max_hop,
|
||||
&dfs_from_src_seq_vertex](PwrSeqVertex* src_marco_vertex,
|
||||
PwrSeqVertex* current_macro_vertex,
|
||||
std::vector<unsigned> stages_each_hop,
|
||||
unsigned hop) {
|
||||
if (hop == 0) {
|
||||
return;
|
||||
}
|
||||
dfs_from_src_seq_vertex = [¯o_connections, &connection_mutex,
|
||||
&max_hop, &dfs_from_src_seq_vertex](
|
||||
PwrSeqVertex* src_seq_vertex,
|
||||
PwrSeqVertex* current_macro_vertex,
|
||||
std::vector<unsigned> stages_each_hop,
|
||||
unsigned hop) {
|
||||
if (hop == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::tuple<std::size_t, std::string, unsigned> one_connection;
|
||||
auto& src_arcs = current_macro_vertex->get_src_arcs();
|
||||
for (auto* src_arc : src_arcs) {
|
||||
auto* snk_seq_vertex = src_arc->get_snk();
|
||||
stages_each_hop[max_hop - hop] = src_arc->get_combine_depth();
|
||||
if (snk_seq_vertex->isMacro()) {
|
||||
std::string snk_obj_name(snk_seq_vertex->get_obj_name());
|
||||
MacroConnection one_connection(
|
||||
src_marco_vertex->get_own_seq_inst()->get_name(),
|
||||
snk_seq_vertex->get_own_seq_inst()->get_name(),
|
||||
stages_each_hop, max_hop - hop + 1);
|
||||
{
|
||||
// add connection.
|
||||
std::lock_guard lk(connection_mutex);
|
||||
macro_connections.emplace_back(std::move(one_connection));
|
||||
}
|
||||
}
|
||||
|
||||
dfs_from_src_seq_vertex(src_marco_vertex, snk_seq_vertex,
|
||||
stages_each_hop, hop - 1);
|
||||
std::tuple<std::size_t, std::string, unsigned> one_connection;
|
||||
auto& src_arcs = current_macro_vertex->get_src_arcs();
|
||||
for (auto* src_arc : src_arcs) {
|
||||
auto* snk_seq_vertex = src_arc->get_snk();
|
||||
stages_each_hop[max_hop - hop] = src_arc->get_combine_depth();
|
||||
if (snk_seq_vertex->isMacro() || snk_seq_vertex->isOutputPort()) {
|
||||
const char* src_vertex_name = src_seq_vertex->get_obj_name().data();
|
||||
const char* snk_vertex_name = snk_seq_vertex->get_obj_name().data();
|
||||
if (src_seq_vertex->isInputPort() ||
|
||||
snk_seq_vertex->isOutputPort()) {
|
||||
LOG_INFO_FIRST_N(100) << "port connection: " << src_vertex_name
|
||||
<< " -> " << snk_vertex_name;
|
||||
}
|
||||
};
|
||||
MacroConnection one_connection(src_vertex_name, snk_vertex_name,
|
||||
stages_each_hop, max_hop - hop + 1);
|
||||
{
|
||||
// add connection.
|
||||
std::lock_guard lk(connection_mutex);
|
||||
macro_connections.emplace_back(std::move(one_connection));
|
||||
|
||||
LOG_INFO_EVERY_N(2000000)
|
||||
<< "build macro connection num: " << macro_connections.size();
|
||||
}
|
||||
}
|
||||
|
||||
dfs_from_src_seq_vertex(src_seq_vertex, snk_seq_vertex,
|
||||
stages_each_hop, hop - 1);
|
||||
}
|
||||
};
|
||||
|
||||
{
|
||||
ThreadPool thread_pool(48);
|
||||
PwrSeqVertex* seq_vertex;
|
||||
FOREACH_SEQ_VERTEX(&seq_graph, seq_vertex) {
|
||||
if (seq_vertex->isMacro()) {
|
||||
if (seq_vertex->isMacro() || seq_vertex->isInputPort()) {
|
||||
// dfs from src seq vertex.
|
||||
thread_pool.enqueue(
|
||||
[max_hop, &dfs_from_src_seq_vertex](auto* src_marco_vertex,
|
||||
[max_hop, &dfs_from_src_seq_vertex](auto* src_seq_vertex,
|
||||
auto* current_macro_vertex) {
|
||||
std::vector<unsigned> stages_each_hop(max_hop, 0);
|
||||
dfs_from_src_seq_vertex(src_marco_vertex, current_macro_vertex,
|
||||
dfs_from_src_seq_vertex(src_seq_vertex, current_macro_vertex,
|
||||
stages_each_hop, max_hop);
|
||||
},
|
||||
seq_vertex, seq_vertex);
|
||||
|
|
@ -290,6 +302,7 @@ std::vector<MacroConnection> PowerEngine::buildMacroConnectionMap(
|
|||
}
|
||||
|
||||
LOG_INFO << "build macro connection map end";
|
||||
LOG_INFO << "build macro connection num: " << macro_connections.size();
|
||||
double memory_delta = stats.memoryDelta();
|
||||
LOG_INFO << "build macro connection map memory usage " << memory_delta
|
||||
<< "MB";
|
||||
|
|
@ -299,4 +312,161 @@ std::vector<MacroConnection> PowerEngine::buildMacroConnectionMap(
|
|||
return macro_connections;
|
||||
}
|
||||
|
||||
#ifdef USE_GPU
|
||||
/**
|
||||
* @brief build macro connection map with gpu kernel.
|
||||
*
|
||||
* @param max_hop
|
||||
* @return std::vector<MacroConnection>
|
||||
*/
|
||||
std::vector<MacroConnection> PowerEngine::buildMacroConnectionMapWithGPU(
|
||||
unsigned max_hop) {
|
||||
ieda::Stats stats;
|
||||
LOG_INFO << "gpu build macro connection map start";
|
||||
auto& seq_graph = _ipower->get_power_seq_graph();
|
||||
int num_macro = seq_graph.getMacroSeqVertexNum();
|
||||
// The first connection point is the src macro vertex.
|
||||
std::vector<GPUConnectionPoint> connection_points(num_macro);
|
||||
|
||||
std::map<PwrSeqVertex*, unsigned> vertex_to_id;
|
||||
int num_seq_vertexes = seq_graph.get_vertexes().size();
|
||||
std::vector<unsigned> is_macros(num_seq_vertexes, 0);
|
||||
PwrSeqVertex* seq_vertex;
|
||||
int i = 0; // for seq vertex index.
|
||||
int j = 0; // for connection point index.
|
||||
FOREACH_SEQ_VERTEX(&seq_graph, seq_vertex) {
|
||||
if (seq_vertex->isMacro()) {
|
||||
connection_points[j]._src_id = i;
|
||||
connection_points[j++]._snk_id = i;
|
||||
is_macros[i] = 1;
|
||||
}
|
||||
vertex_to_id[seq_vertex] = i;
|
||||
++i;
|
||||
}
|
||||
|
||||
LOG_FATAL_IF(j != num_macro) << "Macro num is " << j;
|
||||
|
||||
// build cpu data for gpu data communcation.
|
||||
std::vector<unsigned> seq_arcs; // seq arc snk id vector.
|
||||
std::vector<unsigned> snk_arcs; // snk arc [start, end] pair id vector.
|
||||
std::vector<unsigned> snk_depths; // snk arc combine cell depth vector.
|
||||
FOREACH_SEQ_VERTEX(&seq_graph, seq_vertex) {
|
||||
PwrSeqArc* seq_arc;
|
||||
std::pair<int, int> snk_arc_id_pair{-1, -1};
|
||||
FOREACH_SRC_SEQ_ARC(seq_vertex, seq_arc) {
|
||||
auto* snk_seq_vertex = seq_arc->get_snk();
|
||||
unsigned snk_seq_vertex_id = vertex_to_id[snk_seq_vertex];
|
||||
seq_arcs.push_back(snk_seq_vertex_id);
|
||||
snk_depths.push_back(seq_arc->get_combine_depth());
|
||||
|
||||
if (snk_arc_id_pair.first == -1) {
|
||||
snk_arc_id_pair.first = seq_arcs.size() - 1;
|
||||
} else {
|
||||
snk_arc_id_pair.second = seq_arcs.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// for only one arc.
|
||||
snk_arcs.emplace_back(snk_arc_id_pair.first);
|
||||
if (snk_arc_id_pair.second == -1) {
|
||||
snk_arc_id_pair.second = snk_arc_id_pair.first;
|
||||
}
|
||||
snk_arcs.emplace_back(snk_arc_id_pair.second);
|
||||
}
|
||||
|
||||
LOG_INFO_IF(seq_arcs.size() != seq_graph.getSeqArcNum())
|
||||
<< "the seq arc size " << seq_arcs.size()
|
||||
<< " is not equal to seq graph arc num " << seq_graph.getSeqArcNum();
|
||||
|
||||
std::size_t output_connection_size = seq_arcs.size();
|
||||
std::vector<GPUConnectionPoint> out_connection_points(output_connection_size);
|
||||
int connection_point_num = connection_points.size();
|
||||
|
||||
auto& seq_vertexes = seq_graph.get_vertexes();
|
||||
|
||||
// use src arc to calc out connection num.
|
||||
auto calc_out_connection_num =
|
||||
[&seq_vertexes](auto& connection_points) -> int {
|
||||
int out_connection_point_num = 0;
|
||||
std::set<int> connection_ids;
|
||||
for (auto& connection_point : connection_points) {
|
||||
int connection_id = connection_point._snk_id;
|
||||
if (connection_ids.contains(connection_id)) {
|
||||
continue;
|
||||
}
|
||||
connection_ids.insert(connection_id);
|
||||
// get src arc num.
|
||||
auto& seq_vertex = seq_vertexes[connection_id];
|
||||
out_connection_point_num += seq_vertex->get_src_arcs().size();
|
||||
}
|
||||
|
||||
return out_connection_point_num;
|
||||
};
|
||||
|
||||
// the actual number of out connection points.
|
||||
int out_connection_point_num = calc_out_connection_num(connection_points);
|
||||
|
||||
std::vector<MacroConnection> macro_connections;
|
||||
bool is_free_memory = false;
|
||||
// call gpu function to bfs seq arc.
|
||||
for (unsigned i = 0; i < max_hop; ++i) {
|
||||
is_free_memory = (i == max_hop - 1) ? true : false;
|
||||
build_macro_connection_map(connection_points.data(), is_macros.data(),
|
||||
seq_arcs.data(), snk_depths.data(),
|
||||
snk_arcs.data(), connection_point_num,
|
||||
num_seq_vertexes, output_connection_size,
|
||||
out_connection_points.data(), is_free_memory);
|
||||
|
||||
// out connection give to connection and build connection map.
|
||||
connection_points.resize(out_connection_point_num);
|
||||
int connection_point_index = 0;
|
||||
for (std::size_t j = 0; j < output_connection_size; ++j) {
|
||||
int src_id = out_connection_points[j]._src_id;
|
||||
int snk_id = out_connection_points[j]._snk_id;
|
||||
// not tranversed, skip.
|
||||
if (snk_id == -1) {
|
||||
continue;
|
||||
}
|
||||
// set connection point
|
||||
connection_points[connection_point_index]._src_id = src_id;
|
||||
connection_points[connection_point_index++]._snk_id = snk_id;
|
||||
|
||||
if (seq_vertexes.at(snk_id)->isMacro()) {
|
||||
// build macro connection.
|
||||
MacroConnection macro_connection;
|
||||
macro_connection._src_macro_name =
|
||||
seq_vertexes[src_id]->get_own_seq_inst()->get_name();
|
||||
macro_connection._dst_macro_name =
|
||||
seq_vertexes[snk_id]->get_own_seq_inst()->get_name();
|
||||
|
||||
macro_connections.emplace_back(std::move(macro_connection));
|
||||
}
|
||||
|
||||
// reset data.
|
||||
out_connection_points[j]._src_id = -1;
|
||||
out_connection_points[j]._snk_id = -1;
|
||||
}
|
||||
|
||||
LOG_FATAL_IF(connection_point_index != out_connection_point_num)
|
||||
<< "connection_point_index " << connection_point_index
|
||||
<< " is not equal to out_connection_point_num "
|
||||
<< out_connection_point_num;
|
||||
|
||||
// update connection num and out connetion point num.
|
||||
connection_point_num = out_connection_point_num;
|
||||
out_connection_point_num = calc_out_connection_num(connection_points);
|
||||
}
|
||||
|
||||
LOG_INFO << "gpu build macro connection map end";
|
||||
double memory_delta = stats.memoryDelta();
|
||||
LOG_INFO << "gpu build macro connection map memory usage " << memory_delta
|
||||
<< "MB";
|
||||
double time_delta = stats.elapsedRunTime();
|
||||
LOG_INFO << "gpu build macro connection map time elapsed " << time_delta
|
||||
<< "s";
|
||||
|
||||
return macro_connections;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ipower
|
||||
|
|
@ -80,6 +80,10 @@ class PowerEngine {
|
|||
// api for build only macro connection.
|
||||
std::vector<MacroConnection> buildMacroConnectionMap(unsigned max_hop);
|
||||
|
||||
#ifdef USE_GPU
|
||||
std::vector<MacroConnection> buildMacroConnectionMapWithGPU(unsigned max_hop);
|
||||
#endif
|
||||
|
||||
private:
|
||||
PowerEngine();
|
||||
~PowerEngine();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
cmake_minimum_required(VERSION 3.15.0)
|
||||
|
||||
cmake_policy(SET CMP0104 NEW)
|
||||
set(CMAKE_CUDA_ARCHITECTURES native)
|
||||
|
||||
find_package(CUDAToolkit)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CUDA_STANDARD 17)
|
||||
|
||||
enable_language(CUDA)
|
||||
|
||||
include(CheckLanguage)
|
||||
check_language(CUDA)
|
||||
|
||||
if(NOT CUDAToolkit_FOUND)
|
||||
include(FindCUDAToolkit)
|
||||
endif()
|
||||
|
||||
set(lib_name "power-gpu")
|
||||
|
||||
add_compile_options("-fopenmp")
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
|
||||
set(NVCC_FLAGS -O3)
|
||||
message(STATUS "${lib_name} compile cuda code in release mode")
|
||||
else()
|
||||
set(NVCC_FLAGS -G)
|
||||
message(STATUS "${lib_name} compile cuda code in debug mode")
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE source_file LIST_DIRECTORIES false *.cpp *.c *.cuh *.h *.cu)
|
||||
|
||||
if(BUILD_STATIC_LIB)
|
||||
add_library(${lib_name} ${source_file})
|
||||
else()
|
||||
add_library(${lib_name} SHARED ${source_file})
|
||||
endif()
|
||||
|
||||
target_include_directories(${lib_name} PUBLIC ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
|
||||
|
||||
target_compile_options(${lib_name} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:${NVCC_FLAGS}>)
|
||||
|
||||
message(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
|
||||
|
||||
set_property(TARGET ${lib_name} PROPERTY LANGUAGES CXX CUDA)
|
||||
set_target_properties(${lib_name}
|
||||
PROPERTIES CUDA_SEPARABLE_COMPILATION ON
|
||||
CUDA_RESOLVE_DEVICE_SYMBOLS ON)
|
||||
|
||||
target_link_libraries(${lib_name} PRIVATE CUDA::cudart)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* @file kernel_common.h
|
||||
* @author simin tao (taosm@pcl.ac.cn)
|
||||
* @brief gpu cuda common functions file.
|
||||
* @version 0.1
|
||||
* @date 2024-10-11
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cuda_runtime.h>
|
||||
#include "kernel_common.h"
|
||||
|
||||
|
||||
inline void cudaCheck(cudaError_t error, const char *file, int line) {
|
||||
if (error != cudaSuccess) {
|
||||
printf("CUDA error at file %s:%d:\n%s\n", file, line, cudaGetErrorString(error));
|
||||
}
|
||||
};
|
||||
#define cudaWithCheck(err) (cudaCheck(err, __FILE__, __LINE__))
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* @file kernel_common.h
|
||||
* @author simin tao (taosm@pcl.ac.cn)
|
||||
* @brief gpu kernel common functions file.
|
||||
* @version 0.1
|
||||
* @date 2024-10-11
|
||||
*
|
||||
* @copyright Copyright (c) 2024
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
inline void *malloc_check(size_t size, const char *file, int line) {
|
||||
void *ptr = malloc(size);
|
||||
if (ptr == NULL) {
|
||||
printf("error: cpu memory allocation failed at %s:%d\n", file, line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#define mallocWithCheck(size) malloc_check(size, __FILE__, __LINE__)
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/**
|
||||
* @file power_kernel.cu
|
||||
* @author simin tao (taosm@pcl.ac.cn)
|
||||
* @brief The power gpu kernel for speed up power tool.
|
||||
* @version 0.1
|
||||
* @date 2024-10-09
|
||||
*
|
||||
*/
|
||||
#include "cuda_common.cuh"
|
||||
#include "power_kernel.cuh"
|
||||
|
||||
namespace ipower {
|
||||
|
||||
const int THREAD_PER_BLOCK_NUM = 1024;
|
||||
|
||||
/**
|
||||
* @brief use gpu to do seq graph bfs.
|
||||
*
|
||||
* @param connection_points the tranverse from connection point.
|
||||
* @param is_macros judge whether the seq vertex is a macro, each element is map to a seq vertex.
|
||||
* @param seq_arcs the snk point each seq vertex src arc reach to.
|
||||
* @param combine_depths each seq vertex src arc combine logic depth.
|
||||
* @param snk_arcs each seq vertex snk arc [start, end] pair.
|
||||
* @param connection_point_num the input connection point number.
|
||||
* @param num_seq_vertexes the seq graph vertex number.
|
||||
* @param num_seq_arcs the seq graph arc number.
|
||||
* @param out_connection_points out connection point number.
|
||||
* @return __global__
|
||||
*/
|
||||
__global__ void find_next_hop_macro(GPUConnectionPoint* connection_points,
|
||||
unsigned* is_macros, unsigned* seq_arcs,
|
||||
unsigned* combine_depths,
|
||||
unsigned* snk_arcs,
|
||||
int connection_point_num,
|
||||
int num_seq_vertexes, int num_seq_arcs,
|
||||
GPUConnectionPoint* out_connection_points) {
|
||||
int i = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
if (i < connection_point_num) {
|
||||
GPUConnectionPoint in_connection_point = connection_points[i];
|
||||
int seq_vertex_id = in_connection_point._snk_id;
|
||||
unsigned start = snk_arcs[seq_vertex_id * 2];
|
||||
unsigned end = snk_arcs[seq_vertex_id * 2 + 1];
|
||||
for (unsigned j = start; j <= end; ++j) {
|
||||
if (j >= num_seq_arcs) {
|
||||
printf(
|
||||
"thread %d seq vertex id %d seq index %d (start %d : end %d) "
|
||||
"beyond seq arc index.\n",
|
||||
i, seq_vertex_id, j, start, end);
|
||||
}
|
||||
unsigned snk_vertex = seq_arcs[j];
|
||||
out_connection_points[j]._src_id = in_connection_point._src_id;
|
||||
out_connection_points[j]._snk_id = snk_vertex;
|
||||
// printf(
|
||||
// "thread %d traverse next hop src id %d -> snk id %d with out "
|
||||
// "connection %d.\n",
|
||||
// i, in_connection_point._src_id, snk_vertex, j);
|
||||
}
|
||||
|
||||
// printf("thread %d traverse the connection point %d next hop.\n", i,
|
||||
// seq_vertex_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief build the macro connection map
|
||||
*
|
||||
* @param seq_vertexes the seq vertex index.
|
||||
* @param is_macros whether the seq vertex is macro.
|
||||
* @param seq_arcs the seq snk arcs for each seq vertex.
|
||||
* @param snk_arcs the snk arcs [start, end] for each seq vertex.
|
||||
* @param N the number of the seq vertex.
|
||||
* @param out_connection_points the output result of the macro connection
|
||||
* points.
|
||||
*/
|
||||
void build_macro_connection_map(GPUConnectionPoint* connection_points,
|
||||
unsigned* is_macros, unsigned* seq_arcs,
|
||||
unsigned* snk_depths, unsigned* snk_arcs,
|
||||
int connection_point_num, int num_seq_vertexes,
|
||||
int num_seq_arcs,
|
||||
GPUConnectionPoint* out_connection_points, bool is_free_memory) {
|
||||
cudaStream_t stream1 = nullptr;
|
||||
cudaStreamCreate(&stream1);
|
||||
|
||||
// for copy to gpu memrory.
|
||||
static GPUConnectionPoint* d_connection_points;
|
||||
static unsigned* d_is_macros;
|
||||
static unsigned* d_seq_arcs;
|
||||
static unsigned* d_snk_depths;
|
||||
static unsigned* d_snk_arcs;
|
||||
static GPUConnectionPoint* d_out_connection_points;
|
||||
|
||||
static bool is_init = false;
|
||||
|
||||
// init gpu memory.
|
||||
auto init_memory = [&]() {
|
||||
|
||||
cudaWithCheck(cudaMallocAsync(
|
||||
(void**)&d_is_macros, num_seq_vertexes * sizeof(unsigned), stream1));
|
||||
cudaWithCheck(cudaMallocAsync((void**)&d_seq_arcs,
|
||||
num_seq_arcs * sizeof(unsigned), stream1));
|
||||
cudaWithCheck(cudaMallocAsync((void**)&d_snk_depths,
|
||||
num_seq_arcs * sizeof(unsigned), stream1));
|
||||
// each point has start and end pair snk arc.
|
||||
cudaWithCheck(cudaMallocAsync(
|
||||
(void**)&d_snk_arcs, num_seq_vertexes * 2 * sizeof(unsigned), stream1));
|
||||
cudaWithCheck(cudaMallocAsync((void**)&d_out_connection_points,
|
||||
num_seq_arcs * sizeof(GPUConnectionPoint),
|
||||
stream1));
|
||||
|
||||
cudaStreamSynchronize(stream1);
|
||||
|
||||
cudaWithCheck(cudaMemcpyAsync(d_is_macros, is_macros,
|
||||
num_seq_vertexes * sizeof(unsigned),
|
||||
cudaMemcpyHostToDevice, stream1));
|
||||
cudaWithCheck(cudaMemcpyAsync(d_seq_arcs, seq_arcs,
|
||||
num_seq_arcs * sizeof(unsigned),
|
||||
cudaMemcpyHostToDevice, stream1));
|
||||
cudaWithCheck(cudaMemcpyAsync(d_snk_depths, snk_depths,
|
||||
num_seq_arcs * sizeof(unsigned),
|
||||
cudaMemcpyHostToDevice, stream1));
|
||||
// each point has start and end pair snk arc.
|
||||
cudaWithCheck(cudaMemcpyAsync(d_snk_arcs, snk_arcs,
|
||||
num_seq_vertexes * 2 * sizeof(unsigned),
|
||||
cudaMemcpyHostToDevice, stream1));
|
||||
};
|
||||
|
||||
if (!is_init) {
|
||||
init_memory();
|
||||
is_init = true;
|
||||
}
|
||||
|
||||
// need alloc memory every time.
|
||||
cudaWithCheck(cudaMallocAsync(
|
||||
(void**)&d_connection_points,
|
||||
connection_point_num * sizeof(GPUConnectionPoint), stream1));
|
||||
|
||||
cudaWithCheck(
|
||||
cudaMemcpyAsync(d_connection_points, connection_points,
|
||||
connection_point_num * sizeof(GPUConnectionPoint),
|
||||
cudaMemcpyHostToDevice, stream1));
|
||||
|
||||
cudaWithCheck(cudaMemcpyAsync(d_out_connection_points, out_connection_points,
|
||||
num_seq_arcs * sizeof(GPUConnectionPoint),
|
||||
cudaMemcpyHostToDevice, stream1));
|
||||
cudaStreamSynchronize(stream1);
|
||||
|
||||
int num_blocks =
|
||||
(connection_point_num + THREAD_PER_BLOCK_NUM - 1) / THREAD_PER_BLOCK_NUM;
|
||||
|
||||
printf("use block number %d per block num %d, start run gpu kernel.\n", num_blocks,
|
||||
THREAD_PER_BLOCK_NUM);
|
||||
|
||||
find_next_hop_macro<<<num_blocks, THREAD_PER_BLOCK_NUM>>>(
|
||||
d_connection_points, d_is_macros, d_seq_arcs, d_snk_depths, d_snk_arcs,
|
||||
connection_point_num, num_seq_vertexes, num_seq_arcs,
|
||||
d_out_connection_points);
|
||||
|
||||
// wait to finish.
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
printf("run gpu kernel finished.\n");
|
||||
|
||||
// copy back to host.
|
||||
cudaWithCheck(cudaMemcpyAsync(out_connection_points, d_out_connection_points,
|
||||
num_seq_arcs * sizeof(GPUConnectionPoint),
|
||||
cudaMemcpyDeviceToHost, stream1));
|
||||
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
cudaStreamDestroy(stream1);
|
||||
|
||||
// free memory.
|
||||
cudaWithCheck(cudaFree(d_connection_points));
|
||||
if (is_free_memory) {
|
||||
cudaWithCheck(cudaFree(d_is_macros));
|
||||
cudaWithCheck(cudaFree(d_seq_arcs));
|
||||
cudaWithCheck(cudaFree(d_snk_depths));
|
||||
cudaWithCheck(cudaFree(d_snk_arcs));
|
||||
cudaWithCheck(cudaFree(d_out_connection_points));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ipower
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
// ***************************************************************************************
|
||||
// Copyright (c) 2023-2025 Peng Cheng Laboratory
|
||||
// Copyright (c) 2023-2025 Institute of Computing Technology, Chinese Academy of
|
||||
// Sciences Copyright (c) 2023-2025 Beijing Institute of Open Source Chip
|
||||
//
|
||||
// iEDA is licensed under Mulan PSL v2.
|
||||
// You can use this software according to the terms and conditions of the Mulan
|
||||
// PSL v2. You may obtain a copy of Mulan PSL v2 at:
|
||||
// http://license.coscl.org.cn/MulanPSL2
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
|
||||
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the Mulan PSL v2 for more details.
|
||||
// ***************************************************************************************
|
||||
/**
|
||||
* @file power_kernel.cuh
|
||||
* @author simin tao (taosm@pcl.ac.cn)
|
||||
* @brief The power gpu kernel for speed up power tool.
|
||||
* @version 0.1
|
||||
* @date 2024-10-09
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cuda_runtime.h>
|
||||
#include "kernel_common.h"
|
||||
|
||||
namespace ipower {
|
||||
|
||||
/**
|
||||
* @brief for gpu kernel function used to store connection point.
|
||||
*
|
||||
*/
|
||||
struct GPUConnectionPoint {
|
||||
int _src_id = -1;
|
||||
int _snk_id = -1;
|
||||
unsigned _last_depth; // The last hop combine depth.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief build macro connection map with gpu kernel function.
|
||||
*
|
||||
* @param connection_points
|
||||
* @param is_macros
|
||||
* @param seq_arcs
|
||||
* @param snk_depths
|
||||
* @param snk_arcs
|
||||
* @param connection_point_num
|
||||
* @param num_seq_vertexes
|
||||
* @param num_seq_arcs
|
||||
* @param out_connection_points
|
||||
*/
|
||||
void build_macro_connection_map(GPUConnectionPoint* connection_points,
|
||||
unsigned* is_macros, unsigned* seq_arcs,
|
||||
unsigned* snk_depths, unsigned* snk_arcs,
|
||||
int connection_point_num, int num_seq_vertexes,
|
||||
int num_seq_arcs,
|
||||
GPUConnectionPoint* out_connection_points, bool is_free_memory);
|
||||
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
namespace ipower {
|
||||
|
||||
// static std::shared_mutex rw_mutex; //! For synchronization read write seq data.
|
||||
/**
|
||||
* @brief add power vertex of the graph.
|
||||
*
|
||||
|
|
@ -48,9 +49,27 @@ void PwrSeqGraph::addPwrSeqVertex(PwrSeqVertex* vertex) {
|
|||
void PwrSeqGraph::addPwrSeqArc(PwrSeqArc* arc) {
|
||||
static std::mutex mt;
|
||||
std::lock_guard lk(mt);
|
||||
// std::unique_lock<std::shared_mutex> lock(rw_mutex);
|
||||
_arcs.emplace_back(arc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief find seq arc.
|
||||
*
|
||||
* @param src_vertex
|
||||
* @param snk_vertex
|
||||
* @return PwrSeqArc*
|
||||
*/
|
||||
PwrSeqArc* PwrSeqGraph::findSeqArc(PwrSeqVertex* src_vertex,
|
||||
PwrSeqVertex* snk_vertex) {
|
||||
// std::shared_lock<std::shared_mutex> lock(rw_mutex);
|
||||
auto it = std::find_if(
|
||||
_arcs.begin(), _arcs.end(), [src_vertex, snk_vertex](auto& arc) {
|
||||
return arc->get_src() == src_vertex && arc->get_snk() == snk_vertex;
|
||||
});
|
||||
return it != _arcs.end() ? it->get() : nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief insert seq instance to and seq vertex mapping.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <mutex>
|
||||
#include <ranges>
|
||||
#include <vector>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "BTreeSet.hh"
|
||||
#include "PwrVertex.hh"
|
||||
|
|
@ -87,7 +88,7 @@ class PwrSeqVertex {
|
|||
|
||||
using PwrSeqArcSet = std::set<PwrSeqArc*, PwrSeqArcComp>;
|
||||
|
||||
auto get_obj_name() const { return _obj_name; }
|
||||
auto& get_obj_name() const { return _obj_name; }
|
||||
|
||||
[[nodiscard]] unsigned isInputPort() const { return _is_input_port; }
|
||||
void set_is_input_port() { _is_input_port = 1; }
|
||||
|
|
@ -254,6 +255,8 @@ class PwrSeqGraph {
|
|||
void addPwrSeqArc(PwrSeqArc* arc);
|
||||
auto& get_arcs() { return _arcs; }
|
||||
|
||||
PwrSeqArc* findSeqArc(PwrSeqVertex* src_vertex, PwrSeqVertex* snk_vertex);
|
||||
|
||||
void addInputPortVerex(PwrSeqVertex* vertex) {
|
||||
_input_port_vertexes.emplace_back(vertex);
|
||||
}
|
||||
|
|
@ -326,6 +329,7 @@ class PwrSeqGraph {
|
|||
_obj_to_vertex; //!< The seq belong inst to graph vertex.
|
||||
std::map<PwrVertex*, PwrSeqVertex*>
|
||||
_port_to_vertex; //!< The seq belong power port to graph vertex.
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -354,7 +358,7 @@ class PwrSeqGraph {
|
|||
*
|
||||
*/
|
||||
#define FOREACH_SEQ_ARC(graph, arc) \
|
||||
if (auto& arcs = graph->get_arcs(); !arcs.empty()) \
|
||||
if (auto& arcs = (graph)->get_arcs(); !arcs.empty()) \
|
||||
for (auto p = arcs.begin(); \
|
||||
p != arcs.end() ? arc = p->get(), true : false; ++p)
|
||||
} // namespace ipower
|
||||
|
|
|
|||
|
|
@ -55,8 +55,17 @@ std::optional<double> PwrVertex::getDriveVoltage() {
|
|||
// for port.
|
||||
auto* the_net = design_obj->get_net();
|
||||
auto the_loads = the_net->getLoads();
|
||||
auto* one_load = the_loads.front();
|
||||
design_obj = one_load;
|
||||
for (auto* one_load : the_loads) {
|
||||
if (one_load->isPin()) {
|
||||
design_obj = one_load;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (design_obj->isPort()) {
|
||||
// TODO(to taosimin), fix io volatage.
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
auto* liberty_port = dynamic_cast<Pin*>(design_obj)->get_cell_port();
|
||||
|
|
|
|||
|
|
@ -107,6 +107,10 @@ unsigned PwrBuildGraph::operator()(StaGraph* sta_graph) {
|
|||
auto* pwr_src_vertex = _power_graph.staToPwrVertex(sta_src_vertex);
|
||||
auto* pwr_snk_vertex = _power_graph.staToPwrVertex(sta_snk_vertex);
|
||||
|
||||
if (sta_arc->is_loop_disable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<PwrArc> power_arc;
|
||||
// power arc only exist for delay arc.
|
||||
if (sta_arc->isInstArc()) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
|
||||
#include "PwrCalcInternalPower.hh"
|
||||
|
||||
#include "PwrCalcSPData.hh"
|
||||
namespace ipower {
|
||||
using ieda::Stats;
|
||||
|
|
@ -94,8 +93,12 @@ double PwrCalcInternalPower::calcCombInputPinPower(Instance* inst,
|
|||
// rise power
|
||||
auto rise_slew = (*the_input_sta_vertex)
|
||||
->getSlewNs(AnalysisMode::kMax, TransType::kRise);
|
||||
LOG_FATAL_IF(!rise_slew)
|
||||
<< (*the_input_sta_vertex)->getName() << " rise slew is not exist.";
|
||||
if (!rise_slew) {
|
||||
LOG_ERROR_IF(!rise_slew)
|
||||
<< (*the_input_sta_vertex)->getName() << " rise slew is not exist.";
|
||||
continue;
|
||||
}
|
||||
|
||||
double rise_power =
|
||||
internal_power->gatePower(TransType::kRise, *rise_slew, std ::nullopt);
|
||||
double rise_power_mw = lib_cell->convertTablePowerToMw(rise_power);
|
||||
|
|
@ -217,6 +220,11 @@ double PwrCalcInternalPower::calcOutputPinPower(Instance* inst,
|
|||
|
||||
auto* power_arc_set =
|
||||
dynamic_cast<PwrInstArc*>(snk_arc)->get_power_arc_set();
|
||||
|
||||
if (!power_arc_set) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LibPowerArc* power_arc;
|
||||
FOREACH_POWER_LIB_ARC(power_arc_set, power_arc) {
|
||||
auto [rise_power_mw, rise_input_slew_ns, rise_output_load] =
|
||||
|
|
@ -376,11 +384,16 @@ double PwrCalcInternalPower::calcSeqInputPinPower(Instance* inst,
|
|||
// rise power
|
||||
auto rise_slew = (*the_input_sta_vertex)
|
||||
->getSlewNs(AnalysisMode::kMax, TransType::kRise);
|
||||
LOG_FATAL_IF(!rise_slew)
|
||||
|
||||
double rise_power_mw = 0.0;
|
||||
LOG_ERROR_IF(!rise_slew)
|
||||
<< (*the_input_sta_vertex)->getName() << " rise slew is not exist.";
|
||||
double rise_power =
|
||||
internal_power->gatePower(TransType::kRise, *rise_slew, std ::nullopt);
|
||||
double rise_power_mw = lib_cell->convertTablePowerToMw(rise_power);
|
||||
if (rise_slew) {
|
||||
double rise_power = internal_power->gatePower(TransType::kRise,
|
||||
*rise_slew, std ::nullopt);
|
||||
rise_power_mw = lib_cell->convertTablePowerToMw(rise_power);
|
||||
}
|
||||
|
||||
// fall power
|
||||
auto fall_slew = (*the_input_sta_vertex)
|
||||
->getSlewNs(AnalysisMode::kMax, TransType::kFall);
|
||||
|
|
@ -566,8 +579,8 @@ unsigned PwrCalcInternalPower::operator()(PwrGraph* the_graph) {
|
|||
|
||||
double nom_voltage = inst_cell->get_owner_lib()->get_nom_voltage();
|
||||
// add power analysis data.
|
||||
auto internal_data =
|
||||
std::make_unique<PwrInternalData>(design_inst, MW_TO_W(inst_internal_power));
|
||||
auto internal_data = std::make_unique<PwrInternalData>(
|
||||
design_inst, MW_TO_W(inst_internal_power));
|
||||
internal_data->set_nom_voltage(nom_voltage);
|
||||
|
||||
addInternalPower(std::move(internal_data));
|
||||
|
|
|
|||
|
|
@ -96,10 +96,17 @@ unsigned PwrCalcSwitchPower::operator()(PwrGraph* the_graph) {
|
|||
/*Calc switch power for power net arc.*/
|
||||
FOREACH_NET(nl, net) {
|
||||
if (net->getLoads().empty()) {
|
||||
LOG_INFO << "net " << net->get_name()
|
||||
<< " has no load, skip switch power calculation.";
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* driver_obj = net->getDriver();
|
||||
if (!driver_obj) {
|
||||
LOG_INFO << "net " << net->get_name()
|
||||
<< " has no driver, skip switch power calculation.";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driver_obj->isPort() &&
|
||||
((net->getLoads().size() == 1) && net->getLoads().front()->isPort())) {
|
||||
|
|
@ -134,7 +141,8 @@ unsigned PwrCalcSwitchPower::operator()(PwrGraph* the_graph) {
|
|||
// calc swich power of the arc.
|
||||
// swich_power = k*toggle*Cap*(VDD^2)
|
||||
double arc_swich_power = c_switch_power_K * toggle * cap * vdd * vdd;
|
||||
auto switch_data = std::make_unique<PwrSwitchData>(net, MW_TO_W(arc_swich_power));
|
||||
auto switch_data =
|
||||
std::make_unique<PwrSwitchData>(net, MW_TO_W(arc_swich_power));
|
||||
switch_data->set_nom_voltage(vdd);
|
||||
// add power analysis data.
|
||||
addSwitchPower(std::move(switch_data));
|
||||
|
|
|
|||
|
|
@ -323,6 +323,12 @@ unsigned PwrCalcToggleSP::calcToggleSP(
|
|||
auto* output_pin = output_vertex->get_sta_vertex()->get_design_obj();
|
||||
auto* liberty_port =
|
||||
lib_cell->get_cell_port_or_port_bus(output_pin->get_name());
|
||||
if (!liberty_port) {
|
||||
LOG_ERROR << "lib cell " << lib_cell->get_cell_name()
|
||||
<< " has no port " << output_pin->get_name();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* port_func = liberty_port->get_func_expr();
|
||||
|
||||
// FiXME, output pad not have function.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
|||
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||
|
||||
aux_source_directory(./ SRC)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue