Exemple #1
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            if (operandTypes.Length != 1 || resultTypes.Length != 2)
            {
                return(null);
            }

            if (!operandTypes[0].CILType.Equals(typeof(SFix)) ||
                !resultTypes[0].CILType.Equals(typeof(SFix)) ||
                !resultTypes[1].Equals(resultTypes[0]))
            {
                return(null);
            }

            var xfmt = SFix.GetFormat(operandTypes[0]);
            var yfmt = SFix.GetFormat(resultTypes[0]);

            int lutWidth   = Math.Max(1, xfmt.FracWidth - 1);
            int mulWidth   = Math.Max(1, xfmt.FracWidth - lutWidth);
            int pipeStages = 0; // 2 * mulWidth * mulWidth / (18 * 18) + yfmt.FracWidth / 18 + 1;
            var scc        = new SinCosLUTCore(lutWidth, xfmt.FracWidth, yfmt.FracWidth, pipeStages);

            var mappings = TryMap(scc.TASite, instr, operandTypes, resultTypes);

            Debug.Assert(mappings.Any());
            return(mappings.First());
        }
Exemple #2
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            if (!instr.Name.Equals(InstructionCodes.RdPort))
            {
                yield break;
            }

            var ts = taSite as DirectPortReadTransactionSite;

            if (ts == null)
            {
                yield break;
            }

            //if (ts.Host != _host)
            //    yield break;

            var tgPort = (ISignalOrPortDescriptor)instr.Operand;

            if (!ts.Port.Equals(tgPort))
            {
                yield break;
            }

            yield return(new DirectPortReadXILMapping(ts.Host, ts));
        }
Exemple #3
0
        private bool TryGetConstSLV(XILInstr instr, TypeDescriptor rtype, out StdLogicVector constSLV)
        {
            switch (instr.Name)
            {
            case InstructionCodes.LdConst:
            {
                object constValue = instr.Operand;
                constSLV = StdLogicVector.Serialize(constValue);
            }
            break;

            case InstructionCodes.Ld0:
            {
                object         sample = rtype.GetSampleInstance();
                StdLogicVector slv    = StdLogicVector.Serialize(sample);
                constSLV = StdLogicVector._0s(slv.Size);
            }
            break;

            default:
            {
                constSLV = "";
                return(false);
            }
            }
            return(true);
        }
Exemple #4
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var    fu     = taSite.Host;
            Slicer slicer = fu as Slicer;

            if (slicer == null)
            {
                yield break;
            }

            bool isSigned;
            int  inputWidth, hiOffset, loOffset;

            if (!GetSliceParams(instr, operandTypes, resultTypes, out isSigned, out inputWidth, out hiOffset, out loOffset))
            {
                yield break;
            }

            if (slicer.IsSigned != isSigned)
            {
                yield break;
            }

            if (slicer.InputWidth != inputWidth)
            {
                yield break;
            }

            if (hiOffset != slicer.HiOffset || loOffset != slicer.LoOffset)
            {
                yield break;
            }

            yield return(new SlicerXILMapping(slicer));
        }
Exemple #5
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            //if (fu != _host)
            //    yield break;
            var taBM = taSite as InlineBCUTransactionSite;

            if (taBM == null)
            {
                yield break;
            }

            switch (instr.Name)
            {
            case InstructionCodes.Goto:
                yield return(new InlineBCUMapping(taBM, InstructionCodes.Goto, (BranchLabel)instr.Operand));

                break;

            case InstructionCodes.BranchIfTrue:
                yield return(new InlineBCUMapping(taBM, InstructionCodes.BranchIfTrue, (BranchLabel)instr.Operand));

                break;

            case InstructionCodes.BranchIfFalse:
                yield return(new InlineBCUMapping(taBM, InstructionCodes.BranchIfFalse, (BranchLabel)instr.Operand));

                break;

            default:
                yield break;
            }
        }
Exemple #6
0
        private void Process(XIL3Instr xil3i)
        {
            var preds = xil3i.Preds.Select(p => p.Remap(_slotRemap[p.PredIndex])).ToArray();
            _instRemap.Add(_outInstrs.Count);

            foreach (int oslot in xil3i.OperandSlots)
            {
                Emit(DefaultInstructionSet.Instance
                    .LoadVar(_interLocals[oslot]).CreateStk(preds, 0, _interLocals[oslot].Type));
            }
            _slotRemap.Add(_outInstrs.Count);
            var cmd = xil3i.Command;
            if (cmd.Name == InstructionCodes.BranchIfFalse ||
                cmd.Name == InstructionCodes.BranchIfTrue ||
                cmd.Name == InstructionCodes.Goto)
            {
                var target = (BranchLabel)cmd.Operand;
                var newTarget = new BranchLabel() { InstructionIndex = target.InstructionIndex };
                cmd = new XILInstr(cmd.Name, newTarget) { BackRef = cmd.BackRef };
                _labels.Add(newTarget);
            }
            Emit(cmd.CreateStk(preds, xil3i.OperandSlots.Length,
                xil3i.OperandSlots.Select(os => _interLocals[os].Type)
                .Concat(xil3i.ResultSlots.Select(rs => _interLocals[rs].Type))
                .ToArray()));
            foreach (int rslot in xil3i.ResultSlots.Reverse())
            {
                Emit(DefaultInstructionSet.Instance
                    .StoreVar(_interLocals[rslot]).CreateStk(1, _interLocals[rslot].Type));
            }
        }
Exemple #7
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            if (instr.Name != InstructionCodes.Abs)
            {
                return(null);
            }

            var operandFormat = operandTypes[0].GetFixFormat();

            if (operandFormat == null)
            {
                return(null);
            }

            var resultFormat = resultTypes[0].GetFixFormat();

            if (resultFormat == null)
            {
                return(null);
            }

            if (operandFormat.FracWidth != resultFormat.FracWidth)
            {
                return(null);
            }

            var fu = new FixedAbs(
                operandFormat.TotalWidth,
                resultFormat.TotalWidth,
                ComputeLatency(operandFormat.TotalWidth, resultFormat.TotalWidth));

            return(new AbsMapping(fu));
        }
Exemple #8
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu  = taSite.Host;
            var scc = fu as SinCosLUTCore;

            if (scc == null)
            {
                yield break;
            }

            if (operandTypes.Length != 1 || resultTypes.Length != 2)
            {
                yield break;
            }

            var xType = TypeDescriptor.GetTypeOf(SFix.FromDouble(0.0, scc.XIntWidth, scc.XFracWidth));
            var yType = TypeDescriptor.GetTypeOf(SFix.FromDouble(0.0, scc.YIntWidth, scc.YFracWidth));

            if (!operandTypes[0].Equals(xType) ||
                !resultTypes[0].Equals(yType) ||
                !resultTypes[1].Equals(yType))
            {
                yield break;
            }

            if (instr.Name != InstructionCodes.ScSinCos)
            {
                yield break;
            }

            yield return(new Mapping(scc));
        }
Exemple #9
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            var far = instr.Operand as FixedArrayRef;

            if (far == null)
            {
                return(null);
            }

            var taSite = new MemoryMapperTransactionSite(this, host, far);

            switch (instr.Name)
            {
            case InstructionCodes.LdelemFixA:
                return(new LdelemFixAMapping(taSite));

            case InstructionCodes.LdelemFixAFixI:
                return(new LdelemFixAFixIMapping(taSite, far.Indices));

            case InstructionCodes.StelemFixA:
                return(new StelemFixAMapping(taSite));

            case InstructionCodes.StelemFixAFixI:
                return(new StelemFixAFixIMapping(taSite, far.Indices));

            default:
                return(null);
            }
        }
Exemple #10
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var mapping = TryMapOne(taSite, instr, operandTypes, resultTypes);

            if (mapping != null)
            {
                yield return(mapping);
            }
        }
Exemple #11
0
        /// <summary>
        /// The default branch handler is applied to any branching instruction when there is no more specific handler registered.
        /// </summary>
        /// <param name="i">instruction to process</param>
        virtual protected void ProcessBranch(XILSInstr i)
        {
            BranchLabel label    = (BranchLabel)i.StaticOperand;
            BranchLabel newLabel = Retarget(label);
            XILInstr    xi       = new XILInstr(i.Name, newLabel);
            var         preds    = RemapPreds(i.Preds);

            Emit(xi.CreateStk(preds, i.OperandTypes, i.ResultTypes));
        }
Exemple #12
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var       fu     = taSite.Host;
            FixFPMod1 fpmod1 = fu as FixFPMod1;

            if (fpmod1 == null)
            {
                yield break;
            }
            if (instr.Name != InstructionCodes.Mod2 &&
                instr.Name != InstructionCodes.Rempow2)
            {
                yield break;
            }

            if (instr.Name == InstructionCodes.Rempow2)
            {
                int n = (int)instr.Operand;
                if (n != 0)
                {
                    yield break;
                }
            }

            FixFormat infmt  = GetFixFormat(operandTypes[0]);
            FixFormat outfmt = GetFixFormat(resultTypes[0]);

            if (infmt == null || outfmt == null)
            {
                yield break;
            }

            if (infmt.IntWidth < 2 || outfmt.IntWidth < 2)
            {
                yield break;
            }
            if (infmt.FracWidth != outfmt.FracWidth)
            {
                yield break;
            }

            if (infmt.IntWidth != fpmod1.InIntWidth)
            {
                yield break;
            }
            if (infmt.FracWidth != fpmod1.FracWidth)
            {
                yield break;
            }
            if (outfmt.IntWidth != fpmod1.OutIntWidth)
            {
                yield break;
            }

            yield return(new FPMod1XILMapping(fpmod1));
        }
Exemple #13
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu  = taSite.Host;
            var fna = fu as FloatNegAbs;

            if (fna == null)
            {
                yield break;
            }

            if (operandTypes.Length != 1 || resultTypes.Length != 1)
            {
                yield break;
            }

            int totalWidth;

            if (operandTypes[0].CILType.Equals(typeof(float)) && resultTypes[0].CILType.Equals(typeof(float)))
            {
                totalWidth = 32;
            }
            else if (operandTypes[0].CILType.Equals(typeof(double)) && resultTypes[0].CILType.Equals(typeof(double)))
            {
                totalWidth = 64;
            }
            else
            {
                yield break;
            }

            if (fna.TotalWidth != totalWidth)
            {
                yield break;
            }

            switch (fna.Operation)
            {
            case FloatNegAbs.EOperation.Abs:
                if (instr.Name != InstructionCodes.Abs)
                {
                    yield break;
                }
                break;

            case FloatNegAbs.EOperation.Neg:
                if (instr.Name != InstructionCodes.Neg)
                {
                    yield break;
                }
                break;

            default:
                throw new NotImplementedException();
            }
            yield return(new Mapping(fna));
        }
 /// <summary>
 /// Constructs a <c>FunctionCall</c> representation of executing a XIL instruction.
 /// </summary>
 /// <param name="xi">XIL instruction to execute</param>
 /// <param name="resultType">result type descriptor</param>
 /// <param name="args">expressions representing the instruction arguments</param>
 public static FunctionCall XILOpCode(XILInstr xi, TypeDescriptor resultType, params Expression[] args)
 {
     return(new FunctionCall()
     {
         Callee = MakeFun(
             new IntrinsicFunction(IntrinsicFunction.EAction.XILOpCode, xi),
             resultType),
         Arguments = args,
         ResultType = resultType
     });
 }
Exemple #15
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu   = taSite.Host;
            var fsas = fu as FloatSignAsSigned;

            if (fsas == null)
            {
                yield break;
            }

            if (instr.Name != InstructionCodes.Sign)
            {
                yield break;
            }

            int floatWidth;

            if (operandTypes[0].CILType.Equals(typeof(float)))
            {
                floatWidth = 32;
            }
            else if (operandTypes[0].CILType.Equals(typeof(double)))
            {
                floatWidth = 64;
            }
            else if (operandTypes[0].CILType.Equals(typeof(Signed)) ||
                     operandTypes[0].CILType.Equals(typeof(SFix)))
            {
                floatWidth = operandTypes[0].GetFixFormat().TotalWidth;
            }
            else
            {
                yield break;
            }
            if (floatWidth != fsas.FloatWidth)
            {
                yield break;
            }

            var fmt = resultTypes[0].GetFixFormat();

            if (fmt == null || !fmt.IsSigned || fmt.IntWidth < 2)
            {
                yield break;
            }

            if (!fmt.Equals(fsas.OutFormat))
            {
                yield break;
            }

            yield return(new Mapping(fsas));
        }
Exemple #16
0
        /// <summary>
        /// The default branch handler is applied to any branching instruction when there is no more specific handler registered.
        /// </summary>
        /// <param name="i">instruction to process</param>
        virtual protected void ProcessBranch(XIL3Instr i)
        {
            BranchLabel label    = (BranchLabel)i.StaticOperand;
            BranchLabel newLabel = Retarget(label);
            XILInstr    xi       = new XILInstr(i.Name, newLabel);

            int[] rslots = RemapResultSlots(i.ResultSlots);
            int[] oslots = RemapOperandSlots(i.OperandSlots);
            var   preds  = RemapPreds(i.Preds);

            Emit(xi.Create3AC(preds, oslots, rslots));
        }
Exemple #17
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            if (instr.Name != InstructionCodes.Select)
            {
                return(null);
            }

            int  width = TypeLowering.Instance.GetWireWidth(operandTypes[1]);
            MUX2 mux2  = new MUX2(width);

            return(new MUX2XILMapping(mux2.TASite));
        }
Exemple #18
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var     fu      = taSite.Host;
            Shifter shifter = fu as Shifter;

            if (shifter == null)
            {
                yield break;
            }

            if (instr.Name != InstructionCodes.LShift &&
                instr.Name != InstructionCodes.RShift)
            {
                yield break;
            }

            int fmtData   = GetFixSize(operandTypes[0]);
            int fmtShift  = GetFixSize(operandTypes[1]);
            int fmtResult = GetFixSize(resultTypes[0]);

            if (fmtData < 0 || fmtShift < 0 || fmtResult < 0)
            {
                yield break;
            }

            if (fmtData != fmtResult)
            {
                yield break;
            }

            if (shifter.DataWidth != fmtData ||
                shifter.ShiftWidth != fmtShift)
            {
                yield break;
            }

            switch (instr.Name)
            {
            case InstructionCodes.LShift:
                yield return(new LShiftXILMapping(shifter));

                break;

            case InstructionCodes.RShift:
                yield return(new RShiftXILMapping(shifter));

                break;

            default:
                throw new NotImplementedException();
            }
        }
        public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap)
        {
            var fu   = taSite.Host;
            var asub = fu as XilinxAdderSubtracter;

            if (asub == null)
            {
                return(null);
            }

            bool iisAdd = instr.Name == InstructionCodes.Add;
            bool iisSub = instr.Name == InstructionCodes.Sub;

            if ((asub.AddMode == XilinxAdderSubtracter.EAddMode.Add && !iisAdd) ||
                (asub.AddMode == XilinxAdderSubtracter.EAddMode.Subtract && !iisSub) ||
                (!iisAdd && !iisSub))
            {
                return(null);
            }

            FixFormat fmta, fmtb, fmtr;

            fmta = GetFixFormat(operandTypes[0]);
            fmtb = GetFixFormat(operandTypes[1]);
            fmtr = GetFixFormat(resultTypes[0]);
            if (fmta == null || fmtb == null || fmtr == null)
            {
                return(null);
            }

            bool expectSigned = fmta.IsSigned || fmtb.IsSigned;

            if (expectSigned != fmtr.IsSigned)
            {
                return(null);
            }

            if (fmta.FracWidth != fmtb.FracWidth ||
                fmtr.FracWidth != fmta.FracWidth)
            {
                return(null);
            }

            if (fmta.TotalWidth != asub.Awidth ||
                fmtb.TotalWidth != asub.Bwidth ||
                fmtr.TotalWidth != asub.OutWidth)
            {
                return(null);
            }

            return(new XILMapping(asub, iisAdd, swap));
        }
Exemple #20
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            switch (instr.Name)
            {
            case InstructionCodes.Goto:
            case InstructionCodes.BranchIfTrue:
            case InstructionCodes.BranchIfFalse:
                return(TryMap(new InlineBCUTransactionSite(this, host), instr, operandTypes, resultTypes).SingleOrDefault());

            default:
                return(null);
            }
        }
Exemple #21
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            switch (instr.Name)
            {
            case InstructionCodes.Goto:
            case InstructionCodes.BranchIfTrue:
            case InstructionCodes.BranchIfFalse:
                return(TryMap(_host.TASite, instr, operandTypes, resultTypes).Single());

            default:
                return(null);
            }
        }
Exemple #22
0
 public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
 {
     List<IXILMapper> mappers = _mlookup.Get(instr.Name);
     foreach (IXILMapper mapper in mappers)
     {
         IXILMapping mapping = mapper.TryAllocate(host, instr, operandTypes, resultTypes, proj);
         if (mapping != null)
         {
             return mapping;
         }
     }
     return null;
 }
Exemple #23
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            StdLogicVector constSLV;

            if (!TryGetConstSLV(instr, resultTypes[0], out constSLV))
            {
                return(null);
            }

            var clts = new ConstLoadingTransactionSite(host, constSLV, CreateSignalsForConstants);

            return(new ConstLoadingXILMapping(clts));
        }
Exemple #24
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            //if (fu != _host)
            //    yield break;

            var taNop = taSite as NopTASite;

            if (taNop == null)
            {
                yield break;
            }

            switch (instr.Name)
            {
            case InstructionCodes.Nop:
            case InstructionCodes.Barrier:
                if (instr.Operand is int)
                {
                    yield return(new NopXILMapping(taNop, (int)instr.Operand));
                }
                else
                {
                    yield return(new NopXILMapping(taNop, 0));
                }
                break;

            case InstructionCodes.Convert:
                if (TypeLowering.Instance.HasWireType(operandTypes[0]) &&
                    TypeLowering.Instance.HasWireType(resultTypes[0]) &&
                    !operandTypes[0].CILType.Equals(resultTypes[0].CILType))
                {
                    TypeDescriptor owt = TypeLowering.Instance.GetWireType(operandTypes[0]);
                    TypeDescriptor rwt = TypeLowering.Instance.GetWireType(resultTypes[0]);
                    if (!owt.Equals(rwt))
                    {
                        yield break;
                    }

                    yield return(new IdXILMapping(taNop));
                }
                else
                {
                    yield break;
                }
                break;

            default:
                yield break;
            }
        }
Exemple #25
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            if (!instr.Name.Equals(InstructionCodes.WrPort))
            {
                return(null);
            }

            var tgPort = (ISignalOrPortDescriptor)instr.Operand;

            InlinePortWriteSite taSite;

            taSite = new InlinePortWriteSite(host, tgPort);
            return(new InlinePortWriterXILMapping(taSite));
        }
Exemple #26
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            StdLogicVector constSLV;

            if (!TryGetConstSLV(instr, resultTypes[0], out constSLV))
            {
                yield break;
            }

            var fu = taSite.Host;
            ConstLoadingTransactionSite clts = new ConstLoadingTransactionSite(fu, constSLV, CreateSignalsForConstants);

            yield return(new ConstLoadingXILMapping(clts));
        }
        public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap)
        {
            var fu = taSite.Host;
            XilinxMultiplier mul = fu as XilinxMultiplier;

            if (mul == null)
            {
                return(null);
            }

            if (instr.Name != InstructionCodes.Mul)
            {
                return(null);
            }

            if (mul.MultType != XilinxMultiplier.EMultiplierType.ParallelMultiplier)
            {
                return(null);
            }

            FixFormat fmta, fmtb, fmtr;

            fmta = GetFixFormat(operandTypes[0]);
            fmtb = GetFixFormat(operandTypes[1]);
            fmtr = GetFixFormat(resultTypes[0]);
            if (fmta == null || fmtb == null || fmtr == null)
            {
                return(null);
            }

            bool expectSigned = fmta.IsSigned || fmtb.IsSigned;

            if (expectSigned != fmtr.IsSigned)
            {
                return(null);
            }

            int expectedHigh = fmtr.IntWidth + fmta.FracWidth + fmtb.FracWidth - 1;
            int expectedLow  = fmta.FracWidth + fmtb.FracWidth - fmtr.FracWidth;

            if (fmta.TotalWidth != mul.PortAWidth ||
                fmtb.TotalWidth != mul.PortBWidth ||
                expectedHigh != mul.OutputWidthHigh ||
                expectedLow != mul.OutputWidthLow)
            {
                return(null);
            }

            return(new XILMapping(mul, swap));
        }
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false);
            var alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);

            if (alt0 != null)
            {
                yield return(alt0);
            }
            if (alt1 != null)
            {
                yield return(alt1);
            }
        }
Exemple #29
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            if (instr.Name != InstructionCodes.Concat)
            {
                return(null);
            }

            int[] inWidths = operandTypes.Select(t => Marshal.SerializeForHW(t.GetSampleInstance()).Size).ToArray();
            var   key      = new KeyClass(inWidths);
            InlineConcatMapperTransactionSite taSite =
                new InlineConcatMapperTransactionSite(this, host, inWidths);

            return(new ConcatMapping(taSite));
        }
Exemple #30
0
        protected override void ProcessDefault(XILSInstr i)
        {
            XILInstr cmd = i.Command;

            if (cmd.Name.Equals(InstructionCodes.LdConst))
            {
                object value  = cmd.Operand;
                object lvalue = TypeLowering.Instance.ConvertToHardwareType(value);
                cmd = DefaultInstructionSet.Instance.LdConst(lvalue);
            }
            base.ProcessDefault(
                cmd.CreateStk(
                    i.Preds,
                    ReduceTypes(i.OperandTypes),
                    ReduceTypes(i.ResultTypes)));
        }
Exemple #31
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu  = taSite.Host;
            var far = instr.Operand as FixedArrayRef;

            if (far == null)
            {
                yield break;
            }

            var taMM = taSite as MemoryMapperTransactionSite;

            if (taMM == null)
            {
                yield break;
            }
            if (taMM.Array.ArrayObj != far.ArrayObj)
            {
                yield break;
            }

            switch (instr.Name)
            {
            case InstructionCodes.LdelemFixA:
                yield return(new LdelemFixAMapping(taMM));

                break;

            case InstructionCodes.LdelemFixAFixI:
                yield return(new LdelemFixAFixIMapping(taMM, far.Indices));

                break;

            case InstructionCodes.StelemFixA:
                yield return(new StelemFixAMapping(taMM));

                break;

            case InstructionCodes.StelemFixAFixI:
                yield return(new StelemFixAFixIMapping(taMM, far.Indices));

                break;

            default:
                yield break;
            }
        }
Exemple #32
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            IFixedAbsTransactionSite fats = taSite as IFixedAbsTransactionSite;

            if (fats == null)
            {
                yield break;
            }

            if (instr.Name != InstructionCodes.Abs)
            {
                yield break;
            }

            var operandFormat = operandTypes[0].GetFixFormat();

            if (operandFormat == null)
            {
                yield break;
            }

            var resultFormat = resultTypes[0].GetFixFormat();

            if (resultFormat == null)
            {
                yield break;
            }

            if (operandFormat.FracWidth != resultFormat.FracWidth)
            {
                yield break;
            }

            if (operandFormat.TotalWidth != fats.Host.InputWidth)
            {
                yield break;
            }

            if (resultFormat.TotalWidth != fats.Host.OutputWidth)
            {
                yield break;
            }

            yield return(new AbsMapping(fats.Host));
        }
Exemple #33
0
        private bool GetSliceParams(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes,
            out bool isSigned, out int inputWidth, out int hiOffset, out int loOffset)
        {
            isSigned = false;
            inputWidth = 0;
            hiOffset = 0;
            loOffset = 0;

            if (instr.Name != InstructionCodes.Convert &&
                instr.Name != InstructionCodes.SliceFixI &&
                instr.Name != InstructionCodes.Rempow2)
                return false;

            bool o0fix = IsSigned(operandTypes[0]) || IsUnsigned(operandTypes[0]);
            bool r0fix = IsSigned(resultTypes[0]) || IsUnsigned(resultTypes[0]);
            bool u2s = o0fix && r0fix;
            bool typesEq = operandTypes[0].CILType.Equals(resultTypes[0].CILType);
            if (!u2s && !typesEq)
                return false;
            if (!IsSliceable(operandTypes[0]) || !IsSliceable(resultTypes[0]))
                return false;
            isSigned = IsSigned(operandTypes[0]) && IsSigned(resultTypes[0]);

            inputWidth = TypeLowering.Instance.GetWireWidth(operandTypes[0]);

            switch (instr.Name)
            {
                case InstructionCodes.Convert:
                    {
                        TypeDescriptor inWType = operandTypes[0];
                        TypeDescriptor outWType = resultTypes[0];
                        hiOffset = outWType.Constraints[0].FirstBound - inWType.Constraints[0].SecondBound;
                        loOffset = outWType.Constraints[0].SecondBound - inWType.Constraints[0].SecondBound;
                    }
                    break;

                case InstructionCodes.SliceFixI:
                    {
                        Range range = (Range)instr.Operand;
                        hiOffset = range.FirstBound;
                        loOffset = range.SecondBound;
                    }
                    break;

                case InstructionCodes.Rempow2:
                    {
                        if (!IsSigned(operandTypes[0]) ||
                            !IsSigned(resultTypes[0]))
                            return false;

                        var infmt = operandTypes[0].GetFixFormat();
                        int p2 = (int)instr.Operand;
                        if (infmt.IntWidth > p2 + 1)
                            return false;

                        goto case InstructionCodes.Convert;
                    }

                default:
                    throw new NotImplementedException();
            }

            return true;
        }
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            bool iisAdd = instr.Name == InstructionCodes.Add;
            bool iisSub = instr.Name == InstructionCodes.Sub;

            if (!iisAdd && !iisSub)
                return null;

            FixFormat fmta, fmtb, fmtr;
            fmta = GetFixFormat(operandTypes[0]);
            fmtb = GetFixFormat(operandTypes[1]);
            fmtr = GetFixFormat(resultTypes[0]);
            if (fmta == null || fmtb == null || fmtr == null)
                return null;

            bool expectSigned = fmta.IsSigned || fmtb.IsSigned;
            if (expectSigned != fmtr.IsSigned)
                return null;

            if (fmta.FracWidth != fmtb.FracWidth ||
                fmtr.FracWidth != fmta.FracWidth)
                return null;

            int expectedWidth = Math.Max(fmta.TotalWidth, fmtb.TotalWidth);
            if (fmtr.TotalWidth != expectedWidth &&
                fmtr.TotalWidth != (expectedWidth + 1))
                return null;

            var xproj = proj as XilinxProject;
            if (xproj == null)
                return null;

            var asub = new XilinxAdderSubtracter()
            {
                AddMode = iisAdd ? XilinxAdderSubtracter.EAddMode.Add : XilinxAdderSubtracter.EAddMode.Subtract,
                Atype = fmta.IsSigned ? XilinxAdderSubtracter.ESignedness.Signed : XilinxAdderSubtracter.ESignedness.Unsigned,
                Awidth = fmta.TotalWidth,
                Bconstant = false,
                Btype = fmtb.IsSigned ? XilinxAdderSubtracter.ESignedness.Signed : XilinxAdderSubtracter.ESignedness.Unsigned,
                Bwidth = fmtb.TotalWidth,
                Implementation = XilinxAdderSubtracter.EImplementation.Fabric,
                TargetDeviceFamily = xproj.DeviceFamily,
                OutWidth = fmtr.TotalWidth,
                LatencyConfiguration = XilinxAdderSubtracter.ELatencyConfiguration.Automatic
            };

            int scaledStages = (int)Math.Round(Config.PipeStageScaling * asub.Latency);
            asub.LatencyConfiguration = XilinxAdderSubtracter.ELatencyConfiguration.Manual;
            asub.Latency = scaledStages;

            return new XILMapping(asub, iisAdd, false);
        }
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            if (instr.Name != InstructionCodes.Concat)
                return null;

            if (!operandTypes[0].CILType.Equals(typeof(StdLogicVector)) ||
                !resultTypes[0].CILType.Equals(typeof(StdLogicVector)))
                return null;

            if (!operandTypes.All(t => t.Equals(operandTypes[0])))
                return null;

            int wordWidth = (int)operandTypes[0].TypeParams[0];
            Concatenizer cc = new Concatenizer(operandTypes.Length, wordWidth);

            return new ConcatXILMapping(cc);
        }
Exemple #36
0
 private bool CheckFixCompliance(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
 {
     var oldMode = DesignContext.Instance.FixPoint.ArithSizingMode;
     DesignContext.Instance.FixPoint.ArithSizingMode = EArithSizingMode.VHDLCompliant;
     bool result = CheckFixComplianceInternal(instr, operandTypes, resultTypes);
     DesignContext.Instance.FixPoint.ArithSizingMode = oldMode;
     return result;
 }
 /// <summary>
 /// Constructs a <c>FunctionCall</c> representation of executing a XIL instruction.
 /// </summary>
 /// <param name="xi">XIL instruction to execute</param>
 /// <param name="resultType">result type descriptor</param>
 /// <param name="args">expressions representing the instruction arguments</param>
 public static FunctionCall XILOpCode(XILInstr xi, TypeDescriptor resultType, params Expression[] args)
 {
     return new FunctionCall()
     {
         Callee = MakeFun(
             new IntrinsicFunction(IntrinsicFunction.EAction.XILOpCode, xi),
             resultType),
         Arguments = args,
         ResultType = resultType
     };
 }
        public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            XilinxDivider divider = fu as XilinxDivider;
            if (divider == null)
                return null;

            if (instr.Name != InstructionCodes.Div &&
                instr.Name != InstructionCodes.DivQF)
                return null;

            FixFormat fmtDividend = GetFixFormat(operandTypes[0]);
            FixFormat fmtDivisor = GetFixFormat(operandTypes[1]);
            FixFormat fmtQuotient = GetFixFormat(resultTypes[0]);
            FixFormat fmtFractional = null;
            if (instr.Name == InstructionCodes.DivQF)
                fmtFractional = GetFixFormat(resultTypes[1]);

            if (fmtDividend.IsSigned != fmtDivisor.IsSigned ||
                fmtDividend.IsSigned != fmtQuotient.IsSigned)
                return null;

            if (fmtDividend.TotalWidth != fmtQuotient.TotalWidth)
                return null;

            int qFracWidth = fmtDividend.FracWidth - fmtDivisor.FracWidth;
            if (qFracWidth != fmtQuotient.FracWidth)
                return null;

            int fracWidth = 0;
            if (fmtFractional != null)
                fracWidth = fmtFractional.TotalWidth;

            if (divider.DividendAndQuotientWidth != fmtDividend.TotalWidth)
                return null;

            if (divider.DivisorWidth != fmtDivisor.TotalWidth)
                return null;

            if ((divider.OperandSign == XilinxDivider.ESignedness.Signed) !=
                fmtDividend.IsSigned)
                return null;

            if (divider.FractionWidth != fracWidth)
                return null;

            return new DividerXILMapping(divider);
        }
 public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
 {
     var mapping = TryMapOne(taSite, instr, operandTypes, resultTypes);
     if (mapping != null)
         yield return mapping;
 }
Exemple #40
0
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            //if (fu != _host)
            //    yield break;

            var taNop = taSite as NopTASite;
            if (taNop == null)
                yield break;

            switch (instr.Name)
            {
                case InstructionCodes.Nop:
                case InstructionCodes.Barrier:
                    if (instr.Operand is int)
                        yield return new NopXILMapping(taNop, (int)instr.Operand);
                    else
                        yield return new NopXILMapping(taNop, 0);
                    break;

                case InstructionCodes.Convert:
                    if (TypeLowering.Instance.HasWireType(operandTypes[0]) &&
                        TypeLowering.Instance.HasWireType(resultTypes[0]) &&
                        !operandTypes[0].CILType.Equals(resultTypes[0].CILType))
                    {
                        TypeDescriptor owt = TypeLowering.Instance.GetWireType(operandTypes[0]);
                        TypeDescriptor rwt = TypeLowering.Instance.GetWireType(resultTypes[0]);
                        if (!owt.Equals(rwt))
                            yield break;

                        yield return new IdXILMapping(taNop);
                    }
                    else
                    {
                        yield break;
                    }
                    break;

                default:
                    yield break;
            }
        }
Exemple #41
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            if (!CheckFixCompliance(instr, operandTypes, resultTypes))
                return null;

            bool isArith = false;
            int osize0, osize1 = 0;
            int rsize;
            ALU.EArithMode amode;
            ALU.EFunction op;
            switch (instr.Name)
            {
                case InstructionCodes.Add:
                case InstructionCodes.Sub:
                case InstructionCodes.Mul:
                    isArith = true;
                    goto case InstructionCodes.IsLt;

                case InstructionCodes.IsLt:
                case InstructionCodes.IsLte:
                case InstructionCodes.IsEq:
                case InstructionCodes.IsNEq:
                case InstructionCodes.IsGte:
                case InstructionCodes.IsGt:
                    {
                        if (operandTypes.All(t => t.CILType.Equals(typeof(Signed))) &&
                            (!isArith || resultTypes[0].CILType.Equals(typeof(Signed))) &&
                            (isArith || resultTypes[0].CILType.Equals(typeof(bool)) ||
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector))))
                            amode = ALU.EArithMode.Signed;
                        else if (operandTypes.All(t => t.CILType.Equals(typeof(SFix))) &&
                            (!isArith || resultTypes[0].CILType.Equals(typeof(SFix))) &&
                            (isArith || resultTypes[0].CILType.Equals(typeof(bool)) ||
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector))))
                            amode = ALU.EArithMode.Signed;
                        else if (operandTypes.All(t => t.CILType.Equals(typeof(Unsigned))) &&
                            (!isArith || resultTypes[0].CILType.Equals(typeof(Unsigned))) &&
                            (isArith || resultTypes[0].CILType.Equals(typeof(bool)) ||
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector))))
                            amode = ALU.EArithMode.Unsigned;
                        else if (operandTypes.All(t => t.CILType.Equals(typeof(UFix))) &&
                            (!isArith || resultTypes[0].CILType.Equals(typeof(UFix))) &&
                            (isArith || resultTypes[0].CILType.Equals(typeof(bool)) ||
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector))))
                            amode = ALU.EArithMode.Unsigned;
                        else if (operandTypes.All(t => t.CILType.Equals(typeof(StdLogicVector))) &&
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector)))
                            amode = ALU.EArithMode.Unsigned;
                        else if (operandTypes.All(t => t.CILType.Equals(typeof(StdLogic))) &&
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector)) &&
                            (instr.Name == InstructionCodes.IsEq ||
                            instr.Name == InstructionCodes.IsNEq))
                            amode = ALU.EArithMode.Unsigned;
                        else
                            return null;
                        osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]);
                        osize1 = TypeLowering.Instance.GetWireWidth(operandTypes[1]);
                        rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]); ;

                        switch (instr.Name)
                        {
                            case InstructionCodes.Add:
                                op = ALU.EFunction.Add;
                                break;

                            case InstructionCodes.Sub:
                                op = ALU.EFunction.Sub;
                                break;

                            case InstructionCodes.Mul:
                                op = ALU.EFunction.Mul;
                                break;

                            case InstructionCodes.IsLt:
                            case InstructionCodes.IsLte:
                            case InstructionCodes.IsEq:
                            case InstructionCodes.IsNEq:
                            case InstructionCodes.IsGte:
                            case InstructionCodes.IsGt:
                                op = ALU.EFunction.Compare;
                                break;

                            default:
                                throw new InvalidOperationException();
                        }
                    }
                    break;

                case InstructionCodes.Neg:
                    {
                        if (operandTypes[0].CILType.Equals(typeof(Signed)) &&
                            resultTypes[0].CILType.Equals(typeof(Signed)))
                            amode = ALU.EArithMode.Signed;
                        else if (operandTypes[0].CILType.Equals(typeof(SFix)) &&
                            resultTypes[0].CILType.Equals(typeof(SFix)))
                            amode = ALU.EArithMode.Signed;
                        else if (operandTypes[0].CILType.Equals(typeof(Unsigned)) &&
                            resultTypes[0].CILType.Equals(typeof(Unsigned)))
                            amode = ALU.EArithMode.Unsigned;
                        else if (operandTypes[0].CILType.Equals(typeof(UFix)) &&
                            resultTypes[0].CILType.Equals(typeof(UFix)))
                            amode = ALU.EArithMode.Unsigned;
                        else
                            return null;
                        osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]);
                        rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]);

                        //alu = new ALU(ALU.EFunction.Neg, amode, 1, osize, 0, rsize);
                        op = ALU.EFunction.Neg;                        
                    }
                    break;

                case InstructionCodes.And:
                case InstructionCodes.Or:
                    {
                        if (operandTypes.Length != 2 ||
                            resultTypes.Length != 1)
                            return null;

                        if (!((operandTypes[0].CILType.Equals(typeof(StdLogicVector)) &&
                            operandTypes[1].CILType.Equals(typeof(StdLogicVector)) &&
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector))) ||

                            (operandTypes[0].CILType.Equals(typeof(Unsigned)) &&
                            operandTypes[1].CILType.Equals(typeof(Unsigned)) &&
                            resultTypes[0].CILType.Equals(typeof(Unsigned)))))
                            return null;

                        osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]);
                        osize1 = TypeLowering.Instance.GetWireWidth(operandTypes[1]);
                        rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]);
                        amode = ALU.EArithMode.Signed;

                        switch (instr.Name)
                        {
                            case InstructionCodes.And:
                                //alu = new ALU(ALU.EFunction.And, ALU.EArithMode.Signed, 0, osize0, osize1, rsize);
                                op = ALU.EFunction.And;
                                break;

                            case InstructionCodes.Or:
                                //alu = new ALU(ALU.EFunction.Or, ALU.EArithMode.Signed, 0, osize0, osize1, rsize);
                                op = ALU.EFunction.Or;
                                break;

                            default:
                                throw new NotImplementedException();
                        }
                    }
                    break;

                case InstructionCodes.Not:
                    {
                        if (operandTypes.Length != 1 ||
                            resultTypes.Length != 1)
                            return null;

                        if (!((operandTypes[0].CILType.Equals(typeof(StdLogicVector)) &&
                            resultTypes[0].CILType.Equals(typeof(StdLogicVector)))))
                            return null;

                        osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]);
                        rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]);

                        //alu = new ALU(ALU.EFunction.Not, ALU.EArithMode.Unsigned, 0, osize, 0, rsize);
                        amode = ALU.EArithMode.Unsigned;
                        op = ALU.EFunction.Not;
                    }
                    break;

                default:
                    return null;
            }

            int pdepth = CalcPipelineDepth(op, amode, osize0, osize1, rsize);
            ALU alu = new ALU(op, amode, pdepth, osize0, osize1, rsize);
            return TryMapOne(alu.Transactor, instr, operandTypes, resultTypes, false);
        }
Exemple #42
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            switch (instr.Name)
            {
                case InstructionCodes.Nop:
                case InstructionCodes.Barrier:
                    if (instr.Operand is int)
                        return new NopXILMapping(new NopTASite(host), (int)instr.Operand);
                    else
                        return new NopXILMapping(new NopTASite(host), 0);

                case InstructionCodes.Convert:
                    if (TypeLowering.Instance.HasWireType(operandTypes[0]) &&
                        TypeLowering.Instance.HasWireType(resultTypes[0]) &&
                        !operandTypes[0].CILType.Equals(resultTypes[0].CILType))
                    {
                        TypeDescriptor owt = TypeLowering.Instance.GetWireType(operandTypes[0]);
                        TypeDescriptor rwt = TypeLowering.Instance.GetWireType(resultTypes[0]);
                        if (!owt.Equals(rwt))
                            return null;

                        return new IdXILMapping(new NopTASite(host));
                    }
                    else
                    {
                        return null;
                    }

                default:
                    return null;
            }
        }
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            var v = instr.Operand as FieldRef;
            if (v == null)
                yield break;

            var taLV = taSite as InlineFieldMapperTransactionSite;
            if (taLV == null)
                yield break;

            if (!taLV.Literal.Equals(v))
                yield break;

            switch (instr.Name)
            {
                case InstructionCodes.LoadVar:
                    yield return new ReadXILMapping(taLV);
                    break;

                case InstructionCodes.StoreVar:
                    yield return new WriteXILMapping(taLV);
                    break;

                default:
                    yield break;
            }
        }
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            var v = instr.Operand as FieldRef;
            if (v == null)
                return null;

            var taSite = new InlineFieldMapperTransactionSite(this, host, v);

            switch (instr.Name)
            {
                case InstructionCodes.LoadVar:
                    return new ReadXILMapping(taSite);

                case InstructionCodes.StoreVar:
                    return new WriteXILMapping(taSite);

                default:
                    return null;
            }
        }
Exemple #45
0
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            Slicer slicer = fu as Slicer;
            if (slicer == null)
                yield break;

            bool isSigned;
            int inputWidth, hiOffset, loOffset;
            if (!GetSliceParams(instr, operandTypes, resultTypes, out isSigned, out inputWidth, out hiOffset, out loOffset))
                yield break;

            if (slicer.IsSigned != isSigned)
                yield break;

            if (slicer.InputWidth != inputWidth)
                yield break;

            if (hiOffset != slicer.HiOffset || loOffset != slicer.LoOffset)
                yield break;

            yield return new SlicerXILMapping(slicer);
        }
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            if (instr.Name != InstructionCodes.Div &&
                instr.Name != InstructionCodes.DivQF)
                return null;

            FixFormat fmtDividend = GetFixFormat(operandTypes[0]);
            FixFormat fmtDivisor = GetFixFormat(operandTypes[1]);
            FixFormat fmtQuotient = GetFixFormat(resultTypes[0]);

            if (fmtDividend == null ||
                fmtDivisor == null ||
                fmtQuotient == null)
                return null;

            FixFormat fmtFractional = null;
            if (instr.Name == InstructionCodes.DivQF)
                fmtFractional = GetFixFormat(resultTypes[1]);

            if (fmtDividend.IsSigned != fmtDivisor.IsSigned ||
                fmtDividend.IsSigned != fmtQuotient.IsSigned)
                return null;

            if (fmtDividend.TotalWidth != fmtQuotient.TotalWidth)
                return null;

            int qFracWidth = fmtDividend.FracWidth - fmtDivisor.FracWidth;
            if (qFracWidth != fmtQuotient.FracWidth)
                return null;

            int fracWidth = 0;
            if (fmtFractional != null)
                fracWidth = fmtFractional.TotalWidth;

            XilinxDivider divider = new XilinxDivider()
            {
                DividendAndQuotientWidth = fmtDividend.TotalWidth,
                DivisorWidth = fmtDivisor.TotalWidth,
                FractionWidth = fracWidth,
                OperandSign = fmtDividend.IsSigned ? XilinxDivider.ESignedness.Signed : XilinxDivider.ESignedness.Unsigned,
                AlgorithmType = XilinxDivider.ERadix.HighRadix,
                RemainderType = XilinxDivider.ERemainder.Fractional,
                HasCE = false,
                HasSCLR = false,
                DivideByZeroDetect = false,
                LatencyConfiguration = XilinxDivider.ELatencyConfiguration.Manual,
                ClocksPerDivision = 1
            };
            int min = divider.MinLatency;
            int max = divider.MaxLatency;
            int scaledStages = (int)Math.Round(min + Config.PipeStageScaling * (max - min));
            if (scaledStages < min)
                scaledStages = min;
            else if (scaledStages > max)
                scaledStages = max;
            divider.Latency = scaledStages;

            return new DividerXILMapping(divider);
        }
Exemple #47
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            bool isSigned;
            int inputWidth, hiOffset, loOffset;
            if (!GetSliceParams(instr, operandTypes, resultTypes, out isSigned, out inputWidth, out hiOffset, out loOffset))
                return null;

            if (inputWidth == 0 || (hiOffset - loOffset + 1) <= 0)
                return null;

            var slicer = new Slicer(inputWidth, hiOffset, loOffset, isSigned);

            return new SlicerXILMapping(slicer);
        }
Exemple #48
0
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            IXILMapping alt0 = null, alt1 = null;
            alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false);
            switch (instr.Name)
            {
                case InstructionCodes.Add:
                case InstructionCodes.Mul:
                case InstructionCodes.And:
                case InstructionCodes.Or:
                case InstructionCodes.IsEq:
                case InstructionCodes.IsNEq:
                    // These operations are commutative => "a op b", "b op a" are both feasible
                    alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);
                    break;

                case InstructionCodes.IsGt:
                    alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsLt(), 
                        new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);
                    break;

                case InstructionCodes.IsGte:
                    alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsLte(),
                        new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);
                    break;

                case InstructionCodes.IsLt:
                    alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsGt(),
                        new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);
                    break;

                case InstructionCodes.IsLte:
                    alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsGte(),
                        new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);
                    break;
            }

            if (alt0 != null)
                yield return alt0;

            if (alt1 != null)
                yield return alt1;
        }
Exemple #49
0
        private bool CheckFixComplianceInternal(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            if (!operandTypes[0].CILType.Equals(typeof(SFix)) &&
                !operandTypes[0].CILType.Equals(typeof(UFix)))
            {
                return true;
            }

            dynamic smp0 = operandTypes[0].GetSampleInstance();
            dynamic smp1 = operandTypes.Length > 1 ? operandTypes[1].GetSampleInstance() : null;
            dynamic smpr = resultTypes[0].GetSampleInstance();
            object smpe;

            try
            {
                switch (instr.Name)
                {
                    case InstructionCodes.Add:
                    case InstructionCodes.Sub:
                        smpe = smp0 + smp1;
                        break;

                    case InstructionCodes.Mul:
                        smpe = smp0 * smp1;
                        break;

                    case InstructionCodes.Neg:
                        smpe = -smp0;
                        break;

                    default:
                        return true;
                }
            }
            catch (Exception)
            {
                return false;
            }

            var fmtr = resultTypes[0].GetFixFormat();
            var fmte = TypeDescriptor.GetTypeOf(smpe).GetFixFormat();
            return fmte.FracWidth == fmtr.FracWidth;
        }
Exemple #50
0
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            MUX2 mux2 = fu as MUX2;
            if (mux2 == null)
                yield break;

            if (instr.Name != InstructionCodes.Select)
                yield break;

            int width = TypeLowering.Instance.GetWireWidth(operandTypes[1]);
            if (width != mux2.Width)
                yield break;

            yield return new MUX2XILMapping(mux2.TASite);
        }
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            XilinxProject xproj = proj as XilinxProject;
            if (xproj == null)
                return null;

            Type otype = operandTypes[0].CILType;
            if (!operandTypes.All(t => t.CILType.Equals(otype)))
                return null;
            Type rtype = resultTypes[0].CILType;
            FloatingPointCore fpu = null;
            CoreConfiguration cfg = null;

            switch (instr.Name)
            {
                case InstructionCodes.Add:
                case InstructionCodes.Sub:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.AddSubtract,
                            Precision = prec,
                            ResultPrecision = prec,
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.AddSubtract];
                        if (cfg.UseDedicatedAddSub)
                        {
                            if (instr.Name.Equals(InstructionCodes.Add))
                                fpu.AddSubSel = FloatingPointCore.EAddSub.Add;
                            else
                                fpu.AddSubSel = FloatingPointCore.EAddSub.Subtract;
                        }
                        else
                        {
                            fpu.AddSubSel = FloatingPointCore.EAddSub.Both;
                        }
                    }
                    break;

                case InstructionCodes.IsEq:
                case InstructionCodes.IsGt:
                case InstructionCodes.IsGte:
                case InstructionCodes.IsLt:
                case InstructionCodes.IsLte:
                case InstructionCodes.IsNEq:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.Compare,
                            Precision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.Compare];
                        if (cfg.UseDedicatedCmp)
                        {
                            switch (instr.Name)
                            {
                                case InstructionCodes.IsEq:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.Equal;
                                    break;
                                case InstructionCodes.IsGt:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThan;
                                    break;
                                case InstructionCodes.IsGte:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThanOrEqual;
                                    break;
                                case InstructionCodes.IsLt:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.LessThan;
                                    break;
                                case InstructionCodes.IsLte:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.LessThanOrEqual;
                                    break;
                                case InstructionCodes.IsNEq:
                                    fpu.CompareSel = FloatingPointCore.ECompareOp.NotEqual;
                                    break;
                                default:
                                    throw new NotImplementedException();
                            }
                        }
                        else
                        {
                            fpu.CompareSel = FloatingPointCore.ECompareOp.Programmable;
                        }

                        fpu.ResultPrecision = FloatingPointCore.EPrecision.Custom;
                        fpu.ResultExponentWidth = 1;
                        fpu.ResultFractionWidth = 0;
                    }
                    break;

                case InstructionCodes.Mul:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.Multiply,
                            Precision = prec,
                            ResultPrecision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.Multiply];
                    }
                    break;

                case InstructionCodes.Div:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.Divide,
                            Precision = prec,
                            ResultPrecision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.Divide];
                    }
                    break;

                case InstructionCodes.Sqrt:
                    {
                        FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single;
                        if (otype.Equals(typeof(float)))
                            prec = FloatingPointCore.EPrecision.Single;
                        else if (otype.Equals(typeof(double)))
                            prec = FloatingPointCore.EPrecision.Double;
                        else
                            return null;
                        fpu = new FloatingPointCore()
                        {
                            Function = FloatingPointCore.EFunction.SquareRoot,
                            Precision = prec,
                            ResultPrecision = prec
                        };
                        cfg = Config[prec, FloatingPointCore.EFunction.SquareRoot];
                    }
                    break;

                case InstructionCodes.Convert:
                    {
                        FloatingPointCore.EPrecision inprec = FloatingPointCore.EPrecision.Single;
                        bool infloat = false;
                        FixFormat infmt = null;
                        if (otype.Equals(typeof(float)))
                        {
                            inprec = FloatingPointCore.EPrecision.Single;
                            infloat = true;
                        }
                        else if (otype.Equals(typeof(double)))
                        {
                            inprec = FloatingPointCore.EPrecision.Double;
                            infloat = true;
                        }
                        else if (otype.Equals(typeof(SFix)) ||
                            otype.Equals(typeof(Signed)))
                        {
                            inprec = FloatingPointCore.EPrecision.Custom;
                            infloat = false;
                            infmt = SFix.GetFormat(operandTypes[0]);
                        }
                        else
                        {
                            return null;
                        }

                        FloatingPointCore.EPrecision outprec = FloatingPointCore.EPrecision.Single;
                        bool outfloat = false;
                        FixFormat outfmt = null;
                        if (rtype.Equals(typeof(float)))
                        {
                            outprec = FloatingPointCore.EPrecision.Single;
                            outfloat = true;
                        }
                        else if (rtype.Equals(typeof(double)))
                        {
                            outprec = FloatingPointCore.EPrecision.Double;
                            outfloat = true;
                        }
                        else if (rtype.Equals(typeof(SFix)) ||
                            rtype.Equals(typeof(Signed)))
                        {
                            outprec = FloatingPointCore.EPrecision.Custom;
                            outfloat = false;
                            outfmt = SFix.GetFormat(resultTypes[0]);
                        }
                        else
                        {
                            return null;
                        }

                        FloatingPointCore.EFunction func;
                        if (!infloat && !outfloat)
                            return null;
                        else if (infloat && outfloat)
                            func = FloatingPointCore.EFunction.FloatToFloat;
                        else if (infloat)
                            func = FloatingPointCore.EFunction.FloatToFixed;
                        else
                            func = FloatingPointCore.EFunction.FixedToFloat;

                        fpu = new FloatingPointCore()
                        {
                            Function = func,
                            Precision = inprec,
                            ResultPrecision = outprec
                        };
                        if (infmt != null)
                        {
                            fpu.ExponentWidth = infmt.IntWidth;
                            fpu.FractionWidth = infmt.FracWidth;
                        }
                        if (outfmt != null)
                        {
                            fpu.ResultExponentWidth = outfmt.IntWidth;
                            fpu.ResultFractionWidth = outfmt.FracWidth;
                        }
                        FloatingPointCore.EPrecision prec = infloat ? inprec : outprec;
                        cfg = Config[prec, FloatingPointCore.EFunction.Multiply];
                    }
                    break;

                default:
                    return null;
            }
            fpu.TargetDeviceFamily = xproj.DeviceFamily;
            fpu.TargetISEVersion = xproj.ISEVersion;
            if (cfg.EnableDeviceCapabilityDependentDSPUsage)
            {
                switch (fpu.Function)
                {
                    case FloatingPointCore.EFunction.Multiply:
                        switch (xproj.DeviceFamily)
                        {
                            case EDeviceFamily.Spartan3:
                            case EDeviceFamily.Spartan3A_3AN:
                            case EDeviceFamily.Spartan3E:
                            case EDeviceFamily.Automotive_Spartan3:
                            case EDeviceFamily.Automotive_Spartan3A:
                            case EDeviceFamily.Automotive_Spartan3E:
                                if (cfg.DSPUsageRatio < 0.5f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage;
                                else
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                break;

                            default:
                                if (cfg.DSPUsageRatio < 0.25f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                else if (cfg.DSPUsageRatio < 0.50f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MediumUsage;
                                else if (cfg.DSPUsageRatio < 0.75f)
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MaxUsage;
                                else
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage;
                                break;
                        }
                        break;

                    case FloatingPointCore.EFunction.AddSubtract:
                        if (fpu.Precision == FloatingPointCore.EPrecision.Custom)
                        {
                            fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                        }
                        else
                        {
                            switch (xproj.DeviceFamily)
                            {
                                case EDeviceFamily.Virtex4:
                                case EDeviceFamily.Virtex5:
                                case EDeviceFamily.Virtex6:
                                case EDeviceFamily.Virtex6_LowPower:
                                    if (cfg.DSPUsageRatio < 0.5f)
                                        fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                    else
                                        fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage;
                                    break;

                                default:
                                    fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                                    break;
                            }
                        }
                        break;

                    default:
                        fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage;
                        break;
                }
            }
            else
            {
                fpu.DSP48EUsage = cfg.DSP48EUsage;
            }
            fpu.HasCE = cfg.HasCE;
            fpu.HasDivideByZero = cfg.HasDivideByZero;
            fpu.HasInvalidOp = cfg.HasInvalidOp;
            fpu.HasOperationND = cfg.HasOperationND;
            fpu.HasOperationRFD = cfg.HasOperationRFD;
            fpu.HasOverflow = cfg.HasOverflow;
            fpu.HasRdy = cfg.HasRdy;
            fpu.HasSCLR = cfg.HasSCLR;
            if (cfg.UseMaximumLatency)
            {
                fpu.UseMaximumLatency = true;
            }
            else if (cfg.SpecifyLatencyRatio)
            {
                fpu.UseMaximumLatency = false;
                fpu.Latency = (int)(cfg.LatencyRatio * fpu.MaximumLatency);
            }
            else
            {
                fpu.Latency = cfg.Latency;
            }
            IXILMapping result = TryMapOne(fpu.TASite, instr, operandTypes, resultTypes, false);
            Debug.Assert(result != null);
            return result;
        }
Exemple #52
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj)
        {
            if (instr.Name != InstructionCodes.Select)
                return null;

            int width = TypeLowering.Instance.GetWireWidth(operandTypes[1]);
            MUX2 mux2 = new MUX2(width);
            return new MUX2XILMapping(mux2.TASite);
        }
        public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap)
        {
            var fu = taSite.Host;
            FloatingPointCore fpu = (FloatingPointCore)fu;
            if (fpu == null)
                return null;

            if (operandTypes.Length != fpu.Arity)
                return null;

            if (fpu.Function == FloatingPointCore.EFunction.AddSubtract ||
                fpu.Function == FloatingPointCore.EFunction.Compare ||
                fpu.Function == FloatingPointCore.EFunction.Divide ||
                fpu.Function == FloatingPointCore.EFunction.FloatToFixed ||
                fpu.Function == FloatingPointCore.EFunction.FloatToFloat ||
                fpu.Function == FloatingPointCore.EFunction.Multiply ||
                fpu.Function == FloatingPointCore.EFunction.SquareRoot)
            {
                Type itype = null;
                switch (fpu.Precision)
                {
                    case FloatingPointCore.EPrecision.Single:
                        itype = typeof(float);
                        break;

                    case FloatingPointCore.EPrecision.Double:
                        itype = typeof(double);
                        break;

                    default:
                        return null;
                }

                foreach (TypeDescriptor otype in operandTypes)
                    if (!otype.CILType.Equals(itype))
                        return null;
            }

            Func<ISignalSource<StdLogicVector>[], ISignalSink<StdLogicVector>[], IEnumerable<TAVerb>> realize = null;
            ISignalSource<StdLogicVector> defOp = SignalSource.Create(StdLogicVector._0s(fpu.OperandWidth));
            ISignalSink<StdLogicVector> defR = SignalSink.Nil<StdLogicVector>();

            switch (fpu.Function)
            {
                case FloatingPointCore.EFunction.AddSubtract:
                    if (instr.Name.Equals(InstructionCodes.Add) &&
                        (fpu.AddSubSel == FloatingPointCore.EAddSub.Add ||
                        fpu.AddSubSel == FloatingPointCore.EAddSub.Both))
                    {
                        realize = (os, rs) => fpu.TASite.Add(os[0], os[1], rs[0]);
                    }
                    else if (instr.Name.Equals(InstructionCodes.Sub) &&
                        (fpu.AddSubSel == FloatingPointCore.EAddSub.Subtract ||
                        fpu.AddSubSel == FloatingPointCore.EAddSub.Both))
                    {
                        realize = (os, rs) => fpu.TASite.Sub(os[0], os[1], rs[0]);
                    }
                    else
                        return null;
                    break;

                case FloatingPointCore.EFunction.Compare:
                    if (instr.Name.Equals(InstructionCodes.IsLt))
                    {
                        realize = (os, rs) => fpu.TASite.IsLt(os[0], os[1], rs[0]);
                    }
                    else if (instr.Name.Equals(InstructionCodes.IsLte))
                    {
                        realize = (os, rs) => fpu.TASite.IsLte(os[0], os[1], rs[0]);
                    }
                    else if (instr.Name.Equals(InstructionCodes.IsEq))
                    {
                        realize = (os, rs) => fpu.TASite.IsEq(os[0], os[1], rs[0]);
                    }
                    else if (instr.Name.Equals(InstructionCodes.IsNEq))
                    {
                        realize = (os, rs) => fpu.TASite.IsNEq(os[0], os[1], rs[0]);
                    }
                    else if (instr.Name.Equals(InstructionCodes.IsGte))
                    {
                        realize = (os, rs) => fpu.TASite.IsGte(os[0], os[1], rs[0]);
                    }
                    else if (instr.Name.Equals(InstructionCodes.IsGt))
                    {
                        realize = (os, rs) => fpu.TASite.IsGt(os[0], os[1], rs[0]);
                    }
                    else
                    {
                        return null;
                    }
                    break;

                case FloatingPointCore.EFunction.Divide:
                    if (instr.Name.Equals(InstructionCodes.Div))
                    {
                        realize = (os, rs) => fpu.TASite.Div(os[0], os[1], rs[0]);
                    }
                    else
                        return null;
                    break;

                case FloatingPointCore.EFunction.FixedToFloat:
                    if (instr.Name.Equals(InstructionCodes.Convert))
                    {
                        if (!operandTypes[0].CILType.Equals(typeof(SFix)) &&
                            !operandTypes[0].CILType.Equals(typeof(Signed)))
                            return null;

                        FixFormat ffmt = SFix.GetFormat(operandTypes[0]);
                        if (ffmt.IntWidth != fpu.ExponentWidth ||
                            ffmt.FracWidth != fpu.FractionWidth)
                            return null;

                        switch (fpu.ResultPrecision)
                        {
                            case FloatingPointCore.EPrecision.Single:
                                if (!resultTypes[0].CILType.Equals(typeof(float)))
                                    return null;
                                break;

                            case FloatingPointCore.EPrecision.Double:
                                if (!resultTypes[0].CILType.Equals(typeof(double)))
                                    return null;
                                break;

                            default:
                                return null;
                        }

                        realize = (os, rs) => fpu.TASite.Fix2Float(os[0], rs[0]);
                    }
                    else
                        return null;
                    break;

                case FloatingPointCore.EFunction.FloatToFixed:
                    if (instr.Name.Equals(InstructionCodes.Convert))
                    {
                        if (!resultTypes[0].CILType.Equals(typeof(SFix)) &&
                            !resultTypes[0].CILType.Equals(typeof(Signed)))
                            return null;

                        FixFormat ffmt = SFix.GetFormat(resultTypes[0]);
                        if (ffmt.IntWidth != fpu.ResultExponentWidth ||
                            ffmt.FracWidth != fpu.ResultFractionWidth)
                            return null;

                        switch (fpu.Precision)
                        {
                            case FloatingPointCore.EPrecision.Single:
                                if (!operandTypes[0].CILType.Equals(typeof(float)))
                                    return null;
                                break;

                            case FloatingPointCore.EPrecision.Double:
                                if (!operandTypes[0].CILType.Equals(typeof(double)))
                                    return null;
                                break;

                            default:
                                return null;
                        }

                        realize = (os, rs) => fpu.TASite.Float2Fix(os[0], rs[0]);
                    }
                    else
                        return null;
                    break;

                case FloatingPointCore.EFunction.FloatToFloat:
                    if (instr.Name.Equals(InstructionCodes.Convert))
                    {
                        switch (fpu.Precision)
                        {
                            case FloatingPointCore.EPrecision.Single:
                                if (!operandTypes[0].CILType.Equals(typeof(float)))
                                    return null;
                                break;

                            case FloatingPointCore.EPrecision.Double:
                                if (!operandTypes[0].CILType.Equals(typeof(double)))
                                    return null;
                                break;

                            default:
                                return null;
                        }

                        switch (fpu.ResultPrecision)
                        {
                            case FloatingPointCore.EPrecision.Single:
                                if (!resultTypes[0].CILType.Equals(typeof(float)))
                                    return null;
                                break;

                            case FloatingPointCore.EPrecision.Double:
                                if (!resultTypes[0].CILType.Equals(typeof(double)))
                                    return null;
                                break;

                            default:
                                return null;
                        }

                        realize = (os, rs) => fpu.TASite.Float2Float(os[0], rs[0]);
                    }
                    else
                        return null;
                    break;

                case FloatingPointCore.EFunction.Multiply:
                    if (instr.Name.Equals(InstructionCodes.Mul))
                    {
                        realize = (os, rs) => fpu.TASite.Mul(os[0], os[1], rs[0]);
                    }
                    else
                        return null;
                    break;

                case FloatingPointCore.EFunction.SquareRoot:
                    if (instr.Name.Equals(InstructionCodes.Sqrt))
                    {
                        realize = (os, rs) => fpu.TASite.Sqrt(os[0], rs[0]);
                    }
                    else
                        return null;
                    break;

                default:
                    throw new NotImplementedException();
            }

            return new XILMapping(fpu.TASite, realize, swap);
        }
 /// <summary>
 /// The default branch handler is applied to any branching instruction when there is no more specific handler registered.
 /// </summary>
 /// <param name="i">instruction to process</param>
 virtual protected void ProcessBranch(XILSInstr i)
 {
     BranchLabel label = (BranchLabel)i.StaticOperand;
     BranchLabel newLabel = Retarget(label);
     XILInstr xi = new XILInstr(i.Name, newLabel);
     var preds = RemapPreds(i.Preds);
     Emit(xi.CreateStk(preds, i.OperandTypes, i.ResultTypes));
 }
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var fu = taSite.Host;
            Concatenizer cc = fu as Concatenizer;
            if (cc == null)
                yield break;

            if (instr.Name != InstructionCodes.Concat)
                yield break;

            if (!operandTypes[0].CILType.Equals(typeof(StdLogicVector)) ||
                !resultTypes[0].CILType.Equals(typeof(StdLogicVector)))
                yield break;

            if (!operandTypes.All(t => t.Equals(operandTypes[0])))
                yield break;

            int wordWidth = (int)operandTypes[0].TypeParams[0];
            if (cc.WordWidth != wordWidth ||
                cc.NumWords != operandTypes.Length)
                yield break;

            yield return new ConcatXILMapping(cc);
        }
Exemple #56
0
        private IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap)
        {
            var fu = taSite.Host;
            ALU alu = fu as ALU;
            if (alu == null)
                return null;
            if (resultTypes.Length != 1)
                return null;
            TypeDescriptor rtype = resultTypes[0];
            if (!rtype.IsComplete)
                return null;

            if (!CheckFixCompliance(instr, operandTypes, resultTypes))
                return null;

            int rsize = TypeLowering.Instance.GetWireWidth(rtype);
            int[] osizes = operandTypes.Select(t => TypeLowering.Instance.GetWireWidth(t)).ToArray();
            Func<ISignalSource<StdLogicVector>[], ISignalSink<StdLogicVector>[], IEnumerable<TAVerb>> realize;
            if (operandTypes.Length == 1)
            {
                realize = (os, rs) => alu.Transactor.Do(os[0], rs[0]);

                TypeDescriptor otype = operandTypes[0];
                long osize = osizes[0];
                switch (instr.Name)
                {
                    case InstructionCodes.Neg:
                        if (alu.FuncSel != ALU.EFunction.Neg)
                            return null;
                        if ((!otype.CILType.Equals(typeof(Signed)) ||
                            !rtype.CILType.Equals(typeof(Signed))) &&
                            (!otype.CILType.Equals(typeof(SFix)) ||
                            !rtype.CILType.Equals(typeof(SFix))))
                            return null;
                        if (alu.AWidth != osize ||
                            alu.RWidth != rsize)
                            return null;
                        break;

                    case InstructionCodes.Not:
                        if (alu.FuncSel != ALU.EFunction.Not)
                            return null;
                        if (!otype.CILType.Equals(typeof(StdLogicVector)) ||
                            !rtype.CILType.Equals(typeof(StdLogicVector)))
                            return null;
                        if (alu.AWidth != osize ||
                            alu.RWidth != osize)
                            return null;
                        break;

                    default:
                        return null;
                }
            }
            else
            {
                realize = (os, rs) => alu.Transactor.Do(os[0], os[1], rs[0]);

                TypeDescriptor otype0 = operandTypes[0];
                TypeDescriptor otype1 = operandTypes[1];
                long osize0 = osizes[0];
                long osize1 = osizes[1];
                if (alu.AWidth != osize0 ||
                    alu.BWidth != osize1 ||
                    (alu.FuncSel != ALU.EFunction.Compare && alu.RWidth != rsize))
                    return null;
                bool isArith = false;
                switch (instr.Name)
                {
                    case InstructionCodes.Add:
                    case InstructionCodes.Sub:
                    case InstructionCodes.Mul:
                        isArith = true;
                        goto case InstructionCodes.IsLt;

                    case InstructionCodes.IsLt:
                    case InstructionCodes.IsLte:
                    case InstructionCodes.IsEq:
                    case InstructionCodes.IsNEq:
                    case InstructionCodes.IsGte:
                    case InstructionCodes.IsGt:
                        switch (alu.ArithMode)
                        {
                            case ALU.EArithMode.Signed:
                                if ((!otype0.CILType.Equals(typeof(Signed)) ||
                                    !otype1.CILType.Equals(typeof(Signed)) ||
                                    (isArith && !rtype.CILType.Equals(typeof(Signed))) ||
                                    (!isArith && !rtype.CILType.Equals(typeof(bool)) &&
                                    !rtype.CILType.Equals(typeof(StdLogicVector)))) &&

                                    (!otype0.CILType.Equals(typeof(SFix)) ||
                                    !otype1.CILType.Equals(typeof(SFix)) ||
                                    (isArith && !rtype.CILType.Equals(typeof(SFix))) ||
                                    (!isArith && !rtype.CILType.Equals(typeof(bool)) &&
                                    !rtype.CILType.Equals(typeof(StdLogicVector)))))
                                    return null;
                                break;

                            case ALU.EArithMode.Unsigned:
                                if ((!(otype0.CILType.Equals(typeof(Unsigned)) || otype0.CILType.Equals(typeof(StdLogicVector))) ||
                                    !(otype1.CILType.Equals(typeof(Unsigned)) || otype1.CILType.Equals(typeof(StdLogicVector))) ||
                                    (isArith && !(rtype.CILType.Equals(typeof(Unsigned)) || rtype.CILType.Equals(typeof(StdLogicVector)))) ||
                                    (!isArith && !rtype.CILType.Equals(typeof(bool)) &&
                                    !rtype.CILType.Equals(typeof(StdLogicVector)))) &&

                                    (!(otype0.CILType.Equals(typeof(UFix)) || otype0.CILType.Equals(typeof(StdLogicVector)) || otype0.CILType.Equals(typeof(StdLogic))) ||
                                    !(otype1.CILType.Equals(typeof(UFix)) || otype1.CILType.Equals(typeof(StdLogicVector)) || otype1.CILType.Equals(typeof(StdLogic))) ||
                                    (isArith && !rtype.CILType.Equals(typeof(UFix))) ||
                                    (!isArith && !rtype.CILType.Equals(typeof(bool)) &&
                                    !rtype.CILType.Equals(typeof(StdLogicVector)))))
                                    return null;
                                break;

                            default:
                                throw new NotImplementedException();
                        }
                        switch (alu.FuncSel)
                        {
                            case ALU.EFunction.Add:
                                if (!instr.Name.Equals(InstructionCodes.Add))
                                    return null;
                                break;

                            case ALU.EFunction.Sub:
                                if (!instr.Name.Equals(InstructionCodes.Sub))
                                    return null;
                                break;

                            case ALU.EFunction.Mul:
                                if (!instr.Name.Equals(InstructionCodes.Mul))
                                    return null;
                                break;

                            case ALU.EFunction.Compare:
                                switch (instr.Name)
                                {
                                    case InstructionCodes.IsLt:
                                        realize = (os, rs) => alu.Transactor.IsLt(os[0], os[1], rs[0]);
                                        break;
                                    case InstructionCodes.IsLte:
                                        realize = (os, rs) => alu.Transactor.IsLte(os[0], os[1], rs[0]);
                                        break;
                                    case InstructionCodes.IsEq:
                                        realize = (os, rs) => alu.Transactor.IsEq(os[0], os[1], rs[0]);
                                        break;
                                    case InstructionCodes.IsNEq:
                                        realize = (os, rs) => alu.Transactor.IsNEq(os[0], os[1], rs[0]);
                                        break;
                                    case InstructionCodes.IsGte:
                                        realize = (os, rs) => alu.Transactor.IsGte(os[0], os[1], rs[0]);
                                        break;
                                    case InstructionCodes.IsGt:
                                        realize = (os, rs) => alu.Transactor.IsGt(os[0], os[1], rs[0]);
                                        break;
                                    default:
                                        return null;
                                }
                                break;
                        }
                        break;

                    case InstructionCodes.And:
                        if (alu.FuncSel != ALU.EFunction.And)
                            return null;
                        break;

                    case InstructionCodes.Or:
                        if (alu.FuncSel != ALU.EFunction.Or)
                            return null;
                        break;
                }
            }
            return new ALUXILMapping(alu.Transactor, realize, swap);
        }
        public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap)
        {
            var fu = taSite.Host;
            var asub = fu as XilinxAdderSubtracter;
            if (asub == null)
                return null;

            bool iisAdd = instr.Name == InstructionCodes.Add;
            bool iisSub = instr.Name == InstructionCodes.Sub;

            if ((asub.AddMode == XilinxAdderSubtracter.EAddMode.Add && !iisAdd) ||
                (asub.AddMode == XilinxAdderSubtracter.EAddMode.Subtract && !iisSub) ||
                (!iisAdd && !iisSub))
                return null;

            FixFormat fmta, fmtb, fmtr;
            fmta = GetFixFormat(operandTypes[0]);
            fmtb = GetFixFormat(operandTypes[1]);
            fmtr = GetFixFormat(resultTypes[0]);
            if (fmta == null || fmtb == null || fmtr == null)
                return null;

            bool expectSigned = fmta.IsSigned || fmtb.IsSigned;
            if (expectSigned != fmtr.IsSigned)
                return null;

            if (fmta.FracWidth != fmtb.FracWidth ||
                fmtr.FracWidth != fmta.FracWidth)
                return null;

            if (fmta.TotalWidth != asub.Awidth ||
                fmtb.TotalWidth != asub.Bwidth ||
                fmtr.TotalWidth != asub.OutWidth)
                return null;

            return new XILMapping(asub, iisAdd, swap);
        }
Exemple #58
0
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            IFixedAbsTransactionSite fats = taSite as IFixedAbsTransactionSite;
            if (fats == null)
                yield break;

            if (instr.Name != InstructionCodes.Abs)
                yield break;

            var operandFormat = operandTypes[0].GetFixFormat();
            if (operandFormat == null)
                yield break;

            var resultFormat = resultTypes[0].GetFixFormat();
            if (resultFormat == null)
                yield break;

            if (operandFormat.FracWidth != resultFormat.FracWidth)
                yield break;

            if (operandFormat.TotalWidth != fats.Host.InputWidth)
                yield break;

            if (resultFormat.TotalWidth != fats.Host.OutputWidth)
                yield break;

            yield return new AbsMapping(fats.Host);
        }
Exemple #59
0
        public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject)
        {
            if (instr.Name != InstructionCodes.Abs)
                return null;

            var operandFormat = operandTypes[0].GetFixFormat();
            if (operandFormat == null)
                return null;

            var resultFormat = resultTypes[0].GetFixFormat();
            if (resultFormat == null)
                return null;

            if (operandFormat.FracWidth != resultFormat.FracWidth)
                return null;

            var fu = new FixedAbs(
                operandFormat.TotalWidth, 
                resultFormat.TotalWidth,
                ComputeLatency(operandFormat.TotalWidth, resultFormat.TotalWidth));
            return new AbsMapping(fu);
        }
        public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            IXILMapping alt0, alt1 = null;
            alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false);
            switch (instr.Name)
            {
                case InstructionCodes.Add:
                    alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true);
                    break;
            }

            if (alt0 != null)
                yield return alt0;
            if (alt1 != null)
                yield return alt1;
        }