MATLAB AND MODELSIM LINKING

DR.S.S.Limaye

Introduction: MATLAB is powerful software package for mathematical
simulation, especially when signals are represented in an abstract i.e.
mathematical form. When we want to test a hardware system in terms of the
abstract inputs and outputs, linking Modelsim VHDL or Verilog simulator with
MATLAB is very helpful. The most beneficial use could be to write a test
bench for the HDL model in MATLAB. The test cases can be generated in
MATLAB at a higher level of abstraction, making it suitable for regression
testing with random inputs. Given the ease of interfacing, this provides a
very attractive alternative to Verilog PLI or VHDL FLI programming. It can be
even considered as a serious alternative to e, vera, system C or system
verilog languages.
Configuring: For the link to work, Modelsim has to be invoked from the
command prompt of MATLAB. For this purpose, MATLAB needs to know the
location of MODELSIM. Install MATLAB and MODELSIM on your computer.
Open MATLAB and type following command.
>>configuremodelsim
The system responds with following:
Do you want configuremodelsim to locate installed ModelSim executables
[y]/n?
Press y
If it finds Modelsim properly installed, it responds with following:
[1] C:\Modeltech_6.2c\win32
ModelSim SE 6.2c
[0] None
Select ModelSim installation to be configured:
Press 1
System responds with following:
ModelSim successfully configured to be used with MATLAB and Simulink

Invoking socket server

MATLAB and Modelsim communicate with each other either through shared
memory server or through TCP/IP links using socket calls. If MATLAB and
Modelsim are running on different machines then TCP/IP link is mandatory.
For same machine, shared memory is preferable. For inter process
communication, MATLAB starts a server called HDLDaemon. For shared
memory mode, give command:
hdldaemon
The system should respond with
HDLDaemon shared memory server is running with 0 connections
In case of trouble, try following steps.
type following command to first check the status:
>>hdldaemon('status')
MATLAB should normally respond with:
HDLDaemon is NOT running

give following commands: ModelSim> vlib work ModelSim> vmap work work . we are creating it as C:\MODELSIM_PROJ.all. library IEEE. Enter the above program and save it as “adderfile. b : in std_logic. In Modelsim command window. Remember this number as it will be required for the Modelsim connection later. give dir command and make sure it is pointing to C:\MODELSIM_PROJ. a b cin FULL ADDER sum cout The program listing is given below. Invoke text editor by pressing File> New> Source> VHDL. end adder. Note that the entity name is “adder”. use IEEE.vhd”. Developing VHDL program Let us start with a small VHDL program for implementing a full adder. cin : in std_logic. cout : out std_logic). sum : out std_logic. cout <= (a and b) or (cin and a) or (cin and b). MATLAB will respond with: HDLDaemon socket server is running on Port portnum with 0 connections Where portnum is a socket port number assigned by the OS.If a previous instance of HDLDaemon is running. Invoke Modelsim compiler from MATLAB command window with command: >>vsim In Modelsim command window. entity adder is port (a : in std_logic. architecture rtl of adder is begin sum <= (a xor b) xor cin. Change MATLAB current directory to above. end rtl. 0) 0 tells the OS to allocate the next available port. In our demo. it needs to be killed with the command: >>hdldaemon('kill') MATLAB will respond with: HDLDaemon server was shut down For socket mode. start the HDLDaemon with the command: >>hdldaemon('socket'. Create a folder outside MATLAB.std_logic_1164. Remember this as it will be required during invocation of the simulator.

In our example. In synchronous systems. then we can convert it like this: op = bin2dec(oport. function [iport.y'). oport.sum. However it is possible to avoid the test bench wrapper in VHDL and generate the clock and all other port signals in MATLAB. then the function returns an array with same length as val. Developing MATLAB test bench The test bench consists of a MATLAB callback function that gets invoked either after a given delay or at rising edge (or falling edge) of any desired port signal. We can use following functions to convert VHDL values to numeric values.L. this structure will have following fields: oport. If there are errors. Suppose the DUT has a vector output signal named val. Note the quote mark after val which takes its transpose. end tnow Current simulation time in seconds. then the oport members will be arrays of matching length. correct them and again compile till they are removed.X.cout The values of these ports will be one of the 9 values of VHDL. namely U. Double click on adderfile. b = 2^length(oport. By default. tnow.tnext] = ADD_TESTER (oport. If the port signals are of the type STD_LOGIC_VECTOR.W.H.y(1) == '1' .-. Since the present example is asynchronous.2^length(oport. usually it is the clock signal. This parameter is . the name of the MATLAB callback function is same as the VHDL entity name but we can choose any other name for it and inform it to the simulator with the “-mfunc” switch. bin2dec(oport. If the port output signal (y) represents a signed integer. subtract MSB weight op = op .Either press compile menu or press compile tool button to invoke “COMPILE SOURCE” dialog box.y). if oport. If you wrap the DUT in a VHDL test bench and generate clock as a part of the VHDL test bench then the callback function will be periodically invoked with the clock.vhd. If you don’t use the quote. there is no clock in the device and hence we will generate all the input signals in MATLAB.1.0.y). It will be represented as a character string will typically look like ‘0110X’. portinfo) Input parameters Oport – It is a structure having one member for each VHDL output port signal. The prototype of the callback function is as follows.val') is used to convert STD_LOGIC_VECTOR to unsigned integer. If sign bit is set. The file gets compiled. portinfo: For the first call to the function (at the start of the simulation) only.Z. this parameter receives a structure whose fields describe the ports defined for the associated VHDL entity or Verilog module.

out.-.size. We can apply stimulus to the DUT inputs by setting the desired values on the iport members. Using this information it is possible to validate the signals or to create a generic MATLAB function that operates differently depending on the port information supplied at startup. use mvl2bin(x. The size of a port.1.g. For signed integers. label. label. direction.c type. We can check whether portinfo data has been passed with a call to the MATLAB function nargin.in. For example: if(nargin == 3) The information is supplied in four fields. .5).cout type. unsigned integers in MATLAB can be converted to a VHDL compatible string with dec2bin function. The Simulator tick size in seconds can be accessed in MATLAB with the statement portinfo. size portinfo. iport iport (DUT input ports) – This is a structure similar to oport.a = ‘1’.tscale In our example. tnext Time for next invocation of MATLAB test bench.out.H. and size is 1. label.val = dec2bin(x.b type.W. tnext = tnow + 100e-9. size portinfo.cout.5).0. For each port. For example.a type.in. and size. it can be assigned the value of an unsigned integer x as: inport. In our first example.tscale. if you have a 5 bit input port named val. size portinfo.out portinfo. label. It can be given directly in seconds e.in.skipped in subsequent calls. type of all signals is std_logic. Single bit values can be assigned as: iport.L. For vector inputs.X. label.Z.out.sum type. the portinfo structure passes information such as the port's type. label is U. size portinfo. size portinfo.in portinfo. or in terms of simulator time steps (If configured this way): tnext = ‘100’. we are ignoring this parameter.Inout null portinfo. Field Subfields Sub sub fields portinfo. Input parameters The input parameters of the DUT are supplied to the simulator through the output of the callback function. say cout can be accessed by statement portinfo.

%Convert counter to binary string iport.b = '0'. function [iport.cin. we reinvoke the function after 100 ns. The next invocation should then be based on transition of a specified signal.3).a = '0'. it is useful to define a persistent (similar to static in C) type variable (named ud here) to store variables that retain their values from call to call.cin. tnow. iport. portinfo) persistent ud. iport.call_count. give command VSIM 3> matlabtb adder -mfunc ADD_TESTER -socket portnum Where portnum is the port number returned by the HDLDaemon . Testing of full adder In the callback routine.cin = bin(3). %Assign bits of bin to 3 inputs iport. Here we are using ud. %Create a struct to store persistent user data %initialize tnext to null %initialize iport to null if(nargin ==3) %First call has 3 arguments ud.call_count + 1.cin = '0'.b. iport = struct(). don’t invoke with tnext end end Invoking Modelsim Give following command on the Modelsim prompt to load the ADDER entity for simulation.call_count = 0. As long as the call count is less than 8.call_count to count the number of calls to the callback routine.b = bin(2). We want to give all possible combinations on a. %Next invocation after 100 ns bin = dec2bin(ud.b. iport. if ud. tnext = [].%Next invocation after 100 ns iport. else disp('Over').tnext] = ADD_TESTER (oport.If you don’t want invocation after a fixed time. else ud. This DUT has 3 inputs – a. %If 8 cycles are over. then you can leave the vector null. The complete MATLAB program is given below.b.call_count < 8 %run for 8 cycles tnext = tnow+100e-9. %Initialize call counter tnext = tnow+100e-9.call_count = ud. ModelSim> vsimmatlab adder Now link it to MATLAB test bench with the command at the VSIM prompt: VSIM 3> matlabtb adder -mfunc ADD_TESTER If you are using the socket mode. A convenient way to generate the input sequence is to convert the call count into a bit string with dec2bin function and apply its individual bits to the inputs a.cin and 2 outputs – sum and cout.a = bin(1).

USE IEEE.Limaye.ALL. . Testing of FIR filter The VHDL code of an 8 tap linear phase FIR is given below.In the Modelsim window. McGraw Hill India. USE IEEE.. PACKAGE FILT IS TYPE CONST_ARRAY IS ARRAY(POSITIVE RANGE <>) OF SIGNED(7 DOWNTO 0). For the details of design. It takes an 8 bit signed integer x and produces 8 bit signed integer y. USE IEEE.ALL.rectwin(7). END PACKAGE.25. --USE DEFINITION OF CONST_ARRAY LIBRARY IEEE.ALL. USE IEEE. you may insert suitable break points.STD_LOGIC_ARITH. by Dr S. Press the “run all” tool button.S.ALL.STD_LOGIC_1164. USE IEEE.ALL.STD_LOGIC_ARITH. one eighth of sampling frequency.'noscale') --8 TAP LINEAR PHASE FIR FILTER LIBRARY IEEE. It is a low pass filter having cut off frequency of /4 radians.STD_LOGIC_SIGNED. add all signals in the design to the waveform viewer.STD_LOGIC_1164.e.STD_LOGIC_SIGNED. If you want to debug the MATLAB function. ENTITY FIRFILT8 IS GENERIC(CON:CONST_ARRAY := ("00110110".FILT.ALL.ALL. USE WORK. USE IEEE. using the GUI commands. i.'low'. refer to VHDL – a design oriented approach. The waveforms of input and output should appear in MATLAB and VHDL. The filter coefficients can be calculated with MATLAB command: fir1(6.

setting X to 0 and then starts invoking itself after every 100 ns. In each invocation. The user data area ud stores the call count and it is used as the index for arrays that store X and Y ."00110001".SCALED FROM -. -.RST) BEGIN IF RST = '1' THEN XA <= (OTHERS => "00000000")."00010000")). FOR I IN 1 TO XA'HIGH-1 LOOP XA(I+1) <= XA(I). Y:OUT SIGNED(7 DOWNTO 0). CLK.UNPAIRED CENTER ELEMENT FOR I IN 1 TO (CON'HIGH .25..1592. END LOOP.CLK. END PROCESS SHIFT_PROC.2) OF SIGNED(7 DOWNTO 0). BEGIN --INPUT X IS NOT PART OF DELAY LINE XA -.35.. Y <= SUM(15 DOWNTO 8). END LOOP. SUM := SUM + XA(CON'HIGH-1) * CON(1). ELSIF CLK'EVENT AND CLK = '1' THEN XA(1) <= X."00100011".--SIGNAL DELAY LINE BEGIN SHIFT_PROC:PROCESS(XA.49.54.--FORCE IT TO 9 BITS SUM := (SUM1(8) & SUM1(8) & SUM1) * CON(CON'HIGH).HANDLE IT SEPARATELY SUM1 := (X(7) & X) + XA(XA'HIGH). SUM := SUM + SUM2 * (CON(I+1)). END RTL. The MATLAB test bench initializes the filter by activating RST for 100 ns. SIGNAL XA:X_ARRAY.16 .X.X) VARIABLE SUM :SIGNED(18 DOWNTO 0). 100 sin(X) is computed and applied to X. VARIABLE SUM2:SIGNED( 8 DOWNTO 0).075 CUT OFF AT PI/4 PORT(X:IN SIGNED(7 DOWNTO 0). END FIRFILT8.. END IF. VARIABLE SUM1:SIGNED( 8 DOWNTO 0). END PROCESS SUM_PROC. -.. ARCHITECTURE RTL OF FIRFILT8 IS TYPE X_ARRAY IS ARRAY(1 TO 2*CON'HIGH .2) LOOP--OTHER ELEMENTS IN LINE SUM2 := (XA(CON'HIGH-I-1)(7) & XA(CON'HIGH-I-1)) + XA(CON'HIGH+I-1). SUM_PROC:PROCESS(XA.2251.RST:STD_LOGIC).

ud. op = bin2dec(oport. portinfo) persistent ud.plot(ud.clk = '0'.10).clk = '1'. end ud.2). end end SIMULINK and MODELSIM ADDER example: Creating simulink model: .clk = '0'. %x= 100.ud.rst = '1'.y(1) == '1' op = op .1. ud.Y). MATLAB TEST BENCH % FIR_TESTER function [iport. iport. else iport. if ud. ud.X(ud. tnext = tnow+100e-9. %initialize tnext to null iport = struct(). the X and Y values are plotted in a graph. tnow. else iport. %initialize iport to null if(nargin ==3) %First call ud.y).call_count)= op.y'). if oport.call_count + 1.tb_clk = 0. The MATLAB code is given below. %Create a struct to store persistent user data tnext = []. x = 125 * sin(ud.x = dec2bin(0. ud. %op = bin2dec(oport.y).y')/256.X = zeros(1. end else subplot(2.10).8). iport.subplot(2.plot(ud. if ud. b = 2^length(oport.call_count = 0.X).tb_clk == 0 iport.x = dec2mvl(x. ud.tb_clk = 0.call_count * 3* pi/8).tnext] = FIR_TESTER (oport. iport.rst = '0'.Y(ud.tb_clk = 1. At the end. iport.8).Y = zeros(1.values. ud.1).2^length(oport.1.call_count < 50 tnext = tnow+100e-9.call_count)=x. disp('Over').call_count = ud.

Timescales. then enlarge the window. Delete all of them one by one by selecting the line and pressing the Delete button to the right. In a similar manner. Enter the simulation stop time as 40 s. cout. Invoke simulink from the MATLAB command prompt by typing the command “simulink” or by clicking the simulink icon. the Ports tab is selected. In the simulink library window. Press OK . The model will be created in the adder folder. If the button is not visible. Add a new line by pressing the New button. Double click on the block to invoke the Function Block Parameters dialog box as shown below. Select “Link for Modelsim” library in the left pane and “HDL cosimulation” block from the right pane. make entries for inputs b. connection and Tcl. enter sample time as 1. Drag it to the center of the new model. leaving space for the stimulus generator on the left side and scope on the right. In the edit box under title Hull HDL name. The dialog box should now look like this. It shows one input port named sig1 and two input ports named sig1 and sig2. This box has tabs for configuring Ports. cin and outputs sum. By default. we will embed the previously created adder block in a simulink model. For the output ports. select File>New>Model.In this example. enter /adder/a and choose I/O mode as Input. Press the Update button situated in the bottom right corner. Clocks. indicating that the output is updated in every cycle.

In the simulink library browser. Now let us create a stimulus generator block. In the right pane. Click on its caption and change it to “3 bit counter”. Double click on it to open its edit window. Select Timescales tab. select “Ports & subsystems”. Press the connection tab and observe that the connection method is shared memory. select “configurable subsystem” and drag it to the left of the HDL cosimulation block. Don’t use the Tcl tab. Thus 1 step of simulink running (40s) advances the Modelsim simulator by 400 ns. By default. We want to show the input and output signal in MATLAB as well as Modelsim. in tab “simulink”. Modelsim tick is configured for 1 ns. The model should look like this when completed. . cin is to create a 3-bit counter and apply its individual bits to the three inputs. We need to add stimulus generator and scope blocks. Make 1 second in simulink correspond to 10 ticks in Modelsim. b. don’t use the clocks tab. We will create the stimulus generator as a subsystem. A convenient way to apply exhaustive input combinations to the inputs a. When completed. Press OK.Since we are not using clock. it should look like this.

select Communication blockset> Utility blocks> Integer to bit converter and drag it to the right of the counter. type vsimulink adder The adder entity gets loaded. Double click on it to open its block parameters window and set the upper limit to 7. (One extra bit is required for proper operation of the index vector blocks. Place three constant blocks from the simulink> commonly used blocks library to the left of the index vector blocks and connect them to the select inputs. it cycles through 0-7. Note that the index 1 corresponds to the MSB and the index 3 corresponds to the LSB. cin. click on the parameter tool button (Second from left) and set the number of axes to 5.In the initial state. Double click on the constant blocks and set their values as 1. Running simulation In MATLAB test bench. Double click on it to invoke its display window. b. we use three index vector blocks. Simulink is the master and it calls VHDL simulator for the evaluation of the VHDL block. sum and cout. Add all signals in the design to the waveform viewer. To pick up its individual bits. The scope block in the model now shows 5 inputs. on MATLAB prompt. In the simulink library browser. Connect them to a. Add two more output ports from the library simulink> Ports and subsystems> Out1. 2. 3. Invoking Modelsim The adder entity has been already developed in the previous exercise. The simulation is started by clicking the “run all” button in the Modelsim window. Delete the input port and the connecting link. In this window. In Simulink method. The simulation starts by clicking the “run” button of the simulink . the VHDL simulator is the master and it calls the MATLAB callback function when programmed. Select them from the library by clicking simulink> signal routing> index vector. As in previous exercise. Save the model as adder_simulink.e.) Also. select simulink> sources> counter limited and drag it to the 3-bit counter window. Connect the output of the Integer to bit converter block to all the index vector blocks. The output of the Integer to bit converter block is a bit vector. In the simulink library browser. type: Hdldaemon The system should respond with HDLDaemon shared memory server is running with 0 connections Now type vsim This invokes Modelsim. Connect the outputs of the index vector blocks to the corresponding output ports. it has an input port connected to an output port. In the Modelsim command window. set its output data type as Boolean. Save the design and return to the main model. Add a scope from simulink> sinks library. Double click it to open its parameters dialog and set the number of bits per integer to 4. i.

model window. We can observe waveforms in both windows. In the simulink library browser window. Double click on the HDL cosimulation block to invoke the Function Block Parameters dialog box. make following settings. The untitled model editor window opens up. By selecting the ports tab. Drag the block “Link for Modelsim”> “HDL cosimulation” to the model editor. Click the menu simulation> configuration parameters to invoke the configuration parameters dialog box. The simulation will run for 40 simulated seconds in simulink and 400 ns in Modelsim. We have already saved the VHDL code for FIR filter in this directory. In the right pane. Start simulink library browser either by typing simulink on the command prompt or by clicking on simulink tool button. click the icon for new model file. Set the tasking mode to single tasking. Select the solver tab in the left pane. Set the solver to discrete (no continious states). Set the type as fixed step. change the port values to look like this: . Click OK. FIR FILTER in Simulink Change the MATLAB current directory to c:\Modelsim_proj\FIR.

. Save the model as fir_simulink. Press OK. Following results should appear. In this window. Connect the sine wave to converter and converter to x. Since this is a continuous type block. Set its output data type mode to Boolean. Double click its icon. first type hdldaemon. click on the parameter tool button (Second from left) and set the number of axes to 3. The scope block in the model now shows 3 inputs. In the Modelsim window. Connect the signal builder to the zero order hold and the zero order hold to RST input of Modelsim. In the fir_simulink model window. From the simulink> sources library. From the simulink> sources library. amplitude to 1. and then vsim. drag the converter block to the model editor. drag the pulse generator block to the model editor. drag the vertical lines so that we have a high pulse of 1 sample duration. So we will use a signal builder block. Connect pulse generator to converter and converter to CLK input of Modelsim. type vsimulink firfilt8. Press OK. For reset pulse. there is no suitable readymade block. Set its output data type mode to Int8. Double click its icon. amplitude to 100. Connect them to x. click the “run” button. Sample time should be 2 because the clock period is 2. Double click its icon. period to 2 and pulse width to 1 and sample time to 1. Add a scope from simulink> sinks library. From the simulink> sources library. Double click its icon. From the simulink> sources library. convert it to a discrete type by using a zero hold from simulink> discrete library. drag the signal builder block to the model editor.y and reset. Set its pulse type to sample based.Do not change any other tabs. drag the sine wave block to the model editor. Double click its icon. From the simulink> sources library. Set its sine type to sample based. Double click on it to invoke its display window. drag the convert block to the model editor. Running the simulation On MATLAB prompt. In the signal builder window. samples per period to 16 and sample time to 2.