public bool isIssuable(BusPacket busPacket) { switch (busPacket.busPacketType) { case BusPacketType.REFRESH: break; case BusPacketType.ACTIVATE: if ((bankStates[(int)busPacket.rank][(int)busPacket.bank].currentBankState == CurrentBankState.Idle || bankStates[(int)busPacket.rank][(int)busPacket.bank].currentBankState == CurrentBankState.Refreshing) && currentClockCycle >= bankStates[(int)busPacket.rank][(int)busPacket.bank].nextActivate && tFAWCountdown[(int)busPacket.rank].Count() < 4) { return(true); } else { return(false); } case BusPacketType.WRITE: case BusPacketType.WRITE_P: if (bankStates[(int)busPacket.rank][(int)busPacket.bank].currentBankState == CurrentBankState.RowActive && currentClockCycle >= bankStates[(int)busPacket.rank][(int)busPacket.bank].nextWrite && busPacket.row == bankStates[(int)busPacket.rank][(int)busPacket.bank].openRowAddress && rowAccessCounters[(int)busPacket.rank][(int)busPacket.bank] < Config.dram_config.TOTAL_ROW_ACCESSES) { return(true); } else { return(false); } case BusPacketType.READ_P: case BusPacketType.READ: if (bankStates[(int)busPacket.rank][(int)busPacket.bank].currentBankState == CurrentBankState.RowActive && currentClockCycle >= bankStates[(int)busPacket.rank][(int)busPacket.bank].nextRead && busPacket.row == bankStates[(int)busPacket.rank][(int)busPacket.bank].openRowAddress && rowAccessCounters[(int)busPacket.rank][(int)busPacket.bank] < Config.dram_config.TOTAL_ROW_ACCESSES) { return(true); } else { return(false); } case BusPacketType.PRECHARGE: if (bankStates[(int)busPacket.rank][(int)busPacket.bank].currentBankState == CurrentBankState.RowActive && currentClockCycle >= bankStates[(int)busPacket.rank][(int)busPacket.bank].nextPrecharge) { return(true); } else { return(false); } default: if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("ERROT == Error - Trying to issue a crazy bus packet type : "); } busPacket.print(); Environment.Exit(0); break; } return(false); }
public void receiveFromBus(ref BusPacket packet) { if (Config.dram_config.DEBUG_BUS) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine(" -- R" + this.id + " Receiving On Bus : "); } packet.print(); } if (Config.dram_config.VERIFICATION_OUTPUT) { packet.print(currentClockCycle, false); } switch (packet.busPacketType) { case BusPacketType.READ: //make sure a read is allowed if (bankStates[(int)packet.bank].currentBankState != CurrentBankState.RowActive || currentClockCycle < bankStates[(int)packet.bank].nextRead || packet.row != bankStates[(int)packet.bank].openRowAddress) { packet.print(); if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Rank " + id + " received a READ when not allowed"); } Environment.Exit(1); } //update state table bankStates[(int)packet.bank].nextPrecharge = Math.Max(bankStates[(int)packet.bank].nextPrecharge, currentClockCycle + Config.dram_config.READ_TO_PRE_DELAY); for (int i = 0; i < Config.dram_config.NUM_BANKS; i++) { bankStates[i].nextRead = Math.Max(bankStates[i].nextRead, currentClockCycle + Math.Max(Config.dram_config.tCCD, Config.dram_config.BL / 2)); bankStates[i].nextWrite = Math.Max(bankStates[i].nextWrite, currentClockCycle + Config.dram_config.READ_TO_WRITE_DELAY); } //get the read data and put it in the storage which delays until the appropriate time (RL) if (Config.dram_config.NO_STORAGE) { banks[(int)packet.bank].read(ref packet); } else { packet.busPacketType = BusPacketType.DATA; } readReturnPacket.Add(packet); readReturnCountdown.Add(Config.dram_config.RL); break; case BusPacketType.READ_P: //make sure a read is allowed if (bankStates[(int)packet.bank].currentBankState != CurrentBankState.RowActive || currentClockCycle < bankStates[(int)packet.bank].nextRead || packet.row != bankStates[(int)packet.bank].openRowAddress) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("ERROR == Error - Rank " + id + " received a READ_P when not allowed"); } Environment.Exit(1); } //update state table bankStates[(int)packet.bank].currentBankState = CurrentBankState.Idle; bankStates[(int)packet.bank].nextActivate = Math.Max(bankStates[(int)packet.bank].nextActivate, currentClockCycle + Config.dram_config.READ_AUTOPRE_DELAY); for (int i = 0; i < Config.dram_config.NUM_BANKS; i++) { //will set next read/write for all banks - including current (which shouldnt matter since its now idle) bankStates[i].nextRead = Math.Max(bankStates[i].nextRead, currentClockCycle + Math.Max(Config.dram_config.BL / 2, Config.dram_config.tCCD)); bankStates[i].nextWrite = Math.Max(bankStates[i].nextWrite, currentClockCycle + Config.dram_config.READ_TO_WRITE_DELAY); } //get the read data and put it in the storage which delays until the appropriate time (RL) if (Config.dram_config.NO_STORAGE) { banks[(int)packet.bank].read(ref packet); } else { packet.busPacketType = BusPacketType.DATA; } readReturnPacket.Add(packet); readReturnCountdown.Add(Config.dram_config.RL); break; case BusPacketType.WRITE: //make sure a write is allowed if (bankStates[(int)packet.bank].currentBankState != CurrentBankState.RowActive || currentClockCycle < bankStates[(int)packet.bank].nextWrite || packet.row != bankStates[(int)packet.bank].openRowAddress) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Rank " + id + " received a WRITE when not allowed"); } bankStates[(int)packet.bank].print(); Environment.Exit(1); } //update state table bankStates[(int)packet.bank].nextPrecharge = Math.Max(bankStates[(int)packet.bank].nextPrecharge, currentClockCycle + Config.dram_config.WRITE_TO_PRE_DELAY); for (int i = 0; i < Config.dram_config.NUM_BANKS; i++) { bankStates[i].nextRead = Math.Max(bankStates[i].nextRead, currentClockCycle + Config.dram_config.WRITE_TO_READ_DELAY_B); bankStates[i].nextWrite = Math.Max(bankStates[i].nextWrite, currentClockCycle + Math.Max(Config.dram_config.BL / 2, Config.dram_config.tCCD)); } //take note of where data is going when it arrives incomingWriteBank = (int)packet.bank; incomingWriteRow = (int)packet.row; incomingWriteColumn = (int)packet.column; // delete(packet); // packet. break; case BusPacketType.WRITE_P: //make sure a write is allowed if (bankStates[(int)packet.bank].currentBankState != CurrentBankState.RowActive || currentClockCycle < bankStates[(int)packet.bank].nextWrite || packet.row != bankStates[(int)packet.bank].openRowAddress) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Rank " + id + " received a WRITE_P when not allowed"); } Environment.Exit(1); } //update state table bankStates[(int)packet.bank].currentBankState = CurrentBankState.Idle; bankStates[(int)packet.bank].nextActivate = Math.Max(bankStates[(int)packet.bank].nextActivate, currentClockCycle + Config.dram_config.WRITE_AUTOPRE_DELAY); for (int i = 0; i < Config.dram_config.NUM_BANKS; i++) { bankStates[i].nextWrite = Math.Max(bankStates[i].nextWrite, currentClockCycle + Math.Max(Config.dram_config.tCCD, Config.dram_config.BL / 2)); bankStates[i].nextRead = Math.Max(bankStates[i].nextRead, currentClockCycle + Config.dram_config.WRITE_TO_READ_DELAY_B); } //take note of where data is going when it arrives incomingWriteBank = (int)packet.bank; incomingWriteRow = (int)packet.row; incomingWriteColumn = (int)packet.column; // delete(packet); break; case BusPacketType.ACTIVATE: //make sure activate is allowed if (bankStates[(int)packet.bank].currentBankState != CurrentBankState.Idle || currentClockCycle < bankStates[(int)packet.bank].nextActivate) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Rank " + id + " received an ACT when not allowed"); } packet.print(); bankStates[(int)packet.bank].print(); Environment.Exit(1); } bankStates[(int)packet.bank].currentBankState = CurrentBankState.RowActive; bankStates[(int)packet.bank].nextActivate = currentClockCycle + Config.dram_config.tRC; bankStates[(int)packet.bank].openRowAddress = (int)packet.row; //if AL is greater than one, then posted-cas is enabled - handle accordingly if (Config.dram_config.AL > 0) { bankStates[(int)packet.bank].nextWrite = currentClockCycle + (Config.dram_config.tRCD - Config.dram_config.AL); bankStates[(int)packet.bank].nextRead = currentClockCycle + (Config.dram_config.tRCD - Config.dram_config.AL); } else { bankStates[(int)packet.bank].nextWrite = currentClockCycle + (Config.dram_config.tRCD - Config.dram_config.AL); bankStates[(int)packet.bank].nextRead = currentClockCycle + (Config.dram_config.tRCD - Config.dram_config.AL); } bankStates[(int)packet.bank].nextPrecharge = currentClockCycle + Config.dram_config.tRAS; for (int i = 0; i < Config.dram_config.NUM_BANKS; i++) { if (i != packet.bank) { bankStates[i].nextActivate = Math.Max(bankStates[i].nextActivate, currentClockCycle + Config.dram_config.tRRD); } } // delete(packet); break; case BusPacketType.PRECHARGE: //make sure precharge is allowed if (bankStates[(int)packet.bank].currentBankState != CurrentBankState.RowActive || currentClockCycle < bankStates[(int)packet.bank].nextPrecharge) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Rank " + id + " received a PRE when not allowed"); } Environment.Exit(1); } bankStates[(int)packet.bank].currentBankState = CurrentBankState.Idle; bankStates[(int)packet.bank].nextActivate = Math.Max(bankStates[(int)packet.bank].nextActivate, currentClockCycle + Config.dram_config.tRP); // delete(packet); break; case BusPacketType.REFRESH: refreshWaiting = false; for (int i = 0; i < Config.dram_config.NUM_BANKS; i++) { if (bankStates[i].currentBankState != CurrentBankState.Idle) { if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Rank " + id + " received a REF when not allowed"); } Environment.Exit(1); } bankStates[i].nextActivate = currentClockCycle + Config.dram_config.tRFC; } // delete(packet); break; case BusPacketType.DATA: // TODO: replace this check with something that works? /* * if(packet->bank != incomingWriteBank || * packet->row != incomingWriteRow || * packet->column != incomingWriteColumn) * { * cout << "== Error - Rank " << id << " received a DATA packet to the wrong place" << endl; * packet->print(); * bankStates[packet->bank].print(); * exit(0); * } */ if (Config.dram_config.NO_STORAGE) { banks[(int)packet.bank].write(ref packet); } // end of the line for the write packet // delete(packet); break; default: if (Config.DEBUG_MEMORY) { DEBUG.WriteLine("== Error - Unknown BusPacketType trying to be sent to Bank"); } Environment.Exit(1); break; } }