Merge branch 'dev' into refactoring

This commit is contained in:
tangxifan 2019-09-27 18:09:58 -06:00
commit f0949fea2f
6 changed files with 250 additions and 14 deletions

View File

@ -924,6 +924,10 @@ typedef struct s_direct_inf {
int y_offset; int y_offset;
int z_offset; int z_offset;
int line; int line;
/* Aurelien: point to point support in direct connection from directlist */
enum e_point2point_interconnection_type interconnection_type;
enum e_point2point_interconnection_dir x_dir;
enum e_point2point_interconnection_dir y_dir;
/* Xifan Tang: FPGA-SPICE support */ /* Xifan Tang: FPGA-SPICE support */
char* spice_model_name; char* spice_model_name;
t_spice_model* spice_model; t_spice_model* spice_model;

View File

@ -3578,6 +3578,9 @@ static void ProcessDirects(INOUTP ezxml_t Parent, OUTP t_direct_inf **Directs,
const char *direct_name; const char *direct_name;
const char *from_pin_name; const char *from_pin_name;
const char *to_pin_name; const char *to_pin_name;
const char *point2point_type;
const char *x_dir;
const char *y_dir;
ezxml_t Node; ezxml_t Node;
@ -3632,6 +3635,77 @@ static void ProcessDirects(INOUTP ezxml_t Parent, OUTP t_direct_inf **Directs,
ezxml_set_attr(Node, "y_offset", NULL); ezxml_set_attr(Node, "y_offset", NULL);
ezxml_set_attr(Node, "z_offset", NULL); ezxml_set_attr(Node, "z_offset", NULL);
// Aurelien: Read point to point connection parameters
if((!FindProperty(Node, "interconnection_type", FALSE)) ||
(0 == strcmp(FindProperty(Node, "interconnection_type", FALSE), "NONE"))) {
(*Directs)[i].interconnection_type = NO_P2P;
} else if(0 == strcmp(FindProperty(Node, "interconnection_type", FALSE), "column")) {
(*Directs)[i].interconnection_type = P2P_DIRECT_COLUMN;
} else if(0 == strcmp(FindProperty(Node, "interconnection_type", FALSE), "row")) {
(*Directs)[i].interconnection_type = P2P_DIRECT_ROW;
} else {
(*Directs)[i].interconnection_type = NUM_POINT2POINT_INTERCONNECT_TYPE;
vpr_printf(TIO_MESSAGE_ERROR,
"Invalid point to point connection '%s' in directlist. '%s' value should be '%s', '%s' or '%s' !\n",
(*Directs)[i].name,
"interconnection_type",
"column",
"row",
"NONE" );
exit(1);
}
if((P2P_DIRECT_COLUMN == (*Directs)[i].interconnection_type) ||
(P2P_DIRECT_ROW == (*Directs)[i].interconnection_type)){
if(0 == strcmp(FindProperty(Node, "x_dir", TRUE), "positive")){
(*Directs)[i].x_dir = POSITIVE_DIR;
} else if(0 == strcmp(FindProperty(Node, "x_dir", TRUE), "negative")){
(*Directs)[i].x_dir = NEGATIVE_DIR;
} else {
(*Directs)[i].x_dir = NUM_POINT2POINT_INTERCONNECT_DIR;
vpr_printf(TIO_MESSAGE_ERROR,
"Invalid point to point connection '%s' in directlist. '%s' value should be '%s' or '%s' !\n",
(*Directs)[i].name,
"x_dir",
"positive",
"negative" );
}
if(0 == strcmp(FindProperty(Node, "y_dir", TRUE), "positive")){
(*Directs)[i].y_dir = POSITIVE_DIR;
} else if(0 == strcmp(FindProperty(Node, "y_dir", TRUE), "negative")){
(*Directs)[i].y_dir = NEGATIVE_DIR;
} else {
(*Directs)[i].y_dir = NUM_POINT2POINT_INTERCONNECT_DIR;
vpr_printf(TIO_MESSAGE_ERROR,
"Invalid point to point connection '%s' in directlist. '%s' value should be '%s' or '%s' !\n",
(*Directs)[i].name,
"y_dir",
"positive",
"negative" );
}
} else {
if(NULL == FindProperty(Node, "x_dir", FALSE)){
(*Directs)[i].x_dir = NUM_POINT2POINT_INTERCONNECT_DIR;
} else if(0 == strcmp(FindProperty(Node, "x_dir", FALSE), "positive")){
(*Directs)[i].x_dir = POSITIVE_DIR;
} else if(0 == strcmp(FindProperty(Node, "x_dir", FALSE), "negative")){
(*Directs)[i].x_dir = NEGATIVE_DIR;
} else {
(*Directs)[i].x_dir = NUM_POINT2POINT_INTERCONNECT_DIR;
}
if(NULL == FindProperty(Node, "y_dir", FALSE)){
(*Directs)[i].y_dir = NUM_POINT2POINT_INTERCONNECT_DIR;
} else if(0 == strcmp(FindProperty(Node, "y_dir", FALSE), "positive")){
(*Directs)[i].y_dir = POSITIVE_DIR;
} else if(0 == strcmp(FindProperty(Node, "y_dir", FALSE), "negative")){
(*Directs)[i].y_dir = NEGATIVE_DIR;
} else {
(*Directs)[i].y_dir = NUM_POINT2POINT_INTERCONNECT_DIR;
}
}
ezxml_set_attr(Node, "x_dir", NULL);
ezxml_set_attr(Node, "y_dir", NULL);
ezxml_set_attr(Node, "interconnection_type", NULL);
/* Check that the direct chain connection is not zero in both direction */ /* Check that the direct chain connection is not zero in both direction */
if ((*Directs)[i].x_offset == 0 && (*Directs)[i].y_offset == 0) { if ((*Directs)[i].x_offset == 0 && (*Directs)[i].y_offset == 0) {
vpr_printf(TIO_MESSAGE_ERROR, vpr_printf(TIO_MESSAGE_ERROR,

View File

@ -5,6 +5,20 @@
#include "linkedlist.h" #include "linkedlist.h"
#include "circuit_library.h" #include "circuit_library.h"
/* Aurelien: point to point connection */
enum e_point2point_interconnection_type {
NO_P2P,
P2P_DIRECT_COLUMN,
P2P_DIRECT_ROW,
NUM_POINT2POINT_INTERCONNECT_TYPE
};
enum e_point2point_interconnection_dir {
POSITIVE_DIR,
NEGATIVE_DIR,
NUM_POINT2POINT_INTERCONNECT_DIR
};
/* Xifan TANG: Spice support*/ /* Xifan TANG: Spice support*/
enum e_spice_tech_lib_type { enum e_spice_tech_lib_type {
SPICE_LIB_INDUSTRY, SPICE_LIB_INDUSTRY,

View File

@ -1123,6 +1123,10 @@ typedef struct s_clb_to_clb_directs {
t_type_descriptor *to_clb_type; t_type_descriptor *to_clb_type;
int to_clb_pin_start_index; int to_clb_pin_start_index;
int to_clb_pin_end_index; int to_clb_pin_end_index;
/* Aurelien: point to point support in direct connection from directlist */
enum e_point2point_interconnection_type interconnection_type;
enum e_point2point_interconnection_dir x_dir;
enum e_point2point_interconnection_dir y_dir;
/* Xifan Tang: add useful addition info to this struct */ /* Xifan Tang: add useful addition info to this struct */
int x_offset; int x_offset;
int y_offset; int y_offset;

View File

@ -39,6 +39,7 @@
#include "verilog_decoder.h" #include "verilog_decoder.h"
#include "verilog_top_netlist_utils.h" #include "verilog_top_netlist_utils.h"
/* Local Subroutines declaration */ /* Local Subroutines declaration */
/******** Subroutines ***********/ /******** Subroutines ***********/
@ -990,12 +991,12 @@ void dump_verilog_clb2clb_directs(FILE* fp,
*/ */
for (idirect = 0; idirect < num_directs; idirect++) { for (idirect = 0; idirect < num_directs; idirect++) {
/* Bypass unmatch types */ /* Bypass unmatch types */
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
continue;
}
/* Apply x/y_offset */ /* Apply x/y_offset */
to_clb_x = ix + direct[idirect].x_offset; to_clb_x = ix + direct[idirect].x_offset;
to_clb_y = iy + direct[idirect].y_offset; to_clb_y = iy + direct[idirect].y_offset;
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
continue;
}
/* see if the destination CLB is in the bound */ /* see if the destination CLB is in the bound */
if ((FALSE == is_grid_coordinate_in_range(0, nx, to_clb_x)) if ((FALSE == is_grid_coordinate_in_range(0, nx, to_clb_x))
||(FALSE == is_grid_coordinate_in_range(0, ny, to_clb_y))) { ||(FALSE == is_grid_coordinate_in_range(0, ny, to_clb_y))) {
@ -1006,21 +1007,157 @@ void dump_verilog_clb2clb_directs(FILE* fp,
continue; continue;
} }
*/ */
/* Check if the to_clb_type matches */
if (grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) {
continue;
}
/* Bypass x/y_offset = 1 /* Bypass x/y_offset = 1
* since it may be addressed in Connection blocks * since it may be addressed in Connection blocks
if (1 == (x_offset + y_offset)) { if (1 == (x_offset + y_offset)) {
continue; continue;
} }
*/ */
/* Now we can print a direct connection with the spice models */
dump_verilog_one_clb2clb_direct(fp, /* Check if the to_clb_type matches */
ix, iy, if (grid[to_clb_x][to_clb_y].type == direct[idirect].to_clb_type) {
to_clb_x, to_clb_y, /* Now we can print a direct connection with the spice models */
&direct[idirect]); dump_verilog_one_clb2clb_direct(fp,
ix, iy,
to_clb_x, to_clb_y,
&direct[idirect]);
/* Check if we can make a point to point connection between direct connection */
}else if((P2P_DIRECT_COLUMN == direct[idirect].interconnection_type) ||
(P2P_DIRECT_ROW == direct[idirect].interconnection_type)){
/* Check in which case we are to adapt coordinates */
if((P2P_DIRECT_COLUMN == direct[idirect].interconnection_type) &&
(POSITIVE_DIR == direct[idirect].x_dir) &&
(POSITIVE_DIR == direct[idirect].y_dir)){ // Bottom to Top on Right
if (grid[ix][iy].type == direct[idirect].from_clb_type) {
to_clb_x = ix + 1;
to_clb_y = ny + 1;
do{ // Find next available type
to_clb_y --; // Scan types from Top to Bottom
if(0 > to_clb_y){ // If scan fails scan the column on the Right until match or no more column
to_clb_x ++;
to_clb_y = ny;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(nx > to_clb_x));
}
} else if((P2P_DIRECT_COLUMN == direct[idirect].interconnection_type) &&
(POSITIVE_DIR == direct[idirect].x_dir) &&
(NEGATIVE_DIR == direct[idirect].y_dir)){ // Top to Bottom on Right
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = ix + 1;
to_clb_y = -1;
do{ // Find next available type
to_clb_y ++; // Scan types from Bottom to Top
if(ny < to_clb_y){ // If scan fails scan the column on the Right until match or no more column
to_clb_x ++;
to_clb_y = 0;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(nx >= to_clb_x));
}
} else if((P2P_DIRECT_COLUMN == direct[idirect].interconnection_type) &&
(NEGATIVE_DIR == direct[idirect].x_dir) &&
(NEGATIVE_DIR == direct[idirect].y_dir)){ // Top to Bottom on Left
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = ix - 1;
to_clb_y = -1;
do{ // Find next available type
to_clb_y ++; // Scan types from Bottom to Top
if(ny < to_clb_y){ // If scan fails scan the column on the Left until match or no more column
to_clb_x --;
to_clb_y = 0;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(0 <= to_clb_x));
}
} else if((P2P_DIRECT_COLUMN == direct[idirect].interconnection_type) &&
(NEGATIVE_DIR == direct[idirect].x_dir) &&
(POSITIVE_DIR == direct[idirect].y_dir)){ // Bottom to Top on Left
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = ix - 1;
to_clb_y = ny + 1;
do{ // Find next available type
to_clb_y --; // Scan types from Top to Bottom
if(0 > to_clb_y){ // If scan fails scan the column on the Left until match or no more column
to_clb_x --;
to_clb_y = ny;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(0 <= to_clb_x));
}
} else if((P2P_DIRECT_ROW == direct[idirect].interconnection_type) &&
(POSITIVE_DIR == direct[idirect].x_dir) &&
(POSITIVE_DIR == direct[idirect].y_dir)){ // Left to Right Above
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = nx + 1;
to_clb_y = iy + 1;
do{ // Find next available type
to_clb_x --; // Scan types from Right to Left
if(0 > to_clb_x){ // If scan fails scan the row above until match or no more row
to_clb_x = nx;
to_clb_y ++;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(ny >= to_clb_y));
}
} else if((P2P_DIRECT_ROW == direct[idirect].interconnection_type) &&
(POSITIVE_DIR == direct[idirect].x_dir) &&
(NEGATIVE_DIR == direct[idirect].y_dir)){ // Left to Right Below
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = nx + 1;
to_clb_y = iy - 1;
do{ // Find next available type
to_clb_x --; // Scan types from Right to Left
if(0 > to_clb_x){ // If scan fails scan the row below until match or no more row
to_clb_x = nx;
to_clb_y --;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(0 <= to_clb_y));
}
} else if((P2P_DIRECT_ROW == direct[idirect].interconnection_type) &&
(NEGATIVE_DIR == direct[idirect].x_dir) &&
(NEGATIVE_DIR == direct[idirect].y_dir)){ // Right to Left Below
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = -1;
to_clb_y = iy - 1;
do{ // Find next available type
to_clb_x ++; // Scan types from Left to Right
if(nx < to_clb_x){ // If scan fails scan the row below until match or no more row
to_clb_x = 0;
to_clb_y --;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(0 <= to_clb_y));
}
} else if((P2P_DIRECT_ROW == direct[idirect].interconnection_type) &&
(NEGATIVE_DIR == direct[idirect].x_dir) &&
(POSITIVE_DIR == direct[idirect].y_dir)){ // Right to Left Above
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
to_clb_x = -1;
to_clb_y = iy + 1;
do{ // Find next available type
to_clb_x ++; // Scan types from Left to Right
if(nx < to_clb_x){ // If scan fails scan the row below until match or no more row
to_clb_x = 0;
to_clb_y ++;
}
} while((grid[to_clb_x][to_clb_y].type != direct[idirect].to_clb_type) &&
(ny >= to_clb_y));
}
}
if(grid[to_clb_x][to_clb_y].type == direct[idirect].from_clb_type){
/* Now we can print a direct connection with the spice models */
fprintf(fp, " //----- Point to Point from grid_%d__%d_ to grid_%d__%d_ -----\n", ix, iy,
to_clb_x, to_clb_y);
dump_verilog_one_clb2clb_direct(fp,
ix, iy,
to_clb_x, to_clb_y,
&direct[idirect]);
fprintf(fp, " //----- END Point to Point from grid_%d__%d_ to grid_%d__%d_ -----\n", ix, iy,
to_clb_x, to_clb_y);
}
}
} }
} }
} }

View File

@ -1245,7 +1245,10 @@ t_clb_to_clb_directs * alloc_and_load_clb_to_clb_directs(INP const t_direct_inf
vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Range mismatch from %s to %s.\n", directs[i].line, directs[i].from_pin, directs[i].to_pin); vpr_printf(TIO_MESSAGE_ERROR, "[LINE %d] Range mismatch from %s to %s.\n", directs[i].line, directs[i].from_pin, directs[i].to_pin);
exit(1); exit(1);
} }
/* Aurelien: assign point to point parameters */
clb_to_clb_directs[i].interconnection_type = directs[i].interconnection_type;
clb_to_clb_directs[i].x_dir = directs[i].x_dir;
clb_to_clb_directs[i].y_dir = directs[i].y_dir;
/* Xifan Tang: assign values to x,y,z_offset */ /* Xifan Tang: assign values to x,y,z_offset */
clb_to_clb_directs[i].x_offset = directs[i].x_offset; clb_to_clb_directs[i].x_offset = directs[i].x_offset;
clb_to_clb_directs[i].y_offset = directs[i].y_offset; clb_to_clb_directs[i].y_offset = directs[i].y_offset;