UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

Reply

ZC706 PS-PL Block RAM sharing

Visitor
Posts: 17
Registered: ‎12-25-2014

ZC706 PS-PL Block RAM sharing

I am using ZC706 evaluation kit. I have Vivado 2016.2.

My goal is to build a small project in which a Block RAM on the FPGA fabric can be accessed by both PS & PL. I am using a true dual port RAM such that through one port PS can read/write & through the other port PL can read/write. I took Zynq 7000 AP SOC Using BRAM for additional On Chip Memory as reference (although it is for earlier ISE version, I managed to build it for vivado 2016.2 & got same result). 

 

I modified my block design as shown below

Block Design.JPG

I wrote a small module which just reads data from BRAM PORTB. I give the same FCLK_CLK0 & increment the read address every clock cycle. I made BRAM_RST=0, BRAM_EN=1, BRAM_WE=0 & BRAM_DIN=0. I registered the BRAM_DOUT & added an ILA debug core on that. Below is the module which read data from PORT B

module system_top(PS_Clk, BRAM_Address, BRAM_DataIn, BRAM_DataOut, BRAM_Clk, BRAM_Rst, BRAM_Enable, BRAM_WE);
input PS_Clk;
input [31:0] BRAM_DataOut;
output [31:0] BRAM_Address;
output [31:0] BRAM_DataIn;
output BRAM_Clk;
output BRAM_Rst;
output BRAM_Enable;
output BRAM_WE;

(* mark_debug = "TRUE" *)reg [15:0] BRAM_Address16=0;
(* mark_debug = "TRUE" *)reg [31:0] Data_Read;

assign BRAM_Clk = PS_Clk;
assign BRAM_Address = {16'd0,BRAM_Address16};

always @(posedge PS_Clk)
	begin
		BRAM_Address16 <= BRAM_Address16 + 1;
		Data_Read <= BRAM_DataOut;
	end
	
assign BRAM_WE = 4'd0;
assign BRAM_Rst = 0;
assign BRAM_Enable = 1;
assign BRAM_DataIn = 32'd0;

endmodule

I generate the bit file & export & launch SDK. Through SDK I porgram the FPGA & run the GDB app that initializes the ZC706. The application project just writes continues int values from 0 to 65535 in the RAM. Below is that code too

#include <stdio.h>
#include "xparameters.h"
#define BRAM_SIZE 0x40000

int main()
{
	 unsigned int uiLoop;
	 unsigned int * uiDataArray = (unsigned int *)XPAR_AXI_BRAM_CTRL_0_S_AXI_BASEADDR;
	 unsigned int uiData;

	 printf("\n\r BRAM Data Initialization \n\r");
	 for(uiLoop =0 ; uiLoop < (BRAM_SIZE/4) ; uiLoop++)
	 {
		 *(unsigned int *)(uiDataArray + uiLoop) = uiLoop;
	 }
	 // BRAM Data Verification.
	 for(uiLoop =0 ; uiLoop < (BRAM_SIZE/4) ; uiLoop++)
	 {
		 uiData = *(unsigned int *)(uiDataArray + uiLoop);
		if(uiData != uiLoop)
		{
			printf("BRAM verification failed \n\r");
			return -1;
		}
	 }
	 printf("\n\r BRAM Verification Successful \n\r");
	 return 0;
}

It displays BRAM Verification Successful in the consol. Now, I close SDK & open Vivado Hardware Manager to see the ILA data. I am expecting data & address to be equal ie. in BRAM_Address=0, BRAM_DataOut=0, in BRAM_Address=1, BRAM_DataOut=1 & so on till in BRAM_Address=65536, BRAM_DataOut=65536. But what I observe doesn't make sense. I see address & data increment but not the above mentioned pattern. Below is what I see in the ILA

ILA.JPG

I am only reading data through PORT B so how is this possible. What mistake am I making?

Highlighted
Teacher
Posts: 4,871
Registered: ‎03-31-2012

Re: ZC706 PS-PL Block RAM sharing

@kharobangd From PS side you are writing to word (32 bit) addresses so you  write 0 to address 0 and 1 to address 4 etc. In PL the increment is in byte addresses and somehow it looks like bottom 2 bits of the address is being ignored. You need to understand how many bits are being used for address on both sides.

- Please mark the Answer as "Accept as solution" if information provided is helpful.
Give Kudos to a post which you think is helpful and reply oriented.
Visitor
Posts: 17
Registered: ‎12-25-2014

Re: ZC706 PS-PL Block RAM sharing

I am aware of that. The memory mapped address for the RAM is 0x4000_0000 to 0x4003_FFFF ie 262144 locations. Each 32 bit data(4 bytes) is stored in memory address offset of 4. The read & write from PS side is OK. I am trying to access this RAM from PL. There is no concept of memory-mapped address in PL(as far as I know, I am new to zynq), only relative address from 0 to 0xFFFF & each address stores the entire 32 bit data as far as PL is concerned. I am using 64 RAMB36 in 32x1024 combination. So when I access the address 0x0000 from PL side I should get 32'h0000, in address 0x0001 from PL side I should get 32'd0001.

 

Please somebody more experienced than me in Zynq programming just implement the code. I have already posted the block design & source code. I am getting frustrated getting this simple thing to work out.