updated SDC generator to embrace the RRGSB data structure

This commit is contained in:
tangxifan 2019-06-10 14:47:27 -06:00
parent 8a8f4153ce
commit e4f70771a2
3 changed files with 83 additions and 10 deletions

View File

@ -1767,6 +1767,7 @@ void verilog_generate_one_routing_wire_report_timing(FILE* fp,
assert( ( CHANX == wire_rr_node->type )
|| ( CHANY == wire_rr_node->type ));
int track_idx = wire_rr_node->ptc_num;
t_rr_type cb_type = wire_rr_node->type;
/* We only care a specific length of wires */
if (L_wire != (abs(wire_rr_node->xlow - wire_rr_node->xhigh + wire_rr_node->ylow - wire_rr_node->yhigh) + 1)) {
@ -1781,19 +1782,18 @@ void verilog_generate_one_routing_wire_report_timing(FILE* fp,
int x_end, y_end;
/* Find where the destination pin belongs to */
get_chan_rr_node_end_coordinate(wire_rr_node, &x_end, &y_end);
DeviceCoordinator next_sb_coordinator;
/* Reciever could be IPIN or CHANX or CHANY */
int inode = wire_rr_node->edges[jedge];
RRGSB next_sb;
t_cb* next_cb = NULL;
/* Find the SB/CB block that it belongs to */
switch (LL_rr_node[inode].type) {
case IPIN:
{
DeviceCoordinator next_cb_coordinator = get_chan_node_ending_cb(wire_rr_node, &(LL_rr_node[inode]));
/* Get the coordinate of ending CB */
next_cb = get_chan_rr_node_ending_cb(wire_rr_node, &(LL_rr_node[inode]));
const RRGSB& next_cb = device_rr_gsb.get_gsb(next_cb_coordinator);
/* This will not be the longest path unless the cb is close to the ending SB */
if ((TRUE == sdc_opts.longest_path_only)
&& ((next_cb->x != x_end) || (next_cb->y != y_end))) {
&& ( ((int)next_cb.get_cb_x(cb_type) != x_end) || ((int)next_cb.get_cb_y(cb_type) != y_end))) {
continue;
}
/* Driver could be OPIN or CHANX or CHANY,
@ -1812,11 +1812,10 @@ void verilog_generate_one_routing_wire_report_timing(FILE* fp,
fprintf(fp, " -to ");
/* output instance name */
fprintf(fp, "%s/",
gen_verilog_one_cb_instance_name(next_cb));
next_cb.gen_cb_verilog_instance_name(cb_type));
/* output pin name */
fprintf(fp, "%s",
gen_verilog_routing_channel_one_midout_name( next_cb,
track_idx));
next_cb.gen_cb_verilog_routing_track_name(cb_type, track_idx));
/* Print through pins */
if (TRUE == sdc_opts.print_thru_pins) {
fprintf(fp, " -through_pins ");
@ -1826,12 +1825,15 @@ void verilog_generate_one_routing_wire_report_timing(FILE* fp,
}
fprintf(fp, " -unconstrained\n");
path_cnt++;
}
break;
case CHANX:
case CHANY:
{
DeviceCoordinator next_sb_coordinator;
/* Get the coordinate of ending SB */
next_sb_coordinator = get_chan_node_ending_sb_coordinator(wire_rr_node, &(LL_rr_node[inode]));
next_sb = device_rr_gsb.get_gsb(next_sb_coordinator);
const RRGSB& next_sb = device_rr_gsb.get_gsb(next_sb_coordinator);
/* This will not be the longest path unless the cb is close to the ending SB */
if ((TRUE == sdc_opts.longest_path_only)
&& ((next_sb.get_sb_x() != (size_t)x_end) || (next_sb.get_sb_y() != (size_t)y_end))) {
@ -1873,6 +1875,7 @@ void verilog_generate_one_routing_wire_report_timing(FILE* fp,
path_cnt++;
/* Set the flag */
sb_dumped = TRUE;
}
break;
default:
vpr_printf(TIO_MESSAGE_ERROR, "(File: %s [LINE%d]) Invalid type of ending point rr_node!\n",
@ -2058,7 +2061,7 @@ void verilog_generate_routing_wires_report_timing(FILE* fp,
DeviceCoordinator sb_range = device_rr_gsb.get_gsb_range();
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 = device_rr_gsb.get_gsb(ix, iy);
const RRGSB& rr_sb = device_rr_gsb.get_gsb(ix, iy);
for (size_t side = 0; side < rr_sb.get_num_sides(); side++) {
Side side_manager(side);
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {

View File

@ -9,6 +9,7 @@
#include <assert.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
/* Include vpr structs*/
#include "util.h"
@ -217,6 +218,72 @@ void dump_verilog_one_sb_routing_pin(FILE* fp,
return;
}
/** Given a starting rr_node (CHANX or CHANY)
* and a ending rr_node (IPIN)
* return the cb contains both (the ending CB of the routing wire)
*/
DeviceCoordinator get_chan_node_ending_cb(t_rr_node* src_rr_node,
t_rr_node* end_rr_node) {
int next_cb_x, next_cb_y;
std::vector<enum e_side> ipin_side;
enum e_side chan_side;
t_rr_type cb_type;
/* Type of connection block depends on the src_rr_node */
switch (src_rr_node->type) {
case CHANX:
/* the x of CB is same as end_rr_node,
* the y of CB should be same as src_rr_node
*/
assert (end_rr_node->xlow == end_rr_node->xhigh);
next_cb_x = end_rr_node->xlow;
assert (src_rr_node->ylow == src_rr_node->yhigh);
next_cb_y = src_rr_node->ylow;
cb_type = CHANX;
break;
case CHANY:
/* the x of CB is same as src_rr_node,
* the y of CB should be same as end_rr_node
*/
assert (src_rr_node->xlow == src_rr_node->xhigh);
next_cb_x = src_rr_node->xlow;
assert (end_rr_node->ylow == end_rr_node->yhigh);
next_cb_y = end_rr_node->ylow;
cb_type = CHANY;
break;
default:
vpr_printf(TIO_MESSAGE_ERROR,
"(File: %s [LINE%d]) Invalid type of src_rr_node!\n",
__FILE__, __LINE__);
exit(1);
}
DeviceCoordinator next_cb_coordinator(next_cb_x, next_cb_y);
/* IMPORTANT: the use of global variables should be removed!!! */
const RRGSB& next_cb = device_rr_gsb.get_gsb(next_cb_coordinator);
/* Side will be either on TOP or BOTTOM */
ipin_side = next_cb.get_cb_ipin_sides(cb_type);
chan_side = next_cb.get_cb_chan_side(cb_type);
/* Double check if src_rr_node is in the IN_PORT list */
assert ( (OPEN != next_cb.get_node_index( src_rr_node, chan_side, IN_PORT))
|| (OPEN != next_cb.get_node_index( src_rr_node, chan_side, OUT_PORT)) );
/* Double check if end_rr_node is in the OUT_PORT list */
bool node_exist = false;
for (size_t iside = 0; iside < ipin_side.size(); ++iside) {
if (OPEN != next_cb.get_node_index(end_rr_node, ipin_side[iside], OUT_PORT)) {
node_exist = true;
break;
}
}
assert (true == node_exist);
return next_cb_coordinator;
}
/** Given a starting rr_node (CHANX or CHANY)
* and a ending rr_node (IPIN)
* return the cb contains both (the ending CB of the routing wire)

View File

@ -26,6 +26,9 @@ void dump_verilog_one_sb_routing_pin(FILE* fp,
t_sb* cur_sb_info,
t_rr_node* cur_rr_node);
DeviceCoordinator get_chan_node_ending_cb(t_rr_node* src_rr_node,
t_rr_node* end_rr_node);
t_cb* get_chan_rr_node_ending_cb(t_rr_node* src_rr_node,
t_rr_node* end_rr_node);