HotSpot 芯片热仿真源码分析
概述
HotSpot是一个基于RC电路模型的芯片级热仿真工具,其核心思想是将热传导问题类比为电路问题。本文档从源码层面分析HotSpot如何将 CT+KT=P(t) 这个常微分方程应用到芯片热仿真过程中。
一、理论基础:CT+KT=P(t) 常微分方程
1.1 物理意义
在热传导问题中:
- C:热容矩阵 (Thermal Capacitance),单位 J/K,表示材料存储热量的能力
- T:温度向量 (Temperature),单位 K,表示各节点的温度
- K:热导矩阵 (Thermal Conductance),单位 W/K,表示节点间热量传递的能力
- P(t):功耗向量 (Power),单位 W,表示各节点的功耗输入
方程 CT+KT=P(t) 描述了热传导的瞬态过程,是热力学第一定律在离散化系统中的体现。
1.2 与电路的类比
| 热学参数 | 电学参数 | 单位 |
|---|---|---|
| 温度 T | 电压 V | K / V |
| 热流 P | 电流 I | W / A |
| 热阻 R | 电阻 R | K/W / Ω |
| 热容 C | 电容 C | J/K / F |
根据这种类比,热传导网络可以等效为RC电路网络。
二、网格拆分 (Grid Discretization)
2.1 从芯片到网格的映射
HotSpot提供两种模型:
- Block Model (块模型):按功能模块划分
- Grid Model (网格模型):将芯片均匀划分为网格
以网格模型为例,代码位置 temperature_grid.c:
c
// 分辨率配置
int grid_rows = 64; // 网格行数
int grid_cols = 64; // 网格列数
// 计算每个单元的尺寸
double cw = model->width / model->cols; // 单元宽度
double ch = model->height / model->rows; // 单元高度
2.2 层次化结构
源码中的层次结构 (temperature_grid.h):
c
typedef struct layer_t_st {
flp_t *flp; // 每层的floorplan
int no; // 层编号
int has_lateral; // 是否考虑侧向热传导
int has_power; // 是否产生功耗
double k; // 热导率 (1/电阻率)
double thickness; // 层厚度
double sp; // 比热容
double rx, ry, rz; // x, y, z方向的热阻
double c; // 热容
blist_t ***b2gmap; // 块到网格的映射
glist_t *g2bmap; // 网格到块的映射
} layer_t;
典型层结构包括:
- 硅层 (Silicon layer):主要发热层
- 界面材料层 (Interface layer):TIM层
- 散热器层 (Spreader/Sink layers):热扩展和散热
- 可选的次要路径:封装基板、焊球、PCB层
2.3 3D网格单元访问
使用宏定义实现3D数组的线性存储 (temperature_grid.c:2854):
c
#define A3D(array,n,i,j,nl,nr,nc) (array[(n)*(nr)*(nc) + (i)*(nc) + (j)])
其中:
n: 层索引 (layer index)i: 行索引 (row index)j: 列索引 (column index)
三、矩阵构建 (Matrix Construction)
3.1 热阻矩阵计算
热阻的基本计算公式 (RCutil.c:20-23):
c
// 热阻计算:R = thickness / (conductivity × area)
double getr(double conductivity, double thickness, double area)
{
return thickness / (conductivity * area);
}
3.1.1 单元内热阻
对于每个网格单元,计算x、y、z三个方向的热阻 (temperature_grid.c:193-219):
c
blist_t *new_blist(int idx, double occupancy, double res, double specificHeat,
int first, int do_detailed_3D, double cw, double ch, double thickness)
{
ptr->rx = getr(1/res, cw, ch * thickness); // x方向热阻
ptr->ry = getr(1/res, ch, cw * thickness); // y方向热阻
ptr->rz = getr(1/res, thickness, cw * ch); // z方向热阻
ptr->capacitance = getcap(specificHeat, thickness, cw * ch);
}
3.1.2 单元间热阻
相邻单元间的热阻计算 (temperature_grid.c:26-136):
c
double find_res(grid_model_t *model, int n1, int i1, int j1,
int n2, int i2, int j2) {
// n1, n2: 层索引
// i1, i2: 行索引
// j1, j2: 列索引
if (n1 != n2 && i1 == i2 && j1 == j2) {
// 垂直方向连接
res = (find_res_3D(n1, i1, j1, model, 3) / 2.0) +
(find_res_3D(n2, i2, j2, model, 3) / 2.0);
}
else if (n1 == n2 && i1 != i2 && j1 == j2) {
// x方向连接
res = (find_res_3D(n1, i1, j1, model, 1) / 2.0) +
(find_res_3D(n2, i2, j2, model, 1) / 2.0);
}
else if (n1 == n2 && i1 == i2 && j1 != j2) {
// y方向连接
res = (find_res_3D(n1, i1, j1, model, 2) / 2.0) +
(find_res_3D(n2, i2, j2, model, 2) / 2.0);
}
}
这里使用并联热阻公式:R_total = (R1/2 + R2/2)
3.2 热容矩阵计算
热容的计算公式 (RCutil.c:26-31):
c
// 热容计算:C = C_FACTOR × specific_heat × thickness × area
double getcap(double sp_heat, double thickness, double area)
{
return C_FACTOR * sp_heat * thickness * area;
}
其中 C_FACTOR = 0.333 是一个拟合因子,用于匹配仿真结果与实际测量。
3.3 模型初始化流程
代码位置 temperature.c:636-653:
c
void populate_R_model(RC_model_t *model, flp_t *flp)
{
if (model->type == BLOCK_MODEL)
populate_R_model_block(model->block, flp);
else if (model->type == GRID_MODEL)
populate_R_model_grid(model->grid, flp);
}
void populate_C_model(RC_model_t *model, flp_t *flp)
{
if (model->type == BLOCK_MODEL)
populate_C_model_block(model->block, flp);
else if (model->type == GRID_MODEL)
populate_C_model_grid(model->grid, flp);
}
四、瞬态求解 (Transient Solution)
4.1 斜率函数 (Slope Function)
瞬态方程 CT+KT=P(t) 可以重写为:
dT/dt = C^(-1) × (P(t) - KT)
这个导数在代码中通过斜率函数计算 (temperature_grid.c:3130-3645):
c
void slope_fn_grid(grid_model_t *model, double *v, grid_model_vector_t *p, double *dv)
{
// v: 当前温度向量
// p: 功耗向量
// dv: 输出的温度变化率向量
double cw = model->width / model->cols;
double ch = model->height / model->rows;
// 对每个网格单元
for(n=0; n < nl; n++)
for(i=0; i < nr; i++)
for(j=0; j < nc; j++) {
// 计算来自6个方向的热流
psum = NP(l,v,n,i,j,nl,nr,nc) + // 北向热流
SP(l,v,n,i,j,nl,nr,nc) + // 南向热流
EP(l,v,n,i,j,nl,nr,nc) + // 东向热流
WP(l,v,n,i,j,nl,nr,nc) + // 西向热流
AP(l,v,n,i,j,nl,nr,nc) + // 上向热流
BP(l,v,n,i,j,nl,nr,nc); // 下向热流
// 边界条件处理
if (n == hsidx) {
psum += (c->ambient - A3D(v,n,i,j,nl,nr,nc))/l[n].rz;
}
// dT/dt = (P + Σ热流) / C
A3D(dv,n,i,j,nl,nr,nc) = (A3D(p,n,i,j,nl,nr,nc) + psum) /
find_cap_3D(n, i, j, model);
}
}
4.2 数值积分方法
HotSpot实现了两种数值积分方法:
4.2.1 四阶Runge-Kutta方法 (RK4)
代码位置 RCutil.c:544-640:
c
double rk4(void *model, double *y, void *p, int n, double *h, double *yout, slope_fn_ptr f)
{
// k1: 起点斜率
(*f)(model, y, p, k1);
// k2: 中点斜率(使用k1)
rk4_core(model, y, k1, p, n, (*h)/2.0, t1, f);
(*f)(model, t1, p, k2);
// k3: 中点斜率(使用k2)
rk4_core(model, y, k2, p, n, (*h)/2.0, t2, f);
(*f)(model, t2, p, k3);
// k4: 终点斜率(使用k3)
rk4_core(model, y, k3, p, n, *h, ttemp, f);
(*f)(model, ttemp, p, k4);
// 加权平均
for (i =0; i < n; i++)
yout[i] = y[i] + (*h) * (k1[i] + 2*k2[i] + 2*k3[i] + k4[i])/6.0;
}
4.2.2 后向欧拉方法 (Backward Euler)
当启用SuperLU时使用 (RCutil.c:268-428):
c
double backward_euler(SuperMatrix *G, diagonal_matrix_t *C,
double *T, double *P, double *h, double *Tout)
{
// 构建矩阵 A = (1/h)C + G
build_A_matrix(G, C, *h, A);
// 构建右端项 B = (1/h)CT + P
build_B_matrix(C, T, P, *h, B);
// 求解线性系统 Ax = B
dgssv(&options, A, perm_c, perm_r, &L, &U, B, &stat, &info);
// 返回下一步的建议步长
return new_h;
}
4.3 瞬态温度计算
完整的瞬态求解流程 (temperature.c:754-761):
c
void compute_temp(RC_model_t *model, double *power, double *temp, double time_elapsed)
{
if (model->type == BLOCK_MODEL)
compute_temp_block(model->block, power, temp, time_elapsed);
else if (model->type == GRID_MODEL)
compute_temp_grid(model->grid, power, temp, time_elapsed);
}
在 hotspot.c:607-609 中的调用示例:
c
compute_temp(model, power, temp, model->config->sampling_intvl);
五、稳态求解 (Steady-State Solution)
5.1 稳态方程
当 dT/dt = 0 时,瞬态方程变为:
KT = P
这是一个线性方程组,需要求解 K×T = P
5.2 多重网格求解器
HotSpot使用递归多重网格方法 (temperature_grid.c:2733-2797):
c
void recursive_multigrid(grid_model_t *model, grid_model_vector_t *power,
grid_model_vector_t *temp)
{
// 在最粗粒度设置启发式初始温度
if (model->rows <= 1 || model->cols <= 1) {
set_heuristic_temp(model, power, temp);
} else {
// 网格粗化
model->rows /= 2;
model->cols /= 2;
for(n=0; n < model->n_layers; n++) {
model->layers[n].rz /= 4;
if (model->c_ready)
model->layers[n].c *= 4;
}
// 递归求解粗网格
recursive_multigrid(model, coarse_power, coarse_temp);
// 插值到细网格
multigrid_prolong_temp(model, temp, coarse_temp);
// 恢复网格
model->rows *= 2;
model->cols *= 2;
}
// Gauss-Seidel迭代直到收敛
do {
delta = single_iteration_steady_grid(model, power, temp);
} while (!eq(delta, 0));
}
5.3 直接求解器
当启用SuperLU时 (temperature_grid.c:2819-2823):
c
#if SUPERLU > 0
direct_SLU(model, p, model->last_steady);
#endif
六、完整仿真流程
6.1 主流程 (hotspot.c)
c
int main(int argc, char **argv)
{
// 1. 解析配置
parse_cmdline(table, MAX_ENTRIES, argc, argv);
thermal_config = default_thermal_config();
// 2. 读取floorplan
flp = read_flp(global_config.flp_file, FALSE, FALSE);
// 3. 分配热模型
model = alloc_RC_model(&thermal_config, flp, ...);
// 4. 构建RC网络
populate_R_model(model, flp);
if (do_transient)
populate_C_model(model, flp);
// 5. 读取功耗trace
while ((num=read_vals(pin, vals)) != 0) {
// 6. 计算瞬态温度
compute_temp(model, power, temp, model->config->sampling_intvl);
write_vals(tout, vals, n);
}
// 7. 计算稳态温度
steady_state_temp(model, overall_power, steady_temp);
}
6.2 数据流图
Floorplan文件 → 网格划分 → 构建RC网络 → 求解CT+KT=P(t) → 输出温度
↓ ↓ ↓ ↓ ↓
功能单元 网格单元 热阻/热容矩阵 数值积分 温度分布
七、关键源文件说明
| 文件 | 功能描述 |
|---|---|
hotspot.c |
主程序,命令行解析,仿真流程控制 |
temperature.c |
温度计算接口,块/网格模型分发 |
temperature_grid.c |
网格模型核心实现 |
temperature_block.c |
块模型核心实现 |
RCutil.c |
RC计算工具函数,数值求解器 |
flp.c |
Floorplan解析 |
util.c |
通用工具函数 |
八、总结
HotSpot通过以下步骤将CT+KT=P(t)应用到芯片热仿真:
- 网格拆分:将芯片离散化为3D网格单元,建立层次化的层结构
- 矩阵构建:计算每个单元的热阻和热容,构建全局的热导矩阵K和热容矩阵C
- 瞬态求解:使用RK4或后向欧拉方法对常微分方程进行数值积分
- 稳态求解:使用多重网格或直接求解器求解线性方程组KT=P
这种基于RC电路的热建模方法,既保证了计算效率,又能够提供合理的精度,是芯片热分析的重要工具。
因为是agent生成的用于理解代码的文章,如有错误请多见谅,后续会根据学习理解刷新。
参考文献
- HotSpot源码: https://github.com/hotspot-ucsd/hotspot
- W. Huang et al., "HotSpot: A Compact Thermal Modeling Methodology for Early-Stage VLSI Design", TODAES 2006
- Numerical Recipes in C - Chapter 16 (ODE求解)
- 多重网格方法理论: Numerical Recipes in C - Sections 19.5-19.6
文档版本:1.0
生成日期:2026-03-22