feat: 实现 Vivado 创建工程功能
- 添加 createVivadoProject 工具 - 实现 Vivado 自动检测(支持所有盘符和版本) - 添加 TCL 脚本生成器 - 添加配置管理模块 - 添加测试命令
This commit is contained in:
@ -1,637 +1,166 @@
|
||||
# Vivado 联动前后端对接文档
|
||||
|
||||
## 1. 概述
|
||||
## 1. 前端提供的工具
|
||||
|
||||
本文档描述后端 AI 服务如何调用前端的 Vivado 工具,以及前端如何响应和返回结果。
|
||||
前端提供 4 个独立工具,每个工具执行一个 Vivado 命令。
|
||||
|
||||
### 1.1 调用流程
|
||||
|
||||
```
|
||||
后端 AI 服务
|
||||
↓ (1) 发送工具调用请求
|
||||
前端 Extension (MessageHandler)
|
||||
↓ (2) 解析请求,调用 VivadoRunner
|
||||
VivadoRunner
|
||||
↓ (3) 执行 Vivado,实时推送进度
|
||||
前端 Webview
|
||||
↓ (4) 显示进度和结果
|
||||
前端 Extension
|
||||
↓ (5) 返回执行结果给后端
|
||||
后端 AI 服务
|
||||
```
|
||||
|
||||
## 2. 工具定义(后端)
|
||||
|
||||
### 2.1 工具注册
|
||||
|
||||
后端需要在工具列表中注册 `runVivado` 工具:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "runVivado",
|
||||
"description": "调用本地 Vivado 工具执行 FPGA 综合、实现或生成比特流。用于将 Verilog 代码部署到 FPGA 硬件。使用前必须先询问用户必要的参数(如芯片型号、执行模式)。",
|
||||
"inputSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": "string",
|
||||
"enum": ["synthesis", "implementation", "bitstream"],
|
||||
"description": "要执行的命令类型:synthesis(综合)、implementation(实现)、bitstream(生成比特流)"
|
||||
},
|
||||
"topModule": {
|
||||
"type": "string",
|
||||
"description": "顶层模块名称"
|
||||
},
|
||||
"files": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "输入的 Verilog 文件路径列表"
|
||||
},
|
||||
"constraints": {
|
||||
"type": "string",
|
||||
"description": "约束文件路径(.xdc 文件),可选"
|
||||
},
|
||||
"part": {
|
||||
"type": "string",
|
||||
"description": "FPGA 芯片型号(如 xc7a35tcpg236-1),必须从用户处获取"
|
||||
},
|
||||
"mode": {
|
||||
"type": "string",
|
||||
"enum": ["batch", "gui"],
|
||||
"description": "执行模式:batch(后台批处理)、gui(打开图形界面),必须询问用户"
|
||||
}
|
||||
},
|
||||
"required": ["command", "topModule", "files", "part", "mode"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 后端调用前的准备工作
|
||||
|
||||
**重要**:后端在调用 `runVivado` 工具前,必须先向用户询问必要参数:
|
||||
|
||||
1. **芯片型号(part)**:必须询问,例如 "xc7a35tcpg236-1"
|
||||
2. **执行模式(mode)**:必须询问用户选择
|
||||
- `batch`:后台批处理执行,自动完成
|
||||
- `gui`:打开 Vivado 图形界面,用户手动操作
|
||||
3. **顶层模块名**:可从文件名推断,但建议确认
|
||||
4. **约束文件**:询问是否有时序约束文件(.xdc)
|
||||
|
||||
**询问示例**:
|
||||
```
|
||||
AI: 我将使用 Vivado 进行综合。请提供以下信息:
|
||||
1. FPGA 芯片型号(例如:xc7a35tcpg236-1)
|
||||
2. 执行模式:
|
||||
- 批处理模式:后台自动执行,完成后返回结果
|
||||
- 图形界面:打开 Vivado GUI,您可以手动操作
|
||||
3. 是否有约束文件(.xdc)?
|
||||
|
||||
用户: xc7a35tcpg236-1,批处理模式,没有约束文件
|
||||
|
||||
AI: 好的,开始后台综合...
|
||||
[调用 runVivado 工具]
|
||||
```
|
||||
|
||||
### 2.3 调用示例
|
||||
|
||||
#### 示例 1:综合单个文件(批处理模式)
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "runVivado",
|
||||
"parameters": {
|
||||
"command": "synthesis",
|
||||
"topModule": "counter",
|
||||
"files": ["counter.v"],
|
||||
"part": "xc7a35tcpg236-1",
|
||||
"mode": "batch"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 示例 2:综合带约束文件(图形界面模式)
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "runVivado",
|
||||
"parameters": {
|
||||
"command": "synthesis",
|
||||
"topModule": "uart_top",
|
||||
"files": ["uart_tx.v", "uart_rx.v", "uart_top.v"],
|
||||
"constraints": "constraints.xdc",
|
||||
"part": "xc7k325tffg900-2",
|
||||
"mode": "gui"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 示例 3:实现(批处理模式)
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "runVivado",
|
||||
"parameters": {
|
||||
"command": "implementation",
|
||||
"topModule": "counter",
|
||||
"part": "xc7a35tcpg236-1",
|
||||
"mode": "batch"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 示例 4:生成比特流(图形界面)
|
||||
|
||||
```json
|
||||
{
|
||||
"tool": "runVivado",
|
||||
"parameters": {
|
||||
"command": "bitstream",
|
||||
"topModule": "counter",
|
||||
"part": "xc7a35tcpg236-1",
|
||||
"mode": "gui"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. 前端接收和处理
|
||||
|
||||
### 3.1 后端如何控制前端
|
||||
|
||||
**核心机制**:后端通过调用 `runVivado` 工具来控制前端执行 Vivado 命令。
|
||||
|
||||
**控制流程**:
|
||||
1. 后端识别用户意图(如"打开 Vivado"、"开始仿真")
|
||||
2. 后端向用户询问必要参数(芯片型号等)
|
||||
3. 后端调用 `runVivado` 工具,传递参数
|
||||
4. 前端接收工具调用,执行相应操作
|
||||
5. 前端返回执行结果给后端
|
||||
6. 后端将结果展示给用户
|
||||
|
||||
**示例场景**:
|
||||
```
|
||||
用户输入:"打开 Vivado 进行综合"
|
||||
|
||||
后端处理:
|
||||
1. 识别意图 → 需要调用 runVivado 工具
|
||||
2. 检查参数 → 缺少芯片型号
|
||||
3. 询问用户 → "请提供 FPGA 芯片型号"
|
||||
4. 用户回复 → "xc7a35tcpg236-1"
|
||||
5. 调用工具 → runVivado({ command: "synthesis", part: "xc7a35tcpg236-1", ... })
|
||||
6. 前端执行 → VivadoRunner 启动 Vivado
|
||||
7. 返回结果 → { success: true, ... }
|
||||
8. 展示结果 → "综合完成,耗时 45 秒"
|
||||
```
|
||||
|
||||
### 3.2 MessageHandler 处理逻辑
|
||||
|
||||
前端在 `messageHandler.ts` 中添加工具处理:
|
||||
### 1.1 createVivadoProject - 创建工程
|
||||
|
||||
**参数**:
|
||||
```typescript
|
||||
// src/utils/messageHandler.ts
|
||||
|
||||
export async function handleToolExecution(
|
||||
panel: vscode.WebviewPanel,
|
||||
toolName: string,
|
||||
parameters: any
|
||||
): Promise<any> {
|
||||
|
||||
if (toolName === 'runVivado') {
|
||||
return await handleVivadoTool(panel, parameters);
|
||||
}
|
||||
|
||||
// 其他工具处理...
|
||||
{
|
||||
projectName: string; // 项目名称
|
||||
part: string; // 芯片型号(如 xc7a35tcpg236-1)
|
||||
topModule: string; // 顶层模块名
|
||||
files: string[]; // 源文件路径列表
|
||||
constraints?: string; // 约束文件路径(可选)
|
||||
mode: 'gui' | 'batch'; // gui=打开图形界面,batch=后台执行
|
||||
}
|
||||
```
|
||||
|
||||
async function handleVivadoTool(
|
||||
panel: vscode.WebviewPanel,
|
||||
parameters: any
|
||||
): Promise<VivadoToolResponse> {
|
||||
**返回**:
|
||||
```typescript
|
||||
{
|
||||
success: boolean; // 是否成功
|
||||
command: "create_project";
|
||||
executionTime: number; // 执行时间(毫秒)
|
||||
output: string; // 完整日志
|
||||
error?: string; // 失败原因(如果失败)
|
||||
outputFiles?: string[]; // 产出的工程文件路径
|
||||
}
|
||||
```
|
||||
|
||||
const { command, topModule, files, constraints, part, mode } = parameters;
|
||||
### 1.2 runVivadoSynthesis - 综合
|
||||
|
||||
// 验证必需参数
|
||||
if (!part) {
|
||||
return {
|
||||
success: false,
|
||||
command,
|
||||
executionTime: 0,
|
||||
output: '',
|
||||
error: '缺少必需参数:芯片型号(part)。后端应该先询问用户。'
|
||||
};
|
||||
}
|
||||
**参数**:
|
||||
```typescript
|
||||
{
|
||||
projectPath?: string; // 工程路径(可选)
|
||||
part: string; // 芯片型号
|
||||
topModule: string; // 顶层模块
|
||||
files?: string[]; // 源文件(如果没有工程)
|
||||
constraints?: string; // 约束文件(可选)
|
||||
mode: 'gui' | 'batch';
|
||||
}
|
||||
```
|
||||
|
||||
if (!mode) {
|
||||
return {
|
||||
success: false,
|
||||
command,
|
||||
executionTime: 0,
|
||||
output: '',
|
||||
error: '缺少必需参数:执行模式(mode)。后端应该询问用户选择 batch 或 gui。'
|
||||
};
|
||||
}
|
||||
|
||||
// 构建请求
|
||||
const request: VivadoToolRequest = {
|
||||
command,
|
||||
parameters: {
|
||||
topModule,
|
||||
files,
|
||||
constraints,
|
||||
part,
|
||||
mode
|
||||
},
|
||||
importOutput: {
|
||||
enabled: mode === 'batch', // 只有批处理模式才自动导入
|
||||
targetDir: path.join(
|
||||
vscode.workspace.workspaceFolders![0].uri.fsPath,
|
||||
'vivado_output'
|
||||
)
|
||||
}
|
||||
**返回**:
|
||||
```typescript
|
||||
{
|
||||
success: boolean;
|
||||
command: "synthesis";
|
||||
executionTime: number;
|
||||
output: string;
|
||||
error?: string; // 失败原因
|
||||
outputFiles?: string[]; // .dcp 文件等
|
||||
reports?: {
|
||||
resources?: string; // 资源使用摘要
|
||||
timing?: string; // 时序摘要
|
||||
};
|
||||
|
||||
// 向前端发送开始消息
|
||||
panel.webview.postMessage({
|
||||
type: 'vivado-start',
|
||||
command
|
||||
});
|
||||
|
||||
// 执行 Vivado
|
||||
const response = await runVivado(request, (progress) => {
|
||||
// 实时推送进度到前端
|
||||
panel.webview.postMessage({
|
||||
type: 'vivado-progress',
|
||||
progress
|
||||
});
|
||||
});
|
||||
|
||||
// 向前端发送完成消息
|
||||
panel.webview.postMessage({
|
||||
type: 'vivado-complete',
|
||||
response
|
||||
});
|
||||
|
||||
// 返回结果给后端
|
||||
return response;
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 响应格式
|
||||
### 1.3 runVivadoImplementation - 实现
|
||||
|
||||
### 4.1 成功响应
|
||||
|
||||
```json
|
||||
**参数**:
|
||||
```typescript
|
||||
{
|
||||
"success": true,
|
||||
"command": "synthesis",
|
||||
"executionTime": 45230,
|
||||
"output": "Vivado 执行日志...",
|
||||
"importedFiles": [
|
||||
"/path/to/vivado_output/counter_synth.dcp",
|
||||
"/path/to/vivado_output/counter_utilization_synth.rpt"
|
||||
],
|
||||
"reports": {
|
||||
"resources": "LUT: 32/20800 (0.15%)\nFF: 8/41600 (0.02%)",
|
||||
"timing": "WNS: 5.234ns, TNS: 0.000ns"
|
||||
}
|
||||
dcpFile: string; // 综合后的 .dcp 文件路径
|
||||
mode: 'gui' | 'batch';
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 失败响应
|
||||
|
||||
```json
|
||||
**返回**:
|
||||
```typescript
|
||||
{
|
||||
"success": false,
|
||||
"command": "synthesis",
|
||||
"executionTime": 1250,
|
||||
"output": "部分执行日志...",
|
||||
"error": "ERROR: [Synth 8-439] module 'counter' not found"
|
||||
success: boolean;
|
||||
command: "implementation";
|
||||
executionTime: number;
|
||||
output: string;
|
||||
error?: string; // 失败原因
|
||||
outputFiles?: string[]; // 实现后的 .dcp 文件等
|
||||
reports?: {
|
||||
resources?: string;
|
||||
timing?: string;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 5. 后端使用指南
|
||||
### 1.4 runVivadoBitstream - 生成比特流
|
||||
|
||||
### 5.1 AI 对话流程(完整版)
|
||||
|
||||
```
|
||||
用户:帮我用 Vivado 综合一下 counter.v
|
||||
|
||||
AI 分析:
|
||||
1. 用户想要综合 Verilog 文件
|
||||
2. 需要调用 runVivado 工具
|
||||
3. 命令类型是 synthesis
|
||||
4. 顶层模块名从文件名推断为 counter
|
||||
5. 输入文件是 counter.v
|
||||
6. ⚠️ 缺少必要参数:芯片型号
|
||||
|
||||
AI 回复用户:
|
||||
"好的,我将使用 Vivado 进行综合。请提供以下信息:
|
||||
1. FPGA 芯片型号(例如:xc7a35tcpg236-1、xc7k325tffg900-2)
|
||||
2. 是否有约束文件(.xdc)?"
|
||||
|
||||
用户:xc7a35tcpg236-1,没有约束文件
|
||||
|
||||
AI 调用工具:
|
||||
**参数**:
|
||||
```typescript
|
||||
{
|
||||
"tool": "runVivado",
|
||||
"parameters": {
|
||||
"command": "synthesis",
|
||||
"topModule": "counter",
|
||||
"files": ["counter.v"],
|
||||
"part": "xc7a35tcpg236-1"
|
||||
}
|
||||
dcpFile: string; // 实现后的 .dcp 文件路径
|
||||
mode: 'gui' | 'batch';
|
||||
}
|
||||
|
||||
前端执行并返回结果
|
||||
|
||||
AI 回复用户:
|
||||
"Vivado 综合完成!
|
||||
- 执行时间:45.2 秒
|
||||
- 芯片型号:xc7a35tcpg236-1
|
||||
- 资源使用:LUT: 32/20800 (0.15%), FF: 8/41600 (0.02%)
|
||||
- 产出文件已导入到 vivado_output 目录"
|
||||
```
|
||||
|
||||
### 5.2 完整流程示例
|
||||
|
||||
```
|
||||
用户:用 Vivado 跑完整个流程
|
||||
|
||||
AI:好的,我将依次执行综合、实现和生成比特流。请提供:
|
||||
1. FPGA 芯片型号
|
||||
2. 顶层模块名
|
||||
3. 是否有约束文件
|
||||
|
||||
用户:xc7a35tcpg236-1,顶层模块是 counter,没有约束文件
|
||||
|
||||
AI:收到,开始执行...
|
||||
|
||||
步骤 1:综合
|
||||
[调用] runVivado { command: "synthesis", topModule: "counter", files: ["counter.v"], part: "xc7a35tcpg236-1" }
|
||||
[结果] 综合成功,耗时 45s
|
||||
|
||||
步骤 2:实现
|
||||
[调用] runVivado { command: "implementation", topModule: "counter", part: "xc7a35tcpg236-1" }
|
||||
[结果] 实现成功,耗时 120s,时序满足要求
|
||||
|
||||
步骤 3:生成比特流
|
||||
[调用] runVivado { command: "bitstream", topModule: "counter", part: "xc7a35tcpg236-1" }
|
||||
[结果] 比特流生成成功,文件:counter.bit
|
||||
|
||||
完成!所有文件已导入到 vivado_output 目录。
|
||||
```
|
||||
|
||||
## 6. 错误处理
|
||||
|
||||
### 6.1 常见错误
|
||||
|
||||
#### 错误 1:Vivado 未配置
|
||||
|
||||
```json
|
||||
**返回**:
|
||||
```typescript
|
||||
{
|
||||
"success": false,
|
||||
"error": "Vivado 未配置,请在设置中配置 Vivado 路径"
|
||||
success: boolean;
|
||||
command: "bitstream";
|
||||
executionTime: number;
|
||||
output: string;
|
||||
error?: string; // 失败原因
|
||||
outputFiles?: string[]; // .bit 文件路径
|
||||
}
|
||||
```
|
||||
|
||||
**AI 应该回复**:
|
||||
"Vivado 尚未配置,请先在插件设置中配置 Vivado 的安装路径。"
|
||||
## 2. 前端职责
|
||||
|
||||
#### 错误 2:文件不存在
|
||||
- 接收后端工具调用
|
||||
- 生成对应的 TCL 脚本
|
||||
- 执行 Vivado 命令
|
||||
- 捕获输出日志
|
||||
- 解析报告文件(提取资源和时序摘要)
|
||||
- 返回执行结果
|
||||
|
||||
```json
|
||||
**前端不做**:
|
||||
- 不检查依赖关系
|
||||
- 不验证执行顺序
|
||||
- 不控制流程
|
||||
|
||||
## 3. 后端职责
|
||||
|
||||
- 询问用户参数(芯片型号、执行模式等)
|
||||
- 理解依赖关系(创建工程 → 综合 → 实现 → 生成比特流)
|
||||
- 按正确顺序调用工具
|
||||
- 检查每步的 `success` 字段
|
||||
- 如果失败,读取 `error` 字段并提示用户
|
||||
- 汇总结果展示给用户
|
||||
|
||||
## 4. 调用示例
|
||||
|
||||
```
|
||||
用户: 用 Vivado 做综合
|
||||
|
||||
后端:
|
||||
1. 询问芯片型号 → xc7a35tcpg236-1
|
||||
2. 询问执行模式 → batch
|
||||
|
||||
3. 调用 createVivadoProject(...)
|
||||
返回: { success: true, outputFiles: ["counter.xpr"] }
|
||||
|
||||
4. 调用 runVivadoSynthesis(...)
|
||||
返回: { success: true, outputFiles: ["counter_synth.dcp"], reports: {...} }
|
||||
|
||||
5. 展示结果给用户
|
||||
```
|
||||
|
||||
## 5. 错误处理
|
||||
|
||||
如果某步失败:
|
||||
```typescript
|
||||
{
|
||||
"success": false,
|
||||
"error": "输入文件不存在: counter.v"
|
||||
success: false,
|
||||
error: "ERROR: [Synth 8-439] module 'counter' not found",
|
||||
output: "详细日志..."
|
||||
}
|
||||
```
|
||||
|
||||
**AI 应该回复**:
|
||||
"找不到文件 counter.v,请确认文件路径是否正确。"
|
||||
|
||||
#### 错误 3:综合失败
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "ERROR: [Synth 8-439] module 'counter' not found",
|
||||
"output": "详细日志..."
|
||||
}
|
||||
```
|
||||
|
||||
**AI 应该回复**:
|
||||
"综合失败,错误信息:找不到模块 'counter'。请检查:
|
||||
1. 模块名是否正确
|
||||
2. 文件中是否定义了该模块
|
||||
3. 是否有语法错误"
|
||||
|
||||
### 6.2 错误处理建议
|
||||
|
||||
后端收到 `success: false` 时:
|
||||
1. 提取 `error` 字段中的错误信息
|
||||
2. 分析错误类型(配置问题、文件问题、语法问题等)
|
||||
3. 给用户提供具体的解决建议
|
||||
4. 必要时可以查看 `output` 字段获取详细日志
|
||||
|
||||
## 7. 进度推送(可选)
|
||||
|
||||
前端会实时推送进度信息到 Webview,后端无需处理,但可以了解进度格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "vivado-progress",
|
||||
"progress": {
|
||||
"stage": "synthesis",
|
||||
"percentage": 45,
|
||||
"message": "正在综合模块 counter..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 测试建议
|
||||
|
||||
### 8.1 后端测试用例
|
||||
|
||||
```javascript
|
||||
// 测试用例 1:基本综合
|
||||
test('综合单个文件', async () => {
|
||||
const result = await callTool('runVivado', {
|
||||
command: 'synthesis',
|
||||
topModule: 'counter',
|
||||
files: ['counter.v']
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.importedFiles.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// 测试用例 2:错误处理
|
||||
test('文件不存在', async () => {
|
||||
const result = await callTool('runVivado', {
|
||||
command: 'synthesis',
|
||||
topModule: 'test',
|
||||
files: ['not_exist.v']
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('不存在');
|
||||
});
|
||||
```
|
||||
|
||||
## 9. 注意事项
|
||||
|
||||
### 9.1 后端必须询问的参数
|
||||
|
||||
**关键要求**:后端在调用 `runVivado` 前,必须先向用户收集以下参数:
|
||||
|
||||
| 参数 | 是否必须 | 询问方式 | 示例 |
|
||||
|------|---------|---------|------|
|
||||
| part(芯片型号) | ✅ 必须 | 直接询问 | "请提供 FPGA 芯片型号(如 xc7a35tcpg236-1)" |
|
||||
| mode(执行模式) | ✅ 必须 | 提供选项 | "选择执行模式:1.批处理 2.图形界面" |
|
||||
| topModule | ✅ 必须 | 可推断或询问 | 从文件名推断,或询问"顶层模块名是什么?" |
|
||||
| files | ✅ 必须(综合时) | 可推断或询问 | 从当前文件或工作区推断 |
|
||||
| constraints | ❌ 可选 | 询问 | "是否有约束文件(.xdc)?" |
|
||||
|
||||
### 9.2 常见用户输入场景
|
||||
|
||||
#### 场景 1:用户说"打开 Vivado"
|
||||
```
|
||||
用户:打开 Vivado
|
||||
|
||||
后端分析:用户想使用 Vivado,但没有指定具体操作
|
||||
|
||||
后端回复:
|
||||
"好的,请问您想执行什么操作?
|
||||
1. 综合(Synthesis)- 将 Verilog 转换为门级网表
|
||||
2. 实现(Implementation)- 布局布线
|
||||
3. 生成比特流(Bitstream)- 生成 .bit 文件
|
||||
|
||||
另外,请提供:
|
||||
- FPGA 芯片型号(例如:xc7a35tcpg236-1)
|
||||
- 执行模式:批处理(后台自动)或 图形界面(手动操作)"
|
||||
```
|
||||
|
||||
#### 场景 2:用户说"开始仿真"
|
||||
```
|
||||
用户:开始仿真
|
||||
|
||||
后端分析:用户可能混淆了仿真和综合
|
||||
|
||||
后端回复:
|
||||
"您是想:
|
||||
1. 使用 iverilog 进行功能仿真(验证逻辑)
|
||||
2. 使用 Vivado 进行综合(部署到 FPGA)
|
||||
|
||||
请选择您需要的操作。"
|
||||
```
|
||||
|
||||
#### 场景 3:用户提供完整信息
|
||||
```
|
||||
用户:用 Vivado 综合 counter.v,芯片是 xc7a35tcpg236-1,批处理模式
|
||||
|
||||
后端分析:信息完整,可以直接调用
|
||||
|
||||
后端操作:
|
||||
[调用] runVivado({
|
||||
command: "synthesis",
|
||||
topModule: "counter",
|
||||
files: ["counter.v"],
|
||||
part: "xc7a35tcpg236-1",
|
||||
mode: "batch"
|
||||
})
|
||||
```
|
||||
|
||||
#### 场景 4:用户选择图形界面
|
||||
```
|
||||
用户:打开 Vivado 图形界面做综合
|
||||
|
||||
后端分析:用户明确要求 GUI 模式
|
||||
|
||||
后端询问:
|
||||
"好的,请提供:
|
||||
1. FPGA 芯片型号
|
||||
2. 顶层模块名"
|
||||
|
||||
用户:xc7a35tcpg236-1, counter
|
||||
|
||||
后端操作:
|
||||
[调用] runVivado({
|
||||
command: "synthesis",
|
||||
topModule: "counter",
|
||||
files: ["counter.v"],
|
||||
part: "xc7a35tcpg236-1",
|
||||
mode: "gui"
|
||||
})
|
||||
|
||||
前端执行:
|
||||
- 生成 TCL 脚本和项目文件
|
||||
- 执行: vivado counter_project.xpr (打开图形界面)
|
||||
- 返回: { success: true, message: "Vivado GUI 已启动" }
|
||||
|
||||
后端回复:
|
||||
"Vivado 图形界面已打开,您可以在界面中手动操作。"
|
||||
```
|
||||
|
||||
### 9.3 执行时间
|
||||
- 综合:小型设计 30s-2min,大型设计 5-30min
|
||||
- 实现:通常是综合时间的 2-3 倍
|
||||
- 生成比特流:通常 10-30s
|
||||
|
||||
后端应该设置合理的超时时间(建议 10 分钟)。
|
||||
|
||||
### 9.4 依赖关系
|
||||
- `implementation` 需要先执行 `synthesis`
|
||||
- `bitstream` 需要先执行 `implementation`
|
||||
|
||||
后端 AI 应该理解这个依赖关系,按顺序调用。
|
||||
|
||||
### 9.5 文件路径
|
||||
- 所有文件路径都是相对于工作区根目录
|
||||
- 前端会自动解析为绝对路径
|
||||
- 支持相对路径和绝对路径
|
||||
|
||||
## 10. 参数传递详细说明
|
||||
|
||||
### 10.1 必需参数
|
||||
|
||||
| 参数 | 类型 | 说明 | 获取方式 |
|
||||
|------|------|------|----------|
|
||||
| command | string | 命令类型 | 从用户意图推断 |
|
||||
| topModule | string | 顶层模块名 | 从文件名推断或询问用户 |
|
||||
| files | string[] | 源文件列表 | 从工作区查找或用户指定 |
|
||||
| part | string | 芯片型号 | **必须询问用户** |
|
||||
|
||||
### 10.2 可选参数
|
||||
|
||||
| 参数 | 类型 | 说明 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| constraints | string | 约束文件路径 | 无 |
|
||||
|
||||
### 10.3 参数验证规则
|
||||
|
||||
后端在调用前应验证:
|
||||
- `part` 格式正确(如 xc7a35tcpg236-1)
|
||||
- `files` 数组不为空
|
||||
- `topModule` 不为空
|
||||
- `command` 在枚举值内
|
||||
|
||||
## 11. 快速集成清单
|
||||
|
||||
后端开发者需要做的事情:
|
||||
|
||||
- [ ] 在工具列表中注册 `runVivado` 工具
|
||||
- [ ] **实现参数询问逻辑(芯片型号等)**
|
||||
- [ ] 实现工具调用逻辑(发送请求到前端)
|
||||
- [ ] 处理返回结果(success/error)
|
||||
- [ ] 实现错误处理和用户提示
|
||||
- [ ] 理解三个命令的依赖关系
|
||||
- [ ] 设置合理的超时时间(建议 10 分钟)
|
||||
- [ ] 编写测试用例
|
||||
|
||||
前端开发者需要做的事情:
|
||||
|
||||
- [ ] 实现 `handleVivadoTool` 函数
|
||||
- [ ] 集成 VivadoRunner
|
||||
- [ ] 实现进度推送
|
||||
- [ ] 实现结果展示
|
||||
- [ ] 处理各种错误情况
|
||||
- [ ] 验证传入的参数完整性
|
||||
后端应该:
|
||||
1. 停止后续步骤
|
||||
2. 提取 `error` 字段
|
||||
3. 给用户提示和建议
|
||||
|
||||
Reference in New Issue
Block a user