2022年四月左右,openwifi进行了大的改版,发布了新的版本。这篇BLOG我根据openwifi官方的步骤,实现一下zedboard_fmcomms3平台下的软件编译。
本BLOG就是我学习试验https://github.com/open-sdr/openwifi-hw 这个页面中讲述的步骤,也是笔记,边做边记录,给大家分享可以让大家少走弯路。
步骤1 :需要的软件:
Pre-conditions:
在ofdem的解码器部分用到了viterbi decoder,需要下载申请xilinx的试用版授权,我以前写了完成步骤提供给我们板子的售后(tqtt.taobao.com购买ZEDBOARD+FMCOMMS3板子)。
这里需要用到装好VIVADO 2018.3版本的UBUNTU系统,当然也可以是装好的虚拟机,对本店售后我们提供了装好2018.3的UBUBTU18.04虚拟机,并加载好了所需要的license,包含之前提到的viterbi解码器,用户可以直接拿去无限制使用。
步骤2:递归方式下载下来openwifi-hw项目的所有代码,使用命令:
git clone --recursive https://github.com/open-sdr/openwifi-hw
看下图中:
这里注意看到此项目调用了adi官方的hdl项目做一个子模块(主要提供IP核的库),并且锁定版本号f61d970,我需要一并下载下来这个子模块,就一定要使用--recursive参数。
如果失败需要多下载几次,现在成功后进入此目录。
这里我们看到有个脚本prepare_adi_lib.sh实际就是下载制定的版本的adi官方hdl,
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "You must enter exactly 1 arguments: \$XILINX_DIR"
exit 1
fi
XILINX_DIR=$1
if [ -d "$XILINX_DIR/Vivado" ]; then
echo "\$XILINX_DIR is found!"
else
echo "\$XILINX_DIR is not correct. Please check!"
exit 1
fi
home_dir=$(pwd)
set -x
git submodule init adi-hdl
git submodule update adi-hdl
cd ./adi-hdl/library
# git reset --hard 2019_r1
git reset --hard f61d9707eb0a62533efd6facab59ab2444da94c9
# # the lib will be built when needed
# source $XILINX_DIR/Vivado/2018.3/settings64.sh
# make
cd $home_dir
我们下载openwifi-hw项目时候使用了 --recursive 关键字,就直接递归把所有用到子模块都下载下来了。可以省略掉这步。
步骤3:编译ADI的HDL库。
Prepare Analgo Devices HDL library (only run once):
export XILINX_DIR=your_Xilinx_install_directory
(Example: export XILINX_DIR=/opt/Xilinx. The Xilinx directory should include sth like: Downloads, SDK, Vivado, xic)
./prepare_adi_lib.sh $XILINX_DIR
这里我们看一下prepare_adi_board_ip.sh里面的内容:
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "You must enter exactly 2 arguments: \$XILINX_DIR \$BOARD_NAME"
exit 1
fi
XILINX_DIR=$1
if [ -d "$XILINX_DIR/Vivado" ]; then
echo "\$XILINX_DIR is found!"
else
echo "\$XILINX_DIR is not correct. Please check!"
exit 1
fi
BOARD_NAME=$2
# [ "$BOARD_NAME" != "zc706_fmcs2" ] && [ "$BOARD_NAME" != "zc702_fmcs2" ] && [ "$BOARD_NAME" != "zed_fmcs2" ] && [ "$BOARD_NAME" != "adrv9361z7035" ] && [ "$BOARD_NAME" != "adrv9361z7035_fmc" ] && [ "$BOARD_NAME" != "adrv9364z7020" ] && [ "$BOARD_NAME" != "zcu102_fmcs2" ] && [ "$BOARD_NAME" != "zcu102_9371" ]; then
if [ "$BOARD_NAME" == "zcu102_fmcs2" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/fmcomms2/zcu102/
elif [ "$BOARD_NAME" == "zcu102_9371" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/fmcomms2/zcu102/
elif [ "$BOARD_NAME" == "zc706_fmcs2" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/fmcomms2/zc706/
elif [ "$BOARD_NAME" == "zc702_fmcs2" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/fmcomms2/zc702/
elif [ "$BOARD_NAME" == "zed_fmcs2" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/fmcomms2/zed/
elif [ "$BOARD_NAME" == "adrv9361z7035" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/adrv9361z7035/ccbob_lvds/
#elif [ "$BOARD_NAME" == "adrv9361z7035_fmc" ]; then
# ADI_PROJECT_DIR=./adi-hdl/projects/adrv9361z7035/ccfmc_lvds/
elif [ "$BOARD_NAME" == "adrv9364z7020" ] || [ "$BOARD_NAME" == "antsdr" ]; then
ADI_PROJECT_DIR=./adi-hdl/projects/adrv9364z7020/ccbob_lvds/
else
echo "\$BOARD_NAME is not correct. Please check!"
exit 1
fi
echo $ADI_PROJECT_DIR
home_dir=$(pwd)
set -x
source $XILINX_DIR/Vivado/2018.3/settings64.sh
cd $ADI_PROJECT_DIR
make
cd $home_dir
首先我们要执行vivado命令要进行一下环境变量等设置,通过运行
source $XILINX_DIR/Vivado/2018.3/settings64.sh
对应在我们虚拟机上就是运行:
source /tools/Xilinx/Vivado/2018.3/settings64.sh
我们看到主要是根据不同的板子进入了不同目录之后进行了编译。这一步主要是为了根据不同板子编译生成不同的库,我们对应ADI官方板子项目目录是./adi-hdl/projects/fmcomms2/zed/。可以直接进入后make。当然我们在进入adi-hdl目录后直接输入
make fmcomm2.zed
就等效于进入./adi-hdl/projects/fmcomms2/zed/后 make .
这里大家看到了射频板名称是fmcomms2而不是fmcomms3,这两张是兼容的,数字引脚以及电源等完全对应,fmcomms2只是射频部分侧重2.4G频段网络,在射频输入输出部分选择了2.4G波段的器件,而fmcomm3则是选择更宽频率的器件支持了整个AD9361芯片所覆盖的整个射频范围70M-6000M。Openwifi默认的配置是5.8G频段,因此就应该选用fmcomm3射频板。
经过一段时间的等待后我们看到编译结束,会看到一系列的OK。
步骤4:由于使用了 --recursive关键词,我们也不需要运行get_ip_openofdm_rx.sh
步骤5,接下来的工作就要在viviado里面进行了。
在vivado的tcl命令的console里面输入:
cd /home/openwifi/work/openwifi-hw-20220510/openwifi-hw/boards/zed_fmcs2
之后输入 source ./ip_repo_gen.tcl,这是生成ip核的脚本我们看看内容:
# // Author: Xianjun Jiao
# // SPDX-FileCopyrightText: 2022 UGent
# // SPDX-License-Identifier: AGPL-3.0-or-later
# ------------------setup ip_repo directory and board files---------------------
exec rm -rf ip_repo
exec mkdir ip_repo
exec cp ../../ip/board_def.v ./ip_repo/ -f
# -----------generate git rev info------------------------
set fd [open "./ip_repo/openwifi_hw_git_rev.v" w]
set HASHCODE [exec ../../get_git_rev.sh]
puts $fd "`define OPENWIFI_HW_GIT_REV (32'h$HASHCODE)"
close $fd
# ----end of generate generate git rev info---------------
# -----------generate has_side_ch_flag.v------------------
# if you want NO side_ch, please use set has_side_ch 0
set has_side_ch 1
set fd [open "./ip_repo/has_side_ch_flag.v" w]
if {$has_side_ch > 0} {
puts $fd "`define HAS_SIDE_CH 1"
} else {
puts $fd "`define NO_SIDE_CH 1"
}
close $fd
# ----end of generate has_side_ch_flag.v------------------
# ---------generate fpga_scale.v---------------------------
# set small_fpga 1 for 7020 FPGA, set small_fpga 0 for the rest
set small_fpga 1
set fd [open "./ip_repo/fpga_scale.v" w]
if {$small_fpga == 1} {
puts $fd "`define SIDE_CH_LESS_BRAM 1"
}
close $fd
# ---------end of generate fpga_scale.v--------------------
# --------generate clock_speed.v for xpu/tx_intf/rx_intf---
set NUM_CLK_PER_US 100
set fd [open "./ip_repo/clock_speed.v" w]
puts $fd "`define NUM_CLK_PER_US $NUM_CLK_PER_US"
if {$small_fpga == 1} {
puts $fd "`define SMALL_FPGA 1"
}
close $fd
# --end of generate clock_speed.v for xpu/tx_intf/rx_intf--
# ---------generate spi_command.v---------------------------
# set grounded_rf_port 1 for port control, set 0 for lo control
set grounded_rf_port 0
set fd [open "./ip_repo/spi_command.v" w]
if {$grounded_rf_port == 1} {
puts $fd "`define SPI_HIGH 24'hC22001"
puts $fd "`define SPI_LOW 24'hC02001"
} else {
puts $fd "`define SPI_HIGH 24'h088A01"
puts $fd "`define SPI_LOW 24'h008A01"
}
close $fd
# ---------end of generate spi_command.v--------------------
# ------------------end of setup ip_repo directory and board files--------------
# --------------------------------generate ip repo------------------------------
set ultra_scale_flag 0
set part_string xc7z020clg484-1
set argc 3
set ip_name openofdm_rx
exec rm -rf project_1
set current_dir [pwd]
set argv [list $ultra_scale_flag $current_dir/../../ip/$ip_name $current_dir/ip_repo/$ip_name]
source ../package_ip_openofdm_rx.tcl
exec rm -rf ./ip_repo/$ip_name/xgui
set ip_name openofdm_tx
exec rm -rf project_1
set argv [list $part_string ../../ip/$ip_name/src/ ./ip_repo/$ip_name]
source ../package_ip.tcl
exec rm -rf ./ip_repo/$ip_name/xgui
set ip_name rx_intf
exec rm -rf project_1
exec cp ./ip_repo/board_def.v ../../ip/$ip_name/src/ -f
exec cp ./ip_repo/clock_speed.v ../../ip/$ip_name/src/ -f
set argv [list $part_string ../../ip/$ip_name/src/ ./ip_repo/$ip_name]
source ../package_ip.tcl
exec rm -rf ./ip_repo/$ip_name/xgui
set ip_name tx_intf
exec rm -rf project_1
exec cp ./ip_repo/board_def.v ../../ip/$ip_name/src/ -f
exec cp ./ip_repo/clock_speed.v ../../ip/$ip_name/src/ -f
set argv [list $part_string ../../ip/$ip_name/src/ ./ip_repo/$ip_name]
source ../package_ip.tcl
exec rm -rf ./ip_repo/$ip_name/xgui
set ip_name xpu
exec rm -rf project_1
exec cp ./ip_repo/openwifi_hw_git_rev.v ../../ip/$ip_name/src/ -f
exec cp ./ip_repo/board_def.v ../../ip/$ip_name/src/ -f
exec cp ./ip_repo/clock_speed.v ../../ip/$ip_name/src/ -f
exec cp ./ip_repo/spi_command.v ../../ip/$ip_name/src/ -f
set argv [list $part_string ../../ip/$ip_name/src/ ./ip_repo/$ip_name]
source ../package_ip.tcl
exec rm -rf ./ip_repo/$ip_name/xgui
set ip_name side_ch
exec rm -rf project_1
exec cp ./ip_repo/fpga_scale.v ../../ip/$ip_name/src/ -f
exec cp ./ip_repo/has_side_ch_flag.v ../../ip/$ip_name/src/ -f
set argv [list $part_string ../../ip/$ip_name/src/ ./ip_repo/$ip_name]
source ../package_ip.tcl
exec rm -rf ./ip_repo/$ip_name/xgui
# ---------------------------------end of generate ip repo-----------------------
我们看到这个相当于一个批处理,根据所选定板子的不同,进入到ip文件夹下编译各个ip。当然各个板子也可以添加自己的IP在里面编译。
执行ip_repo_gen.tcl过程中看到有多次弹出vivado界面后又关闭,每个ip核编译时候就闪现一下vivado。最后编译完之后就可以进行下一步
步骤6,接下来就是运行openwifi.tcl生成项目。
source ./openwifi.tcl
几秒后看到项目执行完毕。
步骤7,直接点generate bitstream.
步骤8,最后生成的bit文件在/openwifihw/boards/zed_fmcs2/openwifi_zed_fmcs2/openwifi_zed_fmcs2.runs/impl_1目录里。