Exemple #1
0
        public ALUTestDesign(int awidth, int bwidth, int pipelineDepth)
        {
            _clk = new SLSignal();
            _a = new SLVSignal(awidth) { InitialValue = StdLogicVector._0s(awidth) };
            _b = new SLVSignal(bwidth) { InitialValue = StdLogicVector._0s(bwidth) };
            _ba = new SLVSignal(awidth) { InitialValue = StdLogicVector._0s(awidth) };

            _clkGen = new Clock(new Time(10.0, ETimeUnit.ns));
            Bind(() => _clkGen.Clk = _clk);

            _add = new ALU(ALU.EFunction.Add, ALU.EArithMode.Signed, pipelineDepth,
                awidth, bwidth, Math.Max(awidth, bwidth) + 1);
            Bind(() =>
            {
                _add.Clk = _clk;
                _add.A = _a;
                _add.B = _b;
                _add.R = _rAdd;
            });
            _rAdd = new SLVSignal(_add.RWidth);

            _sub = new ALU(ALU.EFunction.Sub, ALU.EArithMode.Signed, pipelineDepth,
                awidth, bwidth, Math.Max(awidth, bwidth) + 1);
            Bind(() =>
            {
                _sub.Clk = _clk;
                _sub.A = _a;
                _sub.B = _b;
                _sub.R = _rSub;
            });
            _rSub = new SLVSignal(_sub.RWidth);

            _mul = new ALU(ALU.EFunction.Mul, ALU.EArithMode.Signed, pipelineDepth,
                awidth, bwidth, awidth + bwidth);
            Bind(() =>
            {
                _mul.Clk = _clk;
                _mul.A = _a;
                _mul.B = _b;
                _mul.R = _rMul;
            });
            _rMul = new SLVSignal(_mul.RWidth);

            _neg = new ALU(ALU.EFunction.Neg, ALU.EArithMode.Signed, pipelineDepth,
                awidth, 0, awidth + 1);
            Bind(() =>
            {
                _neg.Clk = _clk;
                _neg.A = _a;
                _neg.R = _rNeg;
            });
            _rNeg = new SLVSignal(_neg.RWidth);

            _not = new ALU(ALU.EFunction.Not, ALU.EArithMode.Signed, pipelineDepth,
                awidth, 0, awidth);
            Bind(() =>
            {
                _not.Clk = _clk;
                _not.A = _a;
                _not.R = _rNot;
            });
            _rNot = new SLVSignal(_not.RWidth);

            _and = new ALU(ALU.EFunction.And, ALU.EArithMode.Signed, pipelineDepth,
                awidth, awidth, awidth);
            Bind(() =>
            {
                _and.Clk = _clk;
                _and.A = _a;
                _and.B = _ba;
                _and.R = _rAnd;
            });
            _rAnd = new SLVSignal(_and.RWidth);

            _or = new ALU(ALU.EFunction.Or, ALU.EArithMode.Signed, pipelineDepth,
                awidth, awidth, awidth);
            Bind(() =>
            {
                _or.Clk = _clk;
                _or.A = _a;
                _or.B = _ba;
                _or.R = _rOr;
            });
            _rOr = new SLVSignal(_or.RWidth);
        }
Exemple #2
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 #3
0
        private int DefaultCalcPipelineDepth(ALU.EFunction op, ALU.EArithMode mode, int osize0, int osize1, int rsize)
        {
            switch (op)
            {
                case ALU.EFunction.And:
                case ALU.EFunction.Not:
                case ALU.EFunction.Or:
                    return 0;

                case ALU.EFunction.Add:
                case ALU.EFunction.Compare:
                case ALU.EFunction.Neg:
                case ALU.EFunction.Sub:
                    return 1;

                case ALU.EFunction.Mul:
                    return 2;

                default:
                    throw new NotImplementedException();
            }
        }
Exemple #4
0
 public ALUTransactor(ALU host):
     base(host)
 {
     _host = host;
 }
            public int CalcALUPipelineDepth(ALU.EFunction op, ALU.EArithMode mode, int osize0, int osize1, int rsize)
            {
                switch (op)
                {
                    case ALU.EFunction.Add:
                    case ALU.EFunction.Compare:
                    case ALU.EFunction.Sub:
                        {
                            float max = (float)osize0 * 0.0625f;
                            int depth = (int)Math.Round(_ratio * max);
                            return depth;
                        }

                    case ALU.EFunction.And:
                    case ALU.EFunction.Not:
                    case ALU.EFunction.Or:
                        return 0;

                    case ALU.EFunction.Mul:
                        {
                            float min = 0.0f;
                            // These coefficients were found experimentally by
                            // regression of Xilinx datasheet
                            float qterm = 0.0049f * (float)osize0 * (float)osize1;
                            float linterm = 0.0857f * (float)(osize0 + osize1);
                            float max = 0.5f * qterm + 0.4f * linterm + 1.0f;
                            int depth = (int)Math.Round(min + _ratio * (max - min));
                            return depth;
                        }

                    case ALU.EFunction.Neg:
                        {
                            float max = osize0 / 16.0f;
                            int depth = (int)Math.Ceiling(_ratio * max);
                            return depth;
                        }

                    default:
                        throw new NotImplementedException();
                }
            }