未分类

Call of the on-site programmable gate array hardware description language library file

How to Call Library Files in FPGA HDL: A Practical Guide for RTL Designers

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.

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.

What Library Files Actually Contain

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.

There are three main categories you will encounter.

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.

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.

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.

For most FPGA RTL work, you are dealing with the first two. Everything else is noise.

How to Call Vendor Primitives in Verilog

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.

Take a simple BUFG (global clock buffer) in Verilog:

verilog1BUFG bufg_inst (
2    .I(clk_in),
3    .O(clk_global)
4);
5

That is it. No include statement. No library declaration. The synthesizer resolves BUFG automatically because it is a built-in primitive.

For block RAM, you use the RAMB18E1 or RAMB36E1 primitive depending on your device family:

verilog1RAMB18E1 #(
2    .INIT_A(18'h00000),
3    .INIT_B(18'h00000),
4    .READ_WIDTH_A(9),
5    .WRITE_WIDTH_A(9)
6) ram_inst (
7    .CLKARDCLK(clk),
8    .ADDRARDADDR(addr),
9    .DIADI(din),
10    .DOADO(dout),
11    .WEA(we),
12    .ENARDEN(en)
13);
14

The #(...) 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.

When you need something the tool does not resolve automatically, you use the unisim or secureip library. For Xilinx devices, you add this at the top of your file:

verilog1`timescale 1ns / 1ps
2
3module my_design (
4    // ports
5);
6
7// Pull in the simulation library
8`include "unisim_vcomp.v"
9
10// Now you can instantiate primitives like STARTUPE2, IDELAYE2, etc.
11STARTUPE2 startup_inst (
12    .USRDONEO(done),
13    .USRCCLKO(cclk),
14    .CFGCLK(),
15    .CFGMCLK(),
16    .EOS(),
17    .PREQ(),
18    .CLK(0),
19    .GSR(0),
20    .GTS(0),
21    .KEYCLEARB(1),
22    .PACK(0),
23    .USRCCLKTS(0),
24    .USRDONETS(1)
25);
26
27endmodule
28

The unisim_vcomp.v 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.

How to Call Vendor Primitives in VHDL

VHDL is more explicit about library binding. You must declare which library you are using before you can instantiate anything from it.

vhdl1library IEEE;
2use IEEE.STD_LOGIC_1164.ALL;
3
4-- Vendor library for primitives
5library UNISIM;
6use UNISIM.VComponents.all;
7
8entity my_top is
9    port (
10        clk_in  : in  std_logic;
11        clk_out : out std_logic
12    );
13end entity;
14
15architecture rtl of my_top is
16begin
17    bufg_inst : BUFG
18        port map (
19            I => clk_in,
20            O => clk_out
21        );
22end architecture;
23

The library UNISIM; line tells the compiler where to look. The use UNISIM.VComponents.all; line makes every component in that library visible by its simple name. Without the use clause, you would have to write UNISIM.VComponents.BUFG every time, which gets old fast.

For Intel (Altera) devices, the equivalent library is altera_mf or altera_lnsim for simulation:

vhdl1library altera_mf;
2use altera_mf.altera_mf_components.all;
3

Then you instantiate things like altsyncram or altpll the same way.

Working with IP Core Libraries

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.

The workflow is always the same.

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.

Then you add the wrapper to your project and instantiate it like any other module:

verilog1// This is the auto-generated wrapper from the IP catalog
2fifo_generator_0 u_fifo (
3    .clk(clk),
4    .srst(rst),
5    .din(data_in),
6    .wr_en(wr_en),
7    .rd_en(rd_en),
8    .dout(data_out),
9    .full(full),
10    .empty(empty)
11);
12

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.

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.

Common Mistakes That Break Library Calls

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.

The second mistake is parameter mismatch. Every primitive has a specific set of legal parameter values. If you set INIT_A 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.

The third mistake is mixing library styles in the same file. Some engineers put include statements and library declarations in the same file without understanding the difference. In Verilog, `include is text substitution. In VHDL, library is a namespace binding. They solve different problems. Do not mix them hoping one will cover the other.

A Clean Pattern for Organizing Library Calls

Here is a pattern that scales across large projects. Create a single file called vendor_libs.vh (for Verilog) or vendor_libs.vhd (for VHDL) that all your modules include.

For Verilog:

verilog1// vendor_libs.vh
2`ifndef VENDOR_LIBS_VH
3`define VENDOR_LIBS_VH
4
5`include "unisim_vcomp.v"
6`include "secureip.v"
7
8`endif
9

Then in every module:

verilog1`include "vendor_libs.vh"
2
3module my_module (...);
4    // primitives work now
5endmodule
6

For VHDL, make a package that handles the library declarations:

vhdl1library IEEE;
2use IEEE.STD_LOGIC_1164.ALL;
3
4package vendor_pkg is
5    library UNISIM;
6    use UNISIM.VComponents.all;
7end package;
8

Then in every entity:

vhdl1use work.vendor_pkg.all;
2

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.

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.

ChipApex is a global distributor of electronic components: ICs, semiconductors, passives & interconnects. Source active & obsolete parts with wholesale pricing, fast RFQ response, and worldwide delivery.Official website address:chipapex.com

Related Articles

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Back to top button