修订历史

版本号 修订日期 修订的章节 修订的内容
1.0 2019/5/10 N/A 初始版本
2.0 2019/9/4 2 修改文件包层次结构
3.0 2019/12/20 2.1,2.12 添加逻辑综合目录和步骤
4.0 2019/1/10 N/A 修订了若干笔误,重塑了文档章节结构
5.0 2021/09/14 3.2 评估板更新为Nuclei MCU200T

1. 交付文件介绍

1.1. 交付文件压缩包

N100交付的文件内容为一个文件压缩包,简介如表 1‑1所示。

表 1‑1 交付文件压缩包介绍

文件包 内容简介 详细内容
n100_rls_pkg.tar.gz 包含交付Verilog RTL加密源代码,代码配置与生成工具、配套Testbench、配套SoC原型、仿真环境与FPGA原型的源码文件压缩包。 详细内容介绍请参见本文档后续章节。

Nuclei N100系列交付的文件正式版可通过与芯来公司取得联系授权获得。用户可以在芯来科技官网免费获取评估版。用户在得到压缩包后,可使用如下命令在Linux系统中进行解压,生成n100_rls_pkg文件夹:

tar –xzvf n100_rls_pkg.tar.gz

下文将介绍Nuclei N100系列交付的n100_rls_pkg文件压缩包的详细内容。

1.2. 文件包层次结构

n100_rls_pkg文件包的文件层次结构如下所示。


n100_rls_pkg
    |n100                   // 存放 配置与生成工具 以及RTL的目录
        |----design             // N100核和配套SoC原型的RTL目录
            |----core           // 存放N100 Core的 加密RTL代码
            |----fab            // 存放配套SoC总线bus fabric的RTL代码
            |----subsys         // 存放配套SoC子系统文件的RTL代码
            |----mems           // 存放配套SoC的memory模块的RTL代码
            |----perips         // 存放配套SoC外设peripherals模块的RTL代码 
            |----soc            //存放配套SoC顶层文件的RTL代码
        |----configs              // 配置与生成工具
            |----core_gen       // core_gen工具, 实现配置以及代码生成,
                                //  见第4章,了解该工具的使用
            |----env.sh         // bash环境变量设置脚本
            |----env.csh        // csh环境变量设置脚本
            |----private.pem    // 解密所用私钥(正式版需联系芯来科技,单独提供)      
            |----check.txt      // 环境检查文件
            |----libc.so.6      // 库依赖文件
            |----rtl.vf         // Core的Verilog RTL file list
|n100_cct
        |----riscv-tests    // 存放一些测试用例的目录
        |----tb                 // 存放Verilog TestBench (测试平台)的目录
        |----vsim                 // 运行Verilog仿真的目录
                                参见第5章了解如何进行Verilog仿真。       
            |----bin                // 存放脚本的文件夹子    
            |----Makefile           // 运行的Makefile
            |----run                // 运行目录
        |----fpga                   // 存放FPGA项目和脚本的目录
                                    参见第3.2节了解如何进行FPGA构建整个SoC原型。
        |----syn                    //存放综合脚本的目录。


注意:

  • 以上N100只是代称,针对具体的发布型号,会换成对应core的名字,如N101。

1.3. Core源代码的命名规则

N100系列不同型号的Core的源代码文件名前缀不一样,譬如N101内核的文件名和模块名的前缀均为“n101_”,其他型号的核前缀同理。

1.4. Core的模块层次结构

以N101处理器内核为例,其模块层次的划分如图 1‑1所示,要点如下。

  • n101_core_wrapper为整个处理器内核的顶层,包含如下主要组件

    • n101_core:为处理器内核的总体部分。

    • n101_rst_ctrl:用于将外界的异步复位信号进行同步使之变成“异步置位同步释放”的复位信号。

    • n101_dbg_top:处理JTAG接口和相关的调试功能。

  • n101_ucore位于n101_core层次之下,为处理器内核的主体逻辑部分。

  • 除了n101_ucore之外,在n101_core层次结构之下还包含了如下主要组件:

    • n101_clk_ctrl:用于控制处理器各个主要组件的自动时钟门控。

    • n101_clic_top:内核私有的中断控制单元。

    • n101_tmr_top:内核计时器单元。

图 1‑1 N101处理器内核的设计模块结构

2. CPU顶层集成

本节对N100系列处理器内核集成至SoC中需要注意的若干方面进行简要介绍。

2.1. 时钟关系

有关N100系列处理器内核的时钟关系,请参见《Nuclei_N100系列简明数据手册》中的“N100系列时钟域介绍”章节。

2.2. 接口关系

有关N100系列处理器内核的接口描述,请参见《Nuclei_N100系列简明数据手册》中的“N100系列接口简介”章节。

2.3. 地址映射

有关N100系列处理器内核的存储器地址映射分配,请参见《Nuclei_N100系列简明数据手册》中的“N100系列地址空间分配”章节。

3. 配套SoC原型与软件开发环境

3.1. 配套SoC原型

如果仅仅交付处理器内核而没有配套SoC,那么为了能够使用该内核,用户需要花费不少精力来构建完整的SoC平台、FPGA平台。为了方便用户快速地上手使用,N100系列内核配套了完整的简单SoC原型,如图 3‑1所示(以N101内核为例)。基于此SoC原型,可以快速实现完整的SoC原型软硬件平台,有关此配套SoC的详细介绍请参见单独文档《Nuclei_N100系列配套SoC介绍》。

图 3‑1 N100系列处理器内核(以N101为例)的配套SoC结构

3.2. 配套FPGA评估板和JTAG调试器

芯来科技定制了专用的FPGA评估板(Nuclei MCU200T)。上节描述的配套SoC原型(包含N100系列处理器内核)可以被整体实现在Nuclei MCU200T上成为SoC FPGA原型开发板。芯来科技还定制了专用的JTAG调试器(HBird Debugger Kit),用于在FPGA评估板上对N100系列进行调试。

有关芯来科技定制的专用JTAG调试器(HBird Debugger Kit)和专用FPGA评估板(Nuclei MCU200T)的详细介绍请参见参见单独文档《Nuclei_N100系列配套FPGA实现》。

3.3. 配套软件开发套件(SDK)

N100系列提供软件开发套件(SDK,Software Development Kit)。用户可以基于上述的SoC FPGA原型开发板,结合SDK,进行完整的嵌入式软件开发和调试,详细介绍请参见参见单独文档《Nuclei_N100系列SDK使用说明》。

注意:SDK使用Linux Makefile进行项目和文件的组织,适用于开发水平较高的用户。

3.4. 配套可视化软件集成开发环境(IDE)

N100系列提供图形化集成开发环境(IDE,Integrated Development Environment)。用户可以基于上述的SoC FPGA原型开发板,结合IDE,进行完整的嵌入式软件开发和调试,详细介绍请参见参见单独文档《Nuclei_N100系列IDE使用说明》。

注意:IDE使用可视化集成开发环境进行项目和文件的组织,适用于习惯图形化开发环境的用户。

4. 可配置代码的生成与编译

4.1. core_gen工具操作说明

为了方便客户,比较容易的配置N100系列core,芯来科技开发了core_gen工具,实现对core的配置以及代码的生成。

在 n100_rls_pkg/n100/configs 目录下,有如下文件:

  • core_gen:core_gen工具

  • private.pem:代码解密所需key(需联系芯来科技,单独提供)

  • check.txt:环境检查文件

  • env.sh:环境变量设置脚本

  • env.csh:csh环境变量设置脚本

  • libc.so.6:库依赖文件

注意:

  • private.pem,check.txt,libc.so.6文件请勿修改,以免代码无法正常生成

在执行core_gen工具之前,需要设置环境变量:

  • bash环境:source env.sh

  • csh环境:source env.csh

以上脚本(env.sh)会自动设置相应环境变量:

  • PROJ_SRC_ROOT: n100_rls_pkg所在目录

  • PROJ_NAME: 对应core的名字

  • PROJ_GEN_ROOT:RTL代码生成目录,默认在 n100_rls_pkg/n100_cct目录下,如果想将代码生成在其他目录,可以修改该环境变量。

设置完环境变量之后,直接执行 ./core_gen,启动代码配置与生成工具。启动之后,界面如下图所示。界面显示的配置选项,与《Nuclei_N100系列简明数据手册》文档中“N100系列内核配置参数选项”章节中的介绍一致。关于每个选项配置的说明,请参阅《Nuclei_N100系列简明数据手册》。

以下以n101 core为例,对该工具使用进行说明。

C:\Users\lzb\AppData\Local\Temp\1574328757(1).png

图 4‑1 core_gen启动配置界面

选项后的特殊字符解释如下:

  • 当选项后续有 --->,表示这个配置有子菜单,输入回车或者空格,进入到子菜单配置界面。

  • 进入到子菜单配置界面后,可输入方向键 “\<” ,回到上一层子菜单。

如进入 TIMER 子菜单,其配置界面如图 4‑2所示:

C:\Users\lzb\AppData\Local\Temp\1574328861(1).png

图 4‑2 TIMER配置子菜单

选项后的特殊字符解释如下:

  • [*] 表示该配置,是被选择,输入空格,取消选择。

  • [ ] 表示该配置,未被选择,输入空格,进行选择。

  • -*- 表示该配置,是固定配置,不可配。

  • () 中的内容,表示该选项的配置值。如果带有(NEW),表示此次配置是使用默认配置值,如果用户修改了配置值,则该(NEW)字符会消失。

对于一些选项,需要手动输入。如配置DEBUG基地址,如图 4‑3所示。在该配置选项上,输入回车或者空格,进入配置输入界面如图 4‑4所示。在配置输入界面,输入想要配置的地址值。输入回车,即配置成功。

C:\Users\lzb\AppData\Local\Temp\1574329090(1).png

图 4‑3 DEBUG基地址配置

C:\Users\lzb\AppData\Local\Temp\1574329409(1).png

图 4‑4 DEBUG基地址输入配置

对于某些选项,需要手动输入,但是输入的条件有限制。如配置外部中断个数,如图 4‑5所示,Range属性要求输入的值处于1-29范围之内。如果输入的值超过了要求的范围之内,会提示错误信息,如图 4‑6所示。

C:\Users\lzb\AppData\Local\Temp\1574329242(1).png

图 4‑5 中断数配置

C:\Users\lzb\AppData\Local\Temp\1574329291(1).png

图 4‑6 配置错误

配置完毕之后,输入 q,保存并退出。退出之后,core_gen工具,会自动进行代码生成,代码生成需要花费几分钟,请耐心等待。生成的代码将放置在\$PROJ_GEN_ROOT目录下。注意:

  • 代码配置生成完毕后,生成的代码将放置在\$PROJ_GEN_ROOT目录下,该目录里面包含了大量的RTL源代码,其中包含了处理器内核和配套SoC原型的所有可综合Verilog RTL源代码。如果仅仅需要内核相关的代码,则仅需关注core这个目录下的源代码。

配置完毕之后,会在当前目录下,生成 .config 文件。 当下次在配置的时候,会加载该.config,继承上一次的配置。如果删除掉该文件,那么使用默认配置。

4.2. 查看和编译Verilog RTL代码

假设用户想快速查看N100系列处理器核配置生成的源代码,可以使用如下步骤进行。注意:

  • 以下N100只是代称,正式版本发布的时候,可能换成对应core的名字,如N101。

// 注意:在操作之前,需要安装RISC-V GCC编译工具链。该工具链可以从我们的官网进行下载。下载地址为:https://www.nucleisys.com/download.php,用户可点击该网页中RISC-V GNU工具链下的下载按钮进行下载。下载完毕后,解压到Linux系统中,解压后可以看到生成的文件夹下有一个bin子文件夹,用户需要将此bin子文件夹的路径添加到PATH环境变量中。

// 步骤一:按照上节所述使用core_gen工具进行配置和代码生成。

    //首先将n100_rls_pkg解压至本机Linux环境中。然后配置并生成RTL代码,使用如下命令:

cd n100_rls_pkg/n100/configs
source env.sh
./core_gen

    // 执行 core_gen 之后,会弹出图形化界面,用户在图形化界面上,配置core的参数
    // 配置完毕后,按 q 退出并保存,之后开始进行代码生成
    // 代码生成需要花费几分钟,请耐心等待
    // 代码生成在 n100_rls_pkg/n100_cct/n100目录中


// 步骤二:编译RTL,使用如下命令:

cd n100_rls_pkg/n100_cct/vsim   
    // 进入到 n100_cct/vsim 目录下

make install    
    // 安装环境

make compile    
    // 编译RTL


// 步骤三:查看RTL代码,可使用如下两个命令:

make verilog
    // 该命令查看所有的Verilog源代码,会自动加载所有的Testbench和Verilog 源代码(例化了整个配套SoC原型,包含处理器内核)。

make verilog_core
    // 该命令仅查看Core的Verilog源代码,会自动加载 n100_cct/n100目录下的RTL。


5. 仿真运行简单汇编测试用例

5.1. 自测试用例简介

所谓自测试用例(Self-Check Testcase)是一种具备自我检测运行成功还是失败的测试程序,存放于以下目录。


n100_rls_pkg
    |----n100_cct               
        |----riscv-tests        
                |----isa_origs     // 存放一些测试用例源码的目录


这些测试程序均由汇编语言编写,里面用某些宏定义组织成程序点,测试指令集架构中定义的指令,如图 5‑1所示,测试add指令(源代码文件为isa/rv64ui/add.S),通过让add指令执行两个数据的相加(譬如0x00000003和0x00000007),设定它期望的结果(譬如0x0000000a)。然后使用比较指令加以判断,假设add指令的执行结果的确与期望的结果相等则程序继续执行,假设与期望的结果不相等则程序直接使用jump指令跳到TEST_FAIL地址。假设所有的测试点都通过了,则程序一直执行到TEST_PASS地址。

图 5‑1 riscv-tests测试用例add.S片段

在TEST_PASS的地址,程序将设置x3寄存器的值为1,而在TEST_FAIL的地址,程序将x3寄存器的值设置为非1值。因此最终可以通过判断x3的值来界定程序的运行结果到底是成功了还是失败了。

5.2. 自测试用例文件

riscv-tests中的这些指令集架构(ISA)测试用例都是使用汇编语言编写,为了在仿真阶段能够被处理器执行,需要将这些汇编程序编译成二进制代码。在n100_cct的以下目录(generated文件夹)下,已经预先上传了一组编译成的可执行文件和反汇编文件,以及能够被Verilog的readmemh函数读入的文件。



n100_cct        
        |----riscv-tests        // 存放一些测试用例的目录
            |----isa
                |----generated                  // 编译好的tests文件夹
                    |----rv32ui-p-addi          // 编译出的elf文件
                    |----rv32ui-p-addi.dump     // 反汇编文件 
                    |----rv32ui-p-addi.verilog  // 可被Verilog 的readmemh
                                            // 函数读入的文件
                    ……



反汇编文件(譬如rv32ui-p-addi.dump)的内容如图 5‑2所示。

图 5‑2 rv32ui-p-addi的反汇编文件内容片段

Verilog 的readmemh函数能够读入的文件(譬如rv32ui-p-addi.verilog)内容如图 5‑3所示。

图 5‑3 Verilog 的readmemh函数可读入文件内容片段

5.3. 测试平台简介

在n100_cct的如下目录已经创建了一个简单的由Verilog编写的TestBench测试平台。


n100_cct
    |----tb                 // 存放Verilog TestBench (测试平台)的目录
        |----tb_*.v             // 简单地Verilog TestBench文件

在测试平台中主要的功能如下:

  • 例化DUT文件,生成clock和reset信号。

  • 根据运行命令解析出测试用例的名称, 并使用Verilog的readmemh函数读入相应的文件(譬如rv32ui-p-addi.verilog)内容,然后使用文件中的内容初始化SoC的Instruction Memory(由Verilog编写的二维数组充当SRAM行为模型)。

  • 在运行结束后分析该测试用例是否执行成功,在Testbench的源文件中对x3寄存器的值进行判断,如果x3的值为1,则意味着通过,向终端上将打印PASS字样,否则将打印FAIL字样。如图 5‑4所示。

注意:用户在将N100系列集成在不同产品的SoC之中时,也可以将相关tb_*.v也集成在SoC中,以便于在SoC环境之中运行自测试用例。

图 5‑4 Testbench中打印测试用例的结果

5.4. 运行测试用例

假设用户想使用N100系列内核源代码运行基于Verilog的仿真测试程序,可以使用如下步骤进行。


// 注意:在运行测试用例之前,需要安装RISC-V GCC编译工具链。该工具链可以从我们的官网进行下载。下载地址为:https://www.nucleisys.com/download.php,用户可点击该网页中RISC-V GNU工具链下的下载按钮进行下载。下载完毕后,解压到Linux系统中,解压后可以看到生成的文件夹下有一个bin子文件夹,用户需要将此bin子文件夹的路径添加到PATH环境变量中。


// 步骤一:将n100_rls_pkg解压至本机Linux环境中。


// 步骤二:生成test:

cd n100_rls_pkg/n100_cct/vsim
        // 进入到n100_cct目录文件夹下面的vsim目录。

make clean
        // 清除当前目录,以保证干净的工作目录。

make install 
        // 运行该命令,会将n100_cct目录下的test进行编译,以及必要tb的生成。


// 步骤三:编译RTL:

make compile 
        // 编译所有的Verilog代码


// 步骤四:运行testcase(测试用例),使用如下命令:
make run_test TESTNAME=rv32ui-p-add
        // 注意:make run_test将执行
        // riscv-tests/isa/generated目录中的一个testcase “rv32ui-p-add”。
        // 如果希望运行所有的回归测试,请参见步骤四。

make wave TESTNAME=rv32ui-p-add
        //查看该test执行后的波形。


// 步骤五:运行回归(regression)测试集,使用如下命令:
make regress_run 
        // 注意:这使用riscv-tests/isa/generated
        // 目录中testcases,逐个的运行testcase。


// 步骤六:查看回归测试结果:
make regress_collect
        // 该命令将收集步骤四中运行的测试集的结果,将打印若干行的结果,每一行对应一个测
        // 试用例,如果那个测试用例运行通过,那一行则打印的PASS,如果运行失败,那一行则
        // 打印的FAIL。



注意:

  • 以上N100只是代称,真正发布的时候,会换成对应core的名字,如N101。

  • 以上的回归测试只是运行riscv-tests中提供的非常基本的自测试汇编程序,并不能达到充分验证处理器核的效果,因此如果用户修改了处理器的Verilog源代码而仅仅运行以上的回归测试将无法保证处理器的功能完备正确性。

6. 仿真运行复杂C测试用例

6.1. 运行C程序

假设用户想在仿真环境中运行C语言编写的程序,那么需要借助N100系列的SDK进行。有关SDK的详细介绍请参见《Nuclei_N100系列SDK使用说明》。

以SDK中的示例程序(Demo_irqc)为例,可以使用如下步骤进行。注意:下列步骤以N101为例,因此命令行中使用CORE=n101。


// 步骤一:进入n100-sdk目录。


// 步骤二:在n100-sdk目录下对用于仿真的示例程序进行编译,使用如下命令:

    make dasm PROGRAM=demo_irqc CORE=n101 DOWNLOAD=ilm SIMULATION=1


// 步骤三:进入n100_rls_pkg目录,将上述步骤生成的software/demo_irqc文件夹拷贝到n100_rls_pkg/n100_cct/vsim目录中,命令如下:

    cp n100-sdk/software/demo_irqc  n100_rls_pkg/n100_cct/vsim -rf


// 步骤四:在n100_cct的vsim目录下对测试程序进行仿真。

    cd n100_rls_pkg/n100_cct/vsim

    make run_test TESTCASE=$PWD/demo_irqc/demo_irqc
        //运行拷贝过来的demo_irqc示例程序


7. 逻辑综合

7.1. 逻辑综合Verilog代码

如果需要对N100系列进行逻辑综合,可以按照以下步骤进行,以N101为例:


// 步骤一:进入n101_cct/syn目录。


// 步骤二:在n101_cct/syn目录下修改Makefile脚本,主要包括工艺库路径,Design路径,频率等。


// 步骤三:综合脚本预处理 

    make install
        //将Makefile中的相关变量替换到综合脚本中。

// 步骤四:综合 

    make syn
        //最后的生成文件和报告文件在syn_<CORE>_config_<freq>_<lib>/reports下面。

上述综合仅仅给出最简单的综合参考环境。同时,如果要进行量产综合,在进行综合之前,需注意如下事项。

7.2. 注意事项

  • 为了达到较好的面积和时序,推荐用户采用打平层次结构(Flatten Hierarchy)的方式进行逻辑综合。

  • 处理器内核完全为纯数字电路逻辑。但是用户需要将源代码文件中的门控时钟逻辑替代成为具体工艺库下的门控时钟单元。

    • 以N101内核为例,时钟门控单元的源代码位于源文件的模块n101_clkgate中,请用户在n101_rls_pkg/n101_cct/design/core目录自行搜索该模块。