zynq PL部分无需打包,与PS AXI通信(linux系统)

项目需求,FPGA的程序部署到ZYNQ上。查了一下发现网上几乎所有的教程都是打包成IP核,这对于我这个多层文件多个IP核很难实现。整体打包始终报错,加上觉得后面修改程序啥的太麻烦,而且PS和PL数据传输比较少,没有时效性要求。就尝试将PL和PS独立出来,方便修改。我觉得这应该是个挺常见的需求不知道为什么搜不到,可能关键字没找对。

再次强调,ZYNQ是个有PL外设的ARM。这就很好办了。首先block design反应了各个模块和ARM 核的关系,生成的wrapper也就是最终的外设部署。那么只要在顶层文件中直接添加PL模块,实现了PS和PL 的并列排布。PS和PL的数据通过AXI总线访问,预留端口,在顶层模块中直接wire 相连即可

程序涉密,所以用个简单的PL程序代替。

PL程序如图。除了心跳灯,就是assign将ps输入的数据回传给ps。

将一个AXI lite的总线打包为IP核

顶层添加输入输出

低层添加

AXI总线改写,用过的都懂

将AXI的IP核添加到block design,并引出输入输出

接下来就生成底层文件,并将PL模块添加到其中

`timescale 1 ps / 1 ps

module ps_system_wrapper
   (DDR_addr,
    DDR_ba,
    DDR_cas_n,
    DDR_ck_n,
    DDR_ck_p,
    DDR_cke,
    DDR_cs_n,
    DDR_dm,
    DDR_dq,
    DDR_dqs_n,
    DDR_dqs_p,
    DDR_odt,
    DDR_ras_n,
    DDR_reset_n,
    DDR_we_n,
    FIXED_IO_ddr_vrn,
    FIXED_IO_ddr_vrp,
    FIXED_IO_mio,
    FIXED_IO_ps_clk,
    FIXED_IO_ps_porb,
    FIXED_IO_ps_srstb,
    led,
    clk,
    rst_n
    );
  inout [14:0]DDR_addr;
  inout [2:0]DDR_ba;
  inout DDR_cas_n;
  inout DDR_ck_n;
  inout DDR_ck_p;
  inout DDR_cke;
  inout DDR_cs_n;
  inout [3:0]DDR_dm;
  inout [31:0]DDR_dq;
  inout [3:0]DDR_dqs_n;
  inout [3:0]DDR_dqs_p;
  inout DDR_odt;
  inout DDR_ras_n;
  inout DDR_reset_n;
  inout DDR_we_n;
  inout FIXED_IO_ddr_vrn;
  inout FIXED_IO_ddr_vrp;
  inout [53:0]FIXED_IO_mio;
  inout FIXED_IO_ps_clk;
  inout FIXED_IO_ps_porb;
  inout FIXED_IO_ps_srstb;
  output[3:0] led;
  input       clk;
  input       rst_n;

  wire [14:0]DDR_addr;
  wire [2:0]DDR_ba;
  wire DDR_cas_n;
  wire DDR_ck_n;
  wire DDR_ck_p;
  wire DDR_cke;
  wire DDR_cs_n;
  wire [3:0]DDR_dm;
  wire [31:0]DDR_dq;
  wire [3:0]DDR_dqs_n;
  wire [3:0]DDR_dqs_p;
  wire DDR_odt;
  wire DDR_ras_n;
  wire DDR_reset_n;
  wire DDR_we_n;
  wire FIXED_IO_ddr_vrn;
  wire FIXED_IO_ddr_vrp;
  wire [53:0]FIXED_IO_mio;
  wire FIXED_IO_ps_clk;
  wire FIXED_IO_ps_porb;
  wire FIXED_IO_ps_srstb;
  wire [31:0]pl_to_ps_0;
  wire [31:0]ps_to_pl_0;

  ps_system ps_system_i
       (.DDR_addr(DDR_addr),
        .DDR_ba(DDR_ba),
        .DDR_cas_n(DDR_cas_n),
        .DDR_ck_n(DDR_ck_n),
        .DDR_ck_p(DDR_ck_p),
        .DDR_cke(DDR_cke),
        .DDR_cs_n(DDR_cs_n),
        .DDR_dm(DDR_dm),
        .DDR_dq(DDR_dq),
        .DDR_dqs_n(DDR_dqs_n),
        .DDR_dqs_p(DDR_dqs_p),
        .DDR_odt(DDR_odt),
        .DDR_ras_n(DDR_ras_n),
        .DDR_reset_n(DDR_reset_n),
        .DDR_we_n(DDR_we_n),
        .FIXED_IO_ddr_vrn(FIXED_IO_ddr_vrn),
        .FIXED_IO_ddr_vrp(FIXED_IO_ddr_vrp),
        .FIXED_IO_mio(FIXED_IO_mio),
        .FIXED_IO_ps_clk(FIXED_IO_ps_clk),
        .FIXED_IO_ps_porb(FIXED_IO_ps_porb),
        .FIXED_IO_ps_srstb(FIXED_IO_ps_srstb),
        .pl_to_ps_0(pl_to_ps_0),
        .ps_to_pl_0(ps_to_pl_0));
        
        
  wire  [3:0]   led;
  wire          clk;
  wire          rst_n;
  led_stream pl_system
  (
  .led(led),
  .clk(clk),
  .rst_n(rst_n),
  .cnt_output_pl2ps(pl_to_ps_0),

最终的效果如图所示

可以看到实现了PS和PL 的并列

裸机 SDK程序如图,写入、加一、读出、串口打印

串口打印,可以看到满足了需求

linux系统代码测试如图:

 22  #define ZYNQ_AXI_REG_BASE      0x43C00000
 23  #define WRITE_AXI_REG_BASE     0
 24  #define READ_AXI_REG_BASE      4
 25 
 26 
 27  /* 映射后的寄存器虚拟地址指针 */
 28  static void __iomem *write_addr;
 29  static void __iomem *read_addr;
 30 
 31  static int AXI_wr_rd_init(void)
 32  {
 33     u32 val = 100;
 34     //int ret;
 35 
 36     /* 寄存器地址映射 */
 37     write_addr = ioremap(ZYNQ_AXI_REG_BASE + WRITE_AXI_REG_BASE, 4);
 38     read_addr = ioremap(ZYNQ_AXI_REG_BASE + READ_AXI_REG_BASE, 4);
 39 
 40     printk("testing……");
 41 
 42     writel(val, write_addr);
 43     msleep(1000);
 44     val = readl(read_addr);
 45 
 46     printk("%d",val);
 47 
 48     /* 取消寄存器地址映射 */
 49     iounmap(write_addr);
 50     iounmap(read_addr);
 51 
 52     return 0;
 53  }

通过ioremap找到linux中的虚拟地址之后写入,读出

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值