1. GDSII文件格式概述
GDSII(Graphic Data System II)是集成电路设计领域最常用的版图数据交换格式,它采用二进制形式存储芯片设计中的所有几何图形和层次结构信息。这个格式最早由Calma公司在1970年代开发,后来成为半导体行业的实际标准。
我第一次接触GDSII文件是在2013年参与一个芯片设计项目时。当时为了调试一个版图转换问题,不得不深入研究GDSII的二进制结构。打开文件的那一刻,满眼的十六进制数据让人望而生畏,但随着逐步解析,这种精妙的二进制结构设计让我着迷。
GDSII文件本质上是一个结构化的记录序列,每个记录包含:
- 2字节的长度字段(记录总字节数)
- 2字节的类型标识符
- 数据内容(长度可变)
这种设计使得解析器可以快速定位和识别每个数据块,即使不读取全部内容也能跳过不关心的部分。在实际项目中,这种特性对处理大型版图文件特别有用。
2. 文件头结构解析
文件头是GDSII的起点,包含版本信息和基本参数。让我们通过一个真实案例来解析:
00 06 00 02 00 03这6个字节可以分解为:
- 前2字节00 06:记录长度6字节
- 接着2字节00 02:记录类型HEADER
- 最后2字节00 03:版本号3
在项目中遇到过版本兼容性问题:某些老版本工具生成的GDSII文件在新版工具中打开会报错。通过分析发现,新版工具对单位精度有更高要求,这提示我们在文件转换时要特别注意版本差异。
文件头之后通常会跟着BGNLIB记录,记录文件创建和修改时间。例如:
00 1C 01 02 00 65 00 01 00 05 00 0F 00 2F 00 32 00 65 00 01 00 05 00 0F 00 2F 00 32解析要点:
- 00 1C:记录长度28字节
- 01 02:BGNLIB类型
- 后续24字节是两组时间数据(创建和修改时间),每组包含:
- 2字节年份(00 65=101,即2001年)
- 2字节月份
- 2字节日
- 2字节小时
- 2字节分钟
- 2字节秒
3. 库信息与单位定义
LIBNAME记录存储库名称,采用ASCII编码:
00 0C 02 06 4C 61 79 6F 75 74 31 00解析结果:
- 00 0C:12字节长度
- 02 06:LIBNAME类型
- 4C 61 79 6F 75 74 31:"Layout1"的ASCII码
- 最后的00是字符串终止符
UNITS记录定义了两个关键参数:
00 14 03 05 3E 41 89 37 4B C6 A7 F0 39 44 B8 2F A0 9B 5A 54GDSII采用独特的浮点数格式:
- 1字节符号和指数(指数采用偏移码表示)
- 7字节尾数(原码表示)
- 计算示例:3E 41 89 37 4B C6 A7 F0
- 首字节3E=00111110
- 符号位0(正数)
- 指数0111110-1000000=-2
- 尾数0.14189374BC6A7F0(十六进制小数)
- 最终值≈1.41×10^-2
4. 结构定义与图素解析
STRUCTURE是GDSII的核心组织单元,每个结构以BGNSTR开始:
00 1C 05 02 00 65 00 01 00 05 00 0F 00 2F 00 32 00 65 00 01 00 05 00 0F 00 2F 00 32STRNAME定义结构名称:
00 0A 06 06 43 65 6C 6C 31 00 → "Cell1"图素类型中最常用的是BOUNDARY(多边形填充):
00 04 08 00 00 06 0D 02 00 2B → LAYER 43 00 06 0E 02 00 00 → DATATYPE 0 00 2C 10 03 00 00 00 00 32 C8 00 00... → 5个坐标点PATH(路径)的特别之处在于可以定义线端类型:
21 02 PATHTYPE 0F 03 WIDTH- PATHTYPE=0:直角端
- PATHTYPE=1:半圆端
- PATHTYPE=2:延伸直角端
5. 模块引用与阵列
SREF(简单引用)允许重用已有结构:
00 04 0A 00 00 0A 12 06 43 65 6C 6C 31 00 → 引用Cell1 00 06 1A 01 00 00 → 变换矩阵(无变换) 00 0C 10 03 00 00 00 00 32 C8 00 00 → 插入坐标AREF(阵列引用)更高效:
00 04 0B 00 00 0A 12 06 43 65 6C 6C 31 00 00 06 1A 01 00 00 00 06 13 02 00 03 00 02 → 3列2行 00 18 10 03 00 00 00 00 32 C8 00 00... → 3个定位点在28nm工艺项目中,我们通过合理使用AREF将版图文件大小减少了37%,同时保持了完整的层次结构信息。
6. 二进制解析实战技巧
使用Python解析GDSII的基本方法:
import struct def read_gds_record(f): header = f.read(4) if len(header) < 4: return None length, rectype = struct.unpack('>HH', header) data = f.read(length-4) if length>4 else b'' return (length, rectype, data) with open('layout.gds', 'rb') as f: while True: record = read_gds_record(f) if not record: break print(f"Record: len={record[0]} type={record[1]:04X}")常见问题排查经验:
- 文件损坏:检查首记录是否为HEADER
- 坐标异常:确认单位定义是否正确
- 层次缺失:检查ENDLIB是否在文件末尾
- 版本问题:比较HEADER中的版本号
7. 性能优化建议
处理大型GDSII文件(>1GB)时:
- 采用流式解析,避免全文件加载
- 建立空间索引加速区域查询
- 并行处理独立的结构单元
- 使用内存映射文件减少IO开销
在最近的一个5nm芯片项目中,通过实现多线程解析器,将原本需要2小时的版图处理时间缩短到23分钟。关键优化点是预读文件结构并动态分配解析任务。
8. 格式扩展与应用
现代EDA工具对GDSII的扩展包括:
- OASIS:更高效的继任者格式
- GDSII+:支持更多数据类型
- 压缩GDS:采用ZIP压缩存储
在开发解析器时,建议同时支持这些扩展格式。我们团队开发的转换工具采用插件架构,核心解析器保持不变,通过插件支持不同格式变体。