Beispiel #1
0
        public virtual void PerformOperation(InternalRequest internalReq)
        {
            FlashChipDie targetDie = this.Dies[internalReq.TargetPageAddress.DieID];

            if (targetDie.Status != DieStatus.Idle &&
                (internalReq.ExecutionType != InternalRequestExecutionType.Multiplane) &&
                (internalReq.ExecutionType != InternalRequestExecutionType.InterleavedMultiplane))
            {
                throw new Exception("Executing operation on a busy die");
            }
            if (targetDie.Planes[internalReq.TargetPageAddress.PlaneID].Status == PlaneStatus.Busy)
            {
                throw new Exception("Executing operation on a busy plane");
            }

            targetDie.CurrentExecutingOperationCount++;
            targetDie.Status = DieStatus.Busy;
            targetDie.Planes[internalReq.TargetPageAddress.PlaneID].Status = PlaneStatus.Busy;
            targetDie.Planes[internalReq.TargetPageAddress.PlaneID].CurrentExecutingRequest = internalReq;
            ulong executionTime = 0;

            switch (internalReq.Type)
            {
            case InternalRequestType.Read:
                this.Status = FlashChipStatus.Reading;

                /* tR + tRR
                 * According to micron's manual, after read operation accomplishment, we have to wait for ready signals to be driven*/
                executionTime = readLatency + readDataOutputReadyTime;
                break;

            case InternalRequestType.Write:
                this.Status   = FlashChipStatus.Writing;
                executionTime = programLatency;
                break;

            case InternalRequestType.Clean:
                this.Status   = FlashChipStatus.Erasing;
                executionTime = eraseLatency;    //This is a normal erase requeset
                break;

            default:
                throw new Exception("Unhandled operation type");
            }
            internalReq.ExpectedFinishTime      = XEngineFactory.XEngine.Time + executionTime;
            internalReq.FlashChipExecutionEvent = new XEvent(internalReq.ExpectedFinishTime, this, internalReq, 0);
            XEngineFactory.XEngine.EventList.InsertXEvent(internalReq.FlashChipExecutionEvent);
            CurrentExecutingOperationCount++;
            if (CurrentExecutingOperationCount == 1)
            {
                ThisRoundExecutionStart     = XEngineFactory.XEngine.Time;
                ThisRoundExecutionFinish    = ulong.MaxValue;
                ExpectedFinishTime          = internalReq.ExpectedFinishTime;
                IssueTimeOfExecutingRequest = internalReq.IssueTime;
            }
        }
Beispiel #2
0
        public FlashChip(
            string id,
            uint channelID,
            uint localChipID,
            uint overallChipID,
            uint dieNo,
            uint PlaneNoPerDie,
            uint BlockNoPerPlane,
            uint PageNoPerBlock,
            uint BlockEraseLimit,
            ulong readLatency,
            ulong programLatency,
            ulong eraseLatency,
            ulong readDataOutputReadyTime
            ) : base(id)
        {
            this.ChannelID          = channelID;
            this.LocalChipID        = localChipID;
            this.OverallChipID      = overallChipID;
            this.CurrentActiveDieID = 0;
            this.PlaneNoPerDie      = PlaneNoPerDie;
            this.BlockNoPerPlane    = BlockNoPerPlane;
            this.PageNoPerBlock     = PageNoPerBlock;
            this.BlockEraseLimit    = BlockEraseLimit;
            this.Dies = new FlashChipDie[dieNo];
            for (uint dieID = 0; dieID < dieNo; dieID++)
            {
                Dies[dieID] = new FlashChipDie(channelID, overallChipID, localChipID, dieID, PlaneNoPerDie, BlockNoPerPlane, PageNoPerBlock);
            }
            this.ReadCount   = 0;
            this.ProgamCount = 0;
            this.EraseCount  = 0;

            this.readLatency             = readLatency;
            this.programLatency          = programLatency;
            this.eraseLatency            = eraseLatency;
            this.readDataOutputReadyTime = readDataOutputReadyTime;
            this.Status = FlashChipStatus.Idle;
        }
Beispiel #3
0
        public override void ProcessXEvent(XEvent e)
        {
            if (e.Removed)
            {
                return;
            }
            //Just only one xevent: OperationFinished
            InternalRequest targetRequest = e.Parameters as InternalRequest;
            FlashChipDie    targetDie     = this.Dies[targetRequest.TargetPageAddress.DieID];

            targetDie.CurrentExecutingOperationCount--;
            if (targetDie.CurrentExecutingOperationCount == 0)
            {
                targetDie.Status = DieStatus.Idle;
            }
            targetDie.Planes[targetRequest.TargetPageAddress.PlaneID].Status = PlaneStatus.Idle;
            targetDie.Planes[targetRequest.TargetPageAddress.PlaneID].CurrentExecutingRequest = null;

            CurrentExecutingOperationCount--;
            if (CurrentExecutingOperationCount == 0)
            {
                Status = FlashChipStatus.Idle;
                totalCommandExecutionPeriod += XEngineFactory.XEngine.Time - ThisRoundExecutionStart;
                ThisRoundExecutionFinish     = XEngineFactory.XEngine.Time;
            }

            switch (targetRequest.Type)
            {
            case InternalRequestType.Read:
                this.ReadCount++;
                targetDie.Planes[targetRequest.TargetPageAddress.PlaneID].ReadCount++;
                targetRequest.ExecutionTime += this.readLatency;
                this.Status = FlashChipStatus.Waiting;

                //Either a normal read (waiting for read data transfer) or a copyback read (waiting for write execution)
                this.CurrentWaitingTransfers++;

                if (targetDie.Status == DieStatus.Idle)
                {
                    targetDie.TotalReadExecutionPeriod += readLatency;
                }
                break;

            case InternalRequestType.Write:
                this.ProgamCount++;
                targetDie.Planes[targetRequest.TargetPageAddress.PlaneID].ProgamCount++;
                targetRequest.ExecutionTime += this.programLatency;

                if (targetDie.Status == DieStatus.Idle)
                {
                    targetDie.TotalProgramExecutionPeriod += programLatency;
                }
                break;

            case InternalRequestType.Clean:
                this.EraseCount++;
                targetDie.Planes[targetRequest.TargetPageAddress.PlaneID].EraseCount++;
                targetRequest.ExecutionTime += this.eraseLatency;
                FlashChipBlock targetBlock = this.Dies[targetRequest.TargetPageAddress.DieID].Planes[targetRequest.TargetPageAddress.PlaneID].Blocks[targetRequest.TargetPageAddress.BlockID];
                targetDie.Planes[targetRequest.TargetPageAddress.PlaneID].FreePagesNo += (PageNoPerBlock - targetBlock.FreePageNo);
                targetBlock.FreePageNo        = PageNoPerBlock;
                targetBlock.InvalidPageNo     = 0;
                targetBlock.LastWrittenPageNo = -1;
                targetBlock.EraseCount++;
                for (int i = 0; i < PageNoPerBlock; i++)
                {
                    targetBlock.Pages[i].StreamID    = FlashChipPage.PG_NOSTREAM;
                    targetBlock.Pages[i].ValidStatus = FlashChipPage.PG_FREE;
                    targetBlock.Pages[i].LPN         = ulong.MaxValue;
                }

                #region UpdateFastGCData
                targetDie.BlockInfoAbstract[targetBlock.BlockID].FreePageNo   += PageNoPerBlock;
                targetDie.BlockInfoAbstract[targetBlock.BlockID].InvalidPageNo = 0;
                targetDie.BlockInfoAbstract[targetBlock.BlockID].EraseCount++;
                #endregion

                if (targetDie.Status == DieStatus.Idle)
                {
                    targetDie.TotalEraseExecutionPeriod += eraseLatency;
                }
                break;

            default:
                break;
            }
            OnInternalRequestServiced(targetRequest);
        }