E603 First Glance
从 E203 到 E603
通过阅读 E203 Docs ,了解 SoC 的基本结构,框架,并结合具体代码进行分析,从而对阅读 E603 源码的过程提供参考。
E203 Docs 以及 E203 概览
E203 Docs 主要分为三部分,分别介绍 E203 Core ,SoC 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指四线模式,可以提供更高的数据传输速率
- :两线制的串行通信协议,链接低速设备,传感器,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 的分析了。