【DNN Weaver FPGA实现】Vivado IP打包及ZYNQ系统集成

1、IP打包

由于所需打包系统中使用了AXI接口进行DDR访存,所以需要将IP接口打包为Vivado可以识别的AXI接口,以保证后续系统集成的顺利进行,因此需要使用下图所示的Vivado IP打包工具。

Pakage IP

选择下图所示的生成AXI4接口例程,将我们的RTL设计放入其中,就可以将该RTL设计包裹在这一例程中,并且实现对外的AXI接口。

image.png

如下图所示为继续配置该AXI接口例程,可以设置该AXI接口的类型和模式,但是位宽在这里只能设置为32bits,与我所需的256bits位宽不一致,不过这里暂时不用担心,直接设置为32bits然后完成IP。

AXI接口配置

IP完成设置后会在定义的文件夹中生成相应的代码和配置文件,进入到对应文件夹找到该IP RTL代码文件,如下图所示,名字中前半部分都是自己定义的。其中第一个代码为AXI例程的wrapper,不用管。第二份代码为具体的AXI接口逻辑实现,例程中还包含了简单的访存测试以及对应的接口,具体如何改动和测试参考【DNN Weaver FPGA实现】Vivado SDK实现BRAM、DDR访存

AXI例程代码

这里由于是借用这个IP的外壳打包我们的RTL代码设计,所以直接把第二份代码中的逻辑删干净,仅保留接口定义和必要的信号连接,然后例化我们的模块,将AXI接口线直接接出即可。当然如果还有别的IO信号也可以在接口上添加。具体代码例子放在最后。搞好这部分以后回到Vivado中,创建Block Design,直接ADD IP中查找这个AXI IP的名字然后例化,如下图所示。

查找IP

例化IP

例化完成IP后,右键点击IP进入Edit IP in Packager。

Edit IP in Packager

在这里可以直接对IP的RTL代码进行改动,像刚刚没有改好的RTL代码,可以在Packager中进行后续修改。例如上面提到的接口位宽需要256bits,而生成的代码中位宽只有32bit,就需要我们将wrapper中定义接口位宽的C_M_AXI_DATA_WIDTH参数修改为256,修改之后发现package IP后接口位宽并没有发生变化,说明直接修改有问题,因此找到下图所示的参数配置界面,打开C_M_AXI_DATA_WIDTH参数配置,发现默认参数值只有32bits,点击加号按钮添加默认值256,就可以将下面的Default Value值设定为256了,这样将IP打包得到的接口大小即为256bits。

IP Packager参数配置界面

配置C_M_AXI_DATA_WIDTH参数

配置C_M_AXI_DATA_WIDTH参数为256

配置结果,数据通道位宽拓宽为256bits

如果想要在IP上加入新的端口,就直接在RTL代码中写好保存,再进入下图所示Package IP界面中的Ports and Interfaces选项中点击上面的红框,即可自动完成新接口的打包。

用户自定义新接口

Ports and Interface

自动打包结果

然后重新打包IP,回到Block Design,更新IP状态,即可看到新IP接口。

新的IP接口

至此,IP打包的内容基本完成,后续对IP的任何修改都需要按照上述方法进入IP Packager来实现。

2、ZYNQ系统集成

进入Block Design,添加Zynq Processing System,并双击Block配置系统资源,配置一个AXI HP Slave接口用于我们IP的DDR访存。这里注意到HP接口位宽只能设置为64bits或者32bits,而我们的IP需要256bits的数据位宽,这一问题先不管。

Zynq Processing System Block

PS-PL AXI HP Slave Port

配置好Zynq系统资源后,点击Run Connection Automation,即可将上述打包好的IP与Zynq系统自动连接完整,如下图所示。注意到左边的红框为我们打包的IP,右边的红框就是Zynq PS端系统。可以看到Vivado自动帮我们例化了两个模块,一个是生成总线reset信号的模块,而另一个axi_smc则是AXI Interconnect模块,一般来说是用于多组AXI主从设备之间互联的。本系统只有一组主从设备,之所以需要这一模块,就是因为刚才所说的两者AXI数据接口位宽不匹配,需要进行不同位宽AXI之间进行数据的串并转换,而axi_smc模块中就包含了这一功能,或者说包含了AXI Dwidth Converter模块。所以说Vivado的功能非常强大,帮助用户减轻了系统集成负担。

自动连接好的系统Block Design

点击工具栏中的Validate Design,发现Block Design正确,点开axi_smc的主从接口,确认两端AXI接口位宽都是正确的。

axi_smc接口位宽确认

最后,右键Source->design_1(Block Design名称),点击Generate Output Hardware,完成后再次右键点击Create HDL Wrapper,即可完成Block Design全部设计流程。

Generate Output Hardware和Create HDL Wrapper

除此之外,需要提及的一点是,如果需要在用户RTL代码中例化使用Vivado中的IP模块而不是在Block Design中添加IP,需要在IP Catelog中自定义好所需的IP配置,然后直接在RTL代码中使用该IP配置的名称例化。但是需要注意的是,如果这些Vivado IP用在打包好的用户IP中,需要在打包IP的IP Packager中的IP Catelog进行自定义配置,而不能在总工程中配置,这样会导致用户IP找不到配置的Vivado IP。(这段说的有点乱……)

3、IP打包代码示例

// IP打包代码示例
`timescale 1 ns / 1 ps

    module AXI_IP_demo_v1_0_M00_AXI #
    (
        // Users to add parameters here

        // User parameters ends
        // Do not modify the parameters beyond this line

        // Base address of targeted slave
        parameter  C_M_TARGET_SLAVE_BASE_ADDR   = 32'h40000000,
        // Burst Length. Supports 1, 2, 4, 8, 16, 32, 64, 128, 256 burst lengths
        parameter integer C_M_AXI_BURST_LEN = 16,
        // Thread ID Width
        parameter integer C_M_AXI_ID_WIDTH  = 1,
        // Width of Address Bus
        parameter integer C_M_AXI_ADDR_WIDTH    = 32,
        // Width of Data Bus
        parameter integer C_M_AXI_DATA_WIDTH    = 32,
        // Width of User Write Address Bus
        parameter integer C_M_AXI_AWUSER_WIDTH  = 0,
        // Width of User Read Address Bus
        parameter integer C_M_AXI_ARUSER_WIDTH  = 0,
        // Width of User Write Data Bus
        parameter integer C_M_AXI_WUSER_WIDTH   = 0,
        // Width of User Read Data Bus
        parameter integer C_M_AXI_RUSER_WIDTH   = 0,
        // Width of User Response Bus
        parameter integer C_M_AXI_BUSER_WIDTH   = 0
    )
    (
        // Users to add ports here
                output wire dnnweaver2_done,
                input wire decoder_start,
                output wire [4-1:0]ld_state_q,
        // User ports ends
        // Do not modify the ports beyond this line

        // Initiate AXI transactions
        // Global Clock Signal.
        input wire  M_AXI_ACLK,
        // Global Reset Singal. This Signal is Active Low
        input wire  M_AXI_ARESETN,
        // Master Interface Write Address ID
        output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID,//**
        // Master Interface Write Address
        output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
        // Burst length. The burst length gives the exact number of transfers in a burst
        output wire [7 : 0] M_AXI_AWLEN,
        // Burst size. This signal indicates the size of each transfer in the burst
        output wire [2 : 0] M_AXI_AWSIZE,
        // Burst type. The burst type and the size information, 
    // determine how the address for each transfer within the burst is calculated.
        output wire [1 : 0] M_AXI_AWBURST,
        // Lock type. Provides additional information about the
    // atomic characteristics of the transfer.
        output wire  M_AXI_AWLOCK,//**
        // Memory type. This signal indicates how transactions
    // are required to progress through a system.
        output wire [3 : 0] M_AXI_AWCACHE,//**
        // Protection type. This signal indicates the privilege
    // and security level of the transaction, and whether
    // the transaction is a data access or an instruction access.
        output wire [2 : 0] M_AXI_AWPROT,//**
        // Quality of Service, QoS identifier sent for each write transaction.
        output wire [3 : 0] M_AXI_AWQOS,//**
        // Optional User-defined signal in the write address channel.
        output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER,//**
        // Write address valid. This signal indicates that
    // the channel is signaling valid write address and control information.
        output wire  M_AXI_AWVALID,
        // Write address ready. This signal indicates that
    // the slave is ready to accept an address and associated control signals
        input wire  M_AXI_AWREADY,
        // Master Interface Write Data.
        output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
        // Write strobes. This signal indicates which byte
    // lanes hold valid data. There is one write strobe
    // bit for each eight bits of the write data bus.
        output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
        // Write last. This signal indicates the last transfer in a write burst.
        output wire  M_AXI_WLAST,
        // Optional User-defined signal in the write data channel.
        output wire [C_M_AXI_WUSER_WIDTH-1 : 0] M_AXI_WUSER,//**
        // Write valid. This signal indicates that valid write
    // data and strobes are available
        output wire  M_AXI_WVALID,
        // Write ready. This signal indicates that the slave
    // can accept the write data.
        input wire  M_AXI_WREADY,
        // Master Interface Write Response.
        input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID,//**
        // Write response. This signal indicates the status of the write transaction.
        input wire [1 : 0] M_AXI_BRESP,
        // Optional User-defined signal in the write response channel
        input wire [C_M_AXI_BUSER_WIDTH-1 : 0] M_AXI_BUSER,//**
        // Write response valid. This signal indicates that the
    // channel is signaling a valid write response.
        input wire  M_AXI_BVALID,
        // Response ready. This signal indicates that the master
    // can accept a write response.
        output wire  M_AXI_BREADY,
        // Master Interface Read Address.
        output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID,
        // Read address. This signal indicates the initial
    // address of a read burst transaction.
        output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
        // Burst length. The burst length gives the exact number of transfers in a burst
        output wire [7 : 0] M_AXI_ARLEN,
        // Burst size. This signal indicates the size of each transfer in the burst
        output wire [2 : 0] M_AXI_ARSIZE,
        // Burst type. The burst type and the size information, 
    // determine how the address for each transfer within the burst is calculated.
        output wire [1 : 0] M_AXI_ARBURST,
        // Lock type. Provides additional information about the
    // atomic characteristics of the transfer.
        output wire  M_AXI_ARLOCK,//**
        // Memory type. This signal indicates how transactions
    // are required to progress through a system.
        output wire [3 : 0] M_AXI_ARCACHE,//**
        // Protection type. This signal indicates the privilege
    // and security level of the transaction, and whether
    // the transaction is a data access or an instruction access.
        output wire [2 : 0] M_AXI_ARPROT,//**
        // Quality of Service, QoS identifier sent for each read transaction
        output wire [3 : 0] M_AXI_ARQOS,//**
        // Optional User-defined signal in the read address channel.
        output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER,//**
        // Write address valid. This signal indicates that
    // the channel is signaling valid read address and control information
        output wire  M_AXI_ARVALID,
        // Read address ready. This signal indicates that
    // the slave is ready to accept an address and associated control signals
        input wire  M_AXI_ARREADY,
        // Read ID tag. This signal is the identification tag
    // for the read data group of signals generated by the slave.
        input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_RID,
        // Master Read Data
        input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
        // Read response. This signal indicates the status of the read transfer
        input wire [1 : 0] M_AXI_RRESP,
        // Read last. This signal indicates the last transfer in a read burst
        input wire  M_AXI_RLAST,
        // Optional User-defined signal in the read address channel.
        input wire [C_M_AXI_RUSER_WIDTH-1 : 0] M_AXI_RUSER,//**
        // Read valid. This signal indicates that the channel
    // is signaling the required read data.
        input wire  M_AXI_RVALID,
        // Read ready. This signal indicates that the master can
    // accept the read data and response information.
        output wire  M_AXI_RREADY
    );


    // function called clogb2 that returns an integer which has the
    //value of the ceiling of the log base 2

      // function called clogb2 that returns an integer which has the 
      // value of the ceiling of the log base 2.                      
      function integer clogb2 (input integer bit_depth);              
      begin                                                           
        for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                   
          bit_depth = bit_depth >> 1;                                 
        end                                                           
      endfunction                                                     

    // C_TRANSACTIONS_NUM is the width of the index counter for 
    // number of write or read transaction.
     localparam integer C_TRANSACTIONS_NUM = clogb2(C_M_AXI_BURST_LEN-1);

    // Burst length for transactions, in C_M_AXI_DATA_WIDTHs.
    // Non-2^n lengths will eventually cause bursts across 4K address boundaries.
     localparam integer C_MASTER_LENGTH = 12;
    // total number of burst transfers is master length divided by burst length and burst size
     localparam integer C_NO_BURSTS_REQ = C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/8)-1);
    // Example State machine to initialize counter, initialize write transactions, 
    // initialize read transactions and comparison of read data with the 
    // written data words.
    parameter [1:0] IDLE = 2'b00, // This state initiates AXI4Lite transaction 
            // after the state machine changes state to INIT_WRITE 
            // when there is 0 to 1 transition on INIT_AXI_TXN
        INIT_WRITE   = 2'b01, // This state initializes write transaction,
            // once writes are done, the state machine 
            // changes state to INIT_READ 
        INIT_READ = 2'b10, // This state initializes read transaction
            // once reads are done, the state machine 
            // changes state to INIT_COMPARE 
        INIT_COMPARE = 2'b11; // This state issues the status of comparison 
            // of the written data with the read data   

    assign M_AXI_AWID   = 'b0;
    assign M_AXI_AWLOCK = 1'b0;
    assign M_AXI_AWCACHE    = 4'b0010;
    assign M_AXI_AWPROT = 3'h0;
    assign M_AXI_AWQOS  = 4'h0;
    assign M_AXI_AWUSER = 'b1;
    assign M_AXI_WUSER  = 'b0;
    assign M_AXI_ARLOCK = 1'b0;
    assign M_AXI_ARCACHE    = 4'b0010;
    assign M_AXI_ARPROT = 3'h0;
    assign M_AXI_ARQOS  = 4'h0;
    assign M_AXI_ARUSER = 'b1;

// My RTL Block
    wrapper wrapper_axi_u(
    .clk(M_AXI_ACLK),
    .reset(M_AXI_ARESETN),
    .dnnweaver2_done(dnnweaver2_done),
    .decoder_start(decoder_start),

    // CL_wrapper -> DDR0 AXI4 interface
    .s00_axi_awaddr_0(M_AXI_AWADDR),
    .s00_axi_awlen_0(M_AXI_AWLEN),
    .s00_axi_awsize_0(M_AXI_AWSIZE),
    .s00_axi_awburst_0(M_AXI_AWBURST),
    .s00_axi_awvalid_0(M_AXI_AWVALID),
    .s00_axi_awready(M_AXI_AWREADY),
    .s00_axi_wdata_0(M_AXI_WDATA),
    .s00_axi_wstrb_0(M_AXI_WSTRB),
    .s00_axi_wlast_0(M_AXI_WLAST),
    .s00_axi_wvalid_0(M_AXI_WVALID),
    .s00_axi_wready(M_AXI_WREADY),
    .s00_axi_bresp(M_AXI_BRESP),
    .s00_axi_bvalid(M_AXI_BVALID),
    .s00_axi_bready_0(M_AXI_BREADY),
    .s00_axi_arid_0(M_AXI_ARID),
    .s00_axi_araddr_0(M_AXI_ARADDR),
    .s00_axi_arlen_0(M_AXI_ARLEN),
    .s00_axi_arsize_0(M_AXI_ARSIZE),
    .s00_axi_arburst_0(M_AXI_ARBURST),
    .s00_axi_arvalid_0(M_AXI_ARVALID),
    .s00_axi_arready(M_AXI_ARREADY),
    .s00_axi_rid(M_AXI_RID),
    .s00_axi_rdata(M_AXI_RDATA),
    .s00_axi_rresp(M_AXI_RRESP),
    .s00_axi_rlast(M_AXI_RLAST),
    .s00_axi_rvalid(M_AXI_RVALID),
    .s00_axi_rready_0(M_AXI_RREADY),

    .ld_state_q(ld_state_q)
    );

    endmodule

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,321评论 6 543
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,559评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,442评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,835评论 1 317
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,581评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,922评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,931评论 3 447
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,096评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,639评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,374评论 3 358
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,591评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,104评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,789评论 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,196评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,524评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,322评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,554评论 2 379