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 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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ***********/
|
||||||
|
@ -959,7 +960,7 @@ void dump_verilog_one_clb2clb_direct(FILE* fp,
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Apply CLB to CLB direct connections to a Verilog netlist
|
/* Apply CLB to CLB direct connections to a Verilog netlist
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue