ShakerFpgaSourceGenerator.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  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($" ///<para> {register.Name}{(register.Datatype == Datatype.Array?$",数组长度为:{register.Size}":"")}</para>");
  90. if(register.Datatype == Datatype.FXP || register.ArrayValueType == Datatype.FXP)
  91. {
  92. stringBuilder.AppendLine($" ///<para> 数据类型:定点数</para>");
  93. stringBuilder.AppendLine($" ///<para> 最大值:{register.FxpTypeInfo.Max}</para>");
  94. stringBuilder.AppendLine($" ///<para> 最小值:{register.FxpTypeInfo.Min}</para>");
  95. stringBuilder.AppendLine($" ///<para> 最小分辨率:{register.FxpTypeInfo.Delta}</para>");
  96. stringBuilder.AppendLine($" ///<para> 字长:{register.FxpTypeInfo.wordLength}</para>");
  97. stringBuilder.AppendLine($" ///<para> 整数字长:{register.FxpTypeInfo.integerWordLength}</para>");
  98. stringBuilder.AppendLine($" ///<para> {(register.FxpTypeInfo.isSigned?"有符号":"无符号")}</para>");
  99. }
  100. else
  101. {
  102. var type = register.Datatype != Datatype.Array ? register.Datatype : register.ArrayValueType;
  103. stringBuilder.AppendLine($" ///<para> 数据类型:{type}</para>");
  104. }
  105. stringBuilder.AppendLine($" /// </summary>");
  106. stringBuilder.AppendLine($" public {protype} {proname}");
  107. stringBuilder.AppendLine(" {");
  108. stringBuilder.AppendLine(" get");
  109. stringBuilder.AppendLine(" {");
  110. stringBuilder.AppendLine($" _" + proname + $" ??= ({protype})fpga.Properties[\"{register.Name}\"];");
  111. stringBuilder.AppendLine($" return _" + proname + ";");
  112. stringBuilder.AppendLine(" }");
  113. stringBuilder.AppendLine(" }");
  114. }
  115. private void GeneratorFifo(DMA dma,StringBuilder stringBuilder)
  116. {
  117. string protype = GetFifoType(dma);
  118. string proname = $"{dma.Name.Split('_')[0]}";
  119. proname = RemovePropertySpecialcharacters(proname);
  120. stringBuilder.AppendLine($" private {protype} _{proname};");
  121. stringBuilder.AppendLine($" /// <summary>");
  122. stringBuilder.AppendLine($" ///<para> {dma.Name}</para>");
  123. if(dma.Datatype == Datatype.FXP)
  124. {
  125. stringBuilder.AppendLine($" ///<para> 数据类型:定点数</para>");
  126. stringBuilder.AppendLine($" ///<para> 最大值:{dma.FxpTypeInfo.Max}</para>");
  127. stringBuilder.AppendLine($" ///<para> 最小值:{dma.FxpTypeInfo.Min}</para>");
  128. stringBuilder.AppendLine($" ///<para> 最小分辨率:{dma.FxpTypeInfo.Delta}</para>");
  129. stringBuilder.AppendLine($" ///<para> 字长:{dma.FxpTypeInfo.wordLength}</para>");
  130. stringBuilder.AppendLine($" ///<para> 整数字长:{dma.FxpTypeInfo.integerWordLength}</para>");
  131. stringBuilder.AppendLine($" ///<para> {(dma.FxpTypeInfo.isSigned ? "有符号" : "无符号")}</para>");
  132. }
  133. else
  134. {
  135. stringBuilder.AppendLine($" ///<para> 数据类型:{dma.Datatype}</para>");
  136. }
  137. stringBuilder.AppendLine($" /// </summary>");
  138. stringBuilder.AppendLine($" public {protype} {proname}");
  139. stringBuilder.AppendLine(" {");
  140. stringBuilder.AppendLine(" get");
  141. stringBuilder.AppendLine(" {");
  142. stringBuilder.AppendLine($" _" + proname + $" ??= ({protype})fpga.Fifos[\"{dma.Name}\"];");
  143. stringBuilder.AppendLine($" return _" + proname + ";");
  144. stringBuilder.AppendLine(" }");
  145. stringBuilder.AppendLine(" }");
  146. }
  147. private string GetFifoType(DMA dma)
  148. {
  149. string direction = dma.Direction == "TargetToHost" ? "ReadFifo" : "WriteFifo";
  150. string protype = string.Empty;
  151. switch (dma.Datatype)
  152. {
  153. case NIFPGA.lvbitx.Datatype.Boolean:
  154. protype = $"{direction}<bool>";
  155. break;
  156. case NIFPGA.lvbitx.Datatype.Int8:
  157. protype = $"{direction}<sbyte>";
  158. break;
  159. case NIFPGA.lvbitx.Datatype.Double:
  160. protype = $"{direction}<double>";
  161. break;
  162. case NIFPGA.lvbitx.Datatype.Float:
  163. protype = $"{direction}<float>";
  164. break;
  165. case NIFPGA.lvbitx.Datatype.FXP:
  166. protype = $"{(dma.Direction == "TargetToHost" ? "ReadFXPFifo" : "WriteFXPFifo")}";
  167. break;
  168. case NIFPGA.lvbitx.Datatype.Int16:
  169. protype = $"{direction}<short>";
  170. break;
  171. case NIFPGA.lvbitx.Datatype.Int32:
  172. protype = $"{direction}<int>";
  173. break;
  174. case NIFPGA.lvbitx.Datatype.Int64:
  175. protype = $"{direction}<long>";
  176. break;
  177. case NIFPGA.lvbitx.Datatype.Uint16:
  178. protype = $"{direction}<ushort>";
  179. break;
  180. case NIFPGA.lvbitx.Datatype.Uint32:
  181. protype = $"{direction}<uint>";
  182. break;
  183. case NIFPGA.lvbitx.Datatype.Uint64:
  184. protype = $"{direction}<ulong>";
  185. break;
  186. case NIFPGA.lvbitx.Datatype.Uint8:
  187. protype = $"{direction}<byte>";
  188. break;
  189. default:
  190. throw new Exception("类型错误");
  191. }
  192. return protype;
  193. }
  194. private string RemovePropertySpecialcharacters(string s)
  195. {
  196. string proname = Regex.Replace(s,@"\((.+?)\)","", RegexOptions.IgnoreCase).Replace("(", "_").Replace(")", "_").Replace("/", "_").Replace("__", "_").Trim('_');
  197. return char.ToUpper(proname[0]) + proname.Substring(1);
  198. }
  199. private string GetProType(Register register)
  200. {
  201. string value = "";
  202. switch (register.Datatype)
  203. {
  204. case NIFPGA.lvbitx.Datatype.Boolean:
  205. if(!register.Indicator)
  206. {
  207. value = "FPGAWriteProperty<bool>";
  208. }
  209. else
  210. {
  211. value = "FPGAReadProperty<bool>";
  212. }
  213. break;
  214. case NIFPGA.lvbitx.Datatype.Int8:
  215. if (!register.Indicator)
  216. {
  217. value = "FPGAWriteProperty<sbyte>";
  218. }
  219. else
  220. {
  221. value = "FPGAReadProperty<sbyte>";
  222. }
  223. break;
  224. case NIFPGA.lvbitx.Datatype.Uint8:
  225. if (!register.Indicator)
  226. {
  227. value = "FPGAWriteProperty<byte>";
  228. }
  229. else
  230. {
  231. value = "FPGAReadProperty<byte>";
  232. }
  233. break;
  234. case NIFPGA.lvbitx.Datatype.Int16:
  235. if (!register.Indicator)
  236. {
  237. value = "FPGAWriteProperty<short>";
  238. }
  239. else
  240. {
  241. value = "FPGAReadProperty<short>";
  242. }
  243. break;
  244. case NIFPGA.lvbitx.Datatype.Uint16:
  245. if (!register.Indicator)
  246. {
  247. value = "FPGAWriteProperty<ushort>";
  248. }
  249. else
  250. {
  251. value = "FPGAReadProperty<ushort>";
  252. }
  253. break;
  254. case NIFPGA.lvbitx.Datatype.Int32:
  255. if (!register.Indicator)
  256. {
  257. value = "FPGAWriteProperty<int>";
  258. }
  259. else
  260. {
  261. value = "FPGAReadProperty<int>";
  262. }
  263. break;
  264. case NIFPGA.lvbitx.Datatype.Uint32:
  265. if (!register.Indicator)
  266. {
  267. value = "FPGAWriteProperty<uint>";
  268. }
  269. else
  270. {
  271. value = "FPGAReadProperty<uint>";
  272. }
  273. break;
  274. case NIFPGA.lvbitx.Datatype.Int64:
  275. if (!register.Indicator)
  276. {
  277. value = "FPGAWriteProperty<long>";
  278. }
  279. else
  280. {
  281. value = "FPGAReadProperty<long>";
  282. }
  283. break;
  284. case NIFPGA.lvbitx.Datatype.Uint64:
  285. if (!register.Indicator)
  286. {
  287. value = "FPGAWriteProperty<ulong>";
  288. }
  289. else
  290. {
  291. value = "FPGAReadProperty<ulong>";
  292. }
  293. break;
  294. case NIFPGA.lvbitx.Datatype.Float:
  295. if (!register.Indicator)
  296. {
  297. value = "FPGAWriteProperty<float>";
  298. }
  299. else
  300. {
  301. value = "FPGAReadProperty<float>";
  302. }
  303. break;
  304. case NIFPGA.lvbitx.Datatype.Double:
  305. if (!register.Indicator)
  306. {
  307. value = "FPGAWriteProperty<double>";
  308. }
  309. else
  310. {
  311. value = "FPGAReadProperty<double>";
  312. }
  313. break;
  314. case NIFPGA.lvbitx.Datatype.FXP:
  315. if(!register.Indicator)
  316. {
  317. value = "FPGAFXPWriteProperty";
  318. }
  319. else
  320. {
  321. value = "FPGAFXPReadProperty";
  322. }
  323. break;
  324. case NIFPGA.lvbitx.Datatype.Array:
  325. switch (register.ArrayValueType)
  326. {
  327. case NIFPGA.lvbitx.Datatype.Boolean:
  328. if(!register.Indicator)
  329. {
  330. value = "FPGAArrayWriteProperty<bool>";
  331. }
  332. else
  333. {
  334. value = "FPGAArrayReadProperty<bool>";
  335. }
  336. break;
  337. case NIFPGA.lvbitx.Datatype.Int8:
  338. if (!register.Indicator)
  339. {
  340. value = "FPGAArrayWriteProperty<sbyte>";
  341. }
  342. else
  343. {
  344. value = "FPGAArrayReadProperty<sbyte>";
  345. }
  346. break;
  347. case NIFPGA.lvbitx.Datatype.Uint8:
  348. if (!register.Indicator)
  349. {
  350. value = "FPGAArrayWriteProperty<byte>";
  351. }
  352. else
  353. {
  354. value = "FPGAArrayReadProperty<byte>";
  355. }
  356. break;
  357. case NIFPGA.lvbitx.Datatype.Int16:
  358. if (!register.Indicator)
  359. {
  360. value = "FPGAArrayWriteProperty<short>";
  361. }
  362. else
  363. {
  364. value = "FPGAArrayReadProperty<short>";
  365. }
  366. break;
  367. case NIFPGA.lvbitx.Datatype.Uint16:
  368. if (!register.Indicator)
  369. {
  370. value = "FPGAArrayWriteProperty<ushort>";
  371. }
  372. else
  373. {
  374. value = "FPGAArrayReadProperty<ushort>";
  375. }
  376. break;
  377. case NIFPGA.lvbitx.Datatype.Int32:
  378. if (!register.Indicator)
  379. {
  380. value = "FPGAArrayWriteProperty<int>";
  381. }
  382. else
  383. {
  384. value = "FPGAArrayReadProperty<int>";
  385. }
  386. break;
  387. case NIFPGA.lvbitx.Datatype.Uint32:
  388. if (!register.Indicator)
  389. {
  390. value = "FPGAArrayWriteProperty<uint>";
  391. }
  392. else
  393. {
  394. value = "FPGAArrayReadProperty<uint>";
  395. }
  396. break;
  397. case NIFPGA.lvbitx.Datatype.Int64:
  398. if (!register.Indicator)
  399. {
  400. value = "FPGAArrayWriteProperty<long>";
  401. }
  402. else
  403. {
  404. value = "FPGAArrayReadProperty<long>";
  405. }
  406. break;
  407. case NIFPGA.lvbitx.Datatype.Uint64:
  408. if (!register.Indicator)
  409. {
  410. value = "FPGAArrayWriteProperty<ulong>";
  411. }
  412. else
  413. {
  414. value = "FPGAArrayReadProperty<ulong>";
  415. }
  416. break;
  417. case NIFPGA.lvbitx.Datatype.Float:
  418. if (!register.Indicator)
  419. {
  420. value = "FPGAArrayWriteProperty<float>";
  421. }
  422. else
  423. {
  424. value = "FPGAArrayReadProperty<float>";
  425. }
  426. break;
  427. case NIFPGA.lvbitx.Datatype.Double:
  428. if (!register.Indicator)
  429. {
  430. value = "FPGAArrayWriteProperty<double>";
  431. }
  432. else
  433. {
  434. value = "FPGAArrayReadProperty<double>";
  435. }
  436. break;
  437. case NIFPGA.lvbitx.Datatype.FXP:
  438. if (!register.Indicator)
  439. {
  440. value = "FPGAArrayFXPWriteProperty";
  441. }
  442. else
  443. {
  444. value = "FPGAArrayFXPReadProperty";
  445. }
  446. break;
  447. }
  448. break;
  449. }
  450. return value;
  451. }
  452. }
  453. }