예제 #1
0
        private void Decode()
        {
            int maxDecode = 0;

            while (!DE_RN.Stalled && FE_DE.Instructions.Count > 0 && maxDecode < 4)
            {
                IData     d = FE_DE.Instructions.Dequeue();
                UInt32    i = d.Data;
                DecodedOp op;
                op.PC    = d.PC;
                op.Op    = (byte)(i >> 25);
                op.Const = (UInt32)(i >> 4) & 0x1FFFFFU;
                op.Var   = (UInt32)(i >> 8) & 0x1FFFF;
                op.Dst   = (byte)((i >> 8) & 0xf);
                op.Src1  = (byte)((i >> 4) & 0xf);
                op.Src2  = (byte)((i >> 0) & 0xf);
                OpCodes.OpInfo opd = OpCodes.GetInfo((OpCodes.Op)op.Op);
                op.Meta = opd;

                DE_RN.Ops.Enqueue(op);
                // Optimization: Check op is a branch and if it is use branch prediction
                // to load in new instructions and do a partial pipeline flush.
                maxDecode++;
            }

            // Renamer is stalled for some reason, we will have to stall and propogate stall to fetch stage.
            FE_DE.Stalled = DE_RN.Stalled && FE_DE.Instructions.Count >= 4;

            this.StalledDecodeCycles += (4 - maxDecode);
        }
예제 #2
0
        private void Rename()
        {
            int maxRename = 0;

            while (PhysFreeList.PhysicalRegisterAvailable() && !this.IQueue.IsFull() && !ROB.Full() && DE_RN.Ops.Count > 0 && maxRename < 4)
            {
                DecodedOp      o   = DE_RN.Ops.Dequeue();
                byte           op  = o.Op;
                OpCodes.OpInfo opi = o.Meta;
                byte           dst = 0;
                if (opi.HasOutput)
                {
                    // TODO: Don't cast this. Do it properly.
                    dst = (byte)PhysFreeList.GetUnusedRegister();
                    PhysRegisters.SetReady(dst, false);
                }

                byte src1 = (byte)ArchToPhysTable.GetPhysicalRegisterId(opi.Src1Dep ? o.Src1 : 0);
                byte src2 = (byte)ArchToPhysTable.GetPhysicalRegisterId(opi.Src2Dep ? o.Src2 : 0);
                bool rd1  = opi.Src1Dep ? PhysRegisters.IsReady(src1) : true;
                bool rd2  = opi.Src2Dep ? PhysRegisters.IsReady(src2) : true;

                if (opi.HasOutput)
                {
                    byte archReg = 0;
                    switch (opi.OutputSource)
                    {
                    case OpCodes.DstSource.Dst:
                        archReg = o.Dst;
                        break;

                    case OpCodes.DstSource.Src1:
                        archReg = o.Src1;
                        break;

                    case OpCodes.DstSource.Src2:
                        archReg = o.Src2;
                        break;
                    }
                    ArchToPhysTable.MapArchToPhys(archReg, dst);
                    // Redirect dst register to the correct destination.
                    o.Dst = archReg;
                }
                // Resulting register of this operation should be declared not ready until it has executed.
                Console.WriteLine("Rename: rd1={0}, rd2={1}, src1={2}, src2={3}, dst={4}", rd1, rd2, (int)src1, (int)src2, (int)dst);
                // Add entry to issue queue and re-order buffer
                this.IQueue.AddToQueue(o.PC, op, src1, src2, dst, rd1, rd2, o.Const, o.Meta);
                this.ROB.AddToQueue(o.PC, o.Dst, dst, o.Meta.HasOutput);
                maxRename++;
            }

            // Stallable by multiple resource hazards: re-order buffer full, issue queue full or lack of physical registers.
            // Therefore a stall may occur, resulting in wasted cycles.
            this.DE_RN.Stalled = !PhysFreeList.PhysicalRegisterAvailable() || this.IQueue.IsFull() || ROB.Full() || DE_RN.Ops.Count >= 4;

            this.StalledRenameCycles += (4 - maxRename);
        }
예제 #3
0
 public void AddToQueue(UInt32 pc, byte op, byte src1, byte src2, byte dst, bool rd1, bool rd2, UInt32 constant, OpCodes.OpInfo info)
 {
     Debug.Assert(!IsFull());
     IQueue.Add(new Entry()
     {
         PC = pc, Op = op, Src1 = src1, Src2 = src2, Rd1 = rd1, Rd2 = rd2, Dst = dst, Const = constant, Meta = info
     });
 }