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

📄 issue.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * issue.c -- * *  This file contains issue engines for different DLX processors. * *  This file is part of DISC.  It was written by Yinong Zhang  *  (yinong@ecn.purdue.edu) * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "dlx.h"#define getcolor(x)	Colors[(x) & 0x000f]char *operationNames[] = {    "NOP", "ADD", "ADDI", "ADDU", "ADDUI", "AND", "ANDI", "BEQZ", "BFPF",    "BFPT", "BNEZ", "J", "JAL", "JALR", "JR", "LB", "LBU", "LD", "LF",    "LH", "LHI", "LHU", "LW", "MOVD", "MOVF", "MOVFP2I", "MOVI2FP",    "MOVI2S", "MOVS2I", "OR", "ORI", "RFE", "SB", "SD", "SEQ",  "SEQI",    "SEQU", "SEQUI",    "SF", "SGE", "SGEI", "SGEU", "SGEUI", "SGT", "SGTI", "SGTU", "SGTUI",    "SH", "SLE", "SLEI", "SLEU", "SLEUI", "SLL",    "SLLI", "SLT", "SLTI", "SLTU", "SLTUI", "SNE", "SNEI", "SNEU", "SNEUI",    "SRA", "SRAI", "SRL",    "SRLI", "SUB", "SUBI", "SUBU", "SUBUI", "SW", "TRAP", "XOR", "XORI",    "", "", "", "","", "",    /* There must be at least one empty string between the last integer operation     *	and the first floating point operation.	*/    "ADDD", "ADDF", "CVTD2F", "CVTD2I", "CVTF2D", "CVTF2I", "CVTI2D",    "CVTI2F", "DIV", "DIVD", "DIVF", "DIVU", "EQD", "EQF", "GED", "GEF",    "GTD", "GTF", "LED", "LEF", "LTD", "LTF", "MULT", "MULTD", "MULTF",    "MULTU", "NED", "NEF", "SUBD", "SUBF", ""    };char *Units[] = {" Int1 ", " Int2 ", " Int3 ", " Int4 ", " Int5 ", " Int6 ", " Int7 ", " Int8 "," Add1 ", " Add2 ", " Add3 ", " Add4 ",  " Add5 ", " Add6 ", " Add7 ", " Add8 ", " Div1 ", " Div2 ", " Div3 ", " Div4 "," Div5 ", " Div6 ", " Div7 ", " Div8 "," Mult1", " Mult2", " Mult3", " Mult4"," Mult5", " Mult6", " Mult7", " Mult8", " Load1", " Load2", " Load3", " Load4", " Load5", " Load6", " Load7", " Load8"};char *Colors[] ={"Goldenrod ",	"SlateBlue ",	"Red ",        	        "Purple ","Turquoise ", 	"Blue ",	"LightSeaGreen ",	"IndianRed ","Magenta ",	"VioletRed ",	"YellowGreen ", 	"DeepSkyBlue ","HotPink ", 	"SaddleBrown ",	"DarkSeaGreen ", 	"Maroon "};                              		char *functionTypes[] = {"int", "add", "div", "mul", "load", "store"};      /* * Forward declarations for procedures defined later in this file: */static void	GenEightBit(char *);static Op	*WhichOp(DLX *, int);static Op	*mallocOp(DLX *);static Update   *mallocUpdate(DLX *);static Bypass   *mallocBypass(DLX *);static void     BypassInsert(DLX *, int, int, int); static void     GenUpdateStruct(DLX *, char *, int, int, int, int, 		                char *, char *, char *, char *, char *);static voidGenEightBit(str)    char *str;{    char temp[20];    int i;    int len;    temp[0] = '\0';    len = strlen(str);    for (i = 0; i < (7 - len)/2.0; i++)      strcat(temp, " ");    strcat(temp, str);    for (i = 0; i < (8 - len)/2.0; i++)      strcat(temp, " ");    temp[8] = '\0';    strcpy(str, temp);}static voidGenUpdateStruct(machPtr, w, displayLater, actionType, displayCycle, readyCycle,     part1, part2, part3, part4, part5)    DLX *machPtr;			/* Machine description. */    char *w;    int displayLater;    int actionType;    int displayCycle;    int readyCycle;    char *part1;    char *part2;    char *part3;    char *part4;    char *part5;{  Update *updatePtr,  *uPtr;  if (!displayLater) {    Tcl_SetVar(machPtr->interp, "msg", part1, TCL_GLOBAL_ONLY);    switch (actionType) {      case INSERT_HIGHLIGHT:        Tcl_VarEval(machPtr->interp, "InsertAndHighLight ", w, "$msg", (char *)NULL);        break;      case HIGHLIGHT_CODE:        Tcl_VarEval(machPtr->interp, "HighLightCodeLine ", "$msg", (char *)NULL);        break;      case DELETE_INSERT:        Tcl_VarEval(machPtr->interp, "DeleteAndInsert ", w, "$msg", (char *)NULL);        break;      case ADD_END:        Tcl_VarEval(machPtr->interp, "AddToEnd ", w, "$msg", (char *)NULL);        break;      case SHOW_LINE:        goto InsertList;    }    return;  }  InsertList:  updatePtr = mallocUpdate(machPtr);  strcpy(updatePtr->w, w);  updatePtr->actionType = actionType;  updatePtr->displayCycle = displayCycle;  updatePtr->readyCycle = readyCycle;  strcpy(updatePtr->msg, part1);  strcat(updatePtr->msg, part2);  strcat(updatePtr->msg, part3);  strcat(updatePtr->msg, part4);  strcat(updatePtr->msg, part5);  if (machPtr->updateList == NULL ||       updatePtr->displayCycle < machPtr->updateList->displayCycle) {    updatePtr->nextPtr = machPtr->updateList;    machPtr->updateList = updatePtr;  } else {    for (uPtr = machPtr->updateList; uPtr->nextPtr != NULL;         uPtr = uPtr->nextPtr)       if (updatePtr->displayCycle < uPtr->nextPtr->displayCycle) break;    updatePtr->nextPtr = uPtr->nextPtr;    uPtr->nextPtr = updatePtr;  }}Op *Isu_Issue(machPtr, wordPtr, unitType, rs1Type, rs2Type, rdType)    DLX *machPtr;			/* Machine description. */    MemWord *wordPtr;    int unitType;    int rs1Type;    int rs2Type;    int rdType;{  Op *opPtr,  *opPtr2;  int i,j;  int wait;  int soonest;  int num_units;  int latency;   int load_store = 0;  int regType, regNumber;  Update *updatePtr;    char msg[80], part1[40];          switch (machPtr->config) {    case BASICPIPE: {      Bypass *bypassPtr;      int result_buf1 = TOTAL_REGS;      int result_buf2 = TOTAL_REGS;      int result_buf3 = TOTAL_REGS;      int mem_buf0 = TOTAL_REGS;      int mem_buf1 = TOTAL_REGS;      int IF, ID, EX, MEM, WB;      int rdReady;      int rs1;      int ful_pipe = 0;      int branch = 0;      int fpbypass_to_store = 0;      int k;      char *instrcolor;      char linelist[200], linecolorlist[200];      char textlist[100], textcolorlist[200];      char rectlist[200], rectcolorlist[200];      char *cycleTemp;      IF = machPtr->nextIF;      ID = machPtr->nextID;      instrcolor = getcolor(IF);       switch (unitType) {        case LOAD_BUF:        case STORE_BUF:          load_store = 1;          num_units = machPtr->num_int_units;          latency = 2;          unitType = INT;          break;        case INT:          num_units = machPtr->num_int_units;          latency = 1;          break;        case BRANCH:	  branch = 1;          num_units = machPtr->num_int_units;          latency = 1;          unitType = INT;          break;        case FP_ADD:          num_units = machPtr->num_add_units;          latency = machPtr->fp_add_latency;          ful_pipe = machPtr->add_ful_pipe;          break;        case FP_MUL:          num_units = machPtr->num_mul_units;          latency = machPtr->fp_mul_latency;          ful_pipe = machPtr->mul_ful_pipe;          break;        case FP_DIV:          latency = machPtr->fp_div_latency;          if (machPtr->fp_div_exist) {            num_units = machPtr->num_div_units;            ful_pipe = machPtr->div_ful_pipe;          } else {            /* POSSIBLE BUG. Visualization of block diagram do not know how               to show this.            */    	    unitType = FP_MUL;            num_units = machPtr->num_mul_units;            ful_pipe = machPtr->mul_ful_pipe;          }          break;       }       issueCheck0:      wait = 0;      /* check for WAW hazard */      if (rdType != NON_OP && machPtr->waiting_regs[wordPtr->rd])         wait = machPtr->waiting_regs[wordPtr->rd];      /* check for RAW hazard */      if (rs1Type != NON_OP && rs1Type != IMM_OP           && machPtr->waiting_regs[wordPtr->rs1] > wait)        wait = machPtr->waiting_regs[wordPtr->rs1];           /* for any store instr, the value of rs2 is required at the MEM	 stage, so the value of wait should be 	 "machPtr->waiting_regs[wordPtr->rs2]-1".  Also, note that for	 load instr, rs2Type is NON_OP      */      if (rs2Type != NON_OP && rs2Type != IMM_OP          && machPtr->waiting_regs[wordPtr->rs2] > wait)        wait = machPtr->waiting_regs[wordPtr->rs2] - load_store;      /* check for structural hazard */      for (i = 0, soonest = 0x7fffffff; i < num_units; i++) {        if (!(j = machPtr->func_units[unitType][i]))           break;        else           if (j < soonest)             soonest = j;      }      if (i == num_units && (soonest > wait))        wait = soonest;      /* check for multiple wirtes to FP reg file in the same cycle          rdReady is the clock cycle for the last EX stage      */      if (rdType && wordPtr->rd >= 32 && wordPtr->rd < 64) {        soonest = wait ? wait : machPtr->cycleCount;        /* load instructions "completes" in MEM stage, therefore,           1 (load_sotre) must be subtracted from rdReady.        */        rdReady = soonest + latency - load_store;        opPtr2 = machPtr->opsList;        while (opPtr2 != NULL) {          if (rdReady == opPtr2->rdReady && opPtr2->resultType &&               opPtr2->rd >=32 && opPtr2->rd < 64) {            soonest++;            rdReady++;            wait = soonest;    	    opPtr2 = opPtr2->nextPtr;          } else if (rdReady > opPtr2->rdReady) {    	    opPtr2 = opPtr2->nextPtr;	  } else {	    break;	  }        }      }           if (wait > machPtr->cycleCount) {        machPtr->cycleCount = wait;        Isu_WriteBack(machPtr);        goto issueCheck0;       }            sprintf(part1, "%d", wordPtr->line);      Tcl_VarEval(machPtr->interp, "HighLightCodeLine ", part1, (char *)NULL);         EX = machPtr->cycleCount + 1;      while (machPtr->bypassList != NULL && machPtr->bypassList->displayCycle < EX) {	bypassPtr = machPtr->bypassList;        machPtr->bypassList = bypassPtr->nextPtr;	Isu_FreeBypass(machPtr, bypassPtr);      }      while (machPtr->bypassList != NULL && machPtr->bypassList->displayCycle == EX) {	bypassPtr = machPtr->bypassList;        machPtr->bypassList = bypassPtr->nextPtr;	switch (bypassPtr->buffer) {	  case RESULT_BUF1:            result_buf1 = bypassPtr->reg;            break;	  case RESULT_BUF2:            result_buf2 = bypassPtr->reg;            break;	  case RESULT_BUF3:            result_buf3 = bypassPtr->reg;            break;	  case MEM_BUF0:            mem_buf0 = bypassPtr->reg;            break;	  case MEM_BUF1:            mem_buf1 = bypassPtr->reg;            break;        }        Isu_FreeBypass(machPtr, bypassPtr);              }      /* when a branch depends on a previous ALU operation or previous          two loads, there is a data hazard.      */      if (branch && rs1Type == INT_OP) {        rs1 = wordPtr->rs1;        if (rs1 == mem_buf1 || rs1 == result_buf1) {          machPtr->cycleCount++;             ID = machPtr->cycleCount;                 EX = ID + 1;          Isu_WriteBack(machPtr);          while (machPtr->bypassList != NULL && 	      machPtr->bypassList->displayCycle < EX) {	    bypassPtr = machPtr->bypassList;            machPtr->bypassList = bypassPtr->nextPtr;	    Isu_FreeBypass(machPtr, bypassPtr);	  }        }      }      /* Now, machPtr->cycleCount is one less than the EX stage clock cycle.         (not always the same as ID stage clock cycle)      */         opPtr = mallocOp(machPtr);      opPtr->unit = unitType * MAX_FUNC_UNITS + i;      opPtr->resultType = rdType;      opPtr->rdReady = machPtr->cycleCount + latency;      machPtr->nextIF = ID;      machPtr->nextID = EX;      if (unitType == INT) {        MEM = EX + 1;        WB = EX + 2;      } else {        MEM = opPtr->rdReady + 1;        WB = opPtr->rdReady + 2;      }      if (!machPtr->cycleDisplayMode) {        sprintf(msg, "%d;", IF);        Tcl_VarEval(machPtr->interp,        	    ".bas.datapath.counter configure -text ", msg,       	    ".bas.block.counter configure -text ", msg, (char *)NULL);      }          if (rs1Type != NON_OP && rs1Type != IMM_OP) {        switch (rs1Type) {          case INT_OP:            *((int *)&(opPtr->source1[0])) =             *((int *)&(machPtr->regs[wordPtr->rs1]));            break;          case SFP_OP:            *((float *)&(opPtr->source1[0])) =             *((float *)&(machPtr->regs[wordPtr->rs1]));            break;          case DFP_OP:            *((double *)&(opPtr->source1[0])) =            *((double *)&(machPtr->regs[wordPtr->rs1]));          break;        }      }           if (rs2Type != NON_OP && rs2Type != IMM_OP) {        switch (rs2Type) {          case INT_OP:            *((int *)&(opPtr->source2[0])) =             *((int *)&(machPtr->regs[wordPtr->rs2]));            break;          case SFP_OP:            *((float *)&(opPtr->source2[0])) =             *((float *)&(machPtr->regs[wordPtr->rs2]));    	break;          case DFP_OP:            *((double *)&(opPtr->source2[0])) =             *((double *)&(machPtr->regs[wordPtr->rs2]));    	break;        }        }            if (load_store)         opPtr->address = opPtr->source1[0] + wordPtr->extra;              if (ful_pipe)        machPtr->func_units[unitType][i] = 0;      else         machPtr->func_units[unitType][i] = opPtr->rdReady;          if (machPtr->opsList == NULL ||           opPtr->rdReady < machPtr->opsList->rdReady) {        opPtr->nextPtr = machPtr->opsList;        machPtr->opsList = opPtr;      } else {        for (opPtr2 = machPtr->opsList; opPtr2->nextPtr != NULL;     	 opPtr2 = opPtr2->nextPtr)           if (opPtr->rdReady < opPtr2->nextPtr->rdReady) break;        opPtr->nextPtr = opPtr2->nextPtr;        opPtr2->nextPtr = opPtr;      }      opPtr->rd = wordPtr->rd;      if (rdType && wordPtr->rd) {

⌨️ 快捷键说明

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