Adding signal mapping file
This commit is contained in:
@@ -61,6 +61,11 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Keep ModelSim result files for debugging."
|
"description": "Keep ModelSim result files for debugging."
|
||||||
|
},
|
||||||
|
"modelsimWave.interMediateSignalMapping": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "",
|
||||||
|
"description": "Path to a signal name translation file"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { promises as fsp } from 'fs';
|
import { promises as fsp } from 'fs';
|
||||||
|
import * as os from 'os';
|
||||||
|
|
||||||
import { MyWebviewViewProvider } from './wave_action';
|
import { MyWebviewViewProvider } from './wave_action';
|
||||||
import { sendAndAwait } from './eda_connect';
|
import { sendAndAwait } from './eda_connect';
|
||||||
import { requestModuleTree, addWave } from './wave_editor';
|
import { requestModuleTree, addWave } from './wave_editor';
|
||||||
|
import { loadMappingJson } from './signal_mapping';
|
||||||
|
|
||||||
// Tracks the most recent hover position per document, with a timestamp.
|
// Tracks the most recent hover position per document, with a timestamp.
|
||||||
export const lastHoverByDoc = new Map<string, { pos: vscode.Position; at: number }>();
|
export const lastHoverByDoc = new Map<string, { pos: vscode.Position; at: number }>();
|
||||||
@@ -14,6 +16,8 @@ let statusItem: vscode.StatusBarItem;
|
|||||||
const CTX = 'modelsim.mode';
|
const CTX = 'modelsim.mode';
|
||||||
export let waveMode = false;
|
export let waveMode = false;
|
||||||
|
|
||||||
|
export let waveMappingEnable = false;
|
||||||
|
|
||||||
// Hold MANY instance paths per module name, e.g. queue_slot -> ["/test/...[0]", "/test/...[1]", ...]
|
// Hold MANY instance paths per module name, e.g. queue_slot -> ["/test/...[0]", "/test/...[1]", ...]
|
||||||
|
|
||||||
const svSelectors: vscode.DocumentSelector = [
|
const svSelectors: vscode.DocumentSelector = [
|
||||||
@@ -30,6 +34,45 @@ async function toggleWaveMode() {
|
|||||||
statusItem.tooltip = waveMode
|
statusItem.tooltip = waveMode
|
||||||
? 'Wave Debug Mode — click to switch to Edit Mode'
|
? 'Wave Debug Mode — click to switch to Edit Mode'
|
||||||
: 'Edit Mode — click to switch to Wave Debug 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<string>('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) {
|
export async function activate(context: vscode.ExtensionContext) {
|
||||||
|
|||||||
33
src/signal_mapping.ts
Normal file
33
src/signal_mapping.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import * as vscode from "vscode";
|
||||||
|
|
||||||
|
export const globalMap: Map<string, string> = new Map();
|
||||||
|
|
||||||
|
export async function loadMappingJson(uri: vscode.Uri): Promise<void> {
|
||||||
|
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<string, unknown>;
|
||||||
|
|
||||||
|
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}`);
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as path from 'path';
|
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 { sendAndAwait } from './eda_connect';
|
||||||
|
import { globalMap } from './signal_mapping';
|
||||||
|
|
||||||
export let moduleTree: Record<string, { module: string[], last: number }> = {};
|
export let moduleTree: Record<string, { module: string[], last: number }> = {};
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ export async function addWave(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenText = editor.document.getText(wordRange);
|
let tokenText = editor.document.getText(wordRange);
|
||||||
const isVariable = await looksLikeVariable(editor, position);
|
const isVariable = await looksLikeVariable(editor, position);
|
||||||
if (!isVariable) {
|
if (!isVariable) {
|
||||||
const choice = await vscode.window.showWarningMessage(
|
const choice = await vscode.window.showWarningMessage(
|
||||||
@@ -80,6 +81,13 @@ export async function addWave(
|
|||||||
if (choice !== 'Add') return;
|
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
|
// Load module tree once per session
|
||||||
if (Object.keys(moduleTree).length === 0) {
|
if (Object.keys(moduleTree).length === 0) {
|
||||||
moduleTree = await requestModuleTree(sharedDir, topScope, timeoutMs);
|
moduleTree = await requestModuleTree(sharedDir, topScope, timeoutMs);
|
||||||
|
|||||||
Reference in New Issue
Block a user