ShakerFpgaSourceGenerator.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. using Microsoft.CodeAnalysis;
  2. using NIFPGA.lvbitx;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. namespace ShakerFpga
  9. {
  10. [Generator(LanguageNames.CSharp)]
  11. internal class ShakerFpgaSourceGenerator : IIncrementalGenerator
  12. {
  13. public void Initialize(IncrementalGeneratorInitializationContext context)
  14. {
  15. context.RegisterPostInitializationOutput(c =>
  16. {
  17. var names = typeof(ShakerFpgaSourceGenerator).Assembly.GetManifestResourceNames().First(x => x.IndexOf(".lvbitx")>=0);
  18. NIFPGA.lvbitx.Bitfile bitfile = NIFPGA.lvbitx.Parse.ParseFile(typeof(ShakerFpgaSourceGenerator).Assembly.GetManifestResourceStream(names),names);
  19. string s = string.Join(",", bitfile.VI.Registers.Select(x => x.Name));
  20. StringBuilder stringBuilder = new StringBuilder();
  21. stringBuilder.AppendLine("/// <auto-generated>");
  22. stringBuilder.AppendLine("/// This code was generated by Source Generator.");
  23. stringBuilder.AppendLine("/// </auto-generated>");
  24. stringBuilder.AppendLine("using NIFPGA;");
  25. stringBuilder.AppendLine("using FxpConvert.Common;");
  26. stringBuilder.AppendLine("namespace ShakerFpga");
  27. stringBuilder.AppendLine("{");
  28. stringBuilder.AppendLine(" public sealed class ShakerFpga");
  29. stringBuilder.AppendLine(" {");
  30. stringBuilder.AppendLine(" private static ShakerFpga myFpga;");
  31. stringBuilder.AppendLine(" private readonly NIFPGA.FPGA fpga;");
  32. stringBuilder.AppendLine(" public string BitstreamMD5 => fpga.BitstreamMD5;");
  33. stringBuilder.AppendLine(" public string BitfileVersion => fpga.BitfileVersion;");
  34. stringBuilder.AppendLine(" public string SignatureRegister => fpga.SignatureRegister;");
  35. stringBuilder.AppendLine(" public string BitstreamVersion => fpga.BitstreamVersion;");
  36. stringBuilder.AppendLine(" public string SignatureNames => fpga.SignatureNames;");
  37. stringBuilder.AppendLine(" public bool LastError => fpga.Error;");
  38. stringBuilder.AppendLine(" public NiFpga_Status LastStatus => fpga.LastStatus;");
  39. stringBuilder.AppendLine(" public string LastMessage => fpga.Message;");
  40. stringBuilder.AppendLine(" private ShakerFpga(IFxpConvert convert)");
  41. stringBuilder.AppendLine(" {");
  42. stringBuilder.AppendLine(" fpga = new FPGA(convert);");
  43. stringBuilder.AppendLine(" }");
  44. stringBuilder.AppendLine(" static ShakerFpga()");
  45. stringBuilder.AppendLine(" {");
  46. stringBuilder.AppendLine(" }");
  47. stringBuilder.AppendLine(" public Irq Irq => fpga.Irq;");
  48. stringBuilder.AppendLine(" public void Open(string bitfile, string resource, NiFpga_OpenAttribute attribute) => fpga.Open(bitfile, resource, attribute);");
  49. stringBuilder.AppendLine(" public void Close() => fpga.Close();");
  50. stringBuilder.AppendLine(" public void Run() => fpga.Run();");
  51. stringBuilder.AppendLine(" public void Download() => fpga.Download();");
  52. stringBuilder.AppendLine(" public void FpgaFinalize() => fpga.FpgaFinalize();");
  53. stringBuilder.AppendLine(" public void Abort() => fpga.Abort();");
  54. stringBuilder.AppendLine(" public void Reset() => fpga.Reset();");
  55. stringBuilder.AppendLine(" public static ShakerFpga CreateFpga(IFxpConvert convert)");
  56. stringBuilder.AppendLine(" {");
  57. stringBuilder.AppendLine(" myFpga ??= new ShakerFpga(convert);");
  58. stringBuilder.AppendLine(" return myFpga;");
  59. stringBuilder.AppendLine(" }");
  60. stringBuilder.AppendLine(" public static ShakerFpga Instance");
  61. stringBuilder.AppendLine(" {");
  62. stringBuilder.AppendLine(" get");
  63. stringBuilder.AppendLine(" {");
  64. stringBuilder.AppendLine(" if (myFpga == null)");
  65. stringBuilder.AppendLine(" {");
  66. stringBuilder.AppendLine(" throw new Exception(\"must call first CreateFpga\");");
  67. stringBuilder.AppendLine(" }");
  68. stringBuilder.AppendLine(" return myFpga;");
  69. stringBuilder.AppendLine(" }");
  70. stringBuilder.AppendLine(" }");
  71. stringBuilder.AppendLine(" #region 寄存器定义");
  72. bitfile.VI.Registers.ForEach(x => GeneratorRegister(x, stringBuilder));
  73. stringBuilder.AppendLine(" #endregion");
  74. stringBuilder.AppendLine(" #region Fifo定义");
  75. bitfile.Project.DMA.ForEach(x => GeneratorFifo(x, stringBuilder));
  76. stringBuilder.AppendLine(" #endregion");
  77. stringBuilder.AppendLine(" }");
  78. stringBuilder.AppendLine("}");
  79. c.AddSource("ShakerFpga.g.cs", stringBuilder.ToString());
  80. });
  81. }
  82. private void GeneratorRegister(Register register, StringBuilder stringBuilder)
  83. {
  84. string protype = GetProType(register);
  85. string proname = $"{register.Name.Split('_')[0]}";
  86. proname = RemovePropertySpecialcharacters(proname);
  87. stringBuilder.AppendLine($" private {protype} _{proname};");
  88. stringBuilder.AppendLine($" /// <summary>");
  89. stringBuilder.AppendLine($" /// {register.Name}");
  90. stringBuilder.AppendLine($" /// </summary>");
  91. stringBuilder.AppendLine($" public {protype} {proname}");
  92. stringBuilder.AppendLine(" {");
  93. stringBuilder.AppendLine(" get");
  94. stringBuilder.AppendLine(" {");
  95. stringBuilder.AppendLine($" if(_" + proname + "==null)");
  96. stringBuilder.AppendLine(" {");
  97. stringBuilder.AppendLine($" _" + proname + $"=({protype})fpga.Properties[\"{register.Name}\"];");
  98. stringBuilder.AppendLine(" }");
  99. stringBuilder.AppendLine($" return _" + proname + ";");
  100. stringBuilder.AppendLine(" }");
  101. stringBuilder.AppendLine(" }");
  102. }
  103. private void GeneratorFifo(DMA dma,StringBuilder stringBuilder)
  104. {
  105. string protype = GetFifoType(dma);
  106. string proname = $"{dma.Name.Split('_')[0]}";
  107. proname = RemovePropertySpecialcharacters(proname);
  108. stringBuilder.AppendLine($" private {protype} _{proname};");
  109. stringBuilder.AppendLine($" /// <summary>");
  110. stringBuilder.AppendLine($" /// {dma.Name}");
  111. stringBuilder.AppendLine($" /// </summary>");
  112. stringBuilder.AppendLine($" public {protype} {proname}");
  113. stringBuilder.AppendLine(" {");
  114. stringBuilder.AppendLine(" get");
  115. stringBuilder.AppendLine(" {");
  116. stringBuilder.AppendLine($" if(_" + proname + "==null)");
  117. stringBuilder.AppendLine(" {");
  118. stringBuilder.AppendLine($" _" + proname + $"=({protype})fpga.Fifos[\"{dma.Name}\"];");
  119. stringBuilder.AppendLine(" }");
  120. stringBuilder.AppendLine($" return _" + proname + ";");
  121. stringBuilder.AppendLine(" }");
  122. stringBuilder.AppendLine(" }");
  123. }
  124. private string GetFifoType(DMA dma)
  125. {
  126. string direction = dma.Direction == "TargetToHost" ? "ReadFifo" : "WriteFifo";
  127. string protype = string.Empty;
  128. switch (dma.Datatype)
  129. {
  130. case NIFPGA.lvbitx.Datatype.Boolean:
  131. protype = $"{direction}<bool>";
  132. break;
  133. case NIFPGA.lvbitx.Datatype.Int8:
  134. protype = $"{direction}<sbyte>";
  135. break;
  136. case NIFPGA.lvbitx.Datatype.Double:
  137. protype = $"{direction}<double>";
  138. break;
  139. case NIFPGA.lvbitx.Datatype.Float:
  140. protype = $"{direction}<float>";
  141. break;
  142. case NIFPGA.lvbitx.Datatype.FXP:
  143. protype = $"{(dma.Direction == "TargetToHost" ? "ReadFXPFifo" : "WriteFXPFifo")}";
  144. break;
  145. case NIFPGA.lvbitx.Datatype.Int16:
  146. protype = $"{direction}<short>";
  147. break;
  148. case NIFPGA.lvbitx.Datatype.Int32:
  149. protype = $"{direction}<int>";
  150. break;
  151. case NIFPGA.lvbitx.Datatype.Int64:
  152. protype = $"{direction}<long>";
  153. break;
  154. case NIFPGA.lvbitx.Datatype.Uint16:
  155. protype = $"{direction}<ushort>";
  156. break;
  157. case NIFPGA.lvbitx.Datatype.Uint32:
  158. protype = $"{direction}<uint>";
  159. break;
  160. case NIFPGA.lvbitx.Datatype.Uint64:
  161. protype = $"{direction}<ulong>";
  162. break;
  163. case NIFPGA.lvbitx.Datatype.Uint8:
  164. protype = $"{direction}<byte>";
  165. break;
  166. default:
  167. throw new Exception("类型错误");
  168. }
  169. return protype;
  170. }
  171. private string RemovePropertySpecialcharacters(string s)
  172. {
  173. string proname = Regex.Replace(s,@"\((.+?)\)","", RegexOptions.IgnoreCase).Replace("(", "_").Replace(")", "_").Replace("/", "_").Replace("__", "_").Trim('_');
  174. return char.ToUpper(proname[0]) + proname.Substring(1);
  175. }
  176. private string GetProType(Register register)
  177. {
  178. string value = "";
  179. switch (register.Datatype)
  180. {
  181. case NIFPGA.lvbitx.Datatype.Boolean:
  182. if(!register.Indicator)
  183. {
  184. value = "FPGAWriteProperty<bool>";
  185. }
  186. else
  187. {
  188. value = "FPGAReadProperty<bool>";
  189. }
  190. break;
  191. case NIFPGA.lvbitx.Datatype.Int8:
  192. if (!register.Indicator)
  193. {
  194. value = "FPGAWriteProperty<sbyte>";
  195. }
  196. else
  197. {
  198. value = "FPGAReadProperty<sbyte>";
  199. }
  200. break;
  201. case NIFPGA.lvbitx.Datatype.Uint8:
  202. if (!register.Indicator)
  203. {
  204. value = "FPGAWriteProperty<byte>";
  205. }
  206. else
  207. {
  208. value = "FPGAReadProperty<byte>";
  209. }
  210. break;
  211. case NIFPGA.lvbitx.Datatype.Int16:
  212. if (!register.Indicator)
  213. {
  214. value = "FPGAWriteProperty<short>";
  215. }
  216. else
  217. {
  218. value = "FPGAReadProperty<short>";
  219. }
  220. break;
  221. case NIFPGA.lvbitx.Datatype.Uint16:
  222. if (!register.Indicator)
  223. {
  224. value = "FPGAWriteProperty<ushort>";
  225. }
  226. else
  227. {
  228. value = "FPGAReadProperty<ushort>";
  229. }
  230. break;
  231. case NIFPGA.lvbitx.Datatype.Int32:
  232. if (!register.Indicator)
  233. {
  234. value = "FPGAWriteProperty<int>";
  235. }
  236. else
  237. {
  238. value = "FPGAReadProperty<int>";
  239. }
  240. break;
  241. case NIFPGA.lvbitx.Datatype.Uint32:
  242. if (!register.Indicator)
  243. {
  244. value = "FPGAWriteProperty<uint>";
  245. }
  246. else
  247. {
  248. value = "FPGAReadProperty<uint>";
  249. }
  250. break;
  251. case NIFPGA.lvbitx.Datatype.Int64:
  252. if (!register.Indicator)
  253. {
  254. value = "FPGAWriteProperty<long>";
  255. }
  256. else
  257. {
  258. value = "FPGAReadProperty<long>";
  259. }
  260. break;
  261. case NIFPGA.lvbitx.Datatype.Uint64:
  262. if (!register.Indicator)
  263. {
  264. value = "FPGAWriteProperty<ulong>";
  265. }
  266. else
  267. {
  268. value = "FPGAReadProperty<ulong>";
  269. }
  270. break;
  271. case NIFPGA.lvbitx.Datatype.Float:
  272. if (!register.Indicator)
  273. {
  274. value = "FPGAWriteProperty<float>";
  275. }
  276. else
  277. {
  278. value = "FPGAReadProperty<float>";
  279. }
  280. break;
  281. case NIFPGA.lvbitx.Datatype.Double:
  282. if (!register.Indicator)
  283. {
  284. value = "FPGAWriteProperty<double>";
  285. }
  286. else
  287. {
  288. value = "FPGAReadProperty<double>";
  289. }
  290. break;
  291. case NIFPGA.lvbitx.Datatype.FXP:
  292. if(!register.Indicator)
  293. {
  294. value = "FPGAFXPWriteProperty";
  295. }
  296. else
  297. {
  298. value = "FPGAFXPReadProperty";
  299. }
  300. break;
  301. case NIFPGA.lvbitx.Datatype.Array:
  302. switch (register.ArrayValueType)
  303. {
  304. case NIFPGA.lvbitx.Datatype.Boolean:
  305. if(!register.Indicator)
  306. {
  307. value = "FPGAArrayWriteProperty<bool>";
  308. }
  309. else
  310. {
  311. value = "FPGAArrayReadProperty<bool>";
  312. }
  313. break;
  314. case NIFPGA.lvbitx.Datatype.Int8:
  315. if (!register.Indicator)
  316. {
  317. value = "FPGAArrayWriteProperty<sbyte>";
  318. }
  319. else
  320. {
  321. value = "FPGAArrayReadProperty<sbyte>";
  322. }
  323. break;
  324. case NIFPGA.lvbitx.Datatype.Uint8:
  325. if (!register.Indicator)
  326. {
  327. value = "FPGAArrayWriteProperty<byte>";
  328. }
  329. else
  330. {
  331. value = "FPGAArrayReadProperty<byte>";
  332. }
  333. break;
  334. case NIFPGA.lvbitx.Datatype.Int16:
  335. if (!register.Indicator)
  336. {
  337. value = "FPGAArrayWriteProperty<short>";
  338. }
  339. else
  340. {
  341. value = "FPGAArrayReadProperty<short>";
  342. }
  343. break;
  344. case NIFPGA.lvbitx.Datatype.Uint16:
  345. if (!register.Indicator)
  346. {
  347. value = "FPGAArrayWriteProperty<ushort>";
  348. }
  349. else
  350. {
  351. value = "FPGAArrayReadProperty<ushort>";
  352. }
  353. break;
  354. case NIFPGA.lvbitx.Datatype.Int32:
  355. if (!register.Indicator)
  356. {
  357. value = "FPGAArrayWriteProperty<int>";
  358. }
  359. else
  360. {
  361. value = "FPGAArrayReadProperty<int>";
  362. }
  363. break;
  364. case NIFPGA.lvbitx.Datatype.Uint32:
  365. if (!register.Indicator)
  366. {
  367. value = "FPGAArrayWriteProperty<uint>";
  368. }
  369. else
  370. {
  371. value = "FPGAArrayReadProperty<uint>";
  372. }
  373. break;
  374. case NIFPGA.lvbitx.Datatype.Int64:
  375. if (!register.Indicator)
  376. {
  377. value = "FPGAArrayWriteProperty<long>";
  378. }
  379. else
  380. {
  381. value = "FPGAArrayReadProperty<long>";
  382. }
  383. break;
  384. case NIFPGA.lvbitx.Datatype.Uint64:
  385. if (!register.Indicator)
  386. {
  387. value = "FPGAArrayWriteProperty<ulong>";
  388. }
  389. else
  390. {
  391. value = "FPGAArrayReadProperty<ulong>";
  392. }
  393. break;
  394. case NIFPGA.lvbitx.Datatype.Float:
  395. if (!register.Indicator)
  396. {
  397. value = "FPGAArrayWriteProperty<float>";
  398. }
  399. else
  400. {
  401. value = "FPGAArrayReadProperty<float>";
  402. }
  403. break;
  404. case NIFPGA.lvbitx.Datatype.Double:
  405. if (!register.Indicator)
  406. {
  407. value = "FPGAArrayWriteProperty<double>";
  408. }
  409. else
  410. {
  411. value = "FPGAArrayReadProperty<double>";
  412. }
  413. break;
  414. case NIFPGA.lvbitx.Datatype.FXP:
  415. if (!register.Indicator)
  416. {
  417. value = "FPGAArrayFXPWriteProperty";
  418. }
  419. else
  420. {
  421. value = "FPGAArrayFXPReadProperty";
  422. }
  423. break;
  424. }
  425. break;
  426. }
  427. return value;
  428. }
  429. }
  430. }