Skip to content

Commit

Permalink
fix and save files when opening pinplanner/compile
Browse files Browse the repository at this point in the history
  • Loading branch information
HendrikMennen committed Nov 9, 2024
1 parent c97ec7b commit 17e3df9
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/OneWare.Essentials/Services/IProjectExplorerService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public Task<IProjectRoot?>
public Task SaveProjectAsync(IProjectRoot project);
public Task SaveLastProjectsFileAsync();
public Task OpenLastProjectsFileAsync();
public Task<bool> SaveOpenFilesForProjectAsync(IProjectRoot project);

public void RegisterConstructContextMenu(
Action<IReadOnlyList<IProjectExplorerNode>, IList<MenuItemViewModel>> construct);
Expand Down
10 changes: 10 additions & 0 deletions src/OneWare.ProjectExplorer/ViewModels/ProjectExplorerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,16 @@ public Task SaveProjectAsync(IProjectRoot project)
if (manager == null) throw new NullReferenceException(nameof(manager));
return manager.SaveProjectAsync(project);
}

public async Task<bool> SaveOpenFilesForProjectAsync(IProjectRoot project)
{
var saveTasks = _dockService.OpenFiles.Where(x => x.Key is IProjectFile file && file.Root == project)
.Select(x => x.Value.SaveAsync());

var results = await Task.WhenAll(saveTasks);

return results.All(x => x);
}

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,23 @@ public async Task CompileAsync()
{
if(EnsureProjectAndFpga() is not {project: not null, fpga: not null} data) return;

await ProjectExplorerService.SaveOpenFilesForProjectAsync(data.project);
await data.project.RunToolchainAsync(data.fpga);
}

public async Task OpenPinPlannerAsync()
{
if (ProjectExplorerService.ActiveProject is UniversalFpgaProjectRoot project)
{
await ProjectExplorerService.SaveOpenFilesForProjectAsync(project);

await _windowService.ShowDialogAsync(new UniversalFpgaProjectPinPlannerView
{
DataContext =
ContainerLocator.Container.Resolve<UniversalFpgaProjectPinPlannerViewModel>((
typeof(UniversalFpgaProjectRoot), project))
});
}
}

public async Task OpenProjectSettingsAsync()
Expand Down
55 changes: 39 additions & 16 deletions src/OneWare.Vhdl/Parsing/VhdlNodeProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ private static Dictionary<string, int> ExtractGenerics(string vhdlCode)

foreach (Match match in genericDeclarations)
{
var name = match.Groups[1].Value;
var value = match.Groups[2].Value;
genericValues[name] = int.Parse(value);
var name = match.Groups[1].Value.Trim();
var value = match.Groups[2].Value.Trim();
if (int.TryParse(value, out int intValue))
{
genericValues[name] = intValue;
}
}
}

Expand All @@ -69,31 +72,50 @@ private static void ExtractPorts(string vhdlCode, List<FpgaNode> nodes, Dictiona

if (vectorMatch.Success)
{
var name = vectorMatch.Groups[1].Value;
var direction = vectorMatch.Groups[2].Value.ToUpper();
var name = vectorMatch.Groups[1].Value.Trim();
var direction = vectorMatch.Groups[2].Value.ToUpper().Trim();
var upperBoundExpr = vectorMatch.Groups[3].Value.Trim();
var lowerBoundExpr = vectorMatch.Groups[4].Value.Trim();

var upperBound = EvaluateExpression(upperBoundExpr, genericValues);
var lowerBound = EvaluateExpression(lowerBoundExpr, genericValues);

// Create nodes for each bit in the vector
for (var i = lowerBound; i <= upperBound; i++)
try
{
var upperBound = EvaluateExpression(upperBoundExpr, genericValues);
var lowerBound = EvaluateExpression(lowerBoundExpr, genericValues);

// Create nodes for each bit in the vector
if (upperBound >= lowerBound)
{
for (var i = lowerBound; i <= upperBound; i++)
{
nodes.Add(new FpgaNode($"{name}[{i}]", direction));
}
}
else
{
for (var i = lowerBound; i >= upperBound; i--)
{
nodes.Add(new FpgaNode($"{name}[{i}]", direction));
}
}
}
catch (Exception ex)
{
nodes.Add(new FpgaNode($"{name}[{i}]", direction));
Console.WriteLine($"Error processing vector {name}: {ex.Message}");
}
}
else if (logicMatch.Success)
{
nodes.Add(new FpgaNode(logicMatch.Groups[1].Value, logicMatch.Groups[2].Value.ToUpper()));
var name = logicMatch.Groups[1].Value.Trim();
var direction = logicMatch.Groups[2].Value.ToUpper().Trim();
nodes.Add(new FpgaNode(name, direction));
}
}
}

private static int EvaluateExpression(string expression, Dictionary<string, int> genericValues)
{
// Replace generic constants with their values
foreach (var generic in genericValues)
foreach (var generic in genericValues.OrderByDescending(x => x.Key.Length))
{
expression = Regex.Replace(expression,
$@"\b{generic.Key}\b",
Expand All @@ -107,15 +129,16 @@ private static int EvaluateExpression(string expression, Dictionary<string, int>
try
{
var dt = new DataTable();
return Convert.ToInt32(dt.Compute(expression, ""));
var result = dt.Compute(expression, "");
return Convert.ToInt32(result);
}
catch (Exception)
{
throw new ArgumentException($"Unable to evaluate expression: {expression}");
}
}

[GeneratedRegex(@"(\w+)\s*:\s*(IN|OUT|INOUT)\s*STD_LOGIC(?:\s*:=\s*'[01]')?", RegexOptions.IgnoreCase, "en-US")]
[GeneratedRegex(@"(\w+)\s*:\s*(IN|OUT|INOUT|BUFFER)\s*STD_LOGIC(?:\s*:=\s*'[01]')?", RegexOptions.IgnoreCase, "en-US")]
private static partial Regex LogicMatch();

[GeneratedRegex(@"port\s*\(((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*)\)\s*;", RegexOptions.IgnoreCase | RegexOptions.Singleline, "en-US")]
Expand All @@ -127,6 +150,6 @@ private static int EvaluateExpression(string expression, Dictionary<string, int>
[GeneratedRegex(@"(\w+)\s*:\s*\w+\s*:=\s*(\d+)")]
private static partial Regex GenericDeclarationMatch();

[GeneratedRegex(@"(\w+)\s*:\s*(IN|OUT|INOUT)\s*STD_LOGIC_VECTOR\s*\(\s*(\d+|\w+(?:\s*[+\-*/]\s*\d+)?)\s*downto\s*(\d+|\w+(?:\s*[+\-*/]\s*\d+)?)\s*\)(?:\s*:=\s*[^;]+)?", RegexOptions.IgnoreCase, "en-US")]
[GeneratedRegex(@"(\w+)\s*:\s*(IN|OUT|INOUT|BUFFER)\s*STD_LOGIC_VECTOR\s*\(\s*([^)]+)\s*downto\s*([^)]+)\s*\)(?:\s*:=\s*[^;]+)?", RegexOptions.IgnoreCase, "en-US")]
private static partial Regex VectorMatch();
}

0 comments on commit 17e3df9

Please sign in to comment.