增加对于 IP 的解析

This commit is contained in:
锦恢 2024-11-08 23:00:26 +08:00
parent 0c820c7e55
commit 98e5de8686
11 changed files with 142 additions and 33 deletions

1
images/svg/dark/ip.svg Normal file
View File

@ -0,0 +1 @@
<svg t="1731048022644" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5088" width="200" height="200"><path d="M924.672 625.664l-65.536-55.808c3.072-18.944 4.608-38.4 4.608-57.856s-1.536-38.912-4.608-57.856l65.536-55.808c10.24-8.704 13.824-22.528 9.216-35.328l-1.024-2.56c-17.92-50.688-45.056-96.768-79.872-137.728l-2.048-2.048c-8.704-10.24-22.528-13.824-35.328-9.728l-81.408 28.672c-30.208-24.576-63.488-44.032-99.84-57.856L620.032 97.28c-2.56-13.312-12.8-23.552-25.6-25.6l-2.56-0.512c-52.224-9.216-107.008-9.216-159.232 0l-3.072 0.512c-13.312 2.56-23.552 12.8-25.6 25.6l-15.872 85.504c-35.84 13.824-69.12 32.768-98.816 57.344l-81.92-29.184c-12.288-4.608-26.624-0.512-35.328 9.728l-2.048 2.048c-34.816 40.96-61.44 87.552-79.872 137.728l-1.024 2.56c-4.608 12.288-1.024 26.624 9.216 35.328l66.048 56.832c-3.072 18.944-4.608 37.888-4.608 57.344 0 18.944 1.536 38.4 4.608 57.344l-66.048 56.832c-10.24 8.704-13.824 22.528-9.216 35.328l1.024 2.56c17.92 50.176 45.056 96.768 79.872 137.728l2.048 2.048c8.704 10.24 22.528 13.824 35.328 9.728l81.92-29.184c29.696 24.576 62.976 44.032 98.816 57.344l15.872 85.504c2.56 13.312 12.8 23.552 25.6 25.6l2.56 0.512c26.112 4.608 52.736 7.168 79.36 7.168 26.624 0 53.248-2.56 79.36-7.168l2.56-0.512c13.312-2.56 23.552-12.8 25.6-25.6l15.872-84.992c36.352-13.824 69.632-32.768 99.84-57.344l81.408 28.672c12.288 4.608 26.624 0.512 35.328-9.728l2.048-2.048c34.816-40.96 61.44-87.552 79.872-137.728l1.024-2.56c4.096-13.312 0.512-27.648-9.728-36.352zM788.48 465.92c2.56 14.848 3.584 30.72 3.584 46.08s-1.536 31.232-3.584 46.08l-6.656 39.936 74.752 64c-11.264 26.112-25.6 50.688-42.496 73.728l-92.672-32.768-31.232 25.6c-24.064 19.456-50.688 34.816-79.36 45.568l-37.888 14.336-17.92 96.768c-28.16 3.072-56.832 3.072-84.992 0l-17.92-97.28-37.888-14.336c-28.672-10.752-54.784-26.112-78.848-45.568l-31.232-26.112-93.184 33.28c-16.896-23.04-31.232-47.616-42.496-73.728l75.264-64.512-6.656-39.936c-2.56-14.848-3.584-30.208-3.584-45.568s1.024-30.72 3.584-45.568l6.656-39.936-76.288-64c11.264-26.112 25.6-50.688 42.496-73.728l93.184 33.28 31.232-26.112c23.552-19.456 50.176-34.816 78.848-45.568l37.888-14.336 17.92-97.28c28.16-3.072 56.832-3.072 84.992 0l17.92 96.768 37.888 14.336c28.672 10.752 55.296 26.112 79.36 45.568l31.232 25.6 92.672-32.768c16.896 23.04 31.232 47.616 42.496 73.728l-74.752 64L788.48 465.92z" p-id="5089" fill="#c5c5c5"></path><path d="M353.28 363.008h79.36v297.984H353.28V363.008zM484.352 363.008h106.496c47.616 0 70.656 7.68 90.624 23.04 19.968 15.36 35.328 39.424 35.328 71.68s-14.848 56.832-34.816 73.728c-19.456 16.896-40.448 25.088-78.336 25.088h-39.936V660.48H490.496l-6.144-297.472z m79.36 53.76v86.528h27.136c15.872 0 38.4-3.584 46.08-10.24 8.192-7.168 12.288-17.408 12.288-31.232 0-14.848-3.584-26.112-11.776-33.792-8.192-7.68-30.72-11.264-46.08-11.264h-27.648z" p-id="5090" fill="#c5c5c5"></path></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

14
images/svg/light/ip.svg Normal file
View File

@ -0,0 +1,14 @@
<svg
t="1731048022644"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5088"
width="200"
height="200"
>
<path d="M924.672 625.664l-65.536-55.808c3.072-18.944 4.608-38.4 4.608-57.856s-1.536-38.912-4.608-57.856l65.536-55.808c10.24-8.704 13.824-22.528 9.216-35.328l-1.024-2.56c-17.92-50.688-45.056-96.768-79.872-137.728l-2.048-2.048c-8.704-10.24-22.528-13.824-35.328-9.728l-81.408 28.672c-30.208-24.576-63.488-44.032-99.84-57.856L620.032 97.28c-2.56-13.312-12.8-23.552-25.6-25.6l-2.56-0.512c-52.224-9.216-107.008-9.216-159.232 0l-3.072 0.512c-13.312 2.56-23.552 12.8-25.6 25.6l-15.872 85.504c-35.84 13.824-69.12 32.768-98.816 57.344l-81.92-29.184c-12.288-4.608-26.624-0.512-35.328 9.728l-2.048 2.048c-34.816 40.96-61.44 87.552-79.872 137.728l-1.024 2.56c-4.608 12.288-1.024 26.624 9.216 35.328l66.048 56.832c-3.072 18.944-4.608 37.888-4.608 57.344 0 18.944 1.536 38.4 4.608 57.344l-66.048 56.832c-10.24 8.704-13.824 22.528-9.216 35.328l1.024 2.56c17.92 50.176 45.056 96.768 79.872 137.728l2.048 2.048c8.704 10.24 22.528 13.824 35.328 9.728l81.92-29.184c29.696 24.576 62.976 44.032 98.816 57.344l15.872 85.504c2.56 13.312 12.8 23.552 25.6 25.6l2.56 0.512c26.112 4.608 52.736 7.168 79.36 7.168 26.624 0 53.248-2.56 79.36-7.168l2.56-0.512c13.312-2.56 23.552-12.8 25.6-25.6l15.872-84.992c36.352-13.824 69.632-32.768 99.84-57.344l81.408 28.672c12.288 4.608 26.624 0.512 35.328-9.728l2.048-2.048c34.816-40.96 61.44-87.552 79.872-137.728l1.024-2.56c4.096-13.312 0.512-27.648-9.728-36.352zM788.48 465.92c2.56 14.848 3.584 30.72 3.584 46.08s-1.536 31.232-3.584 46.08l-6.656 39.936 74.752 64c-11.264 26.112-25.6 50.688-42.496 73.728l-92.672-32.768-31.232 25.6c-24.064 19.456-50.688 34.816-79.36 45.568l-37.888 14.336-17.92 96.768c-28.16 3.072-56.832 3.072-84.992 0l-17.92-97.28-37.888-14.336c-28.672-10.752-54.784-26.112-78.848-45.568l-31.232-26.112-93.184 33.28c-16.896-23.04-31.232-47.616-42.496-73.728l75.264-64.512-6.656-39.936c-2.56-14.848-3.584-30.208-3.584-45.568s1.024-30.72 3.584-45.568l6.656-39.936-76.288-64c11.264-26.112 25.6-50.688 42.496-73.728l93.184 33.28 31.232-26.112c23.552-19.456 50.176-34.816 78.848-45.568l37.888-14.336 17.92-97.28c28.16-3.072 56.832-3.072 84.992 0l17.92 96.768 37.888 14.336c28.672 10.752 55.296 26.112 79.36 45.568l31.232 25.6 92.672-32.768c16.896 23.04 31.232 47.616 42.496 73.728l-74.752 64L788.48 465.92z" p-id="5089">
</path>
<path d="M353.28 363.008h79.36v297.984H353.28V363.008zM484.352 363.008h106.496c47.616 0 70.656 7.68 90.624 23.04 19.968 15.36 35.328 39.424 35.328 71.68s-14.848 56.832-34.816 73.728c-19.456 16.896-40.448 25.088-78.336 25.088h-39.936V660.48H490.496l-6.144-297.472z m79.36 53.76v86.528h27.136c15.872 0 38.4-3.584 46.08-10.24 8.192-7.168 12.288-17.408 12.288-31.232 0-14.848-3.584-26.112-11.776-33.792-8.192-7.68-30.72-11.264-46.08-11.264h-27.648z" p-id="5090">
</path></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -25,5 +25,6 @@
"error.vcd-viewer.unexist-direct-vcd-file": "Die von der Ansichtsdatei referenzierte vcd-Datei existiert nicht",
"info.welcome.join-qq-group": "Klicken Sie auf den Link, um der QQ-Gruppe beizutreten",
"info.level.test": "Dies ist ein einfaches Beispiel",
"info.progress.build-ip-module-tree": "构建 IP 模块树"
"info.progress.build-ip-module-tree": "构建 IP 模块树",
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核"
}

View File

@ -25,5 +25,6 @@
"error.vcd-viewer.unexist-direct-vcd-file": "The vcd file pointed to by the view file does not exist",
"info.welcome.join-qq-group": "Click the link to join the QQ group",
"info.level.test": "This is a simple example",
"info.progress.build-ip-module-tree": "构建 IP 模块树"
"info.progress.build-ip-module-tree": "构建 IP 模块树",
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核"
}

View File

@ -25,5 +25,6 @@
"error.vcd-viewer.unexist-direct-vcd-file": "ビューファイルが指す vcd ファイルは存在しません",
"info.welcome.join-qq-group": "リンクをクリックして QQ グループに参加",
"info.level.test": "これは簡単な例です",
"info.progress.build-ip-module-tree": "构建 IP 模块树"
"info.progress.build-ip-module-tree": "构建 IP 模块树",
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核"
}

View File

@ -25,5 +25,6 @@
"error.vcd-viewer.unexist-direct-vcd-file": "视图文件指向的 vcd 文件不存在",
"info.welcome.join-qq-group": "点击链接加入 QQ 群",
"info.level.test": "这是一个简单的样例",
"info.progress.build-ip-module-tree": "构建 IP 模块树"
"info.progress.build-ip-module-tree": "构建 IP 模块树",
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核"
}

View File

@ -25,5 +25,6 @@
"error.vcd-viewer.unexist-direct-vcd-file": "視圖文件指向的 vcd 文件不存在",
"info.welcome.join-qq-group": "點擊鏈接加入 QQ 群",
"info.level.test": "這是一個簡單的樣例",
"info.progress.build-ip-module-tree": "构建 IP 模块树"
"info.progress.build-ip-module-tree": "构建 IP 模块树",
"info.treeview.ip-no-active.message": "当前 IP 还未激活,请通过 Xilinx 工具链将 XCI 文件生成完整的 IP 核"
}

View File

@ -1,12 +1,21 @@
import * as vscode from 'vscode';
import { hdlPath } from '../../hdlFs';
import * as fs from 'fs';
import * as fspath from 'path';
import { hdlFile, hdlPath } from '../../hdlFs';
import { hardwareTreeProvider, softwareTreeProvider, toolTreeProvider } from './command';
import { moduleTreeProvider, ModuleDataItem } from './tree';
import { Range } from '../../hdlParser/common';
import { MainOutput, opeParam, ReportType } from '../../global';
async function openFileAtPosition(uri: vscode.Uri, range: Range) {
async function openFileAtPosition(uri: vscode.Uri, range?: Range) {
if (range === undefined) {
range = {
start: { line: 0, character: 0 },
end: { line: 0, character: 0 }
}
}
const document = await vscode.workspace.openTextDocument(uri);
const start = new vscode.Position(range.start.line, range.start.character);
const end = new vscode.Position(range.end.line, range.end.character);
@ -19,15 +28,43 @@ async function openFileAtPosition(uri: vscode.Uri, range: Range) {
);
}
function openFileByUri(path: string, range: Range) {
function openFileByUri(path: string, range: Range, element: ModuleDataItem) {
const { t } = vscode.l10n;
if (range === undefined) {
vscode.window.showErrorMessage(`${path} not support jump yet`);
return;
}
if (hdlPath.exist(path)) {
if (hdlPath.exist(path) && hdlFile.isFile(path)) {
const uri = vscode.Uri.file(path);
openFileAtPosition(uri, range);
return;
} else {
if (element.doFastFileType === 'ip') {
switch (opeParam.prjInfo.toolChain) {
case 'xilinx':
return gotoXilinxIPDefinition(element);
default:
break;
}
}
}
MainOutput.report("invalid jump uri triggered in treeview, el: " + JSON.stringify(element, null, ' '), ReportType.Error);
}
function gotoXilinxIPDefinition(element: ModuleDataItem) {
const { t } = vscode.l10n;
const folderPath = element.path;
if (folderPath) {
const ipName = fspath.basename(folderPath);
const defPath = hdlPath.join(folderPath, 'synth', ipName + '.vhd');
if (fs.existsSync(defPath)) {
openFileAtPosition(vscode.Uri.file(defPath), element.range);
} else {
vscode.window.showInformationMessage(t('info.treeview.ip-no-active.message'));
}
} else {
MainOutput.report("[gotoXilinxIPDefinition] path is undefined", ReportType.Error);
}
}

View File

@ -7,6 +7,7 @@ import { HdlFileType, Range } from '../../hdlParser/common';
import { hdlFile, hdlPath } from '../../hdlFs';
import { xilinx, itemModes, otherModes } from './common';
import { getIconConfig } from '../../hdlFs/icons';
import { DoFastFileType } from '../../global/lsp';
let needExpand = true;
@ -14,9 +15,10 @@ interface ModuleDataItem {
icon: string, // 图标
name: string, // module name
type: string,
range: Range | undefined | null,
doFastFileType: DoFastFileType | undefined,
range: Range | undefined,
path: AbsPath | undefined, // path of the file
parent: ModuleDataItem | null // parent file
parent: ModuleDataItem | undefined // parent file
}
interface FirstTopItem {
@ -65,8 +67,26 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
src: null,
sim: null,
};
this.srcRootItem = {icon: 'src', type: HdlFileType.Src, name: 'src', range: null, path: '', parent: null};
this.simRootItem = {icon: 'sim', type: HdlFileType.Sim, name: 'sim', range: null, path: '', parent: null};
this.srcRootItem = {
icon: 'src',
type: HdlFileType.Src,
doFastFileType: undefined,
name: 'src',
range: undefined,
path: '',
parent: undefined
};
this.simRootItem = {
icon: 'sim',
type: HdlFileType.Sim,
doFastFileType: undefined,
name: 'sim',
range: undefined,
path: '',
parent: undefined
};
}
public refresh(element?: ModuleDataItem) {
@ -125,7 +145,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
treeItem.command = {
title: "Open this HDL File",
command: 'digital-ide.treeView.arch.openFile',
arguments: [element.path, element.range],
arguments: [element.path, element.range, element],
};
return treeItem;
@ -135,7 +155,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
if (element) {
const name = element.name;
if (name === 'sim' || name === 'src') {
element.parent = null;
element.parent = undefined;
return this.getTopModuleItemList(element);
} else {
return this.getInstanceItemList(element);
@ -158,10 +178,11 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
const hardwarePath = opeParam.prjInfo.arch.hardware;
const moduleType = element.name as keyof (SrcPath & SimPath);
const topModules = hdlParam.getTopModulesByType(moduleType);
const topModules = hdlParam.getTopModulesByType(moduleType);
const topModuleItemList = topModules.map<ModuleDataItem>(module => ({
icon: 'top',
icon: this.judgeTopModuleIconByDoFastType(module.file.doFastType),
type: moduleType,
doFastFileType: module.file.doFastType,
name: module.name,
range: module.range,
path: module.path,
@ -180,6 +201,8 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
const icon = this.makeFirstTopIconName(type);
const range = firstTop.range;
const parent = element;
// TODO: check
const doFastFileType = undefined;
const tops = topModuleItemList.filter(item => item.path === path && item.name === name);
const adjustItemList = [];
@ -198,7 +221,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
} else {
// mean the selected top is not an original top module
// create it and add it to the head of *topModuleItemList*
const selectedTopItem: ModuleDataItem = {icon, type, name, range, path, parent};
const selectedTopItem: ModuleDataItem = {icon, type, name, range, path, parent, doFastFileType};
adjustItemList.push(selectedTopItem);
adjustItemList.push(...topModuleItemList);
}
@ -219,14 +242,16 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
if (targetModule) {
for (const instance of targetModule.getAllInstances()) {
// 所有的例化模块都定向到它的定义文件上
// 所有的例化模块都定向到它的定义文件上
const item: ModuleDataItem = {
icon: 'file',
type: instance.name,
name: instance.type,
range: instance.module?.range,
path: instance.module?.path,
parent: element
parent: element,
doFastFileType: instance.getDoFastFileType
};
if (item.type === element.type && // 防止递归
@ -260,6 +285,10 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
return 'File Error';
}
if (item.doFastFileType === 'ip') {
return 'ip';
}
if (hdlPath.exist(item.path)) {
if (!item.path?.includes(workspacePath)) {
return 'remote';
@ -276,6 +305,19 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
}
}
private judgeTopModuleIconByDoFastType(doFastType: DoFastFileType): string {
switch (doFastType) {
case 'common':
return 'top';
case 'ip':
return 'ip';
case 'primitives':
return 'celllib';
}
return 'top';
}
public getItemType(item: ModuleDataItem): string | null {
if (!item) {
return null;

View File

@ -230,7 +230,7 @@ class HdlParam {
try {
const fast = await HdlSymbol.fast(path, fileType);
if (fast) {
const languageId = hdlFile.getLanguageId(path);
const languageId = this.getRealLanguageId(path, fast.fileType);
new HdlFile(path,
languageId,
fast.macro,
@ -243,6 +243,13 @@ class HdlParam {
}
}
private getRealLanguageId(path: string, fileType: DoFastFileType): HdlLangID {
if (fileType === 'ip' && opeParam.prjInfo.toolChain === 'xilinx') {
return HdlLangID.Vhdl;
}
return hdlFile.getLanguageId(path);
}
public async initializeHdlFiles(hdlFiles: AbsPath[], progress: vscode.Progress<IProgress>) {
const { t } = vscode.l10n;
@ -267,9 +274,7 @@ class HdlParam {
}
for (const path of hdlFiles) {
count ++;
console.log('send request: ' + path);
count ++;
const p = this.doHdlFast(path, 'common');
pools.push({ id: count, promise: p, path });
if (pools.length % parallelChunk === 0) {
@ -307,9 +312,7 @@ class HdlParam {
}
for (const path of IPsPath) {
count ++;
console.log('send request: ' + path);
count ++;
const p = this.doHdlFast(path, 'ip');
pools.push({ id: count, promise: p, path });
if (pools.length % parallelChunk === 0) {
@ -439,8 +442,8 @@ class HdlInstance {
instModPathStatus: common.InstModPathStatus; // status of the instance (current, include, others)
instparams: common.InstRange; // range of params
instports: common.InstRange; // range of ports
parentMod: HdlModule; // HdlModule that the instance serves
module: HdlModule | undefined; // module
parentMod: HdlModule; // 例化模块例化地点的外层 module
module: HdlModule | undefined; // 例化模块的定义模块
constructor(name: string,
type: string,
@ -511,6 +514,10 @@ class HdlInstance {
this.instModPath = this.parentMod.path;
this.instModPathStatus = this.parentMod.solveInstModPathStatus();
}
public get getDoFastFileType(): DoFastFileType | undefined {
return this.module?.file.doFastType;
}
};
class HdlModule {
@ -706,7 +713,10 @@ class HdlModule {
// search other files in the project
for (const hdlFile of hdlParam.getAllHdlFiles()) {
if (!excludeFile.has(hdlFile) && hdlFile.hasHdlModule(instModName)) {
return {path: hdlFile.path, status: common.InstModPathStatus.Others};
return {
path: hdlFile.path,
status: common.InstModPathStatus.Others
};
}
}

View File

@ -165,7 +165,7 @@ class PrjManage {
public isValidXilinxIP(folderPath: string): boolean {
const folderName = fspath.basename(folderPath);
const descriptionFile = folderName + '.vho';
const descriptionFile = folderName + '.xci';
const descriptionFilePath = hdlPath.join(folderPath, descriptionFile);
return fs.existsSync(descriptionFilePath);
}
@ -182,14 +182,14 @@ class PrjManage {
prjManage.refreshPrjFolder(refreshPrjConfig);
// 解析 hdl 文件,构建 hdlParam
const hdlFiles = await this.getPrjHardwareFiles();
const hdlFiles = await this.getPrjHardwareFiles();
await hdlParam.initializeHdlFiles(hdlFiles, progress);
// 根据 toolchain 解析合法的 IP构建 hdlParam
const IPsPath = await this.getPrjIPs();
await hdlParam.initializeIPsPath(IPsPath, progress);
// TODO: 解析原语并构建
// TODO: 解析原语并构建,向后端索要原语缓存
// 构建 instance 解析