The Vitis Networking P4 Architecture definition file (xsa.p4) provides the following declaration:
extern UserExtern<I, O> {
UserExtern(bit<16> latency_in_cycles);
UserExtern(bit<16> latency_in_cycles, bit<16> pipe_capacity_in_cycles);
void apply(in I data_in, out O result);
}
- The declaration contains a method with the same name as the
declaration itself, such as a constructor.
- This method is used to instantiate the extern object in the P4 program.
- It is used to specify the hardware latency of the functionality implemented by the user extern. When a single argument is used in the declaration, the User extern is expected to be in 'fixed latency' mode, where the value specified is the fixed latency in clock cycles. When two arguments are used instead, the User Extern is expected to be in 'variable latency' mode, where the first argument is the minimum latency value in clock cycles and the second the maximum internal pipeline capacity in clock cycles. The user extern in variable latency mode must support back-pressure connected via a 'ready out' port found in the user extern interface. The user extern in variable latency mode can also produce back-pressure onto the VitisNetP4 instance via the 'ready in' port found in the user extern interface.
- The declaration contains a method named apply().
- This method is invoked by the P4 program to pass data between the P4 program and the custom functionality.
- The declaration uses type specialization, which is similar to
C++ template support.
- When instantiating the extern, the user specifies the type of data shared between the P4 program and the custom functionality.
As mentioned briefly above, a P4 program utilizes this declaration to interact with custom functionality by first creating an instance of UserExtern and then later in the program, invoking the apply() method of the instance.
The following statement shows a sample instantiation of a UserExtern object:
UserExtern<bit<12>,bit<12>>(16)
minimal_user_extern_example;
This instantiation describes an interface to some custom functionality that has been named "minimal_user_extern_example," which accepts a 12-bit wide input, produces a 12-bit wide output and executes in hardware with a fixed latency of 16 clock cycles.
The following statement illustrates how the interface to the custom functionality described above is used by the P4 program:
minimal_user_extern_example.apply(input,
output);
This statement shows the apply() method of minimal_user_extern_example being
invoked. The effect of this statement in the generated VNP4 IP is that the value stored
in the variable input is presented to the 12-bit wide
input of the custom functionality implemented by the user. 16 clock cycles later, the
12-bit result produced by the custom functionality is propagated to the output variable.