2. SoC设计流程:从需求分析到流片

各位同学,今天我们来聊聊SoC设计的完整流程。说实话,很多刚入行的工程师容易把设计流程看成一条流水线——需求来了,架构定好,RTL写完,验证通过,然后丢给后端就完事了。但我在实际项目中踩过不少坑,发现每个环节之间都有很多「隐形的工作」。

我个人习惯把SoC设计流程分成八个阶段。你想想看,这就像盖一栋楼,从画图纸到打地基,再到装修入住,每一步都马虎不得。

核心流程速览:

需求分析 → 架构设计 → RTL编码 → 验证 → 综合 → 布局布线 → 流片 → 测试

下面我逐一展开讲,每个阶段我都会结合自己的项目经验,告诉你哪些地方容易翻车。

2.1 需求分析:别急着写代码

很多团队一上来就开干,结果做到一半发现需求变了。嗯,这很常见。

需求分析阶段,说白了就是搞清楚三件事:

  • 功能需求:芯片要做什么?支持哪些协议?跑什么操作系统?
  • 性能指标:主频多少?功耗限制?面积预算?
  • 接口定义:外部要接DDR吗?PCIe几代?USB是3.0还是2.0?

我在一个AI芯片项目里遇到过,客户说「要支持4K视频编解码」,结果我们按H.265做了,最后发现他们用的是VP9。这一改,架构全推倒重来。所以我的建议是:需求文档一定要签字确认,而且最好写清楚「不支持什么」。

小技巧:需求分析阶段可以画一个简单的功能框图,把芯片的输入输出、主要模块、数据流向画出来。这张图后面会变成架构设计的起点。

2.2 架构设计:搭骨架

架构设计是SoC设计中最考验经验的一步。你需要决定:

  • 总线拓扑:用AXI还是NoC?多主多从怎么仲裁?
  • 存储层次:Cache多大?SRAM分布在哪?DDR控制器怎么接?
  • 时钟复位:多少个时钟域?异步处理怎么做?
  • 功耗策略:哪些模块可以关掉?DVFS怎么实现?

我记得有一次做车规级芯片,架构评审时大家吵了三天,就为了决定「CPU cluster用big.LITTLE还是DSU」。最后我们选了DSU,因为功耗更可控。你看,架构设计没有标准答案,只有「最适合当前需求」的方案。

这里我画了一张SoC架构的简化框图,你可以看看各个模块之间的关系:

SoC 典型架构框图 CPU Cluster Cortex-A78 x4 L2 Cache 2MB DSU 控制 GPU Mali-G78 MP16 Shader Core x16 L2 Cache 1MB NPU MAC Array 1024 SRAM 4MB Winograd 加速 AXI 总线 / NoC 互联 高速外设 PCIe Gen4 USB 3.2 Ethernet 存储控制器 DDR5/LPDDR5 eMMC 5.1 NAND Flash 低速外设 I2C/SPI/UART GPIO/PWM Watchdog 图:典型SoC架构框图(简化版)

2.3 RTL编码:把想法变成代码

架构定好了,接下来就是写RTL。这一步看似简单,其实最容易出问题。

我建议你养成几个好习惯:

  • 代码风格统一:命名规范、注释清晰、模块化设计
  • 同步设计原则:所有触发器都用时钟沿触发,避免组合逻辑环路
  • 异步处理:跨时钟域信号一定要做同步处理,用双锁存器或者异步FIFO

举个例子,一个简单的AXI从机接口,代码大概长这样:

module axi_slave #(
    parameter DATA_WIDTH = 32,
    parameter ADDR_WIDTH = 16
)(
    input  logic                  clk,
    input  logic                  rst_n,
    // AXI写地址通道
    input  logic [ADDR_WIDTH-1:0] awaddr,
    input  logic                  awvalid,
    output logic                  awready,
    // AXI写数据通道
    input  logic [DATA_WIDTH-1:0] wdata,
    input  logic                  wvalid,
    output logic                  wready,
    // AXI写响应通道
    output logic [1:0]            bresp,
    output logic                  bvalid,
    input  logic                  bready
);

    // 内部寄存器
    logic [ADDR_WIDTH-1:0] awaddr_reg;
    logic                  awvalid_reg;
    
    // 写地址通道处理
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            awaddr_reg  <= '0;
            awvalid_reg <= '0;
        end else begin
            if (awvalid && awready) begin
                awaddr_reg  <= awaddr;
                awvalid_reg <= 1'b1;
            end else if (bvalid && bready) begin
                awvalid_reg <= 1'b0;
            end
        end
    end
    
    // 握手信号
    assign awready = !awvalid_reg || (bvalid && bready);
    
endmodule

注意:写RTL时最容易犯的错误是「组合逻辑环路」。我曾经在一个项目中,因为一个assign语句写成了组合反馈,导致仿真时信号一直震荡。后来花了三天才定位到问题。所以,写完代码一定要做 lint 检查。

2.4 验证:花的时间比写代码多

验证是SoC设计中最耗时的环节。一般来说,验证时间占整个项目周期的60%以上。

验证策略通常包括:

  • 模块级验证:每个IP单独测,用UVM搭建testbench
  • 子系统验证:把几个相关模块连起来测,比如CPU+Cache+DDR
  • 系统级验证:整个SoC跑起来,跑操作系统、跑应用
  • 后仿验证:综合后、布局布线后,带上时序信息再仿一遍

我个人习惯在验证阶段做三件事:

  1. 写测试计划:把功能点列出来,每个点对应一个测试用例
  2. 做覆盖率分析:代码覆盖率、功能覆盖率、翻转覆盖率,缺一不可
  3. 随机测试:用约束随机生成测试向量,往往能发现意想不到的bug

避坑指南:我曾经在一个项目中,模块级验证都过了,系统级验证也跑了三天三夜没报错。结果流片回来,发现DDR控制器在特定温度下会丢数据。后来查出来是后仿没做全,有个时序路径没覆盖到。所以,后仿一定不能省

2.5 综合:把RTL变成门级网表

综合就是把RTL代码映射到标准单元库上。这一步会决定你的芯片能不能跑到目标频率。

综合的关键参数:

参数 说明 我的建议
时钟周期 目标工作频率 留10%-20%余量
输入延迟 外部信号到达时间 按接口协议严格约束
输出延迟 信号到达外部的时间 同样按协议约束
面积约束 芯片面积上限 不要压太紧,留布线空间
功耗约束 动态/静态功耗上限 多电压域设计更灵活

综合完成后,一定要做静态时序分析(STA)。说白了就是检查所有路径的建立时间和保持时间是否满足。我刚开始做设计时总觉得这步可有可无,直到有一次流片回来芯片死活上不了高频...嗯,从那以后我再也不敢跳过STA了。

2.6 布局布线:把网表变成版图

布局布线是后端工程师的活,但作为架构师,你也要了解基本流程:

  • 布局:把标准单元放到芯片的物理位置上
  • 时钟树综合:把时钟信号均匀分布到所有触发器
  • 布线:用金属层把单元连起来
  • 物理验证:DRC检查、LVS检查

这里有个坑:布局布线阶段往往会发现时序不满足。为什么?因为综合时用的是线负载模型,而实际布线后的延迟可能更大。所以,后仿真的重要性怎么强调都不为过

2.7 流片:把设计交给工厂

流片就是把最终的GDSII文件交给晶圆厂。这一步其实没什么技术含量,但流程非常繁琐。

流片前需要确认:

  • 所有验证都通过了
  • 时序收敛了
  • 物理验证没有DRC/LVS错误
  • 功耗分析满足要求
  • IR drop分析通过

我记得第一次流片时,光签核文件就签了二十多页。每一页都要确认签字,少签一个工厂就不收。所以,流片前的检查清单一定要逐项打勾

2.8 测试:芯片回来了,是骡子是马牵出来遛遛

芯片回来后,第一件事就是上电测试。测试通常分几步:

  1. 功能测试:跑基本的读写操作,看芯片能不能正常工作
  2. 性能测试:跑benchmark,看能不能达到设计指标
  3. 压力测试:高温、低温、高电压、低电压,看芯片的鲁棒性
  4. 量产测试:用ATE自动测试设备批量测试

经验之谈:芯片测试时,一定要先测电源和时钟。如果电源短路或者时钟没起振,后面的测试都不用做了。我见过一个团队,芯片回来后直接跑功能测试,结果发现所有寄存器都读不到值。查了两天才发现是PLL没锁定,时钟根本没出来。

好了,以上就是SoC设计流程的八个阶段。每个阶段都有它的难点和坑,但只要你按部就班、步步为营,最终一定能拿到一颗能工作的芯片。


公众号:蓝海资料掘金营,微信deep3321