# Can you interface a Modelsim testbench with an external stimuli

I am working on a team that is doing both driver software and FPGA development. The FPGA simulation is being done in Modelsim and driver software is written in C. To minimize integration risk, I would love to be able to model the interaction between the two halves of our product before putting it on hardware.

I know Modelsim supports a testbench which lets you provide stimulus in the form of a text file with times and values to input. I'm wondering if Modelsim has a mode which allows you to hook up a pipe to an external application (such as our driver), and run a sort of distributed simulation where the software can push values into the testbench, then observe the results later.

The trick that I cannot do with a text file input is have the two halves of the product interact. I need to have the software "write" values into the FPGA simulator, read the results, and then write new values into the FPGA which are dependent on the results it read. Text files require the inputs to be independent from the output.

I've done searches on both StackExchange and google, but I have not been able to come up with a set of keywords to narrow my search enough to either identify the behavior I am looking for, or determine that it does not exist.

External Control of a ModelSim Simulation Via Unix Named Pipes

Abstract: In this thesis, we present a method of controlling a ModelSim simulation via an external program. Communication between ModelSim and the external program is accomplished by using Named Pipes ("FIFOs"), which appear as normal files to each application. The main difference between using FIFOs versus normal files for Inter-Process Communication (IPC) is that an application attempting to write to a FIFO is paused until another application attempts to read from the FIFO and vice-versa. This improves reliability of the IPC. The major advantages of this method are 1) Since only generic file operations are used, the external application can be written in nearly any programming language; 2) It gives the verification engineer the ability to reuse standards-validation software packages with minimal rewriting; 3) By having multiple Devices Under Test (DUT) communicate with each other, a more accurate simulation of the final system can be created; and 4) Performance of the overall simulation can be increased easily on a Single-System Image (SSI) cluster or multiprocessor computer even though ModelSim's simulation engine is not multi- threaded. Due to its implementation of file input/output (I/O) for behavioral VHDL, ModelSim cannot read or write these FIFOs directly. A workaround for this limitation is demonstrated using ModelSim's Foreign Language Interface (FLI). This paper also shows a working example of this method being used in the verification of the next generation of floating point routines in VHDL. Specifically, the open-source IEEE Compliance Checker software package, which is written in C++, is modified to communicate with a VHDL testbench running on ModelSim to verify functionality of the add, multiply, divide, and square root operations with various widths of floating point numbers.

And the issue with FIFOs requiring a Foreign programming interface is that VHDL file I/O can't deal gracefully with blocking until data is available.

Unfortunately the thesis isn't available on the web.

Model Sim ® Foreign Language Interface Version 5.6d, PDF 3.4 MB.

Using ModelSim Foreign Language Interface for c – VHDL Co-Simulation and for Simulator Control on Linux x86 Platform (The matching github code repository).

There's a bit more open source, using the VHPI Foreign function calls in ghdl: vhdl/src/sim/ghdlex_mein at master · texane/vhdl · GitHub.

And what looks like an update from Martin Strubel on the GHDL_discuss list: http://www.section5.ch/downloads/ghdlex-0.051.tgz showing a date for fifo.c of April 14, 2014.

FLI would by definition lock you in to Modelsim, not sure of the state of their VHPI support (which is part of IEEE Std 1076-2008, the VHDL LRM).

Using a socket or file FIFO allows the software and hardware process to run at different rates, by providing rate buffering. It isn't always necessary if you're software system is orders of magnitude faster than the hardware simulation (and it generally is).

There's an effort to provide UNIX (POSIX) functionality to VHDL, See Public Domain VHDL packages, which contains a pointer to an earlier paper SNUG San Jose 2002 1 C/UNIX Functions for VHDL Testbenches C/UNIX Functions for VHDL Testbenches along with a slide set with additional notes on Unix pipes & rsh. This shows how to keep named pipes opened. All the VHDL code can be downloaded as well. I'm of the opinion this would lead to the easiest way of achieving your goal.

So is there something native to Modelsim that allows you to hook up to a pipe? Likely not, the more so under Windows. Can it be done? Yes, but the way isn't for the fainthearted. You can deadlock one end or the other or possibly both waiting on data availability.

A Foreign programming interface theoretically allows you to spawn a child process for one or the other end of the 'pipe' which also means you could use a shared memory model to communicate between the two ends.

• Thank you for the wonderfully researched answer! "Foreign Language Interface" was exactly the phrase I needed to pull up the reference documentation I need, I just would have never guessed it! Early integration here I come! – Cort Ammon Apr 18 '14 at 0:28

You might want to look at Cocotb. It's a Python based co-simulation library, one of the design goals was to enable the methodology you describe, easily simulating un-modified production software and RTL.

There's an example in the repository of running unmodified ping command against a simulation and a tutorial walking through the code.

For user-space drivers, configuration utilities etc. you have a couple of options to run your software un-modified:

1. If your accesses to the device boil down to a few functions (e.g. a read and a write call) you can link against a simulation library which block while performing the access against the simulation. This works very well for configuration.

2. If your software uses memory mapped IO and dereferences pointers to access the device then things get slightly more complex - you have to create a shared memory area with protection bits set and trap accesses.

If you use networking then virtual interfaces like TUN/TAP can be used (see the tutorial mentioned above), I suspect there may be similar options for USB transfer or other common host interfaces.

Cocotb works with a variety of simulators and VHDL (via VHPI) or Verilog/SystemVerilog designs (via VPI). Unfortunately Modelsim doesn't implement VHPI so as a VHDL user you're stuck with FLI, which is not nearly so useful as an interface. You could moan at Mentor to try and persuade them to implement an industry standard interface, or you could evaluate another simulator that supports VHPI.

Sadly, it appears that tool vendors in general aren't particularly interested in the VHDL market, judging by the time it takes them to implement any VHDL related functionality...

Disclaimer: I'm a Cocotb developer.