%% Verify Digital Up-Converter Using FPGA-in-the-Loop
% This example shows you how to verify a digital up-converter design 
% generated with Filter Design HDL Coder(TM) using FPGA-in-the-Loop
% simulation.
%
%% Requirements
% Tools required for this example:
% 
% * FPGA design software
% * One of the supported FPGA development boards and accessories (the ML403
% board is not supported for this example). For more information about
% supported hardware, see <docid:hdlv_gs#bt16i4l-11 Supported FPGA Devices for FPGA Verification>.
% * For connection using Ethernet: Gigabit Ethernet Adapter installed on
% host computer, Gigabit Ethernet crossover cable
% * For connection using JTAG: JTAG cable with USB Blaster I or II, USB
% Blaster driver
% * For connection using PCI Express(R): FPGA board installed into PCI
% Express slot of host computer.

% Copyright 2010-2015 The MathWorks, Inc.

%% Create Cascade Filter for DUC
%
% A digital up-converter (DUC) is a digital circuit that converts a digital
% baseband signal to a passband signal. A DUC is composed of three
% filtering stages; each stage filters the input signal with a lowpass
% interpolating filter, followed by a sample rate change. In this example,
% the DUC is a cascade of two FIR interpolation filters and a CIC
% interpolation filter, as described in the example HDL Digital Up-Converter (DUC).
% 
% 1. Create the two FIR and CIC filters.

%%
%   pfir = [0.0007    0.0021   -0.0002   -0.0025   -0.0027    0.0013    0.0049    0.0032 ...
%        -0.0034   -0.0074   -0.0031    0.0060    0.0099    0.0029   -0.0089   -0.0129 ...
%        -0.0032    0.0124    0.0177    0.0040   -0.0182   -0.0255   -0.0047    0.0287 ...
%         0.0390    0.0049   -0.0509   -0.0699   -0.0046    0.1349    0.2776    0.3378 ...
%         0.2776    0.1349   -0.0046   -0.0699   -0.0509    0.0049    0.0390    0.0287 ...
%        -0.0047   -0.0255   -0.0182    0.0040    0.0177    0.0124   -0.0032   -0.0129 ...
%        -0.0089    0.0029    0.0099    0.0060   -0.0031   -0.0074   -0.0034    0.0032 ...
%         0.0049    0.0013   -0.0027   -0.0025   -0.0002    0.0021    0.0007 ];
% 
%   hpfir = dsp.FIRInterpolator(2, pfir);
%   hpfir.FullPrecisionOverride = false;
%   hpfir.CoefficientsDataType = 'Custom';
%   hpfir.CustomCoefficientsDataType = numerictype([],16);
%   hpfir.ProductDataType = 'Custom';
%   hpfir.CustomProductDataType = numerictype([],31,31);
%   hpfir.AccumulatorDataType = 'Custom';
%   hpfir.CustomAccumulatorDataType = numerictype([],16,15);
%   hpfir.OutputDataType = 'Custom';
%   hpfir.CustomOutputDataType = numerictype([],16,15);
%   hpfir.RoundingMethod = 'Nearest';
% 
%   cfir = [-0.0007   -0.0009    0.0039    0.0120    0.0063   -0.0267   -0.0592   -0.0237 ...
%          0.1147    0.2895    0.3701    0.2895    0.1147   -0.0237   -0.0592   -0.0267 ...
%          0.0063    0.0120    0.0039   -0.0009   -0.0007];
% 
%   hcfir = dsp.FIRInterpolator(2, cfir);
%   hcfir.FullPrecisionOverride = false;
%   hcfir.CoefficientsDataType = 'Custom';
%   hcfir.CustomCoefficientsDataType = numerictype([],16);
%   hcfir.ProductDataType = 'Custom';
%   hcfir.CustomProductDataType = numerictype([],31,31);
%   hcfir.AccumulatorDataType = 'Custom';
%   hcfir.CustomAccumulatorDataType = numerictype([],16,15);
%   hcfir.OutputDataType = 'Custom';
%   hcfir.CustomOutputDataType = numerictype([],16,15);
%   hcfir.RoundingMethod = 'Nearest';
% 
%   hcic = dsp.CICInterpolator(32, 1, 5);
%   hcic.FixedPointDataType = 'Minimum section word lengths';
%   hcic.OutputWordLength = 20;

%%
% 2. Create a cascade filter using these filters. 
%%
%   hduc = dsp.FilterCascade(hpfir, hcfir, hcic);

%% 
% The frequency response of the cascade filter is shown in the following
% figure.

%%
%   fvtool(hduc,'Arithmetic','fixed');

%%
% <<../filter_result.png>>

%% Generate HDL Code
%
% When the cascade filter is ready, generate HDL code for the DUC using the
% Filter Design HDL Coder function |generatehdl|, with the property
% 'AddPipelineRegisters' set to 'on'.
%%
%   generatehdl(hduc, 'Name', 'hdlduc', 'AddPipelineRegisters', 'on', 'InputDataType', numerictype(1,16,15));
%% 
% This option inserts pipeline registers between filter stages, and allows
% the generated filter to be synthesized at a higher clock frequency.
%
% If you do not have Filter Design HDL Coder, you can use the pre-generated
% HDL files in the current directory.

%% Set Up FPGA Design Software
%
% Before using FPGA-in-the-Loop, make sure your system environment is set
% up properly for accessing FPGA design software. You can use the function
% *hdlsetuptoolpath* to add FPGA design software to the system path for the
% current MATLAB session.
%

%% Configure and Build FPGA-in-the-Loop
%
% The FIL Wizard guides you in configuring settings necessary for building
% FPGA-in-the-Loop. Launch the wizard with the following command:
%% 
%   filWizard
%% 
% 1. In Hardware Options, select the FPGA development board connected to
% your host computer. If necessary, you can also customize the Board IP and
% MAC Address under Advanced Options. Click *Next" to continue.
%
% 2. In Source Files, add the following generated HDL files for the DUC to
% the source file table using *Browse*.
% 
%  hdlduc.vhd
%  hdlduc_stage1.vhd
%  hdlduc_stage2.vhd
%  hdlduc_stage3.vhd
% 
% Select the top-level checkbox next to |hdlduc.vhd|. Click *Next" to
% continue.
% 
% 3. In DUT I/O Ports, the input and output port information, such as port
% name, direction, width and port type are automatically generated from the
% HDL file. Port types, such as Clock and Data, are generated based on port
% names; you may change the selection as necessary. For this example, the
% generated port types are correct, and you can click *Next*.
% 
% 4. In Build Options, specify the folder for FIL output files. You can use
% the default value for this example. Click *Build*. Clicking *Build*
% causes the FIL Wizard to generate all the necessary files for
% FPGA-in-the-Loop simulation and perform the following actions:
% 
% * Generates a FIL block in a new Simulink(R) model
% * Opens a command-line window to compile the FPGA project and generate
% the FPGA programming file
% 
% The FPGA project compilation process takes several minutes. When the
% process is finished, you are prompted to close the command-line
% window. Close this window now.

%% Configure FIL Block
% 
% To prepare for FPGA-in-the-Loop simulation, follow the steps below to
% configure the FIL block.
% 
% 1. Open the *Open Model* button to open the test bench model 
% and copy the generated FIL block into the model.
%
% <<../fil_duc_screen1.png>>
 
%%
% 2. Double-click the FIL block to open the block mask. Click *Load* to
% program the FPGA with the generated programming file.
% 
% 3. Under Runtime Options, change *Overclocking factor* to 128. This
% specifies that an input value is sampled 128 times by the FPGA clock
% before the input changes value.
% 
% 4. On the FIL block mask, click on the Signal Attributes tab. Change the
% data type for filter_out to |fixdt(1,20,-1)| to match the data type of
% the behavioral filter block.
% 
% 5. Click *OK* to close the block mask.

%% Verify Generated Filter
%
% In this example, the generated filter running on FPGA is compared to a
% behavioral filter block. Delays are added to the output of the behavioral
% filter to match the HDL latency of the generated filter.
% 
% <<../fil_duc_screen2.png>>
% 
% Run simulation. Observe the output waveforms from the behavioral filter
% block, the FIL block, and the error margin. Because the behavioral filter
% block does not have pipeline registers, there are small differences
% between the behavioral filter block output and the FIL block output.
% These errors are within the error margin.
% 
% <<../fil_duc_screen3.png>>
%
% This concludes the example.
%
