libtrellis Overview¶
libtrellis is a C++ library containing utilities to manipulate ECP5 bitstreams, and the databases that correspond tile bits to functionality (routing and configuration). Although libtrellis can be used as a standard shared library, its primary use in Project Trellis is as a Python module (called pytrellis), imported by the fuzzing and utility scripts. The C++ classes are bound to Python using Boost::Python.
Bitstream¶
This class provides functionality to read and write Lattice bitstream files, parse their commands, and convert them into a chip’s configuration memory (in terms of frames and bits).
To read a bitstream, use read_bit
to create a Bitstream
object, then call deserialise_chip
on that to
create a Chip
.
Chip¶
This represents a configured FPGA, in terms of its configuration memory (CRAM
), tiles and metadata. You can either
use deserialise_chip
on a bitstream to construct a Chip from an existing bitstream, or construct a Chip by device
name or IDCODE.
The ChipInfo
structure contains information for a particular FPGA device.
CRAM¶
This class stores the entire configuration data of the FPGA, as a 2D array (frames and bits). Although the array can be
accessed directly, many cases will use CRAMView
instead. CRAMView
provides a read/write view of a window of the
CRAM. This is usually used to represent the configuration memory of a single tile, and takes frame and bit offsets
and lengths.
Subtracting two CRAMView
s, if they are the same size, will produce a CRAMDelta
, a list of the changes between
the two memories. This is useful for fuzzing or comparing bitstreams.
Tile¶
This represents a tile of the FPGA. It includes a CRAMView
to represent the configuration memory of the tile.
TileConfig¶
This represents the actual configuration of a tile, in terms of arcs (programmable connections), config words (such as LUT initialisation) and config enums (such as IO type). It is the result of decoding the tile CRAM content using the bit database, and can be converted to a FASM-like format.
The contents of TileConfig
are ConfigArc
for connections, ConfigWord
for non-routing configuration words
(which also includes single config bits), ConfigEnum
for enum configurations with multiple textual values, and
ConfigUnknown
for unknown bits not found in the database, which are simply stored as a frame, bit reference.
The contents of a tile’s configuration RAM can be converted to and from a TileConfig
by using the tile_cram_to_config
and config_to_tile_cram
methods on the TileBitDatabase
instance for the tile.
TileBitDatabase¶
There will always be only one TileBitDatabase
for each tile type, which is enforced by requiring calling the
function get_tile_bitdata
(in Database.cpp
) to obtain a shared_ptr
to the TileBitDatabase
.
The TileBitDatabase
stored the function of all bits in the tile, in terms of the following constructs:
Muxes (
MuxBits
) specify a list of arcs that can drive a given node. Each arc (ArcData
) contains specifies source, sink and the list of bits that enable it as aBitGroup
.Config words (
WordSettingBits
) specify non-routing configuration settings that are arranged as one or more bits. Each config bit has an associated list of bits that enable it. This would be used both for single-bit settings and configuration such as LUT initialisation and PLL dividers.Config enums (
EnumSettingBits
) specify non-routing configuration settings that have a set of possible textual values, used for either modes/types (i.e. IO type) or occasionally “special” muxes not part of general routing. These are specified as a map between possible values and the bits that enable those values.
TileBitDatabase
instances can be modified during runtime, in a thread-safe way, to enable parallel fuzzing. They can
be saved back to disk using the save
method.
They can also be used to convert between tile CRAM data and higher level tile config, as described above.
RoutingGraph¶
RoutingGraph
and related structures are designed to store a complete routing graph for the Chip. RoutingWire
represents wires, RoutingArc
represents arcs between wires and RoutingBel
represents a Bel (logic element).
To reduce memory usage, ident_t
, an index into a string store, is used instead of using strings directly. Use
RoutingGraph.ident
to convert from string to ident_t
, and RoutingGraph.to_str
to convert to a string.
DedupChipdb¶
This is an experimental part of libtrellis to “deduplicate” the repetition in the routing graph, by converting it to relative coordinates and then storing identical tile locations only once. The data produced is intended to be exported to a database for a place and route tool using the Python API.
ChipConfig¶
ChipConfig contains the high-level configuration for the entire chip, including all tiles and metadata. It can be directly converted to or from a high-level configuration text file. For more information see Text Config Documentation.