Visible to Intel only — GUID: xgp1588717865492
Ixiasoft
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:
- Create IOPLL in using IP Catalog and set PLL to desired settings.
- Instantiate PLL in hello_afu with ccip_async_shim to perform clock boundary crossing.
- Edit ccip_std_afu.sv to connect G_CLK100 to AFU.
- 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.