%% HDL Verifier Cosimulation Model Generation in HDL Coder(TM)
% This example shows how to generate a cosimulation model in
% of HDL Coder and integrate the generated HDL code into an
% HDL Verifier(TM) workflow. Automation of cosimulation model generation
% enables seamless verification of the generated hardware design.

% Copyright 2006-2012 The MathWorks, Inc.
      
%% Quick Introduction
% Cosimulation is a challenging task, especially with automatically
% generated code; one has to keep in-sync various aspects of the source
% model including sample rates, feedforward/feedthrough systems, and other
% various parameters and settings used during code generation while setting
% up the HDL Verifier block and the target EDA Simulator.
%
% The automated cosimulation model generation takes the guess-work out of
% the HDL cosimulation block and simulator setup by deciphering all the compiled 
% model and code generation information; in addition all the automated settings 
% are documented in the generated scripts. The end result is a cosimulation 
% model ready to verify the generated code.

% >> docsearch('Code Generation for HDL Cosimulation Model')   

%% Generating the Cosimulation Model
% Let us take a simple accumulator design in Simulink and automatically generate a
% cosimulation model for it as a part of test bench generation.

%% Multiply Accumulator Design in Simulink
% Open the source design/model
bdclose all;
load_system('hdl_cosim_demo1')
open_system('hdl_cosim_demo1/MAC')

% Now generate vhdl code for the device under test 'MAC' in that
% model in the source Simulink model.
makehdl('hdl_cosim_demo1/MAC', 'targetlang', 'vh')

%% Generate HDL Test Bench with Cosimulation Model
% HDL Coder supports generation of cosimulation model with an HDL Verifier
% block for Mentor Graphics 'Modelsim' or Cadence 'Incisive'

% Now as a part of test bench generation specify that in addition to the
% textual based test bench a cosimulation model needs to be generated. Use
% the new makehdl parameter 'GenerateCosimModel' with value 'ModelSim' or
% 'Incisive' to choose between the two HDL Verifier blocks to generate the
% cosimulation model.
makehdltb('hdl_cosim_demo1/MAC', 'targetlang', 'vh', 'GenerateCosimModel', 'ModelSim')

%% (Optional) Generate HDL Code Coverage Report and Database
% To instrument the HDL Simulator to generate a code coverage database, either:
%
% a.) On the 'HDL Code Generation > Test Bench' pane, select the check box labeled 'HDL code coverage'.
% 
% b.) When you call 'makehdltb', set 'HDLCodeCoverage' to 'on'. For example:
%
%   makehdltb('hdl_cosim_demo1/MAC', 'targetlang', 'vh', 'GenerateCosimModel', 'ModelSim','HDLCodeCoverage','on');
%
% The HDL code coverage artifacts are generated in the source directory after the test bench is simulated.
%
%% New Code Generation Messages
% As you can see from the following additional code generation messages in 
% the command window a cosimulation model 'gm_hdl_cosim_demo1_mq' is generated;
% In addition to the code generated in the target directory 'hdlsrc' an additional 
% cosimulation script 'gm_hdl_cosim_demo1_mq_tcl.m' is generated to prepare 
% the target simulator for cosimulation with Simulink.
%
%   ### Generating new cosimulation model: gm_hdl_cosim_demo1_mq
%   ### Generating new cosimulation tcl script: hdlsrc/gm_hdl_cosim_demo1_mq_tcl.m
%   ### Cosimulation Model Generation Complete.

%% Cosimulation Model Stimulus and Response Capture
% As can be seen from the cosimulation model the original device under test (DUT)
% is intercepted by two subsystems 'ToCosimSrc' and 'ToCosimSink'; 
% As shown below the purpose of these two subsystems is to capture the
% stimulus and the response of the DUT and use it for driving the
% cosimulation using 'Goto' blocks. The number of 'Goto'
% blocks in each of the following subsystem match the number of inputs and
% outputs of the DUT.
open_system('gm_hdl_cosim_demo1_mq/ToCosimSrc')
open_system('gm_hdl_cosim_demo1_mq/ToCosimSink')

%% Stimulus to the HDL Cosimulation Block
% The stimulus that is originally driving the DUT is fed to the fully
% configured HDL cosimulation block using the 'From' block as shown below.
% In some cases input stimulus signals cannot be directly
% fed to the HDL Cosimulation block; for example the HDL Cosimulation block does not allow 
% complex and vector signals and in such cases further massaging of the 
% input stimulus signals is done automatically. 
% In the current model the 'From' blocks directly feed the contents of
% corresponding 'Goto' blocks.
open_system('gm_hdl_cosim_demo1_mq/FromCosimSrc')

%% Comparison of the Results
% The response from the original DUT is compared with the response from the
% HDL Cosimulation block in HDL Verifier using the Sink 
% blocks provided by Simulink for visualization of the response data.
open_system('gm_hdl_cosim_demo1_mq/Compare')

%% Assertion Checking in the Generated Model
% For each output of the device under test subsystem the following assertion-checking
% model is generated that checks the original output ('dut ref') with
% cosimulation output ('cosim') and generates assertion messages when the input 
% to the assertion block detects a mismatch.
open_system('gm_hdl_cosim_demo1_mq/Compare/Assert_Out1')

%% Using Assertion Blocks
% Assertions are enabled in the Assertion block but do not stop simulation.
% If as a part of cosimulation there are any assertions from the
% following block you should see a warning from the Assertion block:
%
%  Warning: Assertion detected in 'gm_hdl_cosim_demo1_mq/Compare/Assert_Out1/AssertEq' at time 1.000000 
open_system('gm_hdl_cosim_demo1_mq/Compare/Assert_Out1/AssertEq')


%% HDL Cosimulation Block Setup
% The HDL Cosimulation block is automatically populated with the compiled input output 
% interface of the DUT. The 'Ports' panel is fully populated with 'Full HDL
% Name', 'Sample Time' and 'Data type' information. Similarly various
% HDL Cosimulation block setup parameters such as TimeScale and tcl port panes are
% automatically populated. Note that cosimulation model is always
% configured in the 'Shared Memory' connection method.
open_system('gm_hdl_cosim_demo1_mq/MAC_mq')

%% Target Simulator Launch and Setup
% Now let's look at the automation associated with the launch and setup of
% the target simulator (ModelSim or Incisive). As can be seen in the
% top level of the generated model, a Subsystem with the name 'Start Simulator'
% is generated with the following callback function; this subsystem is used 
% to launch the target simulator of choice. 
get_param('gm_hdl_cosim_demo1_mq/Start Simulator', 'OpenFcn')

%% Simulation of the Cosimulation Model
% The following script is executed on launch
%
%  vsim('tclstart',gm_hdl_cosim_demo1_mq_tcl)
%
% The MATLAB command 'vsim' for ModelSim (or 'hdlsimulink' for Incisive)
% launches the target simulator from within MATLAB environment with the
% necessary setup for cosimulation. The 'vsim' command is invoked with the
% 'tclstart' option that accepts an tcl string that configures the simulator 
% on its launch. The file 'gm_hdl_cosim_demo1_mq_tcl' 
% is also automatically generated by HDL Coder along with 
% the cosimulation model.

%% Contents of the Generated tclstart Command File
% The generated tclstart file contains commands for configuring the
% launched simulator as well as comments about how various settings
% of Cosimulation model are generated. 

type hdlsrc/hdl_cosim_demo1/gm_hdl_cosim_demo1_mq_tcl

%% Header Comments in the 'tclstart' File
% At the top level, the comments specify the source and generated model
% names of the DUT portion of the model for which code is generated and being
% co-simulated. The cosimulation HDL Verifier DUT is placed in 
% parallel with our generated model DUT, (which  captures any modifications/changes to
% bit-true or cycle-accuracy of the original model DUT as a part of code
% generation)

%% Test Bench Options Affecting Cosimulation Model Generation
% The next part of the tclstart script file shows all the makehdltb 
% test bench parameters supported by HDL Coder and their initial
% values used in cosimulation scripts.
%
%  ClockName, ResetName, ClockEnableName
%  ClockLowTime, ClockHighTime, ClockPeriod
%  ResetLength, ClockEnableDelay, HoldTime
%

%% Model Sample Times and Mapping of DutBaseSampleTime to ClockPeriod
% The next part of the comment section covers sample times in
% the model and how they influenced clocking of the HDL Cosimulation block
% in HDL Verifier.
%
%    N = (ClockPeriod / DutBaseSampleTime) * OverClockFactor
%    1 sec in Simulink corresponds to 10ns in the HDL Simulator(N = 10)

%% Generated 'tclstart' Script Output
% The function in 'gm_hdl_cosim_demo1_mq_tcl' generates the necessary tcl
% command string (tclCmds).
%
% If the 'EDAScriptGeneration' option is turned 'on' and compilation do
% files are generated for ModelSim as part of 'makehdl', then a single 'do'
% command is generated. If the 'EDAScriptGeneration' option is turned
% 'off', then explicit compilation commands are added for compiling the
% generated HDL code for the DUT.
%
% Wave commands are added for all top-level interface signals. 

%% Pre-simulation Commands
% In the HDL Cosimulation block, the "Pre-simulation Tcl commands"
% parameter contains force commands that drive the clock bundle (clock,
% clock-enable, reset). The "Time to run HDL simulator before cosimulation
% starts" parameter initiates simulation with a run time necessary to bring
% the chip out of reset.
get_param('gm_hdl_cosim_demo1_mq/MAC_mq','TclPreSimCommand')


%% Launching the Simulator
% Double clicking the Start Simulator launches the simulator with the
% tcl commands in the generated 'tclstart' MATLAB script. Once the
% simulator is launched all the generated code is compiled and the
% HDL Cosimulation block is ready for simulation. 

%% Support for Complex Signals
% The model hdl_cosim_demo2 contains a complex MAC subsystem; 
bdclose all;
load_system('hdl_cosim_demo2');
open_system('hdl_cosim_demo2/Complex MAC');
makehdl('hdl_cosim_demo2/Complex MAC', 'targetlang', 'vh');
%% Cosimulation Model for Complex MAC
% Let's generate a cosimulation model as a part of test bench generation and
% observe the stimulus part of cosimulation model:
makehdltb('hdl_cosim_demo2/Complex MAC', 'targetlang', 'vh', 'GenerateCosimModel', 'ModelSim')
%% Generated Complex FromCosimSrc Subsystems
% The input complex signal is automatically broken 
% into real and imaginary pieces before driving the HDL Cosimulation block.
open_system('gm_hdl_cosim_demo2_mq/FromCosimSrc')
%% Generated Complex Compare Subsystems
% The comparison section checks the results for real and
% imaginary parts of complex outputs separately.
open_system('gm_hdl_cosim_demo2_mq/Compare/Assert_Out1')
 
%% Support for Vector Signals
% The model hdl_cosim_demo3 contains a Vector MAC subsystem; 
bdclose all;
load_system('hdl_cosim_demo3');
open_system('hdl_cosim_demo3/Vector MAC');
makehdl('hdl_cosim_demo3/Vector MAC', 'targetlang', 've');
%% Cosimulation Model for Vector MAC
% Let's generate cosimulation model as a part of test bench generation and
% observe the stimulus part of cosimulation model for vector signals in
% 'verilog' where we flatten the vector signals for code generation.
makehdltb('hdl_cosim_demo3/Vector MAC', 'targetlang', 've', 'GenerateCosimModel', 'ModelSim')
%% Generated Vector FromCosimSrc Subsystem
open_system('gm_hdl_cosim_demo3_mq/FromCosimSrc')
%% Generated Vector Compare Subsystem
open_system('gm_hdl_cosim_demo3_mq/Compare')

%% Support for Local Multi-Rate
% The model hdl_cosim_demo4 contains a MAC subsystem with a Sum of Elements 
% block that is configured with a Cascade implementation and requires
% overclocking as can be seen in the Code generation messages.
bdclose all;
load_system('hdl_cosim_demo4');
open_system('hdl_cosim_demo4/LocalMR MAC');
makehdl('hdl_cosim_demo4/LocalMR MAC', 'targetlang', 'vh');
makehdltb('hdl_cosim_demo4/LocalMR MAC', 'targetlang', 'vh', 'GenerateCosimModel', 'ModelSim');

%% Time-Scale Setting Updates to Offset Overclocking
% The code generation messages show an overclocking that
% require a five times faster clock with respect to base rate of the model.
% This info is encapsulated in the cosimulation model as a part of the time
% scale setting as per the following message
%
%   N = (ClockPeriod / DutBaseSampleTime) * OverClockFactor
%   1 sec in Simulink corresponds to 50ns in the HDL Simulator(N = 50)


%% Support for Incisive
bdclose all;
load_system('hdl_cosim_demo1')
makehdl('hdl_cosim_demo1/MAC', 'targetlang', 'vh')
makehdltb('hdl_cosim_demo1/MAC', 'targetlang', 'vh', 'GenerateCosimModel', 'Incisive')
type hdlsrc/hdl_cosim_demo1/gm_hdl_cosim_demo1_in_tcl
bdclose all;

% close Modelsim
%tclHdlSim('after 1000 quit -f');

displayEndOfDemoMessage(mfilename)
