⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sim-outorder.c

📁 一个很有名的硬件模拟器。可以模拟CPU
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* 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 + -