/* Program Section: mem_time_fpga_read_files.c Revision: 9-Feb-2025 */ #include #include #include #define MAX_BUFF 200 #define MAX_LINE 120 #define MAX_ARRAY 200 #define INPUT_FILE_LINE_COUNT 71 #define MAX_NET_NAME 30 #define MAX_PIN_NAME 7 /** Define the Propagation Constants in psec/mm **/ #define PROP_CNST_SURFACE 6.19 /** Surface Trace psec/mm **/ #define PROP_CNST_INTERNAL 6.32 /** Internal Trace psec/mm **/ #define PROP_CNST_VIA 6.66 /** Via Tunnel psec/mm **/ main( int argc, char *argv[] ) { /** Declare the functions aka provide the function prototypes **/ /** with dummy arguments **/ double calculate_delay( double package_delay, double xy_length, \ double surface_fraction, double escp_via, \ double return_via, double extra_via ) ; /** Declare some Character Arrays 1d and 2d **/ char filename[MAX_LINE] ; char this_net_name[MAX_NET_NAME] ; char array_of_net_names[MAX_BUFF][MAX_NET_NAME] ; char this_pin_name[MAX_PIN_NAME] ; char array_of_pin_names[MAX_BUFF][MAX_PIN_NAME] ; /** Declare the File Pointers to the 3 Input and 2 Output files **/ FILE *fp_pkg_delays_file ; FILE *fp_2d_trace_lengths_file ; FILE *fp_aux_routing_data_file ; FILE *fp_check_file ; FILE *fp_trace_diff_report_file ; /** Declare some Integer Variables **/ int parse_count = 0 ; int return_cnt = 0 ; /** Declare some Double Floating Point Variables **/ double this_delay = 0.0 ; double this_xy_length = 0.0 ; double this_fraction_on_surface = 0.0 ; double this_via_escape_length = 0.0 ; double this_via_return_length = 0.0 ; double this_via_third_length = 0.0 ; /** Declare the Propagation Constants in psec/mm double prop_cnst_surface = 6.19 ; double prop_cnst_internal = 6.32 ; double prop_cnst_via = 6.66 ; **/ /** Declare the Arrays that will hold the Input Data **/ double package_delay[MAX_ARRAY] ; double trace_xy_length[MAX_ARRAY] ; double fraction_on_surface[MAX_ARRAY] ; double via_escape_length[MAX_ARRAY] ; double via_return_length[MAX_ARRAY] ; double via_third_length[MAX_ARRAY] ; /** **/ /** Get the filenames of the 3x Input and 2x Output Files: **/ /** **/ /** input: package_delays_packed.txt **/ /** input: mem_2d_trace_lenghts_packed.txt **/ /** input: aux_memory_routing_packed.txt **/ /** **/ /** output: check_file.txt **/ /** output: mem_trace_differences_by_group.txt **/ /** **/ /** Recall that each of the inputs files has 71 lines of **/ /** ascii data divided into various columns which are **/ /** separated by white space. **/ /** **/ /** This program allows two different ways to specify **/ /** these 5 filenames: **/ /** **/ /** If no filename is specified on the command line that **/ /** starts this program then this program will prompt the **/ /** user for these 5 filenames one at a time. **/ /** **/ if ( argc == 1) /** Prompt the user for 5 filenames **/ { printf("Enter the filename of the Package Delays file to READ: "); scanf( "%50s", filename ); if ((fp_pkg_delays_file = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input Package Delays file %s\n", filename); exit (1); } printf("Enter the filename of the 2d Trace Lengths file to READ: "); scanf( "%50s", filename ); if ((fp_2d_trace_lengths_file = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input 2d Trace Lengths file %s\n", filename); exit (2); } printf("Enter the filename of the Aux Routing Data file to READ: "); scanf( "%50s", filename ); if ((fp_aux_routing_data_file = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input Aux Routing Data file %s\n", filename); exit (3); } printf("Enter the filename to receive the Check information: "); scanf( "%50s", filename ); if ((fp_check_file = fopen(filename, "w")) == NULL) { printf("\nERROR: Can't open the Check output file %s\n", filename); exit (4); } printf("Enter the filename to receive the Trace Differences Report: "); scanf( "%50s", filename ); if ((fp_trace_diff_report_file = fopen(filename, "w")) == NULL) { printf("\nERROR: Can't open Trace Differences output file %s\n", filename); exit (4); } } else if ( argc == 6 ) /** 4 filenames come from the command line **/ { printf( "\n\n\n " ); printf( "The 5 filenames are received from the command line. \n\n\n "); strcpy( filename, argv[1] ) ; if ((fp_pkg_delays_file = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input Package Delays file %s\n", filename); exit (2); } strcpy( filename, argv[2] ) ; if ((fp_2d_trace_lengths_file = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input 2d Trace Lengths file %s\n", filename); exit (2); } strcpy( filename, argv[3] ) ; if ((fp_aux_routing_data_file = fopen(filename, "r")) == NULL) { printf("\nERROR: Can't open input Aux Routing Data file %s\n", filename); exit (3); } strcpy( filename, argv[4] ) ; if ((fp_check_file = fopen(filename, "w")) == NULL) { printf("\nERROR: Can't open the Check output file %s\n", filename); exit (4); } strcpy( filename, argv[5] ) ; if ((fp_trace_diff_report_file = fopen(filename, "w")) == NULL) { printf("\nERROR: Can't open Trace Differences output file %s\n", filename); exit (4); } } else { printf( "\n\n\n " ); printf( "ERROR an illegal number of arguments was present \n "); printf( "on the command line. The user should either provide \n "); printf( "no arguments on the command line in which case this \n "); printf( "program will prompted the user for all required \n "); printf( "arguments or the user should supply all 5 \n "); printf( "filenames on the command line. \n\n\n "); exit (1); } /** **/ /** We now have all the information that we need to start the actual work **/ /** **/ /** Read the input files one at a time. For each input file read it **/ /** one line at a time and extract the useful column(s) of data **/ /** into Array variables. Recall that each of the inputs files has **/ /** 71 lines of ascii data divided into various columns which are **/ /** separated by white space. **/ /** **/ /** The fscanf funtion can be used to extract this information **/ /** into strings and normal double floating point variables. **/ /** **/ /** **/ /** First read the Package Delay input file. The pin delay values **/ /** that we want are in the 10th column of each line. Skip over **/ /** the first 9 columns by using edit masks that do not assign **/ /** these first 9 character strings in a line to a variable. **/ /** **/ /** The Package Delay values are between about 75 and 125 psec. **/ /** **/ parse_count = 0 ; while( parse_count < INPUT_FILE_LINE_COUNT ) { return_cnt = fscanf( fp_pkg_delays_file, \ "%6s %*20s %*20s %*20s %*20s \ %*20s %*20s %*20s %*20s %lf", \ this_pin_name, &this_delay ) ; package_delay[parse_count] = this_delay ; strcpy( array_of_pin_names[parse_count], this_pin_name ) ; ++parse_count ; } fclose( fp_pkg_delays_file ) ; /** **/ /** The 71 values of Package Delay are now in the **/ /** double float array package_delay[]. **/ /** **/ /** **/ /** Next read the XY 2d Trace Lengths input file. **/ /** **/ /** The first column of this file is the full Net_Name ascii string **/ /** The net names are less than 25 characters. **/ /** **/ /** The second column is the X,Y 2d Trace Length in mm ascii string **/ /** Trace Lengths are between about 20 and 55 mm **/ /** and are in the format JK.LM **/ /** **/ parse_count = 0 ; while( parse_count < INPUT_FILE_LINE_COUNT ) { return_cnt = fscanf( fp_2d_trace_lengths_file, \ "%25s %lf", this_net_name, &this_xy_length ) ; trace_xy_length[parse_count] = this_xy_length ; strcpy( array_of_net_names[parse_count], this_net_name ) ; ++parse_count ; } fclose( fp_2d_trace_lengths_file ) ; /** **/ /** The 71 values of XY 2d Trace Length are now in the **/ /** double float array trace_xy_length[]. **/ /** **/ /** **/ /** Next read the Aux Routing Data input file. **/ /** **/ /** The first column of this file is the Pin Number ascii string **/ /** Pin Numbers are less than 6 characters. **/ /** For now we will just skip over the first column. **/ /** **/ /** The second column is an abreviation of the Net Name ascii string **/ /** Net Names are less than 28 characters. **/ /** For now we will just skip over the second column. **/ /** **/ /** The third column is the Fraction of the Trace Length on **/ /** a Surface Layer. This is a value between 0.00 and 1.00 **/ /** Read this value into the fraction_on_surface array. **/ /** **/ /** The 4th, 5th, and 6th columns are the: **/ /** Length of the Escape Via in the FPGA BGA **/ /** Length of the Return Via in the Memory Chip BGA **/ /** Length of the Third Via in the routing if there is one **/ /** These mm values of form J.KLM are read into the arrays: **/ /** via_escape_length, via_return_length, via_third_length **/ /** These via are between about 0.0 mm and 2.2 mm long. **/ /** **/ parse_count = 0 ; while( parse_count < INPUT_FILE_LINE_COUNT ) { return_cnt = fscanf( fp_aux_routing_data_file, \ "%*20s %*20s %lf %lf %lf %lf", \ &this_fraction_on_surface, \ &this_via_escape_length, \ &this_via_return_length, \ &this_via_third_length ) ; fraction_on_surface[parse_count] = this_fraction_on_surface ; via_escape_length[parse_count] = this_via_escape_length ; via_return_length[parse_count] = this_via_return_length ; via_third_length[parse_count] = this_via_third_length ; ++parse_count ; } fclose( fp_aux_routing_data_file ) ; /** **/ /** The 71 values of: **/ /** Fraction on Surface Layers **/ /** Escape Via Length **/ /** Return Via Length **/ /** Third Via Length **/ /** **/ /** are now all in double float arrays. **/ /** **/ /** Write out information to the Check file: **/ /** **/ /** Package Delay in psec **/ /** XY 2d Trace Length in mm **/ /** **/ /** **/ fprintf( fp_check_file, \ "\n\n Package Trace Fract Via Lengths \n" ); fprintf( fp_check_file, \ " Pin Net Delay Length on Escp Rtrn 3rd \n" ); fprintf( fp_check_file, \ " Number Name psec mm Surf mm mm mm \n\n" ); parse_count = 0 ; while( parse_count < INPUT_FILE_LINE_COUNT ) { fprintf( fp_check_file, \ "%6s %25s %10.5f %6.2f %5.2f %4.2f %4.2f %4.2f \n", \ array_of_pin_names[parse_count], \ array_of_net_names[parse_count], \ package_delay[parse_count], \ trace_xy_length[parse_count], \ fraction_on_surface[parse_count], \ via_escape_length[parse_count], \ via_return_length[parse_count], \ via_third_length[parse_count] ); ++parse_count ; } fclose( fp_check_file ) ; /** **/ /** The Check file has now been written and closed. **/ /** **/ /** **/ /** Now start the code section that does the timing **/ /** analysis and writes out the Memory Timing Report. **/