static void sim_check_options(struct opt_odb_t *odb, /* options database */ int argc, char **argv) /* command line arguments */ { char name[128], c; if (ruu_ifq_size < 1 || (ruu_ifq_size & (ruu_ifq_size - 1)) != 0) fatal("inst fetch queue size must be positive > 0 and a power of two"); pipe_ibuf_size = ruu_ifq_size; fetch_width = ruu_decode_width * fetch_speed; //if (ruu_branch_penalty < 1) // fatal("mis-prediction penalty must be at least 1 cycle"); if (!mystricmp(pred_type, "perfect")) { /* perfect predictor */ bpred_scheme = NO_BPRED; } #if 0 else if (!mystricmp(pred_type, "taken")) { /* static predictor, not taken */ //pred = bpred_create(BPredTaken, 0, 0, 0, 0, 0, 0, 0, 0, 0); } else if (!mystricmp(pred_type, "nottaken")) { /* static predictor, taken */ //pred = bpred_create(BPredNotTaken, 0, 0, 0, 0, 0, 0, 0, 0, 0); } #endif else if (!mystricmp(pred_type, "bimod")) { /* bimodal predictor, bpred_create() checks BTB_SIZE */ if (bimod_nelt != 1) fatal("bad bimod predictor config (<table_size>)"); if (btb_nelt != 2) fatal("bad btb config (<num_sets> <associativity>)"); bpred_scheme = LOCAL; BHT_SIZE = btb_config[0]; BHT = log_base2(BHT_SIZE); BHT_MSK = BHT_SIZE - 1; } else if (!mystricmp(pred_type, "2lev")) { if (twolev_nelt != 4) fatal("bad 2-level pred config (<l1size> <l2size> <hist_size> <xor>)"); if (btb_nelt != 2) fatal("bad btb config (<num_sets> <associativity>)"); if ((twolev_config[1] & (twolev_config[1] - 1)) != 0) fatal("Branch History Table (BHT) size %d is not power of 2!\n", twolev_config[1]); if ((twolev_config[2] < 0) || (twolev_config[2] > 4)) fatal("Branch History Register (BHR) bits %d is not within [0, 4]\n", twolev_config[2]); if (twolev_config[2] == 0) bpred_scheme = LOCAL; if (twolev_config[3] == FALSE) bpred_scheme = GAG; else bpred_scheme = GSHARE; BHT_SIZE = twolev_config[1]; BHT = log_base2(BHT_SIZE); BHT_MSK = BHT_SIZE - 1; BHR = twolev_config[2]; BHR_PWR = 1 << BHR; BHR_MSK = BHR_PWR - 1; if ( (1 << BHR) > BHT_SIZE) fatal("The combination of Branch History Register (BHR) bits %d and \nBranch History Table size %d is invalid because 2^BHR > BHT \n", BHR, BHT_SIZE); } #if 0 else if (!mystricmp(pred_type, "comb")) { /* combining predictor, bpred_create() checks args */ if (twolev_nelt != 4) fatal("bad 2-level pred config (<l1size> <l2size> <hist_size> <xor>)"); if (bimod_nelt != 1) fatal("bad bimod predictor config (<table_size>)"); if (comb_nelt != 1) fatal("bad combining predictor config (<meta_table_size>)"); if (btb_nelt != 2) fatal("bad btb config (<num_sets> <associativity>)"); pred = bpred_create(BPredComb, /* bimod table size */bimod_config[0], /* l1 size */twolev_config[0], /* l2 size */twolev_config[1], /* meta table size */comb_config[0], /* history reg size */twolev_config[2], /* history xor address */twolev_config[3], /* btb sets */btb_config[0], /* btb assoc */btb_config[1], /* ret-addr stack size */ras_size); } #endif else fatal("cannot parse predictor type `%s'", pred_type); #if 0 if (ruu_decode_width < 1 || (ruu_decode_width & (ruu_decode_width-1)) != 0) fatal("issue width must be positive non-zero and a power of two"); if (ruu_issue_width < 1 || (ruu_issue_width & (ruu_issue_width-1)) != 0) fatal("issue width must be positive non-zero and a power of two"); if (ruu_commit_width < 1) fatal("commit width must be positive non-zero"); #endif if (RUU_size < 2) fatal("Re-order buffer size must be greater than one!"); pipe_iwin_size = RUU_size; PROLOG_SIZE = pipe_iwin_size + pipe_ibuf_size; EPILOG_SIZE = pipe_iwin_size * 2; LSQ_size = pipe_iwin_size; #if 0 if (LSQ_size < 2 || (LSQ_size & (LSQ_size-1)) != 0) fatal("LSQ size must be a positive number > 1 and a power of two"); #endif /* use a level 1 D-cache? */ if (!mystricmp(cache_dl1_opt, "none")) { #if 0 cache_dl1 = NULL; #endif enable_dcache = enable_scp_dcache = 0; /* the level 2 D-cache cannot be defined */ if (strcmp(cache_dl2_opt, "none")) fatal("the l1 data cache must defined if the l2 cache is defined"); #if 0 cache_dl2 = NULL; #endif } else /* dl1 is defined */ { enable_scp_dcache = 1; if (sscanf(cache_dl1_opt, "%[^:]:%d:%d:%d:%c", name, &nsets_dl1, &bsize_dl1, &assoc_dl1, &c) != 5) fatal("bad l1 D-cache parms: <name>:<nsets>:<bsize>:<assoc>:<repl>"); /* sudiptac ::: enable level 1 data cache analysis */ enable_dcache = 1; #if 0 cache_dl1 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), dl1_access_fn, /* hit lat */cache_dl1_lat); #endif /* is the level 2 D-cache defined? */ if (!mystricmp(cache_dl2_opt, "none")) enable_ul2cache = 0; #if 0 cache_dl2 = NULL; #endif else { if (sscanf(cache_dl2_opt, "%[^:]:%d:%d:%d:%c", name, &nsets_dl2, &bsize_dl2, &assoc_dl2, &c) != 5) fatal("bad l2 D-cache parms: " "<name>:<nsets>:<bsize>:<assoc>:<repl>"); enable_scp_dl2cache = 1; } }
/* check simulator-specific option values */ void sim_check_options(struct opt_odb_t *odb, /* options database */ int argc, char **argv) /* command line arguments */ { char name[128], c; int nsets, bsize, assoc; int prefetch_type; /* this specifies the type of the prefetcher */ /* use a level 1 D-cache? */ if (!mystricmp(cache_dl1_opt, "none")) { cache_dl1 = NULL; /* the level 2 D-cache cannot be defined */ if (strcmp(cache_dl2_opt, "none")) fatal("the l1 data cache must defined if the l2 cache is defined"); cache_dl2 = NULL; } else /* dl1 is defined */ { if (sscanf(cache_dl1_opt, "%[^:]:%d:%d:%d:%c:%d", name, &nsets, &bsize, &assoc, &c, &prefetch_type) != 6) fatal("bad l1 D-cache parms: <name>:<nsets>:<bsize>:<assoc>:<repl>:<pref>"); cache_dl1 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), dl1_access_fn, /* hit latency */1, prefetch_type); /* is the level 2 D-cache defined? */ if (!mystricmp(cache_dl2_opt, "none")) cache_dl2 = NULL; else { if (sscanf(cache_dl2_opt, "%[^:]:%d:%d:%d:%c:%d", name, &nsets, &bsize, &assoc, &c, &prefetch_type) != 6) fatal("bad l2 D-cache parms: " "<name>:<nsets>:<bsize>:<assoc>:<repl>:<pref>"); cache_dl2 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), dl2_access_fn, /* hit latency */1, prefetch_type); } } /* use a level 1 I-cache? */ if (!mystricmp(cache_il1_opt, "none")) { cache_il1 = NULL; /* the level 2 I-cache cannot be defined */ if (strcmp(cache_il2_opt, "none")) fatal("the l1 inst cache must defined if the l2 cache is defined"); cache_il2 = NULL; } else if (!mystricmp(cache_il1_opt, "dl1")) { if (!cache_dl1) fatal("I-cache l1 cannot access D-cache l1 as it's undefined"); cache_il1 = cache_dl1; /* the level 2 I-cache cannot be defined */ if (strcmp(cache_il2_opt, "none")) fatal("the l1 inst cache must defined if the l2 cache is defined"); cache_il2 = NULL; } else if (!mystricmp(cache_il1_opt, "dl2")) { if (!cache_dl2) fatal("I-cache l1 cannot access D-cache l2 as it's undefined"); cache_il1 = cache_dl2; /* the level 2 I-cache cannot be defined */ if (strcmp(cache_il2_opt, "none")) fatal("the l1 inst cache must defined if the l2 cache is defined"); cache_il2 = NULL; } else /* il1 is defined */ { if (sscanf(cache_il1_opt, "%[^:]:%d:%d:%d:%c:%d", name, &nsets, &bsize, &assoc, &c,&prefetch_type) != 6) fatal("bad l1 I-cache parms: <name>:<nsets>:<bsize>:<assoc>:<repl>:<pref>"); cache_il1 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), il1_access_fn, /* hit latency */1, prefetch_type); /* is the level 2 D-cache defined? */ if (!mystricmp(cache_il2_opt, "none")) cache_il2 = NULL; else if (!mystricmp(cache_il2_opt, "dl2")) { if (!cache_dl2) fatal("I-cache l2 cannot access D-cache l2 as it's undefined"); cache_il2 = cache_dl2; } else { if (sscanf(cache_il2_opt, "%[^:]:%d:%d:%d:%c:%d", name, &nsets, &bsize, &assoc, &c, &prefetch_type) != 6) fatal("bad l2 I-cache parms: " "<name>:<nsets>:<bsize>:<assoc>:<repl>:<pref>"); cache_il2 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), il2_access_fn, /* hit latency */1, prefetch_type); } } /* use an I-TLB? */ if (!mystricmp(itlb_opt, "none")) itlb = NULL; else { if (sscanf(itlb_opt, "%[^:]:%d:%d:%d:%c:%d", name, &nsets, &bsize, &assoc, &c, &prefetch_type) != 6) fatal("bad TLB parms: <name>:<nsets>:<page_size>:<assoc>:<repl>:<pref>"); itlb = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */sizeof(md_addr_t), assoc, cache_char2policy(c), itlb_access_fn, /* hit latency */1, prefetch_type); } /* use a D-TLB? */ if (!mystricmp(dtlb_opt, "none")) dtlb = NULL; else { if (sscanf(dtlb_opt, "%[^:]:%d:%d:%d:%c:%d", name, &nsets, &bsize, &assoc, &c, &prefetch_type) != 6) fatal("bad TLB parms: <name>:<nsets>:<page_size>:<assoc>:<repl>:<pref>"); dtlb = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */sizeof(md_addr_t), assoc, cache_char2policy(c), dtlb_access_fn, /* hit latency */1, prefetch_type); } }
#if 0 cache_dl2 = NULL; #endif else { if (sscanf(cache_dl2_opt, "%[^:]:%d:%d:%d:%c", name, &nsets_dl2, &bsize_dl2, &assoc_dl2, &c) != 5) fatal("bad l2 D-cache parms: " "<name>:<nsets>:<bsize>:<assoc>:<repl>"); enable_scp_dl2cache = 1; } } #if 0 cache_dl2 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), dl2_access_fn, /* hit lat */cache_dl2_lat); } } #endif /* use a level 1 I-cache? */ if (!mystricmp(cache_il1_opt, "none")) { enable_icache = 0; #if 0 cache_il1 = NULL; /* the level 2 I-cache cannot be defined */ if (strcmp(cache_il2_opt, "none")) fatal("the l1 inst cache must defined if the l2 cache is defined"); cache_il2 = NULL;