NICE协处理器

赛题要求:

  对蜂鸟E203 RISC-V内核进行运算算子(譬如加解密算法、浮点运算、矢量运算等)的扩展,可通过NICE协处理器接口进行添加,也可直接实现RISC-V指令子集(譬如P扩展、F/D扩展、V扩展、B扩展、K扩展等)

  对于采用NICE协处理器接口进行的扩展实现,需要在蜂鸟软件开发平台HBird SDK中进行相关软件驱动的添加

  • 实现思路:

    • 1.硬件设计,编写相应的verilog文件,需要注意的是NICE协处理器定义了一些基本的接口;
    • 2.编写驱动,通过内联汇编的伪指令.insn配置相关的驱动设置;
    • 3.编写用于测试的.C文件
  • 参考示例:

    • 背景: 假设有一个3行3列的矩阵按顺序存储在存储器中,每个元素都是32位的整数,目标进行逐行和逐列的累加和,若采用C语言调用主数据通路进行实现,基本思路是循环,按行/列读取各个元素然后相加得到各行/列的累加和,将其转换为汇编语言,则需要约上百个周期才能完成全部运算。

    • 硬件实现:(不太好写)

      (e203_hbirdv2-master\e203_hbirdv2-master\rtl\e203\subsys\e203_subsys_nice_core.v)

      ->NICE协处理器工作机理:

      • 请求通道:主处理器在流水线的EXU级时,将指令的编码信息和源操作数传输到协处理器。
      • 反馈通道:协处理器告诉主处理器其已完成了该指令,并将结果反馈到主处理器。
      • 存储器请求通道:协处理器向主处理器发起存储器读写请求。
      • 存储器反馈通道:主处理器向协处理器写回存储器读写结果。

      ->NICE示例协处理器的设计:

      控制模块(和主处理器通过NICE协处理器的接口进行交互)+累加器(累加运算)

      ->NICE示例协处理器的自定义指令

      ->verilog文件中包含内容:

      自定义指令的编码+各模块功能实现(以状态机实现的转换)

    • 软件驱动:

      (nuclei-board-labs-master\nuclei-board-labs-master\e203_hbirdv2\common\demo_nice\insn.h)

      基本格式:

      .insn r opcode, func3, func7, rd, rs1, rs2
    //.insn告知编译器当前的指令是.insn形式的指令
    //r用来表示指令类型为R-type
    //opcode、func3、func7、rd、rs1、rs2分别代表R类型指令格式的各位域

      具体实现:(累加和)

      // custom lbuf
    __STATIC_FORCEINLINE void custom_lbuf(int addr)
    {
    int zero = 0; asm volatile (
    ".insn r 0x7b, 2, 1, x0, %1, x0"
    :"=r"(zero)
    :"r"(addr)
    );
    } // custom sbuf
    __STATIC_FORCEINLINE void custom_sbuf(int addr)
    {
    int zero = 0; asm volatile (
    ".insn r 0x7b, 2, 2, x0, %1, x0"
    :"=r"(zero)
    :"r"(addr)
    );
    } // custom rowsum
    __STATIC_FORCEINLINE int custom_rowsum(int addr)
    {
    int rowsum; asm volatile (
    ".insn r 0x7b, 6, 6, %0, %1, x0"
    :"=r"(rowsum)
    :"r"(addr)
    ); return rowsum;
    }
    • 测试程序:(nuclei-board-labs-master\nuclei-board-labs-master\e203_hbirdv2\common\demo_nice\insn.c --> 功能实现;nuclei-board-labs-master\nuclei-board-labs-master\e203_hbirdv2\common\demo_nice\main.c --> 顶层文件,测试输出)
      /***********************************insn.c*********************************/
    // normal_case:通过主流水线来实现的累加操作
    int normal_case(unsigned int array[ROW_LEN][COL_LEN])
    {
    volatile unsigned char i=0, j=0;
    volatile unsigned int col_sum[COL_LEN]={0};
    volatile unsigned int row_sum[ROW_LEN]={0};
    volatile unsigned int tmp=0;
    for (i = 0; i < ROW_LEN; i++)
    {
    tmp = 0;
    for (j = 0; j < COL_LEN; j++)
    {
    col_sum[j] += array[i][j];
    tmp += array[i][j];
    }
    row_sum[i] = tmp;
    }
    } // nice_case:调用NICE协处理器实现的累加操作
    int nice_case(unsigned int array[ROW_LEN][COL_LEN])
    {
    volatile unsigned char i, j;
    volatile unsigned int col_sum[COL_LEN]={0};
    volatile unsigned int row_sum[ROW_LEN]={0};
    volatile unsigned int init_buf[3]={0}; custom_lbuf((int)init_buf);
    for (i = 0; i < ROW_LEN; i++)
    {
    row_sum[i] = custom_rowsum((int)array[i]);
    }
    custom_sbuf((int)col_sum);
    } /***********************************main.c*********************************/
    // 主要就是调用两个函数然后输出结果
    int main(void)
    {
    int i=100;
    int arr[4]={1,2,3,4};
    unsigned int array[ROW_LEN][COL_LEN]=
    {{10,20,30},
    {20,30,40},
    {30,40,50}
    };
    unsigned int begin_instret, end_instret, instret_normal, instret_nice;
    unsigned int begin_cycle, end_cycle, cycle_normal, cycle_nice; printf("**********************************************\n");
    printf("** begin to sum the array using ordinary add sum\n");
    begin_instret = __get_rv_instret();
    begin_cycle = __get_rv_cycle(); normal_case(array); end_instret = __get_rv_instret();
    end_cycle = __get_rv_cycle(); instret_normal = end_instret - begin_instret;
    cycle_normal = end_cycle - begin_cycle;
    printf("\n\n"); printf("**********************************************\n");
    printf("** begin to sum the array using nice add sum\n");
    begin_instret = __get_rv_instret();
    begin_cycle = __get_rv_cycle(); nice_case(array); end_instret = __get_rv_instret();
    end_cycle = __get_rv_cycle(); instret_nice = end_instret - begin_instret;
    cycle_nice = end_cycle - begin_cycle; printf("**********************************************\n");
    printf("** performance list \n"); printf("\t normal: \n");
    printf("\t instret: %d, cycle: %d \n", instret_normal, cycle_normal);
    printf("\t nice : \n");
    printf("\t instret: %d, cycle: %d \n", instret_nice , cycle_nice ); printf("**********************************************\n\n"); printf("* * * * ***** * ******* *** \n");
    printf("** * * * * * * * * \n");
    printf("* * * * * * * * * \n");
    printf("* * * * * * * ***** * \n");
    printf("* * * * * * * * * \n");
    printf("* ** * * * * * * * \n");
    printf("* * ***** ***** ******* ******* *** \n"); printf("\n\n**********************************************");
    return 0;
    }
    • 实际测试:

      • 法一:(不推荐)通过.c文件配置工程,参考这里(5.3. 无模板手动创建项目)

      • 法二:(推荐)

        • 创建HelloWorld例程,删除左侧相应工程目录下application/main.c文件

        • 将我们所编写的软件驱动文件和测试文件放入该目录下

        • 点击锤子进行编译,做好硬件连接后,点击️️绿色的三角运行。

      采用NICE协处理器进行的累加所用的指令数和周期数都远小于普通情况,如下图所示。

  • 一些疑惑:

    • 对于NICE协处理器和普通的情况,均进行了诸如循环读寄存器数据之类的操作,那么实现NICE协处理器相较于普通情况的优化体现在什么方面,节约的是进行取数+计算的时间,还是其他诸如循环控制等的时间;
    • 是否应该根据后续的系统及应用来判断进行什么样的扩展;
    • 对于添加了NICE协处理器的内核,其跑分结果应该有所提高,那么该如何通过跑分的程序测试出来;

3.NucleiStudio+Vivado联合仿真教程

  猜测后续的工作流程:

  • Benchmark:

    Vivado中修改RTL设计-->NucleiStudio中跑分验证/Vivado中仿真验证(尝试跑通中);

  • 指令集扩展:

    Vivado中添加RTL设计+IDE中添加软件驱动-->NucleiStudio中验证功能/Vivado中仿真验证功能(当前尝试的NICE协处理器可仿真验证)

  编写了一个Nucleistudio+Vivado联合仿真的教程,或许会有用((。

手把手教你蜂鸟e203协处理器的扩展的更多相关文章

  1. 手把手教你蜂鸟e203移植(以Nexys4DDR为例)

    准备工作:(网盘链接:) 1.蜂鸟e203的RTL源码: 2.一段分频代码: 3.顶层设计文件(system.v) 4.开发板文件: 5.Nexys4DDR电路图: 6.Nexys4DDR管脚约束模板 ...

  2. 手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单

    手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单   手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩 ...

  3. 菜鸟-手把手教你把Acegi应用到实际项目中(8)-扩展UserDetailsService接口

    一个能为DaoAuthenticationProvider提供存取认证库的的类,它必须要实现UserDetailsService接口: public UserDetails loadUserByUse ...

  4. 手把手教你开发chrome扩展

    转载:http://www.cnblogs.com/walkingp/archive/2011/04/04/2003875.html 手把手教你开发chrome扩展一:开发Chrome Extenst ...

  5. 手把手教你Chrome扩展开发:本地存储篇

    手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 HTML5 ...

  6. 手把手教你开发Chrome扩展三:关于本地存储数据

    手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 HTML5 ...

  7. 手把手教你开发Chrome扩展二:为html添加行为

    手把手教你开发chrome扩展一:开发Chrome Extenstion其实很简单 手把手教你开发Chrome扩展二:为html添加行为 手把手教你开发Chrome扩展三:关于本地存储数据 上一节我们 ...

  8. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(二)-Hexo参数设置

    前言 前文手把手教从零开始在GitHub上使用Hexo搭建博客教程(一)-附GitHub注册及配置介绍了github注册.git相关设置以及hexo基本操作. 本文主要介绍一下hexo的常用参数设置. ...

  9. 手把手教你写Sublime中的Snippet

    手把手教你写Sublime中的Snippet Sublime Text号称最性感的编辑器, 并且越来越多人使用, 美观, 高效 关于如何使用Sublime text可以参考我的另一篇文章, 相信你会喜 ...

  10. 30分钟手把手教你学webpack实战

    30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解ba ...

随机推荐

  1. vue3中watch监听不是你想的那样简单

    vue3 中watch监听数组,数组变化后未触发回调 今天发生了一个很神奇的现象,就是我使用watch监听数组时. 被监听的数组已经发生了变化.但是没有触发回调操作. 当时的我感到很疑惑? 不应该呀? ...

  2. python2和python3的版本历史及入门书籍

    python版本历史 我们端游项目使用是python2.7版本 32位 python2 2.7.18 last version on 2020.4.20 2.7 first version on 20 ...

  3. 从零开始配置 vim(18)——终端模式

    在进入下一个配置之前,先了解一下如何在 neovim 中使用它内置的终端. 我们之前说过在命令模式中可以使用 !来执行shell命令.但是终归来说,执行和使用上不是那么方便,特别是混合使用 vim 命 ...

  4. 2.3 CE修改器:浮点数扫描

    本关需要使用 Cheat Engine 工具对浮点数进行扫描,完成修改任务.浮点数是一种带有小数点的数值,通过"浮点数"扫描方式进行修改.本关中,健康值为单精度浮点数,弹药值为双精 ...

  5. 21.10 Python 使用CRC32校验文件

    CRC文件校验是一种用于验证文件完整性的方法,通过计算文件的CRC值并与预先计算的CRC校验值进行比较,来判断文件是否发生变化,此类功能可以用于验证一个目录中是否有文件发生变化,如果发生变化则我们可以 ...

  6. Java实现将中缀表达式转换到后缀表达式

    思路: 1.初始化两个栈 运算符栈 s1 和储存中间结果栈 s22. 从左到右扫描中缀表达式3. 遇到操作数时 压入s24. 遇到操作符 o1 时 比较其与 S1 栈顶运算符的优先级 1)如果s1为空 ...

  7. P6824 「EZEC-4」可乐 题解

    题目链接:可乐 一开始想着 0-1 Trie,枚举 \(x\) 去写,然后判断就行了.然后想起南京区域赛的 C 题,其实和这个也有点大同小异的感觉,可以用更朴素的办法,找到对于一个 \(a_i\) 而 ...

  8. HTTP 400 Bad Request 错误。

  9. 扩展说明: 指令微调 Llama 2

    这篇博客是一篇来自 Meta AI,关于指令微调 Llama 2 的扩展说明.旨在聚焦构建指令数据集,有了它,我们则可以使用自己的指令来微调 Llama 2 基础模型. 目标是构建一个能够基于输入内容 ...

  10. NC19325 游戏

    题目链接 题目 题目描述 BLUESKY007,fengxunling和dreagonm三个人发现了一个像素游戏,这款神奇的游戏每次会生成一个nxm的网格,其中每一个格子都被随机染色为R,G,B三种颜 ...