Accelerator Functional Unit Developer Guide: Intel FPGA Programmable Acceleration Card N3000 Variants

ID 683190
Date 7/15/2022
Public

Visible to Intel only — GUID: xgp1588717865492

Ixiasoft

Document Table of Contents

4.5.2.2. Hello AFU Example (pll)

A new PLL can be instantiated to provide additional clocks in your design. These steps are performed to add an Intel® Arria® 10 IOPLL to the hello_afu design:
  1. Create IOPLL in using IP Catalog and set PLL to desired settings.
  2. Instantiate PLL in hello_afu with ccip_async_shim to perform clock boundary crossing.
  3. Edit ccip_std_afu.sv to connect G_CLK100 to AFU.
  4. Update the *.qsf and *.sdc files.
The updated hello_afu module is listed below:
import ccip_if_pkg::*; module hello_afu_pll ( input pClk, // Core clock. CCI interface is synchronous to this clock. input pClk_reset, // CCI interface ACTIVE HIGH reset. input G_CLK100, //100 MHz Global clock for PLL // CCI-P signals input t_if_ccip_Rx pClk_cp2af_sRxPort, output t_if_ccip_Tx pClk_af2cp_sTxPort ); `define AFU_ACCEL_UUID 128'h850adcc2_6ceb_4b22_9722_d43375b61c66 // The AFU must respond with its AFU ID in response to MMIO reads of // the CCI-P device feature header (DFH). The AFU ID is a unique ID // for a given program. Here we generated one with the "uuidgen" // program and stored it in the AFU's JSON file. ASE and synthesis // setup scripts automatically invoke the OPAE afu_json_mgr script // to extract the UUID into afu_json_info.vh. logic [127:0] afu_id = `AFU_ACCEL_UUID; logic [63:0] scratch_reg; pll_50Mhz u0 ( .rst (pClk_reset), // input, width = 1, reset.reset .refclk (G_CLK100), // input, width = 1, refclk.clk .locked (), // output, width = 1, locked.export .outclk_0 (uClk_50) // output, width = 1, outclk0.clk ); //uClk_usr domain CCIP signals t_if_ccip_Tx af2cp_sTxPort; t_if_ccip_Rx cp2af_sRxPort; ccip_async_shim ccip_async_shim ( .bb_softreset (pClk_reset), .bb_clk (pClk), .bb_tx (pClk_af2cp_sTxPort), .bb_rx (pClk_cp2af_sRxPort), .afu_softreset (reset), .afu_clk (uClk_50), .afu_tx (af2cp_sTxPort), .afu_rx (cp2af_sRxPort) ); // The c0 header is normally used for memory read responses. // The header must be interpreted as an MMIO response when // c0 mmmioRdValid or mmioWrValid is set. In these cases the // c0 header is cast into a ReqMmioHdr. t_ccip_c0_ReqMmioHdr mmioHdr; assign mmioHdr = t_ccip_c0_ReqMmioHdr'(cp2af_sRxPort.c0.hdr); // // Receive MMIO writes // always_ff @(posedge uClk_50) begin if (reset) begin scratch_reg <= '0; end else begin // set the registers on MMIO write request // these are user-defined AFU registers at offset 0x40. if (cp2af_sRxPort.c0.mmioWrValid == 1) begin case (mmioHdr.address) 16'h0020: scratch_reg <= cp2af_sRxPort.c0.data[63:0]; endcase end end end // // Handle MMIO reads. // always_ff @(posedge uClk_50) begin if (reset) begin af2cp_sTxPort.c1.hdr <= '0; af2cp_sTxPort.c1.valid <= '0; af2cp_sTxPort.c0.hdr <= '0; af2cp_sTxPort.c0.valid <= '0; af2cp_sTxPort.c2.hdr <= '0; af2cp_sTxPort.c2.mmioRdValid <= '0; end else begin // Clear read response flag in case there was a response last cycle. af2cp_sTxPort.c2.mmioRdValid <= 0; // serve MMIO read requests if (cp2af_sRxPort.c0.mmioRdValid == 1'b1) begin // Copy TID, which the host needs to map the response to the request af2cp_sTxPort.c2.hdr.tid <= mmioHdr.tid; // Post response af2cp_sTxPort.c2.mmioRdValid <= 1; case (mmioHdr.address) // AFU header 16'h0000: af2cp_sTxPort.c2.data <= { 4'b0001, // Feature type = AFU 8'b0, // reserved 4'b0, // afu minor revision = 0 7'b0, // reserved 1'b1, // end of DFH list = 1 24'b0, // next DFH offset = 0 4'b0, // afu major revision = 0 12'b0 // feature ID = 0 }; // AFU_ID_L 16'h0002: af2cp_sTxPort.c2.data <= afu_id[63:0]; // AFU_ID_H 16'h0004: af2cp_sTxPort.c2.data <= afu_id[127:64]; // DFH_RSVD0 and DFH_RSVD1 16'h0006: af2cp_sTxPort.c2.data <= 64'h0; 16'h0008: af2cp_sTxPort.c2.data <= 64'h0; // Scratch Register. Return the last value written // to this MMIO address. 16'h0020: af2cp_sTxPort.c2.data <= scratch_reg; default: af2cp_sTxPort.c2.data <= 64'h0; endcase end end end endmodule
The afu.qsf is updated as shown below:
# CCI-P async shim source $AFU_SRC_ROOT/rtl/BBB_ccip_async/hw/par/ccip_async_addenda.qsf set_global_assignment -name IP_FILE $AFU_SRC_ROOT/rtl/pll/pll_50Mhz.ip set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to G_CLK100 -entity pac_top
Compile the design with make as shown below:
$ make 2x2x25G INCLUDE_DIAGNOSTICS=0 INCLUDE_MEMORY=0 INCLUDE_AFU_PCIE1=0 GUI=1
Note: You may need to modify the afu.sdc file based on the new clock added.