创建OOT RFNoC Block

在RFNoC 4.0 中,取消的原来的rfnocmodtool(虽然这个还在工具链中)。根据Getting Started with RFNoC in UHD 4.0中介绍的步骤,我们需要根据我们的需求来更改rfnoc-example这个例子工程,然后再将oot block 编译到新的镜像中。

1 创建工程模板

RFNoC block的设计思路同GR的OOT模块类似,由一个大的OOT module带着一系列的功能模块(blocks)。 与之前版本不同的是,RFNoC4.0提供了一个RFNoC-oot模板工程,由用户自己复制出去并修改。

cp -r <repo>/host/examples/rfnoc-example <work_dir>/
cd <work_dir>/
mv rfnoc-example/ rfnoc-demo/

在工程配置文件中修改工程名称:将rfnoc-example改为rfnoc-demo

rfnoc-demo/CMakeLists.txt
rfnoc-demo/lib/CMakeLists.txt
rfnoc-demo/apps/CMakeLists.txt

需要修改的地方如下所示,共6处

2 创建一个自定义OOT Block

2.1 定义OOT Block

在你刚刚复制的工程模板中,包含一个gain模块,你可以在这个模块的基础上进行创建新的模块。

cd <work_dir>/rfnoc-demo/blocks/
cp gain.yml demo.yml

Note: 本篇的目的是简述如何创建并编译一个RFNoC Block,因此配置文件的内容将不再赘述

打开demo.yml文件,更改如下内容:

  • module_name的值从gain改为demo
  • noc_id的值改为0x0000DE30
  • data下的in outformat项从int32改为sc16

2.2 根据yaml文件生成verilog代码

python3 <repo>/host/utils/rfnoc_blocktool/rfnoc_create_verilog.py -c <work_dir>/rfnoc-demo/blocks/demo.yml -d <work_dir>/rfnoc-demo/fpga/rfnoc_block_demo

工具会在 <work_dir>/rfnoc-demo/fpga/rfnoc_block_demo 目录下创建RFNoC block的相关源码文件。

注意: 有一个步骤在官方的guide中没有提及,会导致编译image时工程中找不到自定义创建的rfnoc-block的源文件

修改fpga/Makefile.srcs

# One include statement for every RFNoC block with its own subdirectory, which
# itself will contain a Makefile.srcs
include $(OOT_FPGA_DIR)/rfnoc_block_gain/Makefile.srcs
include $(OOT_FPGA_DIR)/rfnoc_block_demo/Makefile.srcs

3 定义自定义模块在镜像中的使用方式

3.1 在image配置文件中使用自定义oot-block

这里考虑到节约fpga的资源,选择将自定义oot直接连接到数据通路中。

cp <repo>/fpga/usrp3/top/e31x/e310_rfnoc_image_core.yml <work_dir>/rfnoc-demo/icores/e310_rfnoc_with_demo.yml

然后编辑e310_rfnoc_with_demo.yml

# A list of all NoC blocks in design
# ----------------------------------
noc_blocks:
  radio0:                            # NoC block name
    block_desc: 'radio_2x64.yml'     # Block device descriptor
  gain0:
    block_desc: 'demo.yml'

其中 gain0 是为自定义oot module 起得实例化名字,也就是说可以创建多个。 在block_desc: 'demo.yml'则描述了所使用的描述文件名

3.2 定义oot module 的连接方式

  • 使用静态连接
    # 原来的连接方式
    connections:
      - { srcblk: ep0,    srcport: out0,  dstblk: radio0, dstport: in_0 }
      - { srcblk: ep1,    srcport: out0,  dstblk: radio0, dstport: in_1 }
      - { srcblk: radio0, srcport: out_0, dstblk: ep0,    dstport: in0  }
      - { srcblk: radio0, srcport: out_1, dstblk: ep1,    dstport: in0  }
      - { srcblk: radio0, srcport: ctrl_port, dstblk: _device_, dstport: ctrlport_radio }
      - { srcblk: _device_, srcport: x300_radio, dstblk: radio0, dstport: x300_radio }
      - { srcblk: _device_, srcport: time_keeper, dstblk: radio0, dstport: time_keeper }
    
    radio0 -> ep0
    # 修改之后
    connections:
      - { srcblk: ep0,    srcport: out0,  dstblk: radio0, dstport: in_0 }
      - { srcblk: ep1,    srcport: out0,  dstblk: radio0, dstport: in_1 }
      - { srcblk: radio0, srcport: out_0, dstblk: gain0,    dstport: in  }
      - { srcblk: gain0, srcport: out, dstblk: ep0,    dstport: in0  }
    
    { srcblk: radio0, srcport: out_1, dstblk: ep1,    dstport: in0  }
    { srcblk: radio0, srcport: ctrl_port, dstblk: device, dstport: ctrlport_radio }
    { srcblk: device, srcport: x300_radio, dstblk: radio0, dstport: x300_radio }
    { srcblk: device, srcport: time_keeper, dstblk: radio0, dstport: time_keeper }
    
    radio0[out_0] -> [in]gain0[out] -> [in0]ep1

这样就将gain0 串入了radio的输出通路上

3.3 定义时钟连接方式

gain模块不需要额外定义时钟,这里不再赘述。

4 启动编译

切换到rfnoc-demo目录

cd <work_dir>/rfnoc-demo
rfnoc_image_builder -F <repo>/fpga -I <work_dir>/rfnoc-test -y icores/e310_rfnoc_gain.yml -t E310_SG3 -l debug

如果看到以下输出,则没有错误,编译成功。

========================================================
Warnings:           949
Critical Warnings:  125
Errors:             0

make[1]: Leaving directory '/home/lilacsat/Downloads/tmp/uhd/fpga/usrp3/top/e31x'
Exporting bitstream file...
Exporting build report...
Build DONE ... E310_SG3

5 测试

暂无

参考

Getting Started with RFNoC in UHD 4.0

posted @ 2022-01-13 16:02  ArtisticZhao  阅读(235)  评论(0编辑  收藏  举报