async Task RunWithData( List <SOCRecord> externalData, string mainCode) { var textReplacer = new TextReplacer(); var templateRoot = TemplatesPath(Path.GetDirectoryName(Directory.GetCurrentDirectory())); var sourceRoot = @"C:\code\Quokka.RISCV.Docker.Server\Quokka.RISCV.Integration.Tests\Client\Blinker\Source"; var context = new RISCVIntegrationContext() .WithExtensionClasses( new ExtensionClasses() .Text("") .Text("lds") .Text("s") .Text("c") .Text("cpp") .Text("h") .Binary("bin") .Binary("elf") .Text("map") ) .WithRootFolder(sourceRoot) .WithAllRegisteredFiles() .WithOperations( new BashInvocation("make firmware.bin") ) .TakeModifiedFiles() ; var firmwareTemplatePath = File.ReadAllText(Path.Combine(templateRoot, "firmware.template.cpp")); var firmwareMap = new Dictionary <string, string>() { { "MAIN_CODE", mainCode } }; firmwareTemplatePath = textReplacer.ReplaceToken(firmwareTemplatePath, firmwareMap); var dmaGenerator = new SOCGenerator(); context.SourceSnapshot.Files.Add(dmaGenerator.SOCImport(externalData)); var generator = new IntegrationGenerator(); context.SourceSnapshot.Files.Add(generator.Firmware(firmwareTemplatePath)); new FSManager(sourceRoot).SaveSnapshot(context.SourceSnapshot); var result = await RISCVIntegrationClient.Run(context); Assert.IsNotNull(result); var hardwareTemplatePath = Path.Combine(templateRoot, "hardware.template.v"); var hardwareTemplate = File.ReadAllText(hardwareTemplatePath); // memory init file var binFile = (FSBinaryFile)result.ResultSnapshot.Files.Find(f => f.Name == "firmware.bin"); Assert.IsNotNull(binFile); var replacers = new Dictionary <string, string>(); var words = TestTools.ReadWords(binFile.Content).ToList(); var memInit = generator.MemInit(words, "l_mem", 512, 4); replacers["MEM_INIT"] = memInit; // data declarations replacers["DATA_DECL"] = generator.DataDeclaration(externalData); // data control signals var templates = new IntegrationTemplates(); foreach (var templatePath in Directory.EnumerateFiles(templateRoot, "*.*", SearchOption.AllDirectories)) { var name = Path.GetFileName(templatePath).Split('.')[0]; templates.Templates[name] = File.ReadAllText(templatePath); } replacers["DATA_CTRL"] = generator.DataControl(externalData, templates); replacers["MEM_READY"] = generator.MemReady(externalData); replacers["MEM_RDATA"] = generator.MemRData(externalData); hardwareTemplate = textReplacer.ReplaceToken(hardwareTemplate, replacers); File.WriteAllText(@"C:\code\picorv32\quartus\RVTest.v", hardwareTemplate); }
async Task TranslateSourceFiles( IEnumerable <FSTextFile> files, Action entryPoint ) { var textReplacer = new TextReplacer(); var generator = new IntegrationGenerator(); var firmwareTemplates = IntegrationTemplatesLoader.FirmwareTemplates; var hardwareTemplates = IntegrationTemplatesLoader.HardwareTemplates; var tx = new CSharp2CPPTranslator(); var source = new FSSnapshot(); source.Files.AddRange(files); tx.Run(source); var firmwareSource = tx.Result; var socGenerator = new SOCGenerator(); var socRecords = new List <SOCRecord>(); var socRecordsBuilder = new SOCRecordsBuilder(); // default code block socRecords.Add(new SOCRecord() { DataType = typeof(uint), SegmentBits = 12, HardwareName = "firmware", SoftwareName = "firmware", Segment = 0, Depth = 512, Template = "memory32" }); socRecords.AddRange(socRecordsBuilder.ToSOCRecords(0x800, tx.SOCResources)); firmwareSource.Add(socGenerator.SOCImport(socRecords)); var generatedSourceFiles = firmwareSource.Files.Where(f => Path.GetExtension(f.Name).ToLower() == ".cpp").ToList(); var generatedHeaderFiles = firmwareSource.Files.Where(f => Path.GetExtension(f.Name).ToLower() == ".h").ToList(); firmwareSource.Merge(firmwareTemplates, f => !f.Name.Contains("template")); var firmwareTemplate = firmwareTemplates.Get <FSTextFile>("firmware.template.cpp"); var firmwareMap = new Dictionary <string, string>() { { "FIRMWARE_INCLUDES", string.Join(Environment.NewLine, generatedHeaderFiles.Select(f => $"#include \"{f.Name}\"")) }, { "FIRMWARE_CODE", $"{entryPoint.Method.DeclaringType.Namespace}::{entryPoint.Method.DeclaringType.Name}::{entryPoint.Method.Name}();" }, }; firmwareSource.Add("firmware.cpp", textReplacer.ReplaceToken(firmwareTemplate.Content, firmwareMap)); var makefileTemplate = firmwareTemplates.Get <FSTextFile>("Makefile.template"); var makefileMap = new Dictionary <string, string>() { { "SOURCES_LIST", string.Join(" ", generatedSourceFiles.Select(f => f.Name)) } }; firmwareSource.Add("Makefile", textReplacer.ReplaceToken(makefileTemplate.Content, makefileMap)); IntermediateData.SaveFirmwareSource(firmwareSource); var firmwareOutput = await CompileFromIntermediate(); IntermediateData.SaveFirmwareOutput(firmwareOutput); // generat verilog var hardwareTemplate = hardwareTemplates.Get <FSTextFile>("hardware.template.v").Content; var replacers = new Dictionary <string, string>(); // memory init file replacers["MEM_INIT"] = ""; foreach (var dma in socRecords) { var binFile = firmwareOutput.Get <FSBinaryFile>($"{dma.HardwareName}.bin"); if (binFile != null) { var words = TestTools.ReadWords(binFile.Content).ToList(); var memInit = generator.MemInit(words, dma.HardwareName, (int)dma.Depth, SizeOfType(dma.DataType)); replacers["MEM_INIT"] += memInit; } else { var memInit = generator.MemInit(Enumerable.Range(0, (int)dma.Depth).Select(idx => 0UL).ToList(), dma.HardwareName, (int)dma.Depth, SizeOfType(dma.DataType)); replacers["MEM_INIT"] += memInit; } } // data declarations replacers["DATA_DECL"] = generator.DataDeclaration(socRecords); // data control signals var templates = new IntegrationTemplates(); foreach (var t in hardwareTemplates.Files.OfType <FSTextFile>()) { templates.Templates[t.Name] = t.Content; } replacers["DATA_CTRL"] = generator.DataControl(socRecords, templates); replacers["MEM_READY"] = generator.MemReady(socRecords); replacers["MEM_RDATA"] = generator.MemRData(socRecords); hardwareTemplate = textReplacer.ReplaceToken(hardwareTemplate, replacers); var hardwareSource = new FSSnapshot(); hardwareSource.Add("hardware.v", hardwareTemplate); IntermediateData.SaveHardwareSource(hardwareSource); }