452 #define SDC_TOKENS " \t\n{}[]"
454 char * ptr, ** from_list = NULL, ** to_list = NULL, * clock_name;
455 float clock_period, rising_edge, falling_edge, max_delay;
456 int iclock, iio, num_exclusive_groups = 0,
457 num_from = 0, num_to = 0, num_multicycles, i, j;
459 boolean found, domain_level_from =
FALSE, domain_level_to =
FALSE;
472 if (strcmp(ptr,
"create_clock") == 0) {
478 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Create_clock must be directly followed by '-period'.\n",
485 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] A number must follow '-period'.\n",
489 clock_period = (float) strtod(ptr, NULL);
492 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Clock(s) not specified.\n",
496 if (strcmp(ptr,
"-waveform") == 0) {
501 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] First token following '-waveform' should be rising edge, but is not a number.\n",
504 rising_edge = (float) strtod(ptr, NULL);
507 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Second token following '-waveform' should be falling edge, but is not a number.\n",
511 falling_edge = (float) strtod(ptr, NULL);
514 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Clock(s) not specified.\n",
522 falling_edge = clock_period / 2.0;
525 if (strcmp(ptr,
"-name") == 0) {
532 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Virtual clock name not specified.\n",
554 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] More than one virtual clock name is specified after '-name'.\n",
592 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Clock name or regular expression does not correspond to any nets.\n",
594 vpr_printf(TIO_MESSAGE_ERROR,
"If you'd like to create a virtual clock, use the '-name' keyword.\n");
601 if (fabs(rising_edge - falling_edge) - clock_period/2.0 >
EPSILON) {
602 vpr_printf(TIO_MESSAGE_WARNING,
"Clock %s does not have 50%% duty cycle.\n",
608 }
else if (strcmp(ptr,
"set_clock_groups") == 0) {
612 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_clock_groups must be directly followed by '-exclusive'.\n",
618 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_clock_groups '-exclusive' must be followed by lists of clock names or regular expressions each starting with the '-group' command.\n",
633 exclusive_groups[num_exclusive_groups - 1].
clock_names = NULL;
642 exclusive_groups[num_exclusive_groups - 1].clock_names, ++exclusive_groups[num_exclusive_groups - 1].num_clock_names *
sizeof(
char *));
643 exclusive_groups[num_exclusive_groups - 1].
clock_names
652 exclusive_groups[num_exclusive_groups - 1].clock_names, ++exclusive_groups[num_exclusive_groups - 1].num_clock_names *
sizeof(
char *));
653 exclusive_groups[num_exclusive_groups - 1].
clock_names
660 if (num_exclusive_groups < 2) {
661 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] At least two '-group' commands required.",
672 for (i = 0; i < num_exclusive_groups; i++) {
673 for (j = 0; j < num_exclusive_groups; j++) {
683 for (i = 0; i < num_exclusive_groups; i++) {
685 free(exclusive_groups[i].clock_names[j]);
687 free(exclusive_groups[i].clock_names);
689 free (exclusive_groups);
693 }
else if (strcmp(ptr,
"set_false_path") == 0) {
697 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_false_path must be directly followed by '-from <clock/flip-flop_list>'.\n",
702 if (strcmp(ptr,
"get_clocks") == 0) {
703 domain_level_from =
TRUE;
705 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_false_path must be directly followed by '-from <clock/flip-flop_list>'.\n",
713 from_list = (
char **)
my_realloc(from_list, ++num_from *
sizeof(
char *));
714 from_list[num_from - 1] =
my_strdup(ptr);
718 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_false_path requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
722 }
while (strcmp(ptr,
"-to") != 0);
725 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_false_path requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
729 if (strcmp(ptr,
"get_clocks") == 0) {
730 domain_level_to =
TRUE;
732 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_false_path must be directly followed by '-from <clock/flip-flop_list>'.\n",
740 to_list = (
char **)
my_realloc(to_list, ++num_to *
sizeof(
char *));
751 from_list = NULL, to_list = NULL;
755 }
else if (strcmp(ptr,
"set_max_delay") == 0) {
762 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Token following set_max_delay should be a delay value, but is not a number.\n",
766 max_delay = (float) strtod(ptr, NULL);
769 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_max_delay requires '-from <clock/flip-flop_list>' after max_delay.\n",
774 if (strcmp(ptr,
"get_clocks") == 0) {
775 domain_level_from =
TRUE;
777 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_max_delay requires '-from <clock/flip-flop_list>' after max_delay.\n",
785 from_list = (
char **)
my_realloc(from_list, ++num_from *
sizeof(
char *));
786 from_list[num_from - 1] =
my_strdup(ptr);
790 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_max_delay requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
794 }
while (strcmp(ptr,
"-to") != 0);
797 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_max_delay requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
801 if (strcmp(ptr,
"get_clocks") == 0) {
802 domain_level_to =
TRUE;
804 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_max_delay requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
812 to_list = (
char **)
my_realloc(to_list, ++num_to *
sizeof(
char *));
821 from_list = NULL, to_list = NULL;
825 }
else if (strcmp(ptr,
"set_multicycle_path") == 0) {
834 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path must be directly followed by '-setup'.\n",
840 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path requires '-from <clock/flip-flop_list>' after '-setup'.\n",
845 if (strcmp(ptr,
"get_clocks") == 0) {
846 domain_level_from =
TRUE;
848 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path '-setup' must be followed by '-from <clock/flip-flop_list>'.\n",
856 from_list = (
char **)
my_realloc(from_list, ++num_from *
sizeof(
char *));
857 from_list[num_from - 1] =
my_strdup(ptr);
861 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
865 }
while (strcmp(ptr,
"-to") != 0);
868 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
872 if (strcmp(ptr,
"get_clocks") == 0) {
873 domain_level_to =
TRUE;
875 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path requires '-to <clock/flip-flop_list>' after '-from <clock/flip-flop_list>'.\n",
883 to_list = (
char **)
my_realloc(to_list, ++num_to *
sizeof(
char *));
889 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_multicycle_path requires num_multicycles after '-to <clock/flip-flop_list>'.\n",
894 num_multicycles = (int) strtod(ptr, NULL);
899 num_multicycles, domain_level_from, domain_level_to,
FALSE);
903 from_list = NULL, to_list = NULL;
907 }
else if (strcmp(ptr,
"set_input_delay") == 0) {
914 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_input_delay must be directly followed by '-clock <virtual or netlist clock name>'.\n",
919 if (num_netlist_clocks == 1 && strcmp(ptr,
"*") == 0) {
928 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_input_delay '-clock <virtual or netlist clock name>' must be directly followed by '-max <maximum_input_delay>'.\n",
935 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Token following '-max' should be a delay value, but is not a number.\n",
939 max_delay = (float) strtod(ptr, NULL);
942 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_input_delay requires a [get_ports {...}] command following '-max <max_input_delay>'.\n",
976 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Output name or regular expression \"%s\" does not correspond to any nets.\n",
982 }
else if (strcmp(ptr,
"set_output_delay") == 0) {
989 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_output_delay must be directly followed by '-clock <virtual or netlist clock name>'.\n",
994 if (num_netlist_clocks == 1 && strcmp(ptr,
"*") == 0) {
1003 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_output_delay -clock <virtual or netlist clock name> must be directly followed by '-max <maximum_output_delay>'.\n",
1010 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Token following '-max' should be a delay value, but is not a number.\n",
1014 max_delay = (float) strtod(ptr, NULL);
1017 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] set_output_delay requires a [get_ports {...}] command following '-max <max_output_delay>'.\n",
1051 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Output name or regular expression \"%s\" does not correspond to any nets.\n",
1058 vpr_printf(TIO_MESSAGE_ERROR,
"[SDC line %d] Incorrect or unsupported syntax near start of line.\n",
static boolean is_number(char *ptr)
int num_constrained_outputs
static boolean regex_match(char *string, char *pattern)
int num_constrained_inputs
int num_constrained_clocks
static void add_override_constraint(char **from_list, int num_from, char **to_list, int num_to, float constraint, int num_multicycles, boolean domain_level_from, boolean domain_level_to, boolean make_copies)
char * my_strtok(char *ptr, const char *tokens, FILE *fp, char *buf)
t_clock * constrained_clocks
static void * my_realloc(void *memblk, int ibytes)
t_io * constrained_outputs
t_timing_constraints * g_sdc
char * my_strdup(const char *str)
#define HUGE_NEGATIVE_FLOAT
t_io * constrained_inputs