目录
微信公众号获取更多FPGA相关源码:

1.前言
在FPGA的顶层设计中,常常会涉及到诸多模块进行相互连接。通常情况下,我们会使用verilog语言中的模块例化,来完成各个模块之间的连接,但是这样可读性太差,过一段时间再来看项目,或者交给其他人,要理清模块之间的连接情况,需要额外花费大量时间。
2.使用BlockDesign图形化设计的好处
下图展示了基于802.11a协议设计OFDM发射机时的顶层各模块模块连接图,数据流和控制信号以总线的方式连接,这样线条就会很少,看上去就十分的清晰。

如果使用代码例化连接是下面这样:
//Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
//--------------------------------------------------------------------------------
//Tool Version: Vivado v.2018.3 (win64) Build 2405991 Thu Dec 6 23:38:27 MST 2018
//Date : Tue May 28 14:50:05 2024
//Host : BF-202305231136 running 64-bit major release (build 9200)
//Command : generate_target OFDM_TX.bd
//Design : OFDM_TX
//Purpose : IP block netlist
//--------------------------------------------------------------------------------
`timescale 1 ps / 1 ps
(* CORE_GENERATION_INFO = "OFDM_TX,IP_Integrator,{x_ipVendor=xilinx.com,x_ipLibrary=BlockDiagram,x_ipName=OFDM_TX,x_ipVersion=1.00.a,x_ipLanguage=VERILOG,numBlks=13,numReposBlks=13,numNonXlnxBlks=0,numHierBlks=0,maxHierDepth=0,numSysgenBlks=0,numHlsBlks=0,numHdlrefBlks=11,numPkgbdBlks=0,bdsource=USER,da_board_cnt=2,da_clkrst_cnt=2,synth_mode=Global}" *) (* HW_HANDOFF = "OFDM_TX.hwdef" *)
module OFDM_TX
(TxPWR,
dac_din_rdy,
dac_dout,
dac_dout_Index,
dac_dout_last,
dac_dout_vld,
mcu_config_din,
mcu_config_din_start,
mcu_config_din_vld,
mcu_config_dout_rdy,
mcu_mac_din,
mcu_mac_din_vld,
mcu_mac_dout_rdy,
sys_clk,
sys_rst_n);
output [2:0]TxPWR;
input dac_din_rdy;
(* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.DAC_DOUT DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.DAC_DOUT, LAYERED_METADATA undef" *) output [15:0]dac_dout;
(* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.DAC_DOUT_INDEX DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.DAC_DOUT_INDEX, LAYERED_METADATA undef" *) output [8:0]dac_dout_Index;
output dac_dout_last;
output dac_dout_vld;
(* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.MCU_CONFIG_DIN DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.MCU_CONFIG_DIN, LAYERED_METADATA undef" *) input [20:0]mcu_config_din;
input mcu_config_din_start;
input mcu_config_din_vld;
output mcu_config_dout_rdy;
(* X_INTERFACE_INFO = "xilinx.com:signal:data:1.0 DATA.MCU_MAC_DIN DATA" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME DATA.MCU_MAC_DIN, LAYERED_METADATA undef" *) input [7:0]mcu_mac_din;
input mcu_mac_din_vld;
output mcu_mac_dout_rdy;
(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 CLK.SYS_CLK CLK" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME CLK.SYS_CLK, CLK_DOMAIN OFDM_TX_sys_clk, FREQ_HZ 50000000, INSERT_VIP 0, PHASE 0.000" *) input sys_clk;
(* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 RST.SYS_RST_N RST" *) (* X_INTERFACE_PARAMETER = "XIL_INTERFACENAME RST.SYS_RST_N, INSERT_VIP 0, POLARITY ACTIVE_LOW" *) input sys_rst_n;
wire clk_wiz_0_clk_out2;
wire clk_wiz_0_locked;
wire clk_wiz_clk_out1;
wire [1:0]convenc_0_m_axis_conv_TDATA;
wire [3:0]convenc_0_m_axis_conv_TID;
wire convenc_0_m_axis_conv_TREADY;
wire convenc_0_m_axis_conv_TSTRB;
wire convenc_0_m_axis_conv_TVALID;
wire [15:0]dac_0_dac_dout;
wire [8:0]dac_0_dac_dout_Index;
wire dac_0_dac_dout_last;
wire dac_0_dac_dout_vld;
wire dac_din_rdy_1;
wire [15:0]ifft_0_m_axis_ifft_TDATA;
wire ifft_0_m_axis_ifft_TLAST;
wire ifft_0_m_axis_ifft_TREADY;
wire [7:0]ifft_0_m_axis_ifft_TUSER;
wire ifft_0_m_axis_ifft_TVALID;
wire interleaver_1_0_m_axis_intv1_TDATA;
wire [1:0]interleaver_1_0_m_axis_intv1_TID;
wire interleaver_1_0_m_axis_intv1_TREADY;
wire interleaver_1_0_m_axis_intv1_TSTRB;
wire interleaver_1_0_m_axis_intv1_TVALID;
wire interleaver_2_0_m_axis_intv2_TDATA;
wire [1:0]interleaver_2_0_m_axis_intv2_TID;
wire interleaver_2_0_m_axis_intv2_TREADY;
wire interleaver_2_0_m_axis_intv2_TVALID;
wire [15:0]maping_0_m_axis_map_TDATA;
wire maping_0_m_axis_map_TREADY;
wire [5:0]maping_0_m_axis_map_TUSER;
wire maping_0_m_axis_map_TVALID;
wire [20:0]mcu_config_din_1;
wire mcu_config_din_start_1;
wire mcu_config_din_vld_1;
wire [7:0]mcu_mac_din_1;
wire mcu_mac_din_vld_1;
wire [15:0]pilot_0_m_axis_pilot_TDATA;
wire pilot_0_m_axis_pilot_TLAST;
wire pilot_0_m_axis_pilot_TREADY;
wire pilot_0_m_axis_pilot_TVALID;
wire puncture_0_m_axis_punt_TDATA;
wire [1:0]puncture_0_m_axis_punt_TID;
wire puncture_0_m_axis_punt_TREADY;
wire puncture_0_m_axis_punt_TSTRB;
wire puncture_0_m_axis_punt_TVALID;
wire scramler_0_m_axis_scram_TDATA;
wire [3:0]scramler_0_m_axis_scram_TID;
wire scramler_0_m_axis_scram_TREADY;
wire scramler_0_m_axis_scram_TSTRB;
wire scramler_0_m_axis_scram_TVALID;
wire [15:0]symbol_train_0_m_axis_train_TDATA;
wire symbol_train_0_m_axis_train_TLAST;
wire symbol_train_0_m_axis_train_TREADY;
wire [8:0]symbol_train_0_m_axis_train_TUSER;
wire symbol_train_0_m_axis_train_TVALID;
wire sys_clk_1;
wire sys_rst_n_1;
wire [2:0]tx_mcu_0_TxPWR;
wire tx_mcu_0_m_axis_mcu_TDATA;
wire [3:0]tx_mcu_0_m_axis_mcu_TID;
wire tx_mcu_0_m_axis_mcu_TREADY;
wire tx_mcu_0_m_axis_mcu_TSTRB;
wire tx_mcu_0_m_axis_mcu_TVALID;
wire tx_mcu_0_mcu_config_dout_rdy;
wire tx_mcu_0_mcu_dout_scram_load;
wire [6:0]tx_mcu_0_mcu_dout_scram_seed;
wire tx_mcu_0_mcu_mac_dout_rdy;
wire tx_mcu_0_phy_rst_n;
wire [0:0]util_vector_logic_0_Res;
assign TxPWR[2:0] = tx_mcu_0_TxPWR;
assign dac_din_rdy_1 = dac_din_rdy;
assign dac_dout[15:0] = dac_0_dac_dout;
assign dac_dout_Index[8:0] = dac_0_dac_dout_Index;
assign dac_dout_last = dac_0_dac_dout_last;
assign dac_dout_vld = dac_0_dac_dout_vld;
assign mcu_config_din_1 = mcu_config_din[20:0];
assign mcu_config_din_start_1 = mcu_config_din_start;
assign mcu_config_din_vld_1 = mcu_config_din_vld;
assign mcu_config_dout_rdy = tx_mcu_0_mcu_config_dout_rdy;
assign mcu_mac_din_1 = mcu_mac_din[7:0];
assign mcu_mac_din_vld_1 = mcu_mac_din_vld;
assign mcu_mac_dout_rdy = tx_mcu_0_mcu_mac_dout_rdy;
assign sys_clk_1 = sys_clk;
assign sys_rst_n_1 = sys_rst_n;
OFDM_TX_clk_wiz_0_0 clk_wiz_0
(.clk_in1(sys_clk_1),
.clk_out1(clk_wiz_clk_out1),
.clk_out2(clk_wiz_0_clk_out2),
.locked(clk_wiz_0_locked),
.resetn(sys_rst_n_1));
OFDM_TX_convenc_0_0 convenc_0
(.clk(clk_wiz_clk_out1),
.conv_din(scramler_0_m_axis_scram_TDATA),
.conv_din_rate_con(scramler_0_m_axis_scram_TID),
.conv_din_rdy(convenc_0_m_axis_conv_TREADY),
.conv_din_sig_flag(scramler_0_m_axis_scram_TSTRB),
.conv_din_vld(scramler_0_m_axis_scram_TVALID),
.conv_dout(convenc_0_m_axis_conv_TDATA),
.conv_dout_rate_con(convenc_0_m_axis_conv_TID),
.conv_dout_rdy(scramler_0_m_axis_scram_TREADY),
.conv_dout_sig_flag(convenc_0_m_axis_conv_TSTRB),
.conv_dout_vld(convenc_0_m_axis_conv_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_dac_0_0 dac_0
(.clk(clk_wiz_clk_out1),
.clk_dac(clk_wiz_0_clk_out2),
.dac_din_rdy(dac_din_rdy_1),
.dac_dout(dac_0_dac_dout),
.dac_dout_Index(dac_0_dac_dout_Index),
.dac_dout_last(dac_0_dac_dout_last),
.dac_dout_vld(dac_0_dac_dout_vld),
.dac_ifft_din(ifft_0_m_axis_ifft_TDATA),
.dac_ifft_din_Index(ifft_0_m_axis_ifft_TUSER),
.dac_ifft_din_last(ifft_0_m_axis_ifft_TLAST),
.dac_ifft_din_vld(ifft_0_m_axis_ifft_TVALID),
.dac_ifft_dout_rdy(ifft_0_m_axis_ifft_TREADY),
.dac_train_din(symbol_train_0_m_axis_train_TDATA),
.dac_train_din_Index(symbol_train_0_m_axis_train_TUSER),
.dac_train_din_last(symbol_train_0_m_axis_train_TLAST),
.dac_train_din_vld(symbol_train_0_m_axis_train_TVALID),
.dac_train_dout_rdy(symbol_train_0_m_axis_train_TREADY),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_ifft_0_0 ifft_0
(.clk(clk_wiz_clk_out1),
.ifft_din(pilot_0_m_axis_pilot_TDATA),
.ifft_din_last(pilot_0_m_axis_pilot_TLAST),
.ifft_din_rdy(ifft_0_m_axis_ifft_TREADY),
.ifft_din_vld(pilot_0_m_axis_pilot_TVALID),
.ifft_dout(ifft_0_m_axis_ifft_TDATA),
.ifft_dout_Index(ifft_0_m_axis_ifft_TUSER),
.ifft_dout_last(ifft_0_m_axis_ifft_TLAST),
.ifft_dout_rdy(pilot_0_m_axis_pilot_TREADY),
.ifft_dout_vld(ifft_0_m_axis_ifft_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_interleaver_1_0_0 interleaver_1_0
(.clk(clk_wiz_clk_out1),
.intv1_din(puncture_0_m_axis_punt_TDATA),
.intv1_din_Map_Type(puncture_0_m_axis_punt_TID),
.intv1_din_rdy(interleaver_1_0_m_axis_intv1_TREADY),
.intv1_din_sig_flag(puncture_0_m_axis_punt_TSTRB),
.intv1_din_vld(puncture_0_m_axis_punt_TVALID),
.intv1_dout(interleaver_1_0_m_axis_intv1_TDATA),
.intv1_dout_Map_Type(interleaver_1_0_m_axis_intv1_TID),
.intv1_dout_rdy(puncture_0_m_axis_punt_TREADY),
.intv1_dout_sig_flag(interleaver_1_0_m_axis_intv1_TSTRB),
.intv1_dout_vld(interleaver_1_0_m_axis_intv1_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_interleaver_2_0_0 interleaver_2_0
(.clk(clk_wiz_clk_out1),
.intv2_din(interleaver_1_0_m_axis_intv1_TDATA),
.intv2_din_Map_Type(interleaver_1_0_m_axis_intv1_TID),
.intv2_din_rdy(interleaver_2_0_m_axis_intv2_TREADY),
.intv2_din_sig_flag(interleaver_1_0_m_axis_intv1_TSTRB),
.intv2_din_vld(interleaver_1_0_m_axis_intv1_TVALID),
.intv2_dout(interleaver_2_0_m_axis_intv2_TDATA),
.intv2_dout_Map_Type(interleaver_2_0_m_axis_intv2_TID),
.intv2_dout_rdy(interleaver_1_0_m_axis_intv1_TREADY),
.intv2_dout_vld(interleaver_2_0_m_axis_intv2_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_maping_0_0 maping_0
(.clk(clk_wiz_clk_out1),
.map_din(interleaver_2_0_m_axis_intv2_TDATA),
.map_din_Map_Type(interleaver_2_0_m_axis_intv2_TID),
.map_din_rdy(maping_0_m_axis_map_TREADY),
.map_din_vld(interleaver_2_0_m_axis_intv2_TVALID),
.map_dout(maping_0_m_axis_map_TDATA),
.map_dout_Index(maping_0_m_axis_map_TUSER),
.map_dout_rdy(interleaver_2_0_m_axis_intv2_TREADY),
.map_dout_vld(maping_0_m_axis_map_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_pilot_0_0 pilot_0
(.clk(clk_wiz_clk_out1),
.pilot_din(maping_0_m_axis_map_TDATA),
.pilot_din_Index(maping_0_m_axis_map_TUSER),
.pilot_din_rdy(pilot_0_m_axis_pilot_TREADY),
.pilot_din_vld(maping_0_m_axis_map_TVALID),
.pilot_dout(pilot_0_m_axis_pilot_TDATA),
.pilot_dout_last(pilot_0_m_axis_pilot_TLAST),
.pilot_dout_rdy(maping_0_m_axis_map_TREADY),
.pilot_dout_vld(pilot_0_m_axis_pilot_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_puncture_0_1 puncture_0
(.clk(clk_wiz_clk_out1),
.punt_din(convenc_0_m_axis_conv_TDATA),
.punt_din_rate_con(convenc_0_m_axis_conv_TID),
.punt_din_rdy(puncture_0_m_axis_punt_TREADY),
.punt_din_sig_flag(convenc_0_m_axis_conv_TSTRB),
.punt_din_vld(convenc_0_m_axis_conv_TVALID),
.punt_dout(puncture_0_m_axis_punt_TDATA),
.punt_dout_Map_Type(puncture_0_m_axis_punt_TID),
.punt_dout_rdy(convenc_0_m_axis_conv_TREADY),
.punt_dout_sig_flag(puncture_0_m_axis_punt_TSTRB),
.punt_dout_vld(puncture_0_m_axis_punt_TVALID),
.rst_n(util_vector_logic_0_Res));
OFDM_TX_scramler_0_0 scramler_0
(.clk(clk_wiz_clk_out1),
.rst_n(util_vector_logic_0_Res),
.scram_din(tx_mcu_0_m_axis_mcu_TDATA),
.scram_din_rate_con(tx_mcu_0_m_axis_mcu_TID),
.scram_din_rdy(scramler_0_m_axis_scram_TREADY),
.scram_din_sig_flag(tx_mcu_0_m_axis_mcu_TSTRB),
.scram_din_vld(tx_mcu_0_m_axis_mcu_TVALID),
.scram_dout(scramler_0_m_axis_scram_TDATA),
.scram_dout_rate_con(scramler_0_m_axis_scram_TID),
.scram_dout_rdy(tx_mcu_0_m_axis_mcu_TREADY),
.scram_dout_sig_flag(scramler_0_m_axis_scram_TSTRB),
.scram_dout_vld(scramler_0_m_axis_scram_TVALID),
.scram_load(tx_mcu_0_mcu_dout_scram_load),
.scram_seed(tx_mcu_0_mcu_dout_scram_seed));
OFDM_TX_symbol_train_0_0 symbol_train_0
(.clk(clk_wiz_clk_out1),
.rst_n(util_vector_logic_0_Res),
.train_din_rdy(symbol_train_0_m_axis_train_TREADY),
.train_dout(symbol_train_0_m_axis_train_TDATA),
.train_dout_Index(symbol_train_0_m_axis_train_TUSER),
.train_dout_last(symbol_train_0_m_axis_train_TLAST),
.train_dout_vld(symbol_train_0_m_axis_train_TVALID));
OFDM_TX_tx_mcu_0_0 tx_mcu_0
(.TxPWR(tx_mcu_0_TxPWR),
.clk(clk_wiz_clk_out1),
.mcu_config_din(mcu_config_din_1),
.mcu_config_din_start(mcu_config_din_start_1),
.mcu_config_din_vld(mcu_config_din_vld_1),
.mcu_config_dout_rdy(tx_mcu_0_mcu_config_dout_rdy),
.mcu_din_rdy(tx_mcu_0_m_axis_mcu_TREADY),
.mcu_dout(tx_mcu_0_m_axis_mcu_TDATA),
.mcu_dout_rate_con(tx_mcu_0_m_axis_mcu_TID),
.mcu_dout_scram_load(tx_mcu_0_mcu_dout_scram_load),
.mcu_dout_scram_seed(tx_mcu_0_mcu_dout_scram_seed),
.mcu_dout_sig_flag(tx_mcu_0_m_axis_mcu_TSTRB),
.mcu_dout_vld(tx_mcu_0_m_axis_mcu_TVALID),
.mcu_mac_din(mcu_mac_din_1),
.mcu_mac_din_vld(mcu_mac_din_vld_1),
.mcu_mac_dout_rdy(tx_mcu_0_mcu_mac_dout_rdy),
.phy_rst_n(tx_mcu_0_phy_rst_n),
.rst_n(clk_wiz_0_locked),
.tx_end(1'b0));
OFDM_TX_util_vector_logic_0_1 util_vector_logic_0
(.Op1(clk_wiz_0_locked),
.Op2(tx_mcu_0_phy_rst_n),
.Res(util_vector_logic_0_Res));
endmodule
是不是,看着就头大?但是使用BlockDesign图形化设计,也不一定就那么好,如果连接的线条太多也是很容易出错的,很容易错连,漏连。相比之下,使用verilog例化的话,能够减少出错的概率。
但是如果能在设计中添加总线,那么一堆信号就可以使用一根线来进行来接,这样就会使BlockDesign的设计出错概率大大减小,连接思路也会更加清晰。
3.如何使用BlockDesign
新建FPGA工程,在完成了自己的各个子模块之后,点击Creat Block Design,创建一个bd文件。

Block Design其实就是一个容器,这个容器里面我们放入IP并且通过把IP接口通过连线的方式相互关联,这样图形化的设计效率要高一些,也更加直观。
单击"+"号添加我们需要用到的IP:

输入IP的关键字可以进行搜索:

想要添加自己的模块,找到Design Sources里面需要添加的模块,右键选择Add Module to Block Design。

添加完成之后,就可以根据需求去进行模块之间的连接。连接完成之后,顶层的输入输出需要通过Creat Port进行添加。在空白部分点击右键,选择Creat Port:

然后配置端口的相关参数。

比如这样,配置一个输入时钟端口s_aclk:

输入时钟端口s_aclk,和模块进行连接:

Design Sources里面找到db文件,右键选择Creat HDL Wrapper,可以生成顶层模块的verlig HDL的例化连接代码。如上面第2节所展示的代码那样。

4.如何将BlockDesign里面的信号聚合成总线形式
一般信号聚合成总线形式,有两种方法:端口声明遵循xilinx对于总线的命名方式、使用xilinx的原语进行总线封装。
4.1 端口声明遵循xilinx对于总线的命名方式
这里以AXI Stream协议为例,端口命名时遵循,从机到主机以s_axis_开头,主机到从机以m_axis_开头,代码如下所示:
module test123(
input wire m_aclk ,
input wire s_aclk ,
input wire s_aresetn ,
input wire s_axis_tvalid ,
output wire s_axis_tready ,
input wire [15 : 0] s_axis_tdata ,
input wire s_axis_tlast ,
input wire [7 : 0] s_axis_tuser ,
output wire m_axis_tvalid ,
input wire m_axis_tready ,
output wire [15 : 0] m_axis_tdata ,
output wire m_axis_tlast ,
output wire [7 : 0] m_axis_tuser
);
endmodule
添加到Block Design里面,端口就聚合在一起,形成了总线。

4.2 使用xilinx的原语进行总线封装
左上角,选择Lanquage Templates,打开

输入AXI Stream:

可以看到相关原语如何使用:
// Normally AXI is automatically inferred. However, if the names of your ports do not match, you can force the
// the creation of an interface and map the physical ports to the logical ports by using the X_INTERFACE_INFO
// attribute before each physical port
// Parameters are typically computed by the Block Diagram and annotated onto the cell (no need to specify these)
// axis - AMBA AXI4-Stream Interface (slave directions)
//
// Allowed parameters:
// CLK_DOMAIN - Clk Domain (string default: <blank>)
// PHASE - Phase (float)
// FREQ_HZ - Frequency (float default: 100000000)
// LAYERED_METADATA - Layered Metadata (string default: <blank>)
// HAS_TLAST - Has Tlast (long) {false - 0, true - 1}
// HAS_TKEEP - Has Tkeep (long) {false - 0, true - 1}
// HAS_TSTRB - Has Tstrb (long) {false - 0, true - 1}
// HAS_TREADY - Has Tready (long) {false - 0, true - 1}
// TUSER_WIDTH - Tuser Width (long)
// TID_WIDTH - Tid Width (long)
// TDEST_WIDTH - Tdest Width (long)
// TDATA_NUM_BYTES - Tdata Num Bytes (long)
module my_module (
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TID" *)
// Uncomment the following to set interface specific parameter on the bus interface.
// (* X_INTERFACE_PARAMETER = "CLK_DOMAIN <value>,PHASE <value>,FREQ_HZ <value>,LAYERED_METADATA <value>,HAS_TLAST <value>,HAS_TKEEP <value>,HAS_TSTRB <value>,HAS_TREADY <value>,TUSER_WIDTH <value>,TID_WIDTH <value>,TDEST_WIDTH <value>,TDATA_NUM_BYTES <value>" *)
input [<left_bound>:0] <s_tid>, // Transfer ID tag (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TDEST" *)
input [<left_bound>:0] <s_tdest>, // Transfer Destination (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TDATA" *)
input [<left_bound>:0] <s_tdata>, // Transfer Data (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TSTRB" *)
input [<left_bound>:0] <s_tstrb>, // Transfer Data Byte Strobes (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TKEEP" *)
input [<left_bound>:0] <s_tkeep>, // Transfer Null Byte Indicators (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TLAST" *)
input <s_tlast>, // Packet Boundary Indicator (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TUSER" *)
input [<left_bound>:0] <s_tuser>, // Transfer user sideband (optional)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TVALID" *)
input <s_tvalid>, // Transfer valid (required)
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 <interface_name> TREADY" *)
output <s_tready>, // Transfer ready (optional)
// additional ports here
);
在自己的代码里面,像例子那样,端口前面添加原语,进行总线聚合。
module dac(
input clk ,
input clk_dac ,
input rst_n ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_ifft_dac TDATA" *) input [15:0] dac_ifft_din ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_ifft_dac TVALID" *) input dac_ifft_din_vld ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_ifft_dac TLAST" *) input dac_ifft_din_last ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_ifft_dac TUSER" *) input [7:0] dac_ifft_din_Index ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_ifft_dac TREADY" *) output dac_ifft_dout_rdy ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_train_dac TDATA" *) input [15:0] dac_train_din ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_train_dac TVALID" *)input dac_train_din_vld ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_train_dac TLAST" *) input dac_train_din_last ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_train_dac TUSER" *) input [8:0] dac_train_din_Index ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 s_axis_train_dac TREADY" *)output dac_train_dout_rdy ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 m_axis_dac TREADY" *) input dac_din_rdy ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 m_axis_dac TDATA" *) output [15:0] dac_dout ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 m_axis_dac TVALID" *) output dac_dout_vld ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 m_axis_dac TLAST" *) output dac_dout_last ,
(* X_INTERFACE_INFO = "xilinx.com:interface:axis:1.0 m_axis_dac TUSER" *) output [8:0] dac_dout_Index
);
然后在Block Design里面就完成了总线的聚合。

当然如果有需求,也可以使用自己定义的总线,而不使用xilinx官方的总线,这个相对比较复杂,后面有机会再讲。
微信公众号获取更多FPGA相关源码:


7278

被折叠的 条评论
为什么被折叠?



