update rr_block writer to include IPINs in XML files

This commit is contained in:
tangxifan 2019-06-25 11:17:22 -06:00
parent 785b560bd5
commit a88263a4c2
5 changed files with 110 additions and 47 deletions

View File

@ -1279,25 +1279,12 @@ void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
break; /* least type should stay in the front of the vector */
} else if (ipin_node->drive_rr_nodes[i_from_node]->type
== sorted_drive_nodes[j_from_node]->type) {
/* For channel node, we do not know the node direction
* But we are pretty sure it is either IN_PORT or OUT_PORT
* So we just try and find what is valid
*/
enum PORTS i_from_node_direction = IN_PORT;
if (-1 == rr_gsb.get_node_index(ipin_node->drive_rr_nodes[i_from_node],
ipin_chan_side,
IN_PORT)) {
i_from_node_direction = OUT_PORT;
}
enum PORTS j_from_node_direction = IN_PORT;
if (-1 != rr_gsb.get_node_index(sorted_drive_nodes[j_from_node],
ipin_chan_side,
IN_PORT)) {
j_from_node_direction = OUT_PORT;
}
int i_from_node_track_index = rr_gsb.get_chan_node_index(ipin_chan_side, ipin_node->drive_rr_nodes[i_from_node]);
int j_from_node_track_index = rr_gsb.get_chan_node_index(ipin_chan_side, sorted_drive_nodes[j_from_node]);
/* We must have a valide node index */
assert ( (-1 != i_from_node_track_index) && (-1 != j_from_node_track_index) );
/* Now a lower ptc_num will win */
if ( rr_gsb.get_node_index(ipin_node->drive_rr_nodes[i_from_node], ipin_chan_side, i_from_node_direction)
< rr_gsb.get_node_index(sorted_drive_nodes[j_from_node], ipin_chan_side, j_from_node_direction) ) {
if ( i_from_node_track_index < j_from_node_track_index ) {
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
}

View File

@ -1258,6 +1258,17 @@ bool RRGSB::is_sb_mirror(const RRGSB& cand) const {
/* Public Accessors: Cooridinator conversion */
/* get the x coordinator of this GSB */
size_t RRGSB::get_x() const {
return coordinator_.get_x();
}
/* get the y coordinator of this GSB */
size_t RRGSB::get_y() const {
return coordinator_.get_y();
}
/* get the x coordinator of this switch block */
size_t RRGSB::get_sb_x() const {
return coordinator_.get_x();
@ -1431,6 +1442,21 @@ const char* RRGSB::gen_sb_verilog_module_name() const {
return ret;
}
const char* RRGSB::gen_gsb_verilog_module_name() const {
std::string x_str = std::to_string(get_sb_x());
std::string y_str = std::to_string(get_sb_y());
char* ret = (char*)my_malloc(sizeof(char)*
( 2 + 1
+ x_str.length() + 2
+ y_str.length() + 1
+ 1));
sprintf (ret, "gsb_%s__%s_",
x_str.c_str(), y_str.c_str());
return ret;
}
const char* RRGSB::gen_sb_verilog_instance_name() const {
char* ret = (char*)my_malloc(sizeof(char)*
( strlen(gen_sb_verilog_module_name()) + 3
@ -1441,6 +1467,16 @@ const char* RRGSB::gen_sb_verilog_instance_name() const {
return ret;
}
const char* RRGSB::gen_gsb_verilog_instance_name() const {
char* ret = (char*)my_malloc(sizeof(char)*
( strlen(gen_gsb_verilog_module_name()) + 3
+ 1));
sprintf (ret, "%s_0_",
gen_gsb_verilog_module_name());
return ret;
}
/* Public Accessors Verilog writer */
const char* RRGSB::gen_sb_verilog_side_module_name(enum e_side side, size_t seg_id) const {
Side side_manager(side);

View File

@ -228,6 +228,8 @@ class RRGSB {
bool is_cb_exist(t_rr_type cb_type) const; /* check if the candidate SB is a mirror of the current one */
size_t get_hint_rotate_offset(const RRGSB& cand) const; /* Determine an initial offset in rotating the candidate Switch Block to find a mirror matching*/
public: /* Cooridinator conversion and output */
size_t get_x() const; /* get the x coordinator of this switch block */
size_t get_y() const; /* get the y coordinator of this switch block */
size_t get_sb_x() const; /* get the x coordinator of this switch block */
size_t get_sb_y() const; /* get the y coordinator of this switch block */
DeviceCoordinator get_sb_coordinator() const; /* Get the coordinator of the SB */
@ -239,6 +241,8 @@ class RRGSB {
DeviceCoordinator get_side_block_coordinator(enum e_side side) const;
DeviceCoordinator get_grid_coordinator() const;
public: /* Verilog writer */
const char* gen_gsb_verilog_module_name() const;
const char* gen_gsb_verilog_instance_name() const;
const char* gen_sb_verilog_module_name() const;
const char* gen_sb_verilog_instance_name() const;
const char* gen_sb_verilog_side_module_name(enum e_side side, size_t seg_id) const;

View File

@ -11,10 +11,10 @@
#include "write_rr_blocks.h"
void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb) {
void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_gsb) {
/* Prepare file name */
std::string fname(fname_prefix);
fname += rr_sb.gen_sb_verilog_module_name();
fname += rr_gsb.gen_gsb_verilog_module_name();
fname += ".xml";
vpr_printf(TIO_MESSAGE_INFO, "Output SB XML: %s\r", fname.c_str());
@ -25,30 +25,69 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb) {
fp.open(fname, std::fstream::out | std::fstream::trunc);
/* Output location of the Switch Block */
fp << "<rr_sb x=\"" << rr_sb.get_sb_x() << "\" y=\"" << rr_sb.get_sb_y() << "\""
<< " num_sides=\"" << rr_sb.get_num_sides() << "\">" << std::endl;
fp << "<rr_gsb x=\"" << rr_gsb.get_x() << "\" y=\"" << rr_gsb.get_y() << "\""
<< " num_sides=\"" << rr_gsb.get_num_sides() << "\">" << std::endl;
/* Output each side */
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
Side side_manager(side);
for (size_t side = 0; side < rr_gsb.get_num_sides(); ++side) {
Side gsb_side_manager(side);
enum e_side gsb_side = gsb_side;
/* Output IPIN nodes */
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(gsb_side); ++inode) {
t_rr_node* cur_rr_node = rr_gsb.get_ipin_node(gsb_side, inode);
/* General information of this IPIN */
fp << "\t<" << rr_node_typename[cur_rr_node->type]
<< " side=\"" << gsb_side_manager.to_string()
<< "\" index=\"" << inode
<< "\" mux_size=\"" << cur_rr_node->num_drive_rr_nodes
<< "\">"
<< std::endl;
/* General information of each driving nodes */
for (int jnode = 0; jnode < cur_rr_node->num_drive_rr_nodes; ++jnode) {
enum e_side chan_side = rr_gsb.get_cb_chan_side(gsb_side);
Side chan_side_manager(chan_side);
/* For channel node, we do not know the node direction
* But we are pretty sure it is either IN_PORT or OUT_PORT
* So we just try and find what is valid
*/
int drive_node_index = rr_gsb.get_chan_node_index(chan_side, cur_rr_node->drive_rr_nodes[jnode]);
/* We must have a valide node index */
assert (-1 != drive_node_index);
size_t des_segment_id = rr_gsb.get_chan_node_segment(chan_side, drive_node_index);
fp << "\t\t<driver_node type=\"" << rr_node_typename[cur_rr_node->drive_rr_nodes[jnode]->type]
<< "\" side=\"" << chan_side_manager.to_string()
<< "\" index=\"" << drive_node_index
<< "\" segment_id=\"" << des_segment_id
<< "\"/>"
<< std::endl;
}
fp << "\t</" << rr_node_typename[cur_rr_node->type]
<< ">"
<< std::endl;
}
/* Output chan nodes */
for (size_t inode = 0; inode < rr_sb.get_chan_width(side_manager.get_side()); ++inode) {
for (size_t inode = 0; inode < rr_gsb.get_chan_width(gsb_side); ++inode) {
/* We only care OUT_PORT */
if (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), inode)) {
if (OUT_PORT != rr_gsb.get_chan_node_direction(gsb_side, inode)) {
continue;
}
/* Output drivers */
size_t num_drive_rr_nodes = 0;
t_rr_node** drive_rr_nodes = 0;
t_rr_node* cur_rr_node = rr_sb.get_chan_node(side_manager.get_side(), inode);
t_rr_node* cur_rr_node = rr_gsb.get_chan_node(gsb_side, inode);
/* Output node information: location, index, side */
size_t src_segment_id = rr_sb.get_chan_node_segment(side_manager.get_side(), inode);
size_t src_segment_id = rr_gsb.get_chan_node_segment(gsb_side, inode);
/* Check if this node is directly connected to the node on the opposite side */
if (true == rr_sb.is_sb_node_imply_short_connection(cur_rr_node)) {
if (true == rr_gsb.is_sb_node_imply_short_connection(cur_rr_node)) {
/* Double check if the interc lies inside a channel wire, that is interc between segments */
assert(true == rr_sb.is_sb_node_exist_opposite_side(cur_rr_node, side_manager.get_side()));
assert(true == rr_gsb.is_sb_node_exist_opposite_side(cur_rr_node, gsb_side));
num_drive_rr_nodes = 0;
drive_rr_nodes = NULL;
} else {
@ -56,8 +95,8 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb) {
drive_rr_nodes = cur_rr_node->drive_rr_nodes;
}
fp << "\t<" << convert_chan_type_to_string(cur_rr_node->type)
<< " side=\"" << side_manager.to_string()
fp << "\t<" << rr_node_typename[cur_rr_node->type]
<< " side=\"" << gsb_side_manager.to_string()
<< "\" index=\"" << inode
<< "\" segment_id=\"" << src_segment_id
<< "\" mux_size=\"" << num_drive_rr_nodes
@ -66,10 +105,10 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb) {
/* Direct connection: output the node on the opposite side */
if (0 == num_drive_rr_nodes) {
Side oppo_side = side_manager.get_opposite();
fp << "\t\t<driver_node type=\"" << convert_chan_type_to_string(cur_rr_node->type)
Side oppo_side = gsb_side_manager.get_opposite();
fp << "\t\t<driver_node type=\"" << rr_node_typename[cur_rr_node->type]
<< "\" side=\"" << oppo_side.to_string()
<< "\" index=\"" << rr_sb.get_node_index(cur_rr_node, oppo_side.get_side(), IN_PORT)
<< "\" index=\"" << rr_gsb.get_node_index(cur_rr_node, oppo_side.get_side(), IN_PORT)
<< "\" segment_id=\"" << src_segment_id
<< "\"/>"
<< std::endl;
@ -77,22 +116,19 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb) {
for (size_t jnode = 0; jnode < num_drive_rr_nodes; ++jnode) {
enum e_side drive_node_side = NUM_SIDES;
int drive_node_index = -1;
rr_sb.get_node_side_and_index(drive_rr_nodes[jnode], IN_PORT, &drive_node_side, &drive_node_index);
rr_gsb.get_node_side_and_index(drive_rr_nodes[jnode], IN_PORT, &drive_node_side, &drive_node_index);
Side drive_side(drive_node_side);
std::string node_type_str;
if (OPIN == drive_rr_nodes[jnode]->type) {
node_type_str = "opin";
Side grid_side(rr_sb.get_opin_node_grid_side(drive_node_side, drive_node_index));
fp << "\t\t<driver_node type=\"" << node_type_str
Side grid_side(rr_gsb.get_opin_node_grid_side(drive_node_side, drive_node_index));
fp << "\t\t<driver_node type=\"" << rr_node_typename[OPIN]
<< "\" side=\"" << drive_side.to_string()
<< "\" index=\"" << drive_node_index
<< "\" grid_side=\"" << grid_side.to_string()
<<"\"/>"
<< std::endl;
} else {
node_type_str = convert_chan_type_to_string(drive_rr_nodes[jnode]->type);
size_t des_segment_id = rr_sb.get_chan_node_segment(drive_node_side, drive_node_index);
fp << "\t\t<driver_node type=\"" << node_type_str
size_t des_segment_id = rr_gsb.get_chan_node_segment(drive_node_side, drive_node_index);
fp << "\t\t<driver_node type=\"" << rr_node_typename[drive_rr_nodes[jnode]->type]
<< "\" side=\"" << drive_side.to_string()
<< "\" index=\"" << drive_node_index
<< "\" segment_id=\"" << des_segment_id
@ -107,7 +143,7 @@ void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb) {
}
}
fp << "</rr_sb>"
fp << "</rr_gsb>"
<< std::endl;
/* close a file */
@ -130,8 +166,8 @@ void write_device_rr_gsb_to_xml(char* sb_xml_dir,
/* For each switch block, an XML file will be outputted */
for (size_t ix = 0; ix < sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy < sb_range.get_y(); ++iy) {
RRGSB rr_sb = LL_device_rr_gsb.get_gsb(ix, iy);
write_rr_switch_block_to_xml(fname_prefix, rr_sb);
RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
write_rr_switch_block_to_xml(fname_prefix, rr_gsb);
}
}

View File

@ -1,7 +1,7 @@
#ifndef WRITE_RR_BLOCKS_H
#define WRITE_RR_BLOCKS_H
void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_sb);
void write_rr_switch_block_to_xml(std::string fname_prefix, RRGSB& rr_gsb);
void write_device_rr_gsb_to_xml(char* sb_xml_dir, DeviceRRGSB& LL_device_rr_gsb);