2pyrtl logo2pyrtl

The library

The component library

Every workspace arrives with rtllibpack, a library of components written in the same Python you write. Import one and it becomes part of your design; open one and it is a worked example of how something is done.

Using a component

from rtlpack import *
from rtllibpack import FIFO
from ProjectConfig import ProjectConfig

cfg = ProjectConfig()
fifo = FIFO(global_config=cfg, name='fifo', parent_module=None,
            word_length=16, depth=16)

Every component takes the project configuration first, then a name and its parent, then its own parameters. Inside a design of your own, pass parent_module=self and connect its ports in the constructor - hierarchy and interfaces.

The library folder in your workspace is read-only and updates when the library does. Copy a module into src/ if you want to change one - your copy is then yours, and will not move under you.

What is in it

AreaComponents
StorageFIFO, FIFO_from_sp_RAM, LIFO, DoubleBuffer, RAM_single_port, RAM_dual_port, RAM_3d
Flow controlPipelineForwardPath, PipelineBackwardPath, PipelineFull, RandomStaller, Synchronizer
Arbitration and decodeArbiter (fixed priority, round robin, LRU), Decoder, PriorityEncoder, BarrelShifter
Floating pointFP16_ALU, FP16_Adder, FP16_Multiplier, FP16_Divider, Fixed2FP16, FP162Fixed
IntegrityCRC8, CRC_Serial, ParityGen, ParityCheck, SECDED_Encoder, SECDED_Decoder, LFSR8, GrayEncoder, GrayDecoder
InstrumentationBasicIfacePerfMon, PipeStageWithPerfMon - counters that measure a live interface
InterfacesBasicValidEnableIface, BasicValidCreditIface, BasicValidOnlyIface, fp16_if

Worth reading, and why

Each of these shows a way of writing hardware that is hard to see from a bare reference, and every one of them is a few pages of Python you can open in the workspace:

Read thisFor this
SynchronizerThe smallest thing in the library: a chain of flops built by a Python loop, with the number of stages a parameter. Start here.
ParityGenA balanced XOR reduce tree built by a helper method that returns an expression - structure computed at build time, hardware only where it is assigned.
CRC_SerialThe textbook LFSR, drawn so the tap positions are the polynomial. The picture IS the specification.
CRC8The parallel version, derived by symbolically simulating eight serial steps in a helper - one algorithm, two shapes of hardware, one source.
ArbiterThree policies behind one parameter, and priority logic written as sibling ifs from low to high, where the last write wins.
BarrelShifterA variable shift as a staged mux ladder keyed on the bits of the shift amount - the pattern behind every normalise in the floating-point units.
FIFOA whole array of flops with wire-indexed reads and writes, and a control module of its own.
FP16_AdderAlignment, a wide add, normalisation and rounding: the biggest thing in the library, and still one readable file.
DoubleBufferTwo banks and a role-swapping select flop - ping-pong buffering with no special support from the tool.

They are drawn by hand

Every library module carries a _schematic() method: a hand placement that makes the algorithm legible - phases left to right, repeated structures as staircases. Open one in the viewer and the picture explains the design; open the file and you can see how the placement was written.