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); }
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); }
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(); } }
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(); } }