Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/OneWare.Core/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,19 @@ Select the target OpenVINO device.
InputGesture = new KeyGesture(Key.S, PlatformHelper.ControlKey | KeyModifiers.Shift),
Icon = new IconModel("VsImageLib.SaveAll16X")
});
windowService.RegisterMenuItem("MainWindow_MainMenu/File", new MenuItemModel("exit")
{
Command = new RelayCommand(() =>
{
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow?.Close();
}
}),
Header = "Exit",
InputGesture = new KeyGesture(Key.X, PlatformHelper.ControlKey | KeyModifiers.Shift),
Icon = new IconModel("VsImageLib.Exit")
});

var applicationCommandService = Services.Resolve<IApplicationCommandService>();

Expand Down
39 changes: 30 additions & 9 deletions src/OneWare.OssCadSuiteIntegration/Loaders/OpenFpgaLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

namespace OneWare.OssCadSuiteIntegration.Loaders;

public class OpenFpgaLoader(IChildProcessService childProcess,
ISettingsService settingsService, ILogger logger, IOutputService outputService,
public class OpenFpgaLoader(ISettingsService settingsService, ILogger logger, IOutputService outputService,
IToolExecutionDispatcherService toolExecutionDispatcherService)
: IFpgaLoader
{
Expand Down Expand Up @@ -44,9 +43,19 @@ public async Task DownloadAsync(UniversalFpgaProjectRoot project)
return;
}

if (longTerm) openFpgaLoaderArguments.Add("-f");
if (longTerm)
{
if (properties.GetValueOrDefault("openFpgaLoaderLongTermFlags") is { } longFlags)
openFpgaLoaderArguments.Add(longFlags);

openFpgaLoaderArguments.Add("-f");
}
else if (properties.GetValueOrDefault("openFpgaLoaderShortTermFlags") is { } shortFlags)
{
openFpgaLoaderArguments.Add(shortFlags);
}

openFpgaLoaderArguments.AddRange(properties.GetValueOrDefault("OpenFpgaLoader_Flags")?.Split(' ',
openFpgaLoaderArguments.AddRange(properties.GetValueOrDefault("OpenFpgaLoaderFlags")?.Split(' ',
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) ?? []);

var bitstreamFormat = properties
Expand All @@ -66,16 +75,28 @@ public async Task DownloadAsync(UniversalFpgaProjectRoot project)
}

var path = settingsService.GetSettingValue<string>(OssCadSuiteIntegrationModule.OpenFpgaLoaderPathSetting);
var command = ToolCommand.FromShellParams(path, openFpgaLoaderArguments,
outputService.WriteLine("Starting OpenFpgaLoader ...");
var command = ToolCommand.FromShellParams(path, openFpgaLoaderArguments!,
project.FullPath, $"Running {path}...", AppState.Loading, true, null, s =>
{
Dispatcher.UIThread.Post(() => { outputService.WriteLine(s); });
return true;
});

await toolExecutionDispatcherService.ExecuteAsync(command);

//await childProcess.ExecuteShellAsync(path, openFpgaLoaderArguments,
// project.FullPath, "Running OpenFPGALoader...", AppState.Loading, true);
try
{
await toolExecutionDispatcherService.ExecuteAsync(command);
}
catch (Exception ex)
{
Dispatcher.UIThread.Post(() =>
{
outputService.WriteLine($"Error in ExecuteAsync: {ex.Message}");
if (ex.InnerException != null)
{
outputService.WriteLine($"Details: {ex.InnerException.Message}");
}
});
}
}
}
29 changes: 27 additions & 2 deletions src/OneWare.OssCadSuiteIntegration/OssCadSuiteIntegrationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ public override void Initialize(IServiceProvider serviceProvider)
var windowService = serviceProvider.Resolve<IWindowService>();
var projectExplorerService = serviceProvider.Resolve<IProjectExplorerService>();
var fpgaService = serviceProvider.Resolve<FpgaService>();
var outputService = serviceProvider.Resolve<IOutputService>();

fpgaService.RegisterNodeProvider<YosysNodeProvider>();

Expand Down Expand Up @@ -545,8 +546,13 @@ await windowService.ShowDialogAsync(
Path.Combine(x, "lib", $"python3{PlatformHelper.ExecutableExtension}"));
//environmentService.SetEnvironmentVariable("VERILATOR_ROOT",
// Path.Combine(x, "share", $"verilator"));
environmentService.SetEnvironmentVariable("GHDL_PREFIX",
Path.Combine(x, "lib", $"ghdl"));
// GHDL is not provided in the Windows version
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
environmentService.SetEnvironmentVariable("GHDL_PREFIX",
Path.Combine(x, "lib", $"ghdl"));
}

environmentService.SetEnvironmentVariable("GTK_EXE_PREFIX", x);
environmentService.SetEnvironmentVariable("GTK_DATA_PREFIX", x);
environmentService.SetEnvironmentVariable("GDK_PIXBUF_MODULEDIR",
Expand Down Expand Up @@ -598,6 +604,25 @@ await serviceProvider.Resolve<GtkWaveService>().OpenInGtkWaveAsync(wave.FullPath
}
}
}
if (x is [IProjectFile { Extension: ".ccf" } ccf])
{
if (ccf.Root is UniversalFpgaProjectRoot universalFpgaProjectRoot)
{
l.Add(new MenuItemModel("ccf")
{
Header = "Convert to pcf",
Command = new AsyncRelayCommand(() =>
{
var absoluteCcfPath = Path.Combine(universalFpgaProjectRoot.RootFolderPath, ccf.FullPath);
var absolutePcfPath = Path.ChangeExtension(absoluteCcfPath, ".pcf");
outputService.WriteLine($"Converting {absoluteCcfPath} to CCF File");
if (Path.Exists(absolutePcfPath))
ConstraintFileHelper.Convert(absoluteCcfPath, absolutePcfPath);
return Task.CompletedTask;
}),
});
}
}
});

serviceProvider.Resolve<IMainDockService>().RegisterFileOpenOverwrite(x =>
Expand Down
10 changes: 9 additions & 1 deletion src/OneWare.OssCadSuiteIntegration/Yosys/YosysService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ public async Task<bool> SynthAsync(UniversalFpgaProjectRoot project, FpgaModel f
var includedFiles = project.GetFiles("*.v").Concat(project.GetFiles("*.sv"))
.Where(x => !project.IsCompileExcluded(x))
.Where(x => !project.IsTestBench(x));

var genVerilogPath = Path.Combine(project.RootFolderPath, "build", "gen_verilog");
if (Directory.Exists(genVerilogPath))
{
var generatedFiles = Directory.EnumerateFiles(genVerilogPath, "*.v",
SearchOption.AllDirectories);
includedFiles = includedFiles.Concat(generatedFiles);
}

var yosysSynthTool = properties.GetValueOrDefault("yosysToolchainYosysSynthTool") ??
throw new Exception("Yosys Tool not set!");
Expand All @@ -91,7 +99,7 @@ public async Task<bool> SynthAsync(UniversalFpgaProjectRoot project, FpgaModel f
}
else
{
yosysCommand = yosysCommand.Replace("$TOP", top.Split(".")[0]);
yosysCommand = yosysCommand.Replace("$TOP", Path.GetFileNameWithoutExtension(top));
yosysCommand = yosysCommand.Replace("$SYNTH_TOOL", yosysSynthTool);
yosysCommand = yosysCommand.Replace("$OUTPUT", "build/synth.json");

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using Avalonia;
using Avalonia.Controls;
using CommunityToolkit.Mvvm.Input;
using OneWare.Essentials.Extensions;
using OneWare.Essentials.Helpers;
using CommunityToolkit.Mvvm.Input;
using OneWare.Essentials.Models;
using OneWare.Essentials.Services;
using OneWare.Essentials.ViewModels;
using OneWare.UniversalFpgaProjectSystem.Models;
using OneWare.UniversalFpgaProjectSystem.Services;
using OneWare.UniversalFpgaProjectSystem.ViewModels;
Expand All @@ -19,14 +14,16 @@ public class UniversalFpgaProjectManager : IProjectManager
private readonly IMainDockService _mainDockService;
private readonly IProjectExplorerService _projectExplorerService;
private readonly IWindowService _windowService;
private readonly IOutputService _outputService;

public UniversalFpgaProjectManager(IProjectExplorerService projectExplorerService, IMainDockService mainDockService,
IWindowService windowService, FpgaService fpgaService)
IWindowService windowService, FpgaService fpgaService, IOutputService outputService)
{
_projectExplorerService = projectExplorerService;
_mainDockService = mainDockService;
_windowService = windowService;
_fpgaService = fpgaService;
_outputService = outputService;

_projectExplorerService.RegisterConstructContextMenu(ConstructContextMenu);
}
Expand Down Expand Up @@ -112,6 +109,12 @@ private void ConstructContextMenu(IReadOnlyList<IProjectExplorerNode> selected,
Command = new AsyncRelayCommand(() => _projectExplorerService.ReloadProjectAsync(root)),
Icon = new IconModel("VsImageLib.RefreshGrey16X")
});
menuItems.Add(new MenuItemModel("Clean")
{
Header = "Clean",
Command = new AsyncRelayCommand(() =>
CleanBuildFoldersAsync(root))
});
menuItems.Add(new MenuItemModel("ProjectSettings")
{
Header = "Project Settings",
Expand Down Expand Up @@ -211,4 +214,18 @@ await _windowService.ShowDialogAsync(new UniversalFpgaProjectSettingsEditorView
typeof(UniversalFpgaProjectRoot), root))
});
}

private async Task CleanBuildFoldersAsync(UniversalFpgaProjectRoot root)
{
var buildFolderPath = Path.Combine(root.RootFolderPath, "build");
_outputService.WriteLine($"Cleaning build folders: {buildFolderPath}");
if (Directory.Exists(buildFolderPath))
{
await Task.Run(() =>
{
Directory.Delete(buildFolderPath, true);
Directory.CreateDirectory(buildFolderPath);
});
}
}
}
Loading