跳转至

整体微架构

香山是一个 RV64 高性能乱序核。对软件工程师最有用的第一层抽象不是“多少级 流水”,而是三条彼此耦合的状态流:

  • 控制流:BPU 预测未来 PC,后端验证并在错误时 redirect;
  • 数据流:逻辑寄存器经重命名进入物理寄存器和旁路网络;
  • 内存顺序流:Load/Store 在 LSQ 中乱序执行,在 ROB 中顺序提交。

核内三大边界

flowchart LR
  SW["软件可见状态<br/>PC · GPR/FPR/VR · CSR · Memory"]
  FE["Frontend<br/>BPU · FTQ · ICache<br/>IFU · IBuffer"]
  BE["Backend<br/>Decode · Rename · Dispatch<br/>Issue · Execute · ROB/RAB"]
  MEM["MemBlock<br/>LSU · LSQ · MMU<br/>DCache · Prefetch"]
  L2["L2 / OpenLLC<br/>TileLink · CHI"]

  FE -->|"指令流"| BE
  BE -->|"访存微操作"| MEM
  MEM -->|"写回 / replay / violation"| BE
  BE -->|"redirect / fence / CSR control"| FE
  FE <-->|"I 请求"| L2
  MEM <-->|"D / PTW 请求"| L2
  BE -->|"顺序退休"| SW
  SW -.->|"取指与数据地址"| FE
  SW -.-> MEM

顶层 XSCore.scala 直接实例化 FrontendBackendMemBlock。它的连线是理解全仓库最好的 入口:前端与后端交换指令和 redirect,后端与 MemBlock 交换发射、写回、LSQ 索引和违例信息,CSR 控制则同时影响前端和 MMU。

当前默认配置快照

下表是本仓库当前 DefaultConfig 的代码默认值,不代表频率、物理实现结果或 其他配置类。

维度 当前值 源码含义
XLEN / VLEN / ELEN 64 / 128 / 64 bit 标量、向量寄存器长度与最大元素宽度
Fetch block / ports 64 B / 2 前端一次预测/取指块与双取指端口
Decode / Rename 8 / 8 每周期进入后端前半段的最大宽度
Commit 8 每周期最大退休宽度
ROB / RAB 352 / 352 指令顺序窗口与架构提交解耦结构
物理寄存器 Int 224 / FP 256 / Vec 128 分别服务标量整数、浮点、向量数据
标量 Load / Store 流水 3 / 2 MemBlock 与后端配置的对应执行通道
向量 Load / Store 流水 2 / 2 向量访存执行通道
L1D / L2 / OpenLLC 64 KiB / 2 MiB / 16 MiB DefaultConfig 中的 cache 容量

参数来源: XSCoreParametersFrontendParametersDefaultConfig

不要把参数名直接当成有效硬件规格

配置由 CDE/Chisel 组合生成;同名旧字段、派生 BackendParams、alternate config 和 submodule 参数可能共同决定最终硬件。严谨做法是固定 CONFIG,查看 elaboration 输出,并在生成 Verilog 中复核实例数量。

一条普通整数指令

  1. BPU 给出下一取指块;FTQ 保存预测上下文。
  2. ICache/IFU 取得并预译码指令,IBuffer 对齐后送入后端。
  3. Decode 产生微操作;Rename 把逻辑源/目的寄存器映射为物理寄存器。
  4. Dispatch 把微操作分配到对应调度区域和 Issue Queue。
  5. 源操作数就绪后发射;执行结果经旁路和写回网络唤醒消费者。
  6. ROB 等待此前指令完成;到达头部且无异常时按程序顺序退休。

控制错误和异常为什么代价高

乱序核允许大量“尚未成为架构事实”的工作同时存在。分支预测错误、访存顺序 违例或异常出现时,需要:

  • 选出最老且应优先处理的 redirect/exception;
  • 作废更年轻的微操作和队列项;
  • 恢复重命名映射、预测历史和取指 PC;
  • 保留已经提交的架构状态;
  • 重新取指并重新建立流水线占用。

因此优化不能只看单条指令延迟,还要看错误发生时核内有多少有效工作被丢弃。

下一步