Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: Data Transfer from FPGA-to-HPS

  1. #11
    Join Date
    Jun 2018
    Posts
    28
    Rep Power
    1

    Default Re: Data Transfer from FPGA-to-HPS

    I'm not sure what the correct answer is, but it's definitely less frequent than that. I've been testing my own project for the last several days without changing the preloader. It may just need to match the version of Quartus (the preloader that comes with the board might have been generated by 16.0 or an even earlier version.)

  2. #12
    Join Date
    Jun 2018
    Posts
    15
    Rep Power
    1

    Default Re: Data Transfer from FPGA-to-HPS

    Quote Originally Posted by eugenek View Post
    I'm not sure what the correct answer is, but it's definitely less frequent than that. I've been testing my own project for the last several days without changing the preloader. It may just need to match the version of Quartus (the preloader that comes with the board might have been generated by 16.0 or an even earlier version.)
    Alright well I'm having some issues generating preloaders right now, So I'm working on getting that figured out, in the mean time have you successfully written to the HPS ddr and then read the value from it? If so what address are you writing/read to/from?

  3. #13
    Join Date
    Jun 2018
    Posts
    28
    Rep Power
    1

    Default Re: Data Transfer from FPGA-to-HPS

    Code:
    wire mm_bridge_2_s0_waitrequest;
    wire [31:0] mm_bridge_2_s0_readdata;
    wire        mm_bridge_2_s0_readdatavalid;
    reg [31:0] mm_bridge_2_s0_writedata=0;
    reg [31:0] mm_bridge_2_s0_address=0;
    reg mm_bridge_2_s0_write=0;
    reg mm_bridge_2_s0_read=0;
    //reg mm_bridge_2_s0_read_requested=0;
    //reg mm_bridge_2_s0_write_requested=0;
    
    reg[31:0] fifo_read_offset= 32'h20000000;
    reg[26:0] fifo_read_address=0;
    
    reg[31:0] fifo_write_offset=32'h28000000;
    reg[26:0] fifo_write_address=0;
    
    
    		if(!source_empty && !mm_bridge_2_s0_waitrequest)
    			begin
    			mm_bridge_2_s0_read<=1;
    			mm_bridge_2_s0_address<=fifo_read_offset|{5'b0,fifo_read_address};
    			fifo_read_address<=fifo_read_address+4;
    			source_empty<=...;
    			end
    		else if(!mm_bridge_2_s0_waitrequest)
    			mm_bridge_2_s0_read<=0;
    
    		if(mm_bridge_2_s0_readdatavalid && !core_full)
    			... <= mm_bridge_2_s0_readdata;
    		else
    			mm_bridge_2_s0_read<=0;
    			
    		if(core_readdatavalid && !mm_bridge_2_s0_waitrequest)
    			begin
    			mm_bridge_2_s0_write<=1;
    			mm_bridge_2_s0_writedata <= ...;
    			mm_bridge_2_s0_address<=fifo_write_offset|{5'b0,fifo_write_address};
    			fifo_write_address<=fifo_write_address+4;
    			end
    		else if(!mm_bridge_2_s0_waitrequest)
    			mm_bridge_2_s0_write<=0;
    
    ....
    
    	   // FPGA->HPS access wires
    		.mm_bridge_2_s0_waitrequest(mm_bridge_2_s0_waitrequest),            //                 mm_bridge_1_s0.waitrequest
    		.mm_bridge_2_s0_readdata(mm_bridge_2_s0_readdata),               //                               .readdata
    		.mm_bridge_2_s0_readdatavalid(mm_bridge_2_s0_readdatavalid),          //                               .readdatavalid
    		.mm_bridge_2_s0_burstcount(1'b1),             //                               .burstcount
    		.mm_bridge_2_s0_writedata(mm_bridge_2_s0_writedata),              //                               .writedata
    		.mm_bridge_2_s0_address(mm_bridge_2_s0_address),                //                               .address
    		.mm_bridge_2_s0_write(mm_bridge_2_s0_write),                  //                               .write
    		.mm_bridge_2_s0_read(mm_bridge_2_s0_read),                   //                               .read
    		.mm_bridge_2_s0_byteenable(4'hf),             //                               .byteenable
    		.mm_bridge_2_s0_debugaccess(1'b0),            //                               .debugaccess

  4. #14
    Join Date
    Jun 2018
    Posts
    15
    Rep Power
    1

    Default Re: Data Transfer from FPGA-to-HPS

    Hi Eugene,

    Just a few questions on your code.

    On this section here:
    Code:
    if(!source_empty && !mm_bridge_2_s0_waitrequest)			begin
    			mm_bridge_2_s0_read<=1;
    			mm_bridge_2_s0_address<=fifo_read_offset|{5'b0,fifo_read_address};
    			fifo_read_address<=fifo_read_address+4;
    			source_empty<=...;
    			end
    		else if(!mm_bridge_2_s0_waitrequest)
    			mm_bridge_2_s0_read<=0;
    
    
    		if(mm_bridge_2_s0_readdatavalid && !core_full)
    			... <= mm_bridge_2_s0_readdata;
    		else
    			mm_bridge_2_s0_read<=0;
    I am pretty lost on what this read section here is for. I don't think I need to do any reads so for now I am commenting it out assuming that it is regarding some specific act you are trying to do. I'm not exactly sure. And I do not know what source_empty or core_full are either.

    I am pretty sure I understand the write section found here:
    Code:
    if(core_readdatavalid & !mm_bridge_0_s0_waitrequest)			begin
    			mm_bridge_0_s0_write<=1;
    			mm_bridge_0_s0_writedata <= data_input;
    			mm_bridge_0_s0_address<=fifo_write_offset|{5'b0,fifo_write_address};
    			fifo_write_address<=fifo_write_address+4;
    			end
    		else if(!mm_bridge_0_s0_waitrequest)
    			mm_bridge_0_s0_write<=0;
    Except I am not sure what core_readdatavalid is for, I'm assuming though that it would help if I understood what the read section before that is for?

    Given that I followed along with everything above correctly, I modified it into my module here:
    Code:
    module send_to_hps(data_input, mm_bridge_0_s0_waitrequest, mm_bridge_0_s0_writedata, mm_bridge_0_s0_address, mm_bridge_0_s0_write);
    
    	//Inputs
    	input [127:0] data_input;
    	input mm_bridge_0_s0_waitrequest;
    	
    	//Wires
    	//wire mm_bridge_0_s0_waitrequest;
    	//wire [127:0] mm_bridge_0_s0_readdata;
    	//wire        mm_bridge_0_s0_readdatavalid;
    	
    	//Outputs
    	output [127:0] mm_bridge_0_s0_writedata;
    	output mm_bridge_0_s0_write;
    	output [31:0]mm_bridge_0_s0_address;
    	
    	//Registers
    	reg [127:0] mm_bridge_0_s0_writedata=0;
    	reg [31:0] mm_bridge_0_s0_address=0;
    	reg mm_bridge_0_s0_write=0;
    	//reg mm_bridge_0_s0_read=0;
    
    
    	//reg[31:0] fifo_read_offset= 32'h20000000;
    	//reg[26:0] fifo_read_address=0;
    
    
    	reg[31:0] fifo_write_offset=32'h28000000;
    	reg[26:0] fifo_write_address=0;
    
    
    	/*if(!source_empty && !mm_bridge_2_s0_waitrequest)
    			begin
    			mm_bridge_2_s0_read<=1;
    			mm_bridge_2_s0_address<=fifo_read_offset|{5'b0,fifo_read_address};
    			fifo_read_address<=fifo_read_address+4;
    			source_empty<=...;
    			end
    		else if(!mm_bridge_2_s0_waitrequest)
    			mm_bridge_2_s0_read<=0;
    
    
    		if(mm_bridge_2_s0_readdatavalid && !core_full)
    			... <= mm_bridge_2_s0_readdata;
    		else
    			mm_bridge_2_s0_read<=0;*/
    	always @ (data_input)
    	begin
    		if(/*core_readdatavalid &&*/ !mm_bridge_0_s0_waitrequest)
    			begin
    			mm_bridge_0_s0_write<=1;
    			mm_bridge_0_s0_writedata <= data_input;
    			mm_bridge_0_s0_address<=fifo_write_offset|{5'b0,fifo_write_address};
    			fifo_write_address<=fifo_write_address+16;
    			end
    		else if(!mm_bridge_0_s0_waitrequest)
    			mm_bridge_0_s0_write<=0;
    	end
    
    
    endmodule
    The Inputs/Outputs to this module are all connected to the MM_Bridge for the HPS except for data_input. So I think that's correct.

    I have two final questions:

    One where did you come to the address 32'h28000000 to start writing at?

    And two would I then try to read from that address in Linux using the C code something like this:
    Code:
    char* toBinary(int value, int precision){	static char buf[20] = {0};
    	buf[precision+1] = 0;
      for(; value && precision ; --precision, value /= 2)	{
        buf[precision] = "01"[value % 2];		
      }
      for(; precision ; --precision){
        buf[precision] = '0';
      }
    	return &buf[precision+1];
    }
    
    
    int main(int argc, char *argv[]) {
        if (argc != 3) {
            printf("usage: %s <address> <#bytes>\n",argv[0]);
            return 0;
        }
        off_t offset = strtoul(argv[1], NULL, 0);
        size_t len = strtoul(argv[2], NULL, 0);
    
    
        // Truncate offset to a multiple of the page size, or mmap will fail.
        size_t pagesize = sysconf(_SC_PAGE_SIZE);
        off_t page_base = (offset / pagesize) * pagesize;
        off_t page_offset = offset - page_base;
    
    
        int fd = open("/dev/mem", O_SYNC);
        unsigned char *mem = mmap(NULL, page_offset + len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, page_base);
        if (mem == MAP_FAILED) {
            perror("Can't map memory");
            return -1;
        }
    
    
        size_t i;
        for (i = 0; i < len; i++){
            int temp = (int)mem[page_offset + i]; 
            printf("%s ",toBinary(temp,8));
            if((i + 1) % 16 == 0 && i != len - 1){
                printf("\n");
            }
        }
        printf("\n");
        for (i = 0; i < len; i++){
            int temp = (int)mem[page_offset + i]; 
            if(temp >= 32 && temp <= 126){
                printf("%c",temp);
            }else{
                printf("_");
            }
            if((i + 1) % 143 == 0 && i != len - 1){
                printf("\n");
            }
        }
        printf("\n");
        
        return 0;
    }
    Where address would be 28000000 and bytes in my case would be 16 for 128 bits?

  5. #15
    Join Date
    Jun 2018
    Posts
    28
    Rep Power
    1

    Default Re: Data Transfer from FPGA-to-HPS

    core_readdatavalid and core_full are signals from the part of my code that does the processing. source_empty signals the code to stop reading after a certain number of bytes has been read.

    I am confused by your "always @ (data_input)". Either I misunderstand what you're trying to do, or this is wrong (or both). It should be "always @(posedge clk)" where clk is the clock that is associated with mm_bridge_0_s0. If the write succeeds (you come into the block, you have data to write, and mm_bridge_0_s0_waitrequest is low), you do whatever has to be done to replace data_input with the next value to write.

    I use the entire top 512M for transferring data in and out. 2000_0000 to 2800_0000 is input buffer (written by the HPS and read by the FPGA) and 2800_0000 onwards is the output buffer (written by the FPGA and read by the HPS).

    Yes, the resulting data should be visible to a code like that at address 2800_0000.

  6. #16
    Join Date
    Jun 2018
    Posts
    15
    Rep Power
    1

    Default Re: Data Transfer from FPGA-to-HPS

    Quote Originally Posted by eugenek View Post
    core_readdatavalid and core_full are signals from the part of my code that does the processing. source_empty signals the code to stop reading after a certain number of bytes has been read.

    I am confused by your "always @ (data_input)". Either I misunderstand what you're trying to do, or this is wrong (or both). It should be "always @(posedge clk)" where clk is the clock that is associated with mm_bridge_0_s0. If the write succeeds (you come into the block, you have data to write, and mm_bridge_0_s0_waitrequest is low), you do whatever has to be done to replace data_input with the next value to write.

    I use the entire top 512M for transferring data in and out. 2000_0000 to 2800_0000 is input buffer (written by the HPS and read by the FPGA) and 2800_0000 onwards is the output buffer (written by the FPGA and read by the HPS).

    Yes, the resulting data should be visible to a code like that at address 2800_0000.
    What I am trying to do is send the data every time I get new data, aka every time it changes. The overall idea of how this project will work, or what I need it to do:

    1) I get some data over FPGA GPIO.
    2) The FPGA does some formatting with the data.
    3) As soon as the its ready, it sends it to the HPS DDR memory.
    4) Once the FPGA has written an entire packet, interrupts the HPS to let it know its ready.
    5) HPS reads it and sends it out over the network.

    So my idea was everytime data_input changes it would launch the write block. But maybe like you said I should change the always to @(posedge clk) and then check inside that block if the data_input changed AND if the waitrequest is low? I'll edit this post once I work on that, hopefully that always block is what is causing my issue. Because I still wasn't able to see anything at that 2800_0000 address. What I don't want happening is the system to write data multiple times. So, if no new data has been sent, the block still executes on the clock cycle and writes a single data point twice.

    Maybe always@(posedge clk AND data_input) would work? I'm going to try and run some tests but its hard since I cant even get anything to write to the DDR right now.
    Last edited by andrew44; Today at 05:49 AM.

Similar Threads

  1. Data Transfer from PC to FPGA
    By jaribro in forum FPGA, Hardcopy, and CPLD Discussion
    Replies: 4
    Last Post: July 25th, 2017, 07:25 AM
  2. Replies: 4
    Last Post: October 20th, 2014, 01:33 AM
  3. data transfer from fpga to hps
    By anand4mrtpl in forum Development Kit Related
    Replies: 3
    Last Post: November 18th, 2013, 10:44 AM
  4. Need to Transfer Data Between FPGA and PC
    By notooth in forum General Altera Discussion
    Replies: 1
    Last Post: January 21st, 2012, 06:30 AM
  5. how to use the USB transfer data to FPGA
    By silentyx in forum FPGA, Hardcopy, and CPLD Discussion
    Replies: 2
    Last Post: May 29th, 2011, 04:33 PM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •