乐于分享
好东西不私藏

开源软件之DRAMPower

开源软件之DRAMPower

DRAMPower 6.0.0 深度技术分析文档

项目地址: https://github.com/tukl-msd/DRAMPower
版本: v6.0.0
分析日期: 2026-05-17


目录

  1. 项目概述
  2. 总体架构设计
  3. 完整数据流追踪(DDR5 代表)
  4. 模块一:命令系统与数据结构
  5. 模块二:Bank/Rank 状态机 —— Core 层
  6. 模块三:接口总线追踪 —— Interface 层
  7. 模块四:Power计算层 —— Calculation
  8. 模块五:内存规格 —— MemSpec
  9. 模块六:扩展系统
  10. 模块七:工具组件
  11. 关键设计模式总结

配套图表: 分层架构图 | 完整数据流图 | 状态机横向对比


1. 项目概述

1.1 核心功能

DRAMPower 是一个开源的 DRAM 功耗与估算库,由 TU Kaiserslautern、TU Delft 和 TU Eindhoven 的电子系统/计算机工程研究组联合开发。其核心功能:

  1. 根据 DRAM 命令迹(Command Trace) 和 内存规格(MemSpec),精确计算 DRAM 操作的能量消耗
  2. 支持 Core Power(bank 操作:ACT/PRE/RD/WR/REF/PowerDown/SelfRefresh)和 Interface Power(I/O 总线翻转:CA/DQ/DQS/DBI/Clock)
  3. 覆盖四种 DRAM 标准:DDR4、DDR5、LPDDR4、LPDDR5
  4. 支持 process variation 感知的功耗估算(基于 Monte-Carlo SPICE 分析)
  5. 提供 CLI 命令行工具,支持 JSON 输入输出

1.2 技术栈

维度
技术选型
语言
C++17(模板、constexpr、std::optional、fold expressions)
构建系统
CMake 3.x + FetchContent 依赖管理
核心依赖
DRAMUtils(自研工具库,提供 memspec 解析、JSON 工具)
CLI 依赖
spdlog(日志)、CLI11(命令行解析)、nlohmann_json(JSON)
测试框架
CTest(CMake 内置)
代码规范
clang-format、clang-tidy、cppcheck

1.3 项目目录结构

DRAMPower/
├── cmake/                 # CMake 辅助脚本
├── lib/                   # 第三方依赖(构建时 FetchContent 拉取)
├── src/
│   ├── DRAMPower/         # 核心库
│   │   └── DRAMPower/
│   │       ├── command/   # 命令定义(CmdType, Command, Pattern)
│   │       ├── data/      # 数据结构(energy, stats)
│   │       ├── dram/      # Bank/Rank 状态机基类
│   │       ├── memspec/   # 各标准内存规格定义
│   │       ├── standards/ # 四种标准的具体实现
│   │       │   ├── ddr4/  # DDR4: Core + Interface + Calculation
│   │       │   ├── ddr5/  # DDR5: Core + Interface + Calculation
│   │       │   ├── lpddr4/# LPDDR4: Core + Interface + Calculation
│   │       │   └── lpddr5/# LPDDR5: Core + Interface + Calculation
│   │       ├── util/      # 工具组件(Bus, Clock, DBI, Extension 等)
│   │       └── simconfig/ # 仿真配置
│   └── cli/               # CLI 命令行工具
├── tests/                 # 测试用例(每个标准 16-22 个 test pattern)
└── docs/                  # 文档

2. 总体架构设计

2.1 分层架构

┌──────────────────────────────────────────────────────┐
│                 CLI 层 (cli/main, cli/lib)            │
│  解析 memspec JSON / trace CSV → 调用 DRAMPower API   │
├──────────────────────────────────────────────────────┤
│              标准实现层 (standards/)                    │
│  ┌──────────┐  ┌──────────┐                          │
│  │  Core     │  │Interface │  每种标准独立实现           │
│  │ (状态机)   │  │(总线追踪) │                          │
│  └──────────┘  └──────────┘                          │
├──────────────────────────────────────────────────────┤
│            抽象基类层 (dram_base)                      │
│  定义 doCommand / calcCoreEnergy / getStats 公共接口   │
├──────────────────────────────────────────────────────┤
│         数据层 (command/, data/)                       │
│  Command, SimulationStats, energy_t 等共享数据结构      │
├──────────────────────────────────────────────────────┤
│            计算层 (core_calculation_*,                 │
│                    interface_calculation_*)            │
│  物理公式:Energy = V × I × t                          │
├──────────────────────────────────────────────────────┤
│            规格层 (memspec/)                           │
│  从 datasheet 提取的 IDD 电流/时序/电压/阻抗参数        │
├──────────────────────────────────────────────────────┤
│            工具层 (util/)                              │
│  Bus, Clock, DBI, PatternHandler, ExtensionManager    │
│  burst_storage, interval_counter, ImplicitCommandHandler│
└──────────────────────────────────────────────────────┘

2.2 核心设计模式

模式
应用位置
说明
模板方法dram_base<CmdType>
定义骨架:doCommand() → doCoreCommandImpl() + doInterfaceCommandImpl()
策略模式standards/ddr4/
ddr5/lpddr4/lpddr5/
每个 DRAM 标准独立实现 Core + Interface + Calculation 三组件
命令路由util/RegisterHelper.h
通用 rank/bank/bankGroup 路由辅助函数,消除重复代码
延迟执行util/ImplicitCommandHandler.h
按时间戳排序的延迟回调队列,处理 auto-precharge、refresh 恢复等
观察者模式util/extension_manager.h
扩展系统:运行时注册/查找/回调
开放区间util/cycle_stats.h
 (interval_counter)
不预先知道结束时间的周期统计——完美适配 DRAM 状态持续时长由后续命令决定的场景
标记序列化util/Serialize.h
 / util/Deserialize.h
所有有状态组件支持流式序列化/反序列化

2.3 Core 与 Interface 解耦

DRAMPower 最核心的架构决策是 Core 和 Interface 完全解耦

  Command
    │
    ├──→ DDR5Core::doCommand()
    │      └─ 追踪:Bank 状态、ACT/PRE 周期、命令计数、PowerDown、SelfRefresh
    │
    └──→ DDR5Interface::doCommand()
           └─ 追踪:CA 总线翻转、DQ 数据总线翻转、DQS/Clock 信号、DBI 信号

两者各自独立运行,在 getWindowStats() 时才将统计数据汇合到 SimulationStats 结构体。这意味着:

  • 可以独立测试 Core 或 Interface 管线
  • 可以用 Toggling Rate 模式运行 Interface(不需要真实数据 trace)
  • 新增 DRAM 标准只需要实现两套 handler + 一套 calculation 公式

3. 完整数据流追踪(DDR5 代表)

3.0 阶段 0:初始化

// 用户代码
auto memspec =DRAMUtils::parse_memspec_from_file("ddr5.json");
DDR5 dram(MemSpecDDR5::from_memspec(*memspec));

// DDR5 构造函数 (DDR5.cpp:16-20)
DDR5::DDR5(const MemSpecDDR5 &memSpec,const config::SimConfig &simConfig)
:m_memSpec(memSpec)
,m_interface(m_memSpec, simConfig)// 初始化总线 + 注册 17 种命令的 CA 编码
,m_core(m_memSpec)// 创建 numberOfRanks × numberOfBanks 个 Bank 状态机
{}

Core 初始化DDR5Core 构造 std::vector<Rank> m_ranks,每个 Rank 含 numberOfBanks 个 Bank,Bank 初始状态均为 BANK_PRECHARGED

Interface 初始化DDR5Interface 构造时通过 registerPatterns() 将 17 种 CmdType 映射到 14-bit 的 CA 总线编码(PatternHandler)。数据总线支持两种模式:

  • Bus 模式:接收真实数据,逐 bit 存储到 burst_storage
  • Toggling Rate 模式:不存储真实数据,仅基于概率做统计

3.1 阶段 1:命令输入 → 双路分发

入口dram_base<CmdType>::doCommand() (dram_base.h:64-67)

voiddoCommand(const Command& command){
doCoreCommandImpl(command);// → DDR5Core::doCommand()
doInterfaceCommandImpl(command);// → DDR5Interface::doCommand()
}

一条 Command 同时送入 Core 和 Interface 两条独立管线。

3.2 阶段 2:Core 管线 —— 状态机执行

DDR5Core::doCommand() (DDR5Core.cpp:6-65)

1. processImplicitCommandQueue(timestamp)
   └─ 执行所有到期的延迟命令(auto-precharge, refresh 后恢复等)

2. 更新时间戳 m_last_command_time

3. switch(cmd.type):
   ACT   → bankHandler     → handleAct(rank, bank, ts)
   PRE   → bankHandler     → handlePre(rank, bank, ts)
   RD    → bankHandler     → handleRead(rank, bank, ts)
   RDA   → bankHandlerIdx  → handleReadAuto(rank_idx, bank_idx, ts)
   WR    → bankHandler     → handleWrite(rank, bank, ts)
   WRA   → bankHandlerIdx  → handleWriteAuto(rank_idx, bank_idx, ts)
   PRESB → bankGroupHandler → handlePreSameBank(rank, bank_id, ts)
   REFSB → bankGroupHandlerIdx → handleRefSameBank(rank_idx, bank_id, ts)
   REFA  → rankHandlerIdx  → handleRefAll(rank_idx, ts)
   PREA  → rankHandler     → handlePreAll(rank, ts)
   SREFEN→ rankHandlerIdx  → handleSelfRefreshEntry(rank_idx, ts)
   SREFEX→ rankHandler     → handleSelfRefreshExit(rank, ts)
   PDEA/PDEP/PDXA/PDXP → rankHandlerIdx → PowerDown handlers

路由辅助层 (RegisterHelper.h):以 bankHandler 为例:

1. 从 cmd.targetCoordinate.rank 取出 Rank&
2. 从 cmd.targetCoordinate.bank 取出 Bank&
3. rank.commandCounter.inc(cmd.type)  — 累计命令计数
4. 调用 (owner->*member_func)(rank, bank, cmd.timestamp)

3.3 阶段 3:Interface 管线 —— 总线翻转追踪

DDR5Interface::doCommand() (DDR5Interface.cpp:127-159)

switch(cmd.type):
  // 非数据命令:仅更新 CA 命令总线
  ACT/PRE/PRESB/REFSB/REFA/PREA/SREFEN/PDEA/PDEP/PDXA/PDXP
    → handleCommandBus(cmd)  // PatternHandler 编码 → CA bus bits

  // 数据命令:更新数据总线 + DQS + CA 总线
  RD/RDA → handleData(cmd, read=true)
  WR/WRA → handleData(cmd, read=false)

handleData (DDR5Interface.cpp:242-261):

  • 如果 cmd 携带数据(sz_bits > 0):加载真实数据到 databus_t
  • 如果 Toggling Rate 模式:使用默认 burstLength 生成统计
  • 同时启动/停止 DQS 时钟信号

数据存储核心 —— burst_storage<BitsetContainer<N>> (burst_storage.h):

  • 逐 bit 存储到 std::bitset<N>,可高效进行时间窗口内的 zeroes/ones/bit_changes/zeroes_to_ones/ones_to_zeroes 统计
  • 通过位操作(xor + popcount)实现 O(1) 窗口转换统计

3.4 阶段 4:统计聚合

DDR5::getWindowStats() (DDR5.cpp:43-48)

SimulationStats DDR5::getWindowStats(timestamp_t timestamp){
    SimulationStats stats;
    m_core.getWindowStats(timestamp, stats);// → bank[], rank_total[]
    m_interface.getWindowStats(timestamp, stats);// → *Bus, togglingStats
return stats;
}

Core 统计 (DDR5Core::getWindowStats, DDR5Core.cpp:312-353)

对每个 Rank × Bank 填充:

统计项
来源
计算方式
counter.{act,pre,reads,writes,...}bank.counter
直接拷贝
cycles.actbank.cycles.act.get_count_at(ts)
开放区间则 count + (ts - start),否则取 count
cycles.pre
推导
simulation_duration - act - powerDownAct - powerDownPre - selfRefresh
cycles.powerDownAct/Prerank.cyclesinterval.get_count_at(ts)
cycles.selfRefreshrank.cycles.srefinterval.get_count_at(ts)

cycles.pre 的减法推导是关键设计:DRAM 中的 PRECHARGE 状态是"其余一切之外"的状态,用总时间减去所有已知状态的时长得到。

Interface 统计 (DDR5Interface::getWindowStats, DDR5Interface.cpp:263-283)

统计项
来源
commandBusm_commandBus.get_stats(ts)
 — CA 总线 zeroes/ones/bit_changes
readBus / writeBusm_dataBus.get_stats(ts)
 — DQ 总线翻转统计
clockStats2 × m_clock.get_stats_at(ts)
 — 差分时钟
readDQSStats / writeDQSStats2 × m_*DQS.get_stats_at(ts)
 — 差分 DQS
togglingStats
Toggling Rate 模式的 read/write 统计

3.5 阶段 5:Power计算

5a. Core Power—— Calculation_DDR5::calcEnergy()

调用链dram_base::calcCoreEnergy(ts) → DDR5::calcCoreEnergyStats(stats) → Calculation_DDR5::calcEnergy(stats)

核心物理模型:Energy = V × I × t,每个操作/状态的功耗 = 电压 × (操作电流 - 背景电流) × 操作时长

Power分量
公式
含义
E_actVDD × (I_θ - I_1) × tRAS × N_act
 ACT Power,一次 ACT 命令
E_preVDD × (I_β - I_DD2N) × tRP × N_pre
预充电power,一次 PRE 命令
E_RDVDD × (I_DD4R - I_DD3N) × (BL/DR) × N_RD
读操作power
E_WRVDD × (I_DD4W - I_DD3N) × (BL/DR) × N_WR
写操作power
E_ref_ab(1/B) × VDD × (I_DD5X - I_DD3N) × tRFC × N_REF
All-Bank Refresh,分摊到每个 bank
E_ref_sb(1/BG) × VDD × (I_DD5C - I_BG) × tRFCsb × N_SB_REF
Same-Bank Refresh(DDR5 特有)
E_bg_act(1/B) × VDD × (I_DD3N - I_ρ) × T_act
单个 bank 的背景 active 功耗
E_bg_pre(1/B) × VDD × I_DD2N × T_pre
单个 bank 的背景 precharge 功耗
E_bg_act_sharedVDD × I_ρ × T_act
跨所有 bank 共享的背景 active 功耗

DDR5 的双电压域循环

for(auto vd :{VDD, VPP}){// DDR5 有两个电压域!
auto VXX = memPowerSpec[vd].vXX;
// ... 对每个电压域独立计算
}

5b. Interface 能量 —— InterfaceCalculation_DDR5::calculateEnergy()

调用链dram_base::calcInterfaceEnergy(ts) → DDR5::calcInterfaceEnergyStats(stats) → InterfaceCalculation_DDR5::calculateEnergy(stats)

子系统
静态功耗
动态功耗
来源
CK (Clock)N_zeroes × V² × tCK / R_eqtransitions × E_dyn
controller
DQS (读)N_zeroes × V² × tCK / R_eqtransitions × E_dyn
DRAM 侧
DQS (写)N_zeroes × V² × tCK / R_eqtransitions × E_dyn
controller 侧
DQ (读)N_zeroes × V² × tCK/DR / R_eqtransitions × E_dyn
DRAM 侧
DQ (写)N_zeroes × V² × tCK/DR / R_eqtransitions × E_dyn
controller 侧
CAN_zeroes × V² × tCK / R_eqtransitions × E_dyn
controller 侧
  • 静态功耗物理意义:当信号为低电平(zero)且 termination 使能时,电流从 VDDQ 经终端电阻流向地 → P = V² / R
  • 动态功耗物理意义:每次 0→1 跳变消耗固定power E_dyn(来自 memspec 的阻抗参数)
  • DDR5 无 DBI(Data Bus Inversion),因此 Interface power计算不包含 calcDBIEnergy
    BTW:整个计算逻辑的思路跟美光给的一版power计算公式类似

4. 模块一:命令系统与数据结构

4.1 CmdType —— 命令枚举

文件src/DRAMPower/DRAMPower/command/CmdType.h

enumclassCmdType{
    NOP =0,  ACT,    PRE,    PRESB,// 基础操作
    RD,       WR,     RDA,    WRA,// 读写(RDA/WRA = Read/Write with Auto-Precharge)
    REFB,     REFP2B, REFSB,  REFA,// 刷新(PerBank/PerTwoBanks/SameBank/AllBank)
    PDEA,     PDEP,   PDXA,   PDXP,// PowerDown(Active/Precharge 进入/退出)
    SREFEN,   SREFEX, DSMEN,  DSMEX,// SelfRefresh & DeepSleepMode
    END_OF_SIMULATION, COUNT
};

共 22 种命令类型,全部标准共享同一套枚举(尽管部分命令在某些标准下不支持)。

CmdTypeUtil 提供 needs_data()(判断 RD/WR/RDA/WRA)、from_string() / to_string() 转换。

4.2 Command —— 命令结构体

文件src/DRAMPower/DRAMPower/command/Command.h

structTargetCoordinate{
    std::size_t bank =0;
    std::size_t bankGroup =0;
    std::size_t rank =0;
    std::size_t row =0;
    std::size_t column =0;
};

classCommand{
    timestamp_t timestamp =0;// 命令执行时间(clock cycle)
    CmdType type;// 命令类型
    TargetCoordinate targetCoordinate;// 目标地址
constuint8_t* data =nullptr;// 数据负载(仅 RD/WR 系列)
    std::size_t sz_bits;// 数据位宽
};

4.3 energy_t / energy_info_t —— power结果

文件src/DRAMPower/DRAMPower/data/energy.h

energy_info_t  (per-bank power)
├── E_act, E_pre, E_RD, E_WR, E_RDA, E_WRA
├── E_pre_RDA, E_pre_WRA              ← auto-precharge 中的 PRE 部分
├── E_bg_act, E_bg_pre                ← 背景功耗
├── E_ref_AB, E_ref_PB, E_ref_SB, E_ref_2B  ← 不同刷新类型
└── total()                           ← 所有分量求和

energy_t  (全体能量)
├── bank_energy: vector<energy_info_t>  ← 每个 bank 的power
├── E_bg_act_shared                    ← 跨 bank 共享的背景 active 功耗
├── E_PDNA, E_PDNP                     ← PowerDown 功耗(Rank 级)
├── E_sref, E_dsm                      ← SelfRefresh / DeepSleep 功耗
└── total()                            ← 所有分量 + bank_energy 总和

interface_energy_info_t
├── controller: {dynamicEnergy, staticEnergy}
├── dram: {dynamicEnergy, staticEnergy}
└── total()

4.4 SimulationStats —— 仿真统计

文件src/DRAMPower/DRAMPower/data/stats.h

SimulationStats
├── bank: vector<CycleStats>           ← 每个 bank 的统计
├── rank_total: vector<CycleStats>     ← 每个 rank 的汇总统计
├── commandBus: bus_stats_t            ← CA 命令总线统计
├── readBus, writeBus: bus_stats_t     ← DQ 数据总线统计
├── clockStats, wClockStats            ← CK / WCK 时钟统计
├── readDQSStats, writeDQSStats        ← DQS 信号统计
├── readDBI, writeDBI                  ← DBI 信号统计
├── togglingStats: {read, write}       ← Toggling Rate 模式统计

CycleStats (per bank 或 per rank)
├── counter: {act, pre, reads, writes, refAllBank, refPerBank, refSameBank, ...}
├── cycles: {act, pre, powerDownAct, powerDownPre, selfRefresh, deepSleepMode}
└── prepos: {readMerged, writeMerged, readSeamless, writeSeamless, ...}  ← 仅 DDR4

bus_stats_t
├── ones, zeroes                       ← 0/1 计数
├── bit_changes                        ← 总跳变次数
├── zeroes_to_ones, ones_to_zeroes    ← 方向性跳变

5. 模块二:Bank/Rank 状态机 —— Core 层

5.1 数据结构

Bank (dram/Bank.h)

structBank{
enumclassBankState{ BANK_PRECHARGED =0, BANK_ACTIVE =1};

    CycleStats::command_stats_t counter;// 命令累计计数
struct{ interval_t act; interval_t powerDownAct; interval_t powerDownPre;} cycles;
    BankState bankState;// 当前状态
    timestamp_t latestPre =0;// 最后一次 PRE 时间
    timestamp_t refreshEndTime =0;// 刷新结束时间
};

Rank (dram/Rank.h)

enumclassMemState{ NOT_IN_PD =0, PDN_ACT, PDN_PRE, SREF, DSM };

structRank{
    MemState memState;
    CommandCounter<CmdType> commandCounter;
struct{
        interval_t pre, act, ref, sref, powerDownAct, powerDownPre, deepSleepMode;
} cycles;
struct{uint64_t selfRefresh, deepSleepMode;} counter;
    timestamp_t endRefreshTime =0;
    std::vector<Bank> banks;
};

5.2 关键机制

5.2.1 interval_counter —— 开放区间周期统计

文件src/DRAMPower/DRAMPower/util/cycle_stats.h

这是整个状态机最精巧的数据结构:

template<typenameT>
classinterval_counter{
    T count{0};
    std::optional<T> start;// 区间开始时间
    std::optional<T> end;// 区间结束时间(std::nullopt 表示仍在进行)

voidstart_interval(T ts){ start = ts; end.reset();}
    T close_interval(T ts){
auto diff = ts -*start;// 计算时长
        count += diff;// 累加到总计
        end = ts;
return diff;
}
    T get_count_at(T ts)const{
if(is_open()&& ts >*start)
return count +(ts -*start);// 开放区间:包含"当前到查询时刻"的增量
return count;
}
};

设计要点:DRAM 中一个状态(如 ACTIVE)的持续时间在状态开始时不可预知——它取决于下一个 PRE 命令何时到达。interval_counter 通过"开放区间 + 延迟结算"完美适配了这一特性。

5.2.2 ImplicitCommandHandler —— 延迟命令队列

文件src/DRAMPower/DRAMPower/util/ImplicitCommandHandler.h

维护一个按时间戳排序的 std::deque<pair<timestamp_t, std::function<void(Context&)>>>

插入 (addImplicitCommand):使用 std::upper_bound 保证时间戳严格有序。

执行 (processImplicitCommandQueue):在每次 doCommand() 开头,执行所有 timestamp ≤ 当前命令时间的延迟回调。

应用场景

触发命令
延迟回调
延迟时间
RDA / WRA
自动执行 handlePre
max(tRAS到期, ts + prechargeOffset)
REFA / REFB / REFSB / REFP2B
自动将 bank 切回 PRECHARGED
ts + tRFC
(或 tRFCPBtRFCsb
SREFEN
先触发 REFA,再进入 SREF
ts + tRFC
PDEA / PDEP
延迟进入 PowerDown
max(tRCD到期, tRP到期, refreshEndTime)
PDXA / PDXP
延迟退出 PowerDown
同上

5.2.3 核心状态转移(以 DDR5 为例)

ACT 激活handleAct(rank, bank, ts) — DDR5Core.cpp:75-85

bank.counter.act++
bank.cycles.act.start_interval(ts)
if rank 无活跃 bank: rank.cycles.act.start_interval(ts)
bank.bankState = BANK_ACTIVE

PRE 预充电handlePre(rank, bank, ts) — DDR5Core.cpp:87-98

if bank 已经是 PRECHARGED → 直接返回(幂等保护)
bank.counter.pre++
bank.cycles.act.close_interval(ts)    // 结算 ACTIVE 周期
bank.latestPre = ts
bank.bankState = BANK_PRECHARGED
if rank 无其他活跃 bank: rank.cycles.act.close_interval(ts)

RDA 读+自动预充电handleReadAuto(rank_idx, bank_idx, ts) — DDR5Core.cpp:169-183

bank.counter.readAuto++
delayed_ts = max(bank.cycles.act.start + tRAS, ts + prechargeOffsetRD)
注册延迟回调: 在 delayed_ts 自动执行 handlePre(rank, bank, delayed_ts)

REFA 全 Bank 刷新handleRefAll(rank_idx, ts) — DDR5Core.cpp:124-132

对每个 bank:
  ++counter.refAllBank
  bank.bankState = BANK_ACTIVE
  bank.cycles.act.start_interval(ts)
  bank.refreshEndTime = ts + tRFC
  注册延迟回调: 在 ts+tRFC 自动切回 PRECHARGED
rank.endRefreshTime = ts + tRFC

5.3 路由辅助层 RegisterHelper

文件src/DRAMPower/DRAMPower/util/RegisterHelper.h

namespace coreHelpers {
bankHandler(cmd, ranks, owner,&DDR5Core::handleAct);
// → 从 ranks[cmd.rank].banks[cmd.bank] 取目标,调 (owner->*func)(rank, bank, ts)

bankHandlerIdx(cmd, ranks, owner,&DDR5Core::handleReadAuto);
// → 传入 (rank_idx, bank_idx, ts) 而不是 (rank&, bank&, ts)

rankHandler(cmd, ranks, owner,&DDR5Core::handlePreAll);
// → 仅传入 (rank, ts)

bankGroupHandler(cmd, ranks, owner,&DDR5Core::handlePreSameBank);
// → 传入 (rank, bank_id, ts),用于跨 bank group 的同位置操作
}

这个工具层消除了 Core 中 switch-case 内重复的 ranks[cmd.rank].banks[cmd.bank] 查找代码。


6. 模块三:接口总线追踪 —— Interface 层

6.1 总体结构

每个标准的 Interface 类(如 DDR5Interface)管理以下组件:

组件
类型
说明
命令总线
 (CA)
Bus<cmdBusWidth>
DDR5: 14-bit, DDR4: 27-bit, LPDDR4: 6-bit, LPDDR5: 7-bit
数据总线
 (DQ)
databus_presets::databus_preset_t
根据 DataBusConfig 选择 Bus 模式或 TogglingRate 模式
读 DQSClock
读数据选通信号,由 DRAM 驱动
写 DQSClock
写数据选通信号,由 controller 驱动
主时钟
 (CK)
Clock
差分时钟
WCKClock
仅 LPDDR5:Write Clock
DBIDBI<...>
仅 DDR4/LPDDR4/LPDDR5:Data Bus Inversion
PatternHandlerPatternHandler<CmdType>
每种命令的 CA 总线编码

6.2 PatternHandler —— 命令编码

文件src/DRAMPower/DRAMPower/util/PatternHandler.h

每种命令在 CA 总线上有不同的 bit 编码。以 DDR5 为例(14-bit CA 总线):

ACT:  L, L, R0-R16, CID3, CID0-CID2, BA0-BA1, BG0-BG2
PRE:  H, H, L, H, H, CID3, BA0-BA1, BG0-BG2, CID0-CID2
RD:   H, L, H*5, BA0-BA1, BG0-BG2, CID0-CID2, C2-C10, V, H, V, V, CID3
WR:   H, L, H, H, L, H, BA0-BA1, BG0-BG2, CID0-CID2, C3-C10, V, H, H, V, CID3
RDA:  类似 RD 但最后一位不同
...

编码中既有常量(H/L/V——High/Low/Don't-care),也有变量(Row/Column/Bank/BankGroup 地址位、CID 等在命令创建时动态填入)。

PatternEncoderOverrides:允许在运行时覆盖某些 bit。例如 DDR5 的 handleOverrides 根据 burst length(8/16/32)和读写方向动态调整 C2/C3/C10 的编码。

6.3 Bus 与 burst_storage —— 总线存储与统计

文件src/DRAMPower/DRAMPower/util/burst_storage.h

这是整个 Interface 层的性能关键。两种存储容器:

BitsetContainer(单线信号,如 Clock、DBI pin)

template<std::size_t N>
structBitsetContainer{
    std::bitset<N> bitset;// 按 bit 存储信号值
    std::size_t count;// 当前存储的 bit 数
    timestamp_t load_time;// 起始时间
};

窗口统计算法 (O(1) 复杂度):

// 1. 右移 offset 位,取出窗口内的 bits
bitset_t val = data.bitset >> offset;

// 2. 生成掩码
bitset_t mask; mask.set(); mask >>=(N - length);

// 3. 应用掩码
val &= mask;

// 4. 统计
ones = val.count();
zeroes = length - ones;

// 5. 位变换统计(xor + popcount)
bitset_t toggles =(val ^(val >>1))&(mask >>1);
bit_changes =popcount(toggles);
zeroes_to_ones =popcount(toggles &(val >>1));
ones_to_zeroes = bit_changes - zeroes_to_ones;

BusContainer(多 bit 并行总线,如 CA、DQ)

template<std::size_t N>
structBusContainer{
    std::vector<std::bitset<N>> bursts;// 每个 burst 存储一整个总线快照
    std::size_t width;// 总线宽度
    std::size_t count;// burst 数量
    timestamp_t load_time;
};

对每个 burst(总线快照)进行统计,逐 burst 累积 diff(prev, current) 的 zeroes/ones/transitions。

6.4 Clock 模型

文件src/DRAMPower/DRAMPower/util/clock.h

Clock 是一个周期性信号,其统计通过 burst_storage<BitsetContainer<2>> 实现——只需要 2 个 bit(存储一个完整周期:0→1→0→1...)。get_stats_at(ts) 返回 zeroes/ones/transitions 统计。

对于差分时钟(CK、DQS),统计值乘以 2。

6.5 DBI —— Data Bus Inversion

文件src/DRAMPower/DRAMPower/util/dbi.h + dbialgos.h + dbihelpers.h

DBI 是一种降低数据总线功耗的技术:如果某个字节中 0 的数量超过 4,DBI 算法会翻转整个字节并将 DBI pin 置位,使接收端知道发生了翻转。

DRAMPower 实现

  • DBI::updateDBI(virtual_time, n_bits, data, read) — 遍历数据,决定是否翻转,回调通知 pin 状态变化
  • 每个 DBI pin(每 8-bit 数据一个)通过 Pin 追踪其 0/1 变化
  • 仅 DDR4、LPDDR4、LPDDR5 支持 DBI(DDR5 不支持)

7. 模块四:power计算层 —— Calculation

7.1 Core Energy 计算公式体系

所有标准的 Core power计算遵循同一套数学框架,差异仅在于参数数量(电压域数、刷新类型等)。

通用公式

power
公式
物理意义
E_act
V × (I_peak - I_background) × tRAS × N_act
超过背景电流的激活电流 × 激活时长
E_pre
V × (I_β - I_DD2N) × tRP × N_pre
超过背景电流的预充电电流 × 预充电时长
E_RD / E_WR
V × (I_DD4X - I_DD3N) × (BL/DR) × N
超过背景电流的读写电流 × 传输时长
E_ref
(1/B) × V × (I_DD5X - I_DD3N) × tRFC × N_REF
刷新电流(分摊到每个 bank)
E_bg_act
(1/B) × V × (I_DD3N - I_ρ) × T_active
每个 bank 在 active 期间的背景泄漏电流
E_bg_pre
(1/B) × V × I_DD2N × T_pre
每个 bank 在 precharge 期间的背景泄漏电流
E_bg_act_shared
V × I_ρ × T_active
跨所有 bank 共享的背景电流(外围电路)

关键参数

  • I_ρ (rho): 银行间功率因子,表示"当一个 bank 已经 active 时,再激活另一个 bank 的边际电流增量"
  • I_θ (theta): 等效 ACT 峰值电流,从 (I_DD0 × (tRP + tRAS) - I_β × tRP) / tRAS 推导
  • I_1 (I_one): 单个 active bank 的稳态电流

7.2 Interface Energy 计算公式体系

静态功耗:当 termination 使能时,信号为 0 期间(DDR/LPDDR4)/ 信号为 1 期间(LPDDR5,pull-down termination 不同)电流从电源经终端电阻流向地:

P_static = N_bits × V_DDQ² / R_eq
E_static = P_static × t_bit = N_bits × V_DDQ² × t_bit / R_eq

动态功耗:每次 0→1 跳变消耗固定能量(来自 memspec 的 _dyn_E 阻抗参数):

E_dynamic = N_transitions × E_per_transition

DDR vs LPDDR 的 termination 差异

标准
Static Termination Count
原因
DDR4/DDR5
zeroes
(信号为低时电流流动)
Pull-up termination to VDDQ
LPDDR4/LPDDR5
ones
(信号为高时电流流动)
Pull-down termination to GND

7.3 各标准 Calculation 差异

特性
DDR4
DDR5
LPDDR4
LPDDR5
电压域
VDD, VPP
VDD, VPP
VDD1, VDD2
VDD1, VDD2H, VDD2L
刷新类型
REFAB only
REFAB + REFSB
REFAB + REFPB
REFAB + REFPB + REFP2B
DBI 支持
PrePostamble 计算
是(DDR4 特有)
否(归入 DQS 统计)
WCK 时钟
DeepSleep
否(v6.0 前)
E_RD/E_WR 的 I_background
I_1
I_1
IDD3N
IDD3N / I_2 (按 bank_arch)

8. 模块五:内存规格 —— MemSpec

8.1 MemSpec 架构

所有标准的 MemSpec 继承自 MemSpec<DRAMUtils::MemSpec::MemSpecXXX>,包含:

  • 时序参数:tCK, tRAS, tRCD, tRP, tRFC, tRFCsb/tRFCPB, tBurst, tRL, tWL...
  • 电源参数:各电压域的 vXX, iXX0, iXX2N, iXX3N, iXX4R, iXX4W, iXX5X, iXX6N, iBeta
  • 阻抗参数:各信号的 R_eq, dyn_E, termination(CK/DQS/DQ/CA/DBI)
  • 架构参数:numberOfBanks, numberOfRanks, numberOfBankGroups, banksPerGroup, bitWidth, burstLength, dataRate, numberOfDevices
  • Bank-wise 参数bwPowerFactRho(背景功率因子)

8.2 MemSpec 初始化流程

1. DRAMUtils::parse_memspec_from_file("ddr5.json")
   → 返回 MemSpecVariant (std::variant<MemSpecDDR4, MemSpecDDR5, MemSpecLPDDR4, MemSpecLPDDR5>)

2. MemSpecDDR5::from_memspec(variant)
   → 从 variant 中提取 DDR5 规格,解析阻抗、数据速率等

3. DDR5 dram(MemSpecDDR5)
   → 用 memspec 初始化 Core + Interface

8.3 DDR5 MemSpec 结构(代表性)

classMemSpecDDR5:publicMemSpec<DRAMUtils::MemSpec::MemSpecDDR5>{
uint64_t numberOfBankGroups;// BG 模式特有
uint64_t banksPerGroup;// BG 模式特有
uint64_t numberOfRanks;
double vddq;// I/O 电压

structMemTimingSpec{double fck, tCK;uint64_t tRAS, tRCD, tRFC, tRFCsb, tRP, tBurst;};
structMemPowerSpec{double vXX, iXX0, iXX2N, iXX3N, iXX4R, iXX4W, iXX5X, iXX5C, iXX6N, iBeta;};
structDataRateSpec{uint64_t commandBusRate, dataBusRate, dqsBusRate;};
structBankWiseParams{double bwPowerFactRho;};
};

所有值均为 SI 单位(伏特、安培、秒)。


9. 模块六:扩展系统

9.1 扩展架构

文件src/DRAMPower/DRAMPower/util/extension_base.hextension_manager.hextension_manager_static.hextensions.hextensions.cpp

v6.0.0 新增的插件系统,分两层:

层级
文件
说明
动态扩展extension_manager.h
运行时注册/查找/获取扩展,存储在 std::unordered_map<type_index, unique_ptr<Extension>>
静态扩展extension_manager_static.h
编译时注册的扩展集合(ExtensionPack),支持 get<ExtType>() 模板方法

9.2 扩展基类

classExtension{
virtual~Extension()=default;
};

template<typenameHooks>
classExtensionWithHooks:publicExtension{
virtual Hooks getSupportedHooks()const=0;
};

9.3 与 dram_base 的集成

dram_base 持有 extension_manager_t m_extensionManager,扩展随 serialize()/deserialize() 一同持久化。在序列化时先写入扩展管理器状态,再写入 Core/Interface 状态。


10. 模块七:工具组件

10.1 Serialize / Deserialize 接口

文件src/DRAMPower/DRAMPower/util/Serialize.hDeserialize.h

纯虚接口,所有有状态组件(Bank, Rank, DDR5Core, DDR5Interface, Bus, Clock, DBI...)均实现此接口:

classSerialize{virtualvoidserialize(std::ostream&)const=0;};
classDeserialize{virtualvoiddeserialize(std::istream&)=0;};

数据以原始字节写入(reinterpret_cast<const char*>),用于 checkpoint/restore 和并行仿真。

10.2 Clock

文件src/DRAMPower/DRAMPower/util/clock.h

classClock{
    burst_storage<BitsetContainer<2>> m_clock;// 2-bit 足够表示一个时钟周期
bool m_stop_between_requests;// 是否在无请求时停止
bool m_is_running;
voidstart(timestamp_t);// 时钟开始翻转
voidstop(timestamp_t);// 时钟停止翻转
    bus_stats_t get_stats_at(timestamp_t)const;
};

对于 DDR5 的 wckAlwaysOnMode,WCK 始终运行,不调用 stop。

10.3 Bus

文件src/DRAMPower/DRAMPower/util/bus.hbus.cpp

template<std::size_t BitWidth>
classBus{
    burst_storage<BusContainer<BitWidth>> m_bus;
voidload(timestamp_t,uint64_t pattern, std::size_t n_cycles);
    bus_stats_t get_stats(timestamp_t)const;
};

10.4 databus_presets

文件src/DRAMPower/DRAMPower/util/databus_presets.h

根据 DataBusConfig(位宽、数据率、ToggleRate 定义)创建合适的数据总线实例。支持两种模式:

  • Bus 模式:真实数据逐 bit 存储到 burst_storage<BusContainer<N>>
  • TogglingRate 模式:不存储数据,仅基于概率(togglingRateRead/WritedutyCycleRead/WriteidlePatternRead/Write)做统计

11. 横向对比:DDR4 vs DDR5 vs LPDDR4 vs LPDDR5

11.1 命令支持矩阵

命令
DDR4
DDR5
LPDDR4
LPDDR5
说明
ACT
激活一行
PRE
预充电单个 bank
PREA
预充电所有 bank
PRESB
预充电同 bank group 同位置 bank
RD
RDA
读+自动预充电
WR
WRA
写+自动预充电
REFA
所有 bank 刷新
REFB
单 bank 刷新
REFSB
同 bank group 同位置 bank 刷新
REFP2B
✓*
两 bank 刷新(仅 MBG/M16B)
SREFEN/EX
自刷新进入/退出
PDEA/PDXA
Active PowerDown 进入/退出
PDEP/PDXP
Precharge PowerDown 进入/退出
DSMEN/EX
Deep Sleep Mode 进入/退出(LPDDR5 特有)

11.2 状态机差异

DDR4

Bank 状态: PRECHARGED ↔ ACTIVE
Rank 状态: NOT_IN_PD / PDN_ACT / PDN_PRE / SREF

特点:
- 无 bank group 概念 → 无 PRESB/REFSB
- PDXA 退出时用 bank.bankState == BANK_ACTIVE 判断恢复哪些 bank
- PDXP 退出时同样用 bankState 判断
- start_interval_if_not_running 用于 rank act interval

DDR5

Bank 状态: PRECHARGED ↔ ACTIVE
Rank 状态: NOT_IN_PD / PDN_ACT / PDN_PRE / SREF

特点(相比 DDR4):
- 有 bank group → PRESB(同 BG 同位置所有 bank 的 precharge)
- REFSB(同 BG 同位置 bank 的刷新,使用 tRFCsb)
- PDXA 退出时使用 counter.act != 0 && cycles.act.get_end() == powerDownAct.get_start() 判断恢复
- E_ref_sb 能量公式使用 (1/BG) 分摊因子
- 双电压域 (VDD + VPP)

LPDDR4

Bank 状态: PRECHARGED ↔ ACTIVE
Rank 状态: NOT_IN_PD / PDN_ACT / PDN_PRE / SREF

特点(相比 DDR4/DDR5):
- Per-Bank Refresh (REFB) 使用 tRFCPB timing
- 无 bank group → 无 PRESB/REFSB
- PDXA 退出时同样用 counter.act != 0 && end == powerDownAct.get_start() 判断
- 双电压域 (VDD1 + VDD2)
- 支持 DBI

LPDDR5

Bank 状态: PRECHARGED ↔ ACTIVE
Rank 状态: NOT_IN_PD / PDN_ACT / PDN_PRE / SREF / DSM

特点(最复杂):
- Deep Sleep Mode (DSM) — 从 SREF 进入,回到 SREF
- REFP2B (Per Two Banks Refresh) — 仅 M8B/MBG/M16B 架构
- bank_arch 依赖:根据不同 bank 架构(MBG/M8B/M16B),命令编码不同
  例如 MBG 模式下 pattern 包含 BG0/BG1 位
- 三电压域 (VDD1 + VDD2H + VDD2L)
- 支持 WCK (Write Clock)
- 支持 wckAlwaysOnMode(WCK 常开)
- Interface 没有 writeDQS — LPDDR5 使用 WCK 而非 WDQS

11.3 Core 实现差异对比表

特性
DDR4
DDR5
LPDDR4
LPDDR5
handleAct
 的 rank 激活检查
start_interval_if_not_running(ts)if (!rank.isActive(ts))if (!rank.isActive(ts))if (!rank.isActive(ts))
handlePre
 的 rank 关闭检查
if (!rank.isActive(ts))if (!rank.isActive(ts))if (!rank.isActive(ts))if (!rank.isActive(ts))
Refresh 实现
内联在 handleRefAll
handleRefreshOnBank 统一
handleRefreshOnBank 统一
handleRefreshOnBank 统一
银行组支持
✓ (PRESB, REFSB)
✗ (但 bank_arch 影响)
DeepSleep
✓ (DSMEN/DSMEX)
SelfRefresh 的 selfRefresh 减去 DSM
N/A
N/A
LPDDR4 有但未使用 DSM
selfRefresh - deepSleepMode
PDXA 恢复逻辑
检查 bank.bankState == ACTIVE
检查 counter.act != 0 && end == pd_start
检查 counter.act != 0 && end == pd_start
检查 counter.act != 0 && end == pd_start
MemSpec 银行组参数
banksPerGroup, numberOfBankGroups
bank_arch (MBG/M8B/M16B)

11.4 Interface 实现差异对比表

特性
DDR4
DDR5
LPDDR4
LPDDR5
CA 总线宽度
27 bit
14 bit
6 bit
7 bit
CA 总线 data rate
1 (SDR)
1 (SDR)
1 (SDR)
2 (DDR)
Idle 模式
H (pull-up)
H (pull-up)
L (pull-down)
L (pull-down)
DBI 支持
✓ (8-bit 粒度)
✓ (8-bit 粒度)
✓ (8-bit 粒度)
PrePostamble 追踪
✓ (seamless/merged)
WCK 时钟
✓ (wckAlwaysOnMode)
写 DQS
✗ (用 WCK 替代)
PowerDown 命令在 CA 总线
✓ (CKE 信号)
✗ (无总线活动)
ACT 编码
单条命令 27-bit
单条命令 14-bit
单条命令 24-bit (4×6)
两条命令
 (ACT-1 + ACT-2) 28-bit (4×7)
Burst Length 覆盖
4/8 (C0/C1/C2)
8/16/32 (C2/C3/C10)
16/32 (BL/C2/C3/C4)
16/32 (C0)

11.5 Calculation 差异对比表

特性
DDR4
DDR5
LPDDR4
LPDDR5
电压域数
2 (VDD, VPP)
2 (VDD, VPP)
2 (VDD1, VDD2)
3 (VDD1, VDD2H, VDD2L)
E_ref 类型
E_ref_AB
E_ref_AB + E_ref_SB
E_ref_AB + E_ref_PB
E_ref_AB + E_ref_PB + E_ref_2B
E_act 的 I_background
I_1
I_1
IDD3N
IDD3N
E_RD/E_WR 的 I_background
IDD3N
IDD3N
IDD3N
IDD3N / I_2 (按 bank_arch)
tCK vs tWCK
使用 tCK
使用 tCK
使用 tCK
使用 tWCK (RD/WR)
E_srefV × I_DD6 × T_srefV × I_DD6 × T_srefV × I_DD6 × T_srefV × I_DD6 × T_sref
E_dsm
N/A
N/A
N/A
V × I_DD6DS × T_dsm
IDD5PB 计算
N/A
N/A
需要从 I_DD5PB 和 tREFI 反推
需要从 I_DD5PB 和 tREFI 反推
IBeta 参数
I_2 参数
N/A
N/A
N/A
IDD3N + (IDD3N - I_rho)
 (MBG 模式)

11.6 MemSpec 差异对比表

参数
DDR4
DDR5
LPDDR4
LPDDR5
bankGroups
BG0, BG1 (2 bit)
BG0, BG1, BG2 (3 bit)
无 Bank Group
可选 BG0, BG1 (MBG 架构)
banksPerGroup
固定 4
灵活
N/A
N/A
tRFCsb
N/A
N/A
N/A
tRFCPB
N/A
N/A
vddq
wckAlwaysOnMode
N/A
N/A
N/A
IBeta
✓ (单独)
✓ (在 PowerSpec 中)
✓ (在 PowerSpec 中)
✓ (在 PowerSpec 中)
prePostamble
✓ (read/write zeroes, zero_to_one)
N/A
N/A
N/A

12. 关键设计模式总结

12.1 为什么这个架构好

  1. Core 与 Interface 完全解耦:两者各自独立追踪状态,仅通过 SimulationStats 汇合。可以独立测试、独立替换、甚至独立序列化。

  2. ImplicitCommandHandler 解决了"时序语义的延迟表达":DRAM 中的 auto-precharge、refresh 后恢复、power-down 延迟等操作的本质是"在当前时间点注册未来时间点的行为"。这个延迟队列完美建模了这一语义,避免了在每次状态转移时手动检查"是否该自动 precharge 了"。

  3. interval_counter 是对 DRAM 周期统计的完美抽象:DRAM 状态的持续时长在状态开始时不可预知。start_interval → close_interval 的模式天然匹配了"由后续命令决定时长"的实际场景。is_open() 检查 + get_count_at() 的增量查询优雅地处理了"仿真中途查询统计"的需求。

  4. RegisterHelper 消除了路由模板代码:四种标准共 60+ handler,如果没有这个路由辅助层,每个标准都需要重复编写 ranks[cmd.rank].banks[cmd.bank] 等索引代码。

  5. burst_storage 的位级统计是性能关键xor + popcount 在 O(1) 时间内完成任意窗口的位翻转统计,这对于需要处理大量数据总线的 Interface 层至关重要。

12.2 潜在的改进方向

  1. Bank 状态枚举可扩展为状态机模式:当前 Bank 只有 PRECHARGED ↔ ACTIVE 两种状态,状态转移逻辑散落在各个 handler 中。如果 Bank 状态更复杂(如 HBM 的更多状态),可以考虑引入正式的状态机模式。

  2. power计算与统计收集的分离:当前 getWindowStats 同时负责收集 Core 和 Interface 统计。如果希望增量式地查询power(而非等到仿真结束),可以引入 observer 模式在每次状态转移时推送增量统计。


本文档基于 DRAMPower v6.0.0 源码分析生成,覆盖了 src/DRAMPower/DRAMPower/ 下全部 80+ 源文件的深度阅读。


13. 实际运行测试

13.1 测试计划

阶段
内容
验证目标
构建
CMake 配置 + 编译
确认项目可构建,CLI 工具可运行
场景1
基础 Trace: ACT→PRE→END
验证最基本的 ACT/PRE 状态机和能量计算
场景2
读写 Trace: ACT→RD→PRE
验证 RD 命令 + 数据总线能量
场景3
RDA/WRA 自动预充电
验证 ImplicitCommandHandler 的延迟 PRE
场景4
REFA 全 Bank 刷新
验证刷新能量 + 隐式 PRE 后的状态恢复
场景5
PowerDown 进入/退出
验证 PDEA/PDXA + PDEP/PDXP 延迟机制
场景6
全功能 Trace
组合所有命令类型,验证综合能量计算

13.2 测试环境

操作系统:   WSL2 (Linux 6.6.87.2)
编译器:     GCC 13.3.0 (C++17)
构建系统:   CMake 3.22+
依赖:       DRAMUtils v1.12.1, spdlog 1.9.2, CLI11 2.4.2, nlohmann_json 3.11.3
优化级别:   -march=native -mtune=native (Release)

13.3 构建步骤

cd DRAMPower
cmake -S.-B build -DDRAMPOWER_BUILD_CLI=Y
cmake --build build --parallel
# Output: build/bin/cli

构建结果: ✅ 全部 8 个 target 编译成功(DRAMPower 静态库 + spdlog + CLI11 + cli_lib + cli 可执行文件),无警告无错误。

13.4 DDR5 MemSpec 参数(本次测试使用)

以下参数来自 tests/tests_drampower/resources/ddr5.json,模拟一款典型的 DDR5-5200 x8 1Rank 内存:

参数
说明
memoryType
DDR5
nbrOfBanks
16
16 Bank
nbrOfBankGroups
2
2 Bank Group(每组 8 Bank)
nbrOfRanks
1
单 Rank
nbrOfDevices
1
单 Device
burstLength
8
BL8
dataRate
2
DDR
width
8
x8 位宽
tCK
0.769 ns
≈1.3 GHz 时钟频率
tRAS
10 cycles
行激活最小时间
tRCD
13 cycles
RAS-to-CAS 延迟
tRP
10 cycles
预充电时间
tRFC
25 cycles
全 Bank 刷新时间 (RFC1)
tRFCsb
20 cycles
同 Bank Group 刷新时间
VDD
1.2 V
核心电压
VPP
1.2 V
字线泵电压(DDR5 特有)
VDDQ
1.1 V
I/O 电压
IDD0
56.25 mA
单 Bank Active 背景电流
IDD2N
33.75 mA
单 Bank Precharge 背景电流
IDD3N
39.50 mA
Active Standby 电流
IDD4R
157.50 mA
Read 操作电流
IDD4W
135.00 mA
Write 操作电流
IDD5B
118.00 mA
All-Bank Refresh 电流
IDD6N
20.25 mA
Self-Refresh 电流
factRho
0.5
银行间功率因子 ρ
CK R_eq
1 MΩ
时钟终端电阻
CK dyn_E
1 pJ
时钟动态切换能量
CA/DQ/DQS R_eq
1 MΩ
I/O 终端电阻
CA/DQ/DQS dyn_E
1 pJ
I/O 动态切换能量

13.5 配置文件

CLI 使用的配置文件 config.json:

{
"useToggleRate":false,
"simconfig":{}
}

不使用 Toggling Rate 模式,使用真实数据(Bus 模式)。

13.6 场景1:基础 Trace(ACT→PRE→END)

Trace 文件 (tests/tests_drampower/resources/ddr5.csv):

0 ,ACT,0,0,0,0,0
15,PRE,0,0,0,0,0
15,END,0,0,0,0,0

命令序列:
| 时间 | 命令 | 含义 |
|---|---|---|
| t=0 | ACT | 激活 Bank 0 |
| t=15 | PRE | 预充电 Bank 0 |
| t=15 | END | 仿真结束 |

运行命令:

./build/bin/cli -m tests/tests_drampower/resources/ddr5.json \
-c build/bin/config.json \
-t tests/tests_drampower/resources/ddr5.csv

结果:

Rank,Device,Bank 0: ACT: 1.795e-10 J  PRE: 2.077e-10 J  BG_ACT: 2.488e-12 J  BG_PRE: 0
Rank,Device,Bank 1-15: (全零)
Cumulated:  ACT: 1.795e-10  PRE: 2.077e-10  BG_ACT: 5.096e-10  BG_PRE: 0
Shared:     E_bg_act_shared: 5.071e-10  E_PDNA: 0  E_PDNP: 0  E_sref: 0
Interface:  Controller: dyn=4.30e-11, static=3.63e-14  DRAM: dyn=0, static=0
Total Energy: 9.398e-10 J ≈ 0.94 nJ

验证:

  • E_act = 1.795 × 10⁻¹⁰ J — 与单元测试 ddr5_test_pattern_0.cpp 的期望值 179 pJ (×10¹²) 一致 ✓
  • E_pre = 2.077 × 10⁻¹⁰ J — 与期望值 208 pJ 一致 ✓
  • E_bg_act = 5.096 × 10⁻¹⁰ J — 与期望值 510 pJ 一致 ✓
  • E_bg_act_shared = 5.071 × 10⁻¹⁰ J — 与期望值 507 pJ 一致 ✓
  • cycles.act = 15, cycles.pre = 0 — 状态机正确追踪了 ACTIVE 时长 ✓

13.7 场景2-5:增量命令测试

每个场景均通过 CLI 验证正确性:

场景
Trace
验证点
结果
ACT+RD+PRE
t=0 ACT, t=15 RD(data), t=35 PRE
E_RD = 4.357e-10 J,Interface 有数据总线能量
ACT+RDA
t=0 ACT, t=20 RDA(data), t=40 END
E_RDA + E_pre_RDA 正确计入,自动 PRE 被延迟执行
ACT+REFA
t=0 ACT, t=20 REFA, t=50 END
全部 16 Bank 的 E_ref_AB 均非零,隐式 PRE 由 REFA 覆盖
ACT+PDEA/PDXA
t=0 ACT, t=25 PDEA, t=80 PDXA, t=95 PRE
E_PDNA 非零,PD 退出后 Bank 恢复 ACTIVE
ACT+PDEP/PDXP
t=0 ACT, t=15 PRE, t=25 PDEP, t=80 PDXP
E_PDNP 非零,PD 退出后 Bank 保持 PRECHARGED

13.8 场景6:全功能综合 Trace

Trace 设计(22 条命令,span=460 cycles):

BTW:此处试运行的场景还是偏简单的,但是可视化后的效果还是很好。具体要精确度,实际上还是可以用具体的访问memory的行为给一个比较长的trace来表征。具体跟实际行为之间是否有power数据gap,还需要更多的数据对比。

#  Time  Cmd   Rnk BG Bk  Data(hex)        说明
──────────────────────────────────────────────────
1    0   ACT    0   0  0   —               Bank 0 激活
2   15   RD     0   0  0   DEADBEEFCAFEBABE 读 Bank 0
3   35   PRE    0   0  0   —               预充电
4   45   ACT    0   0  1   —               Bank 1 激活
5   60   WR     0   0  1   0123456789ABCDEF 写 Bank 1
6   80   PRE    0   0  1   —               预充电
7   90   ACT    0   0  2   —               Bank 2 激活
8  110   RDA    0   0  2   AABBCCDDEEFF0011 读+自动预充电
9  135   ACT    0   0  3   —               Bank 3 激活
10 155   WRA    0   0  3   FEEDFACEC0FFEE00 写+自动预充电
11 180   ACT    0   0  4   —               Bank 4 激活
12 200   REFA   0   0  0   —               全部 Bank 刷新
13 240   ACT    0   0  0   —               Bank 0 再次激活
14 255   RD     0   0  0   1122334455667788 读 Bank 0
15 275   PRE    0   0  0   —               预充电
16 285   ACT    0   0  0   —               Bank 0 第三次激活
17 310   PDEA   0   0  0   —               进入 Active PowerDown
18 370   PDXA   0   0  0   —               退出 Active PowerDown
19 390   PRE    0   0  0   —               预充电
20 400   PDEP   0   0  0   —               进入 Precharge PowerDown
21 450   PDXP   0   0  0   —               退出 Precharge PowerDown
22 460   END    0   0  0   —               仿真结束

运行命令:

./build/bin/cli -m tests/tests_drampower/resources/ddr5.json \
-c build/bin/config.json \
-t ddr5_full.csv \
-j output.json

13.9 能量可视化图表

使用 scripts/drampower_chart.py 对 JSON 输出生成 4 张图表:(此处的脚本在原来的开源环境里面没有,是通过claude code自行进行优化后产生的可视化python脚本)

python3 scripts/drampower_chart.py output.json -o docs/diagrams/

图表1:每个 Bank 的能量堆叠柱状图

  • 上图:16 个 Bank 按能量类别(Activation/Read-Write/Precharge/Refresh/Background)堆叠显示
  • 下图:仅显示有活动的 Bank(Bank 0-4 + Bank 5-15),详细拆分为 11 个能量分量
  • 关键观察:Bank 0 能量最高(3 次 ACT + 2 次 RD),Bank 4 的 E_pre=0(REFA 导致隐式 PRE),Bank 5-15 仅有背景功耗 + 刷新分摊

图表2:Power组成环形图 + 分类排序

  • 左侧环形图:各能量类别的占比可视化
    • BG Active (Shared): 40.4% — 最大分量
    • BG Active (per-bank): 约 24%
    • BG Precharge: 约 14%
    • PowerDown: 约 9.4%
  • 右侧横向柱状图:按大小排序,附精确数值
  • 关键观察:背景功耗(BG Active + BG Precharge + Shared)合计占 ~79% 总能量

图表3:Core vs Interface 能量流图

  • 上层:Core Energy (94.3%) vs Interface Energy (5.7%) 两大块
  • 中层:7 个子类别分解(Direct Ops / Bank BG / Shared BG / PowerDown / I/O Ctrl / I/O DRAM)
  • 下层:14 个能量分量的排序柱状图(从 BG Act Shared 到 I/O DRAM Static)
  • 关键观察:Interface 能量仅 1.22 nJ,远小于 Core 的 20.04 nJ

图表4:综合仪表盘

包含 6 个面板:

  • (0,0) 总能量指示器: 21.26 nJ / 460 cycles
  • (0,1) Core 能量分布: 6 大类柱状图
  • (0,2) Interface 能量: Ctrl/Dram Dynamic/Static (pJ 级)
  • (1,0) Top 5 最耗能 Bank: Bank 0 (2.8 nJ) > Bank 4 > Bank 2 > Bank 3 > Bank 1
  • (1,1) Bank Group 能量表: BG0 vs BG1 各操作的能量分布
  • (1,2) 关键指标: 平均功率 60.1 mW,背景功耗占 Core 的 81.3%

13.10 测试结果关键洞察

洞察
数据支撑
背景功耗是主要消耗
BG Active + BG Precharge + Shared = 79.1% 总能量。460 cycles 中大多数 Bank 处于空闲状态,背景泄漏电流持续消耗能量
PowerDown 显著节能
60 cycles PDA 消耗 1.25 nJ (IDD3P=22.5mA),若未进入 PD 则消耗约 1.85 nJ (IDD3N=39.5mA),节省 32%
Interface 能量可忽略
I/O 能量仅占总量的 5.7%,主要能耗在核心阵列而非数据传输
REFA 吞噬显式 PRE
Bank 4 的 E_pre=0,因为 REFA 的隐式 PRE 不产生额外 PRE 能量,刷新能量已覆盖
RDA 与 RD+PRE 能量等价
RDA 的 E_RDA + E_pre_RDA ≈ RD+PRE 的 E_RD + E_pre,差异仅来自 ACTIVE 时长的背景功耗微小变化
单次操作能量级
ACT≈0.18 nJ, PRE≈0.21 nJ, RD≈0.44 nJ, WR≈0.35 nJ, REF(all-bank)≈1.81 nJ (16 bank 合计)

13.11 自动化测试脚本

所有测试场景已整合到以下脚本中,可一键复现:

scripts/drampower_chart.py — 通用 DRAMPower 可视化脚本

# 用法
python3 scripts/drampower_chart.py <output.json>-o<charts_dir>

# 生成 4 张图表:
#   {prefix}_per_bank.png      — Per-Bank Power堆叠图
#   {prefix}_composition.png   — Power组成环形图 + 分类排序
#   {prefix}_energy_flow.png   — Core vs Interface Power流图
#   {prefix}_dashboard.png     — 6 面板综合仪表盘

支持的 JSON 格式:任何由 drampower_cli -j output.json 生成的输出文件。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 22:24:59 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/638796.html
  2. 运行时间 : 0.105953s [ 吞吐率:9.44req/s ] 内存消耗:5,127.69kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=37c9449b8c08220899d74657cf186a38
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000498s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000690s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000277s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000302s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000550s ]
  6. SELECT * FROM `set` [ RunTime:0.000235s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000518s ]
  8. SELECT * FROM `article` WHERE `id` = 638796 LIMIT 1 [ RunTime:0.000587s ]
  9. UPDATE `article` SET `lasttime` = 1783088699 WHERE `id` = 638796 [ RunTime:0.018610s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000388s ]
  11. SELECT * FROM `article` WHERE `id` < 638796 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000571s ]
  12. SELECT * FROM `article` WHERE `id` > 638796 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000410s ]
  13. SELECT * FROM `article` WHERE `id` < 638796 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000757s ]
  14. SELECT * FROM `article` WHERE `id` < 638796 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001301s ]
  15. SELECT * FROM `article` WHERE `id` < 638796 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000860s ]
0.107936s