项目分析文档

一生一芯 (YSYX) 全栈处理器设计项目

一、项目概览

1.1 项目简介

"一生一芯"(One Student One Chip, YSYX) 是由中国科学院大学、中国科学院计算技术研究所主导的开源免费公益性质的处理器芯片设计人才培养项目。目标是让每位参与的学生独立完成一颗 RISC-V 处理器芯片的设计,最终实现流片。

项目官网:https://ysyx.oscc.cc

1.2 合作单位

  • 中国科学院大学 (UCAS)
  • 中国科学院计算技术研究所 (ICT)
  • 鹏城实验室 (PCL)
  • 北京开源芯片研究院 (BOSC)
  • 上海处理器技术创新中心
  • 字节跳动、有道
  • 中国开放指令生态联盟 (CRVA)

1.3 项目特色

  • 全栈培养:涵盖软件模拟器 → RTL 设计 → SoC 集成 → 流片验证全流程
  • 差分测试驱动:用已验证的软件模型作为参考,保证硬件设计正确性
  • 开源生态:基于 RISC-V 开放指令集,使用开源 EDA 工具链
  • 阶梯式学习:D → C → B 阶段递进,逐步提升设计复杂度

1.4 技术栈总览

类别 技术
硬件描述语言 Verilog, SystemVerilog
编程语言 C, C++, RISC-V Assembly
处理器架构 RISC-V (RV32E/RV32IM + Zicsr)
总线协议 AMBA AXI4, AXI4-Lite
仿真工具 Verilator (周期精确仿真)
EDA 工具 Yosys (逻辑综合), GTKWave (波形查看)
构建系统 GNU Make, Kconfig
验证方法 差分测试 (DiffTest), 形式验证 (SVA)
调试追踪 ITRACE, MTRACE, FTRACE, ETRACE, IRINGBUF

二、D 阶段 — 基础阶段 (NEMU + AM + 迷你处理器)

D 阶段的核心目标是理解计算机系统的完整执行流程:从编写程序到机器码执行,建立软硬件协同的整体认知。


D1: 支持 RV32IM 的 NEMU

目标:实现一个支持 RISC-V 32 位指令集的全系统模拟器

项目中对应的实现

NEMU (NJU Emulator) 是南京大学开发的教学用全系统模拟器,本项目对其进行了完整实现。

核心架构

nemu/src/
├── cpu/          # CPU 执行核心
│   ├── cpu-exec.c    # 指令执行主循环 (取指→译码→执行→更新PC)
│   └── iringbuf.c   # 指令环形缓冲 (crash 时回溯)
├── engine/       # 执行引擎 (解释器模式)
├── isa/          # 多 ISA 实现
│   ├── riscv32/      # RV32IM 指令集实现
│   ├── riscv64/      # RV64IM 指令集实现
│   ├── mips32/       # MIPS32 实现
│   └── loongarch32r/ # LoongArch32R 实现
├── memory/       # 物理/虚拟地址管理
│   ├── paddr.c       # 物理地址空间
│   └── vaddr.c       # 虚拟地址翻译
├── monitor/      # 简易调试器 (sdb)
│   └── sdb/          # 单步、断点、表达式求值、监视点
└── utils/        # 反汇编、日志、计时

实现的 RV32IM 指令

  • R 型:add, sub, sll, slt, sltu, xor, srl, sra, or, and
  • R 型 (M 扩展):mul, mulh, mulhsu, mulhu, div, divu, rem, remu
  • I 型:addi, slti, sltiu, xori, ori, andi, slli, srli, srai, lb, lh, lw, lbu, lhu, jalr
  • S 型:sb, sh, sw
  • B 型:beq, bne, blt, bge, bltu, bgeu
  • U 型:lui, auipc
  • J 型:jal
  • 系统指令:ecall, ebreak, csrrw, csrrs, csrrc, mret

调试监视器 (sdb) 功能

  • si [N] — 单步执行 N 条指令
  • info r — 查看寄存器状态
  • x N EXPR — 扫描内存
  • p EXPR — 表达式求值
  • w EXPR — 设置监视点
  • d N — 删除监视点

配置管理:使用 Kconfig (Linux 内核配置系统) 管理编译选项,支持 menuconfig 交互式配置。

关键技术点

  • 解释器模式逐条执行 guest 指令
  • 支持构建为共享库 (.so),作为差分测试的 Golden Reference
  • Kconfig 管理多 ISA/多功能的条件编译

D2: 程序的机器级表示

目标:理解 C 程序如何被编译为机器码,掌握 ABI、调用约定、内存布局

项目中对应的实现

  • 交叉编译工具链:使用 riscv64-linux-gnu-gcc 交叉编译
  • 编译选项 (abstract-machine/Makefile):
    CC = $(CROSS_COMPILE)gcc
    CFLAGS += -O2 -Wall -Werror -fno-builtin -fno-stack-protector
    
  • ABI:RV32E 使用 ilp32e ABI (16 个寄存器, 简化调用约定)
  • 链接脚本scripts/linker.ld 定义内存布局 (text, data, bss, heap 各段地址)

关键技术点

  • 理解 RISC-V 调用约定 (a0-a7 参数, ra 返回地址, sp 栈指针)
  • ELF 文件格式解析与加载
  • 反汇编工具 (objdump) 使用

D3: AM 运行时环境

目标:实现硬件抽象层,使应用程序与具体硬件平台解耦

项目中对应的实现

Abstract-Machine (AM) 提供 5 层抽象 API:

              应用程序 (am-kernels: CoreMark, 贪吃蛇, NES模拟器...)
                      │
              ┌───────▼───────┐
              │ Abstract-Machine │  统一 API 接口
              │ (am.h)          │
              └───────┬───────┘
                      │
      ┌───────┬───────┼───────┬───────┬───────┐
      ▼       ▼       ▼       ▼       ▼       ▼
    NEMU    NPC   ysyxSoC   QEMU   Spike  Native
   (模拟器) (RTL)  (FPGA)  (虚拟机) (参考)  (Linux)

五层抽象 API (am/include/am.h):

层级 名称 API 说明
TRM 图灵机 heap, putch(), halt() 最基本的计算能力
IOE I/O 扩展 ioe_init(), ioe_read(), ioe_write() 设备抽象
CTE 上下文扩展 cte_init(), yield(), kcontext() 中断/异常/上下文切换
VME 虚拟内存 vme_init(), map(), protect() 页表/地址空间
MPE 多处理 mpe_init(), cpu_count() 多核支持

NPC 平台配置 (scripts/riscv32e-npc.mk):

COMMON_CFLAGS += -march=rv32e_zicsr -mabi=ilp32e
LDFLAGS       += -melf32lriscv
AM_SRCS += riscv/npc/libgcc/div.S       # 软件除法
           riscv/npc/libgcc/muldi3.S    # 软件乘法

klib 最小内核库:提供 memcpy, strlen, printf 等基本函数,不依赖操作系统。

关键技术点

  • 裸金属编程,无 OS 依赖
  • 同一份 CoreMark 代码可运行于模拟器/RTL/FPGA
  • 启动代码 (RISC-V 汇编) 完成栈初始化和跳转 main

D4: 用 RTL 实现迷你 RISC-V 处理器

目标:用 Verilog 实现最基本的 RISC-V 处理器核,能执行简单程序

项目中对应的实现

NPC (New Processor Core) 的初始版本,实现核心数据通路:

// npc/vsrc/top.v — 顶层模块
module top (
  input clock,
  input reset
);
  // 流水线各级互联信号
  wire [31:0] instr;     // IFU → IDU
  wire [31:0] pc;        // BRU → IFU
  wire [31:0] rs1, rs2;  // RegFile → EXU
  wire [31:0] imm;       // IDU → EXU
  wire [31:0] exu_res;   // EXU → LSU/WBU
  wire [31:0] lsu_res;   // LSU → WBU
  ...
endmodule

核心模块

模块 文件 功能
RegFile regfile.v 16 个通用寄存器 (RV32E)
ALU alu.v 算术逻辑运算
IDU idu/idu.v 指令译码,生成控制信号
EXU exu.v 执行运算
BRU bru.v 分支跳转决策

Verilator 仿真环境 (csrc/main.cpp):

// 主仿真循环
while (!contextp->gotFinish()) {
    top->clock = !top->clock;
    step_and_dump_wave();  // eval + 时间推进 + VCD 记录
}

关键技术点

  • Verilog RTL 设计基础
  • Verilator 将 Verilog 编译为 C++ 进行仿真
  • DPI-C 接口打通 Verilog 与 C++ 的数据交互

D5: 设备和输入输出

目标:实现 I/O 设备模拟和硬件外设接口

项目中对应的实现

NEMU 中的设备模拟 (nemu/src/device/):

设备 文件 接口类型 功能
串口 serial.c MMIO 字符输出
定时器 timer.c MMIO 系统时钟
键盘 keyboard.c MMIO 扫描码输入
VGA vga.c MMIO 帧缓冲显示
音频 audio.c MMIO 音频 DMA

NPC 中的硬件外设 (npc/vsrc/peripheral/):

模块 接口 功能
axi_lite_uart.v AXI-Lite 串口输出
axi_lite_clint.v AXI-Lite 机器定时器 (mtime/mtimecmp)

关键技术点

  • MMIO (Memory-Mapped I/O) 设备访问方式
  • 设备寄存器读写语义
  • 中断触发与处理流程

三、C 阶段 — 进阶阶段 (完善处理器 + 系统能力)

C 阶段的核心目标是将处理器从"能跑"提升到"能用",增加异常处理、调试基础设施,支持运行 RT-Thread 等实时操作系统。


C1: 工具和基础设施

目标:搭建完善的开发、调试、验证工具链

项目中对应的实现

差分测试框架 (DiffTest)

┌─────────────┐     每条指令提交后     ┌─────────────┐
│    NPC      │ ──────────────────── ▶ │    NEMU     │
│   (DUT)     │                        │   (.so)     │
│ Verilator仿真│                        │  参考模型    │
└──────┬──────┘                        └──────┬──────┘
       │                                      │
       ▼                                      ▼
  DUT 寄存器/PC/CSR                     REF 寄存器/PC/CSR
       │                                      │
       └─────────── 逐一对比 ─────────────────┘
                       │
               ┌───────┴───────┐
               │ 一致 → 继续   │
               │ 不一致 → 报错 + 波形│
               └───────────────┘

实现代码 (npc/csrc/):

// difftest.cpp 核心逻辑
bool difftest_check() {
    regfile ref = get_ref_regs();   // 从 NEMU .so 获取参考状态
    regfile dut = pack_dut_regfile(...);  // 从 RTL 获取 DUT 状态
    return checkregs(&ref, &dut);   // 逐寄存器对比
}

追踪系统 (Kconfig 可配)

Trace 启用方式 用途
ITRACE CONFIG_ITRACE=y 打印每条指令的 PC、机器码、反汇编
MTRACE CONFIG_MTRACE=y 监控指定地址范围的读写
FTRACE CONFIG_FTRACE=y 跟踪函数调用/返回
ETRACE CONFIG_ETRACE=y 记录异常触发
IRINGBUF CONFIG_IRINGBUF=y 环形缓冲,crash 时打印最近 N 条指令

波形调试

make run WAVE=1           # 生成 VCD 波形
make wave                 # GTKWave 打开波形查看

关键技术点

  • DPI-C 接口设计 (Verilog 导出信号 → C++ 读取)
  • 共享库动态加载 (dlopen/dlsym 加载 NEMU .so)
  • 条件编译的宏技巧 (IFDEF(DIFFTEST_ON, ...))

C2: 支持 RV32E 的单周期 NPC

目标:完成完整的单周期处理器,通过所有 CPU 测试

项目中对应的实现

单周期意味着每条指令在一个时钟周期内完成取指→译码→执行→访存→写回。

处理器数据通路

         ┌──────────────────────────────────────────────────┐
         │                   一个时钟周期                     │
         │                                                   │
  PC ──▶ IFU(取指) ──▶ IDU(译码) ──▶ EXU(执行) ──▶ WBU(写回) │
         │     │                         │                   │
         │     └── Memory ◀──────── LSU(访存) ──┘            │
         │                                                   │
         └──── BRU(分支) ◀─── zero flag ─────────────────────┘

指令译码 (vsrc/idu/):

  • idu_normal.v — 处理算术、逻辑、访存、跳转指令
  • idu_system.v — 处理 CSR、ecall、mret、fence.i 等系统指令
  • idu.v — 顶层译码器,合并两部分输出

寄存器堆 (vsrc/regfile.v):

  • 16 个 32-bit 通用寄存器 (RV32E 规范)
  • 双读端口 + 单写端口
  • 零号寄存器硬连线为 0

关键技术点

  • 组合逻辑实现所有指令的执行
  • 控制信号 (exu_opt, lsu_opt) 驱动数据通路选择
  • am-kernels/tests/cpu-tests 作为正确性回归测试

C3: 调试技巧

目标:掌握硬件调试方法论,能高效定位和修复 RTL bug

项目中对应的实现

多层次调试手段

层级 方法 工具
行为级 NEMU 单步调试 sdb (内置调试器)
RTL 级 波形分析 GTKWave + VCD
接口级 DiffTest 对比 NEMU .so + DPI-C
统计级 性能计数器 内置 PFC

错误定位流程

  1. DiffTest 发现寄存器不一致 → 打印出错的指令 PC
  2. ITRACE/IRINGBUF 查看出错前的指令序列
  3. GTKWave 查看对应时刻的信号波形
  4. 定位是译码错误、执行错误还是访存错误

C4: ELF 文件和链接

目标:理解可执行文件格式、符号解析、链接过程

项目中对应的实现

链接脚本 (abstract-machine/scripts/linker.ld):

  • 定义 .text (代码段) 起始地址 = 0x80000000
  • 定义 .data, .bss, _heap_start 等段布局
  • 导出 _start 符号作为入口点

ELF 加载流程

  1. 交叉编译生成 ELF → objcopy 转为纯二进制 (.bin)
  2. 仿真时通过命令行 --img xxx.bin 加载到模拟内存
  3. PC 初始化指向 INST_START (0x80000000)

FTRACE (函数追踪) 利用 ELF 符号表实现函数调用/返回的追踪。


C5: 异常处理和 RT-Thread

目标:实现 RISC-V 特权级架构,支持运行实时操作系统

项目中对应的实现

CSR 寄存器 (vsrc/csrfile.v):

CSR 地址 功能
mtvec 0x305 异常入口地址
mepc 0x341 异常返回地址
mcause 0x342 异常原因码
mstatus 0x300 机器状态 (MIE/MPIE)

异常处理单元 IRU (vsrc/iru.v):

ecall 触发:
  1. mepc ← 当前 PC
  2. mcause ← 异常原因 (environment call from M-mode = 11)
  3. mstatus.MPIE ← mstatus.MIE; mstatus.MIE ← 0
  4. PC ← mtvec

mret 返回:
  1. PC ← mepc
  2. mstatus.MIE ← mstatus.MPIE

CTE (Context Extension) 在 AM 中的实现

  • cte_init() — 注册异常处理函数,设置 mtvec
  • yield() — 触发 ecall,用于上下文切换
  • kcontext() — 创建内核线程上下文

关键技术点

  • RISC-V Machine-mode 特权级
  • 异常向量表 (mtvec) 机制
  • 支持 RT-Thread yield/调度

四、B 阶段 — 高级阶段 (总线 + SoC + 流水线 + 优化)

B 阶段的核心目标是将处理器从"教学级"提升到"工程级",实现总线互联、SoC 集成、流水线、缓存等高级特性,最终具备流片能力。


B1: 总线

目标:实现标准 AXI4 总线协议,支持多 Master/多 Slave 互联

项目中对应的实现

AXI4 总线子系统 (npc/vsrc/amba/):

  ┌─────┐     ┌─────┐
  │ IFU │     │ LSU │       ← 2 个 AXI Master
  │(取指)│     │(访存)│
  └──┬──┘     └──┬──┘
     │            │
     ▼            ▼
  ┌──────────────────────────────┐
  │       AXI Interconnect        │  (arbiter + demux)
  │  axi_demux.sv + arbiter.v    │
  └──┬────────┬────────┬────────┘
     │        │        │
     ▼        ▼        ▼
  ┌─────┐ ┌──────┐ ┌──────┐ ┌──────┐
  │SRAM │ │ICache│ │CLINT │ │ UART │    ← 多个 AXI Slave
  └─────┘ └──────┘ └──────┘ └──────┘

关键模块

模块 文件 功能
AXI Demux axi_demux.sv 根据地址将请求分发到不同 Slave
Arbiter arbiter.v Round-Robin 仲裁多个 Master 请求
AXI Interconnect axi_interconnect.v 完整互联 (N×M 交叉开关)
AXI→AXI-Lite 桥 axi_axil_adapter.v 协议降级转换
Access Fault axi_access_fault.v 总线异常检测
AXI Interface axi_intf.sv SystemVerilog interface 定义

AXI4 协议五通道

  • AW (Write Address) — 写地址通道
  • W (Write Data) — 写数据通道
  • B (Write Response) — 写响应通道
  • AR (Read Address) — 读地址通道
  • R (Read Data) — 读数据通道

地址解码 (vsrc/libs/addr_decode.sv):

// 内存映射规则
localparam rule_t [NoRules-1:0] addr_map = '{
  '{idx: 1, start_addr: 32'h30000000, end_addr: 32'h40000000},  // Flash
  '{idx: 0, start_addr: 32'ha0000000, end_addr: 32'hc0000000},  // SDRAM
  '{idx: 1, start_addr: 32'h0f000000, end_addr: 32'h10000000}   // SRAM
};

关键技术点

  • AXI4 握手协议 (valid/ready 对)
  • 突发传输 (burst) 支持
  • 写地址/写数据解耦
  • 乱序完成 (通过 AXI ID)

B2: SoC 计算机系统

目标:将处理器核集成到完整的 SoC 中,对接真实外设

项目中对应的实现

项目支持两种 SoC 模式:

模式 1:独立仿真 (ARCH=riscv32e-npc)

CPU Core ←→ AXI Bus ←→ DPI-C 内存模型 (C++ 主机内存)

模式 2:ysyxSoC 集成 (ARCH=riscv32e-ysyxsoc)

┌──────────────────────────────────────────────────────┐
│                    ysyxSoC                            │
│                                                      │
│  ┌────────┐    ┌──────────┐    ┌─────────────────┐  │
│  │ NPC    │←──▶│ AXI Bus  │←──▶│ Flash           │  │
│  │ CPU    │    │          │    │ PSRAM           │  │
│  │ Core   │    │          │    │ UART16550       │  │
│  └────────┘    │          │    │ SPI             │  │
│                └──────────┘    │ GPIO            │  │
│                                └─────────────────┘  │
└──────────────────────────────────────────────────────┘

内存映射

地址范围 外设 大小
0x20000000 – 0x20000FFF MROM 4 KB
0x0F000000 – 0x0FFFFFFF SRAM 16 MB
0x30000000 – 0x3FFFFFFF Flash 256 MB
0x80000000 – 0x9FFFFFFF PSRAM/主内存 512 MB

SoC 对接要求

  • 顶层模块暴露标准 AXI4 Master 接口 (io_master_aw*, io_master_w*, io_master_b*, io_master_ar*, io_master_r*)
  • 支持条件编译 ifdef YSYXSOC 切换 SoC/独立模式
  • NVBoard 虚拟 FPGA 验证板

关键技术点

  • 处理器核对外接口标准化 (AXI Master)
  • 多模式兼容 (仿真 vs FPGA)
  • 启动地址配置 (Flash: 0x30000000 vs RAM: 0x80000000)

B3: 时序分析和优化

目标:确保设计满足时序约束,能在目标频率下正确工作

项目中对应的实现

Yosys 逻辑综合 + STA (Makefile syn 目标):

make syn   # 调用 yosys-sta 进行综合
# 目标频率: 100 MHz
# SDC 约束文件: npc/top.sdc

优化手段

  • Valid/Ready 握手协议允许各级独立阻塞,不需要全局 stall
  • Spill Register (libs/spill_register.sv) 用于切断关键路径
  • AXI Demux 的 SPILL_AW/SPILL_AR 选项插入流水寄存器

关键技术点

  • 静态时序分析 (STA) 概念
  • 关键路径识别与优化
  • 面积/时序/功耗 trade-off

B4: 性能优化和简易缓存

目标:通过缓存和微架构优化提升处理器性能

项目中对应的实现

指令缓存 ICache (vsrc/peripheral/axi_icache.v):

  • AXI4 接口 (上游连接 IFU,下游连接主存)
  • 支持 fence.i 指令触发缓存无效化
  • Cache 命中时单周期返回指令

性能计数器 (csrc/main.cpp):

// 仿真时统计的性能指标
printf("CPU IPC: %f\n", total_inst / (time / 2.0));           // 每周期指令数
printf("CPU CPI: %f\n", (time / 2.0) / total_inst);          // 每指令周期数
printf("ICACHE Hit Rate: %f\n", cache_hit_rate);              // 缓存命中率
printf("ICACHE AMAT: %f\n", acc_time + (1-hit_rate)*miss_penalty);  // 平均访存时间
printf("IDU Cal CPI: %f\n", inst_time[0] / idu_cal_type);    // 计算指令 CPI
printf("IDU Mem CPI: %f\n", inst_time[1] / idu_mem_type);    // 访存指令 CPI
printf("IDU Jump CPI: %f\n", inst_time[2] / idu_jump_type);  // 跳转指令 CPI

性能统计分类

指标 含义
IPC Instructions Per Cycle
CPI Cycles Per Instruction
Cache Hit Rate 缓存命中比例
AMAT Average Memory Access Time
TMT True Miss Penalty Time
Per-type CPI 按指令类型 (计算/访存/跳转/CSR) 分别统计

关键技术点

  • Cache 组织结构 (直接映射/组相联)
  • Cache 一致性 (fence.i)
  • Amdahl 定律指导优化方向

B5: 流水线处理器

目标:将单周期处理器改造为流水线设计,提升主频和吞吐量

项目中对应的实现

流水线架构 (Valid/Ready 握手):

  ┌─────┐  valid/ready  ┌─────┐  valid/ready  ┌─────┐  valid/ready  ┌─────┐  valid/ready  ┌─────┐
  │ IFU │ ────────────▶ │ IDU │ ────────────▶ │ EXU │ ────────────▶ │ LSU │ ────────────▶ │ WBU │
  │     │ ◀──────────── │     │ ◀──────────── │     │ ◀──────────── │     │ ◀──────────── │     │
  └─────┘               └─────┘               └─────┘               └─────┘               └─────┘
    ifu_valid             idu_valid             exu_valid             lsu_valid
    idu_ready             exu_ready             lsu_ready             wbu_ready

握手信号 (vsrc/top.v):

// 流水线级间握手
wire ifu_valid, idu_ready;   // IFU → IDU
wire idu_valid, exu_ready;   // IDU → EXU
wire exu_valid, lsu_ready;   // EXU → LSU
wire lsu_valid, wbu_ready;   // LSU → WBU

流水线特点

  • 弹性流水线:每级可独立阻塞 (如 ICache Miss 时 IFU 阻塞不影响后级已有数据的处理)
  • 无 stall 信号:用 valid/ready 对代替全局 stall,更灵活
  • 数据前递隐式:单发射顺序执行,WBU 写回后下一条才读取

与总线的交互

  • IFU 通过 AXI Master 读取指令 (可能多周期等待)
  • LSU 通过 AXI Master 读写数据 (可能多周期等待)
  • 非访存指令在 LSU 阶段直通 (lsu_opt 为 NOP)

关键技术点

  • 流水线冒险 (数据冒险、控制冒险) 处理
  • 分支预测/延迟槽 (当前设计为等待分支决议后更新 PC)
  • 流水线刷新 (fence.i / ecall / mret)

五、验证 & 测试生态

5.1 测试程序集 (am-kernels)

类别 路径 说明
CPU 测试 am-kernels/tests/cpu-tests/ 每条指令的正确性验证
AM 测试 am-kernels/tests/am-tests/ 抽象层 API 功能测试
ALU 测试 am-kernels/tests/alu-tests/ 运算单元专项测试
CoreMark am-kernels/benchmarks/coremark/ 工业标准性能基准
Dhrystone am-kernels/benchmarks/dhrystone/ 经典整数性能基准
MicroBench am-kernels/benchmarks/microbench/ 微基准测试

5.2 演示应用

程序 说明 验证的能力
hello 最简输出 TRM 基本功能
snake 贪吃蛇 IOE 键盘 + VGA
typing-game 打字游戏 IOE 定时器 + 键盘
litenes NES 模拟器 复杂计算 + 图形
bad-apple 视频播放 大量内存访问
thread-os 线程 OS CTE 上下文切换

5.3 形式验证

npc/formal/
├── CacheTest.sv      # ICache 属性断言
├── Sub.sv            # 子模块属性断言
└── axi_ram.v         # AXI RAM 模型 (用于形式验证环境)

六、构建命令速查

# === NEMU ===
cd nemu
make menuconfig          # 配置编译选项
make                     # 编译 NEMU
make run                 # 运行 NEMU

# === NPC ===
cd npc
make                     # 编译 NPC (Verilator)
make run                 # 运行仿真
make run DIFFTEST=1      # 启用差分测试
make run WAVE=1          # 记录波形
make run MAXCYCLE=100000 # 限制仿真周期
make wave                # GTKWave 打开波形
make syn                 # Yosys 逻辑综合 + STA

# === AM-Kernels (以 cpu-tests 为例) ===
cd am-kernels/tests/cpu-tests
make ARCH=riscv32e-npc run   # 在 NPC 上运行 CPU 测试
make ARCH=riscv32-nemu run   # 在 NEMU 上运行 CPU 测试

七、简历描述 (按阶段组织)

综合版 (推荐)

一生一芯 — RISC-V 全栈处理器设计 | Verilog/SV, C/C++, RISC-V Assembly

  • 实现全系统指令集模拟器 NEMU,支持 RV32IM/RV64IM/x86/MIPS32,含 MMU、5 种外设模拟、多级调试追踪系统
  • 使用 Verilog/SystemVerilog 独立设计 RV32E 多级流水线处理器 (IFU-IDU-EXU-LSU-WBU),采用 Valid/Ready 弹性流水线架构
  • 设计完整 AXI4 片上总线系统 (Demux、Arbiter、AXI-Lite Bridge),实现 ICache 及 fence.i 一致性维护
  • 实现 RISC-V Machine-mode 特权级 (ecall/mret/CSR),支持运行 RT-Thread RTOS
  • 搭建基于 Verilator 的 SoC 仿真平台,实现 DPI-C 差分测试框架 (RTL vs NEMU 逐指令对比)
  • 使用 Yosys 完成逻辑综合 (100MHz 目标),通过性能计数器分析 IPC/CPI/Cache AMAT 指导优化
  • 设计 Abstract-Machine 硬件抽象层,成功运行 CoreMark/Dhrystone 基准测试及 NES 模拟器

突出 D 阶段 (偏系统软件)

  • 实现支持多 ISA 的全系统模拟器,采用 Kconfig 管理编译配置,含解释器引擎、设备模型、简易调试器
  • 设计 Abstract-Machine 五层硬件抽象 (TRM/IOE/CTE/VME/MPE),实现同一应用在模拟器/RTL/FPGA 间无缝迁移

突出 C 阶段 (偏验证调试)

  • 搭建差分测试框架,通过 DPI-C 接口实现 RTL 与软件参考模型的逐指令状态校验
  • 实现多层追踪系统 (ITRACE/MTRACE/FTRACE/IRINGBUF),支持高效硬件 bug 定位

突出 B 阶段 (偏芯片设计)

  • 设计完整 AXI4 总线互联 (多 Master 仲裁、地址解码、协议桥接),支持 SoC 集成
  • 实现 ICache 并通过 fence.i 维护一致性,优化后 CPI 显著降低
  • 完成 Yosys 逻辑综合与 STA,达到 100MHz 时序收敛

八、面试技术要点

处理器设计

问题 要点
为什么用 RV32E? 16 寄存器,面积小,复杂度低,适合教学迭代
Valid/Ready vs 全局 Stall? 弹性流水线,各级独立阻塞,天然支持不等延迟
AXI4 为什么分五通道? 读写解耦、突发传输、乱序完成、工业标准
ICache fence.i 怎么做? 收到 fence.i 时无效化所有 cache line
差分测试的局限? 需要参考模型,时序行为无法覆盖,仅验证功能正确性

系统软件

问题 要点
NEMU 如何支持多 ISA? 分层设计,ISA 相关代码隔离在 src/isa/ 目录
AM 如何实现平台无关? 编译时选择 $ARCH,链接不同的平台实现代码
ecall 的完整流程? mepc←PC, mcause←原因, mstatus 保存中断状态, PC←mtvec

验证方法

问题 要点
DiffTest 如何同步? 每条指令提交 (commit) 后对比,确保一一对应
波形调试 vs printf? 波形可看并行信号时序关系,printf 只能看串行事件
形式验证 vs 仿真? 仿真覆盖常见路径,形式验证穷举状态空间,互补

参考来源:一生一芯官网 | OSCPU GitHub | 项目源码分析

文档生成时间:2026 年 6 月

posted @ 2026-06-05 15:02  mo686  阅读(28)  评论(0)    收藏  举报