VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
verilog_writer.h File Reference
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include "util.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "globals.h"
#include "read_place.h"
#include "draw.h"
#include "stats.h"
#include "check_route.h"
#include "rr_graph.h"
#include "path_delay.h"
#include "net_delay.h"
#include "timing_place.h"
#include "read_xml_arch_file.h"
#include "ReadOptions.h"
#include "physical_types.h"
#include "string.h"
#include "stdlib.h"
#include "math.h"
+ Include dependency graph for verilog_writer.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  found_pins
 
struct  found_connectivity
 

Typedefs

typedef struct found_pins pb_list
 
typedef struct found_connectivity conn_list
 

Functions

void verilog_writer (void)
 
pb_listtraverse_clb (t_pb *pb, pb_list *prim_list)
 
conn_listfind_connected_primitives_downhill (int block_num, t_pb *pb, conn_list *list)
 
pb_listinsert_to_linked_list (t_pb *pb_new, pb_list *list)
 
conn_listinsert_to_linked_list_conn (t_pb *driver_new, t_pb *load_new, t_pb_graph_pin *driver_pin_, t_pb_graph_pin *load_pin_, float path_delay, conn_list *list)
 
void traverse_linked_list (pb_list *list)
 
void traverse_linked_list_conn (conn_list *list)
 
pb_listfree_linked_list (pb_list *list)
 
conn_listfree_linked_list_conn (conn_list *list)
 
void instantiate_top_level_module (FILE *Verilog)
 
void instantiate_wires (FILE *Verilog)
 
void instantiate_input_interconnect (FILE *Verilog, FILE *SDF, char *clock_name)
 
void instantiate_interconnect (FILE *Verilog, int block_num, t_pb *pb, FILE *SDF)
 
void instantiate_primitive_modules (FILE *Verilog, char *clock_name, FILE *SDF)
 
char * load_truth_table (int inputs, t_pb *pb)
 
char * fix_name (char *name)
 
int find_number_of_inputs (t_pb *pb)
 
int find_index (char *row, int inputs)
 
void interconnect_printing (FILE *fp, conn_list *downhill)
 
void instantiate_SDF_header (FILE *SDF)
 
void SDF_interconnect_delay_printing (FILE *SDF, conn_list *downhill)
 
void sdf_LUT_delay_printing (FILE *SDF, t_pb *pb)
 
void sdf_DFF_delay_printing (FILE *SDF, t_pb *pb)
 
void SDF_Mult_delay_printing (FILE *SDF, t_pb *pb)
 
void SDF_Adder_delay_printing (FILE *SDF, t_pb *pb)
 
char * find_clock_name (void)
 
void SDF_ram_single_port_delay_printing (FILE *SDF, t_pb *pb)
 
void SDF_ram_dual_port_delay_printing (FILE *SDF, t_pb *pb)
 

Typedef Documentation

typedef struct found_connectivity conn_list
typedef struct found_pins pb_list

Function Documentation

char* find_clock_name ( void  )

Definition at line 1035 of file verilog_writer.c.

1036 {
1037  int j;
1038  char *clock_in_the_design=NULL;
1039  int clocks = 0;
1040  for(j=0 ; j<num_nets ; j++)/*Doing this to find the clock name in the design and storing it in clock_,*/
1041  {
1042  /* TODO fix this Hack: Currently detect if a clb_net is a clock using global and not vcc/gnd, need better way */
1043  if(clb_net[j].is_global == TRUE && strcmp(clb_net[j].name, "gnd") != 0 && strcmp(clb_net[j].name, "vcc") != 0)
1044  {
1045  clock_in_the_design = clb_net[j].name;
1046  clocks++;
1047  }
1048  }
1049  if (clocks > 1) {
1050  printf("The post-layout netlist generator presently handles single-clock designs only. Your design contains %d clocks. \n"
1051  "Future VTR releases may support post-layout netlist generation for multi-clock designs.\n", clocks);
1052  exit(1);
1053  }
1054  return(clock_in_the_design);
1055 }
int num_nets
Definition: globals.c:27
char * name
Definition: vpr_types.h:505
boolean * is_global
struct s_net * clb_net
Definition: globals.c:28
Definition: util.h:12

+ Here is the caller graph for this function:

conn_list* find_connected_primitives_downhill ( int  block_num,
t_pb pb,
conn_list list 
)

Definition at line 1096 of file verilog_writer.c.

1097 {
1098  int i,j,k,q,r;
1099  int total_output_pins;
1100  int pin_number , port_number_out=-1 , pin_number_out , starting_block , next_block , vpck_net , pin_count;
1101  float delay , start_delay , end_delay;
1102 
1103  char *temp_port_name = (char *)malloc(1000 * sizeof(char));
1104  int total_output_ports = pb->pb_graph_node->num_output_ports;
1105  int model_port_index;
1106 
1107  assert(temp_port_name);
1108 
1109  /*iterates through all output pins of the primitive "pb", and finds the other primitive and pin they connect to*/
1110  for(i=0 ; i < total_output_ports ; i++)
1111  {
1112  total_output_pins = pb->pb_graph_node->num_output_pins[i];
1113  for(j=0 ; j < total_output_pins ; j++)
1114  {
1115 
1116  model_port_index = pb->pb_graph_node->output_pins[i][j].port->model_port->index;
1117 
1118  pin_number = pb->pb_graph_node->output_pins[i][j].pin_count_in_cluster; /*pin count of the output pin*/
1119  starting_block = pb->logical_block; /*logical block index for the source primitive*/
1120 
1121  vpck_net = logical_block[starting_block].output_nets[model_port_index][j]; /*The index for the vpack_net struct corresponding to this source to sink(s) connections*/
1122 
1123  if (pb->rr_graph[pin_number].net_num != OPEN) /* If this output pin is used*/
1124  { /*Then we will use the logical_block netlist method for finding the connectivity and timing information*/
1125  if(vpck_net != OPEN)
1126  {
1127 
1128  for(k=1 ; k<vpack_net[vpck_net].num_sinks+1 ; k++)/*traversing through all the sink primitives that the source primitive connects to*/
1129  {
1130  next_block = vpack_net[vpck_net].node_block[k];/*next_blk holds the logical block index for the primitive that the source primitive connects to*/
1131 
1132 #if 0
1133 
1134  // we now need to map between the port on the logical block to the port on the physical block
1136  port_number_out = iPin->port->index;
1137 
1138  // because of possible pin swaps, we need to find the physical on load block that
1139  // has the correct attached net
1140  for (q = 0; q < logical_block[next_block].pb->pb_graph_node->num_input_pins[port_number_out]; q++)
1141  {
1142  int physical_pin_pos = logical_block[next_block].pb->pb_graph_node->input_pins[port_number_out][q].pin_count_in_cluster;
1143  if (logical_block[next_block].pb->rr_graph[physical_pin_pos].net_num == vpck_net)
1144  break;
1145  }
1146 
1147  assert(q != logical_block[next_block].pb->pb_graph_node->num_input_pins[port_number_out]);
1148 
1149  pin_number_out = q;
1150 #endif
1151 
1152  port_number_out = pin_number_out = -1;
1153 
1154  for (r = 0; r < logical_block[next_block].pb->pb_graph_node->num_input_ports; r++) {
1155  for (q = 0; q < logical_block[next_block].pb->pb_graph_node->num_input_pins[r]; q++) {
1156  int physical_pin_pos = logical_block[next_block].pb->pb_graph_node->input_pins[r][q].pin_count_in_cluster;
1157  if (logical_block[next_block].pb->rr_graph[physical_pin_pos].net_num == vpck_net) {
1158  port_number_out = r;
1159  pin_number_out = q;
1160  r = logical_block[next_block].pb->pb_graph_node->num_input_ports;
1161  break;
1162  }
1163  }
1164  }
1165 
1166  assert(port_number_out != -1);
1167  assert(pin_number_out != -1);
1168 
1169  int unswapped_pin_number = vpack_net[vpck_net].node_block_pin[k];
1170 
1171  pin_count = logical_block[next_block].pb->pb_graph_node->input_pins[port_number_out][pin_number_out].pin_count_in_cluster;/*pin count for the sink pin*/
1172  assert(logical_block[next_block].pb->rr_graph[pin_count].tnode);
1173 
1174  start_delay = pb->rr_graph[pin_number].tnode->T_arr; /*The arrival time of the source pin*/
1175  end_delay = logical_block[next_block].pb->rr_graph[pin_count].tnode->T_arr;/*The arrival time of the sink pin*/
1176  delay = end_delay - start_delay; /*The difference of start and end arrival times is the delay for going from the source to sink pin*/
1177  list=insert_to_linked_list_conn(pb , logical_block[next_block].pb ,
1178  &pb->pb_graph_node->output_pins[i][j] ,
1179  &logical_block[next_block].pb->pb_graph_node->input_pins[port_number_out][unswapped_pin_number] ,
1180  delay , list);/*Insert this sink primitive in the linked list pointer to by "list"*/
1181 
1182  }
1183  }
1184  }
1185  }
1186  }
1187  free(temp_port_name);
1188  return(list);
1189 }
int * node_block_pin
Definition: vpr_types.h:509
t_model_ports * model_port
int net_num
Definition: vpr_types.h:917
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
float T_arr
Definition: vpr_types.h:343
int * node_block
Definition: vpr_types.h:507
t_pb_graph_pin ** output_pins
int logical_block
Definition: vpr_types.h:181
conn_list * insert_to_linked_list_conn(t_pb *driver_new, t_pb *load_new, t_pb_graph_pin *driver_pin_, t_pb_graph_pin *load_pin_, float path_delay, conn_list *list)
Definition: slre.c:50
struct s_net * vpack_net
Definition: globals.c:19
int ** output_nets
Definition: vpr_types.h:212
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
int num_sinks
Definition: vpr_types.h:506
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
Definition: globals.c:20
t_pb_graph_pin * get_pb_graph_node_pin_from_vpack_net(int inet, int ipin)
Definition: vpr_utils.c:343

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int find_index ( char *  row,
int  inputs 
)

Definition at line 700 of file verilog_writer.c.

701 {
702  int index=0;/*initially setting index to 0*/
703  int or_=0x1;
704  int i,length;
705 
706  for(i=strlen(row)-1 ; i>=0 ; i--)/*traverse through the columns of this truth table row*/
707  {
708  if(row[i] == '1')
709  {
710  index |= or_;/*if this column is logic 1, then set this column in index to logic 1.*/
711  }
712  or_ = or_ << 1;
713  }
714  length = strlen(row);
715  if(length<inputs)/*if the number of used inputs to the lut is less than the total inputs to the lut*/
716  {
717  index = index << (inputs-(strlen(row)));/*shift the index value by the difference*/
718  }
719  return(index);
720 
721 }

+ Here is the caller graph for this function:

int find_number_of_inputs ( t_pb pb)

Definition at line 743 of file verilog_writer.c.

744 {
745  int i,j,count=0;
746  for(i=0 ; i<pb->pb_graph_node->num_input_ports ; i++)
747  {
748  for(j=0 ; j<pb->pb_graph_node->num_input_pins[i] ; j++)
749  {
750  count++;
751  }
752  }
753  return(count);
754 }
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180

+ Here is the caller graph for this function:

char* fix_name ( char *  name)

Definition at line 725 of file verilog_writer.c.

726 {
727  int i;
728 
729  char *new_;
730  new_=my_strdup(name);
731 
732  for(i=0 ; new_[i]!='\0' ; i++)
733  {
734  if(new_[i]=='^' || (int)new_[i]<48 || ((int)new_[i]>57 && (int)new_[i]<65) || ((int)new_[i]>90 && (int)new_[i]<97) || (int)new_[i]>122)
735  {
736  new_[i]='_';
737  }
738  }
739  return(new_);
740 }
char * my_strdup(const char *str)
Definition: util.c:101

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

pb_list* free_linked_list ( pb_list list)

Definition at line 1243 of file verilog_writer.c.

1244 {
1245  pb_list *current;
1246  pb_list *temp_free;
1247 
1248  current=list;
1249  while(current!=NULL)
1250  {
1251  temp_free=current;
1252  current=current->next;
1253  free(temp_free);
1254  }
1255  list = NULL;
1256  return(list);
1257 }
struct found_pins * next

+ Here is the caller graph for this function:

conn_list* free_linked_list_conn ( conn_list list)

Definition at line 1259 of file verilog_writer.c.

1260 {
1261  conn_list *current;
1262  conn_list *temp_free;
1263 
1264  current=list;
1265  while(current!=NULL)
1266  {
1267  temp_free=current;
1268  current=current->next;
1269  free(temp_free);
1270  }
1271  list = NULL;
1272  return(list);
1273 }
struct found_connectivity * next

+ Here is the caller graph for this function:

pb_list* insert_to_linked_list ( t_pb pb_new,
pb_list list 
)

Definition at line 1191 of file verilog_writer.c.

1192 {
1193  pb_list *new_list = (pb_list *)malloc(1 * sizeof(pb_list));
1194  assert(new_list);
1195  new_list->pb = pb_new;
1196  new_list->next = list;
1197  list = new_list;
1198  return(list);
1199 }
struct found_pins * next

+ Here is the caller graph for this function:

conn_list* insert_to_linked_list_conn ( t_pb driver_new,
t_pb load_new,
t_pb_graph_pin driver_pin_,
t_pb_graph_pin load_pin_,
float  path_delay,
conn_list list 
)

Definition at line 1201 of file verilog_writer.c.

1202 {
1203  conn_list *new_list = (conn_list *)malloc(1 * sizeof(conn_list));
1204  assert(new_list);
1205  new_list->driver_pb = driver_new;
1206  new_list->load_pb = load_new;
1207  new_list->driver_pin = driver_pin_;
1208  new_list->load_pin = load_pin_;
1209  new_list->driver_to_load_delay = path_delay;
1210  new_list->next = list;
1211  list = new_list;
1212  return(list);
1213 }
t_pb_graph_pin * driver_pin
t_pb_graph_pin * load_pin
struct found_connectivity * next

+ Here is the caller graph for this function:

void instantiate_input_interconnect ( FILE *  Verilog,
FILE *  SDF,
char *  clock_name 
)

Definition at line 200 of file verilog_writer.c.

201 {
202  int blocks;
203  pb_list *current;
204  pb_list *primitive_list = NULL;
205  conn_list *downhill = NULL;
206 
207  for(blocks=0 ; blocks<num_blocks ; blocks++)
208  {
209  if(strcmp(block[blocks].pb->pb_graph_node->pb_type->name,"io"))/*if this is an io block*/
210  {
211  continue;
212  }
213  primitive_list = traverse_clb(block[blocks].pb , primitive_list);/*find all the primitives in that block*/
214  for(current=primitive_list ; current!=NULL ; current=current->next)/*traversing through all the found primitives*/
215  {
216  if(strcmp(logical_block[current->pb->logical_block].model->name,"input"))/*if that primitive is an inpad*/
217  {
218  continue;
219  }
220  if(clock_name && !strcmp(current->pb->name,clock_name))/*If this is the clock signal, then don't instantiate an interconnect for it*/
221  {
222  continue;
223  }
224  downhill = find_connected_primitives_downhill(blocks , current->pb , downhill );/*find all the other primitives that it connects to*/
225 
226  /*traverse_linked_list_conn(downhill);*/
227  interconnect_printing(verilog , downhill);/*Print the interconnects modules that connect the inputs to the rest of the design*/
228  SDF_interconnect_delay_printing(SDF , downhill);/*Print the Delays of the interconnect module to the SDF file*/
229  downhill = free_linked_list_conn(downhill);
230  break;
231  }
232  primitive_list = free_linked_list(primitive_list);
233  }
234 }
char * name
Definition: vpr_types.h:179
pb_list * traverse_clb(t_pb *pb, pb_list *prim_list)
int num_blocks
Definition: globals.c:30
void interconnect_printing(FILE *fp, conn_list *downhill)
char * name
Definition: vpr_types.h:560
struct s_block * block
Definition: globals.c:31
int logical_block
Definition: vpr_types.h:181
char * name
Definition: logic_types.h:34
struct found_pins * next
conn_list * free_linked_list_conn(conn_list *list)
void SDF_interconnect_delay_printing(FILE *SDF, conn_list *downhill)
pb_list * free_linked_list(pb_list *list)
t_model * model
Definition: vpr_types.h:209
conn_list * find_connected_primitives_downhill(int block_num, t_pb *pb, conn_list *list)
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void instantiate_interconnect ( FILE *  Verilog,
int  block_num,
t_pb pb,
FILE *  SDF 
)

Definition at line 580 of file verilog_writer.c.

581 {
582  conn_list *downhill_connections = NULL;
583 
584  downhill_connections = find_connected_primitives_downhill(block_num , pb , downhill_connections);/*find all the other luts that the lut corresponding to "pb", connects to*/
585 
586  interconnect_printing(verilog , downhill_connections);
587  SDF_interconnect_delay_printing(SDF , downhill_connections);
588  downhill_connections = free_linked_list_conn(downhill_connections);
589 }
void interconnect_printing(FILE *fp, conn_list *downhill)
conn_list * free_linked_list_conn(conn_list *list)
void SDF_interconnect_delay_printing(FILE *SDF, conn_list *downhill)
conn_list * find_connected_primitives_downhill(int block_num, t_pb *pb, conn_list *list)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void instantiate_primitive_modules ( FILE *  Verilog,
char *  clock_name,
FILE *  SDF 
)

multipliers and adders are handled quite similarly

Definition at line 237 of file verilog_writer.c.

238 {
239  int i,j,k,h;
240  pb_list *primitives = NULL;
241  pb_list *current;
242 
243  int place_comma=0;
244  char *truth_table = NULL;
245  int inputs_to_lut;
246  char *fixed_name = NULL;
247  int power;
248  for(i=0 ; i<num_blocks ; i++)
249  {
250  primitives = traverse_clb(block[i].pb , primitives);/*find all the primitives inside block i*/
251  for(current=primitives ; current!=NULL ; current=current->next)/*traverse through all the found primitives*/
252  {
253 
254  fixed_name = fix_name(current->pb->name);
255 
256  if(!strcmp(logical_block[current->pb->logical_block].model->name,"names"))/*if this primitive is a lut*/
257  {
258  inputs_to_lut = find_number_of_inputs(current->pb);
259  assert((inputs_to_lut >= 3) && (inputs_to_lut <= 7));/*currently the primitives.v file only contains the verilog description for 4LUTs and 6LUTs*/
260  truth_table=load_truth_table(inputs_to_lut,current->pb);/*load_truth_table will find the truth table corresponding to this lut, and store it in "truth_table"*/
261 
262  /*instantiating the 6 input lut module and passing the truth table as parameter*/
263 
264  power = 1 << inputs_to_lut;
265  fprintf(fp , "\nLUT_%d #(%d'b%s) lut_%s(", inputs_to_lut , power , truth_table , fixed_name);
266 
267  free(truth_table);
268 
269  j=0;
270  for(k=0 ; k<current->pb->pb_graph_node->num_input_ports ; k++)/*traverse through all the input pins of the lut*/
271  {
272  for(h=0 ; h<current->pb->pb_graph_node->num_input_pins[k] ; h++)
273  {
274  if(current->pb->rr_graph[current->pb->pb_graph_node->input_pins[k][h].pin_count_in_cluster].net_num != OPEN)/*check if that pin is used*/
275  {
276  if(place_comma)/*need this flag check to properly place the commas*/
277  {
278  fprintf(fp , " , %s_input_%d_%d" , fixed_name , k , j); // j was h
279  }
280  else
281  {
282  fprintf(fp , "%s_input_%d_%d" , fixed_name , k , j); // j was h
283  place_comma=1;
284  }
285  j++;
286  }
287  }
288  }
289  while(j<inputs_to_lut)/*if (after writing all the inputs to the lut module) there are still some
290  inputs unused (i.e. not all the inputs to the lut are used) place a logic zero instead*/
291  {
292  if(place_comma && j)
293  {
294  j++;
295  fprintf(fp , " , 1'b0");
296  }
297  else
298  {
299  j++;
300  fprintf(fp , "1'b0");
301  place_comma=1;
302  }
303  }
304 
305  place_comma=0;
306  fprintf(fp , " , %s_output_0_0 );\n\n",fixed_name);/*finaly write the output of the module*/
307 
308  instantiate_interconnect(fp,i,current->pb,SDF);/*this function will instantiate the routing
309  interconnect from the output of this lut to
310  the inputs of other luts that it connects to*/
311  sdf_LUT_delay_printing(SDF , current->pb);/*This function will instantiate the internal delays of the lut to the SDF file*/
312  }
313  else if(!strcmp(logical_block[current->pb->logical_block].model->name,"latch"))/*If this primitive is a Flip Flop*/
314  {
315  char *fixed_clock_name;
316  fixed_clock_name = fix_name(clock_name);
317  fprintf(fp , "\nD_Flip_Flop DFF_%s(%s_output_0_0 , %s_input_0_0 , 1'b1 , 1'b1 , %s_output_0_0 );\n",fixed_name,fixed_clock_name,fixed_name,fixed_name);
318  instantiate_interconnect(fp , i , current->pb , SDF);
319  sdf_DFF_delay_printing(SDF , current->pb);
320  free(fixed_clock_name);
321  }
322  else if(!strcmp(logical_block[current->pb->logical_block].model->name,"multiply") ||
323  !strcmp(logical_block[current->pb->logical_block].model->name,"adder")) /*If this primitive is a multiplier or an adder */
324  {
325  /** multipliers and adders are handled quite similarly **/
326 
327  int mult = !strcmp(logical_block[current->pb->logical_block].model->name,"multiply");
328  int num_inputs = logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_pins[0];/*what is the data width*/
329  int i_port , i_pin ;
330  place_comma = 0;
331  if (mult)
332  fprintf(fp , "\nmult #(%d)%s(" , num_inputs , fixed_name);
333  else
334  fprintf(fp , "\nripple_adder #(%d)%s(" , num_inputs , fixed_name);
335 
336  /*Traversing through all the input ports of this multiplier*/
337  for(i_port=0 ; i_port<logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_ports ; i_port++)
338  {
339  if(i_port == 0)/*This if-else statement will make sure that the signals are concatinated in verilog*/
340  {
341  fprintf(fp , "{");
342  }
343  else{
344  fprintf(fp , ",{");
345  }
346  place_comma = 0;
347  /*Traversing through all the input pins of this input port*/
348  for(i_pin=logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_pins[i_port]-1 ; i_pin>=0 ; i_pin--)
349  {
350  /*If this input pin is used*/
351  if(current->pb->rr_graph[current->pb->pb_graph_node->input_pins[i_port][i_pin].pin_count_in_cluster].net_num != OPEN)
352  {
353  if(place_comma)/*need this flag check to properly place the commas*/
354  {
355  fprintf(fp , " , %s_input_%d_%d" , fixed_name , i_port , i_pin);
356  }
357  else
358  {
359  fprintf(fp , "%s_input_%d_%d" , fixed_name , i_port , i_pin);
360  place_comma=1;
361  }
362 
363  }
364  else{/*If this pin was not used, then instantiate logic zero*/
365  if(place_comma)
366  {
367  fprintf(fp , ", 1'b0");
368  }
369  else{
370  fprintf(fp , " 1'b0");
371  place_comma = 1;
372  }
373  }
374  }
375  fprintf(fp , "}");/*End concatination*/
376  }
377  /*Traversing through all the output ports of this multiplier*/
378  for(i_port=0 ; i_port<logical_block[current->pb->logical_block].pb->pb_graph_node->num_output_ports ; i_port++)
379  {
380  fprintf(fp , ",{");/*Since there is only a single output port for multipliers we only need to concatinate once*/
381  place_comma = 0;
382  /*Traversing through all the output pins of this output port*/
383  for(i_pin=logical_block[current->pb->logical_block].pb->pb_graph_node->num_output_pins[i_port]-1 ; i_pin>=0 ; i_pin--)
384  {
385  if(place_comma)
386  {
387  fprintf(fp , ", %s_output_%d_%d" , fixed_name , i_port , i_pin);
388  }
389  else{
390  fprintf(fp , " %s_output_%d_%d" , fixed_name , i_port , i_pin);
391  place_comma = 1;
392  }
393  }
394  fprintf(fp , "}");/*End concatination*/
395  }
396  fprintf(fp , ");\n\n");
397  instantiate_interconnect(fp , i , current->pb , SDF);
398  if (mult)
399  SDF_Mult_delay_printing(SDF, current->pb);
400  else
401  SDF_Adder_delay_printing(SDF, current->pb);
402  }
403  else if(!strcmp(logical_block[current->pb->logical_block].model->name,"single_port_ram")){/*If this primitive is a single port RAM block*/
404 
405  char *fixed_clock_name;
406  int i_port,i_pin;
407  int data_width,addr_width;
408 
409  data_width = logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_pins[1];/*the data_width (word width) is the number of inputs in the data port*/
410  addr_width = logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_pins[0];/*the addr_width (address width) is the number of inputs in the addr port*/
411 
412  fprintf(fp , "\nsingle_port_ram #(%d,%d)%s(" , addr_width , data_width , fixed_name);/*Passing the address width and data width as a verilog parameter*/
413  /*Traversign through all the input ports of this single_port_ram*/
414  for(i_port=0 ; i_port<logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_ports ; i_port++)
415  {
416  if(i_port == 0)/*This if-else statement will make sure that the signals are concatinated in verilog*/
417  {
418  fprintf(fp , "{");
419  }
420  else{
421  fprintf(fp , ",{");
422  }
423  place_comma = 0;
424  /*Traversing through all the input pins of this input port*/
425  for(i_pin=logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_pins[i_port]-1 ; i_pin>=0 ; i_pin--)
426  {
427  /*If this input pin is used*/
428  if(current->pb->rr_graph[current->pb->pb_graph_node->input_pins[i_port][i_pin].pin_count_in_cluster].net_num != OPEN)
429  {
430  if(place_comma)/*need this flag check to properly place the commas*/
431  {
432  fprintf(fp , " , %s_input_%d_%d" , fixed_name , i_port , i_pin);
433  }
434  else
435  {
436  fprintf(fp , "%s_input_%d_%d" , fixed_name , i_port , i_pin);
437  place_comma=1;
438  }
439  }
440  else{/*If this input pin is not used then instantiate a logic zero*/
441  if(place_comma)
442  {
443  fprintf(fp , ", 1'b0");
444  }
445  else{
446  fprintf(fp , " 1'b0");
447  place_comma = 1;
448  }
449  }
450  }
451  fprintf(fp , "}");/*End concatination*/
452  }
453  /*Traversign through all the output ports of this single_port_ram*/
454  for(i_port=0 ; i_port<logical_block[current->pb->logical_block].pb->pb_graph_node->num_output_ports ; i_port++)
455  {
456  fprintf(fp , ",{");/*Since there is only a single output port for single_port_rams we only need to concatinate once*/
457  place_comma = 0;
458  /*Traverse through all the output pins of this output port*/
459  for(i_pin=logical_block[current->pb->logical_block].pb->pb_graph_node->num_output_pins[i_port]-1 ; i_pin>=0 ; i_pin--)
460  {
461  if(place_comma)
462  {
463  fprintf(fp , ", %s_output_%d_%d" , fixed_name , i_port , i_pin);
464  }
465  else{
466  fprintf(fp , " %s_output_%d_%d" , fixed_name , i_port , i_pin);
467  place_comma = 1;
468  }
469  }
470  fprintf(fp , "}");/*End concatination*/
471  }
472  fixed_clock_name = fix_name(clock_name);/*Must also instantiate the clock signal to the RAM block*/
473  fprintf(fp , ", %s_output_0_0" , fixed_clock_name);
474  fprintf(fp , ");\n\n");
475  free(fixed_clock_name);
476  instantiate_interconnect(fp , i , current->pb , SDF);
477  SDF_ram_single_port_delay_printing(SDF , current->pb);
478  }
479  else if(!strcmp(logical_block[current->pb->logical_block].model->name,"dual_port_ram")){/*If this primitive is a dual_port_ram*/
480 
481  int data1_width,data2_width,addr1_width,addr2_width,i_port,i_pin;
482  char *fixed_clock_name;
483 
484  /*The Input ports of dual port rams are in this order:
485  0-addr1
486  1-addr2
487  2-data1
488  3-data2
489  4-we1
490  5-we2
491 
492  The verilog primitives module only accepts instatiation in this order else the simulation will give error or give incorrect simulation results*/
493 
494  data1_width = current->pb->pb_graph_node->num_input_pins[2];/*the data_width (word width) for the first port, is the number of inputs in the first data port*/
495  addr1_width = current->pb->pb_graph_node->num_input_pins[0];/*the addr_width (address width) for the first port, is the number of inputs in the first addr port*/
496  data2_width = current->pb->pb_graph_node->num_input_pins[3];/*the data_width (word width) for the second port, is the number of inputs in the second data port*/
497  addr2_width = current->pb->pb_graph_node->num_input_pins[1];/*the addr_width (address width) for the second port is the number of inputs in the second addr port*/
498 
499  fprintf(fp , "\ndual_port_ram #(%d,%d,%d,%d)%s(" , addr1_width , data1_width , addr2_width , data2_width , fixed_name);/*passing the addr_wdith and data_wdith for both ports as verilog parameter*/
500 
501  for(i_port=0 ; i_port<logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_ports ; i_port++)
502  {
503  if(i_port == 0)
504  {
505  fprintf(fp , "{");
506  }
507  else{
508  fprintf(fp , ",{");
509  }
510  place_comma = 0;
511  /*Traversign through all the input pins of this input port*/
512  for(i_pin=logical_block[current->pb->logical_block].pb->pb_graph_node->num_input_pins[i_port]-1 ; i_pin>=0 ; i_pin--)
513  {
514  /*If this pin is used*/
515  if(current->pb->rr_graph[current->pb->pb_graph_node->input_pins[i_port][i_pin].pin_count_in_cluster].net_num != OPEN)
516  {
517  if(place_comma)/*need this flag check to properly place the commas*/
518  {
519  fprintf(fp , " , %s_input_%d_%d" , fixed_name , i_port , i_pin);
520  }
521  else
522  {
523  fprintf(fp , "%s_input_%d_%d" , fixed_name , i_port , i_pin);
524  place_comma=1;
525  }
526  }
527  else{/*If this pin is not used, then instantiate logic zero instead*/
528  if(place_comma)
529  {
530  fprintf(fp , ", 1'b0");
531  }
532  else{
533  fprintf(fp , " 1'b0");
534  place_comma = 1;
535  }
536  }
537  }
538  fprintf(fp , "}");/*End concatination*/
539  }
540  /*Traversign through all the output ports of this dual_port_ram*/
541  for(i_port=0 ; i_port<logical_block[current->pb->logical_block].pb->pb_graph_node->num_output_ports ; i_port++)
542  {
543  fprintf(fp , ",{");
544  place_comma = 0;
545  /*Traverse through all the output pins of this output port*/
546  for(i_pin=logical_block[current->pb->logical_block].pb->pb_graph_node->num_output_pins[i_port]-1 ; i_pin>=0 ; i_pin--)
547  {
548  if(place_comma)
549  {
550  fprintf(fp , ", %s_output_%d_%d" , fixed_name , i_port , i_pin);
551  }
552  else{
553  fprintf(fp , " %s_output_%d_%d" , fixed_name , i_port , i_pin);
554  place_comma = 1;
555  }
556  }
557  fprintf(fp , "}");
558  }
559  fixed_clock_name = fix_name(clock_name);/*Must also instantiate the clock */
560  fprintf(fp , ", %s_output_0_0" , fixed_clock_name);
561  fprintf(fp , ");\n\n");
562  free(fixed_clock_name);
563  instantiate_interconnect(fp , i , current->pb , SDF);
564  SDF_ram_dual_port_delay_printing(SDF , current->pb);
565 
566  }
567  else if(strcmp(logical_block[current->pb->logical_block].model->name,"input") && strcmp(logical_block[current->pb->logical_block].model->name,"output"))
568  /*If this primitive is anything else, but an input or an output*/
569  {
570  printf("Failed to generate post-synthesized verilog and sdf files. Primitive %s is unknown.\n\nAcceptable primitives are: LUTs, Flip Flops, IOs, Adders, Rams, and Multiplier blocks.\n\nTo generate the post synthesized verilog and SDF files successfully, you must append the verilog code for the %s to the primitives.v file, and contact the VPR developers team on the website: http://code.google.com/p/vtr-verilog-to-routing/ to update the VPR source code to handle the new primitive. \n",logical_block[current->pb->logical_block].model->name , logical_block[current->pb->logical_block].model->name);
571  exit(1);
572  }
573  free(fixed_name);
574  }
575  primitives = free_linked_list(primitives);
576  }
577 }
char * name
Definition: vpr_types.h:179
void instantiate_interconnect(FILE *verilog, int block_num, t_pb *pb, FILE *SDF)
int net_num
Definition: vpr_types.h:917
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
pb_list * traverse_clb(t_pb *pb, pb_list *prim_list)
void sdf_LUT_delay_printing(FILE *SDF, t_pb *pb)
int num_blocks
Definition: globals.c:30
void SDF_ram_dual_port_delay_printing(FILE *SDF, t_pb *pb)
void SDF_Adder_delay_printing(FILE *SDF, t_pb *pb)
char * load_truth_table(int inputs, t_pb *pb)
struct s_block * block
Definition: globals.c:31
int logical_block
Definition: vpr_types.h:181
void SDF_ram_single_port_delay_printing(FILE *SDF, t_pb *pb)
char * name
Definition: logic_types.h:34
struct found_pins * next
void sdf_DFF_delay_printing(FILE *SDF, t_pb *pb)
Definition: slre.c:50
void SDF_Mult_delay_printing(FILE *SDF, t_pb *pb)
pb_list * free_linked_list(pb_list *list)
t_model * model
Definition: vpr_types.h:209
int find_number_of_inputs(t_pb *pb)
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void instantiate_SDF_header ( FILE *  SDF)

Definition at line 141 of file verilog_writer.c.

142 {
143  fprintf(SDF , "(DELAYFILE\n\t(SDFVERSION \"2.1\")\n\t(DIVIDER /)\n\t(TIMESCALE 1 ps)\n\n ");
144 }

+ Here is the caller graph for this function:

void instantiate_top_level_module ( FILE *  Verilog)

Definition at line 97 of file verilog_writer.c.

98 {
99  int i,place_comma;
100  pb_list *temp=NULL;
101  pb_list *current;
102  char *fixed_name = NULL;
103 
104 
105  fprintf(verilog , "module %s(\n" , blif_circuit_name);
106  place_comma=0;
107  for(i=0 ; i<num_blocks ; i++)/*go through all the blocks in the design*/
108  {
109  if(!strcmp(block[i].pb->pb_graph_node->pb_type->name,"io"))/*if this block is an i/o block*/
110  {
111  temp = traverse_clb(block[i].pb , temp);/*find all the primitives in this block*/
112  for(current=temp ; current!=NULL ; current=current->next)/*traverse through all the primitives in this block*/
113  {
114  if(place_comma){ /*need this for correct placement of commas and verilog syntax correctness*/
115  fprintf(verilog ,"\t,");
116  }
117  else{
118  fprintf(verilog ,"\t");
119  place_comma=1;
120  }
121  fixed_name = fix_name(current->pb->name);/*need to do this, because some names contain characters that cause syntax errors in verilog (e.g. '~' , '^',)*/
122  if(!strcmp(logical_block[current->pb->logical_block].model->name,"input")){/*if this primitive is an input pin, declare as input*/
123 
124  fprintf(verilog , "input %s\n",fixed_name);/*declaring the inputs*/
125 
126 
127  }
128  else if(!strcmp(logical_block[current->pb->logical_block].model->name,"output")){
129 
130  fprintf(verilog , "output %s\n",fixed_name);/*declaring the outputs*/
131  }
132  free(fixed_name);
133  }
134  }
135  temp = free_linked_list(temp);
136  }
137  fprintf(verilog , ");\n\n");
138 
139 }
char * name
Definition: vpr_types.h:179
pb_list * traverse_clb(t_pb *pb, pb_list *prim_list)
int num_blocks
Definition: globals.c:30
char * blif_circuit_name
Definition: globals.c:21
char * name
Definition: vpr_types.h:560
struct s_block * block
Definition: globals.c:31
int logical_block
Definition: vpr_types.h:181
char * name
Definition: logic_types.h:34
struct found_pins * next
pb_list * free_linked_list(pb_list *list)
t_model * model
Definition: vpr_types.h:209
char * fix_name(char *name)
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void instantiate_wires ( FILE *  Verilog)

Definition at line 147 of file verilog_writer.c.

148 {
149  int i,j,k;
150  pb_list *primitive_list=NULL;
151  pb_list *current;
152  char *fixed_name = NULL;
153 
154  for(i=0; i<num_blocks ; i++)/*go through all the blocks in the design*/
155  {
156  primitive_list = traverse_clb(block[i].pb , primitive_list);/*find all the primitives in this block*/
157 
158  for(current=primitive_list ; current!=NULL ; current=current->next)/*traverse through all the primitives in this block*/
159  {
160  fixed_name = fix_name(current->pb->name);/*need to do this, because some names contain characters that cause syntax errors in verilog (e.g. '~' , '^',)*/
161  for(j=0 ; j<current->pb->pb_graph_node->num_output_ports ; j++)/*go through all the found primitives and instantiate their output wires*/
162  {
163  for(k=0 ; k<current->pb->pb_graph_node->num_output_pins[j] ; k++)
164  {
165 
166 
167  fprintf(verilog , "wire %s_output_%d_%d;\n" , fixed_name , j , k);
168 
169  if(!strcmp(logical_block[current->pb->logical_block].model->name,"input"))/*if that pin is an inpad pin then have to connect the
170  inputs to the module to this wire*/
171  {
172  fprintf(verilog , "assign %s_output_%d_%d = %s;\n\n",fixed_name , j , k , fixed_name);
173  }
174 
175 
176  }
177  }
178  for(j=0 ; j<current->pb->pb_graph_node->num_input_ports ; j++)/*instantiating the input wire modules for each primitive*/
179  {
180  for(k=0 ; k<current->pb->pb_graph_node->num_input_pins[j] ; k++)
181  {
182  fprintf(verilog , "wire %s_input_%d_%d;\n" , fixed_name , j , k);
183  if(!strcmp(logical_block[current->pb->logical_block].model->name,"output"))/*if that pin is an outpad then have to connect the input to the outputs
184  of the top level module*/
185  {
186  fprintf(verilog , "assign %s = %s_input_%d_%d;\n\n",fixed_name , fixed_name , j , k);
187  }
188  }
189  }
190  free(fixed_name);
191  }
192  primitive_list = free_linked_list(primitive_list);
193  }
194 }
char * name
Definition: vpr_types.h:179
pb_list * traverse_clb(t_pb *pb, pb_list *prim_list)
int num_blocks
Definition: globals.c:30
struct s_block * block
Definition: globals.c:31
int logical_block
Definition: vpr_types.h:181
char * name
Definition: logic_types.h:34
struct found_pins * next
pb_list * free_linked_list(pb_list *list)
t_model * model
Definition: vpr_types.h:209
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void interconnect_printing ( FILE *  fp,
conn_list downhill 
)

Definition at line 757 of file verilog_writer.c.

758 {
759  char *fixed_name1;
760  char *fixed_name2;
761  conn_list *connections;
762  int port_number_out=-1,port_number_in=-1,i;
763 
764  for(connections=downhill ; connections!=NULL ; connections=connections->next)/*traverse through all the connected primitives and instantiate a routing interconect module*/
765  {
766  fixed_name1 = fix_name(connections->driver_pb->name);
767  fixed_name2 = fix_name(connections->load_pb->name);
768 
769  for(i=0 ; i<connections->load_pin->parent_node->num_input_ports ; i++)
770  {
771  if(!strcmp(connections->load_pin->parent_node->input_pins[i][0].port->name,connections->load_pin->port->name))
772  {
773  port_number_out = i;
774  }
775  }
776  for(i=0 ; i<connections->driver_pin->parent_node->num_output_ports ; i++)
777  {
778  if(!strcmp(connections->driver_pin->parent_node->output_pins[i][0].port->name,connections->driver_pin->port->name))
779  {
780  port_number_in = i;
781  }
782  }
783  assert(port_number_out >= 0 && port_number_in >= 0);
784 
785  fprintf(fp , "interconnect routing_segment_%s_output_%d_%d_to_%s_input_%d_%d( %s_output_%d_%d , %s_input_%d_%d );\n",
786  fixed_name1 , port_number_in/*connections->driver_pin->port->port_index_by_type*/ , connections->driver_pin->pin_number,
787  fixed_name2 , port_number_out , connections->load_pin->pin_number,
788  fixed_name1 , port_number_in/*connections->driver_pin->port->port_index_by_type*/ , connections->driver_pin->pin_number,
789  fixed_name2 , port_number_out , connections->load_pin->pin_number);
790 
791  free(fixed_name1);
792  free(fixed_name2);
793  }
794 }
char * name
Definition: vpr_types.h:179
t_pb_graph_pin * driver_pin
t_pb_graph_pin * load_pin
t_pb_graph_pin ** output_pins
char * name
struct s_pb_graph_node * parent_node
struct found_connectivity * next
char * fix_name(char *name)
t_pb_graph_pin ** input_pins

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

char* load_truth_table ( int  inputs,
t_pb pb 
)

Definition at line 595 of file verilog_writer.c.

596 {
597  int number_of_dont_cares=0;
598  int tries,shift,which_row,i,j;
599  int possibles = 1 << inputs;
600  char *tt_row_blif;
601  char *possible_row = (char *)malloc(inputs+1 * sizeof(char));
602  char *tt = (char *)malloc((possibles+1) * sizeof(char));
603  struct s_linked_vptr *current;
604  int number_of_used_inputs_to_lut;
605  char set_to;
606  assert(possible_row);
607  assert(tt);
608 
609  if (logical_block[pb->logical_block].truth_table) { // ??? janders ???? how can you have a LUT without a truth table???
610  tt_row_blif = (char *)logical_block[pb->logical_block].truth_table->data_vptr;
611  }
612  else { // must be producing a GROUND
613  for (i = 0; i < possibles; i++)
614  tt[i] = '0';
615  tt[possibles] = '\0';
616  free(possible_row);
617  return tt;
618  }
619  set_to = tt_row_blif[strlen(tt_row_blif)-1];
620 
621  /*filling the truth table with the state that is opposite to the output state in the blif truth table*/
622  if(set_to =='1')
623  {
624  for(i=0 ; i<possibles ; i++)
625  {
626  tt[i]='0';
627  }
628  }
629  else{
630  for(i=0 ; i<possibles ; i++)
631  {
632  tt[i]='1';
633  }
634  }
635  tt[possibles] = '\0';/*null terminating the tt string*/
636  /*The code bellow will populate the tt[] array with the truth table of the LUT with "pb"
637 
638  The truth table is stored as a linked list in the VPR. Each node in the linked list stores one line of the truth table. This line is in the exact same format as in the blif file. Each line of the truth table is read by traversing through each node of the linked list. The code bellow then parses each line of the truth table. That line might not have all the inputs to the lut specified, or there could be don't cares in that line of the truth table. at the end we need the output value of the LUT for every possible combination of inputs, which is not given in the blif truth table.
639 
640  The code bellow first counts the number of don't cares in that line of the truth table. It also creates a temporary string "possible_row". and there are n=2^(number of don't cares) possibilities in a particular line of the truth table So in a separate loop we find the nth possibility of the truth table*/
641 
642  for(current=logical_block[pb->logical_block].truth_table ; current!=NULL ; current=current->next)/*traversing through all the lines of the blif truth table*/
643  {
644 
645  tt_row_blif=(char *)current->data_vptr;/*tt_row_blif stores the current truth table line*/
646 
647 
648  /*counting number of don't cares in this line of the blif truth table*/
649  number_of_used_inputs_to_lut = strlen(tt_row_blif)-2;/*used*/
650  if(number_of_used_inputs_to_lut == 0)/*If this is a constant generator, then the truth table only contains the constant value that it generates.*/
651  {
652  for(i=0 ; i<possibles ; i++)
653  {
654  tt[i] = tt_row_blif[1];
655  }
656  }
657  else{
658  for(i=0; i<inputs ; i++)
659  {
660  if(tt_row_blif[i] == '-')
661  {
662  number_of_dont_cares++;
663  }
664  }
665  tries = 1 << number_of_dont_cares;/*how many possibilities are there for this line of the blif truth table*/
666 
667  for(i=0 ; i<(tries) ; i++)/*traverse through all the possibilities for this line of the blif truth table*/
668  {
669  shift=number_of_dont_cares-1;
670  for(j=0 ; j<number_of_used_inputs_to_lut ; j++)/*going through all the columns of the blif truth table*/
671  {
672  if(tt_row_blif[j]=='-')/*if this column represents a don't care*/
673  {
674  /*creating a temporary truth table row by taking different values of the possiblity 'i' depending on the shift value*/
675  if(((i>>shift) & 0x1) == 1)
676  {
677  possible_row[j] = '1';
678  }
679  else{
680  possible_row[j] = '0';
681  }
682  shift--;/*reduce the shift value by one*/
683  }
684  else
685  {
686  possible_row[j]=tt_row_blif[j];
687  }
688  }
689  possible_row[j]=0x0;/*null terminate the temporary truth table row*/
690  which_row = find_index(possible_row,inputs);/*find index returns the index of the 64bit truth table that this temporary truth table row corresponds to*/
691  tt[possibles-1-which_row] = set_to;
692  }
693  }
694  number_of_dont_cares = 0;
695  }
696  free(possible_row);
697  return(tt);
698 }
int find_index(char *row, int inputs)
struct s_linked_vptr * truth_table
Definition: vpr_types.h:227
int logical_block
Definition: vpr_types.h:181
struct s_linked_vptr * next
Definition: util.h:36
void * data_vptr
Definition: util.h:35
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SDF_Adder_delay_printing ( FILE *  SDF,
t_pb pb 
)

Definition at line 940 of file verilog_writer.c.

941 {
942  int i, j, k;
943  int total_input_ports = pb->pb_graph_node->num_input_ports;
944  int pin_count;
945  char *fixed_name;
946  int record = 0;
947 
948  fixed_name = fix_name(pb->name);
949 
950  for (i = 0; i < total_input_ports; i++) {
951 
952  for (j = 0; j < pb->pb_graph_node->num_input_pins[i]; j++) {
953 
954  pin_count = pb->pb_graph_node->input_pins[i][j].pin_count_in_cluster;
955 
956  t_tnode* tNodeInput = pb->rr_graph[pin_count].tnode; // source pin of timing arc
957 
958  if (!tNodeInput)
959  continue; // no timing information on pin
960 
961  for (k = 0; k < tNodeInput->num_edges; k++) {
962 
963  t_tnode tNodeOutput = tnode[tNodeInput->out_edges[k].to_node]; // dest pin of timing arc
964  int del = tNodeInput->out_edges[k].Tdel * 1.0E12 + 0.5;
965 
966  if (!record) { // print the SDF record header
967  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"ripple_adder\")\n\t(INSTANCE inst/%s)\n\t\t(DELAY\n\t\t(ABSOLUTE\n" , fixed_name);
968  record = 1;
969  }
970 
971  fprintf(SDF , "\t\t\t(IOPATH %s %s (%d:%d:%d)(%d:%d:%d))\n" , tNodeInput->pb_graph_pin->port->name,
972  tNodeOutput.pb_graph_pin->port->name,
973  del , del , del , del , del , del);
974 
975  }
976  j = pb->pb_graph_node->num_input_pins[i]; // skip to the next port -- JANDERS to fix
977  // what we really want to do here is find the max delay between any pin of the input port, to any pin of the output port
978  }
979  }
980 
981  if (record)
982  fprintf(SDF , "\t\t)\n\t\t)\n\t)\n");
983  free(fixed_name);
984 }
char * name
Definition: vpr_types.h:179
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
int num_edges
Definition: vpr_types.h:342
t_tnode * tnode
Definition: path_delay.c:143
char * name
float Tdel
Definition: vpr_types.h:297
t_pb_graph_pin * pb_graph_pin
Definition: vpr_types.h:358
t_tedge * out_edges
Definition: vpr_types.h:336
int to_node
Definition: vpr_types.h:296
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)
t_pb_graph_pin ** input_pins

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void sdf_DFF_delay_printing ( FILE *  SDF,
t_pb pb 
)

Definition at line 889 of file verilog_writer.c.

890 {
891  char *fixed_name;
892  float internal_delay;
893  int del,pin_count;
894 
895  fixed_name = fix_name(pb->name);
896  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"D_Flip_Flop\")\n\t(INSTANCE inst/DFF_%s)\n\t\t(DELAY\n\t\t(ABSOLUTE\n" , fixed_name);
897 
898  pin_count = pb->pb_graph_node->output_pins[0][0].pin_count_in_cluster; // the Q output of the FF (which has only a single output port and pin)
899  assert(pb->rr_graph[pin_count].tnode);
900  internal_delay = pb->rr_graph[pin_count].tnode->T_arr * 1.0E12 + 0.5;
901  del = (int)internal_delay;
902 
903  fprintf(SDF , "\t\t\t(IOPATH (posedge clock) Q (%d:%d:%d)(%d:%d:%d))\n" , del , del , del , del , del , del);
904  fprintf(SDF , "\t\t)\n\t\t)\n\t)\n");
905  free(fixed_name);
906 }
char * name
Definition: vpr_types.h:179
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
float T_arr
Definition: vpr_types.h:343
t_pb_graph_pin ** output_pins
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SDF_interconnect_delay_printing ( FILE *  SDF,
conn_list downhill 
)

Definition at line 797 of file verilog_writer.c.

798 {
799  conn_list *connections;
800  char *fixed_name1;
801  char *fixed_name2;
802  float internal_delay;
803  int del;
804  int port_number_out=-1,port_number_in=-1,i;
805 
806  for(connections=downhill ; connections!=NULL ; connections=connections->next)/*traverse through all the connected primitives and instantiate a routing interconect module*/
807  {
808  fixed_name1 = fix_name(connections->driver_pb->name);
809  fixed_name2 = fix_name(connections->load_pb->name);
810 
811  for(i=0 ; i<connections->load_pin->parent_node->num_input_ports ; i++)
812  {
813  if(!strcmp(connections->load_pin->parent_node->input_pins[i][0].port->name,connections->load_pin->port->name))
814  {
815  port_number_out = i;
816  }
817  }
818  for(i=0 ; i<connections->driver_pin->parent_node->num_output_ports ; i++)
819  {
820  if(!strcmp(connections->driver_pin->parent_node->output_pins[i][0].port->name,connections->driver_pin->port->name))
821  {
822  port_number_in = i;
823  }
824  }
825  internal_delay = connections->driver_to_load_delay;
826  internal_delay = internal_delay * 1000000000000.00; /*converting the delay from seconds to picoseconds*/
827  internal_delay = internal_delay + 0.5; /*Rounding the delay to the nearset picosecond*/
828  del = (int)internal_delay;
829 
830  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"interconnect\")\n\t(INSTANCE inst/routing_segment_%s_output_%d_%d_to_%s_input_%d_%d)\n" ,
831  fixed_name1 , port_number_in/*connections->driver_pin->port->port_index_by_type*/ , connections->driver_pin->pin_number,
832  fixed_name2 , port_number_out , connections->load_pin->pin_number);
833  fprintf(SDF , "\t\t(DELAY\n\t\t(ABSOLUTE\n\t\t\t(IOPATH datain dataout (%d:%d:%d)(%d:%d:%d))\n\t\t)\n\t\t)\n\t)\n" ,
834  del , del , del , del , del , del);
835 
836  free(fixed_name1);
837  free(fixed_name2);
838 
839  }
840 }
char * name
Definition: vpr_types.h:179
t_pb_graph_pin * driver_pin
t_pb_graph_pin * load_pin
t_pb_graph_pin ** output_pins
char * name
struct s_pb_graph_node * parent_node
struct found_connectivity * next
char * fix_name(char *name)
t_pb_graph_pin ** input_pins

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void sdf_LUT_delay_printing ( FILE *  SDF,
t_pb pb 
)

Definition at line 843 of file verilog_writer.c.

844 {
845  char *fixed_name;
846  int j,pin_count;
847  float internal_delay;
848  int del;
849  int logical_block_index = pb->logical_block;
850  int record = 0;
851 
852  fixed_name = fix_name(pb->name);
853 
854  for(j=0 ; j < pb->pb_graph_node->num_input_pins[0] ; j++)/*Assuming that LUTs have a single input port*/
855  {
856  if (logical_block[logical_block_index].input_nets[0][j] != OPEN)
857  {
858 
859  int q;
860  pin_count = OPEN;
861  for (q = 0; q < pb->pb_graph_node->num_input_pins[0]; q++)
862  {
863  pin_count = pb->pb_graph_node->input_pins[0][q].pin_count_in_cluster;
864  if (logical_block[logical_block_index].pb->rr_graph[pin_count].net_num == logical_block[logical_block_index].input_nets[0][j])
865  break;
866  }
867 
868  assert(q != pb->pb_graph_node->num_input_pins[0]);
869 
870  internal_delay = pb->rr_graph[pin_count].tnode->out_edges->Tdel;
871  internal_delay = internal_delay * 1000000000000.00;/*converting the delay from seconds to picoseconds*/
872  internal_delay = internal_delay + 0.5; /*Rounding the delay to the nearset picosecond*/
873  del = (int)internal_delay;
874 
875  if (!record) { // print the SDF record header
876  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"LUT_%d\")\n\t(INSTANCE inst/lut_%s)\n\t\t(DELAY\n\t\t(ABSOLUTE\n" , find_number_of_inputs(pb) , fixed_name);
877  record = 1;
878  }
879 
880  fprintf(SDF , "\t\t\t(IOPATH inter%d/datain inter%d/dataout (%d:%d:%d)(%d:%d:%d))\n" , j , j , del , del , del , del , del , del);
881  }
882  }
883  if (record)
884  fprintf(SDF , "\t\t)\n\t\t)\n\t)\n");
885  free(fixed_name);
886 }
char * name
Definition: vpr_types.h:179
int ** input_nets
Definition: vpr_types.h:211
int net_num
Definition: vpr_types.h:917
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
int logical_block
Definition: vpr_types.h:181
float Tdel
Definition: vpr_types.h:297
t_tedge * out_edges
Definition: vpr_types.h:336
Definition: slre.c:50
int find_number_of_inputs(t_pb *pb)
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)
t_pb_graph_pin ** input_pins
struct s_logical_block * logical_block
Definition: globals.c:20

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SDF_Mult_delay_printing ( FILE *  SDF,
t_pb pb 
)

Definition at line 908 of file verilog_writer.c.

909 {
910  char *fixed_name;
911  int pin_count;
912  float internal_delay;
913  int del;
914 
915  fixed_name = fix_name(pb->name);
916  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"mult\")\n\t(INSTANCE inst/%s)\n\t\t(DELAY\n\t\t(ABSOLUTE\n" , fixed_name);
917 
918 
919  pin_count = pb->pb_graph_node->input_pins[0][0].pin_count_in_cluster;
920  assert(pb->rr_graph[pin_count].tnode);
921  internal_delay = pb->rr_graph[pin_count].tnode->out_edges->Tdel;
922  internal_delay = internal_delay * 1000000000000.00;/*converting the delay from seconds to picoseconds*/
923  internal_delay = internal_delay + 0.5; /*Rounding the delay to the nearset picosecond*/
924  del = (int)internal_delay;
925  fprintf(SDF , "\t\t\t(IOPATH delay/A delay/B (%d:%d:%d)(%d:%d:%d))\n" , del , del , del , del , del , del);
926 
927  pin_count = pb->pb_graph_node->input_pins[1][0].pin_count_in_cluster;
928  assert(pb->rr_graph[pin_count].tnode);
929  internal_delay = pb->rr_graph[pin_count].tnode->out_edges->Tdel;
930  internal_delay = internal_delay * 1.0E12;/*converting the delay from seconds to picoseconds*/
931  internal_delay = internal_delay + 0.5; /*Rounding the delay to the nearset picosecond*/
932  del = (int)internal_delay;
933  fprintf(SDF , "\t\t\t(IOPATH delay2/A delay2/B (%d:%d:%d)(%d:%d:%d))\n" , del , del , del , del , del , del);
934 
935  fprintf(SDF , "\t\t)\n\t\t)\n\t)\n");
936  free(fixed_name);
937 
938 }
char * name
Definition: vpr_types.h:179
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
float Tdel
Definition: vpr_types.h:297
t_tedge * out_edges
Definition: vpr_types.h:336
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)
t_pb_graph_pin ** input_pins

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SDF_ram_dual_port_delay_printing ( FILE *  SDF,
t_pb pb 
)

Definition at line 1011 of file verilog_writer.c.

1012 {
1013  // int num_inputs;
1014  char *fixed_name;
1015  int pin_count;
1016  float internal_delay;
1017  int del;
1018 
1019  // num_inputs = pb->pb_graph_node->num_input_pins[0];
1020  fixed_name = fix_name(pb->name);
1021  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"dual_port_ram\")\n\t(INSTANCE inst/%s)\n\t\t(DELAY\n\t\t(ABSOLUTE\n" , fixed_name);
1022 
1023  pin_count = pb->pb_graph_node->output_pins[0][0].pin_count_in_cluster; // an output pin of the RAM
1024  assert(pb->rr_graph[pin_count].tnode);
1025  internal_delay = pb->rr_graph[pin_count].tnode->T_arr * 1.0E12 + 0.5;
1026  del = (int)internal_delay;
1027 
1028  fprintf(SDF , "\t\t\t(IOPATH (posedge clock) out1 (%d:%d:%d)(%d:%d:%d))" , del , del , del , del , del , del);
1029  fprintf(SDF , "\t\t\t(IOPATH (posedge clock) out2 (%d:%d:%d)(%d:%d:%d))" , del , del , del , del , del , del);
1030 
1031  fprintf(SDF , "\t\t)\n\t\t)\n\t)\n");
1032  free(fixed_name);
1033 }
char * name
Definition: vpr_types.h:179
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
float T_arr
Definition: vpr_types.h:343
t_pb_graph_pin ** output_pins
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SDF_ram_single_port_delay_printing ( FILE *  SDF,
t_pb pb 
)

Definition at line 987 of file verilog_writer.c.

988 {
989  // int num_inputs;
990  char *fixed_name;
991  int pin_count;
992  float internal_delay;
993  int del;
994 
995  // num_inputs = pb->pb_graph_node->num_input_pins[0];
996  fixed_name = fix_name(pb->name);
997  fprintf(SDF , "\t(CELL\n\t(CELLTYPE \"single_port_ram\")\n\t(INSTANCE inst/%s)\n\t\t(DELAY\n\t\t(ABSOLUTE\n" , fixed_name);
998 
999  pin_count = pb->pb_graph_node->output_pins[0][0].pin_count_in_cluster; // an output pin of the RAM
1000  assert(pb->rr_graph[pin_count].tnode);
1001  internal_delay = pb->rr_graph[pin_count].tnode->T_arr * 1.0E12 + 0.5;
1002  del = (int)internal_delay;
1003 
1004  fprintf(SDF , "\t\t\t(IOPATH (posedge clock) out (%d:%d:%d)(%d:%d:%d))" , del , del , del , del , del , del);
1005 
1006  fprintf(SDF , "\t\t)\n\t\t)\n\t)\n");
1007  free(fixed_name);
1008 
1009 }
char * name
Definition: vpr_types.h:179
struct s_rr_node * rr_graph
Definition: vpr_types.h:188
t_tnode * tnode
Definition: vpr_types.h:919
float T_arr
Definition: vpr_types.h:343
t_pb_graph_pin ** output_pins
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
char * fix_name(char *name)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

pb_list* traverse_clb ( t_pb pb,
pb_list prim_list 
)

Definition at line 1063 of file verilog_writer.c.

1064 {
1065  int i,j;
1066  const t_pb_type *pb_type;
1067  if(pb == NULL || pb->name == NULL) { /*Reached a pb with no content*/
1068  return(prim_list);
1069  }
1070 
1071  pb_type = pb->pb_graph_node->pb_type;
1072 
1073  if(pb->child_pbs == NULL) {/*reached a primitive*/
1074  prim_list = insert_to_linked_list(pb , prim_list); /*add the primitive to the linked list*/
1075  }
1076 
1077  if(pb_type->num_modes > 0) { /*Traversing through the children of the pb*/
1078  for(i = 0; i < pb_type->modes[pb->mode].num_pb_type_children; i++) {
1079  for(j = 0; j < pb_type->modes[pb->mode].pb_type_children[i].num_pb; j++) {
1080  prim_list = traverse_clb(&(pb->child_pbs[i][j]) , prim_list);
1081  }
1082  }
1083  }
1084 
1085  return(prim_list);
1086 
1087 }
char * name
Definition: vpr_types.h:179
struct s_pb ** child_pbs
Definition: vpr_types.h:185
struct s_pb_type * pb_type_children
t_mode * modes
pb_list * traverse_clb(t_pb *pb, pb_list *prim_list)
pb_list * insert_to_linked_list(t_pb *pb_new, pb_list *list)
int num_pb_type_children
struct s_pb_type * pb_type
int mode
Definition: vpr_types.h:183
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void traverse_linked_list ( pb_list list)

Definition at line 1233 of file verilog_writer.c.

1234 {
1235  pb_list *current;
1236 
1237  for(current=list ; current!=NULL ; current=current->next)
1238  {
1239  printf("type: %s , name: %s \n", logical_block[current->pb->logical_block].model->name , current->pb->name);
1240  }
1241 }
char * name
Definition: vpr_types.h:179
int logical_block
Definition: vpr_types.h:181
char * name
Definition: logic_types.h:34
struct found_pins * next
t_model * model
Definition: vpr_types.h:209
struct s_logical_block * logical_block
Definition: globals.c:20
void traverse_linked_list_conn ( conn_list list)

Definition at line 1216 of file verilog_writer.c.

1217 {
1218  conn_list *current;
1219 
1220  for(current=list ; current != NULL ; current=current->next)
1221  {
1222  printf(" driver=> type: %s , name: %s , output: [%d][%d] , load=> type: %s , name: %s input: [%d][%d]\npath delay: %e\n\n",current->driver_pb->pb_graph_node->pb_type->name ,
1223  current->driver_pb->name,
1224  current->driver_pin->port->index , current->driver_pin->pin_number ,
1225  current->load_pb->pb_graph_node->pb_type->name,
1226  current->load_pb->name,
1227  current->load_pin->port->index , current->load_pin->pin_number,
1228  current->driver_to_load_delay );
1229  }
1230 }
char * name
Definition: vpr_types.h:179
t_pb_graph_pin * driver_pin
t_pb_graph_pin * load_pin
struct s_pb_type * pb_type
struct found_connectivity * next
t_pb_graph_node * pb_graph_node
Definition: vpr_types.h:180
void verilog_writer ( void  )

Definition at line 64 of file verilog_writer.c.

65 {
66  FILE *verilog;
67  FILE *SDF;
68  char * verilog_file_name = (char *)malloc((strlen(blif_circuit_name) + strlen("_post_synthesis.v") + 1) *sizeof(char));/*creating the Verilog file name*/
69  char * sdf_file_name = (char *)malloc((strlen(blif_circuit_name) + strlen("_post_synthesis.sdf") + 1) *sizeof(char));/*creating the SDF file name*/
70  char *clock_name;/*Will need to store the clock name of the design if any exist*/
71  assert(verilog_file_name);
72  assert(sdf_file_name);
73  printf("\nWriting the post-synthesized circuit Verilog and SDF.....\n...");
74 
75  sprintf(verilog_file_name, "%s%s", blif_circuit_name, "_post_synthesis.v");
76  sprintf(sdf_file_name, "%s%s", blif_circuit_name, "_post_synthesis.sdf");
77 
78  /*Openning the post synthesized netlist files*/
79  verilog = fopen(verilog_file_name , "w");
80  SDF = fopen(sdf_file_name , "w");
81 
82  clock_name = find_clock_name();
85  instantiate_wires(verilog);
86  instantiate_input_interconnect(verilog , SDF , clock_name);
87  instantiate_primitive_modules(verilog,clock_name,SDF);
88 
89  fprintf(verilog , "\nendmodule\n");
90  fprintf(SDF , ")\n");
91  fclose(verilog);
92  fclose(SDF);
93  printf("Done\n\n");
94 }
void instantiate_primitive_modules(FILE *fp, char *clock_name, FILE *SDF)
void instantiate_SDF_header(FILE *SDF)
char * blif_circuit_name
Definition: globals.c:21
char * find_clock_name(void)
void instantiate_input_interconnect(FILE *verilog, FILE *SDF, char *clock_name)
void instantiate_wires(FILE *verilog)
void instantiate_top_level_module(FILE *verilog)

+ Here is the call graph for this function:

+ Here is the caller graph for this function: