%% Implementing a Spectrum Display Component in MATLAB(R)
% This example shows how MATLAB(R) can be used to implement a VHDL component
% that is used to display the spectrum of a signal from a VHDL project in
% ModelSim(R).  It compiles a VHDL source containing a frequency
% hopping sine wave feeding a lowpass filter and defines a spectrum display
% component in MATLAB.  The MATLAB component buffers its inputs into frames
% of 128 samples and displays the spectra of the unfiltered and filtered
% signals as the simulation is running.  This example requires a temporary
% working directory to generate a working ModelSim VHDL project.  After
% creating the VHDL project, this example starts ModelSim (this requires
% access to ModelSim from the command line).  This example uses shared memory
% to complete the link and therefore requires ModelSim to be on the same
% computer as MATLAB.  Once the project is compiled, the simulation can be
% run from within ModelSim.

%   Copyright 2003-2011 The MathWorks, Inc.
%     


%% Specify Files to Be Used
% The file
% *<matlab:editModelSimDemoFile('modsimspecdisp','vhdl/specdisp/sine_waves.vhd')
% sine_waves.vhd>* contains the source signal designed in VHDL.
%
% The file
% *<matlab:editModelSimDemoFile('modsimspecdisp','vhdl/specdisp/lowpass_filter.vhd')
% lowpass_filter.vhd>* contains the lowpass filter designed in MATLAB and
% generated with Filter Design HDL Coder(TM).
%
% The file
% *<matlab:editModelSimDemoFile('modsimspecdisp','vhdl/specdisp/spec_display.vhd')
% spec_display.vhd>* contains the MATLAB component that we are modeling.
% It contains an entity with an empty architecture.  The matlabcp command
% checks the VHDL inputs of the instance created from this entity.
%
% The file
% *<matlab:editModelSimDemoFile('modsimspecdisp','vhdl/specdisp/specdisp_top.vhd')
% specdisp_top.vhd>* contains the top-level wiring between the source,
% lowpass filter, and the MATLAB component.
%
% you can also define variables "UsrTclCmds" and "RunMode" with tcl
% commands and ModelSim's runmode.
% Examples: 
%
% UsrTclCmds = {'run 100000'};
% RunMode    = 'Batch' or 'CLI' or 'GUI';

srcfile1 = fullfile(matlabroot,'toolbox','edalink','extensions','modelsim','modelsimdemos',...
    'vhdl','specdisp','sine_waves.vhd');
srcfile2 = fullfile(matlabroot,'toolbox','edalink','extensions','modelsim','modelsimdemos',...
    'vhdl','specdisp','lowpass_filter.vhd');
srcfile3 = fullfile(matlabroot,'toolbox','edalink','extensions','modelsim','modelsimdemos',...
    'vhdl','specdisp','spec_display.vhd');
srcfile4 = fullfile(matlabroot,'toolbox','edalink','extensions','modelsim','modelsimdemos',...
    'vhdl','specdisp','specdisp_top.vhd');

%%
% ModelSim uses UNIX(R) style directory format which uses forward slashes
% ("/") instead of backslashes ("\").

unixsrcfile1 = ['"' strrep(srcfile1,'\','/') '"'];
unixsrcfile2 = ['"' strrep(srcfile2,'\','/') '"'];
unixsrcfile3 = ['"' strrep(srcfile3,'\','/') '"'];
unixsrcfile4 = ['"' strrep(srcfile4,'\','/') '"'];

%% Create Project Directory
% We create a temporary working directory in which the project will be
% generated.

if ispc
    projdir = tempdir;
else
    projdir = tempname;
end
warnstatus = warning('off','MATLAB:MKDIR:DirectoryExists');
mkdir(projdir);
warning(warnstatus);
unixprojdir =  strrep(projdir,'\','/');

%% Start the MATLAB Server
% We first start the MATLAB server, hdldaemon, such that it uses shared
% memory communication.  We first check if the server is already running
% using shared memory.  If hdldaemon is not running, it is started.  Or, if
% it is running using TCP/IP socket communication, it is shut down and
% restarted using shared memory communication.

dstatus = hdldaemon('status');
if isempty(dstatus)
    % hdldaemon is not running
    % start it - default is shared memory communication
    dstatus = hdldaemon;
elseif strcmp(dstatus.comm,'shared memory')
    % hdldaemon is already running with shared memory
elseif strcmp(dstatus.comm,'sockets')
    % hdldaemon is running with socket communication
    % shut it down and restart it
    disp('Shutting down HDLDaemon to restart it with shared memory');
    hdldaemon('kill');
    dstatus = hdldaemon;
else
    error(message('HDLLink:modsimspecdisp:InvalidDaemonStatus'));
end

%% Specify Tcl Commands
% Next we specify the Tcl commands to execute in ModelSim before the
% simulation is run.

tclcmd = {};

%%
% The |cd| command changes to the temporary working directory.
tclcmd = [tclcmd, ['cd ',unixprojdir]];

%%
% The |vlib| command creates the design library |work|.
tclcmd = [tclcmd, 'vlib work'];

%%
% The |vcom| command compiles the VHDL file. The |-performdefaultbinding|
% option enables default bindings in the event that they have been disabled
% in the modelsim.ini file.
tclcmd = [tclcmd, ['vcom -performdefaultbinding ' unixsrcfile1],...
                  ['vcom -performdefaultbinding ' unixsrcfile2],...
                  ['vcom -performdefaultbinding ' unixsrcfile3],...
                  ['vcom -performdefaultbinding ' unixsrcfile4]];

%%
% The |vsimmatlab| command, a variant of the ModelSim |vsim| command, loads
% an instance of the VHDL entity for cosimulation with MATLAB.  This
% command is a HDL Verifier(TM) extension to the ModelSim command set.
tclcmd = [tclcmd, 'vsimmatlab  work.specdisp_top'];

%%
% The |matlabcp| command initiates a MATLAB component for the loaded
% instance of entity |spec_display|. This command is a HDL Verifier 
% extension to the ModelSim command set.  The |-mfunc| option specifies
% *<matlab:editModelSimDemoFile('modsimspecdisp','specdisplay.m')
% specdisplay.m>* will be used to implement this component.
tclcmd = [tclcmd, 'matlabcp u_spec_display -mfunc specdisplay'];

%%
% The |force| command applies stimulus to the clock and reset signals.
tclcmd = [tclcmd, 'force sim:/specdisp_top/clk_enable 1 0',...
                  'force sim:/specdisp_top/reset 1 0, 0 20 ns',...
                  'force sim:/specdisp_top/clk 1 0 ns, 0 40 ns -r 80ns'];


% Add "if any" user tcl commands at the end.
if exist('UsrTclCmds','var')
    tclcmd(end+1)=UsrTclCmds;
end
%% Start ModelSim(R)
% Now we start ModelSim via the vsim command.  The |'tclstart'| property
% causes the specified Tcl commands to be run at startup.  To run the
% simulation, use the run command in ModelSim, specifying the appropriate
% simulation time. For example type |run 100000| in ModelSim.
% We see the figure updating as the simulation proceeds.
% Be sure to quit ModelSim and shut down the MATLAB server by using
% |hdldaemon kill| once you are done with this example as each time the example
% is run, a new ModelSim is started.
% we can also specify RunMode='Batch' or 'CLI' or 'GUI' before running this
% example. If unspecified the default run mode is 'GUI'.

if exist('RunMode','var')
    vsim('tclstart',tclcmd,'runmode',RunMode);
else
    vsim('tclstart',tclcmd);
end


displayEndOfDemoMessage(mfilename)
