FPGA.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. using NIFPGA.lvbitx;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Threading.Tasks.Dataflow;
  9. using FxpConvert.Common;
  10. namespace NIFPGA
  11. {
  12. public sealed class FPGA
  13. {
  14. private List<Fifo> fifos= new List<Fifo>();
  15. private IFxpConvert _FXPConvert;
  16. private List<FPGABaseProperty> properties= new List<FPGABaseProperty>();
  17. public IReadOnlyDictionary<String,Fifo> Fifos => fifos.ToDictionary(x=>x.Name);
  18. public IReadOnlyDictionary<String,FPGABaseProperty> Properties=> properties.ToDictionary(x=>x.Name);
  19. private FPGASession session;
  20. public Boolean Error=> session.Error;
  21. public string Message=>session.Message;
  22. public FPGA(IFxpConvert convert)
  23. {
  24. _FXPConvert = convert;
  25. session = new FPGASession();
  26. Irq = new Irq(session);
  27. }
  28. public T CreateProperty<T>(string name) where T :FPGABaseProperty
  29. {
  30. var pro = properties.FirstOrDefault(x => x.Name == name);
  31. if (pro == null) throw new Exception($"Property {name} not found");
  32. return (T)pro;
  33. }
  34. public T CreateFifo<T>(string name) where T:Fifo
  35. {
  36. var fifo = fifos.FirstOrDefault(x => x.Name == name);
  37. if (fifo == null) throw new Exception($"Fifo {name} not found");
  38. return (T)fifo;
  39. }
  40. public void Parse(string path)
  41. {
  42. var val = lvbitx.Parse.ParseFile(path);
  43. InitProperies(val.VI.Registers);
  44. InitFifo(val.Project.DMA);
  45. }
  46. private void InitFifo(List<DMA> dma)
  47. {
  48. if (dma == null || dma.Count == 0) return;
  49. dma.ForEach(x =>
  50. {
  51. switch(x.Direction)
  52. {
  53. case "TargetToHost"://read
  54. switch (x.Datatype)
  55. {
  56. case Datatype.Boolean:
  57. fifos.Add(new ReadFifo<bool>(session, x.ControlSet)
  58. {
  59. Name = x.Name,
  60. });
  61. break;
  62. case Datatype.Int8:
  63. fifos.Add(new ReadFifo<sbyte>(session, x.ControlSet)
  64. {
  65. Name = x.Name,
  66. });
  67. break;
  68. case Datatype.Uint8:
  69. fifos.Add(new ReadFifo<byte>(session, x.ControlSet) { Name = x.Name });
  70. break;
  71. case Datatype.Int16:
  72. fifos.Add(new ReadFifo<short>(session, x.ControlSet) { Name = x.Name });
  73. break;
  74. case Datatype.Uint16:
  75. fifos.Add(new ReadFifo<ushort>(session, x.ControlSet) { Name = x.Name });
  76. break;
  77. case Datatype.Int32:
  78. fifos.Add(new ReadFifo<int>(session, x.ControlSet) { Name = x.Name });
  79. break;
  80. case Datatype.Uint32:
  81. fifos.Add(new ReadFifo<uint>(session, x.ControlSet) { Name = x.Name });
  82. break;
  83. case Datatype.Int64:
  84. fifos.Add(new ReadFifo<long>(session, x.ControlSet) { Name = x.Name });
  85. break;
  86. case Datatype.Uint64:
  87. fifos.Add(new ReadFifo<ulong>(session, x.ControlSet) { Name = x.Name });
  88. break;
  89. case Datatype.Float:
  90. fifos.Add(new ReadFifo<float>(session, x.ControlSet) { Name = x.Name });
  91. break;
  92. case Datatype.Double:
  93. fifos.Add(new ReadFifo<double>(session, x.ControlSet) { Name = x.Name });
  94. break;
  95. case Datatype.FXP:
  96. fifos.Add(new ReadFXPFifo(session, x.ControlSet,x.FxpTypeInfo, _FXPConvert)
  97. {
  98. Name = x.Name,
  99. });
  100. break;
  101. case Datatype.Array:
  102. break;
  103. }
  104. break;
  105. case "HostToTarget"://write
  106. switch (x.Datatype)
  107. {
  108. case Datatype.Boolean:
  109. fifos.Add(new WriteFifo<bool>(session, x.ControlSet) { Name = x.Name });
  110. break;
  111. case Datatype.Int8:
  112. fifos.Add(new WriteFifo<sbyte>(session, x.ControlSet) { Name = x.Name });
  113. break;
  114. case Datatype.Uint8:
  115. fifos.Add(new WriteFifo<byte>(session, x.ControlSet) { Name = x.Name });
  116. break;
  117. case Datatype.Int16:
  118. fifos.Add(new WriteFifo<short>(session, x.ControlSet) { Name = x.Name });
  119. break;
  120. case Datatype.Uint16:
  121. fifos.Add(new WriteFifo<ushort>(session, x.ControlSet) { Name = x.Name });
  122. break;
  123. case Datatype.Int32:
  124. fifos.Add(new WriteFifo<int>(session, x.ControlSet) { Name = x.Name });
  125. break;
  126. case Datatype.Uint32:
  127. fifos.Add(new WriteFifo<uint>(session, x.ControlSet) { Name = x.Name });
  128. break;
  129. case Datatype.Int64:
  130. fifos.Add(new WriteFifo<long>(session, x.ControlSet) { Name = x.Name });
  131. break;
  132. case Datatype.Uint64:
  133. fifos.Add(new WriteFifo<ulong>(session, x.ControlSet) { Name = x.Name });
  134. break;
  135. case Datatype.Float:
  136. fifos.Add(new WriteFifo<float>(session, x.ControlSet) { Name = x.Name });
  137. break;
  138. case Datatype.Double:
  139. fifos.Add(new WriteFifo<double>(session, x.ControlSet) { Name = x.Name });
  140. break;
  141. case Datatype.FXP:
  142. fifos.Add(new WriteFXPFifo(session, x.ControlSet, x.FxpTypeInfo, _FXPConvert) { Name = x.Name });
  143. break;
  144. case Datatype.Array:
  145. break;
  146. }
  147. break;
  148. }
  149. });
  150. }
  151. public Irq Irq { get; }
  152. public void Open(string bitfile, string resource, NiFpga_OpenAttribute attribute)
  153. {
  154. var lv = lvbitx.Parse.ParseFile(bitfile);
  155. InitProperies(lv.VI.Registers);
  156. InitFifo(lv.Project.DMA);
  157. session.Open(bitfile, lv.SignatureRegister, resource, attribute);
  158. }
  159. private void InitProperies(List<lvbitx.Register> registers)
  160. {
  161. if (registers == null || registers.Count == 0) return;
  162. foreach (var reg in registers)
  163. {
  164. switch (reg.Datatype)
  165. {
  166. case lvbitx.Datatype.Int16:
  167. properties.Add(new FPGAProperty<short>(session, reg.Offset, reg.Indicator)
  168. {
  169. Name= reg.Name,
  170. });
  171. break;
  172. case lvbitx.Datatype.Boolean:
  173. properties.Add(new FPGAProperty<bool>(session, reg.Offset, reg.Indicator)
  174. {
  175. Name = reg.Name,
  176. });
  177. break;
  178. case lvbitx.Datatype.Int8:
  179. properties.Add(new FPGAProperty<sbyte>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  180. break;
  181. case lvbitx.Datatype.Uint8:
  182. properties.Add(new FPGAProperty<byte>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  183. break;
  184. case lvbitx.Datatype.Uint16:
  185. properties.Add(new FPGAProperty<ushort>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  186. break;
  187. case lvbitx.Datatype.Int32:
  188. properties.Add(new FPGAProperty<int>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  189. break;
  190. case lvbitx.Datatype.Uint32:
  191. properties.Add(new FPGAProperty<uint>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  192. break;
  193. case lvbitx.Datatype.Int64:
  194. properties.Add(new FPGAProperty<long>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  195. break;
  196. case lvbitx.Datatype.Uint64:
  197. properties.Add(new FPGAProperty<ulong>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  198. break;
  199. case lvbitx.Datatype.Float:
  200. properties.Add(new FPGAProperty<float>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  201. break;
  202. case lvbitx.Datatype.Double:
  203. properties.Add(new FPGAProperty<double>(session, reg.Offset, reg.Indicator) { Name = reg.Name });
  204. break;
  205. case lvbitx.Datatype.FXP:
  206. properties.Add(new FPGAFXPProperty(session, reg.Offset, reg.FxpTypeInfo,_FXPConvert, reg.Indicator)
  207. {
  208. Name = reg.Name,
  209. });
  210. break;
  211. case lvbitx.Datatype.Array:
  212. switch (reg.ArrayValueType)
  213. {
  214. case lvbitx.Datatype.Boolean:
  215. properties.Add(new FPGAArrayProperty<bool>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  216. break;
  217. case lvbitx.Datatype.Int8:
  218. properties.Add(new FPGAArrayProperty<sbyte>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  219. break;
  220. case lvbitx.Datatype.Uint8:
  221. properties.Add(new FPGAArrayProperty<byte>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  222. break;
  223. case lvbitx.Datatype.Int16:
  224. properties.Add(new FPGAArrayProperty<short>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  225. break;
  226. case lvbitx.Datatype.Uint16:
  227. properties.Add(new FPGAArrayProperty<short>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  228. break;
  229. case lvbitx.Datatype.Int32:
  230. properties.Add(new FPGAArrayProperty<int>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  231. break;
  232. case lvbitx.Datatype.Uint32:
  233. properties.Add(new FPGAArrayProperty<uint>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  234. break;
  235. case lvbitx.Datatype.Int64:
  236. properties.Add(new FPGAArrayProperty<long>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  237. break;
  238. case lvbitx.Datatype.Uint64:
  239. properties.Add(new FPGAArrayProperty<ulong>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  240. break;
  241. case lvbitx.Datatype.Float:
  242. properties.Add(new FPGAArrayProperty<float>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  243. break;
  244. case lvbitx.Datatype.Double:
  245. properties.Add(new FPGAArrayProperty<double>(session, reg.Offset, reg.Size, reg.Indicator) { Name = reg.Name });
  246. break;
  247. case lvbitx.Datatype.FXP:
  248. properties.Add(new FPGAArrayFXPProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo,_FXPConvert) { Name = reg.Name });
  249. break;
  250. case lvbitx.Datatype.Array:
  251. break;
  252. }
  253. break;
  254. }
  255. }
  256. }
  257. public void Close()=>session.Close();
  258. public void Run()
  259. {
  260. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Run>()(session.Session, Interop.NiFpga_RunAttribute.NiFpga_RunAttribute_None));
  261. }
  262. public void Abort()
  263. {
  264. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Abort>()(session.Session));
  265. }
  266. public void Reset()
  267. {
  268. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Reset>()(session.Session));
  269. }
  270. public void Download()
  271. {
  272. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Download>()(session.Session));
  273. }
  274. }
  275. }