feat:接入iverilog工具

- 将iverilog可以随着插件的下载而下载
- 用户输入自然语言就可以控制生成对应的VCD文件
This commit is contained in:
Roe-xin
2025-12-15 11:09:03 +08:00
parent 94225a3525
commit 22b9a0ed13
71 changed files with 2020 additions and 87 deletions

View File

@ -8,16 +8,28 @@ import {
renameFile,
replaceFile,
} from "./createFiles";
import {
generateVCD,
checkVerilogProject,
checkIverilogAvailable,
} from "./iverilogRunner";
/**
* 处理用户消息
*/
export async function handleUserMessage(
panel: vscode.WebviewPanel,
text: string
text: string,
extensionPath?: string
) {
console.log("收到用户消息:", text);
// 检查是否是 VCD 生成命令
if (isVCDGenerationCommand(text)) {
await handleVCDGeneration(panel, extensionPath || "");
return;
}
// 检查是否是文件操作命令
const fileOperation = parseFileOperation(text);
@ -466,3 +478,161 @@ export function insertCodeToEditor(code: string) {
vscode.window.showWarningMessage("请先打开一个编辑器");
}
}
/**
* 检查是否是 VCD 生成命令
*/
function isVCDGenerationCommand(text: string): boolean {
const lowerText = text.toLowerCase().trim();
// 匹配各种 VCD 生成命令
const vcdPatterns = [
/生成\s*vcd/,
/创建\s*vcd/,
/运行\s*仿真/,
/执行\s*仿真/,
/iverilog/,
/生成\s*波形/,
/仿真\s*生成/,
];
return vcdPatterns.some((pattern) => pattern.test(lowerText));
}
/**
* 处理 VCD 生成请求
*/
async function handleVCDGeneration(
panel: vscode.WebviewPanel,
extensionPath: string
) {
try {
// 获取当前工作区路径
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) {
panel.webview.postMessage({
command: "receiveMessage",
text: "❌ 请先打开一个工作区文件夹",
});
vscode.window.showErrorMessage("请先打开一个工作区文件夹");
return;
}
const projectPath = workspaceFolders[0].uri.fsPath;
// 发送开始消息
panel.webview.postMessage({
command: "receiveMessage",
text: "🔍 正在检查项目文件...",
});
// 1. 检查 iverilog 是否可用
const iverilogCheck = await checkIverilogAvailable(extensionPath);
if (!iverilogCheck.available) {
panel.webview.postMessage({
command: "receiveMessage",
text: `${iverilogCheck.message}\n\n请参考插件文档安装 iverilog 工具。`,
});
vscode.window.showErrorMessage(iverilogCheck.message);
return;
}
// 2. 检查项目文件完整性
const projectCheck = await checkVerilogProject(projectPath);
if (!projectCheck.isComplete) {
let errorMsg = "❌ 项目文件不完整:\n\n";
if (projectCheck.allVerilogFiles.length === 0) {
errorMsg += "• 未找到任何 Verilog 文件 (.v 或 .sv)\n";
} else {
errorMsg += `• 找到 ${projectCheck.allVerilogFiles.length} 个 Verilog 文件\n`;
if (!projectCheck.hasTopModule) {
errorMsg += "• ❌ 缺少顶层模块文件\n";
} else {
errorMsg += `• ✅ 顶层模块: ${projectCheck.topModuleFile}\n`;
}
if (!projectCheck.hasTestbench) {
errorMsg += "• ❌ 缺少 testbench 文件\n";
errorMsg += "\n提示: testbench 文件应包含 $dumpfile 和 $dumpvars 语句来生成 VCD 文件。\n";
} else {
errorMsg += `• ✅ Testbench: ${projectCheck.testbenchFile}\n`;
}
}
if (projectCheck.errors.length > 0) {
errorMsg += "\n错误信息:\n" + projectCheck.errors.join("\n");
}
panel.webview.postMessage({
command: "receiveMessage",
text: errorMsg,
});
vscode.window.showWarningMessage("项目文件不完整,无法生成 VCD");
return;
}
// 3. 显示项目检查结果
panel.webview.postMessage({
command: "receiveMessage",
text: `✅ 项目检查通过!\n\n找到 ${projectCheck.allVerilogFiles.length} 个 Verilog 文件\n• 顶层模块: ${projectCheck.topModuleFile}\n• Testbench: ${projectCheck.testbenchFile}\n\n🚀 开始编译和仿真...`,
});
// 4. 生成 VCD 文件
const result = await generateVCD(projectPath, extensionPath);
if (result.success) {
let successMsg = `${result.message}`;
if (result.stdout) {
successMsg += `\n\n仿真输出:\n${result.stdout}`;
}
panel.webview.postMessage({
command: "receiveMessage",
text: successMsg,
});
vscode.window.showInformationMessage(
`VCD 文件生成成功: ${result.vcdFilePath}`,
"打开文件"
).then((selection) => {
if (selection === "打开文件" && result.vcdFilePath) {
vscode.workspace.openTextDocument(result.vcdFilePath).then((doc) => {
vscode.window.showTextDocument(doc);
});
}
});
} else {
let errorMsg = `${result.message}`;
if (result.stderr) {
errorMsg += `\n\n错误输出:\n${result.stderr}`;
}
if (result.stdout) {
errorMsg += `\n\n标准输出:\n${result.stdout}`;
}
panel.webview.postMessage({
command: "receiveMessage",
text: errorMsg,
});
vscode.window.showErrorMessage("VCD 文件生成失败");
}
} catch (error) {
const errorMsg = `❌ 生成 VCD 文件时出错: ${
error instanceof Error ? error.message : "未知错误"
}`;
panel.webview.postMessage({
command: "receiveMessage",
text: errorMsg,
});
vscode.window.showErrorMessage(errorMsg);
}
}