private void HandleSinOrCos(XILSInstr i) { FixFormat oformat, rformat; IsFix(i.OperandTypes[0], out oformat); IsFix(i.ResultTypes[0], out rformat); var preds = RemapPreds(i.Preds); if (oformat == null) { Emit(i.Command.CreateStk(preds, 1, i.OperandTypes[0], i.ResultTypes[0])); } else { TypeDescriptor otype = i.OperandTypes[0]; if (!i.OperandTypes[0].CILType.Equals(typeof(SFix))) { var itype = SFix.MakeType(oformat.IntWidth + 1, oformat.FracWidth); Emit(DefaultInstructionSet.Instance.Convert().CreateStk(preds, i.OperandTypes, i.ResultTypes)); preds = new InstructionDependency[0]; otype = itype; } var nrtype = SFix.MakeType(2, rformat.FracWidth); Emit(i.Command.CreateStk(preds, 1, otype, nrtype)); if (!i.ResultTypes[0].Equals(nrtype)) { Emit(DefaultInstructionSet.Instance.Convert().CreateStk(1, nrtype, i.ResultTypes[0])); } } }
public static void SubstituteLU(SFix[,] LU, SFix[] b, SFix[] y, SFix[] x) { int n = LU.GetLength(0); for (int i = 0; i < n; i++) { x[i] = b[i]; } /* do forward substitution, replacing x vector. */ x[0] /= LU[0, 0]; for (int i = 1; i < n; i++) { SFix sum = SFix.FromLong(0, 1); for (int j = 0; j < i; j++) sum += LU[i, j] * x[j]; x[i] = (x[i] - sum) / LU[i, i]; } /* now get the solution vector, x[n-1] is already done */ for (int i = n - 2; i >= 0; i--) { SFix sum = SFix.FromLong(0, 1); for (int j = i + 1; j < n; j++) sum += LU[i, j] * x[j]; x[i] -= sum; } }
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)); }
public static void SubstituteLU(SFix[,] LU, SFix[] b, SFix[] y, SFix[] x) { int n = LU.GetLength(0); for (int i = 0; i < n; i++) { x[i] = b[i]; } /* do forward substitution, replacing x vector. */ x[0] /= LU[0, 0]; for (int i = 1; i < n; i++) { SFix sum = SFix.FromLong(0, 1); for (int j = 0; j < i; j++) { sum += LU[i, j] * x[j]; } x[i] = (x[i] - sum) / LU[i, i]; } /* now get the solution vector, x[n-1] is already done */ for (int i = n - 2; i >= 0; i--) { SFix sum = SFix.FromLong(0, 1); for (int j = i + 1; j < n; j++) { sum += LU[i, j] * x[j]; } x[i] -= sum; } }
private async void TestProcess() { _nxt = false; await Tick; double a = 100.0; double b = 1.0; while (true) { //ProgramFlow.DoNotUnroll(); _dividend = SFix.FromDouble(a, iw, fw); _divisor = SFix.FromDouble(b, iw, fw); _nxt = true; while (_rdy) { //ProgramFlow.DoNotUnroll(); await Tick; } _nxt = false; while (!_rdy) { //ProgramFlow.DoNotUnroll(); await Tick; } Console.WriteLine(_dividend.DoubleValue + " / " + _divisor.DoubleValue + " = " + _quotient.DoubleValue); b = b + 1.0; } }
public static string Convert_SLV_SFix(string value, TypeDescriptor ttype) { FixFormat fmt = SFix.GetFormat(ttype); return("lv_to_fixed(" + value + ", sc_fixed<" + fmt.TotalWidth + ", " + fmt.IntWidth + "> (0))"); //return "sc_fixed<" + fmt.TotalWidth + ", " + fmt.IntWidth + "> (sc_bigint<" + fmt.TotalWidth + ">(" + value + "))"; }
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()); }
//******************************************************************************************************************** //*******************Hier wird die angegebene Dezimalzahl im Binaere umgewandelt************************************** //int intw; private StdLogicVector Getbinaer(double x) { StdLogicVector v = SFix.FromDouble(x, 2, OutputWidth - 2).SignedValue.SLVValue; //double y = SFix.FromSigned(v.SignedValue, 10).DoubleValue; return(v); }
private void ArgsProcess() { UFix x, xd, xq; _sinFlipSignIn.Next = "0"; _cosFlipSignIn.Next = "0"; if (X.Cur[XFracWidth + 1] == '1') { // x is negative x = (-SFix.FromSigned(X.Cur.SignedValue, XFracWidth - LUTWidth - 1)).UFixValue.Resize(LUTWidth + 2, XFracWidth - LUTWidth - 1); _sinFlipSignIn.Next = "1"; } else { // x is non-negative x = UFix.FromUnsigned(X.Cur[XFracWidth, 0].UnsignedValue, XFracWidth - LUTWidth - 1); } if (x.SLVValue[XFracWidth] == '1' || x.SLVValue[XFracWidth - 1] == '1') { // between Pi/2 and Pi xd = (_mirror - x).Resize(LUTWidth + 1, XFracWidth).Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1); xq = (x - _mirror2).Resize(LUTWidth + 1, XFracWidth).Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1); _cosFlipSignIn.Next = "1"; } else { xd = x.Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1); xq = (_mirror2 - x).Resize(LUTWidth + 1, XFracWidth).Resize(LUTWidth + 1, XFracWidth - LUTWidth - 1); } _x.Next = xd; _xq.Next = xq; }
private static TypeDescriptor MakeUFixSFix(TypeDescriptor t) { var fmt = UFix.GetFormat(t); var smp = SFix.FromDouble(0.0, fmt.IntWidth + 1, fmt.FracWidth); return(TypeDescriptor.GetTypeOf(smp)); }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertLong(long src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(Signed))) { return(Signed.FromLong(src, SFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(Unsigned))) { return(Unsigned.FromBigInt(new System.Numerics.BigInteger(src), UFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(SFix))) { return(SFix.FromSigned(Signed.FromLong(src, SFix.GetFormat(dstType).IntWidth), SFix.GetFormat(dstType).FracWidth)); } else if (dstType.CILType.Equals(typeof(StdLogicVector))) { return(StdLogicVector.FromLong(src, StdLogicVector.GetLength(dstType))); } else { return(ConvertLong(src, dstType.CILType)); } }
private void DiagMonSFix() { if (Clk.RisingEdge() && EnIn.Cur == '1') { Console.WriteLine("Writing variable " + MappedVariableName + ": " + SFix.FromSigned(DIn.Cur.SignedValue, _fracWidth).DoubleValue); } }
public void TestFromToDouble() { Assert.AreEqual(0.0, SFix.FromDouble(0.0, 1, 1).DoubleValue, "conversion from/to 0 failed."); Assert.AreEqual(1.0, SFix.FromDouble(1.0, 2, 0).DoubleValue, "conversion from/to 1 failed."); Assert.AreEqual(-1.0, SFix.FromDouble(-1.0, 2, 0).DoubleValue, "conversion from/to -1 failed."); Assert.AreEqual(1.0, SFix.FromDouble(1.5, 3, 0).DoubleValue, "conversion from/to 1 failed."); Assert.AreEqual(-1.5, SFix.FromDouble(-1.5, 2, 1).DoubleValue, "conversion from/to 1.6 failed."); }
public static SFix Cos(SFix value, int fracWidth) { Contract.Requires <ArgumentOutOfRangeException>(fracWidth >= 0, "fracWidth"); return(SFix.FromDouble( Math.Cos(value.DoubleValue), 2, fracWidth)); }
public static SFix Cos(SFix value) { Contract.Requires <ArgumentOutOfRangeException>(value.Format.FracWidth >= 0, "value.Format.FracWidth"); return(SFix.FromDouble( Math.Sin(value.DoubleValue), 2, value.Format.FracWidth)); }
private async void Processing() { await Tick; var aux = SFix.FromDouble(0.5, 1, 1); SFix aux1; Ctr.Next = _ctr.Cur; aux1 = _ctr.Cur + aux; _ctr.Next = aux1.Resize(7, 1); }
/* * Code partially ported from: * * Chapter 2, Programs 3-5, Fig. 2.8-2.10 * Gerald/Wheatley, APPLIED NUMERICAL ANALYSIS (fourth edition) * Addison-Wesley, 1989 */ public static void ComputeLU(SFix[,] A, int iw, int fw) { int n = A.GetLength(0); SFix sum; SFix diag = (SFix.FromLong(1, iw, fw) / A[0, 0]).Resize(iw, fw); for (int i = 1; i < n; i++) { A[0, i] = (A[0, i] * diag).Resize(iw, fw); } /* * Now complete the computing of L and U elements. * The general plan is to compute a column of L's, then * call pivot to interchange rows, and then compute * a row of U's. */ int nm1 = n - 1; for (int j = 1; j < nm1; j++) { /* column of L's */ for (int i = j; i < n; i++) { sum = SFix.FromLong(0, iw, fw); for (int k = 0; k < j; k++) { sum = (sum + A[i, k] * A[k, j]).Resize(iw, fw); } A[i, j] = (A[i, j] - sum).Resize(iw, fw); } /* row of U's */ diag = (SFix.FromLong(1, iw, fw) / A[j, j]).Resize(iw, fw); for (int k = j + 1; k < n; k++) { sum = SFix.FromLong(0, iw, fw); for (int i = 0; i < j; i++) { sum = (sum + A[j, i] * A[i, k]).Resize(iw, fw); } A[j, k] = ((A[j, k] - sum) * diag).Resize(iw, fw); } } /* still need to get last element in L Matrix */ sum = SFix.FromLong(0, iw, fw); for (int k = 0; k < nm1; k++) { sum = (sum + A[nm1, k] * A[k, nm1]).Resize(iw, fw); } A[nm1, nm1] = (A[nm1, nm1] - sum).Resize(iw, fw); }
/// <summary> /// Constructs a new instance. /// </summary> /// <param name="floatWidth">total bit-width of input floating-point number /// (actual partitioning between exponent and mantissa bits does not matter)</param> /// <param name="outFormat">desired fixed-point output format</param> public FloatSignAsSigned(int floatWidth, FixFormat outFormat) { FloatWidth = floatWidth; OutFormat = outFormat; _outM1 = SFix.FromDouble(-1.0, outFormat.IntWidth, outFormat.FracWidth).SLVValue; _out0 = SFix.FromDouble(0.0, outFormat.IntWidth, outFormat.FracWidth).SLVValue; _out1 = SFix.FromDouble(1.0, outFormat.IntWidth, outFormat.FracWidth).SLVValue; _zeros = StdLogicVector._0s(floatWidth - 1); TASite = new TransactionSite(this); }
private void HandleScSinCos(XILSInstr i) { var preds = RemapPreds(i.Preds); var infmt = i.OperandTypes[0].GetFixFormat(); var outfmt = i.ResultTypes[0].GetFixFormat(); if (infmt == null) { Emit(i.Command.CreateStk(preds, i.OperandTypes, i.ResultTypes)); } else { var otype = i.OperandTypes[0]; if (HaveXilinxCordic && infmt.IntWidth != 3) { // Xilinx Cordic needs exactly 3 integer bits for operand otype = SFix.MakeType(3, infmt.FracWidth); Emit(DefaultInstructionSet.Instance.Convert().CreateStk( preds, 1, i.OperandTypes[0], otype)); } else if (infmt.IntWidth != 2) { // Any reasonable core (e.g. LUT-based implementation) will require 2 integer operand bits otype = SFix.MakeType(2, infmt.FracWidth); Emit(DefaultInstructionSet.Instance.Convert().CreateStk( preds, 1, i.OperandTypes[0], otype)); } preds = new InstructionDependency[0]; var rtype = i.ResultTypes[0]; if (outfmt.IntWidth != 2) { // we gonna need exactly 2 integer bits for results rtype = SFix.MakeType(2, outfmt.FracWidth); } Emit(DefaultInstructionSet.Instance.ScSinCos().CreateStk( preds, 1, otype, rtype, rtype)); if (!rtype.Equals(i.ResultTypes[1])) { Emit(DefaultInstructionSet.Instance.Convert().CreateStk( 1, rtype, i.ResultTypes[1])); } if (!rtype.Equals(i.ResultTypes[0])) { Emit(DefaultInstructionSet.Instance.Swap().CreateStk( 2, i.ResultTypes[0], rtype, rtype, i.ResultTypes[0])); Emit(DefaultInstructionSet.Instance.Convert().CreateStk( 1, rtype, i.ResultTypes[0])); Emit(DefaultInstructionSet.Instance.Swap().CreateStk( 2, rtype, rtype, rtype, rtype)); } } }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types and enum types are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertSigned(Signed src, Type dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.Equals(typeof(double))) { return(SFix.FromSigned(src, 0).DoubleValue); } else { return(ConvertValue(src.LongValue, dstType)); } }
public static Signed SignedSign(SFix number) { if (number < SFix.Zero) { return(Signed.FromInt(-1, 2)); } else if (number > SFix.Zero) { return(Signed.FromInt(1, 2)); } else { return(Signed.FromInt(0, 2)); } }
private async void StimulateAndTest() { DesignContext.Instance.FixPoint.DefaultRadix = 10; for (double i = -1.0; i <= 1.0; i += 0.0625) { var x = SFix.FromDouble(i, 2, _xFracWidth); _x.Next = x.SLVValue; //DesignContext.Wait(_pipeStages + 4); await NTicks(_pipeStages + 3); Console.WriteLine("X = " + x + ", Sin = " + SFix.FromSigned(_sin.Cur.SignedValue, _yFracWidth) + ", Cos = " + SFix.FromSigned(_cos.Cur.SignedValue, _yFracWidth)); } }
public static void RunTest() { DesignContext.Reset(); FixedPointSettings.GlobalArithSizingMode = EArithSizingMode.VHDLCompliant; var a = SFix.FromDouble(1.0, 8, 10); var b = SFix.FromDouble(2.0, 8, 10); var c = SFix.FromDouble(3.0, 8, 10); var d = SFix.FromDouble(4.0, 8, 10); TestAddMul2 dut = new TestAddMul2() { Clk = new SLSignal(), A = new Signal <SFix>() { InitialValue = a }, B = new Signal <SFix>() { InitialValue = b }, C = new Signal <SFix>() { InitialValue = c }, D = new Signal <SFix>() { InitialValue = d }, R = new Signal <SFix>() { InitialValue = a * b + c * d } }; DesignContext.Instance.Elaborate(); XilinxIntegration.RegisterIPCores(DesignContext.Instance.Descriptor); DesignContext.Instance.CompleteAnalysis(); XC6VLX240T_FF1156 fpga = new XC6VLX240T_FF1156() { SpeedGrade = ESpeedGrade._2, TopLevelComponent = dut }; fpga.Synthesize(@".\hdl_out_TestAddMul2", "TestAddMul2"); }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertSigned(Signed src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(Signed))) { return(src.Resize(SFix.GetFormat(dstType).IntWidth)); } else if (dstType.CILType.Equals(typeof(SFix))) { return(SFix.FromSigned(src.Resize(SFix.GetFormat(dstType).TotalWidth), SFix.GetFormat(dstType).FracWidth)); } else { return(ConvertSigned(src, dstType.CILType)); } }
private async void LERPProcess() { await Tick; while (true) { Addr.Next = X.Cur.GetIntPart().Resize(AddrWidth); SFix alpha = UFix.FromUnsigned(X.Cur.GetFracPart(), XFracWidth).SFixValue; await Tick; SFix v0 = Data.Cur; Addr.Next = (X.Cur.GetIntPart() + Unsigned.One).Resize(AddrWidth); await Tick; SFix v1 = Data.Cur; _yIn.Next = (v0 + alpha * (v1 - v0)).Resize(YIntWidth, YFracWidth).SLVValue; await PipeStages.Ticks(); } }
/// <summary> /// Constructs a new instance. /// </summary> /// <param name="xIntWidth">integer bits of operand</param> /// <param name="xFracWidth">fractional bits of operand</param> /// <param name="yIntWidth">integer bits of result</param> /// <param name="yFracWidth">fractional bits of result</param> /// <param name="pipeStages">desired computation-only latency</param> /// <param name="data">data table</param> public LERP11Core(int xIntWidth, int xFracWidth, int yIntWidth, int yFracWidth, int pipeStages, SFix[] data) { Contract.Requires <ArgumentOutOfRangeException>(xIntWidth > 0, "xIntWidth must be positive."); Contract.Requires <ArgumentOutOfRangeException>(xFracWidth >= 0, "xFracWidth must be non-negative."); Contract.Requires <ArgumentOutOfRangeException>(yIntWidth + yFracWidth > 0, "total bit-width of result must be positive"); Contract.Requires <ArgumentOutOfRangeException>(pipeStages >= 0, "pipeStages must be non-negative."); Contract.Requires <ArgumentOutOfRangeException>(xFracWidth > 0 || pipeStages == 0, "xFracWidth == 0 is a degenerate case (lookup-only). No additional pipeline stages allowed."); Contract.Requires <ArgumentNullException>(data != null, "data"); PipeStages = pipeStages; XIntWidth = xIntWidth; XFracWidth = xFracWidth; YIntWidth = yIntWidth; YFracWidth = yFracWidth; DIntWidth = data[0].Format.IntWidth; DFracWidth = data[0].Format.FracWidth; _x = new Signal <UFix>() { InitialValue = UFix.FromDouble(0.0, xIntWidth, xFracWidth) }; _y = new Signal <SFix>() { InitialValue = SFix.FromDouble(0.0, yIntWidth, yFracWidth) }; AddrWidth = MathExt.CeilPow2(data.Length); _unitAddr = new Signal <Unsigned>() { InitialValue = Unsigned.FromUInt(0, AddrWidth) }; _memContent = new VSignal <SFix>(data.Length, _ => new Signal <SFix>() { InitialValue = data[_] }); _lerpUnit = new LERPUnit(xIntWidth, xFracWidth, yIntWidth, yFracWidth, pipeStages); Bind(() => { _lerpUnit.Clk = Clk; _lerpUnit.X = _x; _lerpUnit.Y = _y; _lerpUnit.Addr = _unitAddr; _lerpUnit.Data = _unitData; }); }
/* * Code partially ported from: * * Chapter 2, Programs 3-5, Fig. 2.8-2.10 * Gerald/Wheatley, APPLIED NUMERICAL ANALYSIS (fourth edition) * Addison-Wesley, 1989 */ public static void ComputeLU(SFix[,] A, int iw, int fw) { int n = A.GetLength(0); SFix sum; SFix diag = (SFix.FromLong(1, iw, fw) / A[0, 0]).Resize(iw, fw); for (int i = 1; i < n; i++) A[0, i] = (A[0, i] * diag).Resize(iw, fw); /* * Now complete the computing of L and U elements. * The general plan is to compute a column of L's, then * call pivot to interchange rows, and then compute * a row of U's. */ int nm1 = n - 1; for (int j = 1; j < nm1; j++) { /* column of L's */ for (int i = j; i < n; i++) { sum = SFix.FromLong(0, iw, fw); for (int k = 0; k < j; k++) sum = (sum + A[i, k] * A[k, j]).Resize(iw, fw); A[i, j] = (A[i, j] - sum).Resize(iw, fw); } /* row of U's */ diag = (SFix.FromLong(1, iw, fw) / A[j, j]).Resize(iw, fw); for (int k = j + 1; k < n; k++) { sum = SFix.FromLong(0, iw, fw); for (int i = 0; i < j; i++) sum = (sum + A[j, i] * A[i, k]).Resize(iw, fw); A[j, k] = ((A[j, k] - sum) * diag).Resize(iw, fw); } } /* still need to get last element in L Matrix */ sum = SFix.FromLong(0, iw, fw); for (int k = 0; k < nm1; k++) sum = (sum + A[nm1, k] * A[k, nm1]).Resize(iw, fw); A[nm1, nm1] = (A[nm1, nm1] - sum).Resize(iw, fw); }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types and enum types are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertSFix(SFix src, Type dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.Equals(typeof(double))) { return(src.DoubleValue); } else if (dstType.Equals(typeof(sbyte))) { return((sbyte)src.Resize(8, 0).SignedValue.LongValue); } else if (dstType.Equals(typeof(byte))) { return((byte)src.UFixValue.Resize(8, 0).UnsignedValue.ULongValue); } else if (dstType.Equals(typeof(short))) { return((short)src.Resize(16, 0).SignedValue.LongValue); } else if (dstType.Equals(typeof(ushort))) { return((byte)src.UFixValue.Resize(16, 0).UnsignedValue.ULongValue); } else if (dstType.Equals(typeof(int))) { return((int)src.Resize(32, 0).SignedValue.LongValue); } else if (dstType.Equals(typeof(uint))) { return((uint)src.UFixValue.Resize(32, 0).UnsignedValue.ULongValue); } else if (dstType.Equals(typeof(long))) { return(src.Resize(64, 0).SignedValue.LongValue); } else if (dstType.Equals(typeof(ulong))) { return(src.UFixValue.Resize(64, 0).UnsignedValue.ULongValue); } else { throw new NotImplementedException(); } }
private static IEnumerable <XILSInstr> Rewrite_Sin_ScSinCos_fixpt(TypeDescriptor joker, TypeDescriptor rtype, InstructionDependency[] preds) { var iset = DefaultInstructionSet.Instance; var fmt = joker.GetFixFormat(); var rfmt = rtype.GetFixFormat(); int pifw = fmt.FracWidth; var pitype = SFix.MakeType(0, pifw); int muliw = fmt.IntWidth; var multype = SFix.MakeType(muliw, fmt.FracWidth + pifw); int fw = Math.Max(5, rfmt.FracWidth + 1); // Xilinx Cordic needs at least 8 input bits fw = Math.Min(45, fw); // Xilinx Cordic likes at most 48 input bits var cuttype = SFix.MakeType(3, fw); var modtype = SFix.MakeType(3, fw); // Actually, 1 integer bit less is required. However, Xilinx Cordic needs the additional bit. int fwr = Math.Max(6, rfmt.FracWidth); // Xilinx Cordic needs at least 8 output bits (?) fwr = Math.Min(46, fwr); // Xilinx Cordic likes at most 48 output bits (?) var sintype = SFix.MakeType(2, fwr); if (muliw <= 1) { return(new XILSInstr[] { iset.LdConst(SFix.FromDouble(1.0 / Math.PI, 0, pifw)).CreateStk(preds, 0, pitype), iset.Mul().CreateStk(2, joker, pitype, multype), iset.Convert().CreateStk(1, multype, modtype), iset.ScSinCos().CreateStk(1, modtype, sintype, sintype), iset.Swap().CreateStk(2, sintype, sintype, sintype, sintype), iset.Pop().CreateStk(1, sintype) }); } else { return(new XILSInstr[] { iset.LdConst(SFix.FromDouble(1.0 / Math.PI, 0, pifw)).CreateStk(preds, 0, pitype), iset.Mul().CreateStk(2, joker, pitype, multype), iset.Convert().CreateStk(1, multype, cuttype), iset.Mod2().CreateStk(1, cuttype, modtype), iset.ScSinCos().CreateStk(1, modtype, sintype, sintype), iset.Swap().CreateStk(2, sintype, sintype, sintype, sintype), iset.Pop().CreateStk(1, sintype) }); } }
public static Tuple <SFix, SFix> ScSinCos(SFix value, int resultFracBits) { Contract.Requires <ArgumentOutOfRangeException>(value.DoubleValue >= -1.0, "value"); Contract.Requires <ArgumentOutOfRangeException>(value.DoubleValue <= 1.0, "value"); Contract.Requires <ArgumentOutOfRangeException>(resultFracBits >= 0, "resultFracBits"); var result = Tuple.Create( SFix.FromDouble( Math.Cos(Math.PI * value.DoubleValue), 2, resultFracBits), SFix.FromDouble( Math.Sin(Math.PI * value.DoubleValue), 2, resultFracBits)); return(result); }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertDouble(double src, TypeDescriptor dstType) { Contract.Requires <ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(SFix))) { var fmt = SFix.GetFormat(dstType); return(SFix.FromDouble(src, fmt.IntWidth, fmt.FracWidth)); } else if (dstType.CILType.Equals(typeof(UFix))) { var fmt = UFix.GetFormat(dstType); return(UFix.FromDouble(src, fmt.IntWidth, fmt.FracWidth)); } else { throw new NotImplementedException(); } }
private async void Computation() { await Tick; while (true) { ProgramFlow.DoNotUnroll(); ProgramFlow.IOBarrier(); Rdy.Next = '0'; var sincos = MathExt.ScSinCos(SFix.FromSigned(X.Cur.SignedValue, _xFracWidth), _yFracWidth); Cos.Next = sincos.Item1.SLVValue; Sin.Next = sincos.Item2.SLVValue; await 12.Ticks(); ProgramFlow.IOBarrier(); Rdy.Next = '1'; ProgramFlow.IOBarrier(); await Tick; } }
private async void DivideProcess() { _rdy = true; while (true) { ProgramFlow.DoNotUnroll(); while (!_nxt) { ProgramFlow.DoNotUnroll(); await Tick; } _rdy = false; ProgramFlow.Barrier(); _quotient = _dividend / _divisor; ProgramFlow.Barrier(); await 10.Ticks(); _rdy = true; } }
/// <summary> /// Constructs a new instance. /// </summary> /// <param name="xIntWidth">integer bits of operand</param> /// <param name="xFracWidth">fractional bits of operand</param> /// <param name="yIntWidth">integer bits of result</param> /// <param name="yFracWidth">fractional bits of result</param> /// <param name="pipeStages">desired computation-only latency</param> /// <param name="data">data table</param> public LERP11Core(int xIntWidth, int xFracWidth, int yIntWidth, int yFracWidth, int pipeStages, SFix[] data) { Contract.Requires<ArgumentOutOfRangeException>(xIntWidth > 0, "xIntWidth must be positive."); Contract.Requires<ArgumentOutOfRangeException>(xFracWidth >= 0, "xFracWidth must be non-negative."); Contract.Requires<ArgumentOutOfRangeException>(yIntWidth + yFracWidth > 0, "total bit-width of result must be positive"); Contract.Requires<ArgumentOutOfRangeException>(pipeStages >= 0, "pipeStages must be non-negative."); Contract.Requires<ArgumentOutOfRangeException>(xFracWidth > 0 || pipeStages == 0, "xFracWidth == 0 is a degenerate case (lookup-only). No additional pipeline stages allowed."); Contract.Requires<ArgumentNullException>(data != null, "data"); PipeStages = pipeStages; XIntWidth = xIntWidth; XFracWidth = xFracWidth; YIntWidth = yIntWidth; YFracWidth = yFracWidth; DIntWidth = data[0].Format.IntWidth; DFracWidth = data[0].Format.FracWidth; _x = new Signal<UFix>() { InitialValue = UFix.FromDouble(0.0, xIntWidth, xFracWidth) }; _y = new Signal<SFix>() { InitialValue = SFix.FromDouble(0.0, yIntWidth, yFracWidth) }; AddrWidth = MathExt.CeilPow2(data.Length); _unitAddr = new Signal<Unsigned>() { InitialValue = Unsigned.FromUInt(0, AddrWidth) }; _memContent = new VSignal<SFix>(data.Length, _ => new Signal<SFix>() { InitialValue = data[_] }); _lerpUnit = new LERPUnit(xIntWidth, xFracWidth, yIntWidth, yFracWidth, pipeStages); Bind(() => { _lerpUnit.Clk = Clk; _lerpUnit.X = _x; _lerpUnit.Y = _y; _lerpUnit.Addr = _unitAddr; _lerpUnit.Data = _unitData; }); }
static void PrintMatrix(SFix[,] A) { int n = A.GetLength(0); for (int i = 0; i < n; i++) { if (i > 0) Console.WriteLine(); for (int j = 0; j < n; j++) { if (j > 0) Console.Write(" "); Console.Write(A[i, j].ToString(10, 2)); } } }
public static void RunTest() { FixedPointSettings.GlobalDefaultRadix = 10; FixedPointSettings.GlobalOverflowMode = EOverflowMode.Fail; SFix s1 = SFix.FromDouble(1.0, 2, 2); SFix s2 = SFix.FromDouble(-0.75, 2, 2); SFix s3 = s1 / s2; Random rnd = new Random(); int n = 10; int iw = 14; int fw = 14; double eps = Math.Pow(2.0, -fw); SFix[,] A = new SFix[n, n]; double[,] Ad = new double[n, n]; SFix[] b = new SFix[n]; double[] bd = new double[n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { double a = 2.0 * rnd.NextDouble() - 1.0; Ad[i, j] = a; } } //Ad = new double[,] { { 4, -2, 1 }, { -3, -1, 4 }, { 1, -1, 3 } }; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { double a = Ad[i, j]; SFix c = SFix.FromDouble(a, iw, fw); string cs = c.ToString(); double ar = c.DoubleValue; double d = a - ar; double da = Math.Abs(d); Debug.Assert(da < eps); A[i, j] = c; Ad[i, j] = a; } double bi = 2.0 * rnd.NextDouble() - 1.0; b[i] = SFix.FromDouble(bi, 3, 33); bd[i] = bi; } SFix[,] Ac = (SFix[,])A.Clone(); Console.WriteLine("Original matrix:"); PrintMatrix(A); Console.WriteLine(); ComputeLU(A, iw, fw); Console.WriteLine("LU:"); PrintMatrix(A); Console.WriteLine(); SFix[] x = new SFix[n]; SFix[] y = new SFix[n]; SubstituteLU(A, b, y, x); Console.WriteLine("Precisions:"); for (int i = 0; i < n; i++) { SFix bc = Ac[i, 0] * x[0]; for (int j = 1; j < n; j++) { bc += Ac[i, j] * x[j]; } SFix d = bc - b[i]; Console.Write("b[" + i + "] = " + b[i].ToString(10, 2)); Console.Write(" / " + bc.ToString(10, 2)); Console.WriteLine(" / d = " + d.ToString(10, 2)); } }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types, enum types, and System#-intrinsic datatypes /// Signed, Unsigned, SFix, UFix and StdLogicVector are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertSFix(SFix src, TypeDescriptor dstType) { Contract.Requires<ArgumentNullException>(dstType != null, "dstType"); if (dstType.CILType.Equals(typeof(SFix))) return src.Resize(SFix.GetFormat(dstType).IntWidth, SFix.GetFormat(dstType).FracWidth); else if (dstType.CILType.Equals(typeof(Signed))) return src.SignedValue.Resize(SFix.GetFormat(dstType).IntWidth); else if (dstType.CILType.Equals(typeof(StdLogicVector))) return src.SLVValue[StdLogicVector.GetLength(dstType) - 1, 0]; else return ConvertSFix(src, dstType.CILType); }
/// <summary> /// Converts <paramref name="src"/> to <paramref name="dstType"/> datatype, possibly with loss of precision or overflow. /// </summary> /// <remarks>Currently, conversions between all primitive numeric CIL types and enum types are supported.</remarks> /// <exception cref="ArgumentNullException">if <paramref name="dstType"/> is null</exception> /// <exception cref="NotImplementedException">if there is no known conversion to <paramref name="dstType"/></exception> public static object ConvertSFix(SFix src, Type dstType) { Contract.Requires<ArgumentNullException>(dstType != null, "dstType"); if (dstType.Equals(typeof(double))) return src.DoubleValue; else if (dstType.Equals(typeof(sbyte))) return (sbyte)src.Resize(8, 0).SignedValue.LongValue; else if (dstType.Equals(typeof(byte))) return (byte)src.UFixValue.Resize(8, 0).UnsignedValue.ULongValue; else if (dstType.Equals(typeof(short))) return (short)src.Resize(16, 0).SignedValue.LongValue; else if (dstType.Equals(typeof(ushort))) return (byte)src.UFixValue.Resize(16, 0).UnsignedValue.ULongValue; else if (dstType.Equals(typeof(int))) return (int)src.Resize(32, 0).SignedValue.LongValue; else if (dstType.Equals(typeof(uint))) return (uint)src.UFixValue.Resize(32, 0).UnsignedValue.ULongValue; else if (dstType.Equals(typeof(long))) return src.Resize(64, 0).SignedValue.LongValue; else if (dstType.Equals(typeof(ulong))) return src.UFixValue.Resize(64, 0).UnsignedValue.ULongValue; else throw new NotImplementedException(); }