diff --git a/package.json b/package.json index c87f191..5c971ed 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,11 @@ "type": "boolean", "default": false, "description": "Keep ModelSim result files for debugging." + }, + "modelsimWave.interMediateSignalMapping": { + "type": "string", + "default": "", + "description": "Path to a signal name translation file" } } } diff --git a/src/extension.ts b/src/extension.ts index 57d2582..3361042 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,10 +1,12 @@ import * as vscode from 'vscode'; import * as path from 'path'; import { promises as fsp } from 'fs'; +import * as os from 'os'; import { MyWebviewViewProvider } from './wave_action'; import { sendAndAwait } from './eda_connect'; import { requestModuleTree, addWave } from './wave_editor'; +import { loadMappingJson } from './signal_mapping'; // Tracks the most recent hover position per document, with a timestamp. export const lastHoverByDoc = new Map(); @@ -14,6 +16,8 @@ let statusItem: vscode.StatusBarItem; const CTX = 'modelsim.mode'; export let waveMode = false; +export let waveMappingEnable = false; + // Hold MANY instance paths per module name, e.g. queue_slot -> ["/test/...[0]", "/test/...[1]", ...] const svSelectors: vscode.DocumentSelector = [ @@ -30,6 +34,45 @@ async function toggleWaveMode() { statusItem.tooltip = waveMode ? 'Wave Debug Mode — click to switch to Edit Mode' : 'Edit Mode — click to switch to Wave Debug Mode'; + + // Load Wave Mapping + if (waveMode) { + const cfg = vscode.workspace.getConfiguration('modelsimWave'); + let p = cfg.get('interMediateSignalMapping')?.trim() ?? ''; + + console.log("File defined: ", p); + + if (!p) { + waveMappingEnable = false; + return; + } + + waveMappingEnable = true; + + // Expand ~ to home + if (p.startsWith('~')) { + p = path.join(os.homedir(), p.slice(1)); + } + + if (p.startsWith('${workspaceFolder}')) { + const wf = vscode.workspace.workspaceFolders?.[0]; + if (!wf) return; + const rel = p.replace('${workspaceFolder}', ''); + loadMappingJson(vscode.Uri.file(path.join(wf.uri.fsPath, rel))); + return; + } + + // Absolute path? + if (path.isAbsolute(p)) { + loadMappingJson(vscode.Uri.file(p)); + return; + } + + // Otherwise, treat as path relative to the first workspace folder + const wf = vscode.workspace.workspaceFolders?.[0]; + if (!wf) return; + loadMappingJson(vscode.Uri.file(path.join(wf.uri.fsPath, p))); + } } export async function activate(context: vscode.ExtensionContext) { diff --git a/src/signal_mapping.ts b/src/signal_mapping.ts new file mode 100644 index 0000000..73b132d --- /dev/null +++ b/src/signal_mapping.ts @@ -0,0 +1,33 @@ +import * as vscode from "vscode"; + +export const globalMap: Map = new Map(); + +export async function loadMappingJson(uri: vscode.Uri): Promise { + const bytes = await vscode.workspace.fs.readFile(uri); + const text = new TextDecoder('utf-8').decode(bytes); + + let raw: unknown; + try { + raw = JSON.parse(text); + } catch (err: any) { + throw new Error(`Failed to parse JSON: ${err?.message ?? String(err)}`); + } + + if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) { + throw new Error(`Expected a JSON object at top level (key → value mapping).`); + } + + const obj = raw as Record; + + globalMap.clear(); + + for (const [key, value] of Object.entries(obj)) { + if (typeof value !== 'string') { + console.warn(`⚠️ Skipping key '${key}' because its value is not a string.`); + continue; + } + globalMap.set(key, value); + } + + console.log(`✅ Loaded ${globalMap.size} valid mappings from ${uri.fsPath}`); +} diff --git a/src/wave_editor.ts b/src/wave_editor.ts index d4b9977..c7c0bdd 100644 --- a/src/wave_editor.ts +++ b/src/wave_editor.ts @@ -1,8 +1,9 @@ import * as vscode from 'vscode'; import * as path from 'path'; -import { waveMode, lastHoverByDoc, HOVER_FRESH_MS } from './extension'; +import { waveMode, lastHoverByDoc, waveMappingEnable, HOVER_FRESH_MS } from './extension'; import { sendAndAwait } from './eda_connect'; +import { globalMap } from './signal_mapping'; export let moduleTree: Record = {}; @@ -69,7 +70,7 @@ export async function addWave( return; } - const tokenText = editor.document.getText(wordRange); + let tokenText = editor.document.getText(wordRange); const isVariable = await looksLikeVariable(editor, position); if (!isVariable) { const choice = await vscode.window.showWarningMessage( @@ -80,6 +81,13 @@ export async function addWave( if (choice !== 'Add') return; } + if (waveMappingEnable) { + if (globalMap.has(tokenText)) { + tokenText = globalMap.get(tokenText)!; // "!" asserts it's not undefined + // do something with truc + } + } + // Load module tree once per session if (Object.keys(moduleTree).length === 0) { moduleTree = await requestModuleTree(sharedDir, topScope, timeoutMs);