跳到主要内容

E603 First Glance

从 E203 到 E603

通过阅读 E203 Docs ,了解 SoC 的基本结构,框架,并结合具体代码进行分析,从而对阅读 E603 源码的过程提供参考。

E203 Docs 以及 E203 概览

E203 Docs 主要分为三部分,分别介绍 E203 CoreSoC Peripherals具体的仿真和工具链使用

本文档不涉及仿真和工具链使用的部分。

下图为 E203 的系统结构图。

术语解释

  • DTCM: Data Tightly Coupled Memory 数据紧密耦合存储器,一种集成在 CPU 里的高速缓存。
  • ITCM 与之相对应,是存储指令的缓存。
  • PLIC:Platform-Level Interrupt Controller,平台级中断控制器,管理外部中断。
  • CLINT:Core Local Interrupter ,核内中断控制器。
  • QSPI-FLASH:快速串行接口内存,常用于嵌入式系统
  • JTAG:用于硬件调试和测试的接口
  • 与外设总线有关的
    • ALWAYS-ON:在系统低功耗模式下仍然要保持运行
    • HCLKGEN:时钟发生器,生成提供系统时钟信号
    • GPIOA/GPIOB:通用输入输出端口
    • UART:异步收发传输器,实现串行通信,与其他设备进行数据交换
    • PWM:脉宽调制器,生成特定频率和占空比的脉冲信号
    • SPIO:四项串行外设接口,用于与外部存储器或其他SPI设备进行高速数据传输,Q指四线模式,可以提供更高的数据传输速率
    • I2CI^2C :两线制的串行通信协议,链接低速设备,传感器,EEPROM等
    • RTC:实时时钟,在系统低功耗模式下保持实践的运行
    • WatchDog:用于系统监控的定时器,防止系统长时间处于错误状态
    • PMU:电源管理单元,负责管理系统的电源分配,包括电源的开启,关闭和模式转换
    • LCLKGEN:低频时钟发生器。

E603 Docs 及 E603 概览

E603 Docs 包括数据手册:Nuclei_E603_Databook.pdf(有关 E603 硬件结构和特性),Nuclei_E603_ISA_Spec.pdf (有关 E603 支持哪些指令)和 Nuclei_E603_Integration_Guide.pdf (有关 E603 如何进行集成(嵌入其他的 SoC))等。


在集成手册中有对 GitHub 库中代码的描述。

!Nuclei_E603_Integration_Guide.pdf

以及 E603 的架构图如下

!Nuclei_E603_Databook.pdf

E603 源码阅读

根据手册的提示,可以在 E603 的 GitHub 仓库 中阅读对应的源码。要进行解码工作,首先要解耦 SoC 的各个模块,从而达到对其每个模块,以及模块内功能的深入认识。

由 E203 的代码结构我们知道,一个SoC可以解耦成两部分,一部分是 Core 本身,另一部分是 SoC 的外设。

SoC 顶层文件解读

e603_hbird/design/soc/soc_top.v 是 SoC 的顶层文件,定义了多个输入输出接口。这部分源码涉及了 E603 SoC 与一些外设的交互,外设具体如下:

  • DDR3/DDR4 内存控制器,分别受 DDR3_CONTROLLER/DDR4_CONTROLLER 宏控制
  • 以太网接口(GMII/XMII/MDIO/MDC)
  • NEX(Nuclei Extension)接口
  • QSPI Flash 接口(QSPI0/QSPI1/QSPI2)
  • UART 接口(UART0)
  • JTAG 调试接口
备注

有一些既可以输入也可以输出的管脚(如ddr的双向总线)会被声明为 inout

除此之外,还有一些系统控制相关的输入和输出信号,包括:

  • 输入信号:
    • por_rst_n(上电复位)
    • sys_rst_n(系统复位)
    • sys_clk(系统时钟)
    • sys_clk_fast(高速系统时钟,受 FPGA_SOURCE 宏控制)
    • aon_clk(Always-On时钟)
    • evt_i(事件输入)
    • nmi_i(非屏蔽中断)
    • stop_on_reset(调试/控制相关)
  • 输出信号
    • core_wfi_mode(CPU等待中断模式指示)
    • core_sleep_value(CPU休眠状态指示)

在这个文件中实例化了 e603_subsys_top 这一子模块。阅读实例化这一模块的部分时,我认为这里有以下两点需要注意:

  • 其中定义了 TEMAC_CONTROLLER 宏来控制是否编译以太网 MAC 相关的接口
  • 其中 QSPI Flash 的部分有一些使能管脚没有进行配置,且这些使能管脚并不对称,需要观察子模块的结构来寻找这些管脚的具体位置。

下面来关注 e603_subsys_top 模块自身。这个模块之中就有一些与SoC自身功能相关的模块了。 首先需要关注的是 sysrstreq 这个信号。在这部分中,它经过一个触发器输出 sysrstreq_r ,这个信号与下面 test_mode 以及主模块的 sys_rst_n 的设置有关。而 sys_rst_n 这个信号则是该模块给下一级核心模块也即 e603_subsys_main 系统的系统复位信号。在关注它之前,首先要对这部分代码涉及的一些信号做一些解释:

  • por_rst_n 上电复位信号,芯片上电时,所有逻辑被强制复位到初始状态,确保启动一致。它由芯片外部电路产生,仅仅在芯片干通电时有效,同时是低有效信号(因为用了 n
  • sysrstreq 外界给这个模块的复位请求信号,其实应该是整颗SoC与外界的接口传进来的信号。而 sysrstreq_r 则是该信号经触发器传回的信号。
  • byp_sys_rst_n 一个很单纯的中间信号 下面可以结合代码对这部分做解释了:
wire byp_sys_rst_n = test_mode ? 1'b1 : (sys_rst_n & (~sysrstreq_r));//根据系统是否是test_mode来确定是否复位。如果在test_mode,则永远不复位;否则就是当sys_rst_n不复位且没有外部请求时,系统不复位
wire final_sys_rst_n_a = por_rst_n & byp_sys_rst_n;//把上电复位信号也考虑在内
wire final_sys_rst_n;
e603_reset_sync u_reset_sync(
.clk (sys_clk),
.rst_n_a (final_sys_rst_n_a),
.reset_bypass(test_mode),
.rst_n_sync(final_sys_rst_n)
);//再次同步

除此之外, e603_subsys_top 还定义了一个 mtime_toggle_a 信号,每隔一个 aon_clk 周期翻转一次。 这里可以引入 Databook 中对 E603 时钟域的讨论,如下所示,这里介绍了 aon_clk 这个信号。

Nuclei_E603_Databook.pdf

除此之外还针对使用Verilator的情况进行了定义,具体而言,是定义了 reset_vector ,如果用Verilator,则定义为 reg 可以根据情况赋值。如果不用 Verilator 跑仿真,则直接写死为 32'h20000000 ,这应该与riscv-tests的预定义有关。

那么下面就进入到对 e603_subsys_main 的分析了。