关键词:Google XLS、高层次综合 (HLS)、软硬协同 (Co-design)、DSLX语言、编译器架构、即时编译 (JIT)
摩尔定律逼近物理极限,算力焦虑正席卷整个科技圈。既然通用处理器的“免费午餐”快吃完了,未来的出路在哪里?答案指向专用硬件与软硬协同设计(Co-design) 。
然而,现实存在鸿沟。精通底层硬件逻辑的工程师往往受限于传统的EDA工具链和繁琐的硬件描述语言,而擅长高级抽象的软件工程师则对硬件设计望而却步。有没有一种可能,让开发者像编写现代软件一样,优雅、安全且高效地“编译”出底层硬件电路?

最近,Google开源了一个名为XLS (Accelerated HW Synthesis) 的项目,它是一个处于快速发展阶段的高层次综合(High Level Synthesis, HLS)工具链。其核心愿景是成为“后摩尔定律时代”的通用硬件开发工具包(SDK),旨在弥合软硬件之间的开发隔阂。

为了应对未来硬件专用化的趋势,软件和硬件工程师必须跨越领域边界,进行更紧密的软硬协同设计(Co-design)。XLS试图通过提升抽象层级、发挥软件工程师的生产力优势,并利用自动化工具与机器算力,来加速整个硬件开发流程。
一、核心设计理念
XLS允许开发者使用灵活的高层次功能描述语言编写代码,并将其自动综合为可用的硬件设计(Verilog/SystemVerilog)。其主要特点包括:
- 软件风格的硬件开发:使用XLS开发的硬件模块可以同时作为高效的“宿主软件”运行。这意味着你可以用编写软件的习惯来设计硬件,并且同一份代码不仅能生成硬件,还能在软件环境或模拟器中以原生速度执行和调试。
- 严格的功能一致性:XLS工具链提供了形式化验证等工具,确保代码在软件模拟中的行为与最终生成的硬件电路功能完全一致。
- 纯函数与并发进程:XLS支持纯组合逻辑或可流水线化的函数,也支持有状态的并发进程,用于描述随时间变化的状态机和更复杂的通信接口。
二、核心架构与工具栈
XLS的内部架构呈现为一个层次分明的编译栈。从上层的领域特定语言到底层硬件生成的完整链路如下:
A. 前端语言层:DSLX
为了更契合硬件设计的数据流特性,Google设计了一种名为DSLX的领域特定语言。
- 它在语法上借鉴了Rust,是一种基于表达式的、不可变的数据流语言。
- 包含了面向硬件的原生特性,例如支持任意位宽的整数、完全固定大小的数据类型,以及完全可静态分析的调用图。
DSLX 语法示例:一个简单的硬件加法器
以下是一个使用 DSLX 语言编写的简单硬件加法器示例,其语法与 Rust 非常相似:
“`rust
// xls/examples/tiny_adder.x
// 返回加法结果,类型拓宽以反映进位位 (carry bit)。
fn tiny_adder(x: u1, y: u1) -> u2 {
let lhs = x as u2;
let rhs = y as u2;
lhs + rhs
}
[test]
fn test_exhaustive() {
assert_eq(tiny_adder(u1:0, u1:0), u2:0b00);
assert_eq(tiny_adder(u1:0, u1:1), u2:0b01);
assert_eq(tiny_adder(u1:1, u1:1), u2:0b10);
assert_eq(tiny_adder(u1:1, u1:0), u2:0b01);
}
“`
这段代码可以直接作为软件单元测试运行(通过 #[test] 属性),但在 XLS 工具链中,它会被解析并最终转换为底层的硬件网表。
中间表示层:XLS IR
DSLX 代码首先会被转换为 XLS 的中间表示(IR)。XLS IR 是一种纯粹的、采用静态单赋值(SSA)形式的图结构,编译器的大量优化工作都在这一层进行。
在 xls/ir/node.h 中,定义了 IR 中最基础的节点概念。在硬件网表中,每一个操作(如 AND、OR、MUX)都是一个 Node,它们通过操作数(operands_)和使用者(users_)相互连接。
“`cpp
// xls/ir/node.h
// 高层 IR 中表示一个节点(代表一个表达式)的抽象类型
class Node {
public:
virtual ~Node() = default;
// 访问者模式:遍历该节点
absl::Status Accept(DfsVisitor* visitor);
Type GetType() const { return type_; }
Op op() const { return op_; }
FunctionBase function_base() const { return function_base_; }
// 返回此节点使用的操作数序列(输入端口)
absl::Span operands() const { return operands_; }
// … (省略部分方法)
protected:
FunctionBase function_base_;
int64_t id_;
Op op_;
Type type_;
SourceInfo loc_;
std::unique_ptr name_; // 如果已分配名称则非空
// 绝大多数节点具有 <= 2 个操作数,因此我们使用 InlineVector 尽量在栈上分配
absl::InlinedVector operands_;
// 按 node_id 排序的该节点的使用者集合(输出端口去向)
absl::InlinedVector users_;
};
“`
从上述代码可以看出,XLS IR 使用 C++ 严谨构建,并采用了 absl::InlinedVector 等优化手段来提升内存和缓存性能。
优化与调度
- Passes (位于
xls/passes/):与 LLVM 类似,IR 生成后,XLS 会执行一系列 Pass 进行优化,例如死代码消除、常量折叠等。 - Scheduling (位于
xls/scheduling/):硬件设计需要考虑时序。调度模块中的算法负责决定每个 IR 操作应该在哪个时钟周期的流水线阶段执行。
代码生成:Codegen 与 VAST
经过调度优化的 IR,最终会被翻译成电子设计自动化(EDA)工具能够识别的硬件描述语言(如 Verilog)。XLS 为此构建了一个名为 VAST(Verilog AST) 的抽象语法树。
通过 Generator 组件(例如负责流水线的 PipelineGenerator 和负责状态机的 SequentialGenerator),XLS 将 IR 转化为 VAST,并最终输出 .v 或 .sv 文件。这部分实现位于 xls/codegen/ 目录中。
周边生态与核心工具
除了核心编译链路,XLS 还提供了完善的工程化、验证和仿真工具:
- JIT 编译器 (
xls/jit):基于 LLVM 的即时编译器,可以将 XLS IR 编译成本地机器码运行,使得 DSLX 的验证与执行能达到原生代码的速度。 - 全栈 Fuzzer (
xls/fuzzer):一个多进程模糊测试器,用于捕获工具链中的潜在问题。它会随机生成 DSLX 程序,并交叉对比 DSLX 解释器、IR 解释器、JIT 编译器以及最终生成的 Verilog 在仿真器中的运行结果,任何不一致都会被立即发现。 - SMT 形式化验证 (
xls/solvers):利用 Z3 求解器引擎,可以将 IR 转化为 SMT 逻辑表达式,用于进行形式化证明,例如检查 XLS IR 与网表之间的逻辑等价性。 - C++ 前端 (
xls/contrib/xlscc):一个实验性的 C++ 前端,能够解析特定子集的 C++ 语法并直接生成 XLS IR,方便已有 C++ 高层次综合代码库的迁移。
通过 DSLX 提供类 Rust 的安全开发体验,以 Node 树管理底层逻辑门元操作,并借助 JIT、Fuzzing 与 SMT Solvers 构建全方位的测试验证体系。
纵观整个 google/xls 项目,其展现的不仅是工具创新,更是一种开发范式的转变。它并非简单地再造一个 HLS(高层次综合)工具,而是将现代软件工程的成熟方法论系统性地引入硬件设计领域。从具备 Rust 风格的强类型安全前端 DSLX,到严谨的 SSA 形式中间表示 XLS IR,再到集成的 JIT 即时编译、全栈自动化 Fuzzing 以及 SMT 形式化验证,XLS 几乎整合了现代编译器技术中最核心的工程化组件。
其核心启示在于:硬件开发正朝着敏捷化方向演进。 在 AI 与专用加速芯片爆发的时代,让精通业务逻辑的软件工程师能够安全地参与、甚至直接定义硬件,具有重要的前瞻意义。尽管 XLS 目前仍处于快速迭代的实验阶段,但它已清晰勾勒出“软件定义硬件”的可行路径。
关注“鲸栖”小程序,掌握最新AI资讯
本文来自网络搜集,不代表鲸林向海立场,如有侵权,联系删除。转载请注明出处:https://www.itsolotime.com/archives/27801


