0%

ZYNQ嵌入式之BRAM(基于PYNQ-Z2开发板)

本节通过基于BRAM的PS与PL数据交互实验,简单演示了BRAM的使用

基于BRAM的PS与PL数据交互实验

  • 实验任务:PS将串口接收到的数据写入BRAM(是FPGA内部的一个片上存储资源),然后从BRAM中读出数据,并通过串口打印出来;与此同时,PL从BRAM中同样读出数据,并通过ILA来观察读出的数据与串口打印的数据是否一致

    image-20230929013337035

1.Vivado中的相关配置

  • ZYNQ PS的配置:直接点击auto自动配置

  • AXI BRAM controller的配置:

    image-20231001222224779
  • 产生一个Block RAM的IP核:

    image-20231001222648098 image-20231001222753654
  • 自动连线:

    image-20231001223031999

2.自定义pl_bram_rd的ip核添加

3.ILA观测信号的添加

  • 综合后点击set up debug

  • 添加观测信号

    image-20231002000918153

  • 然后ctrl+s保存xdc文件

4.Vitis中的代码编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream>
#include<xbram_hw.h>
#include<pl_bram_rd.h>

using namespace std;

#define PL_BRAM_START PL_BRAM_RD_S00_AXI_SLV_REG0_OFFSET //RAM读开始寄存器地址
#define PL_BRAM_START_ADDR PL_BRAM_RD_S00_AXI_SLV_REG1_OFFSET //RAM起始寄存器地址
#define PL_BRAM_LEN PL_BRAM_RD_S00_AXI_SLV_REG2_OFFSET //PL读 RAM的深度
#define PL_BRAM_BASE XPAR_PL_BRAM_RD_0_S00_AXI_BASEADDR //PL_RAM_RD基地址

#define START_ADDR 0 //RAM起始地址范围:0~1023
#define BRAM_DATA_BYTE 4 //BRAM数据字节个数

char ch_data[1024]; //写入BRAM的字符数组
int ch_data_len; //写入BRAM的字符个数

int main()
{
while(1)
{
int i = 0;
int wr_cnt = 0;
int read_data = 0;

printf("Please input data to read and write Bram !\n");
scanf("%s",ch_data); //用户输入字符串
ch_data_len = strlen(ch_data); //计算字符串的长度

//将字符串写入BRAM,每次循环向 BRAM中写入 1 个字符
for(i = START_ADDR*BRAM_DATA_BYTE; i<(START_ADDR + ch_data_len)*BRAM_DATA_BYTE; i+=BRAM_DATA_BYTE)
{
XBram_WriteReg(XPAR_BRAM_0_BASEADDR,i,ch_data[wr_cnt]);
wr_cnt++;
}
//配置PL_BRAM_RD起始地址
PL_BRAM_RD_mWriteReg(PL_BRAM_BASE,PL_BRAM_START_ADDR,START_ADDR*BRAM_DATA_BYTE);
//配置PL_BRAM_RD长度
PL_BRAM_RD_mWriteReg(PL_BRAM_BASE,PL_BRAM_LEN,ch_data_len*BRAM_DATA_BYTE);
//配置PL_BRAM_RD开始读信号,产生一个上升沿
PL_BRAM_RD_mWriteReg(PL_BRAM_BASE,PL_BRAM_START,1);
PL_BRAM_RD_mWriteReg(PL_BRAM_BASE,PL_BRAM_START,0);

//从 BRAM 中读出数据,循环从 BRAM 中读出数据
for(i = START_ADDR*BRAM_DATA_BYTE; i<(START_ADDR + ch_data_len)*BRAM_DATA_BYTE; i+=BRAM_DATA_BYTE)
{
read_data = XBram_ReadReg(XPAR_BRAM_0_BASEADDR,i);
printf("BRAM address is %d\t,Read data is %c\n",i/BRAM_DATA_BYTE,read_data);
}

}

}

5.实验结果

  • 串口打印:

    image-20231002010115177
  • ILA:

    image-20231002010038782

欢迎来到ssy的世界