using NIFPGA.lvbitx; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; using FxpConvert.Common; namespace NIFPGA { public sealed class FPGA { public string BitstreamMD5 { get; private set; } = string.Empty; public string BitfileVersion { get; private set; } = string.Empty; public string SignatureRegister { get; private set; } = string.Empty; public string BitstreamVersion { get; private set; } = string.Empty; public string SignatureNames { get; private set; } = string.Empty; private List fifos= new List(); private IFxpConvert _FXPConvert; private List properties= new List(); public IReadOnlyDictionary Fifos => fifos.ToDictionary(x=>x.Name); public IReadOnlyDictionary Properties=> properties.ToDictionary(x=>x.Name); private FPGASession session; public Boolean Error=> session.Error; public NiFpga_Status LastStatus=> session.LastStatus; public string Message=>session.Message; public FPGA(IFxpConvert convert) { _FXPConvert = convert; session = new FPGASession(); Irq = new Irq(session); } public T CreateProperty(string name) where T :FPGABaseProperty { var pro = properties.FirstOrDefault(x => x.Name == name); if (pro == null) throw new Exception($"Property {name} not found"); return (T)pro; } public T CreateFifo(string name) where T:Fifo { var fifo = fifos.FirstOrDefault(x => x.Name == name); if (fifo == null) throw new Exception($"Fifo {name} not found"); return (T)fifo; } public void Parse(string path) { var val = lvbitx.Parse.ParseFile(path); InitProperies(val.VI.Registers); InitFifo(val.Project.DMA); } private void InitFifo(List dma) { if (dma == null || dma.Count == 0) return; dma.ForEach(x => { switch(x.Direction) { case "TargetToHost"://read switch (x.Datatype) { case Datatype.Boolean: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name, }); break; case Datatype.Int8: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name, }); break; case Datatype.Uint8: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int16: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint16: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int32: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint32: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int64: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint64: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Float: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Double: fifos.Add(new ReadFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.FXP: fifos.Add(new ReadFXPFifo(session, x.ControlSet,x.FxpTypeInfo, _FXPConvert) { Name = x.Name, }); break; case Datatype.Array: break; } break; case "HostToTarget"://write switch (x.Datatype) { case Datatype.Boolean: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int8: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint8: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int16: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint16: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int32: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint32: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Int64: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Uint64: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Float: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.Double: fifos.Add(new WriteFifo(session, x.ControlSet) { Name = x.Name }); break; case Datatype.FXP: fifos.Add(new WriteFXPFifo(session, x.ControlSet, x.FxpTypeInfo, _FXPConvert) { Name = x.Name }); break; case Datatype.Array: break; } break; } }); } public Irq Irq { get; } public void Open(string bitfile, string resource, NiFpga_OpenAttribute attribute) { var lv = lvbitx.Parse.ParseFile(bitfile); BitfileVersion = lv.BitfileVersion; SignatureNames = lv.SignatureNames; SignatureRegister= lv.SignatureRegister; BitstreamMD5 = lv.BitstreamMD5; BitstreamVersion = lv.BitstreamVersion; InitProperies(lv.VI.Registers); InitFifo(lv.Project.DMA); session.Open(bitfile, lv.SignatureRegister, resource, attribute); var indicator = properties.Select(x => x.Indicator).ToArray(); } private void InitProperies(List registers) { if (registers == null || registers.Count == 0) return; foreach (var reg in registers) { switch (reg.Datatype) { case lvbitx.Datatype.Int16: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Boolean: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int8: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint8: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint16: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int32: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint32: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int64: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint64: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Float: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Double: if (!reg.Indicator) { properties.Add(new FPGAWriteProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAReadProperty(session, reg.Offset) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.FXP: if (!reg.Indicator) { properties.Add(new FPGAFXPWriteProperty(session, reg.Offset, reg.FxpTypeInfo, _FXPConvert) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAFXPReadProperty(session, reg.Offset, reg.FxpTypeInfo, _FXPConvert) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Array: switch (reg.ArrayValueType) { case lvbitx.Datatype.Boolean: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int8: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint8: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int16: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint16: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int32: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint32: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Int64: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Uint64: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Float: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Double: if (!reg.Indicator) { properties.Add(new FPGAArrayWriteProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayReadProperty(session, reg.Offset, reg.Size) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.FXP: if (!reg.Indicator) { properties.Add(new FPGAArrayFXPWriteProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } else { properties.Add(new FPGAArrayFXPReadProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert) { Name = reg.Name, SizeInBits = reg.SizeInBits, }); } break; case lvbitx.Datatype.Array: break; } break; } } } public void Close()=>session.Close(); public void Run() { session.CheckResult(session.GetDelegate()(session.Session, Interop.NiFpga_RunAttribute.NiFpga_RunAttribute_None)); } public void Abort() { session.CheckResult(session.GetDelegate()(session.Session)); } public void Reset() { session.CheckResult(session.GetDelegate()(session.Session)); } public void Download() { session.CheckResult(session.GetDelegate()(session.Session)); } public void FpgaFinalize() { session.CheckResult(session.GetDelegate()()); } } }