update rr_block writer to include IPINs in XML files
This commit is contained in:
parent
785b560bd5
commit
a88263a4c2
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue