# 波形预览功能技术文档

## 功能概述

在对话界面中显示 VCD 波形文件的预览卡片，用户可以查看前几个信号的真实波形，并通过"展开查看"按钮打开完整的波形查看器。

## 功能流程

```
用户输入"生成VCD"命令
    ↓
系统执行 iverilog 编译和仿真
    ↓
生成 VCD 文件
    ↓
在对话界面显示波形预览卡片
    ├─ 显示真实的波形图（前3个信号）
    ├─ 显示信号名称和波形
    └─ "展开查看"按钮
    ↓
点击"展开查看"按钮
    ↓
打开完整的 VCDViewerPanel 波形查看器
```

## 文件结构

### 1. `src/views/waveformPreviewContent.ts`
**功能：** 波形预览组件的独立模块

**导出函数：**
- `getWaveformPreviewContent()` - 返回波形预览组件的 CSS 样式
- `getWaveformPreviewScript()` - 返回波形预览组件的 JavaScript 代码

**主要功能：**
- 创建波形预览卡片的 HTML 结构
- 从 VCD 文件中提取真实信号数据
- 使用 SVG 绘制波形图
  - 单比特信号：绘制数字波形（高/低电平）
  - 多比特信号：绘制总线波形（梯形）
- 处理"展开查看"按钮点击事件

**关键函数：**
```javascript
createWaveformPreview(vcdFilePath, fileName)
  - 创建波形预览卡片的 DOM 结构
  - 包含头部（标题 + 展开按钮）和内容区域

loadMiniWaveform(containerId, vcdFilePath, loadingDiv)
  - 请求后端获取 VCD 文件信息

renderWaveformInfo(containerId, vcdInfo)
  - 接收 VCD 信息并渲染波形

drawRealWaveform(signals)
  - 根据真实信号数据绘制 SVG 波形图
  - 支持单比特和多比特信号
  - 使用不同颜色区分信号

openFullWaveform(vcdFilePath)
  - 发送消息打开完整波形查看器

addWaveformPreviewToMessage(messageDiv, vcdFilePath, fileName)
  - 将波形预览组件添加到消息中
```

---

### 2. `src/views/webviewContent.ts`
**功能：** 主 WebView 页面，集成波形预览组件

**修改内容：**
- 导入波形预览组件的样式和脚本
- 在 `<style>` 标签中插入 `getWaveformPreviewContent()`
- 在 `<script>` 标签中插入 `getWaveformPreviewScript()`
- 添加 `vcdGenerated` 消息处理逻辑
- 添加 `vcdInfo` 消息处理逻辑

**消息处理：**
```javascript
case 'vcdGenerated':
  // VCD 文件生成成功，显示带波形预览的消息
  - 创建消息 div
  - 添加成功消息文本
  - 调用 addWaveformPreviewToMessage() 添加波形预览卡片

case 'vcdInfo':
  // 接收到 VCD 文件信息，渲染波形预览
  - 调用 renderWaveformInfo() 渲染波形
```

---

### 3. `src/utils/messageHandler.ts`
**功能：** 处理用户消息和 VCD 生成请求

**修改内容：**
- 导入 `path` 模块
- 修改 VCD 生成成功后的消息发送逻辑

**关键代码：**
```typescript
if (result.success) {
  if (result.vcdFilePath) {
    const fileName = path.basename(result.vcdFilePath);
    panel.webview.postMessage({
      command: "vcdGenerated",  // 发送 vcdGenerated 消息
      text: successMsg,
      vcdFilePath: result.vcdFilePath,
      fileName: fileName,
    });
  }
}
```

---

### 4. `src/panels/ICHelperPanel.ts`
**功能：** IC 助手面板，处理 WebView 消息

**修改内容：**
- 导入 `VCDViewerPanel`
- 添加 `openWaveformViewer` 命令处理
- 添加 `getVCDInfo` 命令处理
- 新增 `getVCDFileInfo()` 函数
- 新增 `parseVCDSignals()` 函数

**新增函数：**

#### `getVCDFileInfo(panel, vcdFilePath, containerId)`
**功能：** 获取 VCD 文件信息并解析信号数据

**处理流程：**
1. 检查文件是否存在
2. 获取文件大小
3. 读取 VCD 文件内容
4. 解析信号数量
5. 解析时间范围
6. 调用 `parseVCDSignals()` 解析前 3 个信号的数据
7. 发送 `vcdInfo` 消息回前端

**返回数据结构：**
```typescript
{
  command: "vcdInfo",
  containerId: string,
  vcdInfo: {
    signalCount: string,
    timeRange: string,
    fileSize: string,
    signals: Array<{
      name: string,
      identifier: string,
      width: number,
      values: Array<{ time: number, value: string }>
    }>
  }
}
```

#### `parseVCDSignals(content, maxSignals)`
**功能：** 解析 VCD 文件中的信号数据

**处理流程：**
1. 使用正则表达式解析信号定义部分（`$var ... $end`）
2. 提取信号名称、标识符、位宽
3. 找到数据变化部分（`$dumpvars` 之后）
4. 解析每个信号的值变化
   - 单比特信号：格式 `0!` 或 `1!`
   - 多比特信号：格式 `b1010 !`
5. 限制最多 50 个采样点（避免数据过多）
6. 返回信号数据数组

**VCD 文件格式示例：**
```vcd
$var wire 1 ! clk $end
$var wire 8 " data $end
$dumpvars
0!
b00000000 "
#10
1!
#20
0!
b00000001 "
```

**消息处理：**
```typescript
case "openWaveformViewer":
  // 打开完整波形查看器
  VCDViewerPanel.createOrShow(context.extensionUri, message.vcdFilePath);

case "getVCDInfo":
  // 获取 VCD 文件信息
  getVCDFileInfo(panel, message.vcdFilePath, message.containerId);
```

---

### 5. `src/panels/VCDViewerPanel.ts`
**功能：** 完整的 VCD 波形查看器面板（已存在）

**作用：** 当用户点击"展开查看"按钮时，打开此面板显示完整的波形

---

## 数据流

### 1. VCD 生成流程
```
用户输入 → messageHandler.handleUserMessage()
    ↓
检测到 VCD 生成命令
    ↓
messageHandler.handleVCDGeneration()
    ↓
iverilogRunner.generateVCD()
    ↓
生成 VCD 文件
    ↓
发送 vcdGenerated 消息到前端
    ↓
webviewContent 接收消息
    ↓
创建波形预览卡片
```

### 2. 波形预览加载流程
```
createWaveformPreview() 创建卡片
    ↓
loadMiniWaveform() 请求 VCD 信息
    ↓
发送 getVCDInfo 消息到后端
    ↓
ICHelperPanel 接收消息
    ↓
getVCDFileInfo() 读取并解析 VCD 文件
    ↓
parseVCDSignals() 解析信号数据
    ↓
发送 vcdInfo 消息到前端
    ↓
renderWaveformInfo() 渲染波形
    ↓
drawRealWaveform() 绘制 SVG 波形图
```

### 3. 展开查看流程
```
用户点击"展开查看"按钮
    ↓
openFullWaveform() 发送消息
    ↓
发送 openWaveformViewer 消息到后端
    ↓
ICHelperPanel 接收消息
    ↓
VCDViewerPanel.createOrShow()
    ↓
打开完整波形查看器窗口
```

---

## 样式说明

### CSS 类名
- `.waveform-preview` - 波形预览卡片容器
- `.waveform-preview-header` - 卡片头部
- `.waveform-preview-title` - 标题区域
- `.waveform-expand-btn` - 展开按钮
- `.waveform-preview-content` - 内容区域
- `.waveform-mini-viewer` - 波形显示容器
- `.waveform-loading` - 加载提示

### 波形绘制
- **单比特信号**：使用 SVG `<path>` 绘制数字波形
  - 高电平：y = 顶部
  - 低电平：y = 底部
  - 垂直跳变表示信号变化

- **多比特信号**：使用 SVG `<path>` 绘制总线波形
  - 梯形表示数据变化
  - 中间线表示稳定状态

- **颜色方案**：
  - 第1个信号：蓝色 (`var(--vscode-charts-blue)`)
  - 第2个信号：绿色 (`var(--vscode-charts-green)`)
  - 第3个信号：橙色 (`var(--vscode-charts-orange)`)

---

## 配置参数

### 可调整参数

**在 `ICHelperPanel.ts` 中：**
```typescript
const signals = parseVCDSignals(content, 3); // 解析前3个信号
```
- 修改数字可以改变显示的信号数量

**在 `parseVCDSignals()` 中：**
```typescript
if (values.length >= 50) {
  break; // 限制最多50个采样点
}
```
- 修改数字可以改变采样点数量

**在 `drawRealWaveform()` 中：**
```typescript
const signalHeight = 20;      // 信号高度
const signalSpacing = 30;     // 信号间距
const leftMargin = 80;        // 左边距（信号名称区域）
const rightMargin = 20;       // 右边距
```
- 修改这些参数可以调整波形显示样式

---

## 性能优化

1. **限制信号数量**：只解析前 3 个信号
2. **限制采样点**：每个信号最多 50 个采样点
3. **轻量级渲染**：使用 SVG 而不是 Canvas
4. **按需加载**：只在需要时读取和解析 VCD 文件

---

## 错误处理

### 文件不存在
```typescript
if (!fs.existsSync(vcdFilePath)) {
  // 返回错误信息
  vcdInfo: {
    signalCount: 'N/A',
    timeRange: 'N/A',
    fileSize: 'N/A',
    error: '文件不存在'
  }
}
```

### 解析失败
```typescript
try {
  // 解析逻辑
} catch (error) {
  console.error('解析 VCD 信号数据失败:', error);
  return []; // 返回空数组
}
```

### 无信号数据
```typescript
if (!signals || signals.length === 0) {
  return `<svg>无波形数据</svg>`;
}
```

---

## 未来扩展

### 可能的改进方向

1. **交互功能**
   - 鼠标悬停显示信号值
   - 点击信号高亮显示
   - 缩放和平移功能

2. **显示优化**
   - 自动选择最有代表性的信号
   - 智能采样（保留关键变化点）
   - 支持更多信号类型（模拟信号等）

3. **性能优化**
   - 使用 Web Worker 解析大文件
   - 虚拟滚动显示大量信号
   - 缓存解析结果

4. **功能增强**
   - 支持信号搜索和过滤
   - 导出波形图片
   - 比较多个 VCD 文件

---

## 调试技巧

### 查看消息流
在浏览器开发者工具中查看 `vscode.postMessage()` 的调用：
```javascript
console.log('发送消息:', message);
vscode.postMessage(message);
```

### 查看解析结果
在 `parseVCDSignals()` 中添加日志：
```typescript
console.log('解析到的信号:', signals);
```

### 查看 SVG 输出
在 `drawRealWaveform()` 中添加日志：
```javascript
console.log('SVG 内容:', svgContent);
```

---

## 相关文件

- `src/utils/iverilogRunner.ts` - VCD 文件生成
- `src/panels/VCDViewerPanel.ts` - 完整波形查看器
- `media/vcdrom/` - VCDrom 波形查看库

---

## 版本历史

### v1.0 (当前版本)
- ✅ 创建独立的波形预览组件
- ✅ 解析 VCD 文件中的真实信号数据
- ✅ 绘制单比特和多比特信号波形
- ✅ 支持展开查看完整波形
- ✅ 轻量级预览，快速加载

---

## 总结

波形预览功能通过以下文件协同工作：

1. **`waveformPreviewContent.ts`** - 组件核心逻辑
2. **`webviewContent.ts`** - 集成到主页面
3. **`messageHandler.ts`** - 处理 VCD 生成
4. **`ICHelperPanel.ts`** - 解析 VCD 数据和消息处理

整个功能采用模块化设计，易于维护和扩展。
