123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- using Microsoft.CodeAnalysis;
- using NIFPGA.lvbitx;
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
- namespace ShakerFpga
- {
- [Generator(LanguageNames.CSharp)]
- internal class ShakerFpgaSourceGenerator : IIncrementalGenerator
- {
- public void Initialize(IncrementalGeneratorInitializationContext context)
- {
- context.RegisterPostInitializationOutput(c =>
- {
- var names = typeof(ShakerFpgaSourceGenerator).Assembly.GetManifestResourceNames().First(x => x.IndexOf(".lvbitx")>=0);
- NIFPGA.lvbitx.Bitfile bitfile = NIFPGA.lvbitx.Parse.ParseFile(typeof(ShakerFpgaSourceGenerator).Assembly.GetManifestResourceStream(names),names);
- string s = string.Join(",", bitfile.VI.Registers.Select(x => x.Name));
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.AppendLine("/// <auto-generated>");
- stringBuilder.AppendLine("/// This code was generated by Source Generator.");
- stringBuilder.AppendLine("/// </auto-generated>");
- stringBuilder.AppendLine("using NIFPGA;");
- stringBuilder.AppendLine("using FxpConvert.Common;");
- stringBuilder.AppendLine("namespace ShakerFpga");
- stringBuilder.AppendLine("{");
- stringBuilder.AppendLine(" public sealed class ShakerFpga");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" private static ShakerFpga myFpga;");
- stringBuilder.AppendLine(" private readonly NIFPGA.FPGA fpga;");
- stringBuilder.AppendLine(" public string BitstreamMD5 => fpga.BitstreamMD5;");
- stringBuilder.AppendLine(" public string BitfileVersion => fpga.BitfileVersion;");
- stringBuilder.AppendLine(" public string SignatureRegister => fpga.SignatureRegister;");
- stringBuilder.AppendLine(" public string BitstreamVersion => fpga.BitstreamVersion;");
- stringBuilder.AppendLine(" public string SignatureNames => fpga.SignatureNames;");
- stringBuilder.AppendLine(" public bool LastError => fpga.Error;");
- stringBuilder.AppendLine(" public NiFpga_Status LastStatus => fpga.LastStatus;");
- stringBuilder.AppendLine(" public string LastMessage => fpga.Message;");
- stringBuilder.AppendLine(" private ShakerFpga(IFxpConvert convert)");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" fpga = new FPGA(convert);");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" static ShakerFpga()");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" public Irq Irq => fpga.Irq;");
- stringBuilder.AppendLine(" public void Open(string bitfile, string resource, NiFpga_OpenAttribute attribute) => fpga.Open(bitfile, resource, attribute);");
- stringBuilder.AppendLine(" public void Close() => fpga.Close();");
- stringBuilder.AppendLine(" public void Run() => fpga.Run();");
- stringBuilder.AppendLine(" public void Download() => fpga.Download();");
- stringBuilder.AppendLine(" public void FpgaFinalize() => fpga.FpgaFinalize();");
- stringBuilder.AppendLine(" public void Abort() => fpga.Abort();");
- stringBuilder.AppendLine(" public void Reset() => fpga.Reset();");
- stringBuilder.AppendLine(" public static ShakerFpga CreateFpga(IFxpConvert convert)");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" myFpga ??= new ShakerFpga(convert);");
- stringBuilder.AppendLine(" return myFpga;");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" public static ShakerFpga Instance");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" get");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" if (myFpga == null)");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" throw new Exception(\"must call first CreateFpga\");");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" return myFpga;");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" #region 寄存器定义");
- bitfile.VI.Registers.ForEach(x => GeneratorRegister(x, stringBuilder));
- stringBuilder.AppendLine(" #endregion");
- stringBuilder.AppendLine(" #region Fifo定义");
- bitfile.Project.DMA.ForEach(x => GeneratorFifo(x, stringBuilder));
- stringBuilder.AppendLine(" #endregion");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine("}");
- c.AddSource("ShakerFpga.g.cs", stringBuilder.ToString());
- });
- }
- private void GeneratorRegister(Register register, StringBuilder stringBuilder)
- {
- string protype = GetProType(register);
- string proname = $"{register.Name.Split('_')[0]}";
- proname = RemovePropertySpecialcharacters(proname);
- stringBuilder.AppendLine($" private {protype} _{proname};");
- stringBuilder.AppendLine($" /// <summary>");
- stringBuilder.AppendLine($" ///<para> {register.Name}{(register.Datatype == Datatype.Array?$",数组长度为:{register.Size}":"")}</para>");
- if(register.Datatype == Datatype.FXP || register.ArrayValueType == Datatype.FXP)
- {
- stringBuilder.AppendLine($" ///<para> 数据类型:定点数</para>");
- stringBuilder.AppendLine($" ///<para> 最大值:{register.FxpTypeInfo.Max}</para>");
- stringBuilder.AppendLine($" ///<para> 最小值:{register.FxpTypeInfo.Min}</para>");
- stringBuilder.AppendLine($" ///<para> 最小分辨率:{register.FxpTypeInfo.Delta}</para>");
- stringBuilder.AppendLine($" ///<para> 字长:{register.FxpTypeInfo.wordLength}</para>");
- stringBuilder.AppendLine($" ///<para> 整数字长:{register.FxpTypeInfo.integerWordLength}</para>");
- stringBuilder.AppendLine($" ///<para> {(register.FxpTypeInfo.isSigned?"有符号":"无符号")}</para>");
- }
- else
- {
- var type = register.Datatype != Datatype.Array ? register.Datatype : register.ArrayValueType;
- stringBuilder.AppendLine($" ///<para> 数据类型:{type}</para>");
- }
- stringBuilder.AppendLine($" /// </summary>");
- stringBuilder.AppendLine($" public {protype} {proname}");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" get");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine($" _" + proname + $" ??= ({protype})fpga.Properties[\"{register.Name}\"];");
- stringBuilder.AppendLine($" return _" + proname + ";");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" }");
- }
- private void GeneratorFifo(DMA dma,StringBuilder stringBuilder)
- {
- string protype = GetFifoType(dma);
- string proname = $"{dma.Name.Split('_')[0]}";
- proname = RemovePropertySpecialcharacters(proname);
- stringBuilder.AppendLine($" private {protype} _{proname};");
- stringBuilder.AppendLine($" /// <summary>");
- stringBuilder.AppendLine($" ///<para> {dma.Name}</para>");
- if(dma.Datatype == Datatype.FXP)
- {
- stringBuilder.AppendLine($" ///<para> 数据类型:定点数</para>");
- stringBuilder.AppendLine($" ///<para> 最大值:{dma.FxpTypeInfo.Max}</para>");
- stringBuilder.AppendLine($" ///<para> 最小值:{dma.FxpTypeInfo.Min}</para>");
- stringBuilder.AppendLine($" ///<para> 最小分辨率:{dma.FxpTypeInfo.Delta}</para>");
- stringBuilder.AppendLine($" ///<para> 字长:{dma.FxpTypeInfo.wordLength}</para>");
- stringBuilder.AppendLine($" ///<para> 整数字长:{dma.FxpTypeInfo.integerWordLength}</para>");
- stringBuilder.AppendLine($" ///<para> {(dma.FxpTypeInfo.isSigned ? "有符号" : "无符号")}</para>");
- }
- else
- {
- stringBuilder.AppendLine($" ///<para> 数据类型:{dma.Datatype}</para>");
- }
- stringBuilder.AppendLine($" /// </summary>");
- stringBuilder.AppendLine($" public {protype} {proname}");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine(" get");
- stringBuilder.AppendLine(" {");
- stringBuilder.AppendLine($" _" + proname + $" ??= ({protype})fpga.Fifos[\"{dma.Name}\"];");
- stringBuilder.AppendLine($" return _" + proname + ";");
- stringBuilder.AppendLine(" }");
- stringBuilder.AppendLine(" }");
- }
- private string GetFifoType(DMA dma)
- {
- string direction = dma.Direction == "TargetToHost" ? "ReadFifo" : "WriteFifo";
- string protype = string.Empty;
- switch (dma.Datatype)
- {
- case NIFPGA.lvbitx.Datatype.Boolean:
- protype = $"{direction}<bool>";
- break;
- case NIFPGA.lvbitx.Datatype.Int8:
- protype = $"{direction}<sbyte>";
- break;
- case NIFPGA.lvbitx.Datatype.Double:
- protype = $"{direction}<double>";
- break;
- case NIFPGA.lvbitx.Datatype.Float:
- protype = $"{direction}<float>";
- break;
- case NIFPGA.lvbitx.Datatype.FXP:
- protype = $"{(dma.Direction == "TargetToHost" ? "ReadFXPFifo" : "WriteFXPFifo")}";
- break;
- case NIFPGA.lvbitx.Datatype.Int16:
- protype = $"{direction}<short>";
- break;
- case NIFPGA.lvbitx.Datatype.Int32:
- protype = $"{direction}<int>";
- break;
- case NIFPGA.lvbitx.Datatype.Int64:
- protype = $"{direction}<long>";
- break;
- case NIFPGA.lvbitx.Datatype.Uint16:
- protype = $"{direction}<ushort>";
- break;
- case NIFPGA.lvbitx.Datatype.Uint32:
- protype = $"{direction}<uint>";
- break;
- case NIFPGA.lvbitx.Datatype.Uint64:
- protype = $"{direction}<ulong>";
- break;
- case NIFPGA.lvbitx.Datatype.Uint8:
- protype = $"{direction}<byte>";
- break;
- default:
- throw new Exception("类型错误");
- }
- return protype;
- }
- private string RemovePropertySpecialcharacters(string s)
- {
- string proname = Regex.Replace(s,@"\((.+?)\)","", RegexOptions.IgnoreCase).Replace("(", "_").Replace(")", "_").Replace("/", "_").Replace("__", "_").Trim('_');
- return char.ToUpper(proname[0]) + proname.Substring(1);
- }
- private string GetProType(Register register)
- {
- string value = "";
- switch (register.Datatype)
- {
- case NIFPGA.lvbitx.Datatype.Boolean:
- if(!register.Indicator)
- {
- value = "FPGAWriteProperty<bool>";
- }
- else
- {
- value = "FPGAReadProperty<bool>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int8:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<sbyte>";
- }
- else
- {
- value = "FPGAReadProperty<sbyte>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint8:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<byte>";
- }
- else
- {
- value = "FPGAReadProperty<byte>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int16:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<short>";
- }
- else
- {
- value = "FPGAReadProperty<short>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint16:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<ushort>";
- }
- else
- {
- value = "FPGAReadProperty<ushort>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int32:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<int>";
- }
- else
- {
- value = "FPGAReadProperty<int>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint32:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<uint>";
- }
- else
- {
- value = "FPGAReadProperty<uint>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int64:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<long>";
- }
- else
- {
- value = "FPGAReadProperty<long>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint64:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<ulong>";
- }
- else
- {
- value = "FPGAReadProperty<ulong>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Float:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<float>";
- }
- else
- {
- value = "FPGAReadProperty<float>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Double:
- if (!register.Indicator)
- {
- value = "FPGAWriteProperty<double>";
- }
- else
- {
- value = "FPGAReadProperty<double>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.FXP:
- if(!register.Indicator)
- {
- value = "FPGAFXPWriteProperty";
- }
- else
- {
- value = "FPGAFXPReadProperty";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Array:
- switch (register.ArrayValueType)
- {
- case NIFPGA.lvbitx.Datatype.Boolean:
- if(!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<bool>";
- }
- else
- {
- value = "FPGAArrayReadProperty<bool>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int8:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<sbyte>";
- }
- else
- {
- value = "FPGAArrayReadProperty<sbyte>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint8:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<byte>";
- }
- else
- {
- value = "FPGAArrayReadProperty<byte>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int16:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<short>";
- }
- else
- {
- value = "FPGAArrayReadProperty<short>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint16:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<ushort>";
- }
- else
- {
- value = "FPGAArrayReadProperty<ushort>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int32:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<int>";
- }
- else
- {
- value = "FPGAArrayReadProperty<int>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint32:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<uint>";
- }
- else
- {
- value = "FPGAArrayReadProperty<uint>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Int64:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<long>";
- }
- else
- {
- value = "FPGAArrayReadProperty<long>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Uint64:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<ulong>";
- }
- else
- {
- value = "FPGAArrayReadProperty<ulong>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Float:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<float>";
- }
- else
- {
- value = "FPGAArrayReadProperty<float>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.Double:
- if (!register.Indicator)
- {
- value = "FPGAArrayWriteProperty<double>";
- }
- else
- {
- value = "FPGAArrayReadProperty<double>";
- }
- break;
- case NIFPGA.lvbitx.Datatype.FXP:
- if (!register.Indicator)
- {
- value = "FPGAArrayFXPWriteProperty";
- }
- else
- {
- value = "FPGAArrayFXPReadProperty";
- }
- break;
- }
- break;
- }
- return value;
- }
- }
- }
|