Category Archives: Tutorial

Using Symbolic Libraries to Speed Up Verilog Compilation

Designs often reuse a common set of our Verilog source files. For example, when you’re designing using a particular family of FPGAs or ASICs, you will need to compile the vendor-provided Verilog source files for those parts. Instead of recompiling these files for each new design, you can compile them once into a symbolic library (sometimes referred to as a compiled library), then just reference that symbolic library in your designs. With this approach, you only need to recompile the vendor’s source files when you update your simulator to a newer version.

Cells and Snapshots

A symbolic library contains cells and snapshots. Cells represent the definitions for objects such as modules and User-Defined Primitives (UDPs) that are created when source files are compiled into a library. Snapshots are created during simulation elaboration and represent a fully built “simulation” that can be executed.

Within a library, cell and snapshot names must be unique and any attempt to compile a cell into a library that already contains a cell of that name will cause the original cell to be overwritten. However, cells and snapshots of the same name can exist in different libraries.

Creating Symbolic Libraries

In most Verilog compilers, a symbolic library is given both a logical name (e.g. “work”) and a physical name that indicates it’s storage location (e.g. “c:\myproject\scd_work”). The logical name is used when referring to a symbolic library in the source code or when passing a library name as a command-line option to the verilog compiler, so that the source code and script files don’t have to depend on the library’s location on a particular computer.  The physical name is only used to specify the location of the symbolic library (and typically only when the library is first created). The mapping between these two names is specified using a command-line library tool that can create and manipulate symbolic libraries and the resulting mappings are stored into a “map file”. In simx, for example, this command-line tool is called simxlib. In both Mentor Graphics ModelSim and Aldec Active HDL, the library tool is called vlib.

Work: the Default Symbolic Library

By default, sources files will be compiled into a compiled library with the symbolic name of “work, unless a different destination library is specified via the --work <destination_library_name> compiler option. Also by default, the work library will be mapped to a subdirectory of the current working directory called scd_work, unless a map file is passed to the compiler that specifies a different physical path name for the library.  This default mapping will be written into a default map file called scd.lib which simx will subsequently load automatically whenever simulations are run from this directory. The above defaults allow simx to be used without having to worry about symbolic libraries, if you don’t plan to take advantage of them to avoid re-compiling shared Verilog code.

By contrast, some compilers require you to create at least one symbolic library using their library tool before you can compile code with these simulators, so if you use BugHunter to compile code with ModelSim or ActiveHDL, you will note that it first launches vlib to create a work library before it launches the actual Verilog or VHDL compilers (aka vlog or vsim) for these simulators.

Example Commands for Creating and Using Symbolic Libraries

To compile test1.v and add it’s contents to the default library called “work”, you can either directly specify the work library with the -work option:

simx --work work test1.v

or let the simulator just use work by default:

simx test1.v

In the above commands, the work library will be automatically created in a subdirectory called scd_work if it doesn’t already exist.

To create a library with the logical name vendor1 located at c:\vendor1 and compile a set of files into this library, use the following commands:

simxlib --create c:\vendor1
simx --work vendor1 test1.v test2.v test3.v

The above commands also create a scd.lib file in the current directory with the following contents:

DEFINE vendor1 c:/vendor1

This line says that the logical library name vendor1 maps to the physical library located at c:\vendor1.

Detecting Races with VeriLogger

It’s easy to accidentally introduced “races” into Verilog, especially when you’re working with just one simulator. Since the Verilog language purposely doesn’t specify a particular order for execution of parallel process blocks, these races will frequently lead to different simulation results when a design is simulated by simulators from different vendors. VeriLogger has always been pretty useful for detecting simulation races, because our BugHunter GUI allows you to switch back and forth between our simulator (Simx) and 3rd party simulations (e.g. ModelSim, NcSim, ActivHdl, and VCS), making it easier to find such races. But this still required you to have access to other simulators to detect the races.

Over the past few months, while working with some of our customers who were “qualifying” our simulator with their existing designs, several such races have been found in the designs. Each time we encountered a simulation difference between us and a 3rd party simulator they were using, we had to determine whether the problem was a bug in our simulator, a bug in the other simulator, or a race in the design.

To speed this process up, we added several new command-line options to enable our simulator to change our default ordering of process execution and also to handle a few cases where the Verilog Language Reference Manual was vague enough about how a situation should be handled that different 3rd party vendors have chosen different ways to handle those siutations. By default, our simulator most closely models the process ordering used by Cadence’s Ncsim, so we added options to match the ordering used by Mentor’s ModelSim and Aldec ActiveHdl. We also added an option to randomize the ordering which given a few simulation runs should generally detect a problematic race in just about any design. The new options are:

–scd_invert_queue: inverts order in which “same priority” events in the event queue are evaluated.

–scd_randomize_queue: randomizes the order in which “same priority” events are evaluated.

–scd_mtilike_queue: evaluates event queue similar to ModelSim/ActiveHdl.

–scd_immediate_sensitivity: makes event control statements at the beginning of a process immediately sensitive after simulation initialization.

–scd_mtilike_dist_functions: makes $random and $dist functions behave like ModelSim/ActiveHdl instead of like NcSim.

What all this amounts to is, although our original goal was to make it easier to qualify our simulator as being functionally correct, we’ve ended up creating a new way to quickly detect races in your designs, as well. Finding these races can save you a lot of headaches down the road, especially if you sell IP to customers who use different simulators from the ones you normally work with!

Protecting your Verilog IP via Encryption

The Verilog 2005 standard introduced a new feature to support protected intellectual property. This feature allows IP vendors to deliver models in encrypted form. Vendors may choose to encrypt entire files, or only encrypt parts of a model. You can choose to encrypt entire files, or only encrypt parts of a model. Xilinx has begun using this method to encrypt it’s latest IP models, since the resulting models simulate faster than object-code model equivalents (e.g. SmartModels).

The simplest way to encrypt your source code is to use VeriLogger’s public key. This will allow any VeriLogger user to compile and use the encrypted model by simply adding the file to their project. VeriLogger will compile and simulate using the encrypted code, but the user will not have access to any of the source code. You can also encrypt a file with a public key of own, then provide this key to consumers of your IP so that they can use the IP with any simulator that supports the encryption standard.

Encryption Steps

Before encrypting your source, test the unencrypted source code with VeriLogger Extreme to ensure that it compiles without errors. Since the end-user of your IP will not have access to the source code, they will be unable to fix any problems, and error messages in encrypted sections of code will be useless.

To create an encrypted file, perform the steps below:

1. Add `pragma protect directives to the source to delimit which sections to encrypt. Anything between a `pragma protect begin line and a `pragma protect end will be encrypted. Anything outside these directives will be copied verbatim to the output file.

2. Run the simulation generator, simxgen, to encrypt a source file called sram.v:
simx +protect sram.v

This will generate an encrypted file called sram.vp. The .vp file extension indicates an encrypted verilog file.

For details on how to create and use your own encryption keys or how to encrypt a model with multiple keys, see the section on Verilog Protected Envelopes in the Verilogger online help.