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