FAILED Processor-FPGA Communication: Using FIFO FPGA Part ============================================================= Warning -------------- The approach used in this part, using FIFO provided by Platform Designer(Qsys), has failed due to the lack of proper example from Altera. I will use FIFO component from Quartus Library instead. Please read Processor-FPGA Communication: Using FIFO FPGA Part instead. Credit ------------ - This section is **Modified From** `DE1 SoC ARM HPS and FPGA Addresses and Communication Cornell ece5760`_ .. _DE1 SoC ARM HPS and FPGA Addresses and Communication Cornell ece5760: https://people.ece.cornell.edu/land/courses/ece5760/DE1_SOC/HPS_peripherials/FPGA_addr_index.html :Date: 20 Aug 2019 Dependency ------------- This part uses parameters in Cornell ECE5760 ------------------------------------------------ **Step 1** We will use **Platform Designer** to generate two **FIFOs**, **HPS to FPGA FIFO** and **FPGA to HPS FIFO** .. figure:: imgs/Stage-2_ECE5760_Qsys_FIFO.webp - For **HPS to FPGA FIFO**, its **Output** will be **Exported** and will be connected to the Top-Level module **DE1_SoC_Computer**, please refer to `DE1_SoC_Computer verilog file`_ (**line 515**). .. code-block:: verilog // HPS to FPGA FIFO .fifo_hps_to_fpga_out_readdata (hps_to_fpga_readdata), // fifo_hps_to_fpga_out.readdata .fifo_hps_to_fpga_out_read (hps_to_fpga_read), // out.read .fifo_hps_to_fpga_out_waitrequest (), // out.waitrequest .fifo_hps_to_fpga_out_csr_address (32'd1), //(hps_to_fpga_out_csr_address), // fifo_hps_to_fpga_out_csr.address .fifo_hps_to_fpga_out_csr_read (1'b1), //(hps_to_fpga_out_csr_read), // csr.read .fifo_hps_to_fpga_out_csr_writedata (), // csr.writedata .fifo_hps_to_fpga_out_csr_write (1'b0), // csr.write .fifo_hps_to_fpga_out_csr_readdata (hps_to_fpga_out_csr_readdata), // csr.readdata - To use this **Output** of **HPS to FPGA FIFO**, we must write by ourselves a **State Machine** to handle **Reading Data From HPS**, please refer to `DE1_SoC_Computer verilog file`_ (**line 440**). Specifically, HPS to FPGA FIFO **Reader** state machine waits for data in the FIFO, then reads the data into a buffer and **sets a ready flag**. The **csr-register** used to wait is the **status register**, so that only bit 0 (full) and bit 1 (empty) are read .. code-block:: verilog //================================= // HPS_to_FPGA state machine //================================== // Is there data in HPS_to_FPGA FIFO ? // And the last transfer is complete ? if (HPS_to_FPGA_state == 8'd0 && !(hps_to_fpga_out_csr_readdata[1]) && !data_buffer_valid) begin hps_to_fpga_read <= 1'b1 ; HPS_to_FPGA_state <= 8'd2 ; // end // delay if (HPS_to_FPGA_state == 8'd2) begin // zero the read request BEFORE the data appears // in the next state! hps_to_fpga_read <= 1'b0 ; HPS_to_FPGA_state <= 8'd4 ; end // read the word from the FIFO if (HPS_to_FPGA_state == 8'd4) begin data_buffer <= hps_to_fpga_readdata ; // send back data data_buffer_valid <= 1'b1 ; // set the data ready flag hps_to_fpga_read <= 1'b0 ; HPS_to_FPGA_state <= 8'd0 ; //6 end - For **FPGA to HPS FIFO**, its **Input** will be **Exported** and will be connected to the Top-Level module **DE1_SoC_Computer**, please refer to `DE1_SoC_Computer verilog file`_ (**line 525**). .. code-block:: verilog // FPGA to HPS FIFO .fifo_fpga_to_hps_in_writedata (fpga_to_hps_in_writedata), // fifo_fpga_to_hps_in.writedata .fifo_fpga_to_hps_in_write (fpga_to_hps_in_write), // .write .fifo_fpga_to_hps_in_csr_address (32'd1), //(fpga_to_hps_in_csr_address), // fifo_fpga_to_hps_in_csr.address .fifo_fpga_to_hps_in_csr_read (1'b1), //(fpga_to_hps_in_csr_read), // .read .fifo_fpga_to_hps_in_csr_writedata (), // .writedata .fifo_fpga_to_hps_in_csr_write (1'b0), // .write .fifo_fpga_to_hps_in_csr_readdata (fpga_to_hps_in_csr_readdata), // - To use this **Input** of **FPGA to HPS FIFO**, we must write by ourselves a **State Machine** to handle **Writing Data To HPS**, please refer to `DE1_SoC_Computer verilog file`_ (**line 466**). Specifically, FPGA to HPS FIFO **Writer** state machine waits for space in the **FPGA to HPS FIFO** then writes the data to the FIFO and **clears the ready flag** .. code-block:: verilog //================================= // FPGA_to_HPS state machine //================================== // Is there space in the FPGA_to_HPS FIFO ? // And data is available ? if (FPGA_to_HPS_state==0 && !(fpga_to_hps_in_csr_readdata[0]) && data_buffer_valid) begin fpga_to_hps_in_writedata <= data_buffer ; fpga_to_hps_in_write <= 1'b1 ; FPGA_to_HPS_state <= 8'd4 ; end // finish the write to FPGA_to_HPS FIFO //if (HPS_to_FPGA_state == 8'd8) begin if (FPGA_to_HPS_state==4) begin fpga_to_hps_in_write <= 1'b0 ; data_buffer_valid <= 1'b0 ; // used the data, so clear flag FPGA_to_HPS_state <= 8'd0 ; end .. _DE1_SoC_Computer verilog file: https://github.com/tesla-cat/Works-Done-In-Dzmitry-s-Lab-At-CQT/blob/master/Cyclone%20V%20SoC%20Control%20System/Quartus%20Project%20Stage%202/Cornell%20ECE5760/Top%20Level%20Entity%20for%20FPGA/DE1_SoC_Computer.v#L515 **Step 2** FIFO Settings - Note that **Allow Backpressure** should be **off** .. figure:: imgs/Stage-2_ECE5760_Qsys_FIFO_Settings.webp **Step 3** Some Remarks - Timing for the FIFO read/write is not specified in the users manual! The HPS-to-FPGA read operation takes TWO cycles but the read-enable line **can only be held high for ONE cycle**, Holding it high for two cycles results in two reads. - The HPS program asks the user for the number of items to send (0