void decode_reg_options(struct opt_odb_t * odb, struct core_knobs_t * knobs) { /* decode pipe */ opt_reg_int(odb, "-decode:depth","decode pipeline depth (stages) [DS]", &knobs->decode.depth, /*default*/ knobs->decode.depth, /*print*/true,/*format*/NULL); opt_reg_int(odb, "-decode:width","decode pipeline width (Macro-ops) [DS]", &knobs->decode.width, /*default*/ knobs->decode.width, /*print*/true,/*format*/NULL); opt_reg_int(odb, "-decode:targetstage","decode pipeline stage of branch address calculator [DS]", &knobs->decode.target_stage, /*default*/ knobs->decode.target_stage, /*print*/true,/*format*/NULL); opt_reg_int(odb, "-decode:branches","maximum branches decoded per cycle [D]", &knobs->decode.branch_decode_limit, /*default*/ knobs->decode.branch_decode_limit, /*print*/true,/*format*/NULL); /* actual decoders */ opt_reg_int_list(odb, "-decoders", "maximum uops generated for each decoder (e.g., 4 1 1) [D]", knobs->decode.decoders, MAX_DECODE_WIDTH, &knobs->decode.num_decoder_specs, knobs->decode.decoders, /* print */true, /* format */NULL, /* !accrue */false); opt_reg_int(odb, "-MS:latency","additional latency for accessing ucode sequencer (cycles) [D]", &knobs->decode.MS_latency, /*default*/ knobs->decode.MS_latency, /*print*/true,/*format*/NULL); opt_reg_int(odb, "-uopQ:size","number of entries in uopQ [D]", &knobs->decode.uopQ_size, /*default*/ knobs->decode.uopQ_size, /*print*/true,/*format*/NULL); /* fusion options */ opt_reg_flag(odb, "-fuse:none","disable all uop fusion rules [DS]", &knobs->decode.fusion_none, /*default*/ false, /*print*/true,/*format*/NULL); opt_reg_flag(odb, "-fuse:all","enable all uop fusion rules [D]", &knobs->decode.fusion_all, /*default*/ false, /*print*/true,/*format*/NULL); opt_reg_flag(odb, "-fuse:loadop","enable load-op uop fusion [D]", &knobs->decode.fusion_load_op, /*default*/ false, /*print*/true,/*format*/NULL); opt_reg_flag(odb, "-fuse:stastd","enable sta-std uop fusion [D]", &knobs->decode.fusion_sta_std, /*default*/ false, /*print*/true,/*format*/NULL); opt_reg_flag(odb, "-fuse:partial","enable uop-fusion of partial register write combining uops [D]", &knobs->decode.fusion_partial, /*default*/ false, /*print*/true,/*format*/NULL); }
/* register simulator-specific options */ void sim_reg_options(struct opt_odb_t *odb) { opt_reg_header(odb, "sim-bpred: This simulator implements a branch predictor analyzer.\n" ); /* branch predictor options */ opt_reg_note(odb, " Branch predictor configuration examples for 2-level predictor:\n" " Configurations: N, M, W, X\n" " N # entries in first level (# of shift register(s))\n" " W width of shift register(s)\n" " M # entries in 2nd level (# of counters, or other FSM)\n" " X (yes-1/no-0) xor history and address for 2nd level index\n" " Sample predictors:\n" " GAg : 1, W, 2^W, 0\n" " GAp : 1, W, M (M > 2^W), 0\n" " PAg : N, W, 2^W, 0\n" " PAp : N, W, M (M == 2^(N+W)), 0\n" " gshare : 1, W, 2^W, 1\n" " Predictor `comb' combines a bimodal and a 2-level predictor.\n" ); /* instruction limit */ opt_reg_uint(odb, "-max:inst", "maximum number of inst's to execute", &max_insts, /* default */0, /* print */TRUE, /* format */NULL); opt_reg_string(odb, "-bpred", "branch predictor type {nottaken|taken|smartstatic|bimod|2lev|comb}", &pred_type, /* default */"bimod", /* print */TRUE, /* format */NULL); opt_reg_int_list( odb, "-bpred:bimod", "bimodal predictor config (<num bits> <table size>)", bimod_config, bimod_nelt, &bimod_nelt, bimod_config, // default TRUE, // print NULL, // format FALSE); // !accrue opt_reg_int_list( odb, "-bpred:2lev", "2-level predictor config " "(<num bits> <l1size> <l2size> <hist_size> <xor>)", twolev_config, twolev_nelt, &twolev_nelt, twolev_config, // default TRUE, // print NULL, // format FALSE); // !accrue opt_reg_int_list(odb, "-bpred:comb", "combining predictor config (<meta_table_size>)", comb_config, comb_nelt, &comb_nelt, /* default */comb_config, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); opt_reg_int(odb, "-bpred:ras", "return address stack size (0 for no return stack)", &ras_size, /* default */ras_size, /* print */TRUE, /* format */NULL); opt_reg_int_list(odb, "-bpred:btb", "BTB config (<num_sets> <associativity>) (-1 -1 to disable)", btb_config, btb_nelt, &btb_nelt, /* default */btb_config, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); }
/* register simulator-specific options */ static void sim_reg_options(struct opt_odb_t *odb) { /* ifetch options */ opt_reg_int(odb, "-fetch:ifqsize", "instruction fetch queue size (in insts)", &ruu_ifq_size, /* default */4, /* print */TRUE, /* format */NULL); opt_reg_int(odb, "-fetch:mplat", "extra branch mis-prediction latency", &ruu_branch_penalty, /* default */5, /* print */TRUE, /* format */NULL); opt_reg_int(odb, "-fetch:speed", "speed of front-end of machine relative to execution core", &fetch_speed, /* default */1, /* print */TRUE, /* format */NULL); /* branch predictor options */ opt_reg_string(odb, "-bpred", "branch predictor type {nottaken|taken|perfect|bimod|2lev|comb}", &pred_type, /* default */"perfect", /* print */TRUE, /* format */NULL); opt_reg_int_list(odb, "-bpred:bimod", "bimodal predictor config (<table size>)", bimod_config, bimod_nelt, &bimod_nelt, /* default */bimod_config, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); opt_reg_int_list(odb, "-bpred:2lev", "2-level predictor config " "(<l1size> <l2size> <hist_size> <xor>)", twolev_config, twolev_nelt, &twolev_nelt, /* default */twolev_config, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); opt_reg_int_list(odb, "-bpred:comb", "combining predictor config (<meta_table_size>)", comb_config, comb_nelt, &comb_nelt, /* default */comb_config, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); opt_reg_int_list(odb, "-bpred:btb", "BTB config (<num_sets> <associativity>)", btb_config, btb_nelt, &btb_nelt, /* default */btb_config, /* print */TRUE, /* format */NULL, /* !accrue */FALSE); /* decode options */ opt_reg_int(odb, "-decode:width", "instruction decode B/W (insts/cycle)", &ruu_decode_width, /* default */1, /* print */TRUE, /* format */NULL); /* issue options */ opt_reg_int(odb, "-issue:width", "instruction issue B/W (insts/cycle)", &ruu_issue_width, /* default */1, /* print */TRUE, /* format */NULL); opt_reg_flag(odb, "-issue:inorder", "run pipeline with in-order issue", &ruu_inorder_issue, /* default */TRUE, /* print */TRUE, /* format */NULL); opt_reg_flag(odb, "-issue:wrongpath", "issue instructions down wrong execution paths", &ruu_include_spec, /* default */TRUE, /* print */TRUE, /* format */NULL); /* commit options */ opt_reg_int(odb, "-commit:width", "instruction commit B/W (insts/cycle)", &ruu_commit_width, /* default */1, /* print */TRUE, /* format */NULL); /* register scheduler options */ opt_reg_int(odb, "-ruu:size", "register update unit (RUU) size", &RUU_size, /* default */2, /* print */TRUE, /* format */NULL); /* memory scheduler options */ opt_reg_int(odb, "-lsq:size", "load/store queue (LSQ) size", &LSQ_size, /* default */1, /* print */TRUE, /* format */NULL); /* cache options */ opt_reg_string(odb, "-cache:dl1", "l1 data cache config, i.e., {<config>|none}", &cache_dl1_opt, "dl1:128:32:1:l", /* print */TRUE, NULL); opt_reg_int(odb, "-cache:dl1lat", "l1 data cache hit latency (in cycles)", &cache_dl1_lat, /* default */1, /* print */TRUE, /* format */NULL); opt_reg_string(odb, "-cache:dl2", "l2 data cache config, i.e., {<config>|none}", &cache_dl2_opt, "none", //"ul2:128:32:1:l", /* print */TRUE, NULL); opt_reg_int(odb, "-cache:dl2lat", "l2 data cache hit latency (in cycles)", &cache_dl2_lat, /* default */25, /* print */TRUE, /* format */NULL); opt_reg_string(odb, "-cache:il1", "l1 inst cache config, i.e., {<config>|dl1|dl2|none}", &cache_il1_opt, "il1:128:32:1:l", /* print */TRUE, NULL); opt_reg_int(odb, "-cache:il1lat", "l1 instruction cache hit latency (in cycles)", &cache_il1_lat, /* default */1, /* print */TRUE, /* format */NULL); opt_reg_string(odb, "-cache:il2", "l2 instruction cache config, i.e., {<config>|dl2|none}", &cache_il2_opt, "none", //"dl2", //"ul2:256:64:8:l", /* print */TRUE, NULL); opt_reg_int(odb, "-cache:il2lat", "l2 instruction cache hit latency (in cycles)", &cache_il2_lat, /* default */25, /* print */TRUE, /* format */NULL); /* 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 */64, /* print */TRUE, /* format */NULL); /* TLB options */ opt_reg_string(odb, "-tlb:itlb", "instruction TLB config, i.e., {<config>|none}", &itlb_opt, "none", /* print */TRUE, NULL); opt_reg_string(odb, "-tlb:dtlb", "data TLB config, i.e., {<config>|none}", &dtlb_opt, "none", /* 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_int(odb, "-recursive", "maximum occurance of a function in the call string", &max_recursive_calls, 2, TRUE, NULL); // register my options opt_reg_string(odb, "-run", "functionality {CFG EST}", &run_opt, /* default */"EST", /* print */TRUE, /* format */NULL); }
void main(int argc, char **argv) { struct opt_odb_t *odb; int n_int_vars, n_uint_vars, n_float_vars, n_double_vars; int n_enum_vars, n_enum_eval_vars, n_flag_vars, n_string_vars; int int_var, int_vars[MAX_VARS]; unsigned int uint_var, uint_vars[MAX_VARS]; float float_var, float_vars[MAX_VARS]; double double_var, double_vars[MAX_VARS]; int flag_var, flag_vars[MAX_VARS]; char *string_var, *string_vars[MAX_VARS]; enum etest_t { enum_a, enum_b, enum_c, enum_d, enum_NUM }; static char *enum_emap[enum_NUM] = { "enum_a", "enum_b", "enum_c", "enum_d" }; static int enum_eval[enum_NUM] = { enum_d, enum_c, enum_b, enum_a }; int enum_var, enum_vars[MAX_VARS]; int enum_eval_var, enum_eval_vars[MAX_VARS]; /* get an options processor */ odb = opt_new(f_orphan_fn); opt_reg_int(odb, "-opt:int", "This is an integer option.", &int_var, 1, /* print */TRUE, /* default format */NULL); opt_reg_int_list(odb, "-opt:int:list", "This is an integer list option.", int_vars, MAX_VARS, &n_int_vars, 2, /* print */TRUE, /* default format */NULL); opt_reg_uint(odb, "-opt:uint", "This is an unsigned integer option.", &uint_var, 3, /* print */TRUE, /* default format */NULL); opt_reg_uint_list(odb, "-opt:uint:list", "This is an unsigned integer list option.", uint_vars, MAX_VARS, &n_uint_vars, 4, /* print */TRUE, /* default format */NULL); opt_reg_float(odb, "-opt:float", "This is a float option.", &float_var, 5.0, /* print */TRUE, /* default format */NULL); opt_reg_float_list(odb, "-opt:float:list", "This is a float list option.", float_vars, MAX_VARS, &n_float_vars, 6.0, /* print */TRUE, /* default format */NULL); opt_reg_double(odb, "-opt:double", "This is a double option.", &double_var, 7.0, /* print */TRUE, /* default format */NULL); opt_reg_double_list(odb, "-opt:double:list", "This is a double list option.", double_vars, MAX_VARS, &n_double_vars, 8.0, /* print */TRUE, /* default format */NULL); opt_reg_enum(odb, "-opt:enum", "This is an enumeration option.", &enum_var, "enum_a", enum_emap, /* index map */NULL, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_enum_list(odb, "-opt:enum:list", "This is a enum list option.", enum_vars, MAX_VARS, &n_enum_vars, "enum_b", enum_emap, /* index map */NULL, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_enum(odb, "-opt:enum:eval", "This is an enumeration option w/eval.", &enum_eval_var, "enum_b", enum_emap, enum_eval, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_enum_list(odb, "-opt:enum:eval:list", "This is a enum list option w/eval.", enum_eval_vars, MAX_VARS, &n_enum_eval_vars, "enum_a", enum_emap, enum_eval, enum_NUM, /* print */TRUE, /* default format */NULL); opt_reg_flag(odb, "-opt:flag", "This is a boolean flag option.", &flag_var, FALSE, /* print */TRUE, /* default format */NULL); opt_reg_flag_list(odb, "-opt:flag:list", "This is a boolean flag list option.", flag_vars, MAX_VARS, &n_flag_vars, TRUE, /* print */TRUE, /* default format */NULL); opt_reg_string(odb, "-opt:string", "This is a string option.", &string_var, "a:string", /* print */TRUE, /* default format */NULL); opt_reg_string_list(odb, "-opt:string:list", "This is a string list option.", string_vars, MAX_VARS, &n_string_vars, "another:string", /* print */TRUE, /* default format */NULL); /* parse options */ opt_process_options(odb, argc, argv); /* print options */ fprintf(stdout, "## Current Option Values ##\n"); opt_print_options(odb, stdout, /* long */FALSE, /* notes */TRUE); /* all done */ opt_delete(odb); exit(0); }