📄 sim-outorder.c
字号:
/* mem options */ opt_reg_int_list(odb, "-mem:lat", "memory access latency (<first_chunk> <inter_chunk>)", mem_lat, mem_nelt, &mem_nelt, mem_lat, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); opt_reg_int(odb, "-mem:width", "memory access bus width (in bytes)", &mem_bus_width, /* default */8, /* print */TRUE, /* format */NULL); /* TLB options */ opt_reg_string(odb, "-tlb:itlb", "instruction TLB config, i.e., {<config>|none}", &itlb_opt, "itlb:16:4096:4:l", /* print */TRUE, NULL); opt_reg_string(odb, "-tlb:dtlb", "data TLB config, i.e., {<config>|none}", &dtlb_opt, "dtlb:32:4096:4:l", /* print */TRUE, NULL); opt_reg_int(odb, "-tlb:lat", "inst/data TLB miss latency (in cycles)", &tlb_miss_lat, /* default */30, /* print */TRUE, /* format */NULL); /* resource configuration */ opt_reg_int(odb, "-res:ialu", "total number of integer ALU's available", &res_ialu, /* default */fu_config[FU_IALU_INDEX].quantity, /* print */TRUE, /* format */NULL); opt_reg_int(odb, "-res:imult", "total number of integer multiplier/dividers available", &res_imult, /* default */fu_config[FU_IMULT_INDEX].quantity, /* print */TRUE, /* format */NULL); opt_reg_int(odb, "-res:memport", "total number of memory system ports available (to CPU)", &res_memport, /* default */fu_config[FU_MEMPORT_INDEX].quantity, /* print */TRUE, /* format */NULL); opt_reg_int(odb, "-res:fpalu", "total number of floating point ALU's available", &res_fpalu, /* default */fu_config[FU_FPALU_INDEX].quantity, /* print */TRUE, /* format */NULL); opt_reg_int(odb, "-res:fpmult", "total number of floating point multiplier/dividers available", &res_fpmult, /* default */fu_config[FU_FPMULT_INDEX].quantity, /* print */TRUE, /* format */NULL); opt_reg_string_list(odb, "-pcstat", "profile stat(s) against text addr's (mult uses ok)", pcstat_vars, MAX_PCSTAT_VARS, &pcstat_nelt, NULL, /* !print */FALSE, /* format */NULL, /* accrue */TRUE); opt_reg_flag(odb, "-bugcompat", "operate in backward-compatible bugs mode (for testing only)", &bugcompat_mode, /* default */FALSE, /* print */TRUE, NULL);}/* check simulator-specific option values */voidsim_check_options(struct opt_odb_t *odb, /* options database */ int argc, char **argv) /* command line arguments */{ char name[128], c; int nsets, bsize, assoc; if (fastfwd_count < 0 || fastfwd_count >= 2147483647) fatal("bad fast forward count: %d", fastfwd_count); 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"); if (ruu_branch_penalty < 1) fatal("mis-prediction penalty must be at least 1 cycle"); if (fetch_speed < 1) fatal("front-end speed must be positive and non-zero"); if (!mystricmp(pred_type, "perfect")) { /* perfect predictor */ pred = NULL; pred_perfect = TRUE; } 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); } 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>)"); /* bimodal predictor, bpred_create() checks BTB_SIZE */ pred = bpred_create(BPred2bit, /* bimod table size */bimod_config[0], /* 2lev l1 size */0, /* 2lev l2 size */0, /* meta table size */0, /* history reg size */0, /* history xor address */0, /* btb sets */btb_config[0], /* btb assoc */btb_config[1], /* ret-addr stack size */ras_size); } else if (!mystricmp(pred_type, "2lev")) { /* 2-level adaptive predictor, bpred_create() checks args */ 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>)"); pred = bpred_create(BPred2Level, /* bimod table size */0, /* 2lev l1 size */twolev_config[0], /* 2lev l2 size */twolev_config[1], /* meta table size */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); } 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); } else fatal("cannot parse predictor type `%s'", pred_type); if (!bpred_spec_opt) bpred_spec_update = spec_CT; else if (!mystricmp(bpred_spec_opt, "ID")) bpred_spec_update = spec_ID; else if (!mystricmp(bpred_spec_opt, "WB")) bpred_spec_update = spec_WB; else fatal("bad speculative update stage specifier, use {ID|WB}"); 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"); if (RUU_size < 2 || (RUU_size & (RUU_size-1)) != 0) fatal("RUU size must be a positive number > 1 and a power of two"); if (LSQ_size < 2 || (LSQ_size & (LSQ_size-1)) != 0) fatal("LSQ size must be a positive number > 1 and a power of two"); /* 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", name, &nsets, &bsize, &assoc, &c) != 5) fatal("bad l1 D-cache parms: <name>:<nsets>:<bsize>:<assoc>:<repl>"); cache_dl1 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), dl1_access_fn, /* hit lat */cache_dl1_lat); /* 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", name, &nsets, &bsize, &assoc, &c) != 5) fatal("bad l2 D-cache parms: " "<name>:<nsets>:<bsize>:<assoc>:<repl>"); cache_dl2 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), dl2_access_fn, /* hit lat */cache_dl2_lat); } } /* 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", name, &nsets, &bsize, &assoc, &c) != 5) fatal("bad l1 I-cache parms: <name>:<nsets>:<bsize>:<assoc>:<repl>"); cache_il1 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), il1_access_fn, /* hit lat */cache_il1_lat); /* 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", name, &nsets, &bsize, &assoc, &c) != 5) fatal("bad l2 I-cache parms: " "<name>:<nsets>:<bsize>:<assoc>:<repl>"); cache_il2 = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */0, assoc, cache_char2policy(c), il2_access_fn, /* hit lat */cache_il2_lat); } } /* use an I-TLB? */ if (!mystricmp(itlb_opt, "none")) itlb = NULL; else { if (sscanf(itlb_opt, "%[^:]:%d:%d:%d:%c", name, &nsets, &bsize, &assoc, &c) != 5) fatal("bad TLB parms: <name>:<nsets>:<page_size>:<assoc>:<repl>"); itlb = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */sizeof(md_addr_t), assoc, cache_char2policy(c), itlb_access_fn, /* hit latency */1); } /* use a D-TLB? */ if (!mystricmp(dtlb_opt, "none")) dtlb = NULL; else { if (sscanf(dtlb_opt, "%[^:]:%d:%d:%d:%c", name, &nsets, &bsize, &assoc, &c) != 5) fatal("bad TLB parms: <name>:<nsets>:<page_size>:<assoc>:<repl>"); dtlb = cache_create(name, nsets, bsize, /* balloc */FALSE, /* usize */sizeof(md_addr_t), assoc, cache_char2policy(c), dtlb_access_fn, /* hit latency */1); } if (cache_dl1_lat < 1) fatal("l1 data cache latency must be greater than zero"); if (cache_dl2_lat < 1) fatal("l2 data cache latency must be greater than zero"); if (cache_il1_lat < 1) fatal("l1 instruction cache latency must be greater than zero"); if (cache_il2_lat < 1) fatal("l2 instruction cache latency must be greater than zero"); if (mem_nelt != 2) fatal("bad memory access latency (<first_chunk> <inter_chunk>)"); if (mem_lat[0] < 1 || mem_lat[1] < 1) fatal("all memory access latencies must be greater than zero"); if (mem_bus_width < 1 || (mem_bus_width & (mem_bus_width-1)) != 0) fatal("memory bus width must be positive non-zero and a power of two"); if (tlb_miss_lat < 1) fatal("TLB miss latency must be greater than zero"); if (res_ialu < 1) fatal("number of integer ALU's must be greater than zero"); if (res_ialu > MAX_INSTS_PER_CLASS) fatal("number of integer ALU's must be <= MAX_INSTS_PER_CLASS"); fu_config[FU_IALU_INDEX].quantity = res_ialu; if (res_imult < 1) fatal("number of integer multiplier/dividers must be greater than zero"); if (res_imult > MAX_INSTS_PER_CLASS) fatal("number of integer mult/div's must be <= MAX_INSTS_PER_CLASS"); fu_config[FU_IMULT_INDEX].quantity = res_imult; if (res_memport < 1) fatal("number of memory system ports must be greater than zero"); if (res_memport > MAX_INSTS_PER_CLASS) fatal("number of memory system ports must be <= MAX_INSTS_PER_CLASS"); fu_config[FU_MEMPORT_INDEX].quantity = res_memport; if (res_fpalu < 1) fatal("number of floating point ALU's must be greater than zero"); if (res_fpalu > MAX_INSTS_PER_CLASS) fatal("number of floating point ALU's must be <= MAX_INSTS_PER_CLASS"); fu_config[FU_FPALU_INDEX].quantity = res_fpalu; if (res_fpmult < 1) fatal("number of floating point multiplier/dividers must be > zero"); if (res_fpmult > MAX_INSTS_PER_CLASS) fatal("number of FP mult/div's must be <= MAX_INSTS_PER_CLASS"); fu_config[FU_FPMULT_INDEX].quantity = res_fpmult;}/* print simulator-specific configuration information */voidsim_aux_config(FILE *stream) /* output stream */{ /* nada */}/* register simulator-specific statistics */voidsim_reg_stats(struct stat_sdb_t *sdb) /* stats database */{ int i; stat_reg_counter(sdb, "sim_num_insn", "total number of instructions committed", &sim_num_insn, sim_num_insn, NULL); stat_reg_counter(sdb, "sim_num_refs", "total number of loads and stores committed", &sim_num_refs, 0, NULL); stat_reg_counter(sdb, "sim_num_loads", "total number of loads committed", &sim_num_loads, 0, NULL); stat_reg_formula(sdb, "sim_num_stores", "total number of stores committed", "sim_num_refs - sim_num_loads", NULL); stat_reg_counter(sdb, "sim_num_branches", "total number of branches committed", &sim_num_branches, /* initial value */0, /* format */NULL); stat_reg_int(sdb, "sim_elapsed_time", "total simulation time in seconds", &sim_elapsed_time, 0, NULL); stat_reg_formula(sdb, "sim_inst_rate", "simulation speed (in insts/sec)", "sim_num_insn / sim_elapsed_time", NULL); stat_reg_counter(sdb, "sim_total_insn", "total number of instructions executed", &sim_total_insn, 0, NULL); stat_reg_counter(sdb, "sim_total_refs", "total number of loads and stores executed", &sim_total_refs, 0, NULL); stat_reg_counter(sdb, "sim_total_loads",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -