00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028
00035
00036
00037 #include "acsim.h"
00038 #include "acsim.h"
00039 #include "stdlib.h"
00040 #include "string.h"
00041
00042
00043
00044
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
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
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
00080
00081
00082
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
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
00106
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
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
00156 extern ac_dec_format *format_ins_list;
00157 extern ac_dec_instr *instr_list;
00158
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
00165
00166
00167 int argn,i,j;
00168 endian a, b;
00169
00170 int error_flag=0;
00171
00172
00173
00174
00175
00176 acppInit();
00177
00178
00179 ReadConfFile();
00180
00181 ++argv, --argc;
00182
00183
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;
00212
00213 if( argc > 0){
00214
00215 argn = argc;
00216
00217 for(j= 0; j<argn; j++ ){
00218
00219
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
00247
00248
00249
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
00265
00266
00267
00268
00269
00270
00271
00272
00273
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;
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
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
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
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
00339 fetchsize = wordsize;
00340 }
00341
00342
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;
00351 else
00352 ac_host_endian = 0;
00353
00354 ac_match_endian = (ac_host_endian == ac_tgt_endian);
00355
00356
00357
00358
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
00373 CreateResourceHeader();
00374
00375 CreateResourceImpl();
00376
00377 CreateISAHeader();
00378
00379 CreateParmHeader();
00380
00381 CreateARCHHeader();
00382
00383 CreateARCHImpl();
00384
00385
00386
00387
00388
00389
00390 if( stage_list ){
00391
00392
00393 CreateStgHeader(stage_list, NULL);
00394
00395 CreateStgImpl(stage_list, NULL);
00396
00397 }
00398 else if( pipe_list ){
00399
00400 for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
00401
00402
00403 CreateStgHeader( ppipe->stages, ppipe->name );
00404
00405
00406 CreateStgImpl(ppipe->stages, ppipe->name);
00407 }
00408 }
00409 else{
00410
00411
00412 CreateProcessorHeader();
00413 CreateProcessorImpl();
00414 }
00415
00416
00417
00418 CreateTypeHeader();
00419
00420 if( HaveFormattedRegs ){
00421
00422 CreateRegsHeader();
00423
00424 }
00425
00426
00427
00428
00429
00430
00431 if( ACStatsFlag )
00432 CreateStatsHeader();
00433
00434
00435 if( ACABIFlag )
00436 CreateArchSyscallHeader();
00437
00438
00439 CreateImplTmpl();
00440
00441
00442 CreateMainTmpl();
00443
00444
00445 CreateMakefile();
00446
00447
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
00459
00460
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
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
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
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
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 ) {
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
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 ) {
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
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
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
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
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
00656 fprintf( output, "%sstatic bool ac_parallel_sig;\n", INDENT[1]);
00657
00658
00659 if( !stage_list && !pipe_list ){
00660
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
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
00670 if(HaveMultiCycleIns)
00671 fprintf( output, "%sstatic unsigned ac_cycle;\n", INDENT[1]);
00672
00673
00674
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
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
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
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
00691 fprintf( output, "%sstatic double time_step;\n", INDENT[1]);
00692
00693
00694 fprintf( output, "%sstatic int argc;\n", INDENT[1]);
00695 fprintf( output, "%sstatic char **argv;\n", INDENT[1]);
00696
00697
00698 if( ACDasmFlag )
00699 fprintf( output, "%sstatic ofstream dasmfile;\n", INDENT[1]);
00700
00701 fprintf( output, " \n");
00702 fprintf( output, "\n");
00703
00704
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
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
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
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
00777
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
00787
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]);
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");
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
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
00856 EmitGenInstrClass( output );
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
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
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
01059 fprintf( output, "enum ac_stage_list {");
01060
01061 if( stage_list ){
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){
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
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);
01084 else
01085 fprintf( output, "%s=%d", pstage->name, pstage->id);
01086 }
01087 }
01088 else{
01089 fprintf( output, "ST0");
01090 }
01091
01092
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
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
01141 fprintf( output, "%sstatic ac_instruction instruction;\n",INDENT[1]);
01142
01143
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
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
01155
01156
01157 fprintf( output, "%sint instr_table[AC_DEC_INSTR_NUMBER+1][3];\n\n", INDENT[1]);
01158
01159
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
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
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 ){
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 ){
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
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 ){
01324
01325 for( ppipe = pipe_list; ppipe != NULL; ppipe = ppipe->next ){
01326
01327 for( pstage = ppipe->stages; pstage != NULL; pstage=pstage->next){
01328
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
01452
01453
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
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
01494
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
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
01536
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
01547 fprintf( output, "%s}\n", INDENT[1]);
01548
01549 if(pstage->id==1 && ACDecCacheFlag){
01550 fprintf( output, "%svoid init_dec_cache(){\n", INDENT[1]);
01551 fprintf( output, "%sDEC_CACHE = (cache_item*)calloc(sizeof(cache_item),dec_cache_size);\n", INDENT[2]);
01552 fprintf( output, "%s}\n", INDENT[1]);
01553 }
01554
01555
01556 fprintf( output, "};\n");
01557
01558
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
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]);
01645
01646
01647 if(ACDecCacheFlag){
01648 fprintf( output, "%svoid init_dec_cache(){\n", INDENT[1]);
01649 fprintf( output, "%sDEC_CACHE = (cache_item*)calloc(sizeof(cache_item),dec_cache_size);\n", INDENT[2]);
01650 fprintf( output, "%s}\n", INDENT[1]);
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){
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
01720 fprintf( output, "class ac_%s {\n", pstorage->name);
01721 fprintf( output, "%schar* name;\n", INDENT[1]);
01722 fprintf( output, "public:\n");
01723
01724
01725
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
01732 fprintf( output, "%sac_%s(char* n): \n", INDENT[1], pstorage->name);
01733 for( pfield = pformat->fields; pfield->next != NULL; pfield = pfield->next)
01734
01735
01736 fprintf( output,"%s%s(\"%s\",%d),\n",INDENT[2],pfield->name,pstorage->name, 0 );
01737
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){
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
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
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
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
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
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
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
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
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
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
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
01964 COMMENT(INDENT[1],"Constructor");
01965 fprintf( output, "%sac_stats( );\n\n", INDENT[1]);
01966 fprintf( output, "\n");
01967
01968
01969 COMMENT(INDENT[1],"Print Simulation Statistics Report");
01970 fprintf( output, "%svoid print( );\n\n", INDENT[1]);
01971 fprintf( output, "\n");
01972
01973
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
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
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
02042 fprintf( output, "%soutput.open( \"%s.stats\");\n", INDENT[2], project_name);
02043
02044 fprintf( output, "%s}\n", INDENT[1]);
02045
02046
02047
02048 fprintf( output, "};\n");
02049
02050
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
02071
02072
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
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
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
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
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
02200 fprintf( output, "%sbreak;\n", INDENT[3]);
02201
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
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
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
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
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 ) {
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
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 ) {
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
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
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
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
02521 if( !fetch_device ){
02522
02523
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 ) {
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
02537
02538
02539 for( pstorage = storage_list; pstorage != NULL; pstorage=pstorage->next){
02540 if(pstorage->level > load_device->level)
02541 load_device = pstorage;
02542 }
02543
02544
02545
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
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
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");
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
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 )
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
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
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
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
02913
02914
02915
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
02924 COMMENT(INDENT[0],"Generic instruction behavior method.");
02925
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
02948 COMMENT(INDENT[0]," Instruction Format behavior methods.");
02949 for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next)
02950
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
02973 for( pinstr = instr_list; pinstr!= NULL; pinstr=pinstr->next){
02974
02975
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
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
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
03013 fprintf( output, "%sac_instruction %s_isa::instruction(\"instruction\");\n", INDENT[0], project_name);
03014
03015
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
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
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
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
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
03180 if( stage_list ){
03181
03182 for( pstage = stage_list; pstage!= NULL; pstage = pstage->next)
03183 fprintf( output, "%s.cpp ", pstage->name);
03184 }
03185 else if( pipe_list ){
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{
03194
03195 fprintf( output, "$(MODULE).cpp");
03196 }
03197
03198 fprintf( output, "\n\n");
03199
03200
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
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
03218 if( stage_list ){
03219
03220 for( pstage = stage_list; pstage!= NULL; pstage = pstage->next)
03221 fprintf( output, "%s.H ", pstage->name);
03222 }
03223 else if( pipe_list ){
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{
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
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
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
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
03273 fprintf( output, "OBJS := $(SRCS:.cpp=.o)\n");
03274
03275 fprintf( output, "\n");
03276
03277 fprintf( output, "EXE := $(MODULE).x\n\n");
03278
03279
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
03333
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
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
03358 for( pformat = format_ins_list; pformat!= NULL; pformat=pformat->next){
03359
03360 if( initializing ){
03361
03362
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{
03381
03382 ppf = NULL;
03383
03384
03385 pf = pgenfield;
03386
03387 while( pf ){
03388
03389
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) {
03397
03398 if(ppf){
03399 ppf->next = pf->next;
03400 free(pf);
03401 pf = ppf->next;
03402 }
03403 else{
03404 pgenfield = pf->next;
03405 free(pf);
03406 pf = pgenfield;
03407 }
03408 }
03409 else{
03410 ppf = pf;
03411 pf = pf->next;
03412 }
03413 }
03414 }
03415 }
03416
03417
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
03801
03802
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
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
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
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
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
03935 }
03936
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
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
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
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
04032 fprintf( output, "%sbreak;\n", INDENT[3]);
04033
04034
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
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
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
04177
04178
04179
04180 char parm2[128];
04181 char parm3[128];
04182 char parm4[128];
04183 char parm5[128];
04184
04185
04186 int wp=0;
04187
04188
04189
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:
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") ){
04213 is_dm = 1;
04214 sprintf( parm4, "1");
04215 sprintf( parm5, "DEFAULT");
04216 }
04217 else if( !strcmp(pparms->str, "fully") || !strcmp(pparms->str, "FULLY") ){
04218 is_fully =1;
04219 }
04220 else{
04221 aux = strchr( pparms->str,'w');
04222 if( !aux ){
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);
04232 free(aux);
04233 }
04234 break;
04235
04236 case 2:
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);
04246
04247 sprintf(parm3, "%d", pparms->value);
04248 break;
04249
04250 case 3:
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:
04262
04263
04264
04265
04266
04267 if( is_dm ){
04268
04269 if( !strcmp( pparms->str, "wt") || !strcmp( pparms->str, "WT") ){
04270
04271 wp = WRITE_THROUGH;
04272 }
04273 else if( !strcmp( pparms->str, "wb") || !strcmp( pparms->str, "WB") ) {
04274
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
04285 if( !strcmp( pparms->str, "lru") || !strcmp( pparms->str, "LRU") ){
04286 sprintf( parm5, "LRU");
04287 }
04288 else if( !strcmp( pparms->str, "random") || !strcmp( pparms->str, "RANDOM") ) {
04289 sprintf( parm5, "RANDOM");
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:
04300
04301 if( !is_dm ){
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{
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:
04336
04337
04338 if( !is_dm ){
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
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
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
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'){
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 }