Processor-FPGA Communication: Using FIFO FPGA Part ============================================================= :Date: 20 Sep 2019 What is the idea? ------------------------ - Your custom module, for example a counter, wants to send data to HPS (processor) - FIFO is a buffer, it buffers data until the processor has time to read it What are we gonna do? -------------------------- - We will write a simple counter in the **FPGA Part**, the counter increases :math:`1` every :code:`clk` cycle - This counter makes a write request every :math:`2^{24}` :code:`clk` cycle to the FIFO, and writes the counter value to the FIFO - To FIFO read port is connected to 3 PIOs generated by Platform Designer(Qsys), these 3 PIOs can be directly accessed by the Processor via memory mapping, since this memory is shared by the FPGA and Processor - Meanwhile, the 8 LEDs on the DE10-NANO board are connected to :code:`usedw` (**used words**) which indicates the number of data stored in the FIFO - We will write a simple reader in the **Processor Part** - User execute the compiled C code in the terminal, then they type in number of data to read - They will see read data printed to the terminal, as well as the decrease in number indicated by the LED How FIFO works ------------------ The following IO definition corresponds to FIFO modules generated by Quartus library - Each data in FIFO is called a "word", the number of words currently in FIFO is :code:`usedw` (**used words**) - Writing to a FIFO: make :code:`wrreq` (**write request**) HIGH for one :code:`clk` cycle, then whatever is at input :code:`data` gets written to the FIFO - Reading from the FIFO: make :code:`rdreq` (**read request**) HIGH for one :code:`clk` cycle, then the old value of :code:`q` (**queue**) gets cleared :code:`q` has a new value - Don't write to FIFO when :code:`full` is HIGH. Don't read from FIFO when :code:`empty` is HIGH - If :code:`wrreq` is HIGH for 5 :code:`clk` cycles, 5 data get written into the FIFO, If :code:`rdreq` is HIGH for 5 :code:`clk` cycles, 5 data get cleared from the FIFO. That is why usually you don't want these signals to be HIGH for more than 1 :code:`clk` cycle .. code-block:: verilog // The following shows signal flow, "<--->" represents wires, <===> represents memory-map // MyModule <---> FIFO Module <---> PIOs in Qsys generated Module(DE10_NANO_SoC_GHRD) <===> HPS /* FIFO module description input clock; // Write side by FPGA input wrreq; // write request input [31:0] data; // data to write output full; // Read side by HPS, more accurately, // Parallel IO(PIO) from Qsys generated Module // We need two 32 bits PIOs: // 1. PIO_FifoReadDataQueue: maps to q // 2. PIO_FifoReadControl: maps to rdreq,empty input rdreq; // read request output [31:0] q; // data queue to read output empty; // Fill level, number of "used words" in the queue output [7:0] usedw; // number of used words */ Use the FIFO library in quartus ---------------------------------- - Find and create a FIFO module from the library .. figure:: imgs/Stage-3_FIFOlibrary1.webp - Setup the module details .. figure:: imgs/Stage-3_FIFOlibrary2.webp - Then these files will be generated .. figure:: imgs/Stage-3_FIFOlibrary3.webp - Include :code:`FIFO.qip` file into your project .. figure:: imgs/Stage-3_FIFOlibrary4.webp Create PIO in Platform Designer ------------------------------------------------ **Create PIO (Parallel IO) in Platform Designer (Qsys) to connect to FIFO module** - Search PIO .. figure:: imgs/Stage-3_PIOqsys1.webp - Create the necessary connections .. figure:: imgs/Stage-3_PIOqsys2.webp - Download the following Qsys file to see the details Modify the Standard :code:`DE10_NANO_SoC_GHRD.v` --------------------------------------------------- - create wires that are use to connect different modules in Verilog .. code-block:: verilog // Wires to connect Custom Sub-Modules: // Write side by FPGA wire wire_FIFOwriteRequest; wire [31:0] wire_FIFOwriteData; wire wire_FIFOwriteFull; // Read side by HPS, more accurately, // Parallel IO(PIO) from Qsys generated Module(DE10_NANO_SoC_GHRD) wire wire_FIFOreadRequest; wire wire_FIFOreadRequestShortPulse; ToShortPulse toShortPulse_FIFOreadRequest( .clk(fpga_clk_50), .longPulse(wire_FIFOreadRequest), .shortPulse(wire_FIFOreadRequestShortPulse), ); wire [31:0] wire_FIFOreadDataQueue; wire wire_FIFOreadEmpty; wire [7:0] wire_FIFOnumberOfUsedWords; assign LED = wire_FIFOnumberOfUsedWords; - Connect the **module** generated by Platform Designer (:code:`soc_system`) to the wires .. code-block:: verilog //======================================================= // Structural coding //======================================================= soc_system u0( // other default connections... //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO // Begin Code added by me Part 1: IO Mapping // FIFO .fiforeadrequest_external_connection_export(wire_FIFOreadRequest), //output (to FPGA) PIO .fiforeaddataqueue_external_connection_export(wire_FIFOreadDataQueue), //input (to HPS) PIO .fiforeadempty_external_connection_export(wire_FIFOreadEmpty), //input (to HPS) PIO // End Code added by me Part 1: IO Mapping //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ); - Connect the FIFO to the wires .. code-block:: verilog FIFO fifo( .clock(fpga_clk_50), // Write side by FPGA .wrreq(wire_FIFOwriteRequest), .data(wire_FIFOwriteData), .full(wire_FIFOwriteFull), // Read side by HPS, more accurately, // Parallel IO(PIO) from Qsys generated Module .rdreq(wire_FIFOreadRequestShortPulse), .q(wire_FIFOreadDataQueue), .empty(wire_FIFOreadEmpty), .usedw(wire_FIFOnumberOfUsedWords), ); - Connect MyModule (defined later) to the wires .. code-block:: verilog MyModule myModule( .clk(fpga_clk_50), .FIFOwriteRequest(wire_FIFOwriteRequest), .FIFOwriteData(wire_FIFOwriteData), .FIFOwriteFull(wire_FIFOwriteFull), ); - defined MyModule and module ToShortPulse .. code-block:: verilog //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO // Begin Code added by me Part 3: MyModule module MyModule( input clk, output FIFOwriteRequest, output reg [31:0] FIFOwriteData, input FIFOwriteFull ); ToShortPulse toShortPulse_FIFOwriteRequest( .clk(clk), .longPulse(FIFOwriteData[24] & ~FIFOwriteFull), .shortPulse(FIFOwriteRequest), ); always @(posedge clk) begin FIFOwriteData <= FIFOwriteData+1; end endmodule // Module to make longPulse into shortPulse module ToShortPulse( input clk, input longPulse, output reg shortPulse ); reg last_longPulse; always @ (posedge clk) begin shortPulse <= (last_longPulse==0 && longPulse==1)?1:0; last_longPulse <= longPulse; end endmodule // End Code added by me Part 3: MyModule //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO The full code -------------------------- .. code-block:: verilog //======================================================= // This code is generated by Terasic System Builder //======================================================= module DE10_NANO_SoC_GHRD( //////////// CLOCK ////////// input FPGA_CLK1_50, input FPGA_CLK2_50, input FPGA_CLK3_50, //////////// HDMI ////////// inout HDMI_I2C_SCL, inout HDMI_I2C_SDA, inout HDMI_I2S, inout HDMI_LRCLK, inout HDMI_MCLK, inout HDMI_SCLK, output HDMI_TX_CLK, output [23: 0] HDMI_TX_D, output HDMI_TX_DE, output HDMI_TX_HS, input HDMI_TX_INT, output HDMI_TX_VS, //////////// HPS ////////// inout HPS_CONV_USB_N, output [14: 0] HPS_DDR3_ADDR, output [ 2: 0] HPS_DDR3_BA, output HPS_DDR3_CAS_N, output HPS_DDR3_CK_N, output HPS_DDR3_CK_P, output HPS_DDR3_CKE, output HPS_DDR3_CS_N, output [ 3: 0] HPS_DDR3_DM, inout [31: 0] HPS_DDR3_DQ, inout [ 3: 0] HPS_DDR3_DQS_N, inout [ 3: 0] HPS_DDR3_DQS_P, output HPS_DDR3_ODT, output HPS_DDR3_RAS_N, output HPS_DDR3_RESET_N, input HPS_DDR3_RZQ, output HPS_DDR3_WE_N, output HPS_ENET_GTX_CLK, inout HPS_ENET_INT_N, output HPS_ENET_MDC, inout HPS_ENET_MDIO, input HPS_ENET_RX_CLK, input [ 3: 0] HPS_ENET_RX_DATA, input HPS_ENET_RX_DV, output [ 3: 0] HPS_ENET_TX_DATA, output HPS_ENET_TX_EN, inout HPS_GSENSOR_INT, inout HPS_I2C0_SCLK, inout HPS_I2C0_SDAT, inout HPS_I2C1_SCLK, inout HPS_I2C1_SDAT, inout HPS_KEY, inout HPS_LED, inout HPS_LTC_GPIO, output HPS_SD_CLK, inout HPS_SD_CMD, inout [ 3: 0] HPS_SD_DATA, output HPS_SPIM_CLK, input HPS_SPIM_MISO, output HPS_SPIM_MOSI, inout HPS_SPIM_SS, input HPS_UART_RX, output HPS_UART_TX, input HPS_USB_CLKOUT, inout [ 7: 0] HPS_USB_DATA, input HPS_USB_DIR, input HPS_USB_NXT, output HPS_USB_STP, //////////// KEY ////////// input [ 1: 0] KEY, //////////// LED ////////// output [ 7: 0] LED, //////////// SW ////////// input [ 3: 0] SW ); //======================================================= // REG/WIRE declarations //======================================================= wire hps_fpga_reset_n; wire [1: 0] fpga_debounced_buttons; wire [6: 0] fpga_led_internal; wire [2: 0] hps_reset_req; wire hps_cold_reset; wire hps_warm_reset; wire hps_debug_reset; wire [27: 0] stm_hw_events; wire fpga_clk_50; // connection of internal logics //assign LED[7: 1] = fpga_led_internal; assign fpga_clk_50 = FPGA_CLK1_50; assign stm_hw_events = {{15{1'b0}}, SW, fpga_led_internal, fpga_debounced_buttons}; //======================================================= // Structural coding //======================================================= soc_system u0( //Clock&Reset .clk_clk(FPGA_CLK1_50), // clk.clk .reset_reset_n(hps_fpga_reset_n), // reset.reset_n //HPS ddr3 .memory_mem_a(HPS_DDR3_ADDR), // memory.mem_a .memory_mem_ba(HPS_DDR3_BA), // .mem_ba .memory_mem_ck(HPS_DDR3_CK_P), // .mem_ck .memory_mem_ck_n(HPS_DDR3_CK_N), // .mem_ck_n .memory_mem_cke(HPS_DDR3_CKE), // .mem_cke .memory_mem_cs_n(HPS_DDR3_CS_N), // .mem_cs_n .memory_mem_ras_n(HPS_DDR3_RAS_N), // .mem_ras_n .memory_mem_cas_n(HPS_DDR3_CAS_N), // .mem_cas_n .memory_mem_we_n(HPS_DDR3_WE_N), // .mem_we_n .memory_mem_reset_n(HPS_DDR3_RESET_N), // .mem_reset_n .memory_mem_dq(HPS_DDR3_DQ), // .mem_dq .memory_mem_dqs(HPS_DDR3_DQS_P), // .mem_dqs .memory_mem_dqs_n(HPS_DDR3_DQS_N), // .mem_dqs_n .memory_mem_odt(HPS_DDR3_ODT), // .mem_odt .memory_mem_dm(HPS_DDR3_DM), // .mem_dm .memory_oct_rzqin(HPS_DDR3_RZQ), // .oct_rzqin //HPS ethernet .hps_0_hps_io_hps_io_emac1_inst_TX_CLK(HPS_ENET_GTX_CLK), // hps_0_hps_io.hps_io_emac1_inst_TX_CLK .hps_0_hps_io_hps_io_emac1_inst_TXD0(HPS_ENET_TX_DATA[0]), // .hps_io_emac1_inst_TXD0 .hps_0_hps_io_hps_io_emac1_inst_TXD1(HPS_ENET_TX_DATA[1]), // .hps_io_emac1_inst_TXD1 .hps_0_hps_io_hps_io_emac1_inst_TXD2(HPS_ENET_TX_DATA[2]), // .hps_io_emac1_inst_TXD2 .hps_0_hps_io_hps_io_emac1_inst_TXD3(HPS_ENET_TX_DATA[3]), // .hps_io_emac1_inst_TXD3 .hps_0_hps_io_hps_io_emac1_inst_RXD0(HPS_ENET_RX_DATA[0]), // .hps_io_emac1_inst_RXD0 .hps_0_hps_io_hps_io_emac1_inst_MDIO(HPS_ENET_MDIO), // .hps_io_emac1_inst_MDIO .hps_0_hps_io_hps_io_emac1_inst_MDC(HPS_ENET_MDC), // .hps_io_emac1_inst_MDC .hps_0_hps_io_hps_io_emac1_inst_RX_CTL(HPS_ENET_RX_DV), // .hps_io_emac1_inst_RX_CTL .hps_0_hps_io_hps_io_emac1_inst_TX_CTL(HPS_ENET_TX_EN), // .hps_io_emac1_inst_TX_CTL .hps_0_hps_io_hps_io_emac1_inst_RX_CLK(HPS_ENET_RX_CLK), // .hps_io_emac1_inst_RX_CLK .hps_0_hps_io_hps_io_emac1_inst_RXD1(HPS_ENET_RX_DATA[1]), // .hps_io_emac1_inst_RXD1 .hps_0_hps_io_hps_io_emac1_inst_RXD2(HPS_ENET_RX_DATA[2]), // .hps_io_emac1_inst_RXD2 .hps_0_hps_io_hps_io_emac1_inst_RXD3(HPS_ENET_RX_DATA[3]), // .hps_io_emac1_inst_RXD3 //HPS SD card .hps_0_hps_io_hps_io_sdio_inst_CMD(HPS_SD_CMD), // .hps_io_sdio_inst_CMD .hps_0_hps_io_hps_io_sdio_inst_D0(HPS_SD_DATA[0]), // .hps_io_sdio_inst_D0 .hps_0_hps_io_hps_io_sdio_inst_D1(HPS_SD_DATA[1]), // .hps_io_sdio_inst_D1 .hps_0_hps_io_hps_io_sdio_inst_CLK(HPS_SD_CLK), // .hps_io_sdio_inst_CLK .hps_0_hps_io_hps_io_sdio_inst_D2(HPS_SD_DATA[2]), // .hps_io_sdio_inst_D2 .hps_0_hps_io_hps_io_sdio_inst_D3(HPS_SD_DATA[3]), // .hps_io_sdio_inst_D3 //HPS USB .hps_0_hps_io_hps_io_usb1_inst_D0(HPS_USB_DATA[0]), // .hps_io_usb1_inst_D0 .hps_0_hps_io_hps_io_usb1_inst_D1(HPS_USB_DATA[1]), // .hps_io_usb1_inst_D1 .hps_0_hps_io_hps_io_usb1_inst_D2(HPS_USB_DATA[2]), // .hps_io_usb1_inst_D2 .hps_0_hps_io_hps_io_usb1_inst_D3(HPS_USB_DATA[3]), // .hps_io_usb1_inst_D3 .hps_0_hps_io_hps_io_usb1_inst_D4(HPS_USB_DATA[4]), // .hps_io_usb1_inst_D4 .hps_0_hps_io_hps_io_usb1_inst_D5(HPS_USB_DATA[5]), // .hps_io_usb1_inst_D5 .hps_0_hps_io_hps_io_usb1_inst_D6(HPS_USB_DATA[6]), // .hps_io_usb1_inst_D6 .hps_0_hps_io_hps_io_usb1_inst_D7(HPS_USB_DATA[7]), // .hps_io_usb1_inst_D7 .hps_0_hps_io_hps_io_usb1_inst_CLK(HPS_USB_CLKOUT), // .hps_io_usb1_inst_CLK .hps_0_hps_io_hps_io_usb1_inst_STP(HPS_USB_STP), // .hps_io_usb1_inst_STP .hps_0_hps_io_hps_io_usb1_inst_DIR(HPS_USB_DIR), // .hps_io_usb1_inst_DIR .hps_0_hps_io_hps_io_usb1_inst_NXT(HPS_USB_NXT), // .hps_io_usb1_inst_NXT //HPS SPI .hps_0_hps_io_hps_io_spim1_inst_CLK(HPS_SPIM_CLK), // .hps_io_spim1_inst_CLK .hps_0_hps_io_hps_io_spim1_inst_MOSI(HPS_SPIM_MOSI), // .hps_io_spim1_inst_MOSI .hps_0_hps_io_hps_io_spim1_inst_MISO(HPS_SPIM_MISO), // .hps_io_spim1_inst_MISO .hps_0_hps_io_hps_io_spim1_inst_SS0(HPS_SPIM_SS), // .hps_io_spim1_inst_SS0 //HPS UART .hps_0_hps_io_hps_io_uart0_inst_RX(HPS_UART_RX), // .hps_io_uart0_inst_RX .hps_0_hps_io_hps_io_uart0_inst_TX(HPS_UART_TX), // .hps_io_uart0_inst_TX //HPS I2C1 .hps_0_hps_io_hps_io_i2c0_inst_SDA(HPS_I2C0_SDAT), // .hps_io_i2c0_inst_SDA .hps_0_hps_io_hps_io_i2c0_inst_SCL(HPS_I2C0_SCLK), // .hps_io_i2c0_inst_SCL //HPS I2C2 .hps_0_hps_io_hps_io_i2c1_inst_SDA(HPS_I2C1_SDAT), // .hps_io_i2c1_inst_SDA .hps_0_hps_io_hps_io_i2c1_inst_SCL(HPS_I2C1_SCLK), // .hps_io_i2c1_inst_SCL //GPIO .hps_0_hps_io_hps_io_gpio_inst_GPIO09(HPS_CONV_USB_N), // .hps_io_gpio_inst_GPIO09 .hps_0_hps_io_hps_io_gpio_inst_GPIO35(HPS_ENET_INT_N), // .hps_io_gpio_inst_GPIO35 .hps_0_hps_io_hps_io_gpio_inst_GPIO40(HPS_LTC_GPIO), // .hps_io_gpio_inst_GPIO40 .hps_0_hps_io_hps_io_gpio_inst_GPIO53(HPS_LED), // .hps_io_gpio_inst_GPIO53 .hps_0_hps_io_hps_io_gpio_inst_GPIO54(HPS_KEY), // .hps_io_gpio_inst_GPIO54 .hps_0_hps_io_hps_io_gpio_inst_GPIO61(HPS_GSENSOR_INT), // .hps_io_gpio_inst_GPIO61 //FPGA Partion .led_pio_external_connection_export(fpga_led_internal), // led_pio_external_connection.export .dipsw_pio_external_connection_export(SW), // dipsw_pio_external_connection.export .button_pio_external_connection_export(fpga_debounced_buttons), // button_pio_external_connection.export .hps_0_h2f_reset_reset_n(hps_fpga_reset_n), // hps_0_h2f_reset.reset_n .hps_0_f2h_cold_reset_req_reset_n(~hps_cold_reset), // hps_0_f2h_cold_reset_req.reset_n .hps_0_f2h_debug_reset_req_reset_n(~hps_debug_reset), // hps_0_f2h_debug_reset_req.reset_n .hps_0_f2h_stm_hw_events_stm_hwevents(stm_hw_events), // hps_0_f2h_stm_hw_events.stm_hwevents .hps_0_f2h_warm_reset_req_reset_n(~hps_warm_reset), // hps_0_f2h_warm_reset_req.reset_n //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO // Begin Code added by me Part 1: IO Mapping // FIFO .fiforeadrequest_external_connection_export(wire_FIFOreadRequest), //output (to FPGA) PIO .fiforeaddataqueue_external_connection_export(wire_FIFOreadDataQueue), //input (to HPS) PIO .fiforeadempty_external_connection_export(wire_FIFOreadEmpty), //input (to HPS) PIO // End Code added by me Part 1: IO Mapping //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ); // Debounce logic to clean out glitches within 1ms debounce debounce_inst( .clk(fpga_clk_50), .reset_n(hps_fpga_reset_n), .data_in(KEY), .data_out(fpga_debounced_buttons) ); defparam debounce_inst.WIDTH = 2; defparam debounce_inst.POLARITY = "LOW"; defparam debounce_inst.TIMEOUT = 50000; // at 50Mhz this is a debounce time of 1ms defparam debounce_inst.TIMEOUT_WIDTH = 16; // ceil(log2(TIMEOUT)) // Source/Probe megawizard instance hps_reset hps_reset_inst( .source_clk(fpga_clk_50), .source(hps_reset_req) ); altera_edge_detector pulse_cold_reset( .clk(fpga_clk_50), .rst_n(hps_fpga_reset_n), .signal_in(hps_reset_req[0]), .pulse_out(hps_cold_reset) ); defparam pulse_cold_reset.PULSE_EXT = 6; defparam pulse_cold_reset.EDGE_TYPE = 1; defparam pulse_cold_reset.IGNORE_RST_WHILE_BUSY = 1; altera_edge_detector pulse_warm_reset( .clk(fpga_clk_50), .rst_n(hps_fpga_reset_n), .signal_in(hps_reset_req[1]), .pulse_out(hps_warm_reset) ); defparam pulse_warm_reset.PULSE_EXT = 2; defparam pulse_warm_reset.EDGE_TYPE = 1; defparam pulse_warm_reset.IGNORE_RST_WHILE_BUSY = 1; altera_edge_detector pulse_debug_reset( .clk(fpga_clk_50), .rst_n(hps_fpga_reset_n), .signal_in(hps_reset_req[2]), .pulse_out(hps_debug_reset) ); defparam pulse_debug_reset.PULSE_EXT = 32; defparam pulse_debug_reset.EDGE_TYPE = 1; defparam pulse_debug_reset.IGNORE_RST_WHILE_BUSY = 1; reg [25: 0] counter; reg led_level; always @(posedge fpga_clk_50 or negedge hps_fpga_reset_n) begin if (~hps_fpga_reset_n) begin counter <= 0; led_level <= 0; end else if (counter == 24999999) begin counter <= 0; led_level <= ~led_level; end else counter <= counter + 1'b1; end //assign LED[0] = led_level; //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO // Begin Code added by me Part 2: // The following shows signal flow, "<--->" represents wires, <===> represents memory-map // MyModule <---> FIFO Module <---> PIOs in Qsys generated Module(DE10_NANO_SoC_GHRD) <===> HPS /* FIFO module description input clock; // Write side by FPGA input wrreq; // write request input [31:0] data; // data to write output full; // Read side by HPS, more accurately, // Parallel IO(PIO) from Qsys generated Module // We need two 32 bits PIOs: // 1. PIO_FifoReadDataQueue: maps to q // 2. PIO_FifoReadControl: maps to rdreq,empty input rdreq; // read request output [31:0] q; // data queue to read output empty; // Fill level, number of "used words" in the queue output [7:0] usedw; // number of used words */ // Wires to connect Custom Sub-Modules: // Write side by FPGA wire wire_FIFOwriteRequest; wire [31:0] wire_FIFOwriteData; wire wire_FIFOwriteFull; // Read side by HPS, more accurately, // Parallel IO(PIO) from Qsys generated Module(DE10_NANO_SoC_GHRD) wire wire_FIFOreadRequest; wire wire_FIFOreadRequestShortPulse; ToShortPulse toShortPulse_FIFOreadRequest( .clk(fpga_clk_50), .longPulse(wire_FIFOreadRequest), .shortPulse(wire_FIFOreadRequestShortPulse), ); wire [31:0] wire_FIFOreadDataQueue; wire wire_FIFOreadEmpty; wire [7:0] wire_FIFOnumberOfUsedWords; assign LED = wire_FIFOnumberOfUsedWords; // Custom Sub-Modules: FIFO fifo( .clock(fpga_clk_50), // Write side by FPGA .wrreq(wire_FIFOwriteRequest), .data(wire_FIFOwriteData), .full(wire_FIFOwriteFull), // Read side by HPS, more accurately, // Parallel IO(PIO) from Qsys generated Module .rdreq(wire_FIFOreadRequestShortPulse), .q(wire_FIFOreadDataQueue), .empty(wire_FIFOreadEmpty), .usedw(wire_FIFOnumberOfUsedWords), ); MyModule myModule( .clk(fpga_clk_50), .FIFOwriteRequest(wire_FIFOwriteRequest), .FIFOwriteData(wire_FIFOwriteData), .FIFOwriteFull(wire_FIFOwriteFull), ); /* In the IO mapping at the beginning of this file soc_system u0( ... .fiforeadrequest_external_connection_export(wire_FIFOreadRequest), //output (to FPGA) PIO .fiforeaddataqueue_external_connection_export(wire_FIFOreadDataQueue), //input (to HPS) PIO .fiforeadempty_external_connection_export(wire_FIFOreadEmpty), //input (to HPS) PIO ... ); */ // End Code added by me Part 2 //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO endmodule //=========================================================== //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO // Begin Code added by me Part 3: MyModule module MyModule( input clk, output FIFOwriteRequest, output reg [31:0] FIFOwriteData, input FIFOwriteFull ); ToShortPulse toShortPulse_FIFOwriteRequest( .clk(clk), .longPulse(FIFOwriteData[24] & ~FIFOwriteFull), .shortPulse(FIFOwriteRequest), ); always @(posedge clk) begin FIFOwriteData <= FIFOwriteData+1; end endmodule // Module to make longPulse into shortPulse module ToShortPulse( input clk, input longPulse, output reg shortPulse ); reg last_longPulse; always @ (posedge clk) begin shortPulse <= (last_longPulse==0 && longPulse==1)?1:0; last_longPulse <= longPulse; end endmodule // End Code added by me Part 3: MyModule //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO