bug fixing for SDC generator

This commit is contained in:
tangxifan 2019-04-26 14:07:44 -06:00
parent 46d44fa42a
commit c46c0fc97d
5 changed files with 69 additions and 34 deletions

View File

@ -545,6 +545,8 @@ struct s_pb_graph_edge {
boolean is_disabled;
int nb_mux;
int nb_pin;
char* delay_first_segment;
char* delay_second_segment;
/* END */
};
typedef struct s_pb_graph_edge t_pb_graph_edge;

View File

@ -1423,7 +1423,7 @@ static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) {
/* Xifan TANG: FPGA-SPICE, mode select description for multi-mode CLB */
num_annotations += CountChildren(Cur, "mode_select", 0);
/* END FPGA-SPICE, mode select description */
mode->interconnect[i].annotations =
(t_pin_to_pin_annotation*) my_calloc(num_annotations,
sizeof(t_pin_to_pin_annotation));
@ -1433,8 +1433,10 @@ static void ProcessInterconnect(INOUTP ezxml_t Parent, t_mode * mode) {
Cur2 = NULL;
/* Xifan TANG: FPGA-SPICE, mode select description */
/* for (j = 0; j < 5; j++) { */
for (j = 0; j < 6; j++) {
/* for (j = 0; j < 6; j++) { */
/* END FPGA-SPICE, mode select description */
/* Baudouin Chauviere: loop_breaker for CLB */
for (j = 0; j < 7; j++) {
if (j == 0) {
Cur2 = FindFirstElement(Cur, "delay_constant", FALSE);
} else if (j == 1) {

View File

@ -250,9 +250,16 @@ void verilog_generate_sdc_clock_period(t_sdc_opts sdc_opts,
/* Create a clock */
for (iport = 0; iport < num_clock_ports; iport++) {
fprintf(fp, "create_clock ");
fprintf(fp, "%s -period %.4g -waveform {0 %.4g}\n",
clock_port[iport]->prefix,
critical_path_delay, critical_path_delay/2);
if (NULL != strstr(clock_port[iport]->prefix,"prog")) {
fprintf(fp, "%s -period 100 -waveform {0 50}\n",
clock_port[iport]->prefix,
critical_path_delay, critical_path_delay/2);
}
else {
fprintf(fp, "%s -period %.4g -waveform {0 %.4g}\n",
clock_port[iport]->prefix,
critical_path_delay, critical_path_delay/2);
}
}
@ -1802,7 +1809,7 @@ void verilog_generate_sdc_pnr(t_sram_orgz_info* cur_sram_orgz_info,
sdc_opts.break_loops_mux = FALSE; /* By default, we turn it off to avoid a overkill */
/* Part 1. Constrain clock cycles */
verilog_generate_sdc_clock_period(sdc_opts, arch.spice->spice_params.stimulate_params.vpr_crit_path_delay);
verilog_generate_sdc_clock_period(sdc_opts, pow(10,9)*arch.spice->spice_params.stimulate_params.vpr_crit_path_delay);
/* Part 2. Output Design Constraints for breaking loops */
if (TRUE == sdc_opts.break_loops) {

View File

@ -92,7 +92,7 @@ void sdc_dump_annotation(char* from_path, // includes the cell
fprintf (fp,"0\n");
}*/
if (max_value != NULL){
fprintf (fp, "set_max_delay -from %s -to %s ", from_path, to_path);
fprintf (fp, "set_max_delay -combinational_from_to -from %s -to %s ", from_path, to_path);
fprintf (fp,"%f\n", max_value);
}
return;
@ -219,6 +219,11 @@ void dump_sdc_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
src_pb_type = src_pb_graph_node->pb_type;
/* Des pin, node, pb_type */
des_pb_graph_node = des_pb_graph_pin->parent_node;
// Generation of the paths for the dumping of the annotations
from_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin)) + 1));
sprintf (from_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin));
to_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin)) + 1));
sprintf (to_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin));
/* If the pin is disabled, the dumping is different. We need to use the
* input and output of the inverter of the mux */
@ -237,39 +242,53 @@ void dump_sdc_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
vpr_printf (TIO_MESSAGE_ERROR,
"The loop_breaker annotation can only be applied when there is an input buffer");
}
input_buffer_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 +
strlen (gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable)) + 1 +
strlen (cur_interc->spice_model->name) + 5 + strlen(my_itoa(cur_interc->fan_in)) + 1 +
strlen (my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_mux)) + 1 + 1));
if (0 == strcmp("",gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable))) {
input_buffer_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 +
strlen (cur_interc->spice_model->name) + 5 + strlen(my_itoa(cur_interc->fan_in)) + 1 +
strlen (my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_mux)) + 1 + 1));
sprintf (input_buffer_path, "%s/%s_size%d_%d_",instance_name,
cur_interc->spice_model->name, cur_interc->fan_in,
des_pb_graph_pin->input_edges[iedge]->nb_mux);
}
else {
input_buffer_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 +
strlen (gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable)) +
strlen (cur_interc->spice_model->name) + 5 + strlen(my_itoa(cur_interc->fan_in)) + 1 +
strlen (my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_mux)) + 1 + 1));
sprintf (input_buffer_path, "%s/%s%s_size%d_%d_",instance_name,
gen_verilog_one_pb_graph_pin_full_name_in_hierarchy_parent_node(cur_pin_disable),
cur_interc->spice_model->name, cur_interc->fan_in ,
des_pb_graph_pin->input_edges[iedge]->nb_mux);
}
input_buffer_name = cur_interc ->spice_model->input_buffer->spice_model_name;
/* BChauviere: might need to find the right port if something other than an inverter is used */
input_buffer_in = cur_interc ->spice_model->input_buffer->spice_model->ports[0].lib_name;
input_buffer_out = cur_interc ->spice_model->input_buffer->spice_model->ports[1].lib_name;
set_disable_path = (char*) my_malloc(sizeof(char)*(strlen(input_buffer_path) + 1 + strlen(input_buffer_name)
+ 1 + strlen(my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_pin))));
set_disable_path = (char*) my_malloc(sizeof(char)*(
strlen(input_buffer_path) + 1 +
strlen(input_buffer_name) + 1 +
strlen(my_itoa(des_pb_graph_pin->input_edges[iedge]->nb_pin))
+ 1 + 1) );
sprintf(set_disable_path, "%s/%s_%d_", input_buffer_path, input_buffer_name,
des_pb_graph_pin->input_edges[iedge]->nb_pin);
if (NULL == des_pb_graph_pin->input_edges[iedge]->delay_first_segment) {
des_pb_graph_pin->input_edges[iedge]->delay_first_segment = "0";
}
if (NULL == des_pb_graph_pin->input_edges[iedge]->delay_second_segment) {
des_pb_graph_pin->input_edges[iedge]->delay_second_segment = "0";
}
fprintf (fp, "set_max_delay -from %s -to %s/%s %s \n", from_path, set_disable_path, input_buffer_in,
des_pb_graph_pin->input_edges[iedge]->delay_first_segment);
fprintf (fp, "set_disable_timing -from %s -to %s %s \n", input_buffer_in, input_buffer_out, set_disable_path);
free(input_buffer_path);
free(set_disable_path);
fprintf (fp, "set_max_delay -from %s/%s -to %s %s \n", set_disable_path, input_buffer_out,
to_path, des_pb_graph_pin->input_edges[iedge]->delay_second_segment);
my_free(input_buffer_path);
my_free(set_disable_path);
}
else {
// Generation of the paths for the dumping of the annotations
from_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin)) + 1));
sprintf (from_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (src_pb_graph_pin));
to_path = (char *) my_malloc(sizeof(char)*(strlen(instance_name) + 1 + strlen(gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin)) + 1));
sprintf (to_path, "%s/%s", instance_name, gen_verilog_one_pb_graph_pin_full_name_in_hierarchy (des_pb_graph_pin));
// Dumping of the annotations
sdc_dump_annotation (from_path, to_path, fp, cur_interc[0]);
}

View File

@ -19,6 +19,7 @@
#include "pb_type_graph_annotations.h"
#include "cluster_feasibility_filter.h"
#include "power.h"
#include "read_xml_spice_util.h"
/* variable global to this section that indexes each pb graph pin within a cluster */
static int pin_count_in_cluster;
@ -1778,7 +1779,7 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
int i_tokens, cur_port_index, cur_pin_index;
int i_index_mode;
t_mode* cur_mode;
t_pb_graph_node** cur_node; /* can have a family of nodes */
t_pb_graph_node** cur_node;
int index_cur_node, i_index_cur_node;
t_pb_graph_node* tmp_node;
char* cur_pb_name;
@ -1798,12 +1799,12 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
tokens = GetTokensFromString(loop_breaker_string, &num_tokens);
i_tokens = 0;
cur_node = (t_pb_graph_node**) my_malloc(sizeof(t_pb_graph_node*));
*cur_node = (t_pb_graph_node*) my_malloc(sizeof(t_pb_graph_node));
tmp_node = (t_pb_graph_node*) my_malloc(sizeof(t_pb_graph_node));
while (i_tokens < num_tokens) {
pb_name_found = 0;
pin_name_found = 0;
msb_pin = lsb_pin = msb_pb = lsb_pb = 0;
// *cur_node = (t_pb_graph_node*) my_malloc(sizeof(t_pb_graph_node));
pb_name_found = 0;
pin_name_found = 0;
msb_pin = lsb_pin = msb_pb = lsb_pb = 0;
if (tokens[i_tokens].type != TOKEN_STRING) {
vpr_printf(TIO_MESSAGE_ERROR,
"[LINE %d] loop_breaker: first element of a pair pb+pin should be a string\n",
@ -1811,12 +1812,12 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
exit(1);
}
cur_pb_name = tokens[i_tokens].data;
*cur_node = (t_pb_graph_node*) my_realloc(*cur_node, sizeof(t_pb_graph_node));
/* no distinction is made between children and parent nodes */
for (i_num_input_ports = 0 ; i_num_input_ports < num_input_ports ; i_num_input_ports ++) {
if (0 == strcmp(cur_pb_name, input_pins[i_num_input_ports][0]->parent_node->pb_type->name)) {
pb_name_found = 1;
cur_node[0] = input_pins[i_num_input_ports][0]->parent_node;
// cur_node[0] = input_pins[i_num_input_ports][0]->parent_node;
tmp_node = input_pins[i_num_input_ports][0]->parent_node;
break;
}
}
@ -1829,7 +1830,7 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
i_tokens++;
/* We deal with three cases: nothing, a wire, a bus */
/* First, the bus/wire */
tmp_node = cur_node[0];
//tmp_node = cur_node[0];
if( tokens[i_tokens].type == TOKEN_OPEN_SQUARE_BRACKET) {
i_tokens++;
if( tokens[i_tokens].type != TOKEN_INT) {
@ -1839,7 +1840,7 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
exit(1);
}
msb_pb = my_atoi(tokens[i_tokens].data);
if (msb_pb > cur_node[0]->pb_type->num_pb) {
if (msb_pb > tmp_node->pb_type->num_pb) {
vpr_printf(TIO_MESSAGE_ERROR,
"[LINE %d] loop_breaker: MSB pb larger than the number of pb\n",
line_num);
@ -1884,20 +1885,23 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
}
/* If no bracket was used, we use need to apply the loop breaker to all the pbs with that name */
else {
msb_pb = cur_node[0]->pb_type->num_pb - 1;
//msb_pb = cur_node[0]->pb_type->num_pb - 1;
msb_pb = tmp_node->pb_type->num_pb - 1;
lsb_pb = 0;
}
index_cur_node = 0;
*cur_node = (t_pb_graph_node*) my_realloc(*cur_node, sizeof(t_pb_graph_node) * (msb_pb + 1));
if (tmp_node->parent_pb_graph_node == NULL) {/* if pb_graph_head */
cur_node = (t_pb_graph_node**) my_malloc(sizeof(t_pb_graph_node*));
cur_node[0] = tmp_node;
index_cur_node = 1;
}
else {
cur_node = (t_pb_graph_node**) my_malloc(sizeof(t_pb_graph_node*) * (msb_pb + 1));
for (i_pb_type_in_mode = 0 ;
i_pb_type_in_mode < tmp_node->parent_pb_graph_node->pb_type->modes[index_mode].num_pb_type_children ;
i_pb_type_in_mode ++) {
if (cur_pb_name ==
tmp_node->parent_pb_graph_node->child_pb_graph_nodes[index_mode][i_pb_type_in_mode][0].pb_type->name) {
if (0 == strcmp(cur_pb_name,
tmp_node->parent_pb_graph_node->child_pb_graph_nodes[index_mode][i_pb_type_in_mode][0].pb_type->name)) {
index_pb_type = i_pb_type_in_mode;
break;
}
@ -2088,5 +2092,6 @@ static void map_loop_breaker_onto_edges(char* loop_breaker_string, int line_num,
}
}
}
my_free(cur_node);
return;
}