{"id":3672,"date":"2026-07-15T11:32:25","date_gmt":"2026-07-15T03:32:25","guid":{"rendered":"http:\/\/manufacturing.wiki\/?p=3672"},"modified":"2026-07-15T11:32:26","modified_gmt":"2026-07-15T03:32:26","slug":"call-of-the-on-site-programmable-gate-array-hardware-description-language-library-file","status":"publish","type":"post","link":"http:\/\/manufacturing.wiki\/index.php\/2026\/07\/15\/call-of-the-on-site-programmable-gate-array-hardware-description-language-library-file\/","title":{"rendered":"Call of the on-site programmable gate array hardware description language library file"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">How to Call Library Files in FPGA HDL: A Practical Guide for RTL Designers<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Every FPGA project eventually hits the same wall. You need a block RAM, a PLL, a SERDES transceiver, or a DSP slice. You do not want to write that from scratch. That is where library files come in. They give you pre-built, pre-verified hardware blocks that the synthesis tool maps directly to physical resources on the chip.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But calling those libraries the wrong way leads to simulation mismatches, synthesis failures, and hours of debugging. This guide shows you exactly how to call library files in both Verilog and VHDL, with the patterns that actually work in real projects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Library Files Actually Contain<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Library files in the FPGA world are not like software libraries. They are not linked at runtime. They are compiled into your design at elaboration time and become hard macro cells or mapped primitives.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are three main categories you will encounter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vendor primitive libraries. These contain the lowest-level building blocks: LUTs, flip-flops, carry chains, block RAMs, clock buffers, and I\/O pads. The synthesis tool knows exactly how to map these to the FPGA fabric.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">IP core libraries. These are larger, parameterized blocks: FIFOs, Ethernet MACs, PCIe controllers, memory controllers. They come as encrypted or compiled netlists and you instantiate them through a generated wrapper.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Standard cell libraries. Used mostly in ASIC flows, but some FPGA projects that target structured ASICs or use semi-custom flows still reference these for standard logic gates.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For most FPGA RTL work, you are dealing with the first two. Everything else is noise.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Call Vendor Primitives in Verilog<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The most common pattern is instantiating a primitive directly in your code. You do not need to import anything special for most basic primitives. The tool already knows them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Take a simple BUFG (global clock buffer) in Verilog:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1BUFG bufg_inst (\n2    .I(clk_in),\n3    .O(clk_global)\n4);\n5<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is it. No include statement. No library declaration. The synthesizer resolves&nbsp;<code>BUFG<\/code>&nbsp;automatically because it is a built-in primitive.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For block RAM, you use the RAMB18E1 or RAMB36E1 primitive depending on your device family:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1RAMB18E1 #(\n2    .INIT_A(18'h00000),\n3    .INIT_B(18'h00000),\n4    .READ_WIDTH_A(9),\n5    .WRITE_WIDTH_A(9)\n6) ram_inst (\n7    .CLKARDCLK(clk),\n8    .ADDRARDADDR(addr),\n9    .DIADI(din),\n10    .DOADO(dout),\n11    .WEA(we),\n12    .ENARDEN(en)\n13);\n14<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code>#(...)<\/code>&nbsp;block sets the configuration parameters. Each primitive has its own set of parameters, and the datasheet is your only source of truth. There is no shortcut here.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you need something the tool does not resolve automatically, you use the&nbsp;<code>unisim<\/code>&nbsp;or&nbsp;<code>secureip<\/code>&nbsp;library. For Xilinx devices, you add this at the top of your file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1`timescale 1ns \/ 1ps\n2\n3module my_design (\n4    \/\/ ports\n5);\n6\n7\/\/ Pull in the simulation library\n8`include \"unisim_vcomp.v\"\n9\n10\/\/ Now you can instantiate primitives like STARTUPE2, IDELAYE2, etc.\n11STARTUPE2 startup_inst (\n12    .USRDONEO(done),\n13    .USRCCLKO(cclk),\n14    .CFGCLK(),\n15    .CFGMCLK(),\n16    .EOS(),\n17    .PREQ(),\n18    .CLK(0),\n19    .GSR(0),\n20    .GTS(0),\n21    .KEYCLEARB(1),\n22    .PACK(0),\n23    .USRCCLKTS(0),\n24    .USRDONETS(1)\n25);\n26\n27endmodule\n28<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code>unisim_vcomp.v<\/code>&nbsp;file contains the simulation models for all vendor primitives. Without it, your simulation will show X everywhere because the simulator does not know what a BUFG or an MMCM looks like at the behavioral level.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Call Vendor Primitives in VHDL<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">VHDL is more explicit about library binding. You must declare which library you are using before you can instantiate anything from it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vhdl1library IEEE;\n2use IEEE.STD_LOGIC_1164.ALL;\n3\n4-- Vendor library for primitives\n5library UNISIM;\n6use UNISIM.VComponents.all;\n7\n8entity my_top is\n9    port (\n10        clk_in  : in  std_logic;\n11        clk_out : out std_logic\n12    );\n13end entity;\n14\n15architecture rtl of my_top is\n16begin\n17    bufg_inst : BUFG\n18        port map (\n19            I =&gt; clk_in,\n20            O =&gt; clk_out\n21        );\n22end architecture;\n23<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code>library UNISIM;<\/code>&nbsp;line tells the compiler where to look. The&nbsp;<code>use UNISIM.VComponents.all;<\/code>&nbsp;line makes every component in that library visible by its simple name. Without the&nbsp;<code>use<\/code>&nbsp;clause, you would have to write&nbsp;<code>UNISIM.VComponents.BUFG<\/code>&nbsp;every time, which gets old fast.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For Intel (Altera) devices, the equivalent library is&nbsp;<code>altera_mf<\/code>&nbsp;or&nbsp;<code>altera_lnsim<\/code>&nbsp;for simulation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vhdl1library altera_mf;\n2use altera_mf.altera_mf_components.all;\n3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then you instantiate things like&nbsp;<code>altsyncram<\/code>&nbsp;or&nbsp;<code>altpll<\/code>&nbsp;the same way.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Working with IP Core Libraries<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">IP cores are different from primitives. They do not live in a text file you can edit. They are delivered as compiled netlists, often encrypted, with a wrapper file that you instantiate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The workflow is always the same.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, you generate the IP core using the vendor tool (the GUI-based IP catalog). You configure the parameters: data width, depth, clock domain, interface type. The tool generates a ZIP file containing a wrapper module, constraints, and simulation files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then you add the wrapper to your project and instantiate it like any other module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/ This is the auto-generated wrapper from the IP catalog\n2fifo_generator_0 u_fifo (\n3    .clk(clk),\n4    .srst(rst),\n5    .din(data_in),\n6    .wr_en(wr_en),\n7    .rd_en(rd_en),\n8    .dout(data_out),\n9    .full(full),\n10    .empty(empty)\n11);\n12<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You never edit the wrapper. You never look inside it. You treat it as a black box. If you need to change the FIFO depth or width, you go back to the IP catalog, regenerate, and replace the files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For simulation, the IP package usually includes a behavioral model (a VHDL or Verilog file that simulates the FIFO using regular logic instead of the hard macro). You compile that model into your simulation environment and it matches the synthesized behavior cycle-accurately.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Mistakes That Break Library Calls<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The number one mistake is forgetting the simulation library. Your code simulates perfectly, then synthesis fails or the timing is wrong. That happens because the simulator used a generic model while the synthesizer mapped to a hard macro with different delays. Always simulate with the vendor library included.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The second mistake is parameter mismatch. Every primitive has a specific set of legal parameter values. If you set&nbsp;<code>INIT_A<\/code>&nbsp;to a value with too many bits, the tool either truncates silently or throws an error. Check the primitive guide for your exact device family. Parameters are not portable across families.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The third mistake is mixing library styles in the same file. Some engineers put&nbsp;<code>include<\/code>&nbsp;statements and&nbsp;<code>library<\/code>&nbsp;declarations in the same file without understanding the difference. In Verilog,&nbsp;<code>`include<\/code>&nbsp;is text substitution. In VHDL,&nbsp;<code>library<\/code>&nbsp;is a namespace binding. They solve different problems. Do not mix them hoping one will cover the other.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Clean Pattern for Organizing Library Calls<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Here is a pattern that scales across large projects. Create a single file called&nbsp;<code>vendor_libs.vh<\/code>&nbsp;(for Verilog) or&nbsp;<code>vendor_libs.vhd<\/code>&nbsp;(for VHDL) that all your modules include.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For Verilog:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1\/\/ vendor_libs.vh\n2`ifndef VENDOR_LIBS_VH\n3`define VENDOR_LIBS_VH\n4\n5`include \"unisim_vcomp.v\"\n6`include \"secureip.v\"\n7\n8`endif\n9<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then in every module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verilog1`include \"vendor_libs.vh\"\n2\n3module my_module (...);\n4    \/\/ primitives work now\n5endmodule\n6<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For VHDL, make a package that handles the library declarations:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vhdl1library IEEE;\n2use IEEE.STD_LOGIC_1164.ALL;\n3\n4package vendor_pkg is\n5    library UNISIM;\n6    use UNISIM.VComponents.all;\n7end package;\n8<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then in every entity:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>vhdl1use work.vendor_pkg.all;\n2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This keeps your individual module files clean and makes it impossible to forget a library declaration. When a new team member joins, they include one file and everything just works.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Library calls are not glamorous. But they are the difference between a design that compiles on the first try and one that takes three days to untangle. Get the library setup right at the start, and the rest of the project runs smooth.<\/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","protected":false},"excerpt":{"rendered":"<p>How to Call Library Files in FPGA HDL: A Practical Guid &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-3672","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3672","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=3672"}],"version-history":[{"count":1,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3672\/revisions"}],"predecessor-version":[{"id":3673,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/posts\/3672\/revisions\/3673"}],"wp:attachment":[{"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/media?parent=3672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/categories?post=3672"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/manufacturing.wiki\/index.php\/wp-json\/wp\/v2\/tags?post=3672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}