%% Verify the Combination of Hand-Written and Generated HDL Code
% This example uses HDL cosimulation and FPGA-in-the-Loop (FIL) simulation
% to verify an HDL design comprising generated and legacy HDL code. The
% term "legacy" is used here to indicate code that may have been
% hand-written, purchased from a third party or generated for another
% project and saved for reuse in this design.
%
% The legacy code in this example implements a finite state machine (FSM)
% that is a sub-module of a Multiple Input - Multiple Output (MIMO) decoder
% intended for use in a wireless communications system. Most of the MIMO
% decoder has been developed in Simulink and the HDL code for it will be
% generated by HDL Coder. The FSM belongs inside that Simulink design. The
% legacy code for the FSM will be integrated with the Simulink model and
% incorporated into the FPGA implementation via the code generation
% process.
%
% The example will show how the designer or verification engineer can use
% the HDL Verifier cosimulation wizard to integrate the legacy FSM
% with the Simulink model and verify it. HDL Cosimulation provides full
% visibility and control, enabling debugging and verification of the code.
%
% After successful integration of the legacy FSM, the cosimulation block
% automatically incorporates the legacy code when HDL code is generated
% from the Simulink model, resulting in a complete FPGA implementation of
% the MIMO decoder. Finally, the entire design is verified on the actual
% FPGA using FPGA-in-the-Loop.
%

%% Outline of the Example
% # Use the cosimulation wizard to import legacy HDL code into a Simulink
% model 
% # Verify the legacy HDL code by cosimulating it and comparing results 
% with a behavioral model 
% # Generate HDL code for the entire MIMO decoder using the cosimulation 
% block in a Blackbox 
% # Validate the MIMO decoder with FPGA-in-the-Loop


%% Requirements and Prerequisites
% 
% For cosimulation and FPGA-in-the-Loop you'll need the
% following software and hardware:
%
% * One of the
% <matlab:helpview(fullfile(docroot,'toolbox','hdlverifier','helptargets.map'),'edalink_supported_simulators')
% supported HDL simulators>
% * FPGA design software 
% * One of the
% <matlab:helpview(fullfile(docroot,'toolbox','hdlverifier','helptargets.map'),'edalink_supported_devices')
% supported FPGA development boards> and accessories
% * For connection using Ethernet: Gigabit Ethernet Adapter installed on
% host computer, Gigabit Ethernet crossover cable
% * For connection using JTAG: USB Blaster I or II cable and driver for
% Intel FPGA boards. Digilent(R) JTAG cable and driver for Xilinx FPGA
% boards.
%
% MATLAB(R) and FPGA design software can either be locally installed on
% your computer or on a network accessible device. If you use software from
% the network you will need a second network adapter installed in your
% computer to provide a private network to the FPGA development board.
% Consult the hardware and networking guides for your computer to learn how
% to install the network adapter.
%
% Note: The example includes code generation. 
% If you do not have access to HDL Coder software you can skip
% the code generation step in this example and use the HDL files provided 
% for you together with the FIL wizard to simulate them with 
% FPGA-in-the-Loop.

% Copyright 2012-2013 The MathWorks, Inc.

%% Create a Reference Model for the Finite State Machine
% A reference model is a simulation model of the behavior expected of an
% implementation. It is typically used in HDL verification by instantiating
% it alongside the RTL implementation, giving the same inputs to both and
% comparing their outputs. The advantages of reference models in
% verification are that they can be developed independently of the
% implementation (often by a different person) providing an independent
% validation of the expected behavior, they are easier to create than the
% actual implementation (not requiring synthesis or actual device timing)
% and they usually run fast in simulation.
% 
% The first step in verifying the legacy HDL code in this example is to
% create a reference model for that part of the design. That has already
% been done for the FSM. Open the behavioral_mimo.slx model. 
% Double-click into the MIMO Decoder subsystem and
% you'll see that the FSM subsystem contains a MATLAB function block that
% implements the behavior of the FSM. This reference model will be used to
% verify the legacy HDL code for the FSM.
%


%% 1. Use Cosimulation Wizard to Import Legacy HDL Code
% Invoke the cosimulation wizard by typing the following at the MATLAB
% command prompt:
%
%%
%   cosimWizard

%%
% Select HDL cosimulation with Simulink and your preferred HDL simulator
% from the drop-down list. If the HDL simulator is not on your system path,
% provide the path and click Next.
%
% Add FSMSubsystem.vhd, FSMSubsystem_pkg.vhd, and Embedded_Controller.vhd files 
% (located in the "verify_legacy_hdlsrc" folder) 
% using the cosimWizard's Add button and reorder the
% list to place FSMSubsystem.vhd at the bottom and FSMSubsystem_pkg.vhd at
% the top of the list, for correct compilation ordering. Then click Next.
%
% Click Next on the following 2 panels to accept the default values and
% arrive at the Input/Output Ports panel. In the list of Input Ports,
% select the following Port Type values from the drop-down lists for the
% first 3 ports: 
%
%  clk        : Port Type = clock
%  reset      : Port Type = reset
%  clk_enable : Port Type = reset 
%
% This identification of Port Types causes the cosimulation block to force
% those signals in the HDL simulator rather than require that they be
% driven in the Simulink diagram. In this example we treat the clk_enable
% port as another reset for cosimulation. Before you proceed to the next
% step similarly select "unused" for the ce_out, causing it to be omitted
% from the cosimulation block since it is not needed in Simulink.
%
% The cosimulation wizard automatically identifies inputs and outputs in
% the HDL code and creates the cosimulation block for Simulink based on the
% ports it finds there. There are some details about the output ports that
% it cannot learn from the HDL code. In the HDL code the outputs are simply
% collections of bits with no indication of how you would like to interpret
% those bits in Simulink. You have to tell the cosimulation wizard whether
% you want those bits to be seen as signed or unsigned values and, if they
% are to be interpreted as fixed-point numbers, where to put the radix
% point.
%
% In the Output Port Details panel refine the data type for each output. In
% the case of this design the output ports are to be interpreted as
% follows. Note that there are multiple scalar ports in the HDL code for
% the vector ports (out_1, out_6, out_9, out_10, out_11, out_12):
%
%  out_1  : Signed,   Fraction Length = 0 (4 scalar ports)
%  out_2  : Unsigned, Fraction Length = 0
%  out_3  : Unsigned, Fraction Length = 0
%  out_4  : Unsigned, Fraction Length = 0
%  out_5  : Signed,   Fraction Length = 10
%  out_6  : Signed,   Fraction Length = 10 (3 scalar ports)
%  out_7  : Signed,   Fraction Length = 2
%  out_8  : Unsigned, Fraction Length = 0
%  out_9  : Signed,   Fraction Length = 0 (4 scalar ports)
%  out_10 : Signed,   Fraction Length = 0 (4 scalar ports)
%  out_11 : Signed,   Fraction Length = 10 (4 scalar ports)
%  out_12 : Signed,   Fraction Length = 10 (4 scalar ports)
%  out_13 : Unsigned, Fraction Length = 0
%  out_14 : Signed,   Fraction Length = 0
%
% On the Clock/Reset Details panel set the following values:
%
%  clk Period = 10 ns, Active Edge = Rising
%  reset Initial Value = 1, Duration = 27 ns
%  clk_enable Initial Value = 0, Duration = 37 ns
%
% Click Next to proceed to the Start Time Alignment panel and set the "HDL
% time to start cosimulation (ns)" to 40.
%
% Proceed to the final step and de-select the checkbox for "Automatically
% determine timescale at start of simulation". For this example we know
% that the timescale for cosimulation should be 1 second in Simulink
% corresponds to 10 ns in the HDL simulator. See HDL Verifier
% documentation for information on using the automatic timescale setting
% feature for other designs. Set the aforementioned timescale and click
% Finish.
%
% The cosimulation block will be generated for importing the legacy HDL
% code into the Simulink model. You can drag and drop the newly generated
% cosimulation block and the 2 convenience command blocks into the Simulink
% model, inside the FSMSubsystem block and connect it to the output ports
% of the FSMSubsystem. A cosimulation model, with comparators and
% assertion blocks inside the MIMO Decoder subsystem, has been provided
% for this example. The comparators and assertion blocks have been added to
% alert you to any mismatches between the outputs of the reference model
% for the Embedded Controller and the legacy HDL implementation.
%
% Use the following command to resize the generated cosimulation block to
% make it easier to insert it into the cosimulation model:
%

%%
%   set_param('untitled/fsmsubsystem', 'Position', [0 0 165 852]);

%%
% Open the cosim_mimo.slx model. Drag the
% new block and convenience command blocks created by cosimWizard into the
% cosimulation model, replacing the placeholder subsystem inside the
% MIMODecoder subsystem.
%

%% 2. Cosimulate to Verify the Legacy HDL Code
% In your cosimulation model double-click the "Launch HDL Simulator" block
% to launch your chosen HDL simulator. Click the Play button in Simulink to
% start the cosimulation and observe that warning messages are displayed in
% the MATLAB window. These are indicating mismatches on the output signals
% because of a discrepancy between the reference FSM model and the HDL
% implementation.
%
% Now you can use Simulink and HDL simulator debugging features to isolate
% the problem and fix the bug. In this case the errors arise because a
% state transition arc was missed in the HDL implementation. Notice in the
% HDL simulator's waveform display that the FSM state gets stuck very early
% in the simulation.
%

%% Fix the Hand-Written HDL Code and Rerun the Cosimulation
% The corrected HDL code has been supplied for this example. Use the
% following command to copy the new code to your working directory,
% overwriting the bad version of Embedded_Controller.vhd:

%%
%   copyfile(fullfile('verify_legacy_hdlsrc', 'fixed_hdl', 'Embedded_Controller.vhd'), 'verify_legacy_hdlsrc', 'f');

%%
% Recompile the Legacy HDL code by double-clicking the "Compile HDL Design"
% block. Exit the HDL simulator if it is still open following the previous 
% execution of the cosimulation and relaunch the HDL simulator, then replay
% the cosimulation. You should observe no mismatches this time.
%
% Now that you've debugged and verified the legacy HDL code for the
% Embedded Controller you can go on to verify the entire MIMODecoder with
% FPGA-in-the-Loop.

%% Set FPGA Design Software Environment
% 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.
%

%% Prepare the Model for HDL Code Generation
% To prepare the model for FPGA-in-the-Loop incorporating the legacy HDL
% code and generating new HDL code for the remainder of the MIMO Decoder
% you need to do 2 things to complete the FPGA implementation:
% 
% # edit the cosimulation model to remove the FSM reference design
% # use the HDL Coder Blackbox to incorporate the legacy HDL into the
% model for code generation
%
%
% If you want to follow all steps to prepare the model for HDL code 
% generation using the HDL Blackbox, save the cosimulation model with a
% different name and proceed with the rest of model preparation as follows:
%
% 1. edit the cosimulation model to remove the FSM reference design
%
% * inside the MIMO Decoder subsystem delete the Embedded_Controller function block
% * delete the "from" blocks that drive Embedded_Controller inputs with the
% exception of the enablecoder input
% * delete the comparators and assertion blocks on the outputs
% * reconnect the cosimulation block outputs to the inputs of DelaySubsystem1
%
% 2. use the HDL Coder Blackbox to incorporate the legacy HDL into the
% model for code generation
%
% * select the cosimulation block and type control-G to create a subsystem
% * right-click on the new cosimulation subsystem and select HDL Code and
% HDL Block Properties
% * select Architecture = BlackBox
% * enter FSMSubsystem in the EntityName parameter
% * enter 0 in the ImplementationLatency parameter
% * OK the HDL Block properties dialog
%
% 3. rerun the simulation to update the diagram.
%
% * double-click the "Launch HDL Simulator" block to launch the HDL simulator
% * click the Play button in Simulink to start the cosimulation
% * save the model
%
%% 3. Generate HDL Code and FPGA-in-the-Loop
% This step requires HDL Coder. If you do not have this software, you can
% use pre-generated HDL files for FIL simulation. Jump directly to step
% 5. FIL Simulation Using filWizard.
%
% If you want to follow the process to generate the HDL files yourself
% return to the top level of the model, right click on the MIMODecoder
% subsystem and under "HDL Code" launch the HDL Coder Workflow Advisor. 
%
% * Step 1.1: select FPGA-in-the-Loop Target Workflow, select your preferred
% FPGA development board from the drop-down list, and identify a writeable
% directory to hold the generated HDL code.
%
% <<../verif_cosim_fil_wfa1_1.png>>
%
% * Step 4.1: in Set FPGA Options select "Add" and use the browser to
% navigate to the EmbeddedController HDL files you copied to your working
% folder in Step 1 and modified with the fixed HDL code in Step 3.
%
% <<../verif_legacy_fil_wfa4_1.png>>
%
% * Step 4.2: Right-click on step 4.2 of the workflow in the left-hand
% navigation tree and select "Run to this task". This step may take several
% minutes because it includes the steps to synthesize, map, and route the
% design for the FPGA device.
% 
% <<../verif_cosim_fil_wfa4_2.png>>
% 
% The result will be an FPGA programming file for FPGA-in-the-Loop
% simulation of the MIMO Decoder subsystem and a new model containing the
% original model (including the legacy HDL for the FSM) of the decoder
% alongside the FPGA-in-the-Loop block. It will also have comparators with
% assertion blocks to identify mismatching signals similar to those we saw
% in the cosimulation model.
%

%% 4. Verify the Design with FPGA-in-the-Loop Simulation
% Since the generated verification model includes the cosimulation for the
% FSMSubsystem you will need to use the HDL simulator to run the entire FIL
% model. Make sure that the HDL simulator from your previous cosimulation
% is shut down and relaunch the HDL simulator.
%
% In the FPGA-in-the-Loop model generated in Step 3, open the FIL block.
%
% Select "Load" to download the FPGA programming file to the device on your
% board. 
%
% Click Play in the Simulink model to run FPGA-in-the-Loop simulation. 
%
% Observe the results in the comparison scopes and the ErrorRate
% Calculation in the model. Your FIL simulation results should exactly
% match the reference model.
%

%% 5. FIL Simulation Using FIL Wizard
% This step is the alternative to Step 4 for those who do not have HDL
% Coder software. If you've completed Step 4 you need not continue with
% this step.
%
% The pre-generated HDL files are located in the "verify_legacy_gen_hdlsrc"
% folder.
% You can create the FPGA programming file for FPGA-in-the-Loop using the 
% FIL wizard. the FIL wizard will also create a FIL block which you can
% discard because the FIL model provided for this example already contains
% the FIL block.
%
% Open the FIL wizard by entering the following command:

%%
%   filWizard

%%
%
% * In *FIL Options* select your FPGA development board from the list.
% * *In Source Files* select *Add* and choose all of the files in the folder
% verify_legacy_gen_hdlsrc and identify *MIMODecoder.vhd* as the top level
% file.
% * Accept the default values for the remainder of the filWizard options
% * Wait for the FIl block and FPGA programming file to be created. This
% may take several minutes due to the time required to synthesize and route
% the FPGA implementation.
% * Open the gm_fil_codegen_mimo_fil.slx model
% and drag the newly generated FIL block into the model at the location
% indicated.
% * Open the FIL block mask, click on the Signal Attributes tab. Change the 
% data type for each rx_decoded output to fixdt(1,6,0) to match the data 
% type of the behavioral block.
% * Open the FIL block mask, click on the Main tab, select Load and wait 
% for the FPGA programming
% file to be downloaded to the device.
% * Press Play in the Simulink model to run FPGA-in-the-Loop.
%
% Observe the results in the comparison scopes and the ErrorRate
% Calculation in the model. Your FIL simulation results should exactly
% match the reference model.
%
%%
% This concludes the example of Using HDL Cosimulation and FPGA-in-the-Loop
% to Verify HDL Designs.
%
