AI编程(一) - 从datasheet到verilog原型设计

AI编程(一) - 从datasheet到Verilog原型设计

1. 背景

在芯片/FPGA开发中,数据手册(Datasheet)是芯片设计的核心文档,包含了完整的功能描述、寄存器映射、接口时序、协议规范等信息。传统方式下,工程师需要花费大量时间逐字阅读手册,然后手动编写RTL代码。这个过程枯燥且容易出错。

本文介绍一种基于AI Agent的自动化工作流:将芯片PDF数据手册自动分析并生成Verilog原型设计代码和架构文档。以Microchip LAN8650/1(10BASE-T1S MAC-PHY)为例,演示从PDF到完整RTL代码的完整过程。

完整项目源码已开源:LAN8650-1 Verilog Prototype

2. 环境准备

2.1 安装OpenSkills

OpenSkills 是一个通用Skills加载器,将Anthropic的SKILL.md格式扩展到任何支持AGENTS.md的AI编码助手,包括Claude Code、Cursor、Windsurf、Aider和Codex。

首先安装Node.js(>=20.6)和Git,然后通过npm全局安装:

1
npm install -g openskills

安装完成后,验证版本:

1
2
$ npx openskills --version
openskills/1.x.x

2.2 安装Anthropic官方Skills库

Anthropic官方在GitHub上维护了一套高质量Skills,覆盖了各类常见的开发场景。安装方式如下:

1
2
3
4
5
# 安装Anthropic官方Skills库(包含skill-creator等)
npx openskills install --global anthropics/skills

# 查看已安装的Skills
npx openskills list
1
2
3
4
5
6
7
8
9
10
11
Installed Skills:
├── datasheet-verilog-prototype # 自定义:从PDF生成Verilog
├── alg-algorithmic-art # 生成式艺术
├── doc-coauthoring # 文档协作
├── docx # Word文档
├── frontend-design # 前端界面
├── mcp-builder # MCP服务器
├── pdf # PDF处理
├── pptx # PowerPoint
├── skill-creator # 创建新Skills
└── xlsx # Excel表格

2.3 创建自定义Skill

有了skill-creator,我们可以将本次实验的完整工作流封装为一个可复用的Skill:

1
2
# 使用skill-creator创建新Skill(交互式)
npx openskills read skill-creator

创建好的Skill以SKILL.md文件为核心,目录结构如下:

1
2
3
4
5
6
datasheet-verilog-prototype/
├── SKILL.md # 核心定义文件
├── references/
│ └── QUICKREF.md # 快速参考卡片
└── evals/
└── evals.json # 测试用例

其中SKILL.md的核心YAML frontmatter:

1
2
3
4
5
6
---
name: datasheet-verilog-prototype
description: >
将芯片/IP数据手册(datasheet)自动分析并生成数字Verilog原型设计代码和架构文档。
当用户提供PDF数据手册或要求"分析datasheet生成Verilog"时触发本技能。
---

打包为可分发的.skill文件:

1
2
3
4
5
# 打包(自动排除evals等测试目录)
python skills/skill-creator/scripts/package_skill.py datasheet-verilog-prototype

# 安装到全局
npx openskills install --global ./datasheet-verilog-prototype.skill

关于Skill的更多用法,参见:[AI编程 – Cursor环境配置和简单使用](https://cursorhu.github.io/AI编程 – Cursor环境配置和简单使用/)

3. 完整工作流演示

3.1 目标芯片:LAN8650/1

本次实验选取的芯片是Microchip LAN8650/1,这是一款集成MAC+PHY的10BASE-T1S以太网控制器:

参数
接口 SPI(最高25MHz)
速率 10Mbps 半双工
PHY 10BASE-T1S (IEEE 802.3 Clause 147)
MAC CSMA/CD + PLCA
协议 OPEN Alliance 10BASE-T1x MAC-PHY Serial Interface v1.1
页数 370页

3.2 Step 1:PDF全文提取

首先安装PDF解析库:

1
pip install pdfplumber

然后编写提取脚本,将370页PDF全文提取为文本文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pdfplumber

pdf_path = "LAN8650-1-DataSheet.pdf"

with pdfplumber.open(pdf_path) as pdf:
print(f"Total pages: {len(pdf.pages)}")
all_text = []
for i, page in enumerate(pdf.pages):
text = page.extract_text()
if text:
all_text.append(f"\n===== PAGE {i+1} =====\n{text}")

with open("pdf_text_output.txt", "w", encoding="utf-8") as f:
f.write("\n".join(all_text))
print("Done: pdf_text_output.txt")

注意:在Windows环境下,需要将stdout重定向为UTF-8编码,否则中文PDF可能出现UnicodeEncodeError

提取结果约14000行,涵盖了数据手册的所有文本内容。

3.3 Step 2:关键词定位关键章节

对提取的文本进行关键词搜索,快速定位关键章节:

1
2
3
4
5
6
7
8
9
10
11
# 搜索SPI协议相关
rg -i "SPI" pdf_text_output.txt

# 搜索寄存器定义
rg -i "Register" pdf_text_output.txt

# 搜索MAC相关
rg -i "MAC|CSMA|CRC|FCS" pdf_text_output.txt

# 搜索PLCA相关
rg -i "PLCA|Collision|Avoidance" pdf_text_output.txt

搜索结果中,数据手册的章节结构清晰可见:

章节 内容
第5章 SPI串行接口协议
第6章 以太网MAC(TX/RX/Filters)
第7章 PLCA碰撞避免
第11章 寄存器描述(OA标准/MAC/PHY/TSU)

3.4 Step 3:深度阅读关键章节

根据关键词定位的页码范围,读取具体内容:

1
2
3
4
5
6
7
8
# 读取SPI协议章节(约第53-64页)
Read offset=2332 limit=300

# 读取MAC功能描述(约第65-70页)
Read offset=2906 limit=300

# 读取寄存器定义(约第5370-6000页)
Read offset=5370 limit=500

SPI Header格式(来自数据手册原文):

1
2
3
4
5
6
7
8
9
10
11
Table 5-2. Transmit Data Block Header Format
Bit 31 - DNC: Data(1)/Control(0)
Bit 30 - SEQ: Data Block Sequence
Bit 29 - NORX: No Receive
Bit 21 - DV: Data Valid
Bit 20 - SV: Start Valid
Bit 19:16 - SWO: Start Word Offset
Bit 14 - EV: End Valid
Bit 13:8 - EBO: End Byte Offset
Bit 7:6 - TSC: Timestamp Capture (00=None, 01=A, 10=B, 11=C)
Bit 0 - P: Parity

3.5 Step 4:Verilog原型代码生成

根据提取的协议规范和寄存器定义,按照分层架构生成RTL代码:

1
2
3
4
5
6
7
8
模块层次:
L1 - 接口层 → spi_slave (SPI从机)
L2 - 控制层 → regfile (寄存器文件)
L3 - 数据层 → fifo_dma (FIFO与DMA)
L4 - 协议层 → mac_tx / mac_rx (MAC发射/接收)
L5 - 同步层 → tsu (时间戳单元)
L6 - 调度层 → plca (PLCA协调子层)
L0 - 顶层 → macphy_top (模块互联)

3.5.1 SPI从机模块

核心要素:

  • 32-bit移位寄存器(MSB优先)
  • Header解析状态机
  • DNC bit区分数据/控制事务
  • 奇偶校验保护
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// LAN8650-1_Verilog_Design.v(节选)
module lan8650_spi_slave (
input wire sclk, // SPI时钟
input wire cs_n, // 片选(低有效)
input wire sdi, // 串行数据输入(MOSI)
output wire sdo, // 串行数据输出(MISO)

// TX/RX数据接口
output reg [31:0] tx_dout,
output reg tx_dout_valid,
output reg [5:0] tx_ebo, // End Byte Offset
output reg tx_ev, // End Valid
output reg tx_sv, // Start Valid

// 控制接口(寄存器读写)
output reg [11:0] ctrl_addr,
output reg ctrl_wr,
output reg ctrl_rd,
output reg [31:0] ctrl_wdata,
input wire [31:0] ctrl_rdata
);

// Header解析
wire hdr_dnc = sdi_shift[31]; // Data(1)/Control(0)
wire hdr_dv = sdi_shift[21]; // Data Valid
wire hdr_sv = sdi_shift[20]; // Start Valid
wire hdr_ev = sdi_shift[14]; // End Valid
wire [1:0] hdr_tsc = sdi_shift[7:6]; // Timestamp Capture

// 奇偶校验
wire parity = ^sdi_shift[31:1]; // 奇校验

// 状态机: IDLE → HEADER → DATA_TX/DATA_RX/CTRL_WR/CTRL_RD
localparam ST_IDLE = 3'd0;
localparam ST_HEADER = 3'd1;
localparam ST_DATA_TX = 3'd2;
localparam ST_DATA_RX = 3'd3;
localparam ST_CTRL_WR = 3'd4;
localparam ST_CTRL_RD = 3'd5;

reg [2:0] state;
reg [4:0] bit_cnt; // 比特计数(32bits)
reg [4:0] word_cnt; // 字计数
reg [31:0] sdi_shift;

// SCLK上升沿采样SDI
always @(posedge sclk or negedge rst_n) begin
if (!rst_n) begin
sdi_shift <= 32'h0;
end else if (!cs_n) begin
sdi_shift <= {sdi_shift[30:0], sdi};
end
end
endmodule

3.5.2 寄存器文件模块

完整地址空间定义(基于数据手册第11章):

地址 寄存器 描述
0x004 OA_CONFIG0 配置:SYNC/TXFCSVE/TXCTE/RXCTE/FTSE/BPS
0x008 OA_STATUS0 状态:TTSCA/B/C/RESETC/TXBUE/TXPE
0x009 OA_STATUS1 厂商状态:TXNER/RXNER
0x100 MAC_NCFGR MAC网络配置
0x108 MAC_SAB1 特定地址1低32位(退避种子)
0x800 PLCA_CTRL0 PLCA使能/协调器模式
0x804 PLCA_CTRL1 PLCA本地ID/节点数
0x077 MAC_TI TSU增量(默认0x28=40ns)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 寄存器文件 - OA_CONFIG0位定义
localparam OA_CONFIG0_IDX = 4;
wire [15:0] oa_config0;
assign oa_config0[15] = sync; // 配置同步标志
assign oa_config0[14] = txfcsve; // TX FCS验证
assign oa_config0[9] = txcte; // TX直通
assign oa_config0[8] = rxcte; // RX直通
assign oa_config0[7] = ftse; // 帧时间戳
assign oa_config0[2:0] = bps; // 块负载大小

// 中断合并逻辑
wire [15:0] oa_int0 = oa_status0_reg & ~oa_imask0;
wire any_int = |oa_int0;
assign irq_n = any_int ? 1'b0 : 1'b1;

3.5.3 MAC发射模块

完整状态机(IEEE 802.3 CSMA/CD):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
localparam TX_IDLE      = 4'd0;
localparam TX_PREAMBLE = 4'd1;
localparam TX_SFD = 4'd2;
localparam TX_DATA = 4'd3;
localparam TX_PAD = 4'd4;
localparam TX_FCS = 4'd5;
localparam TX_JAM = 4'd6;
localparam TX_BACKOFF = 4'd7;
localparam TX_WAIT_CRS = 4'd8;
localparam TX_IFG = 4'd9;

// CRC32计算(以太网标准多项式 0x04C11DB7)
wire [31:0] crc_next;
wire crc_bit = frame_data_reg[bit_idx];

always @(*) begin
crc_next = crc32;
crc_next = {crc_next[30:0] ^ ({31{1'b0}} & {crc_next[31] ^ crc_bit}), 1'b0};
if (crc_bit ^ crc32[31])
crc_next = crc_next ^ 32'h04C11DB7;
end

3.5.4 PLCA协调子层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// PLCA总线周期
localparam PLCA_IDLE = 4'd0;
localparam PLCA_BEACON_WAIT = 4'd1;
localparam PLCA_BEACON_DET = 4'd2;
localparam PLCA_OPPORTUNITY = 4'd3;
localparam PLCA_TX = 4'd4;
localparam PLCA_IDLE_SLOT = 4'd5;
localparam PLCA_BEACON_TX = 4'd6;

// 当slot_cnt等于本地PLCA_ID时授予TX权限
PLCA_OPPORTUNITY: begin
if (slot_cnt == local_id && mac_tx_req) begin
plca_tx_grant <= 1'b1;
plca_tx_active <= 1'b1;
end
end

3.5.5 时间戳单元(TSU)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 64-bit墙钟格式:
// [63:32] 秒低位 + [31:30] 扩展 + [29:0] 纳秒
reg [47:0] seconds;
reg [31:0] nanoseconds;

// 25MHz参考时钟,每周期40ns
wire [31:0] ns_next = nanoseconds + mac_ti[15:0];
assign ns_carry = ns_next[16]; // 进位检测

// 秒进位
if (ns_carry) begin
nanoseconds <= ns_next[15:0];
seconds <= seconds + 1'b1;
end

3.6 Step 5:架构文档生成

除了Verilog代码,还需要生成一份面向可持续迭代升级的架构文档ARCHITECTURE.md

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# LAN8650-1 MAC-PHY 数字设计架构文档

## 一、系统级架构

### 模块层次

| 层级 | 模块 | 职责 |
|------|------|------|
| L1 | spi_slave | SPI从机协议解析 |
| L2 | regfile | 寄存器映射、中断管理 |
| L3 | fifo_dma | TX/RX双口FIFO、流控 |
| L4 | mac_tx/rx | CSMA/CD、CRC、地址过滤 |
| L5 | tsu | 时间戳捕获、墙钟维护 |
| L6 | plca | PLCA总线仲裁 |
| L0 | macphy_top | 模块互联 |

## 版本演进路线图

### v1.0 — 基础功能
- [x] SPI从机(OPEN Alliance v1.1)
- [x] 完整寄存器文件
- [x] MAC TX/RX + CRC32
- [x] TSU + PLCA

### v2.0 — 可靠性增强
- [ ] ECC保护
- [ ] Scatter-Gather DMA
- [ ] L2 ACL过滤

### v2.1 — 性能扩展
- [ ] QSPI模式
- [ ] VLAN Offload
- [ ] MSI中断

4. 常见陷阱与解决方案

4.1 PDF编码问题(Windows)

1
2
3
4
# 错误:UnicodeEncodeError: 'gbk' codec can't encode character
# 解决:始终写入文件而非print()
with open("output.txt", "w", encoding="utf-8") as f:
f.write(text)

4.2 扫描件PDF无文本

如果extract_text()返回空,说明PDF是扫描图片。需要OCR:

1
pip install pytesseract pdf2image

4.3 寄存器表跨页断开

读取足够长的行范围:

1
2
# 读取300行以捕获跨页的完整寄存器定义
Read offset=5370 limit=300

5. 总结

本文完整演示了从芯片数据手册到Verilog原型设计的AI辅助工作流:

阶段 工具 耗时
PDF提取 pdfplumber ~60秒(370页)
关键词搜索 ripgrep ~5秒
深度阅读 Read工具 ~30分钟
代码生成 AI Agent ~10分钟
文档撰写 AI Agent ~10分钟

关键经验总结:

  1. 分层架构是关键:L1-L6的分层设计使得每个子模块可独立替换,为后续迭代升级奠定基础
  2. 寄存器是架构的灵魂:精确的寄存器地址、位定义、访问类型是RTL正确性的保证
  3. 协议时序必须完整:MAC的状态机必须覆盖所有IEEE 802.3规定的状态和转移条件
  4. 文档与代码同步:每次代码变更必须同步更新架构文档,保持版本一致性

下一篇文章将介绍:AI编程(二) - 基于OpenSkills的FPGA开发自动化,涵盖如何将完整的FPGA开发流程封装为可复用Skills,包括:综合约束、仿真环境、Bitstream生成等环节的自动化。


参考资料

  1. Microchip LAN8650/1 DataSheet DS60001734F
  2. OPEN Alliance 10BASE-T1x MAC-PHY Serial Interface v1.1
  3. IEEE Std 802.3-2022
  4. OpenSkills - npm
  5. Anthropic Claude Code Skills