%% Implementing the Filter Component of an Oscillator in MATLAB(R)
% This examples shows how MATLAB(R) and HDL Verifier can be used to 
% implement a filter component used in a VHDL model.  
% The example compiles a VHDL oscillator, defines a filter component
% that is modeled using MATLAB, and runs the ModelSim(R) simulation.
% This example requires a temporary 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.
%     

%%
% In this example, a VHDL oscillator has been designed and our job is to find
% a cleanup filter for the oscillator that meets our needs. 
%  
% The first FIR filter is a 31st order (32-tap) filter with no
% oversampling. The second filter is a 127th order (128-tap) filter
% with 4X oversampling. The third filter is a 255th order (256-tap)
% filter with 8X oversampling. All three filters share the same delay
% line and the oversampling is implemented using the polyphase technique.

   
%%
% The file *<matlab:editModelSimDemoFile('modsimosc','vhdl/osc/simple_osc.vhd') 
% simple_osc.vhd>* contains the simple oscillator designed in VHDL.
% 
% The file *<matlab:editModelSimDemoFile('modsimosc','vhdl/osc/osc_filter.vhd')
% osc_filter.vhd>* contains the MATLAB component that we are modeling.
% It contains an entity with an empty architecture.
% The matlabcp command drives the VHDL outputs and checks the VHDL
% inputs of the instance created from this entity
%   
% The file *<matlab:editModelSimDemoFile('modsimosc','vhdl/osc/osc_top.vhd')
% osc_top.vhd>* contains the top-level wiring between the oscillator
% and the MATLAB component. 
%
% The file
% *<matlab:editModelSimDemoFile('modsimosc','oscfilter.m')
% oscfilter.m>* contains the actual component behavioral model.
%
%
% You can also define variables "UsrTclCmds" and "RunMode" before calling 
% the MATLAB program 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','osc','simple_osc.vhd');
srcfile2 = fullfile(matlabroot,'toolbox','edalink','extensions','modelsim','modelsimdemos','vhdl','osc','osc_filter.vhd');
srcfile3 = fullfile(matlabroot,'toolbox','edalink','extensions','modelsim','modelsimdemos','vhdl','osc','osc_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,'\','/') '"']; 

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

if strcmp(computer,'PCWIN'),
    projdir = tempdir;  % Change to writable directory of your choosing
else
    projdir = tempname;
    if ~exist(projdir,'dir')
        mkdir(tempdir,strrep(projdir,tempdir,''));
    end
end


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');
% Use shared memory
if isempty(dstatus)
    % not running - start it
    dstatus = hdldaemon;    % tell user what's happening
elseif strcmp(dstatus.comm,'shared memory')
    % already running
    % user knows what's happening from previous hdldaemon('status')
elseif strcmp(dstatus.comm,'sockets')
    % running with different comm - stop and restart it
    disp('Shutting down HDLDaemon to restart it with shared memory');
    hdldaemon('kill');
    dstatus = hdldaemon;
else
    error(message('HDLLink:modsimosc:UnexpectedDaemonStatus'));
end

  

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

tclcmd = {  ['cd ',unixprojdir],...            
            'vlib work',... %create library (if necessary)
           ['vcom -performdefaultbinding ' unixsrcfile1],...
           ['vcom -performdefaultbinding ' unixsrcfile2],...
           ['vcom -performdefaultbinding ' unixsrcfile3],...
            'vsimmatlab  work.osc_top ',...
            'matlabcp u_osc_filter -mfunc oscfilter',...
            'add wave sim:/osc_top/clk',...
            'add wave sim:/osc_top/clk_enable',...
            'add wave sim:/osc_top/reset',...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.001 -offset 50000 ',...
            'sim:/osc_top/osc_out'],...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.00003125 -offset 50000 ',...
            'sim:/osc_top/filter1x_out'],...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.00003125 -offset 50000 ',...
            'sim:/osc_top/filter4x_out'],...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.00003125 -offset 50000 ',...
            'sim:/osc_top/filter8x_out'],...
            'force sim:/osc_top/clk_enable 1 0',...  
            'force sim:/osc_top/reset 1 0, 0 120 ns',...
            'force sim:/osc_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.  
% After launching ModelSim, to run the
% simulation, use the run command in ModelSim, specifying the appropriate
% simulation time. For example type |run 10000 ns| in ModelSim.
% 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

%%
% Now check results in the ModelSim plot window.  You will see the
% non-oversampled filter does little good, but the 4X and 8X oversampled
% filters look much better.
%
% <<wave1.jpg>>


%%
% This concludes this example.
%
% Be sure to quit ModelSim once you are done with this example as each
% time the example is run, a new ModelSim is started.


displayEndOfDemoMessage(mfilename)
