Viavdo使用系列:IP Integrator HDL

vivado ip hdl rtl
US
发布时间: 2018-05-08
阅读: 2454
测试平台Vivado 2017.2
在Vivado的Block设计里,全IP化逐渐形成了一种新型的设计方案,受Vivado内的IP可配置的GUI界面影响,使用IP要比RTL代码更有良好的用户体验;然而,在Block设计里,并不是只有IP这一种可添加并可配置,RTL也可实现上述功能,只需要在Block内右键Add Module..,会弹出下面界面:
clipboard1.png

选择我之前写的模块add,点击ok(代码见页尾1)

clipboard2.png
这样就添加了一个add的RTL Module到Block Design内了。默认Vivado左边是输入端口,右边是输出端口。
上面是一个很简单的操作,接下来进入正题,讲解如何利用IP Integrator HDL语言使我们的RTL Module在Block内更像一个IP,IP Integrator HDL语言支持Verilog、VHDL,这里只用Verilog进行演示。先看一下Xilinx提供的IP Integrator HDL的Language Templates:
clipboard3.png
分析一下结构,得出以下几点结论:
(1)每个端口定义都是以(*起始,并以*)结束,并写在端口定义之前;
(2)每个端口定义结构满足 X_INTERFACE_INFO = "{存在的接口类型} {接口的名字} 接口内的端口(必须与接口类型定义的端口一致)"
(3)除了端口定义,还有Parameter定义,以X_INTERFACE_PARAMETER = "开始,内部采用键值对,即Param=value型结构;
下面是vivado内的原话:
//
// Verilog attributes are used to declare signal interfaces and set parameters on them.
// Due to the language, the attributes need to be placed before a port which is part of the interface.
// When adding one or more parameters for an interface, a single attribute with multiple
// key value pairs should be added to before of the ports that is mapped into the interface.
// Generally, the form of the attributes are:
//   (* X_INTERFACE_INFO = "<interface vlnv> <interface_name> <logical_port_name>" *)
//   (* X_INTERFACE_PARAMETER = "<parameter_name1> <parameter_value1>, <parameter_name2> <parameter_value2>" *)
//   input <portname>;
接下来以一个AXI4_dma_controller模块做例子演示一下。
首先按上述步骤添加一个AXI4_dma_controller模块到Block内(代码见页尾2)
clipboard4.png
看到了Vivado有两条axi总线,一条Master一条Slave,我们现在要做的就是用IP Integretor HDL语言强制将两条AXI总线指定出来,并让它们以总线形式显示。我添加好的axi_dma_controller的代码(代码见页尾3)
clipboard5.png
可以看到Slave AXI和Master AXI已经以总线图标显示,并能以总线接口进行连线,这是System Verilog才具有的功能,但是Vivado通过Block将其应用在Verilog和VHDL上了。

有的时候Vivado可以根据RTL Module自动推断出模块内的接口,这时候可以不用,但是自动推断的接口,经常会有莫名其妙的问题。如果系统内没有满足自己需要的接口,可以自定义接口,同样可以被IP Integrator HDL使用。

1.

module add(
    input A,
    input B,
    output [1:0] C
    );
endmodule
2.
module axi4_dma_controller_top #(
    parameter AXI4_DATA_WIDTH = 'h100, // AXI4 master data width - 256
    parameter AXI4_ADDR_WIDTH = 'h20, // AXI4 master address width
    parameter AXI4_LENGTH_WIDTH = 'h8, // AXI4 master burst length width
    parameter AXI4_ID_WIDTH = 'h2, // AXI4 master ID width
    parameter AXI4_MASTER_ID = 'h1, // AXI4 master ID
    parameter AXI4_CLK_FREQ = 'hc8, // axi4 master clock frequency in MHz - 200
    parameter DMA_CONTROLLER_ADDR = 'h000000 // axi4lite slave address base
)(
    // axi4_dma_controller
    output dma_done_event, // dma done interrupt (rising edge, s_clk0 domain)
    input axi4_aclk, // AXI4 master clock
    output [AXI4_ADDR_WIDTH-1:0] axi4_dma_length, // AXI4 DMA controller length
    output [AXI4_ADDR_WIDTH-1:0] axi4_dma_read_start_addr, // AXI4 DMA controller read start address
    output [AXI4_ADDR_WIDTH:0] axi4_dma_read_current_addr, // AXI4 DMA controller read current address
    output [AXI4_ADDR_WIDTH-1:0] axi4_dma_write_start_addr, // AXI4 DMA controller write start address
    output [AXI4_ADDR_WIDTH:0] axi4_dma_write_current_addr, // AXI4 DMA controller write current address
    input axi4_dma_read_enable, // AXI4 DMA controller read enable in threshold/stream mode
    // AXI4Lite_slave
    input s_axil_aclk0,
    input s_axil_aresetn0,
    input [31:0] s_axil_awaddr0,
    input s_axil_awvalid0,
    output s_axil_awready0,
    input [31:0] s_axil_wdata0,
    input [3:0] s_axil_wstrb0,
    input s_axil_wvalid0,
    output s_axil_wready0,
    output [1:0] s_axil_bresp0,
    output s_axil_bvalid0,
    input s_axil_bready0,
    input [31:0] s_axil_araddr0,
    input s_axil_arvalid0,
    output s_axil_arready0,
    output [31:0] s_axil_rdata0,
    output [1:0] s_axil_rresp0,
    output s_axil_rvalid0,
    input s_axil_rready0,
    // AXI4_master
    output m_axi_aclk0,
    output m_axi_aresetn0,
    output [AXI4_ID_WIDTH-1:0] m_axi_awid0,
    output [AXI4_ADDR_WIDTH-1:0] m_axi_awaddr0,
    output [AXI4_LENGTH_WIDTH-1:0] m_axi_awlen0,
    output [2:0] m_axi_awsize0,
    output [1:0] m_axi_awburst0,
    output [3:0] m_axi_awcache0,
    output [2:0] m_axi_awprot0,
    output m_axi_awvalid0,
    input m_axi_awready0,
    output [AXI4_DATA_WIDTH-1:0] m_axi_wdata0,
    output [AXI4_DATA_WIDTH/8-1:0] m_axi_wstrb0,
    output m_axi_wlast0,
    output m_axi_wvalid0,
    input m_axi_wready0,
    input [AXI4_ID_WIDTH-1:0] m_axi_bid0,
    input [1:0] m_axi_bresp0,
    input m_axi_bvalid0,
    output m_axi_bready0,
    output [AXI4_ID_WIDTH-1:0] m_axi_arid0,
    output [AXI4_ADDR_WIDTH-1:0] m_axi_araddr0,
    output [AXI4_LENGTH_WIDTH-1:0] m_axi_arlen0,
    output [2:0] m_axi_arsize0,
    output [1:0] m_axi_arburst0,
    output [3:0] m_axi_arcache0,
    output [2:0] m_axi_arprot0,
    output m_axi_arvalid0,
    input m_axi_arready0,
    input [AXI4_ID_WIDTH-1:0] m_axi_rid0,
    input [AXI4_DATA_WIDTH-1:0] m_axi_rdata0,
    input [1:0] m_axi_rresp0,
    input m_axi_rlast0,
    input m_axi_rvalid0,
    output m_axi_rready0
);

endmodule


3.

module axi4_dma_controller_top #(
    parameter AXI4_DATA_WIDTH = 'h100, // AXI4 master data width - 256
    parameter AXI4_ADDR_WIDTH = 'h20, // AXI4 master address width
    parameter AXI4_LENGTH_WIDTH = 'h8, // AXI4 master burst length width
    parameter AXI4_ID_WIDTH = 'h2, // AXI4 master ID width
    parameter AXI4_MASTER_ID = 'h1, // AXI4 master ID
    parameter AXI4_CLK_FREQ = 'hc8, // axi4 master clock frequency in MHz - 200
    parameter DMA_CONTROLLER_ADDR = 'h109000 // axi4lite slave address base
)(
    // axi4_dma_controller
    output dma_done_event, // dma done interrupt (rising edge, s_clk0 domain)
    input axi4_aclk, // AXI4 master clock
    output [AXI4_ADDR_WIDTH-1:0] axi4_dma_length, // AXI4 DMA controller length
    output [AXI4_ADDR_WIDTH-1:0] axi4_dma_read_start_addr, // AXI4 DMA controller read start address
    output [AXI4_ADDR_WIDTH:0] axi4_dma_read_current_addr, // AXI4 DMA controller read current address
    output [AXI4_ADDR_WIDTH-1:0] axi4_dma_write_start_addr, // AXI4 DMA controller write start address
    output [AXI4_ADDR_WIDTH:0] axi4_dma_write_current_addr, // AXI4 DMA controller write current address
    input axi4_dma_read_enable, // AXI4 DMA controller read enable in threshold/stream mode
    // AXI4Lite_slave
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite AWADDR" *)
    input [31:0] s_axil_awaddr0, // Write address (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite AWVALID" *)
    input s_axil_awvalid0, // Write address valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite AWREADY" *)
    output s_axil_awready0, // Write address ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite WDATA" *)
    input [31:0] s_axil_wdata0, // Write data (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite WSTRB" *)
    input [3:0] s_axil_wstrb0, // Write strobes (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite WVALID" *)
    input s_axil_wvalid0, // Write valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite WREADY" *)
    output s_axil_wready0, // Write ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite BRESP" *)
    output [1:0] s_axil_bresp0, // Write response (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite BVALID" *)
    output s_axil_bvalid0, // Write response valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite BREADY" *)
    input s_axil_bready0, // Write response ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite ARADDR" *)
    input [31:0] s_axil_araddr0, // Read address (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite ARVALID" *)
    input s_axil_arvalid0, // Read address valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite ARREADY" *)
    output s_axil_arready0, // Read address ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite RDATA" *)
    output [31:0] s_axil_rdata0, // Read data (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite RRESP" *)
    output [1:0] s_axil_rresp0, // Read response (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite RVALID" *)
    output s_axil_rvalid0, // Read valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 S_AXI_Lite RREADY" *)
    input s_axil_rready0, // Read ready (optional)
    (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF S_AXI_Lite, ASSOCIATED_RESET s_axil_aresetn0, FREQ_HZ 100000000" *)
    (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 s_axil_aclk0 CLK" *)
    input s_axil_aclk0,
    (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *)
    (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 s_axil_aresetn0 RST" *) 
    output s_axi_aresetn0,
    // AXI4_master
    output [AXI4_ID_WIDTH-1:0] m_axi_awid0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWADDR" *)
    output [AXI4_ADDR_WIDTH-1:0] m_axi_awaddr0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWLEN" *)
    output [AXI4_LENGTH_WIDTH-1:0] m_axi_awlen0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWSIZE" *)
    output [2:0] m_axi_awsize0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWBURST" *)
    output [1:0] m_axi_awburst0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWCACHE" *)
    output [3:0] m_axi_awcache0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWPROT" *)
    output [2:0] m_axi_awprot0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWVALID" *)
    input m_axil_awvalid0, // Write address valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI AWREADY" *)
    output m_axil_awready0, // Write address ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WDATA" *)
    output [AXI4_DATA_WIDTH-1:0] m_axi_wdata0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WSTRB" *)
    output [AXI4_DATA_WIDTH/8-1:0] m_axi_wstrb0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WLAST" *)
    output m_axi_wlast0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WVALID" *)
    input m_axil_wvalid0, // Write valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI WREADY" *)
    output m_axil_wready0, // Write ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BID" *)
    input [AXI4_ID_WIDTH-1:0] m_axi_bid0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BRESP" *)
    output [1:0] m_axil_bresp0, // Write response (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BVALID" *)
    output m_axil_bvalid0, // Write response valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI BREADY" *)
    input m_axil_bready0, // Write response ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARID" *)
    output [AXI4_ID_WIDTH-1:0] m_axi_arid0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARADDR" *)
    output [AXI4_ADDR_WIDTH-1:0] m_axi_araddr0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARLEN" *)
    output [AXI4_LENGTH_WIDTH-1:0] m_axi_arlen0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARSIZE" *)
    output [2:0] m_axi_arsize0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARBURST" *)
    output [1:0] m_axi_arburst0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARCACHE" *)
    output [3:0] m_axi_arcache0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARPROT" *)
    output [2:0] m_axi_arprot0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARVALID" *)
    input m_axil_arvalid0, // Read address valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI ARREADY" *)
    output m_axil_arready0, // Read address ready (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RID" *)
    input [AXI4_ID_WIDTH-1:0] m_axi_rid0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RDATA" *)
    input [AXI4_DATA_WIDTH-1:0] m_axi_rdata0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RRESP" *)
    output [1:0] m_axil_rresp0, // Read response (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RLAST" *)
    input m_axi_rlast0,
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RVALID" *)
    output m_axil_rvalid0, // Read valid (optional)
    (* X_INTERFACE_INFO = "xilinx.com:interface:aximm:1.0 M_AXI RREADY" *)
    input m_axil_rready0, // Read ready (optional)

    (* X_INTERFACE_PARAMETER = "ASSOCIATED_BUSIF M_AXI, ASSOCIATED_RESET m_axi_aresetn0, FREQ_HZ 100000000" *)
    (* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 m_axil_aclk0 CLK" *)
    output m_axi_aclk0,
    (* X_INTERFACE_PARAMETER = "POLARITY ACTIVE_LOW" *)
    (* X_INTERFACE_INFO = "xilinx.com:signal:reset:1.0 m_axil_aresetn0 RST" *)
    output m_axi_aresetn0
);

endmodule



原创作品,未经权利人授权禁止转载。详情见转载须知 举报文章

点赞 (0)
US
评论(0)

登录后可评论,请 登录注册

相关文章推荐
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回

我要举报该内容理由

×
请输入您举报的理由(50字以内)