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

📄 bus.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    }      schedule_event(pbus->issuer, pbus->busy_until);  if ((req->type == REQUEST) || (req->type == COHE_REPLY))    pbus->num_subtrans[req->src_proc][req->req_type]++;  if (req->type == REPLY)    {      pbus->num_subtrans[req->dest_proc][req->req_type]++;      pbus->num_trans[req->dest_proc][req->type]++;      pbus->lat_trans[req->dest_proc][req->type]+=req->bus_cycles;    }  else    {      pbus->num_trans[req->src_proc][req->type]++;      pbus->lat_trans[req->src_proc][req->type]+=req->bus_cycles;    }}  /*============================================================================= * Send request on the bus (and of transaction). */void Bus_issuer(void){  BUS *pbus = (BUS *) YS__ActEvnt->uptr1;  REQ *req = pbus->cur_req;  if (req == NULL)    YS__errmsg(pbus->nodeid,	       "Bus_issuer(): Nothing to be sent on bus, why are we here?");  pbus->arb_delay += (YS__Simtime -		      req->bus_cycles*BUS_FREQUENCY -		      req->arb_start_time);    /*-------------------------------------------------------------------------*/  Bus_finish_trans(pbus, pbus->cur_req);  pbus->cur_req = NULL;}/*============================================================================= * Send request on the bus. */void Bus_perform(void){  BUS *pbus = (BUS *) YS__ActEvnt->uptr1;  if (pbus->cur_req == NULL)    YS__errmsg(pbus->nodeid,	       "Bus_perform(): Nothing to be sent on bus, why are we here?");  if (pbus->cur_req_owner == PROCESSOR)    Cache_send_on_bus(pbus->cur_req);    if (pbus->cur_req_owner == IO_MODULE)    IO_send_on_bus(pbus->cur_req);    if (pbus->cur_req_owner == COORDINATOR)    MMC_send_on_bus(pbus->cur_req);}/*============================================================================= * Send an I/O request to the specified I/O port. */void Bus_send_IO_request(REQ *req){  int n;  REQ *new_req;  if (req->dest_proc < ARCH_cpus)    {      if (req->dest_proc == TARGET_ALL_CPUS)	{                         /* @@@ copy instance and code @@@ */	  for (n = 0; n < ARCH_cpus - 1; n++)	    {	      new_req = (REQ*)YS__PoolGetObj(&YS__ReqPool);	      memcpy(new_req, req, sizeof(REQ));	      new_req->dest_proc = n;	      Cache_get_noncoh_request(new_req);	    }	  req->dest_proc = n;	  Cache_get_noncoh_request(req);	}      else	Cache_get_noncoh_request(req);    }  else    IO_get_request(PID2IO(req->node, req->dest_proc), req);}/*============================================================================= * Send a coherence request on bus. The coherence request will be taken * as external request by each bus module. */void Bus_send_request(REQ *req){  BUS *pbus = PID2BUS(req->node);  int n;    if (!tlb_non_coh(req->memattributes))    {      Cache_get_cohe_request(req);      IO_get_cohe_request(req);    }  MMC_recv_request(req);}/*============================================================================= * Send a coherence request on bus. The coherence request will be taken * as external request by each bus module. */void Bus_send_writepurge(REQ *req){  BUS *pbus = PID2BUS(req->node);  int n;    if (!tlb_non_coh(req->memattributes))    {      Cache_get_cohe_request(req);      IO_get_cohe_request(req);    }  MMC_recv_request(req);}/*============================================================================= * Send a reply for an uncached (I/O) read back to the requester. */void Bus_send_IO_reply(REQ *req){  Cache_get_IO_reply(req);}/*============================================================================= * Send a reply back to the requestor. Used by the coordinator (i.e. * the main memory controller. */void Bus_send_reply(REQ *req){  BUS *pbus = PID2BUS(req->node);  req->cohe_done = 1;  req->data_done = 1;  if (req->src_proc < ARCH_cpus)    Cache_get_reply(req);  else    IO_get_reply(req);}/*============================================================================= * Send a write back to the memory. Used by the processor when * dirty data is casted out the cache. */void Bus_send_writeback(REQ *req){  BUS *pbus = PID2BUS(req->node);  MMC_recv_write(req);}/*============================================================================= * Send a coherence report to cluster coordinator. Since there are dedicated * lines between processor and cluster coordinator, a processor can send * the coherence response at any time.  */void Bus_send_cohe_response(REQ *req, int state){  MMC_recv_cohe_response(req, state);}/*============================================================================= * Send a coherence data response. It's used to send out dirty data * directly to the requester and the coordinator. */void Bus_send_cohe_data_response(REQ *req){  BUS *pbus = PID2BUS(req->node);  REQ *nreq;    /*   * First, send dirty data to the requester.   * Second, send dirty data to the main memory controller. Dirty   * data is written back to memory so that the requester can mark    * the data clean instead of dirty to avoid further writebacks.   */  nreq = (REQ *)YS__PoolGetObj(&YS__ReqPool);  memcpy(nreq, req, sizeof(REQ));  if (req->dest_proc < ARCH_cpus)    Cache_get_data_response(req);  else    IO_get_data_response(req);  MMC_recv_data_response(nreq);}/*============================================================================= * Send a coherence completion. Used by the coordinator to complete * a request which has got the required data through cache-to-cache * transfer. */void Bus_send_cohe_completion(REQ *req){  req->cohe_done = 1;  if (req->src_proc < ARCH_cpus)    Cache_get_reply(req);  else    IO_get_reply(req);}void Bus_start_trans(BUS* pbus, REQ* req){  unsigned mask;  if (pbus->busfile == NULL)    return;  if ((req->req_type != WRITE_UC) &&      (req->req_type != READ_UC) &&      (req->req_type != SWAP_UC) &&      (req->req_type != REPLY_UC))    mask = ~(ARCH_linesz2 - 1);  else    mask = 0xFFFFFFFF;  fprintf(pbus->busfile, "%8.0f  Start  ",	  YS__Simtime);  if ((req->type == REQUEST) || (req->type == COHE_REPLY))    {      fprintf(pbus->busfile, "%s\t%08X\t%2d\t%i -> ",	      ReqName[req->req_type],	      req->paddr & mask,	      req->bus_cycles,	      req->src_proc);      if (req->dest_proc == TARGET_ALL_CPUS)	fprintf(pbus->busfile, "All CPUs\n");      if (req->dest_proc == TARGET_ALL_IOS)	fprintf(pbus->busfile, "All IOs\n");      if (req->dest_proc == TARGET_ALL_MODULES)	fprintf(pbus->busfile, "All Modules\n");      if (req->dest_proc >= 0)	fprintf(pbus->busfile, "%i\n", req->dest_proc);    }  if (req->type == WRITEBACK)    fprintf(pbus->busfile, "WRITE_BACK\t%08X\t%2d\t%i -> %i\n",	    req->paddr & mask,	    req->bus_cycles,	    req->src_proc,	    req->dest_proc);  if (req->type == WRITEPURGE)    fprintf(pbus->busfile, "WRITE_PURGE\t%08X\t%2d\t%i -> %i\n",	    req->paddr & mask,	    req->bus_cycles,	    req->src_proc,	    req->dest_proc);  if (req->type == REPLY)    {      fprintf(pbus->busfile, "%s\t%08X\t%2d\t%i -> ",	      ReqName[req->req_type],	      req->paddr & mask,	      req->bus_cycles,	      req->dest_proc);      if (req->src_proc == TARGET_ALL_CPUS)	fprintf(pbus->busfile, "All CPUs\n");      if (req->src_proc == TARGET_ALL_IOS)	fprintf(pbus->busfile, "All IOs\n");      if (req->src_proc == TARGET_ALL_MODULES)	fprintf(pbus->busfile, "All Modules\n");      if (req->src_proc >= 0)	fprintf(pbus->busfile, "%i\n", req->src_proc);    }  fflush(pbus->busfile);}void Bus_finish_trans(BUS* pbus, REQ* req){  if (pbus->busfile == NULL)    return;  if (req->type == WRITEBACK)    fprintf(pbus->busfile, "%8.0f  Finish WRITE_BACK\n\n",	    YS__Simtime);  else if (req->type == WRITEPURGE)    fprintf(pbus->busfile, "%8.0f  Finish WRITE_PURGE\n\n",	    YS__Simtime);  else    fprintf(pbus->busfile, "%8.0f  Finish %s\n\n",	    YS__Simtime,	    ReqName[req->req_type]);  fflush(pbus->busfile);}/*****************************************************************************//* Bus statistics functions                                                  *//*****************************************************************************/void Bus_print_params(int nid){  YS__statmsg(nid, "Bus Configuration\n");  YS__statmsg(nid, "  width:                %3d bytes\n", BUS_WIDTH);  YS__statmsg(nid, "  frequency:            %3d (%.3f MHz)\n",	      BUS_FREQUENCY, 1000000.0 / ((double)CPU_CLK_PERIOD * (double)BUS_FREQUENCY));  YS__statmsg(nid,	      "  arbitration delay:    %3d         turnaround cycles: %3d\n",	      BUS_ARBDELAY, BUS_TURNAROUND);  YS__statmsg(nid,	      "  mininum delay:        %3d  (# cycles between addresses)\n",	      BUS_MINDELAY);  YS__statmsg(nid,	      "  outstanding requests: %3d;  %d per CPU;  %d per I/O device\n",	      BUS_TOTAL_REQUESTS, BUS_CPU_REQUESTS, BUS_IO_REQUESTS);  YS__statmsg(nid,	      "  critical-word first :   %s\n", BUS_CRITICAL_WORD ? "on" : "off");  YS__statmsg(nid, "\n");}void Bus_stat_report(int nid){  BUS *pbus = PID2BUS(nid);  int  n, i;  long long num_trans = 0;  long long lat_trans = 0;  double    total_cycles = (YS__Simtime - pbus->last_clear) / BUS_FREQUENCY;    YS__statmsg(nid, "Bus Statistics\n");  for (n = 0; n < NUM_MODULES+1; n++)    {      for (i = 0; i < sizeof(trans_count_t) / sizeof(long long); i++)	{	  num_trans += pbus->num_trans[n][i];	  lat_trans += pbus->lat_trans[n][i];	}    }    YS__statmsg(nid, "  Avg. Arbitration Delay: %.2f processor cycles\n\n",	      pbus->arb_delay / num_trans);  YS__statmsg(nid, "  Transaction Breakdown\t       Count\t      Cycles (utilization)\n");  YS__statmsg(nid, "    Total\t\t%12lld\t%12lld (%2.2lf%%)\n",	      num_trans, lat_trans, 100.0 * ((double)lat_trans/total_cycles));  for (i = 0; i < sizeof(trans_count_t) / sizeof(long long); i++)    {      num_trans = 0;      lat_trans = 0;      for (n = 0; n < NUM_MODULES+1; n++)	{	  num_trans += pbus->num_trans[n][i];	  lat_trans += pbus->lat_trans[n][i];	}      if (num_trans == 0)	continue;            YS__statmsg(nid, "    %s \t\t%12lld\t%12lld (%2.2lf%%)\n",		  RName[i], num_trans, lat_trans,		  100.0 * ((double)lat_trans/total_cycles));      for (n = 0; n < NUM_MODULES+1; n++)	if (pbus->num_trans[n][i] != 0)	  {	    if (n < ARCH_cpus)	      YS__statmsg(nid, "       CPU %i \t\t\t%12lld\n",		      n, pbus->num_trans[n][i]);	    else if (n < ARCH_cpus + ARCH_ios)	      YS__statmsg(nid, "       IO %i \t\t\t%12lld\n",		      n - ARCH_cpus, pbus->num_trans[n][i]);	    else	      YS__statmsg(nid, "       MemCntl \t\t\t%12lld\n",		      pbus->num_trans[n][i]);	  }    }    YS__statmsg(nid, "\n  Transaction Subtype Breakdown\n");    for (i = 0; i < sizeof(subtrans_count_t) / sizeof(long long); i++)    {      num_trans = 0;      for (n = 0; n < NUM_MODULES+1; n++)	num_trans += pbus->num_subtrans[n][i];      if (num_trans == 0)	continue;            YS__statmsg(nid, "    %s \t%12lld\n",		  ReqName[i], num_trans);      for (n = 0; n < NUM_MODULES+1; n++)	if (pbus->num_subtrans[n][i] != 0)	  {	    if (n < ARCH_cpus)	      YS__statmsg(nid, "       CPU %i \t\t\t%12lld\n",		      n, pbus->num_subtrans[n][i]);	    else if (n < ARCH_cpus + ARCH_ios)	      YS__statmsg(nid, "       IO %i \t\t\t%12lld\n",		      n - ARCH_cpus, pbus->num_subtrans[n][i]);	    else	      YS__statmsg(nid, "       MemCntl \t\t\t%12lld\n",		      pbus->num_subtrans[n][i]);	  }    }    YS__statmsg(nid, "\n\n");}void Bus_stat_clear(int nid){  int i, n;  BUS *pbus = PID2BUS(nid);    for (n = 0; n < NUM_MODULES+1; n++)    {      for (i = 0; i < sizeof(trans_count_t) / sizeof(long long); i++)	{	  pbus->num_trans[n][i] = 0;	  pbus->lat_trans[n][i] = 0;	}      for (i = 0; i < sizeof(subtrans_count_t) / sizeof(long long); i++)	pbus->num_subtrans[n][i] = 0;    }  pbus->arb_delay   = 0.0;  pbus->last_clear  = YS__Simtime;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -