Merge branch 'dev' into refactoring
This commit is contained in:
commit
f0949fea2f
|
@ -924,6 +924,10 @@ typedef struct s_direct_inf {
|
|||
int y_offset;
|
||||
int z_offset;
|
||||
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 */
|
||||
char* spice_model_name;
|
||||
t_spice_model* spice_model;
|
||||
|
|
|
@ -3578,6 +3578,9 @@ static void ProcessDirects(INOUTP ezxml_t Parent, OUTP t_direct_inf **Directs,
|
|||
const char *direct_name;
|
||||
const char *from_pin_name;
|
||||
const char *to_pin_name;
|
||||
const char *point2point_type;
|
||||
const char *x_dir;
|
||||
const char *y_dir;
|
||||
|
||||
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, "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 */
|
||||
if ((*Directs)[i].x_offset == 0 && (*Directs)[i].y_offset == 0) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
|
|
|
@ -5,6 +5,20 @@
|
|||
#include "linkedlist.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*/
|
||||
enum e_spice_tech_lib_type {
|
||||
SPICE_LIB_INDUSTRY,
|
||||
|
|
|
@ -1123,6 +1123,10 @@ typedef struct s_clb_to_clb_directs {
|
|||
t_type_descriptor *to_clb_type;
|
||||
int to_clb_pin_start_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 */
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "verilog_decoder.h"
|
||||
#include "verilog_top_netlist_utils.h"
|
||||
|
||||
|
||||
/* Local Subroutines declaration */
|
||||
|
||||
/******** Subroutines ***********/
|
||||
|
@ -990,12 +991,12 @@ void dump_verilog_clb2clb_directs(FILE* fp,
|
|||
*/
|
||||
for (idirect = 0; idirect < num_directs; idirect++) {
|
||||
/* Bypass unmatch types */
|
||||
if (grid[ix][iy].type != direct[idirect].from_clb_type) {
|
||||
continue;
|
||||
}
|
||||
/* Apply x/y_offset */
|
||||
to_clb_x = ix + direct[idirect].x_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 */
|
||||
if ((FALSE == is_grid_coordinate_in_range(0, nx, to_clb_x))
|
||||
||(FALSE == is_grid_coordinate_in_range(0, ny, to_clb_y))) {
|
||||
|
@ -1006,21 +1007,157 @@ void dump_verilog_clb2clb_directs(FILE* fp,
|
|||
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
|
||||
* since it may be addressed in Connection blocks
|
||||
if (1 == (x_offset + y_offset)) {
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Check if the to_clb_type matches */
|
||||
if (grid[to_clb_x][to_clb_y].type == direct[idirect].to_clb_type) {
|
||||
/* Now we can print a direct connection with the spice models */
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
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 */
|
||||
clb_to_clb_directs[i].x_offset = directs[i].x_offset;
|
||||
clb_to_clb_directs[i].y_offset = directs[i].y_offset;
|
||||
|
|
Loading…
Reference in New Issue