%% Customize Bitstream Configuration to Meet Resource Use Requirements
% The user wants to deploy a digit recognition network with a target performance of 500 frames per second (FPS) to a Xilinx™ ZCU102 ZU4CG device. The target device resource counts are:
% Digital signal processor (DSP) slice count - 240
% Block random access memory (BRAM) count -128
% The reference (shipping) zcu102_int8 bitstream configuration is for a Xilinx ZCU102 ZU9EG device. The default board resource counts are:
% Digital signal processor (DSP) slice count - 2520
% Block random access memory (BRAM) count -912
% The default board resource counts exceed the user resource budget and is on the higher end of the cost spectrum. You can achieve target performance and resource use budget by quantizing the target deep learning network and customizing the custom default bitstream configuration.
% In this example create a custom bitstream configuration to match your resource budget and performance requirements.
%
%% Prerequisites
% Deep Learning HDL Toolbox™ Support Package for Xilinx FPGA and SoC
% Deep Learning Toolbox™
% Deep Learning HDL Toolbox™
% Deep Learning Toolbox Model Quantization Library
%
%% Load Pretrained Network
% To load the pretrained series network, that has been trained on the Modified National Institute Standards of Technology (MNIST) database, enter:

snet = getDigitsNetwork;

%
%% Quantize Network
% To quantize the MNIST based digits network, enter:

dlquantObj = dlquantizer(snet,'ExecutionEnvironment','FPGA');
Image = imageDatastore('five_28x28.pgm','Labels','five');
dlquantObj.calibrate(Image)

%
%% Retrieve zcu102_int Bitstream Configuration
% To retrieve the zcu102_int8 bitstream configuration, use the dlhdl.ProcessorConfig object. For more information, see dlhdl.ProcessorConfig. To learn about modifiable parameters of the processor configuration, see getModuleProperty and setModuleProperty.

hPC_reference = dlhdl.ProcessorConfig('Bitstream','zcu102_int8')

%
%% Estimate Network Performance and Resource Utilization for zcu102_int8 Bitstream Configuration
% To estimate the performance of the digits series network, use the estimatePerformance function of the dlhdl.ProcessorConfig object. The function returns the estimated layer latency, network latency, and network performance in frames per second (Frames/s).
% To estimate the resource use of the zcu102_int8 bitstream, use the estimateResources function of the dlhdl.ProcessorConfig object. The function returns the estimated DSP slice and BRAM usage.

hPC_reference.estimatePerformance(dlquantObj)
hPC_reference.estimateResources

% The estimated performance is 4303 FPS and the estimated resource use counts are:
% Digital signal processor (DSP) slice count - 768
% Block random access memory (BRAM) count -386
% The estimated DSP slice count and BRAM count use exceeds the target device resource budget. Customize the bitstream configuration to reduce resource use.
%
%% Create Custom Bitstream Configuration
% To create a custom processor configuration, use the dlhdl.ProcessorConfig object. For more information, see dlhdl.ProcessorConfig. To learn about modifiable parameters of the processor configuration, see getModuleProperty and setModuleProperty.
% To reduce the resource use for the custom bitstream, modify the KernelDataType for the conv, fc, and adder modules. Modify the ConvThreadNumber to reduce DSP slice count. Reduce the InputMemorySize and OutputMemorySize for the conv module to reduce BRAM count.

hPC_custom = dlhdl.ProcessorConfig;
hPC_custom.ProcessorDataType = 'int8';
hPC_custom.setModuleProperty('conv','ConvThreadNumber',4);
hPC_custom.setModuleProperty('conv','InputMemorySize',[30 30 1]);
hPC_custom.setModuleProperty('conv','OutputMemorySize',[30 30 1]);
hPC_custom

%
%% Estimate Network Performance and Resource Utilization for Custom Bitstream Configuration
% To estimate the performance of the digits series network, use the estimatePerformance function of the dlhdl.ProcessorConfig object. The function returns the estimated layer latency, network latency, and network performance in frames per second (Frames/s).
% To estimate the resource use of the hPC_custom bitstream, use the estimateResources function of the dlhdl.ProcessorConfig object. The function returns the estimated DSP slice and BRAM usage.

hPC_custom.estimatePerformance(dlquantObj)
hPC_custom.estimateResources

% The estimated performance is 750 FPS and the estimated resource use counts are:
% Digital signal processor (DSP) slice count - 129
% Block random access memory (BRAM) count -108
% The estimated resources of the customized bitstream match the user target device resource budget and the estimated performance matches the target network performance.
% Copyright 2020 The MathWorks, Inc.
%