From 4abb979eabe12eb016e4f6d2cd5f3b281d2c9dec Mon Sep 17 00:00:00 2001 From: XiaoFeng <117837368+Fzhiyu1@users.noreply.github.com> Date: Sat, 10 Jan 2026 21:15:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20iverilog=20?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - api.ts: 新增 IverilogArgs 类型定义 - toolExecutor.ts: 新增 executeIverilog 函数,支持直接执行 iverilog 命令 --- src/services/toolExecutor.ts | 69 ++++++++++++++++++++++++++++++++++++ src/types/api.ts | 7 ++++ 2 files changed, 76 insertions(+) diff --git a/src/services/toolExecutor.ts b/src/services/toolExecutor.ts index 4569d61..d38b512 100644 --- a/src/services/toolExecutor.ts +++ b/src/services/toolExecutor.ts @@ -25,6 +25,7 @@ import type { FileDeleteArgs, FileListArgs, SyntaxCheckArgs, + IverilogArgs, SimulationArgs, WaveformSummaryArgs, KnowledgeSaveArgs, @@ -75,6 +76,9 @@ export async function executeToolCall( case 'syntax_check': resultText = await executeSyntaxCheck(args as unknown as SyntaxCheckArgs, context); break; + case 'iverilog': + resultText = await executeIverilog(args as unknown as IverilogArgs, context); + break; case 'simulation': resultText = await executeSimulation(args as unknown as SimulationArgs, context); break; @@ -270,6 +274,71 @@ async function executeSyntaxCheck( } } +/** + * 执行 iverilog 工具 + * 直接执行 iverilog 命令 + */ +async function executeIverilog( + args: IverilogArgs, + context: ToolExecutorContext +): Promise { + // 检查 iverilog 是否可用 + const iverilogCheck = await checkIverilogAvailable(context.extensionPath); + if (!iverilogCheck.available) { + throw new Error(`iverilog 不可用: ${iverilogCheck.message}`); + } + + // 获取工作目录 + const workspaceFolders = vscode.workspace.workspaceFolders; + if (!workspaceFolders || workspaceFolders.length === 0) { + throw new Error('没有打开的工作区'); + } + const projectPath = workspaceFolders[0].uri.fsPath; + const workDir = args.workDir + ? path.join(projectPath, args.workDir) + : projectPath; + + // 解析参数 + const iverilogPath = getIverilogPath(context.extensionPath); + const cmdArgs = args.args.split(/\s+/).filter(a => a.length > 0); + + const { spawn } = require('child_process'); + + return new Promise((resolve, reject) => { + const child = spawn(iverilogPath, cmdArgs, { + cwd: workDir, + env: { + ...process.env, + IVERILOG_ROOT: path.join(context.extensionPath, 'tools', 'iverilog') + } + }); + + let stdout = ''; + let stderr = ''; + + child.stdout.on('data', (data: Buffer) => { + stdout += data.toString(); + }); + + child.stderr.on('data', (data: Buffer) => { + stderr += data.toString(); + }); + + child.on('close', (code: number) => { + const output = stderr || stdout || '(无输出)'; + if (code === 0) { + resolve(`执行成功\n${output}`); + } else { + resolve(`执行失败 (exit code: ${code})\n${output}`); + } + }); + + child.on('error', (error: Error) => { + reject(error); + }); + }); +} + /** * 执行 simulation 工具 */ diff --git a/src/types/api.ts b/src/types/api.ts index d68968e..219ba76 100644 --- a/src/types/api.ts +++ b/src/types/api.ts @@ -518,6 +518,12 @@ export interface SyntaxCheckArgs { code: string; } +/** iverilog 工具参数 */ +export interface IverilogArgs { + args: string; + workDir?: string; +} + /** simulation 工具参数 */ export interface SimulationArgs { rtlPath: string; @@ -566,6 +572,7 @@ export type ToolArgs = | FileDeleteArgs | FileListArgs | SyntaxCheckArgs + | IverilogArgs | SimulationArgs | WaveformSummaryArgs | WaveformTraceArgs