{"id":3680,"date":"2026-07-15T11:34:13","date_gmt":"2026-07-15T03:34:13","guid":{"rendered":"http:\/\/manufacturing.wiki\/?p=3680"},"modified":"2026-07-15T11:34:14","modified_gmt":"2026-07-15T03:34:14","slug":"third-party-simulation-tools-for-on-site-programmable-gate-arrays-connection","status":"publish","type":"post","link":"http:\/\/manufacturing.wiki\/index.php\/2026\/07\/15\/third-party-simulation-tools-for-on-site-programmable-gate-arrays-connection\/","title":{"rendered":"Third-party simulation tools for on-site programmable gate arrays connection"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">FPGA Third-Party Simulation Tool Integration: A Complete Guide to Connecting Your Verification Flow<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Most FPGA engineers hit the same wall eventually. The vendor&#8217;s built-in simulator works fine for a quick check, but when you need serious debugging, code coverage, or mixed-language verification, it falls apart. That is when you reach for a third-party simulator. The problem is not the simulator itself. The problem is getting it to talk to your FPGA toolchain without spending three days on configuration files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide covers how to actually connect third-party simulation tools to the major FPGA development environments. No fluff. No brand worship. Just the steps that work.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why You Would Even Want a Third-Party Simulator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The integrated simulators that ship with FPGA toolchains are convenient. You click a button and a waveform pops up. But convenience has limits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vendor simulators often lag behind in language support. SystemVerilog features, UVM methodologies, and advanced debugging tools tend to arrive later in the vendor ecosystem than in dedicated simulation platforms. When your testbench grows beyond a few hundred lines, you start feeling the gap.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Third-party tools also give you portability. Your simulation scripts do not care which FPGA vendor you target. The same testbench runs against Xilinx primitives today and Intel primitives tomorrow. That kind of flexibility saves weeks when you switch projects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Integration Actually Works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At a high level, the connection between an FPGA toolchain and a third-party simulator comes down to three things.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Simulation libraries. These are pre-compiled models of the FPGA fabric. LUTs, flip-flops, block RAMs, PLLs, SERDES transceivers. The simulator needs these to know what a Xilinx BUFG or an Intel altpll actually does at the behavioral level.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configuration files. The simulator needs to know where those libraries live. This is usually handled through an ini file or a library mapping file that tells the simulator which compiled library corresponds to which FPGA primitive.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Launch scripts. The FPGA toolchain generates a set of commands that compile your design, load the testbench, and fire up the simulator. This can be a TCL script, a shell script, or a do file depending on the tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Get these three right and everything else is just clicking buttons.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Connecting ModelSim or QuestaSim to Vivado<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the most common combination in the industry. Vivado generates the design, Modelsim or QuestaSim runs the verification.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Compiling the Simulation Libraries<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Vivado ships with a built-in command to compile all the necessary libraries for your target device family. Open Vivado, go to Tools, then Compile Simulation Libraries. Select your simulator, pick the language (Verilog or VHDL or both), choose the device family, and point it to an output directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The tool then calls the simulator&#8217;s compiler in the background and builds everything. This can take anywhere from five minutes to thirty minutes depending on how many device families you selected. Do not interrupt it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When it finishes, check the output directory. You should see folders like unisims_ver, unimacro_ver, and secureip. These are your simulation libraries.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Wiring the Configuration File<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the step most people miss. The compiled libraries exist on disk, but Modelsim does not know about them yet. You need to update the modelsim.ini file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Find the modelsim.ini that lives in your Modelsim installation directory. Open it and add a line pointing to the library path you created earlier. It should look something like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1&#91;Library]\n2unisims_ver = C:\/Xilinx\/Vivado\/2024.1\/data\/verilog\/src\/unisims\n3unimacro_ver = C:\/Xilinx\/Vivado\/2024.1\/data\/verilog\/src\/unimacro\n4<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Save the file. Restart Modelsim. The libraries should now appear in the Library panel when you compile your design.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Running Simulation From Vivado<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once the libraries are wired, go to Flow, then Simulation Settings. Set the simulator to Modelsim or QuestaSim, point it to the simulator executable, and specify the library path. Now when you click Run Simulation, Vivado generates all the files, launches the simulator, and you see your waveform.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want more control, use the TCL console. The command&nbsp;<code>launch_simulation<\/code>&nbsp;gives you full access to every option without going through the GUI.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Connecting ModelSim to Quartus Prime<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Quartus takes a slightly different approach. Instead of a separate compilation step, Quartus can generate simulation files directly from the project.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Setting the Tool Path in Quartus<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Go to Tools, then Options. Find EDA Tool Options under the General category. Enter the full path to your Modelsim executable. For example.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1C:\/modeltech64_2024.1\/win64\/vsim.exe\n2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure the path has no Chinese characters and no spaces. This causes more problems than anything else in the entire flow.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Generating the Simulation Netlist<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In your project settings, go to EDA Tool Settings, then Simulation. Set Tool name to ModelSim-Altera. Choose your output format (Verilog or VHDL). Set the top-level module and make sure Compile test bench is enabled.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quartus then generates a simulation directory under your project root. Inside you will find the compiled netlist, a testbench template, and a modelsim.ini file. Open Modelsim, create a new project in that directory, add all the generated files, and you are ready to simulate.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The Testbench Template Trick<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Quartus can auto-generate a testbench template for you. Go to Processing, then Start Test Bench Template Writer. This creates a skeleton testbench with the correct port mappings. You still need to write the stimulus yourself, but at least the boilerplate is done.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One thing to watch for. If your design uses Altera-specific IP like PLLs or FIFOs, make sure the simulation libraries include altera_mf. You may need to manually add this library to your Modelsim project.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Working With Domestic FPGA Toolchains<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The integration pattern is the same for non-Western FPGA vendors, but the details differ.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pango Design and Modelsim<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Pango Design Suite (used with Logos series devices) has a dedicated menu for this. Go to Tools, then Compile Simulation Libraries. Set the simulator executable path to your Modelsim vsim.exe. Set the output directory to a clean folder with no spaces in the path. Click Compile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When it finishes, copy the generated modelsim.ini to your Modelsim installation directory. Replace the existing file. This registers all the Pango-specific primitives with the simulator.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">TD Software and Modelsim<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For Anlogic EF2 series devices using TD software, the flow is similar. TD generates simulation models for the FPGA fabric. You compile those models into a Modelsim library using the vlog command. Then you add the library path to your modelsim.ini.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The directory structure matters here. Keep TD project files separate from Modelsim work files. A clean layout looks like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1project_root\/\n2\u251c\u2500\u2500 td_project\/\n3\u2502   \u251c\u2500\u2500 src\/\n4\u2502   \u2514\u2500\u2500 constraint\/\n5\u251c\u2500\u2500 modelsim_work\/\n6\u2502   \u251c\u2500\u2500 anlogic_lib\/\n7\u2502   \u2514\u2500\u2500 modelsim.ini\n8\u2514\u2500\u2500 doc\/\n9<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This keeps your simulation environment reproducible. When a new engineer clones the repo, they run one script and everything works.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Integration Failures and How to Fix Them<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Library not found errors. This means your modelsim.ini is not pointing to the right place. Double-check the path. On Windows, the path separator is a backslash. Make sure you are not mixing forward and back slashes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Simulator launches but waveform shows X everywhere. The simulator loaded but could not find the primitive models. This usually means the unisim library is not mapped. In Modelsim, type&nbsp;<code>vmap<\/code>&nbsp;to see all mapped libraries. If unisims_ver is missing, add it manually.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Version mismatch crashes. Vivado 2024.1 expects Modelsim 2023.2 or later. If you try to use an older simulator, you get cryptic error messages. Check the compatibility matrix before you start.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Path with spaces or non-ASCII characters. This breaks TCL scripts silently. The tool does not throw an error. It just fails to find files. Always use paths like C:\/EDA\/Vivado\/ not C:\/Program Files\/Xilinx\/.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Building a Reusable Simulation Script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Do not rely on the GUI every time. Write a TCL script that does the full flow.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tcl1# Setup paths\n2set vivado_path \"C:\/Xilinx\/Vivado\/2024.1\"\n3set modelsim_path \"C:\/modeltech64_2024.1\/win64\"\n4set work_dir \".\/sim_work\"\n5\n6# Compile libraries\n7exec $vivado_path\/bin\/vivado -mode batch -source compile_libs.tcl\n8\n9# Launch simulation\n10exec $modelsim_path\/vsim -c -do \"do run_sim.do; quit -f\"\n11<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The compile_libs.tcl calls Vivado&#8217;s library compilation. The run_sim.do compiles your RTL, loads the testbench, runs the simulation, and dumps the waveform. One command. Every time. Same result.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is what separates a hobby project from a production flow. The script does not forget steps. The script does not click the wrong button. The script runs the same way on Monday morning and Friday afternoon.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Keeping Your Simulation Environment Clean<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Version control your simulation scripts. The TCL files, the do files, the modelsim.ini. All of it goes into Git. When someone breaks the build, you bisect to the exact commit that introduced the problem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not commit generated files. The compiled libraries are large and they change with every tool version. Commit the scripts that generate them, not the output.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use a separate work directory for each project. Modelsim caches compiled designs in the work library. If two projects share the same work directory, you get name collisions that are almost impossible to debug.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pin your tool versions. A simulation that passed last month might fail today if the vendor pushed a library update. Lock your Vivado and Modelsim versions in a configuration file and check them at the start of every build.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tcl1if {&#91;version -short] ne \"2024.1\"} {\n2    puts \"ERROR: Wrong Vivado version. Expected 2024.1.\"\n3    exit 1\n4}\n5<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That one check saves you from hours of chasing phantom bugs that are actually just version drift.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">ChipApex is a global distributor of electronic components: ICs, semiconductors, passives &amp; interconnects. Source active &amp; obsolete parts with wholesale pricing, fast RFQ response, and worldwide delivery.Official website address:chipapex.com<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>FPGA Third-Party Simulation Tool Integration: A Complet &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3680","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3680","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/comments?post=3680"}],"version-history":[{"count":1,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3680\/revisions"}],"predecessor-version":[{"id":3681,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3680\/revisions\/3681"}],"wp:attachment":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/media?parent=3680"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/categories?post=3680"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/tags?post=3680"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}