Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
HendrikMennen committed Mar 5, 2024
1 parent e3efe51 commit cc7a0be
Show file tree
Hide file tree
Showing 8 changed files with 234 additions and 35 deletions.
Binary file modified Icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions oneware-extension.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"category": "Tools",
"type": "Plugin",
"name": "OneWare.Quartus Extension",
"name": "OneWare Quartus Extension",
"id": "OneWare.QuartusModule",
"description": "OneWare.Quartus for OneWare",
"description": "Quartus Integration for OneWare",
"license": "MIT",
"iconUrl": "https://raw.githubusercontent.com/one-ware/OneWare.Quartus/main/Icon.png",
"tabs": [
Expand Down
1 change: 1 addition & 0 deletions src/OneWare.Quartus/OneWare.Quartus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<ItemGroup>
<PackageReference Include="OneWare.Essentials" Version="0.1" Private="false" ExcludeAssets="runtime;Native"/>
<PackageReference Include="OneWare.UniversalFpgaProjectSystem" Version="0.14.0" />
</ItemGroup>

</Project>
33 changes: 0 additions & 33 deletions src/OneWare.Quartus/OneWareQuartusModule.cs

This file was deleted.

46 changes: 46 additions & 0 deletions src/OneWare.Quartus/QuartusLoader.cs
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");
}
}
84 changes: 84 additions & 0 deletions src/OneWare.Quartus/QuartusModule.cs
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;
}
}
60 changes: 60 additions & 0 deletions src/OneWare.Quartus/QuartusToolchain.cs
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

View workflow job for this annotation

GitHub Actions / build

Parameter 'quartusService' is unread.

Check warning on line 8 in src/OneWare.Quartus/QuartusToolchain.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'quartusService' is unread.
{
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();
}
}
41 changes: 41 additions & 0 deletions src/OneWare.Quartus/Services/QuartusService.cs
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...");
}
}

0 comments on commit cc7a0be

Please sign in to comment.