-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e3efe51
commit cc7a0be
Showing
8 changed files
with
234 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using Microsoft.Extensions.Logging; | ||
using OneWare.Essentials.Services; | ||
using OneWare.UniversalFpgaProjectSystem.Models; | ||
using OneWare.UniversalFpgaProjectSystem.Services; | ||
using ILogger = OneWare.Essentials.Services.ILogger; | ||
|
||
namespace OneWare.Quartus; | ||
|
||
public class QuartusLoader(IChildProcessService childProcessService, ILogger logger) : IFpgaLoader | ||
{ | ||
public string Name => "Quartus"; | ||
|
||
private string? FirstFileInPath(string path, string extension) | ||
{ | ||
try | ||
{ | ||
return Directory | ||
.GetFiles(path) | ||
.FirstOrDefault(x => Path.GetExtension(x).Equals(extension, StringComparison.OrdinalIgnoreCase)); | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.Error(e.Message, e); | ||
return null; | ||
} | ||
} | ||
|
||
public async Task DownloadAsync(UniversalFpgaProjectRoot project) | ||
{ | ||
var fpga = project.Properties["Fpga"]; | ||
if (fpga == null) return; | ||
var fpgaModel = fpga.ToString(); | ||
|
||
var cableName = "Auto"; | ||
var sofFile = Path.GetFileName(FirstFileInPath(project.FullPath, ".sof") ?? ""); | ||
|
||
if (string.IsNullOrEmpty(sofFile)) | ||
{ | ||
logger.Error("no .sof found! compile Design first!"); | ||
return; | ||
} | ||
|
||
await childProcessService.ExecuteShellAsync("quartus_pgm", $"-c {cableName} -m JTAG -o P;{sofFile}", | ||
project.FullPath, "Running OpenFPGALoader"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System.Runtime.InteropServices; | ||
using CommunityToolkit.Mvvm.Input; | ||
using Microsoft.CodeAnalysis; | ||
using OneWare.Essentials.Helpers; | ||
using OneWare.Essentials.Models; | ||
using OneWare.Essentials.Services; | ||
using OneWare.Essentials.ViewModels; | ||
using OneWare.Quartus.Services; | ||
using OneWare.UniversalFpgaProjectSystem.Models; | ||
using OneWare.UniversalFpgaProjectSystem.Services; | ||
using Prism.Ioc; | ||
using Prism.Modularity; | ||
|
||
namespace OneWare.Quartus; | ||
|
||
public class QuartusModule : IModule | ||
{ | ||
public void RegisterTypes(IContainerRegistry containerRegistry) | ||
{ | ||
containerRegistry.RegisterSingleton<QuartusService>(); | ||
} | ||
|
||
public void OnInitialized(IContainerProvider containerProvider) | ||
{ | ||
var settingsService = containerProvider.Resolve<ISettingsService>(); | ||
var quartusService = containerProvider.Resolve<QuartusService>(); | ||
|
||
containerProvider.Resolve<FpgaService>().RegisterToolchain<QuartusToolchain>(); | ||
containerProvider.Resolve<FpgaService>().RegisterLoader<QuartusLoader>(); | ||
|
||
settingsService.RegisterTitledPath("Tools", "Quartus", "Quartus_Path", "Quartus Path", | ||
"Sets the path for Quartus", Path.Combine(Path.GetPathRoot(Environment.SystemDirectory) ?? "", | ||
"intelFPGA_lite", "18.1", | ||
"quartus"), null, null, IsQuartusPathValid); | ||
|
||
string? environmentPathSetting; | ||
|
||
settingsService.GetSettingObservable<string>("Quartus_Path").Subscribe(x => | ||
{ | ||
if (string.IsNullOrEmpty(x)) return; | ||
if (!IsQuartusPathValid(x)) | ||
{ | ||
containerProvider.Resolve<ILogger>().Warning("Quartus path invalid", null, false); | ||
return; | ||
} | ||
var binPath = Path.Combine(x, "bin64"); | ||
environmentPathSetting = PlatformHelper.Platform switch | ||
{ | ||
PlatformId.WinX64 or PlatformId.WinArm64 => $";{binPath};", | ||
_ => $":{binPath}:" | ||
}; | ||
var currentPath = Environment.GetEnvironmentVariable("PATH"); | ||
Environment.SetEnvironmentVariable("PATH", $"{environmentPathSetting}{currentPath}"); | ||
}); | ||
|
||
// containerProvider.Resolve<IProjectExplorerService>().RegisterConstructContextMenu(x => | ||
// { | ||
// if (x is [UniversalFpgaProjectRoot project]) | ||
// { | ||
// return new[] | ||
// { | ||
// new MenuItemViewModel("Quartus") | ||
// { | ||
// Header = "Compile with quartus", | ||
// Command = new AsyncRelayCommand(() => quartusService.SynthAsync(project)) | ||
// } | ||
// }; | ||
// } | ||
// return null; | ||
// }); | ||
} | ||
|
||
private static bool IsQuartusPathValid(string path) | ||
{ | ||
if (!Directory.Exists(path)) return false; | ||
if (!File.Exists(Path.Combine(path, "bin64", $"quartus_pgm{PlatformHelper.ExecutableExtension}"))) return false; | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using OneWare.Essentials.Services; | ||
using OneWare.Quartus.Services; | ||
using OneWare.UniversalFpgaProjectSystem.Models; | ||
using OneWare.UniversalFpgaProjectSystem.Services; | ||
|
||
namespace OneWare.Quartus; | ||
|
||
public class QuartusToolchain(QuartusService quartusService, ILogger logger) : IFpgaToolchain | ||
Check warning on line 8 in src/OneWare.Quartus/QuartusToolchain.cs GitHub Actions / build
|
||
{ | ||
public string Name => "Quartus"; | ||
|
||
public void LoadConnections(UniversalFpgaProjectRoot project, FpgaModel fpga) | ||
{ | ||
try | ||
{ | ||
var files = Directory.GetFiles(project.RootFolderPath); | ||
var pcfPath = files.FirstOrDefault(x => Path.GetExtension(x) == ".qsf"); | ||
if (pcfPath != null) | ||
{ | ||
var pcf = File.ReadAllText(pcfPath); | ||
var lines = pcf.Split('\n'); | ||
foreach (var line in lines) | ||
{ | ||
var trimmedLine = line.Trim(); | ||
if (trimmedLine.StartsWith("set_io")) | ||
{ | ||
var parts = trimmedLine.Split(' '); | ||
if (parts.Length != 3) | ||
{ | ||
logger.Warning("PCF Line invalid: " + trimmedLine); | ||
continue; | ||
} | ||
|
||
var signal = parts[1]; | ||
var pin = parts[2]; | ||
|
||
if (fpga.PinModels.TryGetValue(pin, out var pinModel) && fpga.NodeModels.TryGetValue(signal, out var signalModel)) | ||
{ | ||
fpga.Connect(pinModel, signalModel); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.Error(e.Message, e); | ||
} | ||
} | ||
|
||
public void SaveConnections(UniversalFpgaProjectRoot project, FpgaModel fpga) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public void StartCompile(UniversalFpgaProjectRoot project, FpgaModel fpga) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using OneWare.Essentials.Models; | ||
using OneWare.Essentials.Services; | ||
using OneWare.UniversalFpgaProjectSystem.Models; | ||
|
||
namespace OneWare.Quartus.Services; | ||
|
||
public class QuartusService | ||
{ | ||
private readonly IChildProcessService _childProcessService; | ||
|
||
public QuartusService(IChildProcessService childProcessService) | ||
{ | ||
_childProcessService = childProcessService; | ||
} | ||
|
||
public async Task SynthAsync(UniversalFpgaProjectRoot project) | ||
{ | ||
var fpga = "ice40"; // project.Properties["Fpga"]; | ||
var top = project.Properties["TopEntity"]; | ||
|
||
var verilogFiles = string.Join(" ", project.Files.Where(x => x.Extension == ".v").Select(x => x.RelativePath)); | ||
var yosysFlags = string.Empty; | ||
|
||
var buildDir = Path.Combine(project.FullPath, "build"); | ||
Directory.CreateDirectory(buildDir); | ||
|
||
await _childProcessService.ExecuteShellAsync("yosys", | ||
$"-q -p \"synth_{fpga} -json {Path.Combine(buildDir, "synth.json")}\" {yosysFlags}{verilogFiles}", | ||
project.FullPath, "Running Yosys..."); | ||
|
||
var nextPnrFlags = "--freq 12 --up5k --package sg48"; | ||
|
||
await _childProcessService.ExecuteShellAsync($"nextpnr-{fpga}", | ||
$"--json ./build/synth.json --pcf project.pcf --asc ./build/nextpnr.asc {nextPnrFlags}", | ||
project.FullPath, "Running NextPnr..."); | ||
|
||
await _childProcessService.ExecuteShellAsync($"icepack", | ||
$"./build/nextpnr.asc ./build/pack.bin", | ||
project.FullPath, "Running IcePack..."); | ||
} | ||
} |