FPGA.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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. public string BitstreamMD5 { get; private set; } = string.Empty;
  15. public string BitfileVersion { get; private set; } = string.Empty;
  16. public string SignatureRegister { get; private set; } = string.Empty;
  17. public string BitstreamVersion { get; private set; } = string.Empty;
  18. public string SignatureNames { get; private set; } = string.Empty;
  19. private List<Fifo> fifos= new List<Fifo>();
  20. private IFxpConvert _FXPConvert;
  21. private List<FPGABaseProperty> properties= new List<FPGABaseProperty>();
  22. public IReadOnlyDictionary<String,Fifo> Fifos => fifos.ToDictionary(x=>x.Name);
  23. public IReadOnlyDictionary<String,FPGABaseProperty> Properties=> properties.ToDictionary(x=>x.Name);
  24. private FPGASession session;
  25. public Boolean Error=> session.Error;
  26. public NiFpga_Status LastStatus=> session.LastStatus;
  27. public string Message=>session.Message;
  28. public FPGA(IFxpConvert convert)
  29. {
  30. _FXPConvert = convert;
  31. session = new FPGASession();
  32. Irq = new Irq(session);
  33. }
  34. public T CreateProperty<T>(string name) where T :FPGABaseProperty
  35. {
  36. var pro = properties.FirstOrDefault(x => x.Name == name);
  37. if (pro == null) throw new Exception($"Property {name} not found");
  38. return (T)pro;
  39. }
  40. public T CreateFifo<T>(string name) where T:Fifo
  41. {
  42. var fifo = fifos.FirstOrDefault(x => x.Name == name);
  43. if (fifo == null) throw new Exception($"Fifo {name} not found");
  44. return (T)fifo;
  45. }
  46. public void Parse(string path)
  47. {
  48. var val = lvbitx.Parse.ParseFile(path);
  49. InitProperies(val.VI.Registers);
  50. InitFifo(val.Project.DMA);
  51. }
  52. private void InitFifo(List<DMA> dma)
  53. {
  54. if (dma == null || dma.Count == 0) return;
  55. dma.ForEach(x =>
  56. {
  57. switch(x.Direction)
  58. {
  59. case "TargetToHost"://read
  60. switch (x.Datatype)
  61. {
  62. case Datatype.Boolean:
  63. fifos.Add(new ReadFifo<bool>(session, x.ControlSet)
  64. {
  65. Name = x.Name,
  66. });
  67. break;
  68. case Datatype.Int8:
  69. fifos.Add(new ReadFifo<sbyte>(session, x.ControlSet)
  70. {
  71. Name = x.Name,
  72. });
  73. break;
  74. case Datatype.Uint8:
  75. fifos.Add(new ReadFifo<byte>(session, x.ControlSet) { Name = x.Name });
  76. break;
  77. case Datatype.Int16:
  78. fifos.Add(new ReadFifo<short>(session, x.ControlSet) { Name = x.Name });
  79. break;
  80. case Datatype.Uint16:
  81. fifos.Add(new ReadFifo<ushort>(session, x.ControlSet) { Name = x.Name });
  82. break;
  83. case Datatype.Int32:
  84. fifos.Add(new ReadFifo<int>(session, x.ControlSet) { Name = x.Name });
  85. break;
  86. case Datatype.Uint32:
  87. fifos.Add(new ReadFifo<uint>(session, x.ControlSet) { Name = x.Name });
  88. break;
  89. case Datatype.Int64:
  90. fifos.Add(new ReadFifo<long>(session, x.ControlSet) { Name = x.Name });
  91. break;
  92. case Datatype.Uint64:
  93. fifos.Add(new ReadFifo<ulong>(session, x.ControlSet) { Name = x.Name });
  94. break;
  95. case Datatype.Float:
  96. fifos.Add(new ReadFifo<float>(session, x.ControlSet) { Name = x.Name });
  97. break;
  98. case Datatype.Double:
  99. fifos.Add(new ReadFifo<double>(session, x.ControlSet) { Name = x.Name });
  100. break;
  101. case Datatype.FXP:
  102. fifos.Add(new ReadFXPFifo(session, x.ControlSet,x.FxpTypeInfo, _FXPConvert)
  103. {
  104. Name = x.Name,
  105. });
  106. break;
  107. case Datatype.Array:
  108. break;
  109. }
  110. break;
  111. case "HostToTarget"://write
  112. switch (x.Datatype)
  113. {
  114. case Datatype.Boolean:
  115. fifos.Add(new WriteFifo<bool>(session, x.ControlSet) { Name = x.Name });
  116. break;
  117. case Datatype.Int8:
  118. fifos.Add(new WriteFifo<sbyte>(session, x.ControlSet) { Name = x.Name });
  119. break;
  120. case Datatype.Uint8:
  121. fifos.Add(new WriteFifo<byte>(session, x.ControlSet) { Name = x.Name });
  122. break;
  123. case Datatype.Int16:
  124. fifos.Add(new WriteFifo<short>(session, x.ControlSet) { Name = x.Name });
  125. break;
  126. case Datatype.Uint16:
  127. fifos.Add(new WriteFifo<ushort>(session, x.ControlSet) { Name = x.Name });
  128. break;
  129. case Datatype.Int32:
  130. fifos.Add(new WriteFifo<int>(session, x.ControlSet) { Name = x.Name });
  131. break;
  132. case Datatype.Uint32:
  133. fifos.Add(new WriteFifo<uint>(session, x.ControlSet) { Name = x.Name });
  134. break;
  135. case Datatype.Int64:
  136. fifos.Add(new WriteFifo<long>(session, x.ControlSet) { Name = x.Name });
  137. break;
  138. case Datatype.Uint64:
  139. fifos.Add(new WriteFifo<ulong>(session, x.ControlSet) { Name = x.Name });
  140. break;
  141. case Datatype.Float:
  142. fifos.Add(new WriteFifo<float>(session, x.ControlSet) { Name = x.Name });
  143. break;
  144. case Datatype.Double:
  145. fifos.Add(new WriteFifo<double>(session, x.ControlSet) { Name = x.Name });
  146. break;
  147. case Datatype.FXP:
  148. fifos.Add(new WriteFXPFifo(session, x.ControlSet, x.FxpTypeInfo, _FXPConvert) { Name = x.Name });
  149. break;
  150. case Datatype.Array:
  151. break;
  152. }
  153. break;
  154. }
  155. });
  156. }
  157. public Irq Irq { get; }
  158. public void Open(string bitfile, string resource, NiFpga_OpenAttribute attribute)
  159. {
  160. var lv = lvbitx.Parse.ParseFile(bitfile);
  161. BitfileVersion = lv.BitfileVersion;
  162. SignatureNames = lv.SignatureNames;
  163. SignatureRegister= lv.SignatureRegister;
  164. BitstreamMD5 = lv.BitstreamMD5;
  165. BitstreamVersion = lv.BitstreamVersion;
  166. InitProperies(lv.VI.Registers);
  167. InitFifo(lv.Project.DMA);
  168. session.Open(bitfile, lv.SignatureRegister, resource, attribute);
  169. var indicator = properties.Select(x => x.Indicator).ToArray();
  170. }
  171. private void InitProperies(List<lvbitx.Register> registers)
  172. {
  173. if (registers == null || registers.Count == 0) return;
  174. foreach (var reg in registers)
  175. {
  176. switch (reg.Datatype)
  177. {
  178. case lvbitx.Datatype.Int16:
  179. if (!reg.Indicator)
  180. {
  181. properties.Add(new FPGAWriteProperty<short>(session, reg.Offset)
  182. {
  183. Name = reg.Name,
  184. SizeInBits = reg.SizeInBits,
  185. });
  186. }
  187. else
  188. {
  189. properties.Add(new FPGAReadProperty<short>(session, reg.Offset)
  190. {
  191. Name = reg.Name,
  192. SizeInBits = reg.SizeInBits,
  193. });
  194. }
  195. break;
  196. case lvbitx.Datatype.Boolean:
  197. if (!reg.Indicator)
  198. {
  199. properties.Add(new FPGAWriteProperty<bool>(session, reg.Offset)
  200. {
  201. Name = reg.Name,
  202. SizeInBits = reg.SizeInBits,
  203. });
  204. }
  205. else
  206. {
  207. properties.Add(new FPGAReadProperty<bool>(session, reg.Offset)
  208. {
  209. Name = reg.Name,
  210. SizeInBits = reg.SizeInBits,
  211. });
  212. }
  213. break;
  214. case lvbitx.Datatype.Int8:
  215. if (!reg.Indicator)
  216. {
  217. properties.Add(new FPGAWriteProperty<sbyte>(session, reg.Offset)
  218. {
  219. Name = reg.Name,
  220. SizeInBits = reg.SizeInBits,
  221. });
  222. }
  223. else
  224. {
  225. properties.Add(new FPGAReadProperty<sbyte>(session, reg.Offset)
  226. {
  227. Name = reg.Name,
  228. SizeInBits = reg.SizeInBits,
  229. });
  230. }
  231. break;
  232. case lvbitx.Datatype.Uint8:
  233. if (!reg.Indicator)
  234. {
  235. properties.Add(new FPGAWriteProperty<byte>(session, reg.Offset)
  236. {
  237. Name = reg.Name,
  238. SizeInBits = reg.SizeInBits,
  239. });
  240. }
  241. else
  242. {
  243. properties.Add(new FPGAReadProperty<byte>(session, reg.Offset)
  244. {
  245. Name = reg.Name,
  246. SizeInBits = reg.SizeInBits,
  247. });
  248. }
  249. break;
  250. case lvbitx.Datatype.Uint16:
  251. if (!reg.Indicator)
  252. {
  253. properties.Add(new FPGAWriteProperty<ushort>(session, reg.Offset)
  254. {
  255. Name = reg.Name,
  256. SizeInBits = reg.SizeInBits,
  257. });
  258. }
  259. else
  260. {
  261. properties.Add(new FPGAReadProperty<ushort>(session, reg.Offset)
  262. {
  263. Name = reg.Name,
  264. SizeInBits = reg.SizeInBits,
  265. });
  266. }
  267. break;
  268. case lvbitx.Datatype.Int32:
  269. if (!reg.Indicator)
  270. {
  271. properties.Add(new FPGAWriteProperty<int>(session, reg.Offset)
  272. {
  273. Name = reg.Name,
  274. SizeInBits = reg.SizeInBits,
  275. });
  276. }
  277. else
  278. {
  279. properties.Add(new FPGAReadProperty<int>(session, reg.Offset)
  280. {
  281. Name = reg.Name,
  282. SizeInBits = reg.SizeInBits,
  283. });
  284. }
  285. break;
  286. case lvbitx.Datatype.Uint32:
  287. if (!reg.Indicator)
  288. {
  289. properties.Add(new FPGAWriteProperty<uint>(session, reg.Offset)
  290. {
  291. Name = reg.Name,
  292. SizeInBits = reg.SizeInBits,
  293. });
  294. }
  295. else
  296. {
  297. properties.Add(new FPGAReadProperty<uint>(session, reg.Offset)
  298. {
  299. Name = reg.Name,
  300. SizeInBits = reg.SizeInBits,
  301. });
  302. }
  303. break;
  304. case lvbitx.Datatype.Int64:
  305. if (!reg.Indicator)
  306. {
  307. properties.Add(new FPGAWriteProperty<long>(session, reg.Offset)
  308. {
  309. Name = reg.Name,
  310. SizeInBits = reg.SizeInBits,
  311. });
  312. }
  313. else
  314. {
  315. properties.Add(new FPGAReadProperty<long>(session, reg.Offset)
  316. {
  317. Name = reg.Name,
  318. SizeInBits = reg.SizeInBits,
  319. });
  320. }
  321. break;
  322. case lvbitx.Datatype.Uint64:
  323. if (!reg.Indicator)
  324. {
  325. properties.Add(new FPGAWriteProperty<ulong>(session, reg.Offset)
  326. {
  327. Name = reg.Name,
  328. SizeInBits = reg.SizeInBits,
  329. });
  330. }
  331. else
  332. {
  333. properties.Add(new FPGAReadProperty<ulong>(session, reg.Offset)
  334. {
  335. Name = reg.Name,
  336. SizeInBits = reg.SizeInBits,
  337. });
  338. }
  339. break;
  340. case lvbitx.Datatype.Float:
  341. if (!reg.Indicator)
  342. {
  343. properties.Add(new FPGAWriteProperty<float>(session, reg.Offset)
  344. {
  345. Name = reg.Name,
  346. SizeInBits = reg.SizeInBits,
  347. });
  348. }
  349. else
  350. {
  351. properties.Add(new FPGAReadProperty<float>(session, reg.Offset)
  352. {
  353. Name = reg.Name,
  354. SizeInBits = reg.SizeInBits,
  355. });
  356. }
  357. break;
  358. case lvbitx.Datatype.Double:
  359. if (!reg.Indicator)
  360. {
  361. properties.Add(new FPGAWriteProperty<double>(session, reg.Offset)
  362. {
  363. Name = reg.Name,
  364. SizeInBits = reg.SizeInBits,
  365. });
  366. }
  367. else
  368. {
  369. properties.Add(new FPGAReadProperty<double>(session, reg.Offset)
  370. {
  371. Name = reg.Name,
  372. SizeInBits = reg.SizeInBits,
  373. });
  374. }
  375. break;
  376. case lvbitx.Datatype.FXP:
  377. if (!reg.Indicator)
  378. {
  379. properties.Add(new FPGAFXPWriteProperty(session, reg.Offset, reg.FxpTypeInfo, _FXPConvert)
  380. {
  381. Name = reg.Name,
  382. SizeInBits = reg.SizeInBits,
  383. });
  384. }
  385. else
  386. {
  387. properties.Add(new FPGAFXPReadProperty(session, reg.Offset, reg.FxpTypeInfo, _FXPConvert)
  388. {
  389. Name = reg.Name,
  390. SizeInBits = reg.SizeInBits,
  391. });
  392. }
  393. break;
  394. case lvbitx.Datatype.Array:
  395. switch (reg.ArrayValueType)
  396. {
  397. case lvbitx.Datatype.Boolean:
  398. if (!reg.Indicator)
  399. {
  400. properties.Add(new FPGAArrayWriteProperty<bool>(session, reg.Offset, reg.Size)
  401. {
  402. Name = reg.Name,
  403. SizeInBits = reg.SizeInBits,
  404. });
  405. }
  406. else
  407. {
  408. properties.Add(new FPGAArrayReadProperty<bool>(session, reg.Offset, reg.Size)
  409. {
  410. Name = reg.Name,
  411. SizeInBits = reg.SizeInBits,
  412. });
  413. }
  414. break;
  415. case lvbitx.Datatype.Int8:
  416. if (!reg.Indicator)
  417. {
  418. properties.Add(new FPGAArrayWriteProperty<sbyte>(session, reg.Offset, reg.Size)
  419. {
  420. Name = reg.Name,
  421. SizeInBits = reg.SizeInBits,
  422. });
  423. }
  424. else
  425. {
  426. properties.Add(new FPGAArrayReadProperty<sbyte>(session, reg.Offset, reg.Size)
  427. {
  428. Name = reg.Name,
  429. SizeInBits = reg.SizeInBits,
  430. });
  431. }
  432. break;
  433. case lvbitx.Datatype.Uint8:
  434. if (!reg.Indicator)
  435. {
  436. properties.Add(new FPGAArrayWriteProperty<byte>(session, reg.Offset, reg.Size)
  437. {
  438. Name = reg.Name,
  439. SizeInBits = reg.SizeInBits,
  440. });
  441. }
  442. else
  443. {
  444. properties.Add(new FPGAArrayReadProperty<byte>(session, reg.Offset, reg.Size)
  445. {
  446. Name = reg.Name,
  447. SizeInBits = reg.SizeInBits,
  448. });
  449. }
  450. break;
  451. case lvbitx.Datatype.Int16:
  452. if (!reg.Indicator)
  453. {
  454. properties.Add(new FPGAArrayWriteProperty<short>(session, reg.Offset, reg.Size)
  455. {
  456. Name = reg.Name,
  457. SizeInBits = reg.SizeInBits,
  458. });
  459. }
  460. else
  461. {
  462. properties.Add(new FPGAArrayReadProperty<short>(session, reg.Offset, reg.Size)
  463. {
  464. Name = reg.Name,
  465. SizeInBits = reg.SizeInBits,
  466. });
  467. }
  468. break;
  469. case lvbitx.Datatype.Uint16:
  470. if (!reg.Indicator)
  471. {
  472. properties.Add(new FPGAArrayWriteProperty<ushort>(session, reg.Offset, reg.Size)
  473. {
  474. Name = reg.Name,
  475. SizeInBits = reg.SizeInBits,
  476. });
  477. }
  478. else
  479. {
  480. properties.Add(new FPGAArrayReadProperty<ushort>(session, reg.Offset, reg.Size)
  481. {
  482. Name = reg.Name,
  483. SizeInBits = reg.SizeInBits,
  484. });
  485. }
  486. break;
  487. case lvbitx.Datatype.Int32:
  488. if (!reg.Indicator)
  489. {
  490. properties.Add(new FPGAArrayWriteProperty<int>(session, reg.Offset, reg.Size)
  491. {
  492. Name = reg.Name,
  493. SizeInBits = reg.SizeInBits,
  494. });
  495. }
  496. else
  497. {
  498. properties.Add(new FPGAArrayReadProperty<int>(session, reg.Offset, reg.Size)
  499. {
  500. Name = reg.Name,
  501. SizeInBits = reg.SizeInBits,
  502. });
  503. }
  504. break;
  505. case lvbitx.Datatype.Uint32:
  506. if (!reg.Indicator)
  507. {
  508. properties.Add(new FPGAArrayWriteProperty<uint>(session, reg.Offset, reg.Size)
  509. {
  510. Name = reg.Name,
  511. SizeInBits = reg.SizeInBits,
  512. });
  513. }
  514. else
  515. {
  516. properties.Add(new FPGAArrayReadProperty<uint>(session, reg.Offset, reg.Size)
  517. {
  518. Name = reg.Name,
  519. SizeInBits = reg.SizeInBits,
  520. });
  521. }
  522. break;
  523. case lvbitx.Datatype.Int64:
  524. if (!reg.Indicator)
  525. {
  526. properties.Add(new FPGAArrayWriteProperty<long>(session, reg.Offset, reg.Size)
  527. {
  528. Name = reg.Name,
  529. SizeInBits = reg.SizeInBits,
  530. });
  531. }
  532. else
  533. {
  534. properties.Add(new FPGAArrayReadProperty<long>(session, reg.Offset, reg.Size)
  535. {
  536. Name = reg.Name,
  537. SizeInBits = reg.SizeInBits,
  538. });
  539. }
  540. break;
  541. case lvbitx.Datatype.Uint64:
  542. if (!reg.Indicator)
  543. {
  544. properties.Add(new FPGAArrayWriteProperty<ulong>(session, reg.Offset, reg.Size)
  545. {
  546. Name = reg.Name,
  547. SizeInBits = reg.SizeInBits,
  548. });
  549. }
  550. else
  551. {
  552. properties.Add(new FPGAArrayReadProperty<ulong>(session, reg.Offset, reg.Size)
  553. {
  554. Name = reg.Name,
  555. SizeInBits = reg.SizeInBits,
  556. });
  557. }
  558. break;
  559. case lvbitx.Datatype.Float:
  560. if (!reg.Indicator)
  561. {
  562. properties.Add(new FPGAArrayWriteProperty<float>(session, reg.Offset, reg.Size)
  563. {
  564. Name = reg.Name,
  565. SizeInBits = reg.SizeInBits,
  566. });
  567. }
  568. else
  569. {
  570. properties.Add(new FPGAArrayReadProperty<float>(session, reg.Offset, reg.Size)
  571. {
  572. Name = reg.Name,
  573. SizeInBits = reg.SizeInBits,
  574. });
  575. }
  576. break;
  577. case lvbitx.Datatype.Double:
  578. if (!reg.Indicator)
  579. {
  580. properties.Add(new FPGAArrayWriteProperty<double>(session, reg.Offset, reg.Size)
  581. {
  582. Name = reg.Name,
  583. SizeInBits = reg.SizeInBits,
  584. });
  585. }
  586. else
  587. {
  588. properties.Add(new FPGAArrayReadProperty<double>(session, reg.Offset, reg.Size)
  589. {
  590. Name = reg.Name,
  591. SizeInBits = reg.SizeInBits,
  592. });
  593. }
  594. break;
  595. case lvbitx.Datatype.FXP:
  596. if (!reg.Indicator)
  597. {
  598. properties.Add(new FPGAArrayFXPWriteProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert)
  599. {
  600. Name = reg.Name,
  601. SizeInBits = reg.SizeInBits,
  602. });
  603. }
  604. else
  605. {
  606. properties.Add(new FPGAArrayFXPReadProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert)
  607. {
  608. Name = reg.Name,
  609. SizeInBits = reg.SizeInBits,
  610. });
  611. }
  612. break;
  613. case lvbitx.Datatype.Array:
  614. break;
  615. }
  616. break;
  617. }
  618. }
  619. }
  620. public void Close()=>session.Close();
  621. public void Run()
  622. {
  623. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Run>()(session.Session, Interop.NiFpga_RunAttribute.NiFpga_RunAttribute_None));
  624. }
  625. public void Abort()
  626. {
  627. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Abort>()(session.Session));
  628. }
  629. public void Reset()
  630. {
  631. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Reset>()(session.Session));
  632. }
  633. public void Download()
  634. {
  635. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Download>()(session.Session));
  636. }
  637. public void FpgaFinalize()
  638. {
  639. session.CheckResult(session.GetDelegate<Interop.NiFpgaDll_Finalize>()());
  640. }
  641. }
  642. }