ysyxSoC

内容涵盖了 SoC 集成、AM 运行时环境移植、链接脚本精髓、启动加载器实现以及 UART 驱动开发的完整链路。


ysyxSoC 核心开发链路小结

一、SoC 集成与总线架构 (Diplomacy)

  • 核心工具:基于 Rocket-Chip 的 Diplomacy 框架,以 Chisel 语言实现。
  • 优势:将设备接入 AXI Xbar 从传统 Verilog 的数百行端口声明,简化为仅需 2 行 Chisel 代码LazyModule + .node 连接)。
  • 关键地址映射
    • MROM0x2000_0000 ~ 0x2000_0fff(4KB,只读,存放启动代码)。
    • SRAM0x0f00_0000 ~ 0x0f00_1fff(8KB,可读写,存放堆、栈、全局变量)。虽预留 16MB 地址空间,但物理仅实现 8KB,访问空洞会触发 Access Fault。

二、AM (抽象机) 运行时环境移植

riscv32e-ysyxsoc 构建 AM 后端,核心在于 TRM (图灵机) 的实现:

API 实现方案
putch(ch) 轮询 UART16550 的 LSR 寄存器,等待发送队列空闲后写入 THR 寄存器。
halt(code) 内嵌 ebreak 指令,让仿真环境捕获并退出。
heap_start/end 返回 SRAM 中堆区的边界地址。

三、链接脚本精髓:VMA 与 LMA 的分离

为了支持全局变量写入(MROM 只读,SRAM 可写),必须利用链接器的 VMA(运行地址)LMA(加载地址) 机制。

核心语法

.data : {
    _sdata = .;          /* VMA (SRAM) */
    *(.data)
    _edata = .;
} > SRAM AT> MROM       /* VMA 在 SRAM,LMA 紧跟 MROM 代码之后 */

_sdata_lma = LOADADDR(.data);  /* 导出 LMA 供启动代码使用 */

Bootloader 任务(start.S 中执行)

  1. 清空 .bss 段(确保未初始化全局变量为 0)。
  2. _sdata_lma(MROM 源)拷贝 .data 段到 _sdata(SRAM 目标)。
  3. 设置栈指针 sp = _stack_top(SRAM 末端)。
  4. 跳转 main()

四、UART16550 串口驱动(解决“16字符”魔咒)

现象:未初始化时,无论字符串多长,终端最多只显示 16 个字符(对应 FIFO 深度)。

1. 串口初始化 (uart_init)

  • 设置波特率除数Divisor = UART_CLK / (16 * BaudRate)
  • 配置线路参数:设置为 8N1(8 位数据、无校验、1 位停止位)。
  • 启用 FIFO:清空收发 FIFO,设置触发阈值。

2. 带流控的 putch

轮询 LSR (线路状态寄存器)THRE (Bit 5) 位,确保发送保持寄存器(FIFO)有空位再写入,实现软硬件速度匹配,彻底杜绝丢字符。

void putch(char ch) {
    while (((*(volatile uint8_t *)UART_LSR) & LSR_THRE) == 0);
    *(volatile uint8_t *)UART_THR = ch;
}

五、验证与调试工具链

测试程序 验证目标
dummy 验证最小系统取指与 ebreak 停机。
mem-test 验证 8/16/32 位访存、字节选通 (WSTRB) 及小端序正确性。
hello 验证串口输出与 FIFO 流控机制。
fib / microbench 验证栈帧、函数调用及全局变量读写。

DiffTest 重新同步

  • NEMU 需新增 mromsram 物理内存数组。
  • 仿真启动时调用 difftest_memcpy 将 MROM 镜像同步至 NEMU。
  • SRAM 无需手动同步:因 DiffTest 逐指令执行,写操作(sb/sh/sw)会自动同步两边状态。

Access Fault 异常(建议实现)

捕获 AXI 返回的 SLVERR / DECERR(如访问 SRAM 空洞),强制 PC 跳转至复位地址(0x20000000),防止“静默死机”,便于调试。


六、编译与链接优化

  • 死代码消除:利用 -ffunction-sections + --gc-sections,未被调用的函数(如未使用的 printf)不会占用宝贵的 MROM 空间。
  • 查看内存布局:使用 --print-map 选项确认 .data 的 VMA 与 LMA 是否分离正确。

总结

当前 ysyxSoC 已具备一个完整最小系统所需的所有要素:

  1. 存储:MROM (代码) + SRAM (数据)。
  2. 启动:Bootloader 自动搬运数据段。
  3. 输出:基于中断/轮询的 UART 驱动(支持 8N1 任意波特率)。
  4. 调试:DiffTest + Access Fault 异常 + Verilator 波形追踪。

下一步可考虑引入更大容量的 PSRAM 或 XIP Flash,以运行更复杂的程序(如操作系统引导)。

posted @ 2026-07-13 16:56  mo686  阅读(10)  评论(0)    收藏  举报