Main Page | Modules | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages | Examples

acsim.c

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 
00003 /*  ArchC Pre-processor generates tools for the described arquitecture
00004     Copyright (C) 2002-2004  The ArchC Team
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 */
00016 
00017 /********************************************************/
00018 /* Acsim.c: The ArchC pre-processor.                    */
00019 /* Author: Sandro Rigo                                  */
00020 /* Date: 16-07-2002                                     */
00021 /*                                                      */
00022 /* The ArchC Team                                       */
00023 /* Computer Systems Laboratory (LSC)                    */
00024 /* IC-UNICAMP                                           */
00025 /* http://www.lsc.ic.unicamp.br                         */
00026 /********************************************************/
00028 
00035 
00036 
00037 #include "acsim.h"
00038 #include "acsim.h"
00039 #include "stdlib.h"
00040 #include "string.h"
00041 
00042 //#define DEBUG_STORAGE
00043 
00044 //Defining Traces and Dasm strings
00045 #define PRINT_TRACE "%strace_file << hex << decode_pc << dec <<\"\\n\";\n"
00046 #define PRINT_DASM "%sdasmfile << hex << decode_pc << dec << \": \" << *instr << *format <<\"\t\t(\" << instr->get_name() << \",\" << format->get_name() << \")\" <<endl;\n"
00047 
00048 //Command-line options flags
00049 int  ACABIFlag=0;                              
00050 int  ACDasmFlag=0;                              
00051 int  ACDebugFlag=0;                             
00052 int  ACDecCacheFlag=1;                          
00053 int  ACDelayFlag=0;                             
00054 int  ACDDecoderFlag=0;                          
00055 //int  ACQuietFlag=0;                             //!<Indicates whether storage update logs are displayed during simulation or not
00056 int  ACStatsFlag=0;                             
00057 int  ACVerboseFlag=0;                           
00058 int  ACVerifyFlag=0;                            
00059 int  ACVerifyTimedFlag=0;                       
00060 int  ACEncoderFlag=0;                           
00061 int  ACGDBIntegrationFlag=0;                    
00062 
00063 char *ACVersion = "1.0.0";                  
00064 char ACOptions[500];                            
00065 char *ACOptions_p = ACOptions;                  
00066 char *arch_filename;                            
00067 
00068 int ac_host_endian;                             
00069 extern int ac_tgt_endian;                       
00070 int ac_match_endian;                            
00071 
00073 
00074 struct option_map
00075 {
00076   const char *name;                          
00077   const char *equivalent;                    
00078   const char *arg_desc;                      
00079   /* Argument info.  A string of flag chars; NULL equals no options.
00080      r => argument required.
00081      o => argument optional.
00082      * => require other text after NAME as an argument.  */
00083   const char *arg_info;                      
00084 };
00085 
00087 ac_decoder_full *decoder;
00088 
00090 ac_sto_list* load_device=0;
00091 
00094 struct option_map option_map[] = {
00095   {"--abi-included"  , "-abi"        ,"Indicate that an ABI for system call emulation was provided." ,"o"},
00096   {"--disassembler"  , "-dasm"       ,"Dump executing instructions in assembly format (Not completely implemented)." ,"o"},
00097   {"--debug"         , "-g"          ,"Enable simulation debug features: traces, update logs." ,"o"},
00098   {"--delay"         , "-dy"          ,"Enable delayed assignments to storage elements." ,"o"},
00099   {"--dumpdecoder"   , "-dd"         ,"Dump the decoder data structure." ,"o"},
00100   {"--help"          , "-h"          ,"Display this help message."       , 0},
00101   //  {"--quiet"         , "-q"          ,".", "o"},
00102   {"--no-dec-cache"  , "-ndc"        ,"Disable cache of decoded instructions." ,"o"},
00103   {"--stats"         , "-s"          ,"Enable statistics collection during simulation." ,"o"},
00104   {"--verbose"       , "-vb"         ,"Display update logs for storage devices during simulation.", "o"},
00105 /*   {"--verify"        , "-v"          ,"Enable co-verification mechanism." ,"o"}, */
00106   //  {"--verify-timed"  , "-vt"         ,"Enable co-verification mechanism. Timed model." ,"o"},
00107   {"--version"       , "-vrs"        ,"Display ACSIM version.", 0},
00108   {"--encoder"       , "-enc"        ,"Use encoder tools with the simulator (beta version).", 0},
00109   {"--gdb-integration", "-gdb"       ,"Enable support for debbuging programs running on the simulator.", 0},
00110   0
00111 };
00112 
00113 
00115 static void DisplayHelp (){
00116   int i;
00117   char line[]="====================";
00118 
00119   line[strlen(ACVersion)+1] = '\0';
00120 
00121   printf ("=========================================%s\n", line);
00122   printf (" This is the ArchC Pre-Processor version %s\n", ACVersion);
00123   printf ("=========================================%s\n\n", line);
00124   printf ("Usage: acsim input_file [options]\n");
00125   printf ("       Where input_file stands for your AC_ARCH description file.\n\n");
00126   printf ("Options:\n");
00127 
00128   for( i=0; i< ACNumberOfOptions; i++)
00129     printf ("    %-17s, %-5s       %s\n", option_map[i].name, option_map[i].equivalent, option_map[i].arg_desc);
00130 
00131   printf ("\n\n");
00132 }
00133 
00136 /*    PARSER-TIME VERSION: Should not be called
00137  */
00138 int ExpandInstrBuffer(int index)
00139 {
00140   AC_ERROR("ExpandInstrBuffer(index=%d): This function should not be called in Parser-time", index);
00141   return index+1;
00142 };
00143 
00144 
00146 
00147 
00148 int main( argc, argv )
00149      int argc;
00150      char **argv;
00151 {
00152   extern char *project_name, *isa_filename;
00153   extern int wordsize;
00154   extern int fetchsize;
00155   // Structures to be passed to the decoder generator 
00156   extern ac_dec_format *format_ins_list;
00157   extern ac_dec_instr *instr_list;
00158   // Structures to be passed to the simulator generator 
00159   extern ac_stg_list *stage_list;
00160   extern ac_pipe_list *pipe_list, *ppipe;
00161   extern int HaveFormattedRegs;
00162   extern ac_decoder_full *decoder;
00163 
00164   //Uncomment the line bellow if you want to debug the parser.
00165   //extern int yydebug; 
00166 
00167   int argn,i,j;
00168   endian a, b;
00169 
00170   int error_flag=0;
00171 
00172   //Uncomment the line bellow if you want to debug the parser.
00173   //yydebug =1; 
00174 
00175   //Initializes the pre-processor
00176   acppInit();
00177 
00178   //Loading Configuration Variables
00179   ReadConfFile();
00180 
00181   ++argv, --argc;  /* skip over program name */
00182 
00183   //First argument must be the file or --help option.
00184   if ( argc > 0 ){
00185     if( !strcmp(argv[0], "--help") | !strcmp(argv[0], "-h")){
00186       DisplayHelp();
00187       return 0;
00188     }
00189 
00190     if( !strcmp(argv[0], "--version") | !strcmp(argv[0], "-vrs")){
00191       printf("This is ArchC version %s\n", ACVersion);
00192       return 0;
00193     }
00194 
00195     else{
00196       if(!acppLoad(argv[0])){
00197         AC_ERROR("Invalid input file: %s\n", argv[0]);
00198         printf("   Try acpp --help for more information.\n");
00199         return EXIT_FAILURE;
00200       }
00201       arch_filename = argv[0];
00202     }
00203   }
00204   else{
00205     AC_ERROR("No input file provided.\n");
00206     printf("   Try acpp --help for more information.\n");
00207     return EXIT_FAILURE;
00208   }
00209 
00210 
00211   ++argv, --argc;  /* skip over arch file name */
00212 
00213   if( argc > 0){
00214  
00215     argn = argc;
00216     /* Handling command line options */
00217     for(j= 0; j<argn; j++ ){
00218                         
00219       /* Searching option map.*/
00220       for( i=0; i<ACNumberOfOptions; i++){
00221                                 
00222         if( (!strcmp(argv[0], option_map[i].name)) || (!strcmp(argv[0], option_map[i].equivalent))){
00223 
00224           switch (i)
00225             {
00226             case OPABI:
00227               ACABIFlag = 1;
00228               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00229               break;
00230             case OPDasm:
00231               ACDasmFlag = 1;
00232               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00233               break;
00234             case OPDebug:
00235               ACDebugFlag = 1;
00236               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00237               break;
00238             case OPDelay:
00239               ACDelayFlag = 1;
00240               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00241               break;
00242             case OPDDecoder:
00243               ACDDecoderFlag = 1;
00244               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00245               break;
00246               /* case OPQuiet: */
00247               /*   ACQuietFlag = 1; */
00248               /*   ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]); */
00249               /*   break; */
00250             case OPDecCache:
00251               ACDecCacheFlag = 0;
00252               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00253               break;
00254 
00255             case OPStats:
00256               ACStatsFlag = 1;
00257               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00258               break;
00259             case OPVerbose:
00260               ACVerboseFlag = 1;
00261               AC_MSG("Simulator running on verbose mode.\n");
00262               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00263               break;
00264 /*             case OPVerify: */
00265 /*               ACVerifyFlag =1; */
00266 /*               AC_MSG("Simulator running on co-verification mode. Use it ONLY along with the ac_verifier tool.\n"); */
00267 /*               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]); */
00268 /*               break; */
00269               /* case OPVerifyTimed: */
00270               /*   ACVerifyFlag = ACVerifyTimedFlag = 1; */
00271               /*   AC_MSG("Co-verification is turned on, running on timed mode.\n"); */
00272               /*   ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]); */
00273               /*   break; */
00274             case OPEncoder:
00275               ACEncoderFlag = 1;
00276               AC_MSG("Simulator will have encoder extra tools (beta version).\n");
00277               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00278               break;
00279             case OPGDBIntegration:
00280               ACGDBIntegrationFlag=1;
00281               ACOptions_p += sprintf( ACOptions_p, "%s ", argv[0]);
00282 
00283             default:
00284               break;
00285             }
00286           ++argv, --argc;  /* skip over founded argument */
00287                                 
00288           break;
00289         }
00290       }
00291     }
00292   }
00293 
00294   if(argc >0){
00295     AC_ERROR("Invalid argument %s.\n", argv[0]);
00296     return EXIT_FAILURE;
00297   }
00298   
00299     
00300   /*Parsing Architecture declaration file. */
00301   AC_MSG("Parsing AC_ARCH declaration file: %s\n", arch_filename);
00302   if( acppRun()){
00303     AC_ERROR("Parser terminated unsuccessfully.\n");
00304     error_flag =1;
00305     return EXIT_FAILURE;
00306   }
00307   acppUnload();
00308 
00309 
00310   /* Opening ISA File */
00311   if(isa_filename == NULL)
00312     AC_ERROR("No ISA file defined");
00313        
00314   if( !acppLoad(isa_filename)){
00315     AC_ERROR("Could not open ISA input file: %s", isa_filename);
00316     AC_ERROR("Parser terminated unsuccessfully.\n");
00317     return EXIT_FAILURE;
00318   }
00319       
00320        
00321   //Parsing ArchC ISA declaration file. 
00322   AC_MSG("Parsing AC_ISA declaration file: %s\n", isa_filename);
00323   if( acppRun()){
00324     AC_ERROR("Parser terminated unsuccessfully.\n");
00325     error_flag =1;
00326   }
00327   acppUnload();
00328 
00329 
00330   if(!error_flag){
00331 
00332     if( wordsize == 0){
00333       AC_MSG("Warning: No wordsize defined. Default value is 32 bits.\n");
00334       wordsize = 32;
00335     }
00336 
00337     if( fetchsize == 0){
00338       //AC_MSG("Warning: No fetchsize defined. Default is to be equal to wordsize (%d).\n", wordsize);
00339       fetchsize = wordsize;
00340     }
00341 
00342     //Testing host endianess.
00343     a.i = 255;
00344     b.c[0] = 0;
00345     b.c[1] = 0;
00346     b.c[2] = 0;
00347     b.c[3] = 255;
00348 
00349     if( a.i == b.i )
00350       ac_host_endian = 1;    //Host machine is big endian
00351     else
00352       ac_host_endian = 0;   //Host machine is little endian
00353 
00354     ac_match_endian = (ac_host_endian == ac_tgt_endian);
00355 
00356 
00357     //Creating decoder to get Field Number info and write its static version.
00358     //This object will be used by some Create functions.
00359     if( ACDDecoderFlag ){
00360       AC_MSG("Dumping decoder structures:\n");
00361       ShowDecInstr(instr_list);
00362       ShowDecFormat(format_ins_list);
00363 
00364       printf("\n\n");
00365     }
00366     decoder = CreateDecoder(format_ins_list, instr_list);
00367 
00368     if( ACDDecoderFlag )
00369       ShowDecoder(decoder -> decoder, 0);
00370 
00371 
00372     //Creating Resources Header File
00373     CreateResourceHeader();
00374     //Creating Resources Impl File
00375     CreateResourceImpl();
00376     //Creating ISA Header File
00377     CreateISAHeader();
00378     //Creating Parameters Header File
00379     CreateParmHeader();
00380     //Creating ARCH Header File
00381     CreateARCHHeader();
00382     //Creating ARCH Impl File
00383     CreateARCHImpl();
00384 
00385     //Now, declare stages if a pipeline was declared
00386     //Otherwise, declare one sc_module to simulate the processor datapath
00387     //OBS: For pipelined architectures there must be a stage_list or a pipe_list,
00388     //     but never both of them.
00389 
00390     if( stage_list  ){  //List of ac_stage declarations. Used only for single pipe archs
00391 
00392       //Creating Stage Module Header Files
00393       CreateStgHeader(stage_list, NULL);
00394       //Creating Stage Module Implementation Files
00395       CreateStgImpl(stage_list, NULL);
00396 
00397     }
00398     else if( pipe_list ){  //Pipeline list exist. Used for ac_pipe declarations.
00399                         
00400       for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
00401 
00402         //Creating Stage Module Header Files
00403         CreateStgHeader( ppipe->stages, ppipe->name );
00404 
00405         //Creating Stage Module Implementation Files
00406         CreateStgImpl(ppipe->stages, ppipe->name);
00407       }
00408     }
00409     else{    //No pipe was declared.
00410 
00411       //Creating Processor Files
00412       CreateProcessorHeader();
00413       CreateProcessorImpl();
00414     }   
00415       
00416       
00417     //Creating Types Header File
00418     CreateTypeHeader();
00419 
00420     if( HaveFormattedRegs ){
00421       //Creating Formatted Registers Header and Implementation Files.
00422       CreateRegsHeader();
00423       //CreateRegsImpl();  This is not used anymore.
00424     }
00425 
00426     //Creating co-verification class header file.
00427     //if( ACVerifyFlag )
00428     //  CreateCoverifHeader();
00429 
00430     //Creating Simulation Statistics class header file.
00431     if( ACStatsFlag )
00432       CreateStatsHeader();
00433 
00434     //Creating model syscall header file.
00435     if( ACABIFlag )
00436       CreateArchSyscallHeader();
00437 
00438     /* Create the template for the .cpp instruction and format behavior file */
00439     CreateImplTmpl();
00440 
00441     /* Create the template for the main.cpp  file */
00442     CreateMainTmpl();
00443 
00444     /* Create the Makefile */
00445     CreateMakefile();
00446                 
00447     //Issuing final messages to the user.
00448     AC_MSG("%s model files generated.\n", project_name);
00449     if( ACDasmFlag)
00450       AC_MSG("Disassembler file is: %s.dasm\n", project_name);
00451   }
00452 
00453   return 0;
00454 }
00455 
00456 
00458 // Create functions ...                                                           //
00459 // These Functions are used to create the behavioral simulato files               //
00460 // All of them use structures built by the parser.                                //
00462 
00464 void CreateResourceHeader() {
00465 
00466   extern ac_pipe_list *pipe_list;
00467   extern ac_sto_list *storage_list;
00468   extern ac_stg_list *stage_list;
00469   extern int HaveFormattedRegs, HaveMultiCycleIns, HaveMemHier, reg_width;
00470 
00471   ac_sto_list *pstorage;
00472   ac_stg_list *pstage;
00473   char Globals[5000];
00474   char *Globals_p = Globals;
00475   ac_pipe_list *ppipe;
00476 
00477 
00478   FILE *output;
00479   char filename[] = "ac_resources.H";
00480 
00481   if ( !(output = fopen( filename, "w"))){
00482     perror("ArchC could not open output file");
00483     exit(1);
00484   }
00485 
00486   print_comment( output, "ArchC Resources header file.");
00487   fprintf( output, "#ifndef  _AC_RESOURCES_H\n");
00488   fprintf( output, "#define  _AC_RESOURCES_H\n\n");
00489   
00490   fprintf( output, "#include  \"ac_storage.H\"\n");
00491   fprintf( output, "#include  \"ac_regbank.H\"\n");
00492   fprintf( output, "#include  \"ac_reg.H\"\n");
00493 
00494   if( HaveMemHier ){
00495     fprintf( output, "#include  \"ac_mem.H\"\n");
00496     fprintf( output, "#include  \"ac_cache.H\"\n");
00497   }
00498 
00499   if( ACStatsFlag )
00500     fprintf( output, "#include  \"ac_stats.H\"\n");
00501 
00502   if( HaveFormattedRegs )
00503     fprintf( output, "#include  \"ac_fmt_regs.H\"\n");
00504   fprintf( output, " \n");
00505 
00506   if( ACGDBIntegrationFlag ) {
00507     fprintf( output, "#ifndef PORT_NUM\n" );
00508     fprintf( output, "#define PORT_NUM 5000 // Port to which GDB binds for remote debugging\n" );
00509     fprintf( output, "#endif /* PORT_NUM */\n" );
00510   }
00511   
00512   //Declaring Architecture Resources class.
00513   COMMENT(INDENT[0],"ArchC class for Architecture Resources.\n");
00514   fprintf( output, "class ac_resources {\n");
00515   fprintf( output, "public:\n");
00516   fprintf( output, " \n");
00517 
00518   if( ACStatsFlag ){
00519     COMMENT(INDENT[1],"Statistics Object.");
00520     fprintf( output, "%sstatic ac_stats ac_sim_stats;\n", INDENT[0]);      
00521   }
00522 
00523   /* Declaring storage devices */
00524   COMMENT(INDENT[1],"Storage Devices.");
00525   for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
00526 
00527     switch( pstorage->type ){
00528 
00529     case REG:
00530 
00531       //Formatted registers have a special class.
00532       if( pstorage->format != NULL ){
00533         fprintf( output, "%sstatic ac_%s %s;\n", INDENT[1], pstorage->name, pstorage->name);
00534         Globals_p += sprintf( Globals_p, "extern ac_%1$s &%1$s;\n", pstorage->name);
00535       }
00536       else{
00537         fprintf( output, "%sstatic ac_reg<unsigned> %s;\n", INDENT[1], pstorage->name);      
00538         Globals_p += sprintf( Globals_p, "extern ac_reg<unsigned> &%s;\n", pstorage->name);
00539       }
00540       break;
00541                         
00542     case REGBANK:
00543       //Emiting register bank. Checking is a register width was declared.
00544       switch( (unsigned)reg_width ){
00545       case 0:
00546         fprintf( output, "%sstatic ac_regbank<ac_word> %s;\n", INDENT[1], pstorage->name);      
00547         Globals_p += sprintf( Globals_p, "extern ac_regbank<ac_word> &%s;\n", pstorage->name);
00548         break;
00549       case 8:
00550         fprintf( output, "%sstatic ac_regbank<unsigned char> %s;\n", INDENT[1], pstorage->name);      
00551         Globals_p += sprintf( Globals_p, "extern ac_regbank<unsigned char> &%s;\n", pstorage->name);
00552         break;
00553       case 16:
00554         fprintf( output, "%sstatic ac_regbank<unsigned short> %s;\n", INDENT[1], pstorage->name);      
00555         Globals_p += sprintf( Globals_p, "extern ac_regbank<unsigned short> &%s;\n", pstorage->name);
00556         break;
00557       case 32:
00558         fprintf( output, "%sstatic ac_regbank<unsigned> %s;\n", INDENT[1], pstorage->name);      
00559         Globals_p += sprintf( Globals_p, "extern ac_regbank<unsigned> &%s;\n", pstorage->name);
00560         break;
00561       case 64:
00562         fprintf( output, "%sstatic ac_regbank<unsigned long long> %s;\n", INDENT[1], pstorage->name);      
00563         Globals_p += sprintf( Globals_p, "extern ac_regbank<unsigned long long> &%s;\n", pstorage->name);
00564         break;
00565       default:
00566         AC_ERROR("Register width not supported: %d\n", reg_width);
00567         break;
00568       }
00569 
00570       break;
00571 
00572     case CACHE:
00573     case ICACHE:
00574     case DCACHE:
00575 
00576       if( !HaveMemHier ) { //It is a generic cache. Just emit a base container object.
00577         fprintf( output, "%sstatic ac_storage %s;\n", INDENT[1], pstorage->name);
00578         Globals_p += sprintf( Globals_p, "extern ac_storage &%s;\n", pstorage->name);
00579       }
00580       else{
00581         //It is an ac_cache object.
00582         fprintf( output, "%sstatic ac_cache %s;\n", INDENT[1], pstorage->name);
00583         Globals_p += sprintf( Globals_p, "extern ac_cache &%s;\n", pstorage->name);
00584       }
00585 
00586       break;
00587 
00588     case MEM:
00589 
00590       if( !HaveMemHier ) { //It is a generic mem. Just emit a base container object.
00591         fprintf( output, "%sstatic ac_storage %s;\n", INDENT[1], pstorage->name);
00592         Globals_p += sprintf( Globals_p, "extern ac_storage &%s;\n", pstorage->name);
00593       }
00594       else{
00595         //It is an ac_mem object.
00596         fprintf( output, "%sstatic ac_mem %s;\n", INDENT[1], pstorage->name);
00597         Globals_p += sprintf( Globals_p, "extern ac_mem &%s;\n", pstorage->name);
00598       }
00599 
00600       break;
00601 
00602       
00603     default:
00604       fprintf( output, "%sstatic ac_storage %s;\n", INDENT[1], pstorage->name);      
00605       Globals_p += sprintf( Globals_p, "extern ac_storage &%s;\n", pstorage->name);
00606       break;
00607     }
00608   }
00609 
00610   //Pointer that stores the object used for fetch.
00611   COMMENT(INDENT[1],"Indicates the storage device from where instructions are fetched.");
00612   fprintf(output , "%sstatic ac_storage *IM;\n\n", INDENT[1]);
00613   
00614   //Pointer that stores the object used for loading applications.
00615   COMMENT(INDENT[1],"Indicates the storage device where applications are loaded.");
00616   fprintf(output , "%sstatic ac_storage *APP_MEM;\n\n", INDENT[1]);
00617   
00618   COMMENT(INDENT[1],"Control Variables.");
00619 
00620   if( stage_list ){
00621     for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
00622       if( pstage->next ){
00623         fprintf( output, "%sstatic bool %s_stall;\n", INDENT[1], pstage->name);
00624         Globals_p += sprintf( Globals_p, "extern bool &%s_stall;\n", pstage->name);
00625       }         
00626     for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
00627       if( pstage->next ){
00628         fprintf( output, "%sstatic bool %s_flush;\n", INDENT[1], pstage->name);
00629         Globals_p += sprintf( Globals_p, "extern bool &%s_flush;\n", pstage->name);
00630       }         
00631 
00632   }else if(pipe_list){
00633         
00634     for( ppipe = pipe_list; ppipe!=NULL; ppipe= ppipe->next ){
00635 
00636       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next)
00637         if( pstage->next ){
00638           fprintf( output, "%sstatic bool %s_%s_stall;\n", INDENT[1], ppipe->name, pstage->name);
00639           Globals_p += sprintf( Globals_p, "extern bool &%s_%s_stall;\n", ppipe->name, pstage->name);
00640         }               
00641                         
00642       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next)
00643         if( pstage->next ){
00644           fprintf( output, "%sstatic bool %s_%s_flush;\n", INDENT[1], ppipe->name, pstage->name);
00645           Globals_p += sprintf( Globals_p, "extern bool &%s_%s_flush;\n", ppipe->name, pstage->name);
00646         }               
00647 
00648     }
00649   } 
00650 
00651   //It is the wait signal to keep processor sleeping while awaiting for data coming from  caches, mems, or buses.
00652   fprintf( output, "%sstatic bool ac_wait_sig;\n", INDENT[1]);
00653   Globals_p += sprintf( Globals_p, "extern bool &ac_wait_sig;\n");
00654 
00655   //It is the parallel signal. It is used to tell the simulator that the next instruction should be executed in parallel with the current one.
00656   fprintf( output, "%sstatic bool ac_parallel_sig;\n", INDENT[1]);
00657 
00658   //There is no annul signal to pipelined archs. They use flush.
00659   if( !stage_list && !pipe_list ){
00660     //It is the annul signal. It is used to cancel the execution of an instruction already fetched.
00661     fprintf( output, "%sstatic bool ac_annul_sig;\n", INDENT[1]);
00662     Globals_p += sprintf( Globals_p, "extern bool &ac_annul_sig;\n");
00663   }
00664 
00665   //The endianness of the target arch
00666   fprintf( output, "%sstatic bool ac_tgt_endian;\n", INDENT[1]);
00667   Globals_p += sprintf( Globals_p, "extern bool &ac_tgt_endian;\n");
00668 
00669   //The cycle control variable. Only available for multi-cycle archs
00670   if(HaveMultiCycleIns) 
00671     fprintf( output, "%sstatic unsigned ac_cycle;\n", INDENT[1]);
00672 
00673   //The archc pc variable
00674   //  fprintf( output, "%sstatic unsigned ac_pc;\n", INDENT[1]);
00675   fprintf( output, "%sstatic ac_reg<unsigned> ac_pc;\n", INDENT[1]);
00676   Globals_p += sprintf( Globals_p, "extern ac_reg<unsigned> &ac_pc;\n");
00677 
00678   //The initial address to be fetched.
00679   fprintf( output, "%sstatic unsigned ac_start_addr;\n", INDENT[1]);
00680   Globals_p += sprintf( Globals_p, "extern unsigned &ac_start_addr;\n");
00681 
00682   //The running instruction counter
00683   fprintf( output, "%sstatic unsigned long long ac_instr_counter;\n", INDENT[1]);
00684   Globals_p += sprintf( Globals_p, "extern unsigned long long &ac_instr_counter;\n");
00685 
00686   //ArchC Internal Simulation cycle counter
00687   fprintf( output, "%sstatic unsigned long long ac_cycle_counter;\n", INDENT[1]);
00688   Globals_p += sprintf( Globals_p, "extern unsigned long long &ac_cycle_counter;\n");
00689 
00690   //Time increasing step
00691   fprintf( output, "%sstatic double time_step;\n", INDENT[1]);
00692 
00693   //Command-line arguments to be passed to the running application
00694   fprintf( output, "%sstatic int argc;\n", INDENT[1]);
00695   fprintf( output, "%sstatic char **argv;\n", INDENT[1]);
00696 
00697   //Disassembler file
00698   if( ACDasmFlag )
00699     fprintf( output, "%sstatic ofstream dasmfile;\n", INDENT[1]);
00700 
00701   fprintf( output, " \n");
00702   fprintf( output, "\n");
00703 
00704   //ac_resources constructor declaration
00705   COMMENT(INDENT[1],"Constructor.");
00706   fprintf( output, "%sac_resources();\n", INDENT[1]);
00707       
00708   fprintf( output, " \n");
00709 
00710   COMMENT(INDENT[1],"Initializing program arguments.");
00711   fprintf( output, "%sstatic void set_args( int ac, char **av){\n", INDENT[1]);
00712   fprintf( output, "%sargc = ac;\n", INDENT[2]);
00713   fprintf( output, "%sargv = av;\n", INDENT[2]);
00714   fprintf( output, "%s\n",  INDENT[1]);
00715   fprintf( output, "%s};\n", INDENT[1]);
00716   
00717   fprintf( output, " \n");
00718 
00719   if( ACDelayFlag ) {
00720     COMMENT(INDENT[1],"Delayed Assignment.");
00721     fprintf( output, "%sstatic change_log delay( ac_word value, unsigned clocks){\n", INDENT[1]);
00722     fprintf( output, "%sreturn change_log( 0, value, clocks + ac_cycle_counter );\n", INDENT[2]);
00723     fprintf( output, "%s};\n", INDENT[1]);
00724     fprintf( output, "\n");
00725   }
00726 
00727 
00728   COMMENT(INDENT[1],"Stall method.");
00729   //We have different methods for pipelined and non-pipelined archs
00730   if(stage_list){
00731     fprintf( output, "%sstatic void ac_stall( char *stage ){\n", INDENT[1]);
00732                 
00733     for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
00734       if( pstage->next ){
00735         if( pstage->id ==1 )
00736           fprintf( output, "%sif( !strcmp( \"%s\", stage ) )\n", INDENT[2], pstage->name);
00737         else
00738           fprintf( output, "%selse if( !strcmp( \"%s\", stage ) )\n", INDENT[2], pstage->name);
00739                                 
00740         fprintf( output, "%s%s_stall = 1;\n", INDENT[3], pstage->name);
00741       }
00742     fprintf( output, "%s};\n", INDENT[1]);
00743   }
00744   else  if(pipe_list){
00745         
00746     fprintf( output, "%sstatic void ac_stall( char *stage ){\n", INDENT[1]);
00747     for( ppipe = pipe_list; ppipe!=NULL; ppipe= ppipe->next ){
00748                         
00749       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next)
00750         if( pstage->next ){
00751           if( pstage->id ==1 )
00752             fprintf( output, "%sif( !strcmp( \"%s_%s\", stage ) )\n", INDENT[2], ppipe->name, pstage->name);
00753           else
00754             fprintf( output, "%selse if( !strcmp( \"%s_%s\", stage ) )\n", INDENT[2], ppipe->name, pstage->name);
00755           fprintf( output, "%s%s_%s_stall = 1;\n", INDENT[3], ppipe->name, pstage->name);
00756         }
00757     }
00758     fprintf( output, "%s};\n", INDENT[1]);
00759   }
00760 
00761   //Wait Method
00762   COMMENT(INDENT[1],"Put the simulator on the wait state.");
00763   fprintf( output, "%sstatic void ac_wait(){\n", INDENT[1]);
00764   fprintf( output, "%sac_wait_sig = 1;\n", INDENT[2]);
00765   fprintf( output, "%s};\n", INDENT[1]);
00766   fprintf( output, "\n");
00767 
00768   //Release Method
00769   COMMENT(INDENT[1],"Release the simulator from the wait state.");
00770   fprintf( output, "%sstatic void ac_release(){\n", INDENT[1]);
00771   fprintf( output, "%sac_wait_sig = 0;\n", INDENT[2]);
00772 
00773   fprintf( output, "%s};\n", INDENT[1]);
00774   fprintf( output, "\n");
00775 
00776   //Annulation Method
00777   //There is no annul signal to pipelined archs. They use flush.
00778   if( !stage_list && !pipe_list ){
00779     COMMENT(INDENT[1],"Annul the current instruction.");
00780     fprintf( output, "%sstatic void ac_annul(){\n", INDENT[1]);
00781     fprintf( output, "%sac_annul_sig = 1;\n", INDENT[2]);
00782     fprintf( output, "%s};\n", INDENT[1]);
00783   }
00784   fprintf( output, "\n");
00785 
00786   //TODO: COlocar como opcao de linha de comando
00787   //ILP method
00788   COMMENT(INDENT[1],"Force Paralelism.");
00789   fprintf( output, "%sstatic void ac_parallel( ){\n", INDENT[1]);
00790   fprintf( output, "%sac_parallel_sig = 1;\n", INDENT[2]);
00791   fprintf( output, "%s};\n", INDENT[1]);
00792   fprintf( output, "\n");
00793       
00794   COMMENT(INDENT[1],"Flush method.");
00795   fprintf( output, "%sstatic void ac_flush( char *stage ){\n", INDENT[1]);
00796 
00797   for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
00798     if( pstage->next ){
00799       if( pstage->id ==1 )
00800         fprintf( output, "%sif( !strcmp( \"%s\", stage ) )\n", INDENT[2], pstage->name);
00801       else
00802         fprintf( output, "%selse if( !strcmp( \"%s\", stage ) )\n", INDENT[2], pstage->name);
00803 
00804       fprintf( output, "%s%s_flush = 1;\n", INDENT[3], pstage->name);
00805     }
00806 
00807   fprintf( output, "%s};\n", INDENT[1]); //end of flush method
00808 
00809   if(ACVerifyFlag){
00810     COMMENT(INDENT[1],"Set co-verification msg queue.");
00811     fprintf( output, "%sstatic void set_queue(char *exec_name);\n", INDENT[1]);
00812         }
00813 
00814   fprintf( output, "};\n\n"); //End of ac_resources class
00815 
00816   
00817   COMMENT(INDENT[0],"Global aliases for resources.");
00818   fprintf( output, "%s\n", Globals);
00819 
00820   fprintf( output, "#endif  //_AC_RESOURCES_H\n");
00821   fclose( output); 
00822 
00823 }
00824 
00826 void CreateTypeHeader() {
00827 
00828 
00829   FILE *output;
00830   char filename[] = "ac_types.H";
00831 
00832   if ( !(output = fopen( filename, "w"))){
00833     perror("ArchC could not open output file");
00834     exit(1);
00835   }
00836 
00837 
00838   print_comment( output, "ArchC Types header file.");
00839   fprintf( output, "#ifndef  _AC_TYPES_H\n");
00840   fprintf( output, "#define  _AC_TYPES_H\n\n");
00841   
00842   fprintf( output, "#include  <systemc.h>\n");
00843   fprintf( output, "#include  \"ac_storage.H\"\n");
00844   fprintf( output, "#include  \"ac_resources.H\"\n");
00845   fprintf( output, "#include  \"archc.H\"\n\n");
00846 
00847   //Declaring abstract stage class.
00848   COMMENT(INDENT[0],"ArchC abstract class for pipeline stages.\n");
00849   fprintf( output, "class ac_stage: public sc_module, public ac_resources {\n");
00850   fprintf( output, "public:\n");
00851   fprintf( output, "%svirtual void behavior(){};\n", INDENT[1]);
00852   fprintf( output, "%sSC_CTOR( ac_stage ){};\n", INDENT[1]);
00853   fprintf( output, "};\n\n");
00854 
00855   //Declaring abstract instruction class.
00856   EmitGenInstrClass( output );
00857 /*   COMMENT(INDENT[0],"ArchC abstract class for instructions.\n"); */
00858 /*   fprintf( output, "class ac_instruction: public ac_resources {\n"); */
00859 /*   fprintf( output, "protected:\n"); */
00860 /*   fprintf( output, "%schar* ac_instr_name;\n", INDENT[1]); */
00861 /*   fprintf( output, "%schar* ac_instr_mnemonic;\n", INDENT[1]); */
00862 /*   fprintf( output, "%sunsigned ac_instr_size;\n", INDENT[1]); */
00863 /*   fprintf( output, "%sunsigned ac_instr_cycles;\n", INDENT[1]); */
00864 /*   fprintf( output, "%sunsigned ac_instr_min_latency;\n", INDENT[1]); */
00865 /*   fprintf( output, "%sunsigned ac_instr_max_latency;\n", INDENT[1]); */
00866 /*   fprintf( output, "public:\n"); */
00867 
00868 /*   fprintf( output, "%sac_instruction( char* name, char* mnemonic, unsigned min, unsigned max ){ ac_instr_name = name ; ac_instr_mnemonic = mnemonic; ac_instr_min_latency = min, ac_instr_max_latency =max;}\n", INDENT[1]); */
00869 /*   fprintf( output, "%sac_instruction( char* name, char* mnemonic ){ ac_instr_name = name ; ac_instr_mnemonic = mnemonic;}\n", INDENT[1]); */
00870 /*   fprintf( output, "%sac_instruction( char* name ){ ac_instr_name = name ;}\n", INDENT[1]); */
00871 /*   fprintf( output, "%sac_instruction( ){ ac_instr_name = \"NULL\";}\n", INDENT[1]); */
00872 
00873 /*   fprintf( output, "%svirtual void behavior(ac_stage_list  stage = (ac_stage_list)0, unsigned cycle=0);\n", INDENT[1]);    */
00874 /*   fprintf( output, "%svirtual void set_fields( ac_instr instr){};\n", INDENT[1]); */
00875 
00876 /*   fprintf( output, "%svoid set_cycles( unsigned c){ ac_instr_cycles = c;}\n", INDENT[1]); */
00877 /*   fprintf( output, "%sunsigned get_cycles(){ return ac_instr_cycles;}\n", INDENT[1]); */
00878 
00879 /*   fprintf( output, "%svoid set_min_latency( unsigned c){ ac_instr_min_latency = c;}\n", INDENT[1]); */
00880 /*   fprintf( output, "%sunsigned get_min_latency(){ return ac_instr_min_latency;}\n", INDENT[1]); */
00881 
00882 /*   fprintf( output, "%svoid set_max_latency( unsigned c){ ac_instr_max_latency = c;}\n", INDENT[1]); */
00883 /*   fprintf( output, "%sunsigned get_max_latency(){ return ac_instr_max_latency;}\n", INDENT[1]); */
00884 
00885 /*   fprintf( output, "%sunsigned get_size() {return ac_instr_size;}\n", INDENT[1]); */
00886 /*   fprintf( output, "%svoid set_size( unsigned s) {ac_instr_size = s;}\n", INDENT[1]); */
00887 
00888 /*   fprintf( output, "%schar* get_name() {return ac_instr_name;}\n", INDENT[1]); */
00889 /*   fprintf( output, "%svoid set_name( char* name) {ac_instr_name = name;}\n", INDENT[1]); */
00890 
00891 /*   fprintf( output, "%svirtual  void print (ostream & os) const{};\n", INDENT[1]); */
00892 
00893 /*   fprintf( output, "%sfriend ostream& operator<< (ostream &os,const ac_instruction &ins){\n", INDENT[1]); */
00894 /*   fprintf( output, "%sins.print(os);\n", INDENT[1]); */
00895 /*   fprintf( output, "%sreturn os;\n", INDENT[1]); */
00896 /*   fprintf( output, "%s};\n", INDENT[1]); */
00897 
00898 /*   fprintf( output, "};\n\n"); */
00899   
00900   EmitFormatClasses( output );
00901   EmitInstrClasses(output ); 
00902 
00903   fprintf( output, "\n\n");
00904   fprintf( output, "#endif  //_AC_TYPES_H\n");
00905   fclose( output); 
00906 
00907 }
00908 
00910 void CreateParmHeader() {
00911 
00912   extern ac_stg_list *stage_list;
00913   extern ac_pipe_list *pipe_list;
00914   extern ac_dec_format *format_ins_list;
00915   extern int instr_num;
00916   extern int declist_num;
00917   extern int format_num, largest_format_size;
00918   extern int wordsize, fetchsize, HaveMemHier, HaveCycleRange;
00919   extern ac_sto_list* load_device;
00920 
00921   extern ac_decoder_full *decoder;
00922   ac_stg_list *pstage;
00923   ac_pipe_list *ppipe;
00924 
00925   
00927   FILE *output;
00928 
00929   if ( !(output = fopen( "ac_parms.H", "w"))){
00930     perror("ArchC could not open output file");
00931     exit(1);
00932   }
00933 
00934   print_comment( output, "ArchC Parameters header file.");
00935   fprintf( output, "#ifndef  _AC_PARMS_H\n");
00936   fprintf( output, "#define  _AC_PARMS_H\n");
00937 
00938   fprintf( output, "\nusing namespace std;\n");
00939 
00940   fprintf( output, "\n#define AC_DEC_FIELD_NUMBER %d \t //!< Number of Fields used by decoder.\n", decoder->nFields);
00941   fprintf( output, "#define AC_DEC_INSTR_NUMBER %d \t //!< Number of Instructions declared.\n", instr_num);
00942   fprintf( output, "#define AC_DEC_FORMAT_NUMBER %d \t //!< Number of Formats declared.\n", format_num);
00943   fprintf( output, "#define AC_DEC_LIST_NUMBER %d \t //!< Number of decodification lists used by decoder.\n", declist_num);
00944   fprintf( output, "#define AC_MAX_BUFFER %d \t //!< This is the size needed by decoder buffer. It is equal to the biggest instruction size.\n", largest_format_size/8);
00945   fprintf( output, "#define AC_WORDSIZE %d \t //!< Architecture wordsize in bits.\n", wordsize);
00946   fprintf( output, "#define AC_FETCHSIZE %d \t //!< Architecture fetchsize in bits.\n", fetchsize);
00947   fprintf( output, "#define AC_MATCH_ENDIAN %d \t //!< If the simulated arch match the endian with host.\n", ac_match_endian);
00948   fprintf( output, "const unsigned int AC_RAMSIZE=%u; \t //!< Architecture RAM size in bytes (storage %s).\n", load_device->size, load_device->name);
00949   fprintf( output, "const unsigned int AC_RAM_END=%u; \t //!< Architecture end of RAM (storage %s).\n", load_device->size, load_device->name);
00950 
00951 
00952   if( ACVerboseFlag || ACVerifyFlag )
00953     fprintf( output, "#define  AC_UPDATE_LOG \t //!< Update log generation turned on.\n");
00954 
00955   if( ACVerboseFlag )
00956     fprintf( output, "#define  AC_VERBOSE \t //!< Indicates Verbose mode. Where update logs are dumped on screen.\n");
00957 
00958   if( ACVerifyFlag )
00959     fprintf( output, "#define  AC_VERIFY \t //!< Indicates that co-verification is turned on.\n");
00960       
00961   if( ACStatsFlag )
00962     fprintf( output, "#define  AC_STATS \t //!< Indicates that statistics collection is turned on.\n");
00963       
00964 
00965   if( ACDasmFlag )
00966     fprintf( output, "#define  AC_DISASSEMBLER \t //!< Indicates that disassembler option is turned on.\n\n");
00967 
00968   if( ACDebugFlag )
00969     fprintf( output, "#define  AC_DEBUG \t //!< Indicates that debug option is turned on.\n\n");
00970 
00971   if( ACDelayFlag )
00972     fprintf( output, "#define  AC_DELAY \t //!< Indicates that delay option is turned on.\n\n");
00973 
00974   if( HaveMemHier )
00975     fprintf( output, "#define  AC_MEM_HIERARCHY \t //!< Indicates that a memory hierarchy was declared.\n\n");
00976 
00977   if( HaveCycleRange )
00978     fprintf( output, "#define  AC_CYCLE_RANGE \t //!< Indicates that cycle range for instructions were declared.\n\n");
00979 
00980   fprintf( output, "\n\n");
00981   COMMENT(INDENT[0],"Word type definitions.");
00982     
00983   //Emiting ArchC word types.
00984   switch( wordsize ){
00985   case 8:
00986     fprintf( output, "typedef  unsigned char ac_word; \t //!< Unsigned word.\n");
00987     fprintf( output, "typedef  unsigned char ac_Uword; \t //!< Unsigned word.\n");
00988     fprintf( output, "typedef  char ac_Sword; \t //!< Signed word.\n");
00989     fprintf( output, "typedef  unsigned char ac_Hword; \t //!< Signed half word.\n");
00990     fprintf( output, "typedef  unsigned char ac_UHword; \t //!< Unsigned half word.\n");
00991     fprintf( output, "typedef  char ac_SHword; \t //!< Signed half word.\n");
00992     fprintf( output, "typedef  unsigned short ac_Dword; \t //!< Signed double word.\n");
00993     fprintf( output, "typedef  unsigned short ac_UDword; \t //!< Unsigned double word.\n");
00994     fprintf( output, "typedef  short ac_SDword; \t //!< Signed double word.\n");
00995     break;
00996   case 16:
00997     fprintf( output, "typedef  unsigned short int ac_word; \t //!< Unsigned word.\n");
00998     fprintf( output, "typedef  unsigned short int ac_Uword; \t //!< Unsigned word.\n");
00999     fprintf( output, "typedef  short int ac_Sword; \t //!< Signed word.\n");
01000     fprintf( output, "typedef  unsigned char ac_Hword; \t //!< Signed half word.\n");
01001     fprintf( output, "typedef  unsigned char ac_UHword; \t //!< Unsigned half word.\n");
01002     fprintf( output, "typedef  char ac_SHword; \t //!< Signed half word.\n");
01003     fprintf( output, "typedef  unsigned int ac_Dword; \t //!< Signed double word.\n");
01004     fprintf( output, "typedef  unsigned int ac_UDword; \t //!< Unsigned double word.\n");
01005     fprintf( output, "typedef  int ac_SDword; \t //!< Signed double word.\n");
01006     break;
01007   case 32:
01008     fprintf( output, "typedef  unsigned int ac_word; \t //!< Unsigned word.\n");
01009     fprintf( output, "typedef  unsigned int ac_Uword; \t //!< Unsigned word.\n");
01010     fprintf( output, "typedef  int ac_Sword; \t //!< Signed word.\n");
01011     fprintf( output, "typedef  short int ac_SHword; \t //!< Signed half word.\n");
01012     fprintf( output, "typedef  unsigned short int  ac_UHword; \t //!< Unsigned half word.\n");
01013     fprintf( output, "typedef  unsigned short int  ac_Hword; \t //!< Unsigned half word.\n");
01014     fprintf( output, "typedef  unsigned long long ac_Dword; \t //!< Signed double word.\n");
01015     fprintf( output, "typedef  unsigned long long ac_UDword; \t //!< Unsigned double word.\n");
01016     fprintf( output, "typedef  long long ac_SDword; \t //!< Signed double word.\n");
01017     break;
01018   case 64:
01019     fprintf( output, "typedef  unsigned long long ac_word; \t //!< Unsigned word.\n");
01020     fprintf( output, "typedef  unsigned long long ac_Uword; \t //!< Unsigned word.\n");
01021     fprintf( output, "typedef  long long ac_Sword; \t //!< Signed word.\n");
01022     fprintf( output, "typedef  int ac_SHword; \t //!< Signed half word.\n");
01023     fprintf( output, "typedef  unsigned int  ac_UHword; \t //!< Unsigned half word.\n");
01024     fprintf( output, "typedef  unsigned int  ac_UHword; \t //!< Unsigned half word.\n");
01025     break;
01026   default:
01027     AC_ERROR("Wordsize not supported: %d\n", wordsize);
01028     break;
01029   }
01030       
01031   fprintf( output, "typedef  char ac_byte; \t //!< Signed byte word.\n");
01032   fprintf( output, "typedef  unsigned char ac_Ubyte; \t //!< Unsigned byte word.\n");
01033 
01034   fprintf( output, "\n\n");
01035   COMMENT(INDENT[0],"Fetch type definition.");
01036 
01037   switch( fetchsize ){
01038   case 8:
01039     fprintf( output, "typedef  unsigned char ac_fetch; \t //!< Unsigned word.\n");
01040     break;
01041   case 16:
01042     fprintf( output, "typedef  unsigned short int ac_fetch; \t //!< Unsigned word.\n");
01043     break;
01044   case 32:
01045     fprintf( output, "typedef  unsigned int ac_fetch; \t //!< Unsigned word.\n");
01046     break;
01047   case 64:
01048     fprintf( output, "typedef  unsigned long long ac_fetch; \t //!< Unsigned word.\n");
01049     break;
01050   default:
01051     AC_ERROR("Fetchsize not supported: %d\n", fetchsize);
01052     break;
01053   }
01054 
01055 
01056   fprintf( output, "\n\n");
01057 
01058   //This enum type is used for case identification inside the ac_behavior methods
01059   fprintf( output, "enum ac_stage_list {");
01060 
01061   if( stage_list ){   //Enum type for pipes declared through ac_stage keyword
01062     fprintf( output, "%s=1,", stage_list->name);
01063     pstage = stage_list->next;
01064     for( pstage = stage_list->next; pstage && pstage->next != NULL; pstage=pstage->next){
01065       fprintf( output, "%s,", pstage->name);
01066     }
01067     fprintf( output, "%s", pstage->name);
01068   }
01069   else if(pipe_list){  //Enum type for pipes declared through ac_pipe keyword
01070 
01071     for(ppipe = pipe_list; ppipe!= NULL; ppipe=ppipe->next){
01072 
01073       for(pstage=ppipe->stages; pstage && pstage->next!= NULL; pstage=pstage->next){
01074 
01075         //When we have just one pipe use only the stage name
01076         if( ppipe->next )
01077           fprintf( output, "%s_%s=%d,", ppipe->name, pstage->name, pstage->id);
01078         else
01079           fprintf( output, "%s=%d,", pstage->name, pstage->id);
01080 
01081       }
01082       if( ppipe->next )
01083         fprintf( output, "%s_%s=%d", ppipe->name, pstage->name, pstage->id);  //The last doesn't need a comma
01084       else
01085         fprintf( output, "%s=%d", pstage->name, pstage->id);
01086     }
01087   }
01088   else{
01089     fprintf( output, "ST0");
01090   }
01091 
01092   //Closing enum declaration
01093   fprintf( output, "};\n\n");
01094     
01095     
01096   fprintf( output, "\n\n");
01097   fprintf( output, "#endif  //_AC_PARMS_H\n");
01098 
01099   fclose(output);
01100 }
01101 
01102 
01104 void CreateISAHeader() {
01105 
01106   extern ac_dec_format *format_ins_list;
01107   extern char *project_name;
01108   extern ac_dec_instr *instr_list;
01109   extern int HaveMultiCycleIns;
01110   ac_dec_format *pformat;
01111   ac_dec_instr *pinstr;
01112 
01113   char filename[256];
01114   char description[] = "Instruction Set Architecture header file.";
01115  
01116   // File containing ISA declaration
01117   FILE  *output;
01118 
01119   sprintf( filename, "%s-isa.H", project_name);
01120 
01121   if ( !(output = fopen( filename, "w"))){
01122     perror("ArchC could not open output file");
01123     exit(1);
01124   }
01125 
01126   print_comment( output, description);
01127   fprintf( output, "#ifndef _ISA_H\n");
01128   fprintf( output, "#define _ISA_H\n\n");
01129   fprintf( output, "#include \"ac_decoder.h\"\n");
01130   fprintf( output, "#include \"ac_parms.H\"\n");
01131   fprintf( output, "#include \"ac_types.H\"\n\n");
01132   fprintf( output, "#include \"ac_resources.H\"\n");
01133   fprintf( output, "\n\n");
01134 
01135   fprintf( output, "#define ac_behavior( c )   ac_##c::behavior( ac_stage_list stage, unsigned cycle )\n\n");
01136 
01137   fprintf( output, "class %s_isa: public ac_resources{\n\n", project_name);
01138   fprintf( output, "public:\n");
01139 
01140   //Declaring the generic instruction object.
01141   fprintf( output, "%sstatic ac_instruction instruction;\n",INDENT[1]); 
01142 
01143   //Declaring each format object.
01144   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next)
01145     fprintf( output, "%sstatic ac_%s %s;\n", INDENT[1], pformat->name, pformat->name); 
01146 
01147   //Declaring each instruction.
01148   for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next)
01149     fprintf( output, "%sstatic ac_%s %s;\n", INDENT[1], pinstr->name, pinstr->name); 
01150 
01151   fprintf( output, " \n");
01152   fprintf( output, "%sac_decoder_full *decoder;\n", INDENT[1]);
01153 
01154   /* We will need one extra row in the following table because
01155      ID = 0 is reserved for nop in behavioral ArchC.
01156   */
01157   fprintf( output, "%sint instr_table[AC_DEC_INSTR_NUMBER+1][3];\n\n", INDENT[1]);
01158 
01159   //Emiting Constructor.
01160   fprintf( output,"\n");
01161   COMMENT(INDENT[1], "Constructor.\n");
01162   fprintf( output,"%s%s_isa(){\n\n", INDENT[1],project_name);
01163 
01164   if( ACStatsFlag ){
01165     fprintf( output, "%sint i;\n", INDENT[1]);
01166     fprintf( output,"\n");
01167   }
01168 
01169   COMMENT(INDENT[2], "Decoding structures.");
01170   EmitDecStruct(output);
01171   COMMENT(INDENT[2], "Building Decoder.");
01172   fprintf( output,"%sdecoder = CreateDecoder(formats, instructions);\n", INDENT[2] );
01173 
01174 #ifdef ADD_DEBUG
01175   fprintf( output,"\n#ifdef AC_DEBUG_DECODER\n" );
01176   fprintf( output,"      ShowDecFormat(formats);\n" );
01177   fprintf( output,"      ShowDecoder(decoder -> decoder, 0);\n" );
01178   fprintf( output,"#endif \n" );
01179 #endif
01180 
01181   if( instr_list ){
01182     COMMENT(INDENT[2], "Initializing Instruction table.\n");
01183     fprintf( output, "%sinstr_table[0][0] = 0;\n", INDENT[2]);
01184     fprintf( output, "%sinstr_table[0][1] = 0;\n", INDENT[2]);
01185     fprintf( output, "%sinstr_table[0][2] = 0;\n", INDENT[2]);
01186     
01187                      
01188     for(pinstr = instr_list; pinstr != NULL; pinstr = pinstr->next ){
01189       fprintf( output, "%sinstr_table[%d][0] = %d;\n", INDENT[2], pinstr->id, pinstr->id);
01190       fprintf( output, "%sinstr_table[%d][1] = (int)&%s;\n",INDENT[2], pinstr->id, pinstr->name);           
01191       fprintf( output, "%sinstr_table[%d][2] = (int)&%s;\n",INDENT[2], pinstr->id, pinstr->format);  
01192       if( HaveMultiCycleIns)
01193         fprintf( output,"%s((ac_instruction*)instr_table[%d][1])->set_cycles( instructions[%d-1].cycles );\n\n",INDENT[2], pinstr->id, pinstr->id);           
01194     }
01195 
01196     if( ACStatsFlag ){
01197       COMMENT(INDENT[2], "Initializing Instruction Statistics table.\n");
01198       fprintf( output, "%sfor( i = 0; i<= AC_DEC_INSTR_NUMBER; i++)\n", INDENT[2] );
01199       fprintf( output, "%sac_sim_stats.instr_table[i][1] = instr_table[i][1];\n", INDENT[3]);
01200     }
01201   }     
01202   fprintf( output,"%s}\n", INDENT[1] );
01203 
01204   /* Closing class declaration. */
01205   fprintf( output,"};\n" );
01206   fprintf( output, "#endif //_ISA_H\n\n");
01207 
01208   fclose( output); 
01209 
01210 }
01211 
01213 void CreateARCHHeader() {
01214 
01215   extern ac_stg_list *stage_list;
01216   extern ac_pipe_list *pipe_list;
01217   extern char *project_name;
01218   extern int stage_num;
01219   extern int HaveMultiCycleIns;
01220   ac_stg_list *pstage;
01221   ac_pipe_list *ppipe;
01222   int i;
01223   char filename[256];
01224   char description[] = "Architecture Module header file.";
01225   
01226   // File containing ISA declaration
01227   FILE  *output;
01228   
01229   sprintf( filename, "%s-arch.H", project_name);
01230 
01231   if ( !(output = fopen( filename, "w"))){
01232     perror("ArchC could not open output file");
01233     exit(1);
01234   }
01235   
01236   print_comment( output, description);
01237   
01238   
01239   fprintf( output, "#ifndef  _ARCH_H\n");
01240   fprintf( output, "#define  _ARCH_H\n\n");
01241   
01242   fprintf( output, "#include \"systemc.h\"\n");
01243   fprintf( output, "#include \"archc.H\"\n");
01244   fprintf( output, "#include \"ac_storage.H\"\n");
01245   fprintf( output, "#include \"ac_resources.H\"\n");
01246   
01247   if( stage_list ){
01248     for( pstage = stage_list; pstage != NULL; pstage=pstage->next)      
01249       fprintf( output, "#include \"%s.H\"\n", pstage->name);
01250   }
01251   else if( pipe_list ){  //Pipeline list exist. Used for ac_pipe declarations.
01252                         
01253     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
01254 
01255       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next)      
01256         fprintf( output, "#include \"%s_%s.H\"\n", ppipe->name, pstage->name);
01257     }
01258   }
01259   else {
01260     fprintf( output, "#include \"%s.H\"\n", project_name);
01261   }
01262 
01263   fprintf( output, " \n\n");
01264   
01265   fprintf( output, "class %s_arch: public sc_module, public ac_resources{\n",project_name);
01266   fprintf( output, "public:\n\n");
01267   
01268   fprintf( output, "%ssc_in<bool> clock;\n", INDENT[1]);
01269   fprintf( output, "%ssc_signal<unsigned> bhv_pc;\n", INDENT[1]);
01270 
01271   if( HaveMultiCycleIns)
01272     fprintf( output, "%ssc_signal<unsigned> bhv_cycle;\n", INDENT[1]);
01273   
01274   fprintf( output, " \n");
01275   
01276   fprintf( output, "%ssc_signal<bool> do_it;\n", INDENT[1]);
01277 
01278   if( stage_list ){
01279     for( i =1; i<=stage_num; i++)     
01280       fprintf( output, "%ssc_signal<bool> st%d_done;\n", INDENT[1], i);
01281   }
01282   else if( pipe_list ){  //Pipeline list exist. Used for ac_pipe declarations.
01283                         
01284     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
01285                         
01286       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next){
01287         fprintf( output, "%ssc_signal<bool> %s_%s_done;\n", INDENT[1], ppipe->name, pstage->name);
01288       }
01289     }
01290   }
01291   else{
01292     fprintf( output, "%ssc_signal<bool> done;\n\n", INDENT[1]);
01293     fprintf( output, "%sdouble last_clock;\n", INDENT[1]);
01294   }
01295   
01296   fprintf( output, " \n");
01297   
01298   COMMENT(INDENT[1], "Verification method.\n");
01299   fprintf( output, "%svoid ac_verify();\n", INDENT[1]);
01300   fprintf( output, " \n");
01301   
01302   COMMENT(INDENT[1], "Updating Pipe Regs for behavioral simulation.\n");
01303   fprintf( output, "%svoid ac_update_regs();\n", INDENT[1]);
01304   
01305   fprintf( output, " \n");
01306   
01308   if( stage_list ){
01309     COMMENT(INDENT[1],"Stage declarations.\n");
01310     for(pstage = stage_list; pstage != NULL; pstage = pstage->next){
01311       
01312       /* Emit stage module and its in/out signal declarations. */
01313       fprintf( output, "%sAC_%s::%s *%s_stage;\n", INDENT[1],pstage->name,pstage->name,pstage->name);
01314       if( pstage->id != 1 )
01315         fprintf( output, "%ssc_signal<ac_instr> %s_regin;\n", INDENT[1],pstage->name);
01316       if( pstage->id != stage_num ){
01317         fprintf( output, "%ssc_signal<ac_instr> %s_regout;\n", INDENT[1],pstage->name);
01318       }
01319       fprintf( output, " \n");
01320       
01321     }
01322   }
01323   else if( pipe_list ){  //Pipeline list exist. Used for ac_pipe declarations.
01324                         
01325     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
01326                         
01327       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next){
01328         /* Emit stage module and its in/out signal declarations. */
01329         fprintf( output, "%sAC_%s_%s::%s_%s *%s_%s_stage;\n", INDENT[1], ppipe->name,pstage->name, ppipe->name, pstage->name, ppipe->name,pstage->name);
01330         if( pstage->id != 1 )
01331           fprintf( output, "%ssc_signal<ac_instr> %s_%s_regin;\n", INDENT[1],ppipe->name, pstage->name);
01332         if( pstage->id != stage_num ){
01333           fprintf( output, "%ssc_signal<ac_instr> %s_%s_regout;\n", INDENT[1],ppipe->name,pstage->name);
01334         }
01335         fprintf( output, " \n");
01336       }
01337     }
01338   }
01339   else{
01340     COMMENT(INDENT[1],"Module declarations.\n");
01341     fprintf( output, "%s%s *%s_mc;\n", INDENT[1],project_name,project_name);
01342   }
01343 
01345   COMMENT(INDENT[1], "Constructor.\n");
01346   fprintf( output,"%sSC_CTOR(%s_arch){\n\n", INDENT[1], project_name);
01347   
01348   fprintf( output,"%sSC_METHOD( ac_verify );\n", INDENT[2]);
01349 
01350   if( stage_list ){
01351     fprintf( output,"%ssensitive ", INDENT[2]);
01352     for ( i =1; i<=stage_num;i++)
01353       fprintf( output,"<< st%d_done", i);
01354     fprintf( output,";\n");
01355 
01356   }else if(pipe_list){
01357     fprintf( output,"%ssensitive ", INDENT[2]);
01358     i=1;
01359 
01360     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
01361 
01362       for ( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next){
01363         fprintf( output,"<< %s_%s_done ", ppipe->name, pstage->name );
01364         i++;
01365       }
01366     }
01367     fprintf( output,";\n");
01368   }             
01369   else{
01370     fprintf( output, "%ssensitive<< done;\n", INDENT[2]);
01371   }
01372   
01373   
01374   fprintf( output, " \n");
01375   fprintf( output,"%sSC_METHOD( ac_update_regs );\n", INDENT[2]);
01376   fprintf( output,"%ssensitive_pos<< clock ; \n", INDENT[2]);
01377   fprintf( output,"%sdont_initialize(); \n\n", INDENT[2]);     
01378   
01379   fprintf( output,"%sbhv_pc = 0; \n", INDENT[2]);
01380   if( HaveMultiCycleIns)
01381     fprintf( output,"%sbhv_cycle = 0; \n", INDENT[2]);
01382   
01383   if( stage_list ){
01384     for( pstage = stage_list; pstage!= NULL; pstage = pstage->next ){
01385       
01386       fprintf( output,"%s%s_stage = new AC_%s::%s(\"%s\");\n", INDENT[2], pstage->name, pstage->name, pstage->name, pstage->name);
01387       fprintf( output,"%s%s_stage->bhv_pc( bhv_pc );\n", INDENT[2], pstage->name);
01388       if( pstage->id !=1)
01389         fprintf( output,"%s%s_stage->regin( %s_regin );\n", INDENT[2], pstage->name, pstage->name);
01390       if( pstage->id !=stage_num){
01391         fprintf( output,"%s%s_stage->regout( %s_regout );\n", INDENT[2], pstage->name, pstage->name);
01392         fprintf( output,"%s%s_stage->bhv_start( st%d_done );\n", INDENT[2], pstage->name, pstage->id+1);
01393       }
01394       fprintf( output,"%s%s_stage->bhv_done(st%d_done);\n", INDENT[2], pstage->name, pstage->id);
01395       
01396       fprintf( output, " \n");
01397     }               
01398   } else if(pipe_list){
01399 
01400     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
01401 
01402       for ( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next){
01403         fprintf( output,"%s%s_%s_stage = new AC_%s_%s::%s_%s(\"%s_%s\");\n", INDENT[2], ppipe->name, pstage->name, ppipe->name, pstage->name, ppipe->name, pstage->name, ppipe->name, pstage->name);
01404         fprintf( output,"%s%s_%s_stage->bhv_pc( bhv_pc );\n", INDENT[2], ppipe->name, pstage->name);
01405         if( pstage->id !=1)
01406           fprintf( output,"%s%s_%s_stage->regin( %s_%s_regin );\n", INDENT[2], ppipe->name, pstage->name, ppipe->name, pstage->name);
01407         if( pstage->id !=stage_num){
01408           fprintf( output,"%s%s_%s_stage->regout( %s_%s_regout );\n", INDENT[2], ppipe->name, pstage->name, ppipe->name, pstage->name);
01409           fprintf( output,"%s%s_%s_stage->bhv_start( %s_%s_done );\n", INDENT[2], ppipe->name, pstage->name, ppipe->name, pstage->next->name);
01410         }
01411         fprintf( output,"%s%s_%s_stage->bhv_done(%s_%s_done);\n", INDENT[2], ppipe->name, pstage->name, ppipe->name, pstage->name);
01412                                 
01413         fprintf( output, " \n");
01414       }
01415     }
01416   }
01417         
01418   else{
01419     fprintf( output,"%s%s_mc = new %s(\"%s\");\n", INDENT[2], project_name, project_name, project_name);
01420     fprintf( output,"%s%s_mc->bhv_pc( bhv_pc );\n", INDENT[2], project_name);
01421     if( HaveMultiCycleIns)
01422       fprintf( output,"%s%s_mc->bhv_cycle( bhv_cycle );\n", INDENT[2], project_name);
01423     fprintf( output,"%s%s_mc->do_it(do_it);\n", INDENT[2], project_name);
01424     fprintf( output,"%s%s_mc->bhv_done(done);\n", INDENT[2], project_name);
01425   }
01426   
01427   fprintf( output,"%s}\n", INDENT[1] );
01428   
01430   fprintf( output,"%s};\n", INDENT[0] );
01431   fprintf( output, "#endif  //_ARCH_H\n\n");
01432 
01433   fclose( output); 
01434   
01435 }
01436 
01437  
01439 void CreateStgHeader( ac_stg_list* stage_list, char* pipe_name) {
01440 
01441   extern char *project_name;
01442   extern int stage_num;
01443   ac_stg_list *pstage;
01444 
01445   char* stage_filename;
01446   FILE* output;
01447 
01448   for( pstage = stage_list; pstage != NULL; pstage=pstage->next){      
01449 
01450 
01451     //IF a ac_pipe declaration was used, stage module names will be PIPENAME_STAGENAME,
01452     //otherwise they will be just STAGENAME.
01453     //This makes possible to define multiple pipelines containg stages with the same name.
01454     if( pipe_name ){
01455       stage_filename = (char*) malloc(strlen(pstage->name)+strlen(pipe_name)+strlen(".H")+2);
01456       sprintf( stage_filename, "%s_%s.H", pipe_name, pstage->name);
01457     }
01458     else{
01459       stage_filename = (char*) malloc(strlen(pstage->name)+strlen(".H")+1);
01460       sprintf( stage_filename, "%s.H", pstage->name);
01461     }
01462 
01463     if ( !(output = fopen( stage_filename, "w"))){
01464       perror("ArchC could not open output file");
01465       exit(1);
01466     }
01467 
01468     print_comment( output, "Stage Module Header File.");
01469     if( pipe_name ){
01470       fprintf( output, "#ifndef  _%s_%s_STAGE_H\n", pipe_name, pstage->name);
01471       fprintf( output, "#define  _%s_%s_STAGE_H\n\n", pipe_name, pstage->name);
01472     }
01473     else{
01474       fprintf( output, "#ifndef  _%s_STAGE_H\n", pstage->name);
01475       fprintf( output, "#define  _%s_STAGE_H\n\n", pstage->name);
01476     }
01477 
01478     fprintf( output, "#include \"archc.H\"\n");
01479     fprintf( output, "#include \"%s-isa.H\"\n\n", project_name);
01480 
01481     if( pstage->id == 1 && ACDecCacheFlag )
01482       fprintf( output, "extern unsigned dec_cache_size;\n\n");
01483  
01484     //Declaring stage namespace.
01485     if( pipe_name ){
01486       fprintf( output, "namespace AC_%s_%s{\n\n", pipe_name, pstage->name); 
01487       fprintf( output, "class %s_%s: public ac_stage {\n", pipe_name, pstage->name);
01488     }
01489     else{
01490       fprintf( output, "namespace AC_%s{\n", pstage->name); 
01491       fprintf( output, "class %s: public ac_stage {\n", pstage->name);
01492     }
01493     //Declaring stage module. 
01494     //It already includes the behavior method.
01495     fprintf( output, "public:\n");
01496 
01497     if( pstage->id != 1 )
01498       fprintf( output, "%ssc_in<ac_instr> regin;\n", INDENT[1]);
01499     fprintf( output, "%ssc_inout<unsigned> bhv_pc;\n", INDENT[1]);
01500 
01501     if( pstage->id != stage_num ){
01502       fprintf( output, "%ssc_out<ac_instr> regout;\n", INDENT[1]);
01503       fprintf( output, "%ssc_out<bool> bhv_start;\n", INDENT[1]);
01504     }
01505 
01506     fprintf( output, "%ssc_out<bool> bhv_done;\n", INDENT[1]);
01507     fprintf( output, "%s%s_isa  ISA;\n", INDENT[1], project_name );
01508 
01509 
01510 
01511     fprintf( output, "%sbool start_up;\n", INDENT[1]);
01512     fprintf( output, "%sunsigned id;\n\n", INDENT[1]);
01513     fprintf( output, "%svoid behavior();\n\n", INDENT[1]);
01514 
01515     if(pstage->id==1 && ACDecCacheFlag){
01516       fprintf( output, "%scache_item* DEC_CACHE;\n\n", INDENT[1]);
01517     }
01518                 
01519     if( pipe_name ){
01520       fprintf( output, "%sSC_HAS_PROCESS( %s_%s );\n\n", INDENT[1], pipe_name, pstage->name);
01521       fprintf( output, "%s%s_%s( sc_module_name name_ ): ac_stage(name_){\n\n", INDENT[1], pipe_name, pstage->name);
01522     }
01523     else{
01524       fprintf( output, "%sSC_HAS_PROCESS( %s );\n\n", INDENT[1], pstage->name);
01525       fprintf( output, "%s%s( sc_module_name name_ ): ac_stage(name_){\n\n", INDENT[1], pstage->name);
01526     }
01527 
01528     //Declaring Constructor.
01529     fprintf( output, "%sSC_METHOD( behavior );\n", INDENT[2]);
01530     if( pstage->id != stage_num)
01531       fprintf( output, "%ssensitive_pos << bhv_start;\n", INDENT[2]);
01532     else
01533       fprintf( output, "%ssensitive << bhv_pc;\n", INDENT[2]);
01534 
01535     //We need this in order to not fetch the first instruction
01536     //during initialization.
01537     if( pstage->id == 1){
01538       fprintf( output, "%sdont_initialize();\n\n", INDENT[2]);
01539       fprintf( output, "%sstart_up=1;\n", INDENT[2]);
01540     }
01541     fprintf( output, "%sid = %d;\n\n", INDENT[2], pstage->id);
01542                 
01543     if( ACDasmFlag && pstage->id == 1)
01544       fprintf( output, "%sdasmfile.open(\"%s.dasm\");\n\n", INDENT[2], project_name);
01545     
01546     //end of constructor
01547     fprintf( output, "%s}\n", INDENT[1]); 
01548 
01549     if(pstage->id==1 && ACDecCacheFlag){
01550       fprintf( output, "%svoid init_dec_cache(){\n", INDENT[1]);  //end constructor
01551       fprintf( output, "%sDEC_CACHE = (cache_item*)calloc(sizeof(cache_item),dec_cache_size);\n", INDENT[2]);  //end constructor
01552       fprintf( output, "%s}\n", INDENT[1]);  //end init_dec_cache
01553     }
01554 
01555                 
01556     fprintf( output, "};\n");
01557 
01558     //End of namespace
01559     fprintf( output, "}\n"); 
01560 
01561     fprintf( output, "#endif \n");
01562     fclose(output);
01563     free(stage_filename);
01564   }
01565 }
01566 
01568 void CreateProcessorHeader() {
01569 
01570   extern char *project_name;
01571   extern int HaveMultiCycleIns;
01572 
01573   char* filename;
01574   FILE* output;
01575 
01576   filename = (char*) malloc(strlen(project_name)+strlen(".H")+1);
01577   sprintf( filename, "%s.H", project_name);
01578 
01579   if ( !(output = fopen( filename, "w"))){
01580     perror("ArchC could not open output file");
01581     exit(1);
01582   }
01583 
01584   print_comment( output, "Processor Module Header File.");
01585   fprintf( output, "#ifndef  _%s_H\n", project_name);
01586   fprintf( output, "#define  _%s_H\n\n", project_name);
01587   
01588   fprintf( output, "#include \"archc.H\"\n");
01589   fprintf( output, "#include \"ac_parms.H\"\n");
01590   fprintf( output, "#include \"%s-isa.H\"\n\n", project_name);
01591 
01592   if(ACGDBIntegrationFlag) {
01593     fprintf( output, "#include \"ac_gdb_interface.H\"\n");
01594     fprintf( output, "#include \"ac_gdb.H\"\n");
01595     fprintf( output, "extern AC_GDB *gdbstub;\n");
01596   }
01597   
01598   if(ACDecCacheFlag){
01599     fprintf( output, "extern unsigned dec_cache_size;\n\n");
01600   }
01603   fprintf( output, "class %s: public ac_stage%s {\n", project_name,
01604            (ACGDBIntegrationFlag) ? ", public AC_GDB_Interface" : "" );
01605   fprintf( output, "public:\n");
01606   
01607   fprintf( output, "%ssc_in<unsigned> bhv_pc;\n", INDENT[1]);
01608   if( HaveMultiCycleIns )
01609     fprintf( output, "%ssc_in<unsigned> bhv_cycle;\n", INDENT[1]);
01610   fprintf( output, "%ssc_in<bool> do_it;\n", INDENT[1]);
01611   fprintf( output, "%ssc_out<bool> bhv_done;\n", INDENT[1]);
01612   fprintf( output, "%s%s_isa  ISA;\n", INDENT[1], project_name );
01613   fprintf( output, "%sac_instruction *instr;\n", INDENT[1]);
01614   fprintf( output, "%sac_instruction *format;\n", INDENT[1]);
01615 
01616   if(ACDecCacheFlag){
01617     fprintf( output, "%scache_item* DEC_CACHE;\n\n", INDENT[1]);
01618   }
01619   fprintf( output, "%sunsigned id;\n\n", INDENT[1]);
01620   fprintf( output, "%sbool start_up;\n", INDENT[1]);
01621   fprintf( output, "%sunsigned *instr_dec;\n", INDENT[1]);
01622   fprintf( output, "%sac_instr *instr_vec;\n", INDENT[1]);
01623 
01624   fprintf( output, "%svoid behavior();\n\n", INDENT[1]);
01625   
01626   fprintf( output, "%sSC_HAS_PROCESS( %s );\n\n", INDENT[1], project_name);
01627   
01629   fprintf( output, "%s%s( sc_module_name name_ ): ac_stage(name_){\n\n", INDENT[1], project_name);
01630   fprintf( output, "%sSC_METHOD( behavior );\n", INDENT[2]);
01631   if( HaveMultiCycleIns ){
01632     fprintf( output, "%ssensitive << bhv_pc << bhv_cycle <<do_it;\n", INDENT[2]);
01633   }
01634   else
01635     fprintf( output, "%ssensitive << bhv_pc << do_it;\n", INDENT[2]);
01636   
01637   //  fprintf( output, "%sdont_initialize();\n\n", INDENT[2]);
01638   fprintf( output, "%sstart_up=1;\n", INDENT[2]);
01639   fprintf( output, "%sid = %d;\n\n", INDENT[2], 1);
01640 
01641   if( ACDasmFlag )
01642     fprintf( output, "%sdasmfile.open(\"%s.dasm\");\n\n", INDENT[2], project_name);
01643 
01644   fprintf( output, "%s}\n", INDENT[1]);  //end constructor
01645 
01646 
01647   if(ACDecCacheFlag){
01648     fprintf( output, "%svoid init_dec_cache(){\n", INDENT[1]);  //end constructor
01649     fprintf( output, "%sDEC_CACHE = (cache_item*)calloc(sizeof(cache_item),dec_cache_size);\n", INDENT[2]);  //end constructor
01650     fprintf( output, "%s}\n", INDENT[1]);  //end init_dec_cache
01651   }
01652 
01653   if(ACGDBIntegrationFlag) {
01654     fprintf( output, "%s/***********\n", INDENT[1]);
01655     fprintf( output, "%s * GDB Support - user supplied methods\n", INDENT[1]);
01656     fprintf( output, "%s * For further information, look at $ARCHC_PATH/src/aclib/ac_gdb/ac_gdb_interface.H\n", INDENT[1]);
01657     fprintf( output, "%s ***********/\n\n", INDENT[1]);
01658     
01659     fprintf( output, "%s/* Register access */\n", INDENT[1]);
01660     fprintf( output, "%sint nRegs(void);\n", INDENT[1]);
01661     fprintf( output, "%sac_word reg_read(int reg);\n", INDENT[1]);
01662     fprintf( output, "%svoid reg_write( int reg, ac_word value );\n\n", INDENT[1]);
01663     
01664     fprintf( output, "%s/* Memory access */\n", INDENT[1]);
01665     fprintf( output, "%sunsigned char mem_read( unsigned int address );\n", INDENT[1]);
01666     fprintf( output, "%svoid mem_write( unsigned int address, unsigned char byte );\n", INDENT[1]);
01667   }
01668 
01669 
01670   fprintf( output, "};\n");
01671   
01672   fprintf( output, "#endif //_%s_H\n",project_name );
01673   fclose(output);
01674   free(filename);
01675 }
01676 
01678 void CreateRegsHeader() {
01679   extern ac_dec_format *format_reg_list;
01680   extern ac_sto_list *storage_list;
01681 
01682   ac_sto_list *pstorage;
01683   ac_dec_format *pformat;
01684   ac_dec_field *pfield;
01685 
01686   int flag = 1;
01687   FILE *output;
01688   char filename[] = "ac_fmt_regs.H";
01689 
01690 
01691   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01692 
01693     if(( pstorage->type == REG ) && (pstorage->format != NULL )){
01694 
01695       if(flag){  //Print this just once.
01696         if ( !(output = fopen( filename, "w"))){
01697           perror("ArchC could not open output file");
01698           exit(1);
01699         }
01700 
01701 
01702         print_comment( output, "ArchC Formatted Registers header file.");
01703         fprintf( output, "#ifndef  _AC_FMT_REGS_H\n");
01704         fprintf( output, "#define  _AC_FMT_REGS_H\n\n");
01705         
01706         fprintf( output, "#include  \"ac_storage.H\"\n");
01707         fprintf( output, "#include  \"ac_parms.H\"\n");
01708         fprintf( output, "\n\n");
01709 
01710         COMMENT(INDENT[0],"ArchC classes for formatted registers.\n");
01711         flag = 0;
01712       }
01713 
01714       for( pformat = format_reg_list; pformat!= NULL; pformat=pformat->next){
01715         if(!(strcmp(pformat->name, pstorage->format))){
01716           break;
01717         }
01718       }
01719       //Declaring formatted register class.
01720       fprintf( output, "class ac_%s {\n", pstorage->name);
01721       fprintf( output, "%schar* name;\n", INDENT[1]);
01722       fprintf( output, "public:\n");
01723       
01724       //TO DO: Registers with parameterized size. The templated class ac_reg is still not
01725       //       working with sc_unit<x> types.
01726       for( pfield = pformat->fields; pfield != NULL; pfield = pfield->next)
01727         fprintf( output,"%sac_reg<unsigned> %s;\n",INDENT[1],pfield->name );
01728 
01729       fprintf( output, "\n\n");
01730    
01731       //Declaring class constructor.
01732       fprintf( output, "%sac_%s(char* n): \n", INDENT[1], pstorage->name);
01733       for( pfield = pformat->fields; pfield->next != NULL; pfield = pfield->next)
01734         //Initializing field names with reg name. This is to enable Formatted Reg stats.
01735         //Need to be changed if we adopt statistics collection for each field individually.
01736         fprintf( output,"%s%s(\"%s\",%d),\n",INDENT[2],pfield->name,pstorage->name, 0 );
01737       //Last field.
01738       fprintf( output,"%s%s(\"%s\",%d){name = n;}\n\n",INDENT[2],pfield->name,pstorage->name, 0 );
01739 
01740       fprintf( output,"%svoid change_dump(ostream& output){}\n\n",INDENT[1] );
01741       fprintf( output,"%svoid reset_log(){}\n\n",INDENT[1] );
01742       fprintf( output,"%svoid behavior(ac_stage_list stage = (ac_stage_list)0, int cycle = 0);\n\n",INDENT[1] );
01743       fprintf( output, "};\n\n");      
01744 
01745     }
01746   }
01747 
01748   if(!flag){ //We had at last one formatted reg declared.
01749     fprintf( output, "#endif //_AC_FMT_REGS_H\n");
01750     fclose(output);
01751   }
01752 }
01753 
01754 
01756 void CreateCoverifHeader(void){
01757  
01758   extern ac_sto_list *storage_list;
01759   ac_sto_list *pstorage;
01760 
01761   FILE *output;
01762   char filename[] = "ac_verify.H";
01763 
01764 
01765   
01766   if ( !(output = fopen( filename, "w"))){
01767     perror("ArchC could not open output file");
01768     exit(1);
01769   }
01770 
01771 
01772   print_comment( output, "ArchC Co-verification Class header file.");
01773 
01774   fprintf( output, "#ifndef  _AC_VERIFY_H\n");
01775   fprintf( output, "#define  _AC_VERIFY_H\n\n");
01776         
01777   fprintf( output, "#include  <fstream>\n");
01778   fprintf( output, "#include  <list>\n");
01779   fprintf( output, "#include  \"archc.H\"\n");
01780   fprintf( output, "#include  \"ac_parms.H\"\n");
01781   fprintf( output, "#include  \"ac_resources.H\"\n");
01782   fprintf( output, "#include  \"ac_storage.H\"\n");
01783   fprintf( output, "\n\n");
01784 
01785   COMMENT(INDENT[0],"ArchC Co-verification class.\n");
01786   fprintf( output, "class ac_verify:public ac_resources {\n\n");
01787   
01788   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01789     fprintf( output, "%slog_list %s_changes;\n", INDENT[1], pstorage->name);
01790   }
01791 
01792   fprintf( output, "public:\n\n");
01793 
01794   fprintf( output, "%sofstream output;\n", INDENT[1]);
01795 
01796   //Printing log method.
01797   COMMENT(INDENT[1],"Logging structural model changes.");
01798 
01799   fprintf( output, "%svoid log( char *name, unsigned address, ac_word datum, double time ){\n\n", INDENT[1]);
01800   fprintf( output, "%slog_list *pdevchg;\n", INDENT[2]);
01801 
01802   fprintf( output, "%s", INDENT[2]);
01803 
01804   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01805     fprintf( output, "if( !strcmp( name, \"%s\") )\n", pstorage->name);
01806     fprintf( output, "%spdevchg = &%s_changes;\n", INDENT[3], pstorage->name);
01807     fprintf( output, "%selse ", INDENT[2]);
01808   }
01809 
01810   fprintf( output, "{\n");
01811 
01812   fprintf( output, "%sAC_ERROR(\"Logging aborted! Unknown storage device used for verification: \" << name);", INDENT[3]);
01813   fprintf( output, "%sreturn;", INDENT[3]);
01814   fprintf( output, "%s}\n", INDENT[2]);
01815 
01816   fprintf( output, "\n\n");
01817 
01818   fprintf( output, "%sadd_log( pdevchg, address, datum, time);\n", INDENT[2]);
01819 
01820   fprintf( output, "%s}\n", INDENT[1]);
01821 
01822   //Printing check_clock method.
01823   COMMENT(INDENT[1],"Checking device logs at a given simulation time");
01824 
01825   fprintf( output, "%svoid check_clock( double time ){\n\n", INDENT[1]);
01826 
01827 
01828   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01829     fprintf( output, "%smatch_logs( &%s, &%s_changes, time );\n", INDENT[2], pstorage->name, pstorage->name);
01830   }
01831   fprintf( output, "%s}\n", INDENT[1]);
01832 
01833   //Printing checker_timed method.
01834   COMMENT(INDENT[1],"Finalize co-verification for timed model.");
01835 
01836   fprintf( output, "%svoid checker_timed( double time ){\n\n", INDENT[1]);
01837 
01838   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01839     fprintf( output, "%smatch_logs( &%s, &%s_changes, time );\n", INDENT[2], pstorage->name, pstorage->name);
01840     fprintf( output, "%scheck_final( &%s, &%s_changes );\n", INDENT[2], pstorage->name, pstorage->name);
01841   }
01842   fprintf( output, "%s}\n", INDENT[1]);
01843 
01844   //Printing checker method.
01845   COMMENT(INDENT[1],"Finalize co-verification for untimed model.");
01846 
01847   fprintf( output, "%svoid checker( ){\n\n", INDENT[1]);
01848 
01849   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01850     fprintf( output, "%scheck_final( &%s, &%s_changes );\n", INDENT[2], pstorage->name, pstorage->name);
01851   }
01852   fprintf( output, "%s}\n", INDENT[1]);
01853 
01854   //Printing class constructor.
01855   COMMENT(INDENT[1],"Constructor");
01856 
01857   fprintf( output, "%sac_verify( ){\n\n", INDENT[1]);
01858   fprintf( output, "%soutput.open( \"ac_verification.log\");\n", INDENT[2]);
01859   fprintf( output, "%s}\n", INDENT[1]);
01860 
01861   //Printing add_log method.
01862   COMMENT(INDENT[1],"Logging structural model changes for a given device");
01863 
01864   fprintf( output, "%svoid add_log( log_list *pdevchg, unsigned address, ac_word datum, double time );\n\n", INDENT[1]);
01865 
01866   //Printing match_logs method.
01867   COMMENT(INDENT[1],"Match device's behavioral and structural logs at a given simulation time");
01868 
01869   fprintf( output, "%svoid match_logs( ac_storage *pdevice, log_list *pdevchange, double time );\n\n", INDENT[1]);
01870 
01871   //Printing check_final method.
01872   COMMENT(INDENT[1],"Check behavioral and structural logs for a given device in the end of simulation");
01873 
01874   fprintf( output, "%svoid check_final( ac_storage *pdevice, log_list *pdevchange );\n\n", INDENT[1]);
01875 
01876   fprintf( output, "};\n");
01877 
01878   //END OF FILE!
01879   fprintf( output, "#endif //_AC_VERIFY_H\n");
01880   fclose(output);
01881 
01882 }
01883 
01885 void CreateStatsHeader(void){
01886  
01887   extern ac_sto_list *storage_list;
01888   extern char *project_name;
01889   ac_sto_list *pstorage;
01890 
01891   FILE *output;
01892   char filename[] = "ac_stats.H";
01893 
01894 
01895   
01896   if ( !(output = fopen( filename, "w"))){
01897     perror("ArchC could not open output file");
01898     exit(1);
01899   }
01900 
01901 
01902   print_comment( output, "ArchC Statistics Collection Class header file.");
01903 
01904   fprintf( output, "#ifndef  _AC_STATS_H\n");
01905   fprintf( output, "#define  _AC_STATS_H\n\n");
01906         
01907   fprintf( output, "#include  <fstream>\n");
01908   fprintf( output, "#include  \"archc.H\"\n");
01909   fprintf( output, "#include  \"ac_parms.H\"\n");
01910   fprintf( output, "#include  \"ac_sto_stats.H\"\n");
01911   fprintf( output, "\n\n");
01912 
01913   pstorage = storage_list;
01914 
01915   if( pstorage ){
01916 
01917     //Defining initialization macro
01918     fprintf( output, "#define   INIT_STO_STATS  ");
01919 
01920     fprintf( output, "%s( \"%s\")",pstorage->name, pstorage->name);
01921     
01922     for( pstorage = pstorage->next; pstorage != NULL; pstorage = pstorage->next ){
01923       fprintf( output, ",%s( \"%s\")",pstorage->name, pstorage->name);
01924     }
01925     fprintf( output, ", ac_pc( \"ac_pc\")");
01926   }
01927   fprintf( output, "\n");
01928 
01929   COMMENT(INDENT[0],"ArchC class for Simulation Statistics.");
01930   fprintf( output, "class ac_stats {\n\n");
01931   
01932   fprintf( output, "%sac_sto_stats* head;\n", INDENT[1]);
01933   fprintf( output, "\n");
01934   fprintf( output, "public:\n\n");
01935 
01936   COMMENT(INDENT[1],"Output File.");
01937   fprintf( output, "%sofstream output;\n", INDENT[1]);
01938 
01939   COMMENT(INDENT[1],"Keeps the total simulation time.");
01940   fprintf( output, "%sdouble time;\n", INDENT[1]);
01941   fprintf( output, "\n");
01942 
01943   COMMENT(INDENT[1],"This table tells  how many times an instruction was executed during simulation.");
01944   fprintf( output, "%sint instr_table[AC_DEC_INSTR_NUMBER+1][3];\n", INDENT[1]);
01945   fprintf( output, "\n");
01946 
01947   COMMENT(INDENT[1],"This keeps the total number of instructions executed so far.");
01948   fprintf( output, "%sint instr_executed;\n", INDENT[1]);
01949   fprintf( output, "\n");
01950 
01951   COMMENT(INDENT[1],"This keeps the cycle count estimates.");
01952   fprintf( output, "%sunsigned long long ac_min_cycle_count;\n", INDENT[1]);
01953   fprintf( output, "%sunsigned long long ac_max_cycle_count;\n", INDENT[1]);
01954 
01955   COMMENT(INDENT[1],"Storage Device statistics objects.");
01956 
01957   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01958     fprintf( output, "%sac_sto_stats %s;\n", INDENT[1], pstorage->name);
01959   }
01960   fprintf( output, "%sac_sto_stats ac_pc;\n", INDENT[1]);
01961   fprintf( output, "\n");
01962 
01963   //Printing class constructor.
01964   COMMENT(INDENT[1],"Constructor");
01965   fprintf( output, "%sac_stats( );\n\n", INDENT[1]);
01966   fprintf( output, "\n");
01967 
01968   //Printing print method.
01969   COMMENT(INDENT[1],"Print Simulation Statistics Report");
01970   fprintf( output, "%svoid print(  );\n\n", INDENT[1]);
01971   fprintf( output, "\n");
01972 
01973   //Printing add_access method.
01974   COMMENT(INDENT[1],"Increase access number for a given device.");
01975   fprintf( output, "%svoid add_access( char *name ){\n\n", INDENT[1]);
01976 
01977   fprintf( output, "\n");
01978 
01979   fprintf( output, "%s", INDENT[2]);
01980   fprintf( output, "if( !strcmp( name, \"ac_pc\") )\n");
01981   fprintf( output, "%sac_pc.inc_accesses();\n", INDENT[3]);
01982   fprintf( output, "%selse ", INDENT[2]);
01983   
01984 
01985   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
01986     fprintf( output, "if( !strcmp( name, \"%s\") )\n", pstorage->name);
01987     fprintf( output, "%s%s.inc_accesses();\n", INDENT[3], pstorage->name);
01988     fprintf( output, "%selse ", INDENT[2]);
01989   }
01990   fprintf( output, "\n%sAC_ERROR(\"Unknown storage device used for statistics collection.\" << name);\n", INDENT[3]);
01991 
01992   fprintf( output, "%s}\n", INDENT[1]);
01993   fprintf( output, "\n");
01994 
01995   //Printing add_miss method.
01996   COMMENT(INDENT[1],"Increase access number for a given device.");
01997   fprintf( output, "%svoid add_miss( char *name ){\n\n", INDENT[1]);
01998 
01999   fprintf( output, "\n");
02000 
02001   fprintf( output, "%s", INDENT[2]);
02002   fprintf( output, "if( !strcmp( name, \"ac_pc\") )\n");
02003   fprintf( output, "%sac_pc.inc_misses();\n", INDENT[3]);
02004   fprintf( output, "%selse ", INDENT[2]);
02005   
02006   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
02007     fprintf( output, "if( !strcmp( name, \"%s\") )\n", pstorage->name);
02008     fprintf( output, "%s%s.inc_misses();\n", INDENT[3], pstorage->name);
02009     fprintf( output, "%selse ", INDENT[2]);
02010   }
02011   fprintf( output, "\n");
02012   fprintf( output, "%sAC_ERROR(\"Unknown storage device used for statistics collection.\" << name);\n", INDENT[3]);
02013 
02014   fprintf( output, "%s}\n", INDENT[1]);
02015 
02016   fprintf( output, "\n\n");
02017 
02018 
02019   //Printing stat_init method.
02020   COMMENT(INDENT[1],"Initialize lists and members.");
02021   fprintf( output, "%svoid init_stat( ){\n\n", INDENT[1]);
02022   
02023   if(storage_list){
02024     
02025     fprintf( output, "%shead = &%s; \n", INDENT[2], storage_list->name);
02026     
02027     for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
02028       if(pstorage->next)
02029         fprintf( output, "%s%s.next = &%s;\n", INDENT[2], pstorage->name, pstorage->next->name);
02030       else{
02031         fprintf( output, "%s%s.next = &ac_pc;\n", INDENT[2], pstorage->name);   
02032         fprintf( output, "%sac_pc.next = NULL;\n", INDENT[2]);  
02033       }
02034     }  
02035   }
02036   else{
02037 
02038     fprintf( output, "%shead = NULL; \n", INDENT[2]);
02039   }
02040 
02041   //Openning input file.
02042   fprintf( output, "%soutput.open( \"%s.stats\");\n", INDENT[2], project_name);
02043 
02044   fprintf( output, "%s}\n", INDENT[1]);
02045     
02046 
02047   //End of Class.
02048   fprintf( output, "};\n");
02049 
02050   //END OF FILE!
02051   fprintf( output, "#endif //_AC_STATS_H\n");
02052   fclose(output);
02053 
02054 }
02055 
02057 
02059 void CreateStgImpl(ac_stg_list* stage_list, char* pipe_name) {
02060   
02061   extern char *project_name;
02062   extern int stage_num;
02063   ac_stg_list *pstage;
02064   int base_indent;
02065   char* stage_filename;
02066   FILE* output;
02067 
02068   for( pstage = stage_list; pstage != NULL; pstage=pstage->next){      
02069 
02070     //IF a ac_pipe declaration was used, stage module names will be PIPENAME_STAGENAME,
02071     //otherwise they will be just STAGENAME.
02072     //This makes possible to define multiple pipelines containg stages with the same name.
02073     if( pipe_name ){
02074       stage_filename = (char*) malloc(strlen(pstage->name)+strlen(pipe_name)+strlen(".cpp")+2);
02075       sprintf( stage_filename, "%s_%s.cpp", pipe_name, pstage->name);
02076     }
02077     else{
02078       stage_filename = (char*) malloc(strlen(pstage->name)+strlen(".cpp")+1);
02079       sprintf( stage_filename, "%s.cpp", pstage->name);
02080     }
02081 
02082     if ( !(output = fopen( stage_filename, "w"))){
02083       perror("ArchC could not open output file");
02084       exit(1);
02085     }
02086 
02087     print_comment( output, "Stage Module Implementation File.");
02088     if( pipe_name ){
02089       fprintf( output, "#include  \"%s_%s.H\"\n\n", pipe_name, pstage->name);
02090     }
02091     else{
02092       fprintf( output, "#include  \"%s.H\"\n\n", pstage->name);
02093     }
02094 
02095     if( pstage->id == 1 && ACABIFlag )
02096       fprintf( output, "#include  \"%s_syscall.H\"\n\n", project_name);
02097     
02098     if( pstage->id == 1 && ACVerifyFlag ){
02099       fprintf( output, "#include  \"ac_msgbuf.H\"\n");
02100       fprintf( output, "#include  \"sys/msg.h\"\n");
02101     }
02102 
02103 
02104     //Emiting stage behavior method implementation.
02105     if( pstage->id != 1 ){
02106 
02107       if( pipe_name )                   
02108         fprintf( output, "void AC_%s_%s::%s_%s::behavior() {\n\n", pipe_name, pstage->name, pipe_name, pstage->name);
02109       else
02110         fprintf( output, "void AC_%s::%s::behavior() {\n\n", pstage->name, pstage->name);
02111 
02112       fprintf( output, "%sac_instruction *instr, *format;\n", INDENT[1]);
02113       fprintf( output, "%sunsigned ins_id;\n", INDENT[1]);
02114       fprintf( output, "%sac_instr *instr_vec;\n\n", INDENT[1]);
02115       fprintf( output, "%sinstr_vec = new ac_instr(regin.read());\n\n", INDENT[1]);
02116       fprintf( output, "%sins_id = instr_vec->get(IDENT);\n", INDENT[1]);
02117 
02118       fprintf( output, "%sif( ins_id != 0 ) {\n", INDENT[1]);
02119       fprintf( output, "%sinstr = (ac_instruction *)ISA.instr_table[instr_vec->get(IDENT)][1];\n", INDENT[2]);
02120       fprintf( output, "%sformat = (ac_instruction *)ISA.instr_table[ins_id][2];\n", INDENT[2]);
02121       fprintf( output, "%sformat->set_fields( *instr_vec  );\n", INDENT[2]);
02122       fprintf( output, "%sinstr->set_fields( *instr_vec  );\n", INDENT[2]);
02123       fprintf( output, "%sISA.instruction.behavior( (ac_stage_list)id );\n", INDENT[2]);
02124       fprintf( output, "%sformat->behavior( (ac_stage_list)id );\n", INDENT[2]);
02125       fprintf( output, "%sinstr->behavior( (ac_stage_list)id );\n", INDENT[2]);
02126       fprintf( output, "%s}\n", INDENT[1]);
02127 
02128       if( pstage->id != stage_num)
02129         fprintf( output, "%sregout.write( *instr_vec);\n", INDENT[1]);
02130 
02131       fprintf( output, "%sdelete instr_vec;\n", INDENT[1]);
02132       fprintf( output, "%sbhv_done.write(1);\n", INDENT[1]);
02133       fprintf( output, "}\n\n");
02134     }
02135 
02136     //First Stage needs to fetch and decode instructions ....
02137     else{
02138       if( pipe_name )                   
02139         fprintf( output, "void AC_%s_%s::%s_%s::behavior() {\n\n", pipe_name, pstage->name, pipe_name, pstage->name);
02140       else
02141         fprintf( output, "void AC_%s::%s::behavior() {\n\n", pstage->name, pstage->name);
02142                         
02143       fprintf( output, "%sac_instruction *instr, *format;\n", INDENT[1]);
02144       fprintf( output, "%sunsigned  ins_id;\n", INDENT[1]);
02145                         
02146       if( ACDebugFlag ){
02147         fprintf( output, "%sextern bool ac_do_trace;\n", INDENT[1]);
02148         fprintf( output, "%sextern ofstream trace_file;\n", INDENT[1]);
02149       }
02150 
02151       if( ACABIFlag ){
02152         fprintf( output, "%s%s_syscall syscall;\n", INDENT[1], project_name);
02153         fprintf( output, "%sstatic int flushes_left=7;\n", INDENT[1]);
02154         fprintf( output, "%sstatic ac_instr *the_nop = new ac_instr;\n", INDENT[1]);
02155       }                 
02156                         
02157       if( ACVerifyFlag ){
02158         fprintf( output, "%sextern int msqid;\n", INDENT[1]);
02159         fprintf( output, "%sstruct log_msgbuf end_log;\n", INDENT[1]);
02160       }
02161                         
02162       if( ac_host_endian == 0 ){
02163         fprintf( output, "%schar fetch[AC_FETCHSIZE/8];\n", INDENT[1]);
02164         fprintf( output, "%sint i;\n\n", INDENT[1]);
02165       }
02166 
02167       if(ACDecCacheFlag)
02168         fprintf( output, "%scache_item* ins_cache;\n", INDENT[1]);
02169 
02170                         
02171       fprintf( output, "%sextern unsigned int decode_pc, quant;\n", INDENT[1]);
02172       fprintf( output, "%sextern unsigned char buffer[AC_MAX_BUFFER];\n", INDENT[1]);
02173       //      fprintf( output, "%sunsigned *instr_dec;\n", INDENT[1]);
02174       fprintf( output, "%sac_instr *instr_vec;\n\n", INDENT[1]);
02175 
02176       EmitFetchInit(output, 1);
02177       base_indent =2;
02178 
02179       if(ACABIFlag){
02180 
02181         base_indent++;
02182         //Emiting system calls handler.
02183         COMMENT(INDENT[1],"Handling System calls.");
02184         fprintf( output, "%sif (decode_pc %% 2) decode_pc--;\n", INDENT[2]);
02185 
02186         fprintf( output, "%sswitch( decode_pc ){\n", INDENT[2]);
02187 
02188         EmitPipeABIDefine(output);
02189         fprintf( output, "\n\n");
02190         EmitABIAddrList(output,3);
02191 
02192         fprintf( output, "%sdefault:\n", INDENT[2]);
02193       }
02194 
02195       EmitDecodification(output, 1);
02196       EmitInstrExec(output, base_indent);
02197 
02198       if( ACABIFlag ){
02199         //Closing default case.
02200         fprintf( output, "%sbreak;\n", INDENT[3]);
02201         //Closing switch
02202         fprintf( output, "%s}\n", INDENT[2]);
02203       }
02204 
02205       fprintf( output, "%sac_instr_counter++;\n", INDENT[2]);
02206       fprintf( output, "%sbhv_done.write(1);\n", INDENT[2]);
02207       //Closing else
02208       fprintf( output, "%s}\n", INDENT[1]);
02209       fprintf( output, "}\n\n");
02210     }
02211 
02212     fclose(output);
02213     free(stage_filename);
02214   }
02215 }
02216 
02218 void CreateProcessorImpl() {
02219 
02220   extern char *project_name;
02221   extern int HaveMultiCycleIns, HaveMemHier;
02222 
02223   char* filename;
02224   FILE* output;
02225 
02226   filename = (char*) malloc(strlen(project_name)+strlen(".cpp")+1);
02227   sprintf( filename, "%s.cpp", project_name);
02228 
02229   if ( !(output = fopen( filename, "w"))){
02230     perror("ArchC could not open output file");
02231     exit(1);
02232   }
02233     
02234   print_comment( output, "Processor Module Implementation File.");
02235   fprintf( output, "#include  \"%s.H\"\n\n", project_name);
02236 
02237   if( ACVerifyFlag ){
02238     fprintf( output, "#include  \"ac_msgbuf.H\"\n");
02239     fprintf( output, "#include  \"sys/msg.h\"\n");
02240   }
02241 
02242   if( ACABIFlag )
02243     fprintf( output, "#include  \"%s_syscall.H\"\n\n", project_name);
02244                 
02245   fprintf( output, "void %s::behavior() {\n\n", project_name);
02246   if( ACDebugFlag ){
02247     fprintf( output, "%sextern bool ac_do_trace;\n", INDENT[1]);
02248     fprintf( output, "%sextern ofstream trace_file;\n", INDENT[1]);
02249   }
02250   fprintf( output, "%sextern unsigned int decode_pc, quant;\n", INDENT[1]);
02251   fprintf( output, "%sextern unsigned char buffer[AC_MAX_BUFFER];\n", INDENT[1]);
02252   fprintf( output, "%sunsigned ins_id;\n", INDENT[1]);
02253 
02254   if( ACVerifyFlag ){
02255     fprintf( output, "%sextern int msqid;\n", INDENT[1]);
02256     fprintf( output, "%sstruct log_msgbuf end_log;\n", INDENT[1]);
02257   }
02258   if( ACABIFlag )
02259     fprintf( output, "%s%s_syscall syscall;\n", INDENT[1], project_name);
02260 
02261   if(ACDecCacheFlag)
02262     fprintf( output, "%scache_item* ins_cache;\n", INDENT[1]);
02263 
02264   if( ac_host_endian == 0 ){
02265     fprintf( output, "%schar fetch[AC_FETCHSIZE/8];\n", INDENT[1]);
02266     fprintf( output, "%sint i;\n\n", INDENT[1]);
02267   }
02268 
02269   if( HaveMemHier ) {
02270     fprintf( output, "%sif( ac_wait_sig ) {\n", INDENT[1]);
02271     fprintf( output, "%sreturn;\n", INDENT[2]);
02272     fprintf( output, "%s}\n\n", INDENT[1]);
02273   }
02274     
02275   //Emiting processor behavior method implementation.
02276   if( HaveMultiCycleIns )
02277     EmitMultiCycleProcessorBhv(output);
02278   else{
02279     if( ACABIFlag )
02280       EmitProcessorBhv_ABI(output);
02281     else
02282       EmitProcessorBhv(output);
02283   }
02284   fclose(output);
02285   free(filename);
02286 }
02287 
02288 
02290 void CreateResourceImpl() {
02291 
02292   extern ac_pipe_list *pipe_list;
02293   extern ac_sto_list *storage_list, *fetch_device;
02294   extern ac_stg_list *stage_list;
02295   extern int HaveMultiCycleIns, HaveMemHier, reg_width; 
02296   extern ac_sto_list* load_device;
02297 
02298   ac_sto_list *pstorage, *pmem;
02299   ac_stg_list *pstage;
02300   char Globals[5000];
02301   char *Globals_p = Globals;
02302         ac_pipe_list *ppipe;
02303 
02304   FILE *output;
02305   char filename[] = "ac_resources.cpp";
02306 
02307   load_device= storage_list;
02308   if ( !(output = fopen( filename, "w"))){
02309     perror("ArchC could not open output file");
02310     exit(1);
02311   }
02312 
02313 
02314   print_comment( output, "ArchC Resources Implementation file.");
02315   
02316   fprintf( output, "#include  \"ac_resources.H\"\n");
02317   fprintf( output, "#include  \"ac_storage.H\"\n");
02318   fprintf( output, "#include  \"ac_regbank.H\"\n");
02319   fprintf( output, "#include  \"ac_reg.cpp\"\n");
02320 
02321   if(ACVerifyFlag){
02322     fprintf( output, "#include  \"ac_msgbuf.H\"\n");
02323     fprintf( output, "#include  <sys/ipc.h>\n");
02324     fprintf( output, "#include  <unistd.h>\n");
02325     fprintf( output, "#include  <sys/msg.h>\n");
02326     fprintf( output, "#include  <sys/types.h>\n");
02327   }
02328 
02329   if( ACStatsFlag ){
02330     COMMENT(INDENT[0],"Statistics Object.");
02331     fprintf( output, "%sac_stats ac_resources::ac_sim_stats;\n", INDENT[0]);
02332   }
02333   
02334   COMMENT(INDENT[0],"Storage Devices.");
02335   for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02336 
02337     switch( pstorage->type ){
02338 
02339     case REG:
02340 
02341       //Formatted registers have a special class.
02342       if( pstorage->format != NULL ){
02343         fprintf( output, "%sac_%s ac_resources::%s(\"%s\");\n", INDENT[0], pstorage->name, pstorage->name, pstorage->name);
02344         Globals_p += sprintf( Globals_p, "ac_%1$s &%1$s = ac_resources::%1$s;\n", pstorage->name);
02345       }
02346       else{
02347         fprintf( output, "%sac_reg<unsigned> ac_resources::%s(\"%s\", 0);\n", INDENT[0], pstorage->name, pstorage->name);      
02348         Globals_p += sprintf( Globals_p, "ac_reg<unsigned> &%1$s = ac_resources::%1$s;\n", pstorage->name);
02349       }
02350       break;
02351                         
02352     case REGBANK:
02353       //Emiting register bank. Checking is a register width was declared.
02354       switch( (unsigned)reg_width ){
02355       case 0:
02356         fprintf( output, "%sac_regbank<ac_word> ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);      
02357         Globals_p += sprintf( Globals_p, "ac_regbank<ac_word> &%1$s = ac_resources::%1$s;\n", pstorage->name);
02358         break;
02359       case 8:
02360         fprintf( output, "%sac_regbank<unsigned char> ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);      
02361         Globals_p += sprintf( Globals_p, "ac_regbank<unsigned char> &%1$s = ac_resources::%1$s;\n", pstorage->name);
02362         break;
02363       case 16:
02364         fprintf( output, "%sac_regbank<unsigned short> ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);      
02365         Globals_p += sprintf( Globals_p, "ac_regbank<unsigned short> &%1$s = ac_resources::%1$s;\n", pstorage->name);
02366         break;
02367       case 32:
02368         fprintf( output, "%sac_regbank<unsigned> ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);      
02369         Globals_p += sprintf( Globals_p, "ac_regbank<unsigned> &%1$s = ac_resources::%1$s;\n", pstorage->name);
02370         break;
02371       case 64:
02372         fprintf( output, "%sac_regbank<unsigned long long> ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);      
02373         Globals_p += sprintf( Globals_p, "ac_regbank<unsigned long long> &%1$s = ac_resources::%1$s;\n", pstorage->name);
02374         break;
02375       default:
02376         AC_ERROR("Register width not supported: %d\n", reg_width);
02377         break;
02378       }
02379       break;
02380 
02381     case CACHE:
02382     case ICACHE:
02383     case DCACHE:
02384 
02385       if( !pstorage->parms ) { //It is a generic cache. Just emit a base container object.
02386         fprintf( output, "%sac_storage ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);
02387         Globals_p += sprintf( Globals_p, "ac_storage &%1$s = ac_resources::%1$s;\n", pstorage->name);
02388       }
02389       else{
02390         //It is an ac_cache object.
02391         EmitCacheDeclaration(output, pstorage, 0);
02392         Globals_p += sprintf( Globals_p, "ac_cache &%1$s = ac_resources::%1$s;\n", pstorage->name);
02393       }
02394       break;
02395 
02396     case MEM:
02397 
02398       if( !HaveMemHier ) { //It is a generic cache. Just emit a base container object.
02399         fprintf( output, "%sac_storage ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);
02400         Globals_p += sprintf( Globals_p, "ac_storage &%1$s = ac_resources::%1$s;\n", pstorage->name);
02401       }
02402       else{
02403         //It is an ac_mem object.
02404         fprintf( output, "%sac_mem ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);
02405         Globals_p += sprintf( Globals_p, "ac_mem &%1$s = ac_resources::%1$s;\n", pstorage->name);
02406       }
02407       break;
02408 
02409     default:
02410       fprintf( output, "%sac_storage ac_resources::%s(\"%s\", %d);\n", INDENT[0], pstorage->name, pstorage->name, pstorage->size);      
02411       Globals_p += sprintf( Globals_p, "ac_storage &%1$s = ac_resources::%1$s;\n", pstorage->name);
02412       break;
02413     }
02414   }
02415 
02416   fprintf( output, "%sac_storage *ac_resources::IM;\n\n", INDENT[0]);
02417   fprintf( output, "%sac_storage *ac_resources::APP_MEM;\n\n", INDENT[0]);
02418   
02419   COMMENT(INDENT[0],"Control Variables.");
02420   fprintf( output, "ac_reg<unsigned> ac_resources::ac_pc(\"ac_pc\", 0xffffffff);\n");
02421   Globals_p += sprintf( Globals_p, "ac_reg<unsigned> &ac_pc = ac_resources::ac_pc;\n");
02422   fprintf( output, "unsigned ac_resources::ac_start_addr = 0;\n");
02423   Globals_p += sprintf( Globals_p, "unsigned &ac_start_addr = ac_resources::ac_start_addr;\n");
02424   fprintf( output, "unsigned long long ac_resources::ac_instr_counter = 0;\n");
02425   Globals_p += sprintf( Globals_p, "unsigned long long &ac_instr_counter = ac_resources::ac_instr_counter;\n");
02426   fprintf( output, "unsigned long long ac_resources::ac_cycle_counter = 0;\n");
02427   Globals_p += sprintf( Globals_p, "unsigned long long &ac_cycle_counter = ac_resources::ac_cycle_counter;\n");
02428 
02429   fprintf( output, "double ac_resources::time_step;\n");
02430 
02431   if(HaveMultiCycleIns) 
02432     fprintf( output, "unsigned ac_resources::ac_cycle;\n");
02433 
02434   fprintf( output, "bool ac_resources::ac_tgt_endian = %d;\n", ac_tgt_endian);
02435   Globals_p += sprintf( Globals_p, "bool &ac_tgt_endian = ac_resources::ac_tgt_endian;\n");
02436 
02437 
02438   //TODO: Test wait signal for pipelined archs
02439   fprintf( output, "%sbool ac_resources::ac_wait_sig;\n", INDENT[0]);
02440   Globals_p += sprintf( Globals_p, "bool &ac_wait_sig = ac_resources::ac_wait_sig;\n");
02441 
02442   fprintf( output, "%sbool ac_resources::ac_parallel_sig;\n", INDENT[0]);
02443 
02444   if( !stage_list && !pipe_list ){
02445     fprintf( output, "%sbool ac_resources::ac_annul_sig;\n", INDENT[0]);
02446     Globals_p += sprintf( Globals_p, "bool &ac_annul_sig = ac_resources::ac_annul_sig;\n");
02447   }
02448 
02449   //Emitting stall variables
02450   if( stage_list ){
02451     for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
02452       if( pstage->next ){
02453         fprintf( output, "%sbool ac_resources::%s_stall;\n", INDENT[0], pstage->name);
02454         Globals_p += sprintf( Globals_p, "bool &%1$s_stall = ac_resources::%1$s_stall;\n", pstage->name);
02455       }
02456                 
02457     for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
02458       if( pstage->next ){
02459         fprintf( output, "%sbool ac_resources::%s_flush;\n", INDENT[0], pstage->name);
02460         Globals_p += sprintf( Globals_p, "bool &%1$s_flush = ac_resources::%1$s_flush;\n", pstage->name);
02461       }
02462 
02463   }else if(pipe_list){
02464         
02465     for( ppipe = pipe_list; ppipe!=NULL; ppipe= ppipe->next ){
02466 
02467       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next)
02468         if( pstage->next ){
02469           fprintf( output, "%sbool ac_resources::%s_%s_stall;\n", INDENT[0], ppipe->name, pstage->name);
02470           Globals_p += sprintf( Globals_p, "bool &%1$s_%2$s_stall = ac_resources::%1$s_%2$s_stall;\n", ppipe->name, pstage->name);
02471         }
02472                 
02473       for( pstage = ppipe->stages ; pstage != NULL; pstage=pstage->next)
02474         if( pstage->next ){
02475           fprintf( output, "%sbool ac_resources::%s_%s_flush;\n", INDENT[0], ppipe->name, pstage->name);
02476           Globals_p += sprintf( Globals_p, "bool &%1$s_%2$s_flush = ac_resources::%1$s_%2$s_flush;\n", ppipe->name, pstage->name);
02477         }
02478     }
02479   } 
02480 
02481   fprintf( output, "\n");
02482 
02483   COMMENT(INDENT[0], "Program arguments.");
02484   fprintf( output, "int ac_resources::argc;\n");
02485   fprintf( output, "char ** ac_resources::argv;\n");
02486         
02487   if( ACDasmFlag ){
02488     COMMENT(INDENT[0], "Disassembler file.");
02489     fprintf( output, "%sofstream ac_resources::dasmfile;\n", INDENT[1]);
02490   }
02491 
02493   COMMENT(INDENT[0],"Constructor.\n");
02494   fprintf( output, "%sac_resources::ac_resources(){\n\n", INDENT[0]);
02495 
02496   COMMENT(INDENT[1],"Initializing.\n");
02497   for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
02498     if( pstage->next )
02499       fprintf( output, "%s%s_stall  =0;\n", INDENT[1], pstage->name);
02500 
02501   fprintf( output, "\n");
02502   for( pstage = stage_list; pstage != NULL; pstage=pstage->next)
02503     if( pstage->next )
02504       fprintf( output, "%s%s_flush  =0;\n", INDENT[1], pstage->name);
02505       
02506   if(HaveMultiCycleIns) 
02507     fprintf( output, "%sac_cycle = 1;\n", INDENT[1]);
02508   
02509   fprintf( output, "%sac_tgt_endian = %d;\n", INDENT[1], ac_tgt_endian);
02510   fprintf( output, "%sac_start_addr = 0;\n", INDENT[1]);
02511   fprintf( output, "%sac_instr_counter = 0;\n", INDENT[1]);
02512   fprintf( output, "%sac_cycle_counter = 0;\n", INDENT[1]);
02513   fprintf( output, "%sac_wait_sig = 0;\n", INDENT[1]);
02514   fprintf( output, "%sac_parallel_sig = 0;\n", INDENT[1]);
02515 
02516   if( !stage_list && !pipe_list )
02517     fprintf( output, "%sac_annul_sig = 0;\n", INDENT[1]);
02518 
02519 
02520   /* Determining which device is gonna be used for fetching instructions */
02521   if( !fetch_device ){
02522     //The parser has not determined because there is not an ac_icache obj declared.
02523     //In this case, look for the object with the lowest (zero) hierarchy level.
02524     for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next)
02525       if( pstorage->level == 0 &&  pstorage->type != REG &&  pstorage->type != REGBANK)
02526         fetch_device = pstorage;
02527 
02528     if( !fetch_device ) { //Couldn't find a fetch device. Error!
02529       AC_INTERNAL_ERROR("Could not determine a device for fetching.");
02530       exit(1);
02531     }
02532   }
02533 
02534   fprintf( output, "%sIM = &%s;\n", INDENT[1], fetch_device->name);
02535 
02536   /* Determining which device is going to be used for loading applications*/
02537   /* The device used for loading applications must be the one in the highest
02538      level of a memory hierachy.*/
02539   for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02540     if(pstorage->level > load_device->level)
02541       load_device = pstorage;
02542   }
02543 
02544   /* If there is only one level, which is gonna be zero, then it is the same
02545      object used for fetching. */
02546   if( load_device->level ==0 )
02547     load_device = fetch_device;
02548 
02549   fprintf( output, "%sAPP_MEM = &%s;\n", INDENT[1], load_device->name);
02550 
02551   fprintf( output, "\n");      
02552 
02553   /* Connecting memory hierarchy */
02554   for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next)
02555     if( pstorage->higher ){
02556       fprintf( output, "%s%s.bindToNext(%s);\n", INDENT[1], pstorage->name, pstorage->higher->name );
02557     }
02558         
02559   fprintf( output, "}\n\n");
02560 
02561   fprintf( output, "\n");      
02562 
02563   if(ACVerifyFlag){
02564     int ndevice=0;
02565 
02566     //Set co-verification msg queue method
02567     fprintf( output, "void ac_resources::set_queue(char* exec_name){\n\n" );
02568     fprintf( output, "%sstruct start_msgbuf sbuf;\n", INDENT[1] );
02569     fprintf( output, "%sstruct dev_msgbuf dbuf;\n", INDENT[1] );
02570     fprintf( output, "%sextern key_t key;\n", INDENT[1] );
02571     fprintf( output, "%sextern int msqid;\n", INDENT[1] );
02572 
02573     fprintf( output, "%sif ((key = ftok(exec_name, 'A')) == -1) {\n", INDENT[1] );
02574     fprintf( output, "%sAC_ERROR(\"Could not attach to the co-verification msg queue. Process:\" << getpid());\n", INDENT[2] );
02575     fprintf( output, "%sperror(\"ftok\");\n", INDENT[2] );
02576     fprintf( output, "%sexit(1);\n", INDENT[2] );
02577     fprintf( output, "%s}\n", INDENT[1] );
02578                 
02579     fprintf( output, "%sif ((msqid = msgget(key, 0644)) == -1) {\n", INDENT[1] );
02580     fprintf( output, "%sAC_ERROR(\"Could not attach to the co-verification msg queue. Process:\" << getpid());\n", INDENT[2] );
02581     fprintf( output, "%sperror(\"msgget\");\n", INDENT[2] );
02582     fprintf( output, "%sexit(1);\n", INDENT[2] );
02583     fprintf( output, "%s}\n", INDENT[1] );
02584 
02585     for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02586 
02587       if( pstorage->type == MEM ||
02588           pstorage->type == ICACHE ||
02589           pstorage->type == DCACHE ||
02590           pstorage->type == CACHE ||
02591           pstorage->type == REGBANK )
02592         ndevice++;
02593     }
02594 
02595     fprintf( output, "%ssbuf.mtype = 1;\n", INDENT[1] );
02596     fprintf( output, "%ssbuf.ndevice =%d;\n", INDENT[1], ndevice );
02597 
02598     fprintf( output, "%sif (msgsnd(msqid, (void*)&sbuf, sizeof(sbuf), 0) == -1)\n", INDENT[1] );
02599     fprintf( output, "%sperror(\"msgsnd\");\n", INDENT[2] );
02600     fprintf( output, "\n" );
02601 
02602     fprintf( output, "%sdbuf.mtype =2;\n", INDENT[1] );
02603 
02604     for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02605 
02606       if( pstorage->type == MEM ||
02607           pstorage->type == ICACHE ||
02608           pstorage->type == DCACHE ||
02609           pstorage->type == CACHE ||
02610           pstorage->type == REGBANK ){
02611 
02612         fprintf( output, "%sstrcpy(dbuf.name,%s.get_name());\n", INDENT[1], pstorage->name );
02613 
02614         fprintf( output, "%sif (msgsnd(msqid, (void*)&dbuf, sizeof(dbuf), 0) == -1)\n", INDENT[1] );
02615         fprintf( output, "%sperror(\"msgsnd\");\n", INDENT[2] );
02616         fprintf( output, "\n" );
02617       }
02618     }
02619     fprintf( output, "}\n");   //End of set_queue
02620   }
02621 
02622   COMMENT(INDENT[0],"Global aliases for resources.");
02623   fprintf( output, "%s\n", Globals);
02624 
02625   fclose( output); 
02626   
02627 }
02628 
02630 void CreateARCHImpl() {
02631 
02632   extern ac_stg_list *stage_list;
02633         extern ac_pipe_list *pipe_list;
02634   extern ac_stg_list *stage_list;
02635   extern ac_sto_list *storage_list;
02636   extern char *project_name;
02637   extern int stage_num;
02638   ac_sto_list *pstorage;
02639   ac_stg_list *pstage;
02640         ac_pipe_list *ppipe;
02641   int i;
02642 
02643   char filename[256];
02644   char description[] = "Architecture Module implementation file.";
02645  
02647   FILE  *output;
02648   
02649   sprintf( filename, "%s-arch.cpp", project_name);
02650   if ( !(output = fopen( filename, "w"))){
02651     perror("ArchC could not open output file");
02652     exit(1);
02653   }
02654 
02655   print_comment( output, description);
02656 
02657   fprintf( output, "#include \"ac_parms.H\"\n");
02658   fprintf( output, "#include  \"%s-arch.H\"\n", project_name);
02659   fprintf( output, "#include  \"ac_reg.cpp\"\n");
02660   if( ACVerifyFlag ){
02661     fprintf( output, "#include  \"ac_msgbuf.H\"\n");
02662     fprintf( output, "#include  \"sys/msg.h\"\n");
02663   }
02664   fprintf( output, " \n");
02665 
02666   //Emiting Verification Method.
02667   COMMENT(INDENT[0],"Verification method.\n");               
02668   fprintf( output, "%svoid %s_arch::ac_verify(){\n", INDENT[0], project_name);        
02669 
02670   if( ACVerifyFlag ){
02671 
02672     fprintf( output, "extern int msqid;\n");
02673     fprintf( output, "struct log_msgbuf lbuf;\n");
02674     fprintf( output, "log_list::iterator itor;\n");
02675     fprintf( output, "log_list *plog;\n");
02676   }
02677   fprintf( output, " \n");
02678 
02679 
02680   fprintf( output, "%sif( ", INDENT[1]);
02681 
02682   if(stage_list){
02683     for( i =1; i<= stage_num-1; i++)    
02684       fprintf( output, "st%d_done.read() && \n%s", i, INDENT[2]); 
02685     fprintf( output, "st%d_done.read() )\n", stage_num); 
02686   }
02687   else if ( pipe_list ){
02688 
02689     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
02690 
02691       for( pstage = ppipe->stages; pstage->next != NULL; pstage=pstage->next)
02692         fprintf( output, "%s%s_%s_done.read() && \n", INDENT[1], ppipe->name, pstage->name);
02693 
02694       if( ppipe->next )  //If we have another pipe in the list, do it normally, otherwise, close if condition
02695         fprintf( output, "%s%s_%s_done.read() && \n", INDENT[1], ppipe->name, pstage->name);
02696       else
02697         fprintf( output, "%s%s_%s_done.read() )\n", INDENT[1], ppipe->name, pstage->name);
02698                                 
02699     }
02700   }
02701   else{
02702     fprintf( output, "done.read() )\n"); 
02703   }
02704 
02705   fprintf( output, "%s  {\n", INDENT[2]);
02706 
02707     
02708   fprintf( output, "#ifdef AC_VERBOSE\n");
02709   for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02710     fprintf( output, "%s%s.change_dump(cerr);\n", INDENT[3],pstorage->name );
02711   }
02712   fprintf( output, "#endif\n");
02713 
02714 
02715   fprintf( output, "#ifdef AC_UPDATE_LOG\n");
02716 
02717   if( ACVerifyFlag ){
02718 
02719     int next_type = 3;
02720 
02721     fprintf( output, "%sif( sc_simulation_time() ){\n", INDENT[3]);
02722 
02723     //Sending logs for every storage device. We just consider for co-verification caches, regbanks and memories
02724     for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02725 
02726       if( pstorage->type == MEM ||
02727           pstorage->type == ICACHE ||
02728           pstorage->type == DCACHE ||
02729           pstorage->type == CACHE ||
02730           pstorage->type == REGBANK ){
02731 
02732         fprintf( output, "%splog = %s.get_changes();\n", INDENT[4],pstorage->name );
02733         fprintf( output, "%sif( plog->size()){\n", INDENT[4] );
02734         fprintf( output, "%sitor = plog->begin();\n", INDENT[5] );
02735         fprintf( output, "%slbuf.mtype = %d;\n", INDENT[5], next_type );
02736         fprintf( output, "%swhile( itor != plog->end()){\n\n", INDENT[5] );
02737         fprintf( output, "%slbuf.log = *itor;\n", INDENT[6] );
02738         fprintf( output, "%sif( msgsnd(msqid, (struct log_msgbuf *)&lbuf, sizeof(lbuf), 0) == -1)\n", INDENT[6] );
02739         fprintf( output, "%sperror(\"msgsnd\");\n", INDENT[7] );
02740         fprintf( output, "%sitor = plog->erase(itor);\n", INDENT[6] );
02741         fprintf( output, "%s}\n", INDENT[5] );
02742         fprintf( output, "%s}\n\n", INDENT[4] );
02743                         
02744         next_type++;
02745       }
02746     }
02747     fprintf( output, "%s}\n\n", INDENT[3] );
02748                 
02749   }
02750   for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02751     //fprintf( output, "%s%s.change_save();\n", INDENT[3],pstorage->name );
02752     fprintf( output, "%s%s.reset_log();\n", INDENT[3],pstorage->name );          
02753   }
02754         
02755   fprintf( output, "#endif\n");
02756 
02757 
02758   if(stage_list){
02759     for( i =1; i<= stage_num; i++)    
02760       fprintf( output, "%sst%d_done.write(0);\n", INDENT[3], i);  
02761   }
02762   else  if ( pipe_list ){
02763                 
02764     for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
02765                         
02766       for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next)
02767         fprintf( output, "%s%s_%s_done.write(0);\n", INDENT[1], ppipe->name, pstage->name);
02768 
02769     }
02770   }
02771   else{
02772     fprintf( output, "%sdone.write(0);\n", INDENT[3]); 
02773   }
02774 
02775   fprintf( output, "%s  }\n", INDENT[2]);
02776   fprintf( output, "%s}\n\n", INDENT[0]);
02777 
02779   if( stage_list )
02780     EmitPipeUpdateMethod( output);
02781   else if ( pipe_list )
02782     EmitMultiPipeUpdateMethod( output);
02783   else
02784     EmitUpdateMethod( output);
02785 
02787   fclose(output);
02788 }
02789 
02790 
02793 void CreateMainTmpl(){
02794 
02795   extern char *project_name;
02796   char filename[] = "main.cpp.tmpl";
02797   char description[256];
02798   FILE  *output;
02799 
02800   sprintf( description, "This is the main file for the %s ArchC model", project_name);
02801   if ( !(output = fopen( filename, "w"))){
02802     perror("ArchC could not open output file");
02803     exit(1);
02804   }
02805 
02806 
02807 
02808   print_comment( output, description);
02809 
02810   fprintf( output, "const char *project_name=\"%s\";\n", project_name);
02811   fprintf( output, "const char *project_file=\"%s\";\n", arch_filename);
02812   fprintf( output, "const char *archc_version=\"%s\";\n", ACVersion);
02813   fprintf( output, "const char *archc_options=\"%s\";\n", ACOptions);
02814   fprintf( output, "\n");
02815 
02816   fprintf( output, "#include  <systemc.h>\n");
02817   fprintf( output, "#include  \"archc.H\"\n");
02818   fprintf( output, "#include  \"ac_decoder.h\"\n");
02819   fprintf( output, "#include  \"%s-isa.H\"\n", project_name);
02820   fprintf( output, "#include  \"%s-arch.H\"\n\n", project_name);
02821 
02822   if (ACEncoderFlag) {
02823     if (ac_tgt_endian == 0)
02824       fprintf( output, "#define USE_LITTLE_ENDIAN\n");
02825     else
02826       fprintf( output, "//#define USE_LITTLE_ENDIAN\n");
02827     fprintf( output, "#include  \"ac_encoder.H\"\n");
02828   }
02829 
02830   if (ACGDBIntegrationFlag) {
02831     fprintf( output, "\n#include \"ac_gdb.H\"\n");
02832     fprintf( output, "AC_GDB *gdbstub;\n\n");
02833   }
02834 
02835   fprintf( output, "\n\n");
02836   fprintf( output, "int sc_main(int ac, char *av[])\n");
02837   fprintf( output, "{\n\n");
02838 
02839   COMMENT(INDENT[1],"Clock");               
02840   fprintf( output, "%ssc_clock clk(\"clk\",20,0.5,true);\n\n", INDENT[1]);
02841 
02842   COMMENT(INDENT[1],"%sISA simulator", INDENT[1]);               
02843   fprintf( output, "%s%s_arch %s(\"%s\");\n\n", INDENT[1], project_name, project_name, project_name);
02844   fprintf( output, "%s%s(clk.signal());\n\n", INDENT[1], project_name);
02845 
02846   if(ACGDBIntegrationFlag)
02847     fprintf( output, "%sgdbstub = new AC_GDB(%s.%s_mc, PORT_NUM);\n\n",
02848              INDENT[1], project_name, project_name );
02849 
02850   if (ACEncoderFlag) {
02851     fprintf( output, "%s//!Encoder tools\n", INDENT[1]);
02852     fprintf( output, "%sac_decoder_full *decoder = %s.%s_mc->ISA.decoder;\n", INDENT[1], project_name, project_name);
02853     fprintf( output, "%sac_encoder(ac,av,decoder);\n\n", INDENT[1]);
02854   }
02855 
02856   fprintf( output, "#ifdef AC_DEBUG\n");
02857   fprintf( output, "%sac_trace(\"%s.trace\");\n", INDENT[1], project_name);
02858   fprintf( output, "#endif \n\n");
02859 
02860   fprintf( output, "%sac_init(%s);\n\n", INDENT[1], project_name);
02861 
02862   fprintf( output, "%sac_start();\n\n", INDENT[1]);
02863 
02864   fprintf( output, "%scerr << endl;\n\n", INDENT[1]);
02865   fprintf( output, "%sPrintStat();\n", INDENT[1]);
02866   fprintf( output, "%scerr << endl;\n\n", INDENT[1]);
02867 
02868   fprintf( output, "#ifdef AC_STATS\n");
02869   fprintf( output, "%s%s.ac_sim_stats.time = sc_simulation_time();\n", INDENT[1], project_name);
02870   fprintf( output, "%s%s.ac_sim_stats.print();\n", INDENT[1], project_name);
02871   fprintf( output, "#endif \n\n");
02872 
02873   fprintf( output, "#ifdef AC_DEBUG\n");
02874   fprintf( output, "%sac_close_trace();\n", INDENT[1]);
02875   fprintf( output, "#endif \n\n");
02876 
02877   fprintf( output, "%sreturn 0;\n", INDENT[1]);
02878 
02879   fprintf( output, "}\n");
02880 }
02881 
02882 
02885 void CreateImplTmpl(){
02886 
02887   extern ac_dec_format *format_ins_list;
02888   extern ac_stg_list *stage_list;
02889   extern ac_dec_instr *instr_list;
02890   extern char *project_name;
02891   ac_dec_format *pformat;
02892   ac_dec_instr *pinstr;
02893   ac_stg_list *pstage;
02894 
02895   char filename[256];
02896   char description[] = "Behavior implementation file template.";
02897   char initfilename[] = "ac_isa_init.cpp";
02898 
02899   //File containing ISA declaration
02900   FILE  *output;
02901   
02902   sprintf( filename, "%s-isa.cpp.tmpl", project_name);
02903   if ( !(output = fopen( filename, "w"))){
02904     perror("ArchC could not open output file");
02905     exit(1);
02906   }
02907 
02908 
02909 
02910   print_comment( output, description);
02911 
02912   /* Parecem nao serem necessarios
02913      fprintf( output, "#include \"archc.H\"\n");
02914      fprintf( output, "#include \"ac_types.H\"\n");
02915      fprintf( output, "#include \"ac_parms.H\"\n");
02916   */
02917   fprintf( output, "#include  \"%s-isa.H\"\n", project_name);
02918   fprintf( output, "#include  \"%s\"\n", initfilename );
02919   fprintf( output, " \n");
02920 
02921   fprintf( output, " \n");
02922 
02923   //Declaring ac_instruction behavior method.
02924   COMMENT(INDENT[0],"Generic instruction behavior method.");               
02925   //Testing if should emit a switch or not.
02926   if( stage_list ){
02927     fprintf( output, "%svoid ac_behavior( instruction ){;\n\n", INDENT[0]); 
02928     fprintf( output, "%sswitch( stage ) {\n", INDENT[1]); 
02929                 
02930     for( pstage = stage_list; pstage != NULL; pstage=pstage->next){
02931       fprintf( output, "%scase _%s:\n", INDENT[1], pstage->name); 
02932       fprintf( output, "%sbreak;\n", INDENT[1]); 
02933     }
02934                 
02935     fprintf( output, "%sdefault:\n", INDENT[1]); 
02936                           fprintf( output, "%sbreak;\n", INDENT[1]); 
02937                           fprintf( output, "%s}\n", INDENT[1]);
02938                           fprintf( output, "};\n\n");  
02939   }
02940   else{
02941     fprintf( output, "%svoid ac_behavior( instruction ){};\n", INDENT[0]);
02942   }
02943         
02944   fprintf( output, " \n");
02945 
02946 
02947   //Declaring Instruction Format behavior methods.
02948   COMMENT(INDENT[0]," Instruction Format behavior methods.");               
02949   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next)
02950     //Testing if should emit a switch or not.
02951     if( stage_list ){
02952       fprintf( output, "%svoid ac_behavior( %s ){\n\n", INDENT[0], pformat->name); 
02953       fprintf( output, "%sswitch( stage ) {\n", INDENT[1]); 
02954       
02955       for( pstage = stage_list; pstage != NULL; pstage=pstage->next){
02956         fprintf( output, "%scase _%s:\n", INDENT[1], pstage->name); 
02957         fprintf( output, "%sbreak;\n", INDENT[1]); 
02958       }
02959       
02960       fprintf( output, "%sdefault:\n", INDENT[1]); 
02961                             fprintf( output, "%sbreak;\n", INDENT[1]); 
02962                             fprintf( output, "%s}\n", INDENT[1]);
02963                             fprintf( output, "};\n\n");  
02964     }
02965     else{
02966       fprintf( output, "%svoid ac_behavior( %s ){}\n", INDENT[0], pformat->name); 
02967     }
02968 
02969   fprintf( output, " \n");
02970 
02971 
02972   //Declaring each instruction behavior method.
02973   for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next){
02974     
02975     //Testing if should emit a switch or not.
02976     if( stage_list ){
02977       COMMENT(INDENT[0],"Instruction %s behavior method.",pinstr->name);               
02978       fprintf( output, "%svoid ac_behavior( %s ){\n\n", INDENT[0], pinstr->name); 
02979       fprintf( output, "%sswitch( stage ) {\n", INDENT[1]); 
02980       
02981       for( pstage = stage_list; pstage != NULL; pstage=pstage->next){
02982         fprintf( output, "%scase _%s:\n", INDENT[1], pstage->name); 
02983         fprintf( output, "%sbreak;\n", INDENT[1]); 
02984       }
02985       
02986       fprintf( output, "%sdefault:\n", INDENT[1]); 
02987                             fprintf( output, "%sbreak;\n", INDENT[1]); 
02988                             fprintf( output, "%s}\n", INDENT[1]);
02989                             fprintf( output, "};\n\n");  
02990     }
02991     else{
02992       COMMENT(INDENT[0],"Instruction %s behavior method.",pinstr->name);               
02993       fprintf( output, "%svoid ac_behavior( %s ){}\n\n", INDENT[0], pinstr->name); 
02994     }
02995   }
02996   
02998   fclose(output);
02999 
03000 
03001   //Now writing ISA initialization file.
03002   if ( !(output = fopen( initfilename, "w"))){
03003     perror("ArchC could not open output file");
03004     exit(1);
03005   }
03006     
03007   print_comment( output, "AC_ISA Initialization File");
03008   //Declaring static members.
03009   fprintf( output, "%s#include \"%s-isa.H\"\n", INDENT[0], project_name); 
03010   fprintf( output, "%s#include \"ac_reg.cpp\"\n\n", INDENT[0]); 
03011   COMMENT(INDENT[0],"Static member declarations.");               
03012   //Declaring the generic instruction object.
03013   fprintf( output, "%sac_instruction %s_isa::instruction(\"instruction\");\n", INDENT[0], project_name); 
03014 
03015   //Declaring each format object.
03016   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next)
03017     fprintf( output, "%sac_%s %s_isa::%s(\"%s\");\n", INDENT[0], pformat->name, project_name,pformat->name,pformat->name); 
03018 
03019   //Declaring each instruction object.
03020   for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next)
03021     fprintf( output, "%sac_%s %s_isa::%s(\"%s\", \"%s\", %d, %d);\n", INDENT[0], pinstr->name, project_name, pinstr->name, pinstr->name, pinstr->mnemonic, pinstr->min_latency, pinstr->max_latency); 
03022         
03023   
03025   fclose(output);
03026 
03027 }
03028 
03029 
03031 void CreateRegsImpl() {
03032   extern ac_sto_list *storage_list;
03033 
03034   ac_sto_list *pstorage;
03035 
03036   FILE *output;
03037   char filename[] = "ac_regs.cpp.tmpl";
03038   char description[] = "Formatted Register Behavior implementation file.";
03039  
03040   if ( !(output = fopen( filename, "w"))){
03041     perror("ArchC could not open output file");
03042     exit(1);
03043   }
03044 
03045 
03046 
03047   print_comment( output, description);
03048 
03049   fprintf( output, "#include \"ac_fmt_regs.H\"\n");
03050   fprintf( output, "#include \"archc.H\"\n");
03051   fprintf( output, " \n");
03052 
03053   //Declaring formatted register behavior methods.
03054   for( pstorage = storage_list; pstorage != NULL; pstorage = pstorage->next ){
03055 
03056     if(( pstorage->type == REG ) && (pstorage->format != NULL )){
03057       fprintf( output, "%svoid ac_behavior( %s ){}\n", INDENT[0], pstorage->name); 
03058     }
03059   }
03060   //END OF FILE.
03061   fclose(output);
03062 }
03063 
03064 
03066 void CreateArchSyscallHeader()
03067 {
03068   extern char *project_name;
03069   FILE *output;
03070   char filename[50];
03071 
03072   snprintf(filename, 50, "%s_syscall.H", project_name);
03073 
03074   if ( !(output = fopen( filename, "w"))){
03075     perror("ArchC could not open output file");
03076     exit(1);
03077   }
03078     
03079 
03080   print_comment( output, "ArchC Architecture Dependent Syscall header file.");
03081 
03082   fprintf(output,
03083           "#ifndef ARCH_SYSCALL_H\n"
03084           "#define ARCH_SYSCALL_H\n"
03085           "\n"
03086           "#include \"ac_syscall.H\"\n"
03087           "\n"
03088           "//%1$s system calls\n"
03089           "class %1$s_syscall : public ac_syscall\n"
03090           "{\n"
03091           "public:\n"
03092           "  void get_buffer(int argn, unsigned char* buf, unsigned int size);\n"
03093           "  void set_buffer(int argn, unsigned char* buf, unsigned int size);\n"
03094           "  void set_buffer_noinvert(int argn, unsigned char* buf, unsigned int size);\n"
03095           "  int  get_int(int argn);\n"
03096           "  void set_int(int argn, int val);\n"
03097           "  void return_from_syscall();\n"
03098           "  void set_prog_args(int argc, char **argv);\n"
03099           "};\n"
03100           "\n"
03101           "#endif\n"
03102           , project_name);
03103 
03104   fclose( output);
03105 }
03106 
03107 
03109 void CreateMakefile(){
03110 
03111   extern ac_pipe_list* pipe_list;
03112   extern ac_stg_list* stage_list;
03113   extern char *project_name;
03114   extern int HaveFormattedRegs;
03115   ac_stg_list *pstage;
03116   ac_pipe_list *ppipe;
03117   FILE *output;
03118   char filename[] = "Makefile.archc";
03119  
03120   if ( !(output = fopen( filename, "w"))){
03121     perror("ArchC could not open output file");
03122     exit(1);
03123   }
03124 
03125   COMMENT_MAKE("####################################################");
03126   COMMENT_MAKE("This is the Makefile for building the %s ArchC model", project_name);
03127   COMMENT_MAKE("This file is automatically generated by ArchC");
03128   COMMENT_MAKE("WITHOUT WARRANTY OF ANY KIND, either express");
03129   COMMENT_MAKE("or implied.");
03130   COMMENT_MAKE("For more information on ArchC, please visit:   ");
03131   COMMENT_MAKE("http://www.archc.org                           ");
03132   COMMENT_MAKE("                                               ");
03133   COMMENT_MAKE("The ArchC Team                                 ");
03134   COMMENT_MAKE("Computer Systems Laboratory (LSC)              ");
03135   COMMENT_MAKE("IC-UNICAMP                                     ");
03136   COMMENT_MAKE("http://www.lsc.ic.unicamp.br                   ");
03137   COMMENT_MAKE("####################################################");
03138 
03139   fprintf( output, "\n\n");
03140 
03141   COMMENT_MAKE("Variable that points to SystemC installation path");
03142   fprintf( output, "SYSTEMC := %s\n", SYSTEMC_PATH);
03143 
03144   fprintf( output, "\n\n");
03145   COMMENT_MAKE("Variable that points to ArchC installation path");
03146   fprintf( output, "ARCHC := %s\n", ARCHC_PATH);
03147 
03148   fprintf( output, "\n");
03149 
03150   COMMENT_MAKE("Target Arch used by SystemC");
03151   fprintf( output, "TARGET_ARCH := %s\n", TARGET_ARCH);
03152 
03153   fprintf( output, "\n\n");
03154         
03155   fprintf( output, "INC_DIR := -I. -I$(ARCHC)/include -I$(SYSTEMC)/include\n");
03156   fprintf( output, "LIB_DIR := -L. -L$(SYSTEMC)/lib-$(TARGET_ARCH)\n");
03157 
03158   fprintf( output, "\n");
03159  
03160   fprintf( output, "LIBS :=  -lsystemc -lm $(EXTRA_LIBS)\n");
03161   fprintf( output, "CC :=  %s\n", CC_PATH);
03162   fprintf( output, "OPT :=  %s\n", OPT_FLAGS);
03163   fprintf( output, "DEBUG :=  %s\n", DEBUG_FLAGS);
03164   fprintf( output, "OTHER :=  %s\n", OTHER_FLAGS);
03165   fprintf( output, "CFLAGS := $(DEBUG) $(OPT) $(OTHER) %s\n",
03166            (ACGDBIntegrationFlag) ? "-DUSE_GDB" : "" );
03167 
03168   fprintf( output, "\n");
03169  
03170   fprintf( output, "MODULE := %s\n", project_name);
03171 
03172   fprintf( output, "\n");
03173  
03174   //Declaring ACSRCS variable
03175 
03176   COMMENT_MAKE("These are the source files automatically generated by ArchC, that must appear in the SRCS variable");
03177   fprintf( output, "ACSRCS := ac_resources.cpp $(MODULE)-arch.cpp ");
03178 
03179   //Checking if we have a pipelined architecture or not.
03180   if( stage_list  ){  //List of ac_stage declarations. Used only for single pipe archs
03181                 
03182     for( pstage = stage_list; pstage!= NULL; pstage = pstage->next)
03183       fprintf( output, "%s.cpp ", pstage->name);
03184   }
03185   else if( pipe_list ){  //Pipeline list exist. Used for ac_pipe declarations.
03186                         
03187     for(ppipe = pipe_list; ppipe!= NULL; ppipe=ppipe->next){
03188 
03189       for(pstage=ppipe->stages; pstage!= NULL; pstage=pstage->next)
03190         fprintf( output, "%s_%s.cpp ", ppipe->name, pstage->name);
03191     }
03192   }
03193   else{    //No pipe was declared. There is just the processor module source file
03194 
03195     fprintf( output, "$(MODULE).cpp");
03196   }     
03197 
03198   fprintf( output, "\n\n");
03199  
03200   //Declaring ACINCS variable
03201   COMMENT_MAKE("These are the source files automatically generated  by ArchC that are included by other files in ACSRCS");
03202   fprintf( output, "ACINCS := ac_isa_init.cpp");
03203 
03204   fprintf( output, "\n\n");
03205 
03206   //Declaring ACHEAD variable
03207 
03208   COMMENT_MAKE("These are the header files automatically generated by ArchC");
03209   fprintf( output, "ACHEAD := ac_resources.H ac_types.H ac_parms.H $(MODULE)-arch.H $(MODULE)-isa.H ");
03210 
03211   if(HaveFormattedRegs)
03212     fprintf( output, "ac_fmt_regs.H ");
03213 
03214   if(ACStatsFlag)
03215     fprintf( output, "ac_stats.H ");
03216 
03217   //Checking if we have a pipelined architecture or not.
03218   if( stage_list  ){  //List of ac_stage declarations. Used only for single pipe archs
03219                 
03220     for( pstage = stage_list; pstage!= NULL; pstage = pstage->next)
03221       fprintf( output, "%s.H ", pstage->name);
03222   }
03223   else if( pipe_list ){  //Pipeline list exist. Used for ac_pipe declarations.
03224                         
03225     for(ppipe = pipe_list; ppipe!= NULL; ppipe=ppipe->next){
03226 
03227       for(pstage=ppipe->stages; pstage!= NULL; pstage=pstage->next)
03228         fprintf( output, "%s_%s.H ", ppipe->name, pstage->name);
03229     }
03230   }
03231   else{    //No pipe was declared. There is just the processor module source file
03232 
03233     fprintf( output, "$(MODULE).H ");
03234   }     
03235 
03236   if(ACABIFlag)
03237     fprintf( output, "$(MODULE)_syscall.H ");
03238 
03239   fprintf( output, "\n\n");
03240  
03241  
03242   //Declaring FILES variable
03243   COMMENT_MAKE("These are the source files provided by ArchC that must be compiled together with the ACSRCS");
03244   COMMENT_MAKE("They are stored in the archc/src/aclib directory");
03245   fprintf( output, "ACFILES := archc.cpp ac_storage.cpp ac_reg.cpp ac_cache.cpp ac_mem.cpp ac_cache_if.cpp %s", (ACGDBIntegrationFlag)?"ac_gdb.cpp breakpoints.cpp ":"");
03246 
03247   if(ACStatsFlag)
03248     fprintf( output, "ac_stats.cpp ");
03249                 
03250   if(ACABIFlag)
03251     fprintf( output, "ac_syscall.cpp ");
03252                 
03253   if(ACEncoderFlag)
03254     fprintf( output, "ac_encoder.cpp ");
03255                 
03256   fprintf( output, "\n\n");
03257 
03258   //Declaring FILESHEAD variable
03259   COMMENT_MAKE("These are the headers files provided by ArchC");
03260   COMMENT_MAKE("They are stored in the archc/include directory");
03261   fprintf( output, "ACFILESHEAD := $(ACFILES:.cpp=.H) ac_regbank.H\n\n");
03262 
03263   //Declaring SRCS variable
03264   COMMENT_MAKE("These are the source files provided by the user + ArchC sources");
03265   fprintf( output, "SRCS := main.cpp $(ACSRCS) $(ACFILES) $(MODULE)-isa.cpp %s",(ACGDBIntegrationFlag)?"$(MODULE)_gdb_funcs.cpp":"");
03266 
03267   if(ACABIFlag)
03268     fprintf( output, " $(MODULE)_syscall.cpp");
03269 
03270   fprintf( output, "\n\n");
03271 
03272   //Declaring OBJS variable
03273   fprintf( output, "OBJS := $(SRCS:.cpp=.o)\n");
03274 
03275   fprintf( output, "\n");
03276   //Declaring Executable name
03277   fprintf( output, "EXE := $(MODULE).x\n\n");
03278 
03279   //Declaring dependencie rules
03280   fprintf( output, ".SUFFIXES: .cc .cpp .o .x\n\n");
03281 
03282   fprintf( output, "all: $(ACFILESHEAD) $(ACFILES) $(EXE)\n\n");
03283 
03284   fprintf( output, "$(EXE): $(OBJS) $(SYSTEMC)/lib-$(TARGET_ARCH)/libsystemc.a\n");
03285   fprintf( output, "\t$(CC) $(CFLAGS) $(INC_DIR) $(LIB_DIR) -o $@ $(OBJS) $(ARCHC)/lib/ac_decoder.o $(LIBS) 2>&1 | c++filt\n\n");
03286 
03287   COMMENT_MAKE("Copy from template if main.cpp not exist");
03288   fprintf( output, "main.cpp:\n");
03289   fprintf( output, "\tcp main.cpp.tmpl main.cpp\n\n");
03290 
03291   fprintf( output, ".cpp.o:\n");
03292   fprintf( output, "\t$(CC) $(CFLAGS) $(INC_DIR) -c $<\n\n");
03293 
03294   fprintf( output, ".cc.o:\n");
03295   fprintf( output, "\t$(CC) $(CFLAGS) $(INC_DIR) -c $<\n\n");
03296 
03297   fprintf( output, "clean:\n");
03298   fprintf( output, "\trm -f $(OBJS) *~ $(EXE) core *.o\n\n");
03299 
03300   fprintf( output, "model_clean:\n");
03301   fprintf( output, "\trm -f $(ACSRCS) $(ACHEAD) $(ACINCS) $(ACFILESHEAD) $(ACFILES) *.tmpl loader.ac\n\n");
03302 
03303   fprintf( output, "sim_clean: clean model_clean\n\n");
03304 
03305   fprintf( output, "distclean: sim_clean\n");
03306   fprintf( output, "\trm -f main.cpp Makefile.archc\n\n");
03307 
03308   fprintf( output, "%%.cpp: $(ARCHC)/src/aclib/ac_storage/%%.cpp\n");
03309   fprintf( output, "\tcp $< $@\n");
03310 
03311   fprintf( output, "%%.cpp: $(ARCHC)/src/aclib/ac_syscall/%%.cpp\n");
03312   fprintf( output, "\tcp $< $@\n");
03313 
03314   fprintf( output, "%%.cpp: $(ARCHC)/src/aclib/ac_utils/%%.cpp\n");
03315   fprintf( output, "\tcp $< $@\n");
03316 
03317   if(ACGDBIntegrationFlag) {
03318     fprintf( output, "%%.cpp: $(ARCHC)/src/aclib/ac_gdb/%%.cpp\n");
03319     fprintf( output, "\tcp $< $@\n");
03320   }
03321 
03322   if(ACEncoderFlag) {
03323     fprintf( output, "%%.cpp: $(ARCHC)/src/aclib/ac_encoder/%%.cpp\n");
03324     fprintf( output, "\tcp $< $@\n");
03325   }
03326 
03327   fprintf( output, "%%.H: $(ARCHC)/include/%%.H\n");
03328   fprintf( output, "\tcp $< $@\n");
03329 }
03330 
03332 // Emit functions ...                                                             //
03333 // These Functions are used by the Create functions declared above to write files //
03335 
03336 /**************************************/
03339 /***************************************/
03340 void EmitGenInstrClass(FILE *output) {
03341   extern ac_dec_format *format_ins_list;
03342   ac_dec_format *pformat;
03343   ac_dec_field *pfield , *pgenfield, *pf, *ppf;
03344   int initializing = 1;
03345         
03346   /* Emiting generic instruction class declaration */
03347   COMMENT(INDENT[0],"Generic Instruction Class declaration.\n"); 
03348   fprintf( output, "class ac_instruction: public ac_resources {\n");
03349   fprintf( output, "protected:\n");
03350   fprintf( output, "%schar* ac_instr_name;\n", INDENT[1]);
03351   fprintf( output, "%schar* ac_instr_mnemonic;\n", INDENT[1]);
03352   fprintf( output, "%sunsigned ac_instr_size;\n", INDENT[1]);
03353   fprintf( output, "%sunsigned ac_instr_cycles;\n", INDENT[1]);
03354   fprintf( output, "%sunsigned ac_instr_min_latency;\n", INDENT[1]);
03355   fprintf( output, "%sunsigned ac_instr_max_latency;\n", INDENT[1]);
03356 
03357   //Selecting fields that are common to all formats.
03358   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next){
03359 
03360     if( initializing ){
03361 
03362       //This is the first format being processed. Put all of its fields.
03363       for( pfield = pformat->fields; pfield != NULL; pfield = pfield->next){
03364 
03365         pf = (ac_dec_field*) malloc( sizeof(ac_dec_field));
03366         pf = memcpy( pf, pfield, sizeof(ac_dec_field) );
03367 
03368         if( pfield == pformat->fields ){
03369           pgenfield = pf;
03370           pgenfield->next = NULL;
03371         }
03372         else{
03373           pf->next = pgenfield;
03374           pgenfield = pf;
03375         }
03376       }
03377       initializing =0;
03378                         
03379     }
03380     else{  //We already have candidate fields. Check if they are present in all formats.
03381 
03382       ppf = NULL;
03383 
03384       //Keep fields that are common to all instructions
03385       pf = pgenfield; 
03386 
03387       while( pf ){
03388 
03389         //Looking for pf into pformat
03390         for( pfield = pformat->fields; pfield != NULL; pfield = pfield->next){ 
03391 
03392           if( !strcmp( pf->name, pfield->name) )
03393             break;
03394         }
03395 
03396         if( !pfield) { //Did not find. Delete pf from pgenfield
03397                                         
03398           if(ppf){
03399             ppf->next = pf->next;
03400             free(pf);
03401             pf = ppf->next;
03402           }
03403           else{  //Deleting the first field
03404             pgenfield = pf->next;
03405             free(pf);
03406             pf = pgenfield;
03407           }
03408         }
03409         else{  //Found. Keep the field and step to the next.
03410           ppf = pf;
03411           pf = pf->next;
03412         }
03413       }
03414     }   
03415   }
03416 
03417   //pgenfield has the list of fields for the generic instruction.
03418   for( pfield = pgenfield; pfield != NULL; pfield = pfield->next){
03419     if( pfield->sign )
03420       fprintf( output,"%sint %s;\n",INDENT[1],pfield->name );
03421     else
03422       fprintf( output,"%sunsigned %s;\n",INDENT[1],pfield->name );
03423   }
03424 
03425   //Now emiting public methods
03426   fprintf( output, "public:\n");
03427 
03428   fprintf( output, "%sac_instruction( char* name, char* mnemonic, unsigned min, unsigned max ){ ac_instr_name = name ; ac_instr_mnemonic = mnemonic; ac_instr_min_latency = min, ac_instr_max_latency =max;}\n", INDENT[1]);
03429   fprintf( output, "%sac_instruction( char* name, char* mnemonic ){ ac_instr_name = name ; ac_instr_mnemonic = mnemonic;}\n", INDENT[1]);
03430   fprintf( output, "%sac_instruction( char* name ){ ac_instr_name = name ;}\n", INDENT[1]);
03431   fprintf( output, "%sac_instruction( ){ ac_instr_name = \"NULL\";}\n", INDENT[1]);
03432 
03433   fprintf( output, "%svirtual void behavior(ac_stage_list  stage = (ac_stage_list)0, unsigned cycle=0);\n", INDENT[1]);   
03434 
03435   fprintf( output, "%svoid set_cycles( unsigned c){ ac_instr_cycles = c;}\n", INDENT[1]);
03436   fprintf( output, "%sunsigned get_cycles(){ return ac_instr_cycles;}\n", INDENT[1]);
03437 
03438   fprintf( output, "%svoid set_min_latency( unsigned c){ ac_instr_min_latency = c;}\n", INDENT[1]);
03439   fprintf( output, "%sunsigned get_min_latency(){ return ac_instr_min_latency;}\n", INDENT[1]);
03440 
03441   fprintf( output, "%svoid set_max_latency( unsigned c){ ac_instr_max_latency = c;}\n", INDENT[1]);
03442   fprintf( output, "%sunsigned get_max_latency(){ return ac_instr_max_latency;}\n", INDENT[1]);
03443 
03444   fprintf( output, "%sunsigned get_size() {return ac_instr_size;}\n", INDENT[1]);
03445   fprintf( output, "%svoid set_size( unsigned s) {ac_instr_size = s;}\n", INDENT[1]);
03446 
03447   fprintf( output, "%schar* get_name() {return ac_instr_name;}\n", INDENT[1]);
03448   fprintf( output, "%svoid set_name( char* name) {ac_instr_name = name;}\n", INDENT[1]);
03449 
03450   fprintf( output, "%svirtual void set_fields( ac_instr instr ){\n",INDENT[1]);
03451   
03452   for( pfield = pgenfield; pfield != NULL; pfield = pfield->next)
03453     fprintf( output,"%s%s = instr.get(%d); \n", INDENT[2],pfield->name, pfield->id );
03454         
03455   //fprintf( output,"%sac_instr_size = %d; \n", INDENT[2], pformat->size );
03456   fprintf( output, "%s}\n", INDENT[1]);
03457 
03458 
03459 
03460   fprintf( output, "%svirtual  void print (ostream & os) const{};\n", INDENT[1]);
03461 
03462   fprintf( output, "%sfriend ostream& operator<< (ostream &os,const ac_instruction &ins){\n", INDENT[1]);
03463   fprintf( output, "%sins.print(os);\n", INDENT[1]);
03464   fprintf( output, "%sreturn os;\n", INDENT[1]);
03465   fprintf( output, "%s};\n", INDENT[1]);
03466 
03467   fprintf( output, "};\n\n");
03468         
03469 }
03470 
03471 /**************************************/
03474 /***************************************/
03475 void EmitFormatClasses(FILE *output) {
03476   extern ac_dec_format *format_ins_list;
03477   ac_dec_format *pformat;
03478   ac_dec_field *pfield;
03479 
03480   /* Emiting format class declaration */
03481   COMMENT(INDENT[0],"Instruction Format class declarations.\n"); 
03482 
03483   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next){
03484 
03485     fprintf( output, "class ac_%s: public ac_instruction {\n", pformat->name); 
03486     fprintf( output, "protected:\n");
03487 
03488     for( pfield = pformat->fields; pfield != NULL; pfield = pfield->next){
03489       if( pfield->sign )
03490         fprintf( output,"%sint %s;\n",INDENT[1],pfield->name );
03491       else
03492         fprintf( output,"%sunsigned %s;\n",INDENT[1],pfield->name );
03493     }
03494 
03495     fprintf( output, "public:\n");
03496     fprintf( output, "%sac_%s( char* name, char* mnemonic, unsigned min, unsigned max ):ac_instruction(name, mnemonic, min, max){};\n", INDENT[1], pformat->name);
03497     fprintf( output, "%sac_%s( char* name, char *mnemonic ):ac_instruction(name, mnemonic) {};\n", INDENT[1], pformat->name);
03498     fprintf( output, "%sac_%s( char* name ):ac_instruction(name) {};\n", INDENT[1], pformat->name);
03499     fprintf( output, "%sac_%s( ):ac_instruction() {};\n", INDENT[1], pformat->name);
03500     fprintf( output, "%svoid set_fields( ac_instr instr ){\n",INDENT[1]);
03501   
03502     for( pfield = pformat->fields; pfield != NULL; pfield = pfield->next)
03503       fprintf( output,"%s%s = instr.get(%d); \n", INDENT[2],pfield->name, pfield->id );
03504 
03505     fprintf( output,"%sac_instr_size = %d; \n", INDENT[2], pformat->size );
03506 
03507     fprintf( output, "%s}\n", INDENT[1]);
03508 
03509     fprintf( output, "%svirtual void behavior( ac_stage_list stage=(ac_stage_list)0, unsigned cycle=0 );\n", INDENT[1]);
03510 
03511 
03512     //Print method
03513     fprintf( output, "%svirtual void print (ostream & os) const{\n", INDENT[1]);
03514     fprintf( output, "%sos ", INDENT[2]);
03515 
03516     for( pfield = pformat->fields; pfield != NULL; pfield = pfield->next)
03517       if(pfield->next)
03518         fprintf( output, " << \"%s: \" << %s << \", \" ",  pfield->name,  pfield->name);
03519       else
03520         fprintf( output, " << \"%s: \" << %s;", pfield->name,  pfield->name);
03521 
03522     fprintf( output, "\n}\n");
03523 
03524     fprintf( output, "};\n\n");
03525   }
03526 }
03527 
03528 /*!*************************************/
03531 /***************************************/
03532 void EmitInstrClasses( FILE *output){
03533 
03534   extern ac_dec_instr *instr_list;
03535   ac_dec_instr *pinstr;
03536 
03537   COMMENT(INDENT[0],"Instruction class declarations.\n"); 
03538 
03539   for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next){
03540     fprintf( output, "class ac_%s: public ac_%s {\n", pinstr->name, pinstr->format); 
03541     fprintf( output, "%spublic:\n", INDENT[0]);
03542     fprintf( output, "%sac_%s( char* name, char* mnemonic, unsigned min, unsigned max ):ac_%s(name, mnemonic, min, max){};\n", INDENT[1], pinstr->name, pinstr->format);
03543     fprintf( output, "%sac_%s( char* name, char *mnemonic ):ac_%s(name, mnemonic) {};\n", INDENT[1], pinstr->name, pinstr->format);
03544     fprintf( output, "%sac_%s( char* name ):ac_%s(name) {};\n", INDENT[1], pinstr->name, pinstr->format);
03545     fprintf( output, "%sac_%s( ):ac_%s() {};\n", INDENT[1], pinstr->name, pinstr->format);
03546     fprintf( output, "%svoid behavior( ac_stage_list  stage = (ac_stage_list)0, unsigned cycle=0 );\n", INDENT[1]);
03547 
03548     //Print method
03549     fprintf( output, "%svoid print (ostream & os) const{\n", INDENT[1]);
03550     fprintf( output, "%sos << ac_instr_mnemonic << \"\t\";", INDENT[2]);
03551     fprintf( output, "}\n");
03552 
03553     fprintf( output, "};\n\n");
03554   }
03555 }
03556 
03557 /**************************************/
03560 /***************************************/
03561 void EmitDecStruct( FILE* output){
03562   extern ac_dec_format *format_ins_list;
03563   extern ac_dec_instr *instr_list;
03564   extern int declist_num;
03565   extern int HaveMultiCycleIns;
03566   ac_dec_field *pdecfield;
03567   ac_dec_format *pformat;
03568   ac_dec_instr *pinstr;
03569   ac_dec_list *pdeclist;
03570   int i;
03571   int count_fields;
03572 
03573   //fprintf( output, "%sunsigned counter;\n", INDENT[2]); 
03574   fprintf( output, "%sextern ac_dec_field *fields;\n", INDENT[2]); 
03575   fprintf( output, "%sextern ac_dec_format *formats;\n", INDENT[2]); 
03576   fprintf( output, "%sextern ac_dec_list *dec_list;\n", INDENT[2]); 
03577   fprintf( output, "%sextern ac_dec_instr *instructions;\n\n", INDENT[2]); 
03578 
03579   //Field Structure
03580   fprintf( output, "%sfields = (ac_dec_field*) malloc(sizeof(ac_dec_field)*AC_DEC_FIELD_NUMBER);\n", INDENT[2]);
03581   i = 0;
03582   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next){
03583 
03584     for( pdecfield = pformat->fields; pdecfield!= NULL; pdecfield=pdecfield->next){
03585       fprintf( output, "%sfields[%d].name      = \"%s\";\n", INDENT[2], i, pdecfield->name);
03586       fprintf( output, "%sfields[%d].size      = %d;\n", INDENT[2], i, pdecfield->size);
03587       fprintf( output, "%sfields[%d].first_bit = %d;\n", INDENT[2], i, pdecfield->first_bit);
03588       fprintf( output, "%sfields[%d].id        = %d;\n", INDENT[2], i, pdecfield->id);
03589       fprintf( output, "%sfields[%d].val       = %ld;\n", INDENT[2], i, pdecfield->val);
03590       fprintf( output, "%sfields[%d].sign      = %d;\n", INDENT[2], i, pdecfield->sign);
03591       if(pdecfield->next)
03592         fprintf( output, "%sfields[%d].next      = &(fields[%d]);\n\n", INDENT[2], i, i+1);
03593       else
03594         fprintf( output, "%sfields[%d].next      = NULL;\n\n", INDENT[2], i);
03595       i++;
03596     }
03597   }
03598 
03599   fprintf( output, " \n");
03600 
03601   //Format Structure
03602   fprintf( output, "%sformats = (ac_dec_format*) malloc(sizeof(ac_dec_format)*AC_DEC_FORMAT_NUMBER);\n", INDENT[2]);
03603   i = 0;
03604   count_fields = 0;
03605   for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next){
03606 
03607     fprintf( output, "%sformats[%d].name      = \"%s\";\n", INDENT[2], i, pformat->name);
03608     fprintf( output, "%sformats[%d].fields    = &(fields[%d]);\n", INDENT[2], i, count_fields);
03609     if(pformat->next)
03610       fprintf( output, "%sformats[%d].next      = &(formats[%d]);\n\n", INDENT[2], i, i+1);
03611     else
03612       fprintf( output, "%sformats[%d].next      = NULL;\n\n", INDENT[2], i);
03613     i++;
03614     for( pdecfield = pformat->fields; pdecfield!= NULL; pdecfield=pdecfield->next)
03615       count_fields++;    
03616   }
03617 
03618   fprintf( output, " \n");
03619 
03620   //Decode list Structure
03621   fprintf( output, "%sdec_list = (ac_dec_list*) malloc(sizeof(ac_dec_list)*AC_DEC_LIST_NUMBER);\n", INDENT[2]);
03622   i = 0;
03623   for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next){
03624 
03625     for( pdeclist = pinstr->dec_list; pdeclist!= NULL; pdeclist=pdeclist->next){
03626       fprintf( output, "%sdec_list[%d].name      = \"%s\";\n", INDENT[2], i, pdeclist->name);
03627       fprintf( output, "%sdec_list[%d].value     = %d;\n", INDENT[2], i, pdeclist->value);
03628       if(pdeclist->next)
03629         fprintf( output, "%sdec_list[%d].next      = &(dec_list[%d]);\n\n", INDENT[2], i, i+1);
03630       else
03631         fprintf( output, "%sdec_list[%d].next      = NULL;\n\n", INDENT[2], i);
03632       i++;
03633     }
03634   }
03635   declist_num = i;
03636 
03637   fprintf( output, " \n");
03638 
03639   //Instruction Structure
03640   fprintf( output, "%sinstructions = (ac_dec_instr*) malloc(sizeof(ac_dec_instr)*AC_DEC_INSTR_NUMBER);\n", INDENT[2]);
03641   i = 0;
03642   count_fields = 0;
03643   for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next){
03644     fprintf( output, "%sinstructions[%d].name      = \"%s\";\n", INDENT[2], i, pinstr->name);
03645     fprintf( output, "%sinstructions[%d].mnemonic  = \"%s\";\n", INDENT[2], i, pinstr->mnemonic);
03646     fprintf( output, "%sinstructions[%d].asm_str   = \"%s\";\n", INDENT[2], i, pinstr->asm_str);
03647     fprintf( output, "%sinstructions[%d].format    = \"%s\";\n", INDENT[2], i, pinstr->format);
03648     fprintf( output, "%sinstructions[%d].id        = %d;\n", INDENT[2], i, pinstr->id);
03649     if(HaveMultiCycleIns)
03650       fprintf( output, "%sinstructions[%d].cycles    = %d;\n", INDENT[2], i, pinstr->cycles);
03651 
03652     fprintf( output, "%sinstructions[%d].dec_list  = &(dec_list[%d]);\n", INDENT[2], i, count_fields);
03653     if(pinstr->next)
03654       fprintf( output, "%sinstructions[%d].next      = &(instructions[%d]);\n\n", INDENT[2], i, i+1);
03655     else
03656       fprintf( output, "%sinstructions[%d].next      = NULL;\n\n", INDENT[2], i);
03657 
03658     for( pdeclist = pinstr->dec_list; pdeclist!= NULL; pdeclist=pdeclist->next)
03659       count_fields++;
03660     i++;
03661   }
03662 
03663 }
03664 
03665 
03666 
03667 /**************************************/
03670 /***************************************/
03671 void EmitPipeUpdateMethod( FILE *output){
03672   extern ac_stg_list *stage_list;
03673   extern char *project_name;
03674   ac_stg_list *pstage;
03675   extern ac_sto_list *storage_list;
03676   ac_sto_list *pstorage;
03677 
03678   //Emiting Update Method.
03679   COMMENT(INDENT[0],"Updating Pipe Regs for behavioral simulation.");               
03680   fprintf( output, "%svoid %s_arch::ac_update_regs(){\n", INDENT[0], project_name);        
03681   fprintf( output, "%sstatic ac_instr nop;\n\n", INDENT[1]);
03682 
03683   for( pstage = stage_list; pstage->next != NULL; pstage=pstage->next){   
03684 
03685     fprintf( output, "%sif( !%s_stall )\n", INDENT[1], pstage->name);        
03686 
03687     fprintf( output, "%sif( %s_flush ){\n", INDENT[2], pstage->name);        
03688     fprintf( output, "%s%s_regin.write( nop );\n", INDENT[3], pstage->next->name);        
03689     fprintf( output, "%s%s_flush = 0;\n", INDENT[3], pstage->name);        
03690     fprintf( output, "%s}\n", INDENT[2]);        
03691 
03692     fprintf( output, "%selse\n", INDENT[2]);        
03693     fprintf( output, "%s%s_regin.write( %s_regout.read() );\n", INDENT[3], pstage->next->name, pstage->name);        
03694 
03695     fprintf( output, "%selse\n", INDENT[1]);        
03696     fprintf( output, "%s%s_stall = 0;\n", INDENT[2], pstage->name);        
03697     fprintf( output, "\n");
03698 
03699   }
03700 
03701   if( ACDelayFlag ){
03702     for( pstorage = storage_list; pstorage!= NULL; pstorage = pstorage->next )
03703       //TODO: Support Delayed assignment for formatted regs
03704       if( pstorage->format == NULL )
03705         fprintf( output, "%s%s.commit_delays( sc_simulation_time() );\n", INDENT[1], pstorage->name);
03706 
03707     fprintf( output, "%sac_pc.commit_delays( sc_simulation_time() );\n", INDENT[1]);
03708   }
03709 
03710   fprintf( output, "%sbhv_pc.write( ac_pc );\n", INDENT[1]);
03711 
03712   fprintf( output, "%s}\n", INDENT[0]);
03713 }
03714 
03715 /**************************************/
03718 /***************************************/
03719 void EmitMultiPipeUpdateMethod( FILE *output){
03720 
03721   extern ac_pipe_list *pipe_list;
03722   extern char *project_name;
03723   ac_stg_list *pstage;
03724   ac_pipe_list *ppipe;
03725   extern ac_sto_list *storage_list;
03726   ac_sto_list *pstorage;
03727 
03728   //Emiting Update Method.
03729   COMMENT(INDENT[0],"Updating Pipe Regs for behavioral simulation.");               
03730   fprintf( output, "%svoid %s_arch::ac_update_regs(){\n", INDENT[0], project_name);        
03731   fprintf( output, "%sstatic ac_instr nop;\n\n", INDENT[1]);
03732 
03733   for ( ppipe = pipe_list; ppipe != NULL; ppipe=ppipe->next ){
03734 
03735     for( pstage = ppipe->stages; pstage->next != NULL; pstage=pstage->next){   
03736 
03737       fprintf( output, "%sif( !%s_%s_stall )\n", INDENT[1], ppipe->name, pstage->name);        
03738 
03739       fprintf( output, "%sif( %s_%s_flush ){\n", INDENT[2], ppipe->name, pstage->name);        
03740       fprintf( output, "%s%s_%s_regin.write( nop );\n", INDENT[3], ppipe->name, pstage->next->name);        
03741       fprintf( output, "%s%s_%s_flush = 0;\n", INDENT[3], ppipe->name, pstage->name);        
03742       fprintf( output, "%s}\n", INDENT[2]);        
03743                         
03744       fprintf( output, "%selse\n", INDENT[2]);        
03745       fprintf( output, "%s%s_%s_regin.write( %s_%s_regout.read() );\n", INDENT[3], ppipe->name, pstage->next->name, ppipe->name, pstage->name);        
03746                         
03747       fprintf( output, "%selse\n", INDENT[1]);        
03748       fprintf( output, "%s%s_%s_stall = 0;\n", INDENT[2], ppipe->name, pstage->name);        
03749       fprintf( output, "\n");
03750                         
03751     }
03752   }
03753 
03754   if( ACDelayFlag ){
03755     for( pstorage = storage_list; pstorage!= NULL; pstorage = pstorage->next )
03756       //TODO: Support Delayed assignment for formatted regs
03757       if( pstorage->format == NULL )
03758         fprintf( output, "%s%s.commit_delays( sc_simulation_time() );\n", INDENT[1], pstorage->name);
03759                 
03760     fprintf( output, "%sac_pc.commit_delays( sc_simulation_time() );\n", INDENT[1]);
03761   }
03762         
03763   fprintf( output, "%sbhv_pc.write( ac_pc );\n", INDENT[1]);
03764         
03765   fprintf( output, "%s}\n", INDENT[0]);
03766 }
03767 
03768 /**************************************/
03771 /***************************************/
03772 void EmitUpdateMethod( FILE *output){
03773 
03774   extern char *project_name;
03775   extern int HaveMultiCycleIns, HaveMemHier;
03776   extern ac_sto_list *storage_list;
03777   ac_sto_list *pstorage;
03778 
03779   //Emiting Update Method.
03780   COMMENT(INDENT[0],"Updating Regs for behavioral simulation.");               
03781   fprintf( output, "%svoid %s_arch::ac_update_regs(){\n", INDENT[0], project_name);        
03782 
03783   fprintf( output, "%sif(!ac_wait_sig){\n", INDENT[1]);
03784   if( ACDelayFlag ){
03785     for( pstorage = storage_list; pstorage!= NULL; pstorage = pstorage->next ) 
03786       fprintf( output, "%s%s.commit_delays( (double)ac_cycle_counter );\n", INDENT[2], pstorage->name);
03787     fprintf( output, "%sac_pc.commit_delays(  (double)ac_cycle_counter );\n", INDENT[2]);
03788 
03789     fprintf( output, "%sif(!ac_parallel_sig)\n", INDENT[2]);
03790     fprintf( output, "%sac_cycle_counter+=1;\n", INDENT[3]);
03791     fprintf( output, "%selse\n", INDENT[2]);
03792     fprintf( output, "%sac_parallel_sig = 0;\n\n", INDENT[3]);
03793 
03794   }
03795         
03796   fprintf( output, "%sbhv_pc.write( ac_pc );\n", INDENT[2]);
03797   if( HaveMultiCycleIns)
03798     fprintf( output, "%sbhv_cycle.write( ac_cycle );\n", INDENT[2]);
03799   fprintf( output, "%s}\n", INDENT[1]);
03800   /*   fprintf( output, "%selse{\n", INDENT[1]); */
03801   /*   fprintf( output, "%sdo_it = do_it.read()^1;\n", INDENT[2]); */
03802   /*   fprintf( output, "%s}\n", INDENT[1]); */
03803 
03804   if( HaveMemHier ){
03805     for( pstorage = storage_list; pstorage!= NULL; pstorage = pstorage->next ) {
03806       if( pstorage->type == CACHE || pstorage->type == ICACHE || pstorage->type == DCACHE || pstorage->type == MEM )
03807         fprintf( output, "%s%s.process_request( );\n", INDENT[1], pstorage->name);
03808     }
03809   }
03810   fprintf( output, "%sdo_it = do_it ^1;\n", INDENT[1]);
03811   fprintf( output, "%s}\n", INDENT[0]);
03812 }
03813 
03814 /**************************************/
03817 /***************************************/
03818 void EmitDecodification( FILE *output, int base_indent){
03819 
03820   extern int wordsize, fetchsize;
03821 
03822   if( ACDecCacheFlag ){
03823     base_indent++;
03824     fprintf( output, "%sins_cache = (DEC_CACHE+(decode_pc/(AC_FETCHSIZE/8)));\n", INDENT[base_indent]);
03825     fprintf( output, "%sif ( !ins_cache->valid ){\n", INDENT[base_indent]);
03826   }
03827 
03828   if (fetchsize == wordsize)
03829     fprintf( output, "%s*((ac_fetch*)(fetch)) = IM->read( decode_pc );\n\n", INDENT[base_indent+1]);
03830   else if (fetchsize == wordsize/2)
03831     fprintf( output, "%s*((ac_fetch*)(fetch)) = IM->read_half( decode_pc );\n\n", INDENT[base_indent+1]);
03832   else if (fetchsize == 8)
03833     fprintf( output, "%s*((ac_fetch*)(fetch)) = IM->read_byte( decode_pc );\n\n", INDENT[base_indent+1]);
03834   else {
03835     AC_ERROR("Fetchsize differs from wordsize or (wordsize/2) or 8: not implemented.");
03836     exit(EXIT_FAILURE);
03837   }
03838 
03839   fprintf( output, "%sif( ac_wait_sig ) {\n", INDENT[base_indent+1]);
03840   fprintf( output, "%sreturn;\n", INDENT[base_indent+2]);
03841   fprintf( output, "%s}\n", INDENT[base_indent+1]);
03842 
03843   fprintf( output, "%squant = AC_FETCHSIZE/8;\n", INDENT[base_indent+1]);
03844 
03845   //The Decoder uses a big endian bit stream. So if the host is little endian, convert it!
03846   if( ac_host_endian == 0 ){
03847     fprintf( output, "%sfor (i=0; i< AC_FETCHSIZE/8; i++) {\n", INDENT[base_indent+1]);
03848     fprintf( output, "%sbuffer[quant - 1 - i] = fetch[i];\n", INDENT[base_indent+2]);
03849     fprintf( output, "%s}\n", INDENT[base_indent+1]);
03850   }
03851 
03852   if( ACDecCacheFlag ){
03853     fprintf( output, "%sins_cache->instr_p = new ac_instr( Decode(ISA.decoder, buffer, quant));\n", INDENT[base_indent+1]);
03854     fprintf( output, "%sins_cache->valid = 1;\n", INDENT[base_indent+1]);
03855     fprintf( output, "%s}\n", INDENT[base_indent]);
03856     fprintf( output, "%sinstr_vec = ins_cache->instr_p;\n", INDENT[base_indent]);
03857   }
03858   else{
03859     fprintf( output, "%sinstr_dec = Decode(ISA.decoder, buffer, quant);\n", INDENT[base_indent]);
03860     fprintf( output, "%sinstr_vec = new ac_instr( instr_dec);\n", INDENT[base_indent]);
03861   }
03862 
03863   //Checking if it is a valid instruction
03864   fprintf( output, "%sins_id = instr_vec->get(IDENT);\n\n", INDENT[base_indent]);
03865   fprintf( output, "%sif( ins_id == 0 ) {\n", INDENT[base_indent]);
03866   fprintf( output, "%scerr << \"ArchC Error: Unidentified instruction. \" << endl;\n", INDENT[base_indent+1]);
03867   fprintf( output, "%scerr << \"PC = \" << hex << decode_pc << dec << endl;\n", INDENT[base_indent+1]);
03868   fprintf( output, "%sac_stop();\n", INDENT[base_indent+1]);
03869   fprintf( output, "%sreturn;\n", INDENT[base_indent+1]);
03870   fprintf( output, "%s}\n", INDENT[base_indent]);
03871 
03872   fprintf( output, "\n");
03873 
03874 }
03875 
03876 /**************************************/
03879 /***************************************/
03880 void EmitInstrExec( FILE *output, int base_indent){
03881   extern ac_stg_list *stage_list;
03882   extern ac_pipe_list *pipe_list;
03883   extern int HaveCycleRange;
03884 
03885   if( ACGDBIntegrationFlag )
03886     fprintf( output, "%sif (gdbstub && gdbstub->stop(decode_pc)) gdbstub->process_bp();\n\n", INDENT[base_indent]);
03887   
03888   fprintf( output, "%sinstr = (ac_instruction *)ISA.instr_table[ins_id][1];\n", INDENT[base_indent]);
03889   fprintf( output, "%sformat = (ac_instruction *)ISA.instr_table[ins_id][2];\n", INDENT[base_indent]);
03890   fprintf( output, "%sISA.instruction.set_fields( *instr_vec  );\n", INDENT[base_indent]);
03891   fprintf( output, "%sformat->set_fields( *instr_vec  );\n", INDENT[base_indent]);
03892   fprintf( output, "%sinstr->set_fields( *instr_vec  );\n", INDENT[base_indent]);
03893   fprintf( output, "%sISA.instruction.set_size(instr->get_size());\n", INDENT[base_indent]);
03894   fprintf( output, "%sac_pc = decode_pc;\n", INDENT[base_indent]);
03895 
03896   //Pipelined archs can annul an instruction through pipelining flushing.
03897   if(stage_list || pipe_list ){
03898     fprintf( output, "%sISA.instruction.behavior( (ac_stage_list) id );\n", INDENT[base_indent]);
03899     fprintf( output, "%sformat->behavior((ac_stage_list) id );\n", INDENT[base_indent]);
03900     fprintf( output, "%sinstr->behavior((ac_stage_list) id );\n", INDENT[base_indent]);
03901   }
03902   else{
03903     fprintf( output, "%sISA.instruction.behavior( );\n", INDENT[base_indent]);
03904     fprintf( output, "%sif(!ac_annul_sig) format->behavior( );\n", INDENT[base_indent]);
03905     fprintf( output, "%sif(!ac_annul_sig) instr->behavior( );\n", INDENT[base_indent]);
03906     fprintf( output, "%selse ac_annul_sig = 0;\n", INDENT[base_indent]);
03907   }
03908 
03909   if( ACDasmFlag ){
03910     fprintf( output, PRINT_DASM , INDENT[base_indent]);
03911   }
03912 
03913   if( ACStatsFlag ){
03914     fprintf( output, "%sac_sim_stats.instr_executed++;;\n", INDENT[base_indent]);
03915     fprintf( output, "%sac_sim_stats.instr_table[ins_id][2]++;\n", INDENT[base_indent]);
03916 
03917     //If cycle range for instructions were declared, include them on the statistics.
03918     if( HaveCycleRange ){
03919       fprintf( output, "%sac_sim_stats.ac_min_cycle_count += instr->get_min_latency();\n", INDENT[base_indent]);
03920       fprintf( output, "%sac_sim_stats.ac_max_cycle_count += instr->get_max_latency();\n", INDENT[base_indent]);
03921     }
03922   }
03923 
03924   if( ACDebugFlag ){
03925     fprintf( output, "%sif( ac_do_trace != 0 ) \n", INDENT[base_indent]);
03926     fprintf( output, PRINT_TRACE, INDENT[base_indent+1]);
03927   }
03928 
03929   if( stage_list || pipe_list )
03930     fprintf( output, "%sregout.write( *instr_vec);\n", INDENT[base_indent]);
03931 
03932   if(!ACDecCacheFlag){
03933     fprintf( output, "%sdelete instr_vec;\n", INDENT[base_indent]);
03934     //    fprintf( output, "%sfree(instr_dec);\n", INDENT[base_indent]);
03935   }
03936   //  fprintf( output, "%s}\n", INDENT[base_indent-1]);
03937 
03938 }
03939 
03940 
03941 /**************************************/
03945 /***************************************/
03946 void EmitFetchInit( FILE *output, int base_indent){
03947   extern int HaveMultiCycleIns;
03948 
03949 
03950   if (!ACDecCacheFlag){
03951     fprintf( output, "%sif( bhv_pc.read() >= APP_MEM->get_size()){\n", INDENT[base_indent]);
03952   }
03953   else
03954     fprintf( output, "%sif( bhv_pc.read() >= dec_cache_size){\n", INDENT[base_indent]);
03955 
03956   fprintf( output, "%scerr << \"ArchC: Address out of bounds (pc=0x\" << hex << bhv_pc.read() << \").\" << endl;\n", INDENT[base_indent+1]);
03957         //  fprintf( output, "%scout = cerr;\n", INDENT[base_indent+1]);
03958 
03959   if( ACVerifyFlag ){
03960     fprintf( output, "%send_log.mtype = 1;\n", INDENT[base_indent+1]);
03961     fprintf( output, "%send_log.log.time = -1;\n", INDENT[base_indent+1]);
03962     fprintf( output, "%sif(msgsnd(msqid, (struct log_msgbuf *)&end_log, sizeof(end_log), 0) == -1)\n", INDENT[base_indent+1]);
03963     fprintf( output, "%sperror(\"msgsnd\");\n", INDENT[base_indent+2]);
03964   }
03965   fprintf( output, "%sac_stop();\n", INDENT[base_indent+1]);
03966   fprintf( output, "%sreturn;\n", INDENT[base_indent+1]);
03967   fprintf( output, "%s}\n", INDENT[base_indent]);
03968 
03969   fprintf( output, "%selse {\n", INDENT[base_indent]);
03970 
03971   fprintf( output, "%sif( start_up ){\n", INDENT[base_indent+1]);
03972   fprintf( output, "%sdecode_pc = ac_start_addr;\n", INDENT[base_indent+2]);
03973   if(ACABIFlag)
03974     fprintf( output, "%ssyscall.set_prog_args(argc, argv);\n", INDENT[3]);
03975   fprintf( output, "%sstart_up=0;\n", INDENT[base_indent+2]);
03976   if( ACDecCacheFlag )
03977     fprintf( output, "%sinit_dec_cache();\n", INDENT[base_indent+2]);
03978   fprintf( output, "%s}\n", INDENT[base_indent+1]);
03979 
03980   fprintf( output, "%selse{ \n", INDENT[base_indent+1]);
03981   if(HaveMultiCycleIns && !ACDecCacheFlag ){
03982     //fprintf( output, "%sfree(instr_dec);\n", INDENT[base_indent+2]);
03983     fprintf( output, "%sdelete(instr_vec);\n", INDENT[base_indent+2]);
03984   }
03985   fprintf( output, "%sdecode_pc = bhv_pc.read();\n", INDENT[base_indent+2]);
03986   fprintf( output, "%s}\n \n", INDENT[base_indent+1]);
03987   
03988 }
03989 
03990 /**************************************/
03994 /***************************************/
03995 void EmitProcessorBhv( FILE *output){
03996 
03997   EmitFetchInit(output, 1);
03998   EmitDecodification(output, 2);
03999   EmitInstrExec(output, 2);
04000 
04001   fprintf( output, "%sac_instr_counter+=1;\n", INDENT[2]);
04002   fprintf( output, "%sbhv_done.write(1);\n", INDENT[2]);
04003   fprintf( output, "%s}\n", INDENT[1]);
04004   fprintf( output, "}\n\n");
04005 
04006 }
04007 
04008 /**************************************/
04013 /***************************************/
04014 void EmitProcessorBhv_ABI( FILE *output){
04015 
04016   EmitFetchInit(output, 1);
04017 
04018   //Emiting system calls handler.
04019   COMMENT(INDENT[2],"Handling System calls.")
04020     fprintf( output, "%sswitch( decode_pc ){\n\n", INDENT[2]);
04021 
04022   EmitABIDefine(output);
04023   fprintf( output, "\n\n");
04024   EmitABIAddrList(output,2);
04025 
04026   fprintf( output, "%sdefault:\n\n", INDENT[2]);
04027 
04028   EmitDecodification(output, 2);
04029   EmitInstrExec(output, 3);
04030 
04031   //Closing default case.
04032   fprintf( output, "%sbreak;\n", INDENT[3]);
04033 
04034   //Closing switch.
04035   fprintf( output, "%s}\n", INDENT[2]);
04036 
04037   fprintf( output, "%sac_instr_counter+=1;\n", INDENT[2]);
04038   fprintf( output, "%sbhv_done.write(1);\n", INDENT[2]);
04039 
04040   //Closing else.
04041   fprintf( output, "%s}\n", INDENT[1]);
04042 
04043   fprintf( output, "}\n\n");
04044 
04045 }
04046 
04047 
04048 /**************************************/
04052 /***************************************/
04053 void EmitMultiCycleProcessorBhv( FILE *output){
04054 
04055  
04056   fprintf( output, "%sif( ac_cycle == 1 ){\n\n", INDENT[1]);
04057 
04058   EmitFetchInit(output, 2);
04059   EmitDecodification(output, 3);
04060 
04061   //Multicycle execution demands a different control. Do not use EmitInstrExec.
04062   fprintf( output, "%sac_pc = decode_pc;\n", INDENT[3]);
04063   fprintf( output, "%sac_cycle = 1;\n", INDENT[3]);
04064   fprintf( output, "%sinstr = (ac_instruction *)ISA.instr_table[ins_id][1];\n", INDENT[3]);
04065   fprintf( output, "%sformat = (ac_instruction *)ISA.instr_table[ins_id][2];\n", INDENT[3]);
04066   fprintf( output, "%sformat->set_fields( *instr_vec  );\n", INDENT[3]);
04067   fprintf( output, "%sinstr->set_fields( *instr_vec  );\n", INDENT[3]);
04068 
04069   if( ACDebugFlag ){
04070     fprintf( output, "%sif( ac_do_trace != 0 ) \n", INDENT[3]);
04071     fprintf( output, PRINT_TRACE, INDENT[4]);
04072   }
04073 
04074   if( ACDasmFlag ){
04075     fprintf( output, PRINT_DASM , INDENT[4]);
04076   }
04077 
04078   if( ACStatsFlag ){
04079     fprintf( output, "%sac_sim_stats.instr_executed++;;\n", INDENT[3]);
04080     fprintf( output, "%sac_sim_stats.instr_table[ins_id][2]++;\n", INDENT[3]);
04081     fprintf( output, "%sac_sim_stats.ac_min_cycle_count += instr->get_min_latency();\n", INDENT[3]);
04082     fprintf( output, "%sac_sim_stats.ac_max_cycle_count += instr->get_max_latency();\n", INDENT[3]);
04083   }
04084 
04085   fprintf( output, "%sISA.instruction.set_cycles( instr->get_cycles());\n", INDENT[3]);
04086   fprintf( output, "%sISA.instruction.set_size( instr->get_size());\n", INDENT[3]);
04087 
04088   fprintf( output, "%s}\n", INDENT[2]);
04089   fprintf( output, "%sac_instr_counter+= 1;\n", INDENT[2]);
04090 
04091   fprintf( output, "%s}\n", INDENT[1]);
04092 
04093   fprintf( output, "%sISA.instruction.behavior( (ac_stage_list)0, ac_cycle );\n", INDENT[1]);
04094   fprintf( output, "%sformat->behavior((ac_stage_list)0, ac_cycle );\n", INDENT[1]);
04095   fprintf( output, "%sinstr->behavior((ac_stage_list)0, ac_cycle );\n", INDENT[1]);
04096 
04097   fprintf( output, "%sif( ac_cycle > instr->get_cycles())\n", INDENT[1]);
04098   fprintf( output, "%sac_cycle=1;\n\n", INDENT[2]);
04099 
04100   fprintf( output, "%sbhv_done.write(1);\n", INDENT[1]);
04101   fprintf( output, "}\n\n");
04102 }
04103 
04104 /**************************************/
04108 /***************************************/
04109 void EmitPipeABIDefine( FILE *output){
04110 
04111   fprintf( output, "%s#define AC_SYSC(NAME,LOCATION) \\\n", INDENT[0]);
04112   fprintf( output, "%scase LOCATION: \\\n", INDENT[2]);
04113 
04114   fprintf( output, "%sif (flushes_left) { \\\n", INDENT[3]);
04115   fprintf( output, "%sfflush(0);\\\n", INDENT[4]);
04116   fprintf( output, "%sflushes_left--;\\\n", INDENT[4]);
04117   fprintf( output, "%s} \\\n", INDENT[3]);
04118 
04119   fprintf( output, "%selse { \\\n", INDENT[3]);
04120   fprintf( output, "%sfflush(0);\\\n", INDENT[4]);
04121 
04122   if( ACDebugFlag ){
04123     fprintf( output, "%sif( ac_do_trace != 0 )\\\n", INDENT[4]);
04124     fprintf( output, "%strace_file << hex << decode_pc << dec << endl; \\\n", INDENT[5]);
04125   }
04126 
04127   fprintf( output, "%ssyscall.NAME(); \\\n", INDENT[4]);
04128   fprintf( output, "%sflushes_left = 7; \\\n", INDENT[4]);
04129   fprintf( output, "%s} \\\n", INDENT[3]);
04130 
04131   fprintf( output, "%sregout.write( *the_nop); \\\n", INDENT[3]);
04132   fprintf( output, "%sif (! (ac_pc.read() %% 2)) ac_pc.write(ac_pc.read() + 1); \\\n", INDENT[3]);
04133   fprintf( output, "%selse ac_pc.write(ac_pc.read() - 1); \\\n", INDENT[3]);
04134   fprintf( output, "%sbreak;  \\\n", INDENT[3]);
04135 
04136 }
04137 
04138 /**************************************/
04142 /***************************************/
04143 void EmitABIDefine( FILE *output){
04144 
04145   fprintf( output, "%s#define AC_SYSC(NAME,LOCATION) \\\n", INDENT[0]);
04146   fprintf( output, "%scase LOCATION: \\\n", INDENT[2]);
04147 
04148   if( ACDebugFlag ){
04149     fprintf( output, "%sif( ac_do_trace != 0 )\\\n", INDENT[4]);
04150     fprintf( output, "%strace_file << hex << decode_pc << dec << endl; \\\n", INDENT[5]);
04151   }
04152 
04153   fprintf( output, "%ssyscall.NAME(); \\\n", INDENT[4]);
04154   fprintf( output, "%sbreak;  \\\n", INDENT[3]);
04155 }
04156 
04157 
04158 /**************************************/
04162 /***************************************/
04163 void EmitABIAddrList( FILE *output, int base_indent){
04164 
04165   fprintf( output, "#include <ac_syscall.def>\n", INDENT[base_indent]);
04166   fprintf( output, "\n");
04167   fprintf( output, "#undef AC_SYSC\n\n");
04168 }
04169 
04170 /**************************************/
04173 /***************************************/
04174 void EmitCacheDeclaration( FILE *output, ac_sto_list* pstorage, int base_indent){
04175 
04176   //Parameter 1 will be the pstorage->name string
04177   //Parameters passed to the ac_cache constructor. They are not exactly in the same
04178   //order used for ArchC declarations.
04179   //TODO: Include write policy
04180   char parm2[128];  //Block size
04181   char parm3[128];  //# if blocks
04182   char parm4[128];  //set  size
04183   char parm5[128];  //replacement strategy
04184 
04185   //Integer indicating the write-policy
04186   int wp=0;   /* 0x11 (Write Through, Write Allocate)  */
04187   /* 0x12 (Write Back, Write Allocate)  */
04188   /* 0x21 (Write Through, Write Around)  */
04189   /* 0x22 (Write Back, Write Around)  */
04190 
04191   char *aux;
04192   int is_dm=0, is_fully=0;
04193   ac_cache_parms* pparms;
04194   int i=1;
04195 
04196   for( pparms = pstorage->parms; pparms != NULL; pparms = pparms->next ){
04197 
04198     switch( i ){
04199 
04200     case 1: /* First parameter must be a valid associativity */
04201 
04202       if( !pparms->str ){
04203         AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04204         printf("The first parameter must be a valid associativity: \"dm\", \"2w\", \"4w\", ... \n");
04205         exit(1);
04206       }
04207 
04208 #ifdef DEBUG_STORAGE
04209       printf("CacheDeclaration: Processing parameter: %d, which is: %s\n", i, pparms->str);
04210 #endif
04211 
04212       if( !strcmp(pparms->str, "dm") || !strcmp(pparms->str, "DM") ){ //It is a direct-mapped cache
04213         is_dm = 1;
04214         sprintf( parm4, "1");  //Set size will be the 4th parameter for ac_cache constructor.
04215         sprintf( parm5, "DEFAULT");  //DM caches do not need a replacement strategy, use a default value in this parameter.
04216       }
04217       else if( !strcmp(pparms->str, "fully") || !strcmp(pparms->str, "FULLY") ){ //It is a fully associative cache
04218         is_fully =1;
04219       }
04220       else{  //It is a n-way cache
04221         aux = strchr( pparms->str,'w'); 
04222         if(  !aux ){   // Checking if the string has a 'w'
04223           AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04224           printf("The first parameter must be a valid associativity: \"dm\", \"2w\", \"4w\", ..., \"fully\" \n");
04225           exit(1);
04226         }
04227         aux = (char*) malloc( strlen(pparms->str) );
04228         strncpy(aux, pparms->str,  strlen(pparms->str)-1);
04229         aux[ strlen(pparms->str)-1]='\0';
04230 
04231         sprintf(parm4, "%s", aux);  //Set size will be the 4th parameter for ac_cache constructor.
04232         free(aux);
04233       }
04234       break;
04235 
04236     case 2: /* Second parameter is the number of blocks (lines) */
04237 
04238       if( !(pparms->value > 0 ) ){
04239         AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04240         printf("The second parameter must be a valid (>0) number of blocks (lines).\n");
04241         exit(1);
04242       }
04243 
04244       if( is_fully )
04245         sprintf( parm4, "%d", pparms->value);  //Set size will be the number of blocks (lines) for fully associative caches
04246                                 
04247       sprintf(parm3, "%d", pparms->value);
04248       break;
04249 
04250     case 3: /* Third parameter is the block (line) size */
04251 
04252       if( !(pparms->value > 0 ) ){
04253         AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04254         printf("The third parameter must be a valid (>0) block (line) size.\n");
04255         exit(1);
04256       }
04257 
04258       sprintf(parm2, "%d", pparms->value);
04259       break;
04260 
04261     case 4: /* The fourth  parameter may be the write policy or the replacement strategy.
04262                If it is a direct-mapped cache, then we don't have a replacement strategy,
04263                so this parameter must be the write policy, which is "wt" (write-through) or
04264                "wb" (write-back). Otherwise, it must be a replacement strategy, which is "lru"
04265                or "random", and the fifth parameter will be the write policy. */
04266 
04267       if( is_dm ){ //This value is set when the first parameter is being processed.
04268         /* So this is a write-policy */
04269         if( !strcmp( pparms->str, "wt") || !strcmp( pparms->str, "WT") ){
04270           //One will tell that a wt cache was declared
04271           wp = WRITE_THROUGH;
04272         }
04273         else if( !strcmp( pparms->str, "wb") || !strcmp( pparms->str, "WB") ) {
04274           //Zero will tell that a wb cache was declared
04275           wp = WRITE_BACK;
04276         }
04277         else{
04278           AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04279           printf("For direct-mapped caches, the fourth parameter must be a valid write policy: \"wt\" or \"wb\".\n");
04280           exit(1);
04281         }
04282       }
04283       else{
04284         /* So, this is a replacement strategy */
04285         if( !strcmp( pparms->str, "lru") || !strcmp( pparms->str, "LRU") ){
04286           sprintf( parm5, "LRU");  //Including parameter
04287         }
04288         else if( !strcmp( pparms->str, "random") || !strcmp( pparms->str, "RANDOM") ) {
04289           sprintf( parm5, "RANDOM");  //Including parameter
04290         }
04291         else{
04292           AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04293           printf("For non-direct-mapped caches, the fourth parameter must be a valid replacement strategy: \"lru\" or \"random\".\n");
04294           exit(1);
04295         }
04296       }
04297       break;
04298 
04299     case 5: /* The fifth parameter is a write policy. */
04300 
04301       if( !is_dm ){ //This value is set when the first parameter is being processed.
04302                                 
04303         if( !strcmp( pparms->str, "wt") || !strcmp( pparms->str, "WT") ){
04304                                         
04305           wp = WRITE_THROUGH;
04306         }
04307         else if( !strcmp( pparms->str, "wb") || !strcmp( pparms->str, "WB") ) {
04308                                         
04309           wp = WRITE_BACK;
04310         }
04311         else{
04312           AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04313           printf("For non-direct-mapped caches, the fourth parameter must be a valid replacement strategy: \"lru\" or \"random\".\n");
04314           exit(1);
04315         }
04316       }
04317                         
04318       else{ //This value is "war" for write-around or "wal" for "write-allocate"
04319                                 
04320         if( !strcmp( pparms->str, "war") || !strcmp( pparms->str, "WAR") ){
04321           wp = wp | WRITE_AROUND;
04322         }
04323         else if( !strcmp( pparms->str, "wal") || !strcmp( pparms->str, "WAL") ) {
04324           wp = wp | WRITE_ALLOCATE;
04325         }
04326         else{
04327           AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04328           printf("For non-direct-mapped caches, the fourth parameter must be a valid replacement strategy: \"lru\" or \"random\".\n");
04329           exit(1);
04330         }
04331                                 
04332       }
04333       break;
04334                         
04335     case 6: /* The sixth parameter, if it is present, is a write policy. 
04336                It must not be present for direct-mapped caches.*/
04337 
04338       if( !is_dm ){ //This value is set when the first parameter is being processed.
04339 
04340         if( !strcmp( pparms->str, "war") || !strcmp( pparms->str, "WAR") ){
04341           wp = wp | WRITE_AROUND;
04342         }
04343         else if( !strcmp( pparms->str, "wal") || !strcmp( pparms->str, "WAL") ) {
04344           wp = wp | WRITE_ALLOCATE;
04345         }
04346         else{
04347           AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04348           printf("For non-direct-mapped caches, the fifth parameter must be  \"war\" or \"wal\".\n");
04349           exit(1);
04350         }
04351 
04352       }
04353       else{
04354         AC_ERROR("Invalid parameter in cache declaration: %s\n", pstorage->name);
04355         printf("For direct-mapped caches there must be only five parameters (do not need a replacement strategy).\n");
04356         exit(1);
04357       }
04358       break;
04359     default:
04360       break;
04361     }                                                                   
04362     i++;
04363                 
04364   }
04365 
04366   //Printing cache declaration.
04367   fprintf( output, "%sac_cache ac_resources::%s(\"%s\", %s, %s, %s, %s, 0x%x);\n",
04368            INDENT[base_indent], pstorage->name, pstorage->name, parm2, parm3, parm4, parm5, wp);
04369 }
04370 
04372 // Utility Functions              //
04374 
04376 void ReadConfFile(){
04377 
04378   char *conf_filename;
04379   extern char *ARCHC_PATH;
04380   extern char *SYSTEMC_PATH;
04381   extern char *CC_PATH;
04382   extern char *OPT_FLAGS;
04383   extern char *DEBUG_FLAGS;
04384   extern char *OTHER_FLAGS;
04385 
04386   FILE *conf_file;
04387   char line[CONF_MAX_LINE];
04388   char var[CONF_MAX_LINE];
04389   char value[CONF_MAX_LINE];
04390 
04391   ARCHC_PATH = getenv("ARCHC_PATH");
04392 
04393   if(!ARCHC_PATH){
04394     AC_ERROR("Yould should set the ARCHC_PATH environment variable.\n");
04395     exit(1);
04396   }
04397                 
04398   conf_filename = (char*) malloc( strlen(ARCHC_PATH)+20);
04399   conf_filename = strcpy(conf_filename, ARCHC_PATH);
04400 
04401   conf_filename = strcat(conf_filename, "/config/archc.conf");
04402 
04403   conf_file = fopen(conf_filename, "r");
04404 
04405   if( !conf_file ){
04406     //ERROR
04407     AC_ERROR("Could not open archc.conf configuration file.\n");
04408     exit(1);
04409   }
04410   else{  
04411     while( fgets( line, CONF_MAX_LINE, conf_file) ){
04412 
04413       var[0]='\0';
04414       value[0]='\0';
04415 
04416       if(line[0] == '#' || line[0] == '\n'){  //Comments or blank lines
04417         continue;
04418       }
04419       else{
04420 
04421         sscanf(line, "%s",var);
04422         strcpy( value, strchr(line, '=')+1);
04423 
04424         if( !strcmp(var, "SYSTEMC_PATH") ){
04425           SYSTEMC_PATH = (char*) malloc(strlen(value)+1);
04426           SYSTEMC_PATH = strcpy(SYSTEMC_PATH, value);
04427         }
04428         else if( !strcmp(var, "CC") ){
04429           CC_PATH =  (char*) malloc(strlen(value)+1);
04430           CC_PATH = strcpy(CC_PATH, value);
04431         }
04432         else if( !strcmp(var, "OPT") ){
04433           OPT_FLAGS =(char*) malloc(strlen(value)+1);
04434           OPT_FLAGS = strcpy(OPT_FLAGS, value); 
04435         }
04436         else if( !strcmp(var, "DEBUG") ){
04437           DEBUG_FLAGS = (char*) malloc(strlen(value)+1);
04438           DEBUG_FLAGS = strcpy(DEBUG_FLAGS, value);
04439         }
04440         else if( !strcmp(var, "OTHER") ){
04441           OTHER_FLAGS = (char*) malloc(strlen(value)+1);
04442           OTHER_FLAGS = strcpy(OTHER_FLAGS, value);
04443         }
04444         else if( !strcmp(var, "TARGET_ARCH") ){
04445           TARGET_ARCH = (char*) malloc(strlen(value)+1);
04446           TARGET_ARCH = strcpy(TARGET_ARCH, value);
04447         }
04448 
04449       }
04450     }
04451   }
04452   free(conf_filename);
04453 }

Generated on Thu Jun 24 08:30:05 2004 for ArchC by doxygen 1.3.4