/// <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; }); }
private void ComputeOutAddr() { if (Rst.Cur == '1') { _outAddr.Next = StartupAddr; } else if (BrP.Cur == "1" || BrN.Cur == "0") { _outAddr.Next = AltAddr.Cur; } else { _outAddr.Next = (_lastAddr.Cur.UnsignedValue + Unsigned.FromUInt(1, AddrWidth)) .Resize(AddrWidth).SLVValue; } }
private void ComputeOutAddrWithRstQ() { if (Rst.Cur == '1') { _outAddr.Next = StartupAddr; } else if (_rstq.Cur[0] == '1' || (BrP.Cur != "1" && BrN.Cur != "0")) { _outAddr.Next = (_lastAddr.Cur.UnsignedValue + Unsigned.FromUInt(1, AddrWidth)) .Resize(AddrWidth).SLVValue; } else { _outAddr.Next = AltAddr.Cur; } }
private Unsigned ComputeConstAddress(Array array, long[] indices, uint nword) { MemoryMappedStorage mms = GetDataLayout(array); ArrayMemoryLayout layout = mms.Layout as ArrayMemoryLayout; if (layout.ElementsPerWord > 1) { throw new NotImplementedException("Multiple elements per word not yet implemented"); } MemoryRegion region = mms.Region; IMarshalInfo minfo = region.MarshalInfo; Unsigned addr = mms.BaseAddress; for (int i = 0; i < indices.Length; i++) { Unsigned offs = Unsigned.FromULong((ulong)indices[i] * layout.Strides[i], mms.Region.AddressWidth); addr += offs; } addr += Unsigned.FromUInt(nword, mms.Region.AddressWidth); addr = addr.Resize(mms.Region.AddressWidth); return(addr); }
/// <summary> /// Constructs a new instance /// </summary> /// <param name="lutWidth">resolution of data table</param> /// <param name="xFracWidth">fractional width of operand</param> /// <param name="yFracWidth">fractional width of result</param> /// <param name="pipeStages">additional pipeline stages for interpolation computation</param> public SinCosLUTCore(int lutWidth, int xFracWidth, int yFracWidth, int pipeStages) { PipeStages = pipeStages; XIntWidth = 2; XFracWidth = xFracWidth; YIntWidth = 2; YFracWidth = yFracWidth; DIntWidth = 2; DFracWidth = yFracWidth; LUTWidth = lutWidth; _x = new Signal <UFix>() { InitialValue = UFix.FromDouble(0.0, LUTWidth + 1, XFracWidth - LUTWidth - 1) }; _xq = new Signal <UFix>() { InitialValue = UFix.FromDouble(0.0, LUTWidth + 1, XFracWidth - LUTWidth - 1) }; _sinRaw = new Signal <SFix>() { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth) }; _cosRaw = new Signal <SFix>() { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth) }; _sinIn = new SLVSignal(YIntWidth + YFracWidth) { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue }; _cosIn = new SLVSignal(YIntWidth + YFracWidth) { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue }; _sinOut = new SLVSignal(YIntWidth + YFracWidth) { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue }; _cosOut = new SLVSignal(YIntWidth + YFracWidth) { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth).SLVValue }; AddrWidth = lutWidth + 1; _sinAddr = new Signal <Unsigned>() { InitialValue = Unsigned.FromUInt(0, AddrWidth) }; _cosAddr = new Signal <Unsigned>() { InitialValue = Unsigned.FromUInt(0, AddrWidth) }; _sinData = new Signal <SFix>() { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth) }; _cosData = new Signal <SFix>() { InitialValue = SFix.FromDouble(0.0, YIntWidth, YFracWidth) }; _sinLUT = new VSignal <SFix>((1 << lutWidth) + 2, _ => new Signal <SFix>() { InitialValue = SFix.FromDouble(Math.Sin(Math.PI * 0.5 * _ / (double)(1 << lutWidth)), 2, yFracWidth) }); _sinFlipSignIn = new SLVSignal(1) { InitialValue = "0" }; _cosFlipSignIn = new SLVSignal(1) { InitialValue = "0" }; _sinFlipSignOut = new SLVSignal(1) { InitialValue = "0" }; _cosFlipSignOut = new SLVSignal(1) { InitialValue = "0" }; _mirror = UFix.FromUnsigned(Unsigned.One.Resize(XFracWidth + 2) << (xFracWidth + 1), xFracWidth - LUTWidth); _mirror2 = UFix.FromUnsigned(Unsigned.One.Resize(XFracWidth + 2) << xFracWidth, xFracWidth - LUTWidth); _sinPipe = new RegPipe(pipeStages, YIntWidth + YFracWidth); Bind(() => { _sinPipe.Clk = Clk; _sinPipe.Din = _sinIn; _sinPipe.Dout = _sinOut; }); _cosPipe = new RegPipe(pipeStages, YIntWidth + YFracWidth); Bind(() => { _cosPipe.Clk = Clk; _cosPipe.Din = _cosIn; _cosPipe.Dout = _cosOut; }); _sinFlipSignPipe = new RegPipe(2, 1); Bind(() => { _sinFlipSignPipe.Clk = Clk; _sinFlipSignPipe.Din = _sinFlipSignIn; _sinFlipSignPipe.Dout = _sinFlipSignOut; }); _cosFlipSignPipe = new RegPipe(2, 1); Bind(() => { _cosFlipSignPipe.Clk = Clk; _cosFlipSignPipe.Din = _cosFlipSignIn; _cosFlipSignPipe.Dout = _cosFlipSignOut; }); _sinUnit = new LERPUnit(lutWidth + 1, xFracWidth - 1 - lutWidth, YIntWidth, yFracWidth, 0); Bind(() => { _sinUnit.Clk = Clk; _sinUnit.X = _x; _sinUnit.Y = _sinRaw; _sinUnit.Addr = _sinAddr; _sinUnit.Data = _sinData; }); _cosUnit = new LERPUnit(lutWidth + 1, xFracWidth - 1 - lutWidth, YIntWidth, yFracWidth, 0); Bind(() => { _cosUnit.Clk = Clk; _cosUnit.X = _xq; _cosUnit.Y = _cosRaw; _cosUnit.Addr = _cosAddr; _cosUnit.Data = _cosData; }); TASite = new TransactionSite(this); }