Implementing the Filter Component of an Oscillator in MATLAB®

MODSIMOSC shows how MATLAB® 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® 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.

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 simple_osc.vhd contains the simple oscillator designed in VHDL.

The file 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 osc_top.vhd contains the top-level wiring between the oscillator and the MATLAB component.

The file oscfilter.m contains the actual component behaviorial 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® 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
    projdir = tempname;
    if ~exist(projdir,'dir')

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');
    dstatus = hdldaemon;
    error('unexpected return value from hdldaemon(''status'')');
HDLDaemon is NOT running
HDLDaemon shared memory server is running with 0 connections

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 ',...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.00003125 -offset 50000 ',...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.00003125 -offset 50000 ',...
           ['add wave -height 100 -radix decimal -format analog-step -scale 0.00003125 -offset 50000 ',...
            '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;

Start ModelSim®

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')

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.

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.