RTL Library¶
This is a set of files that contain useful miscellaneous functions and classes
Adders¶

pyrtl.rtllib.adders.
kogge_stone
(a, b, cin=0)¶ Creates a KoggeStone adder given two inputs
Parameters:  a, b (WireVector) – The two WireVectors to add up (bitwidths don’t need to match)
 cin – An optimal carry in WireVector or value
Returns: a Wirevector representing the output of the adder
The KoggeStone adder is a fast treebased adder with O(log(n)) propagation delay, useful for performance critical designs. However, it has O(n log(n)) area usage, and large fan out.

pyrtl.rtllib.adders.
one_bit_add
(a, b, cin=0)¶

pyrtl.rtllib.adders.
half_adder
(a, b)¶

pyrtl.rtllib.adders.
ripple_add
(a, b, cin=0)¶

pyrtl.rtllib.adders.
ripple_half_add
(a, cin=0)¶

pyrtl.rtllib.adders.
carrysave_adder
(a, b, c, final_adder=<function ripple_add>)¶ Adds three wirevectors up in an efficient manner :param WireVector a, b, c : the three wires to add up :param function final_adder : The adder to use to do the final addition :return: a wirevector with length 2 longer than the largest input

pyrtl.rtllib.adders.
cla_adder
(a, b, cin=0, la_unit_len=4)¶ Carry Lookahead Adder :param int la_unit_len: the length of input that every unit processes
A Carry LookAhead Adder is an adder that is faster than a ripple carry adder, as it calculates the carry bits faster. It is not as fast as a KoggeStone adder, but uses less area.

pyrtl.rtllib.adders.
wallace_reducer
(wire_array_2, result_bitwidth, final_adder=<function kogge_stone>)¶ The reduction and final adding part of a dada tree. Useful for adding many numbers together The use of single bitwidth wires is to allow for additional flexibility
Parameters:  wire_array_2 ([[Wirevector]]) – An array of arrays of single bitwidth wirevectors
 result_bitwidth (int) – The bitwidth you want for the resulting wire. Used to eliminate unnessary wires.
 final_adder – The adder used for the final addition
Returns: wirevector of length result_wirevector

pyrtl.rtllib.adders.
dada_reducer
(wire_array_2, result_bitwidth, final_adder=<function kogge_stone>)¶ The reduction and final adding part of a dada tree. Useful for adding many numbers together The use of single bitwidth wires is to allow for additional flexibility
Parameters:  wire_array_2 ([[Wirevector]]) – An array of arrays of single bitwidth wirevectors
 result_bitwidth (int) – The bitwidth you want for the resulting wire. Used to eliminate unnessary wires.
 final_adder – The adder used for the final addition
Returns: wirevector of length result_wirevector

pyrtl.rtllib.adders.
fast_group_adder
(wires_to_add, reducer=<function wallace_reducer>, final_adder=<function kogge_stone>)¶ A generalization of the carry save adder, this is designed to add many numbers together in a both area and time efficient manner. Uses a tree reducer to achieve this performance
Parameters:  wires_to_add ([WireVector]) – an array of wirevectors to add
 reducer – the tree reducer to use
 final_adder – The two value adder to use at the end
Returns: a wirevector with the result of the addition The length of the result is: max(len(w) for w in wires_to_add) + ceil(len(wires_to_add))
AES128¶
A class for building a PyRTL AES circuit.
Currently this class only supports 128 bit AES encryption/decryption
Example
:
aes = AES()
plaintext = pyrtl.Input(bitwidth=128, name='aes_plaintext')
key = pyrtl.Input(bitwidth=128, name='aes_key')
aes_ciphertext = pyrtl.Output(bitwidth=128, name='aes_ciphertext')
reset = pyrtl.Input(1)
ready = pyrtl.Output(1, name='ready')
ready_out, aes_cipher = aes.encryption_statem(plaintext, key, reset)
ready <<= ready_out
aes_ciphertext <<= aes_cipher
sim_trace = pyrtl.SimulationTrace()
sim = pyrtl.Simulation(tracer=sim_trace)
sim.step ({
aes_plaintext: 0x00112233445566778899aabbccddeeff,
aes_key: 0x000102030405060708090a0b0c0d0e0f,
reset: 1
})
for cycle in range(1,10):
sim.step ({
aes_plaintext: 0x00112233445566778899aabbccddeeff,
aes_key: 0x000102030405060708090a0b0c0d0e0f,
reset: 0
})
sim_trace.render_trace(symbol_len=40, segment_size=1)

class
pyrtl.rtllib.aes.
AES
¶ Bases: :class:`object`

__init__
()¶ x.__init__(…) initializes x; see help(type(x)) for signature

encryption
(plaintext, key)¶ Builds a single cycle AES Encryption circuit
Parameters:  plaintext (WireVector) – text to encrypt
 key (WireVector) – AES key to use to encrypt
Returns: a WireVector containing the ciphertext

encrypt_state_m
(plaintext_in, key_in, reset)¶ Builds a multiple cycle AES Encryption state machine circuit
Parameters: reset – a one bit signal telling the state machine to reset and accept the current plaintext and key Return ready, cipher_text: ready is a one bit signal showing that the encryption result (cipher_text) has been calculated.

decryption
(ciphertext, key)¶ Builds a single cycle AES Decryption circuit
Parameters:  ciphertext (WireVector) – data to decrypt
 key (WireVector) – AES key to use to encrypt (AES is symmetric)
Returns: a WireVector containing the plaintext

decryption_statem
(ciphertext_in, key_in, reset)¶ Builds a multiple cycle AES Decryption state machine circuit
Parameters: reset – a one bit signal telling the state machine to reset and accept the current plaintext and key Return ready, plain_text: ready is a one bit signal showing that the decryption result (plain_text) has been calculated.

Barrel¶

pyrtl.rtllib.barrel.
barrel_shifter
(bits_to_shift, bit_in, direction, shift_dist, wrap_around=0)¶ Create a barrel shifter that operates on data based on the wire width.
Parameters:  bits_to_shift – the input wire
 bit_in – the 1bit wire giving the value to shift in
 direction – a one bit WireVector representing shift direction (0 = shift down, 1 = shift up)
 shift_dist – WireVector representing offset to shift
 wrap_around – **currently not implemented**
Returns: shifted WireVector
Library Utilities¶

pyrtl.rtllib.libutils.
match_bitwidth
(*args)¶ Matches the bitwidth of all of the input arguments.
Parameters: args (WireVector) – input arguments Returns: tuple of args in order with extended bits

pyrtl.rtllib.libutils.
partition_wire
(wire, partition_size)¶

pyrtl.rtllib.libutils.
str_to_int_array
(string, base=16)¶ Converts a string to an array of integer values according to the base specified (int numbers must be whitespace delimited).
Example: “13 a3 3c” => [0x13, 0xa3, 0x3c]
Returns: [int]

pyrtl.rtllib.libutils.
twos_comp_repr
(val, bitwidth)¶ Converts a value to it’s two’scomplement (positive) integer representation using a given bitwidth (only converts the value if it is negative). For use with Simulation.step() etc. in passing negative numbers, which it does not accept

pyrtl.rtllib.libutils.
rev_twos_comp_repr
(val, bitwidth)¶ Takes a two’scomplement represented value and converts it to a signed integer based on the provided bitwidth. For use with Simulation.inspect() etc. when expecting negative numbers, which it does not recognize
Multipliers¶
Multipliers contains various PyRTL sample multipliers for people to use

pyrtl.rtllib.multipliers.
simple_mult
(A, B, start)¶ Builds a slow, small multiplier using the simple shiftandadd algorithm. Requires very small area (it uses only a single adder), but has long delay (worst case is len(A) cycles). start is a onebit input to indicate inputs are ready. done is a onebit output signal raised when the multiplication is finished.
Parameters: A, B (WireVector) – two input wires for the multiplication Returns: Register containing the product; the “done” signal

pyrtl.rtllib.multipliers.
complex_mult
(A, B, shifts, start)¶ Generate shiftandadd multiplier that can shift and add multiple bits per clock cycle. Uses substantially more space than simple_mult() but is much faster.
Parameters:  A, B (WireVector) – two input wires for the multiplication
 shifts (int) – number of spaces Register is to be shifted per clk cycle (cannot be greater than the length of A or B)
 start (bool) – start signal
Returns: Register containing the product; the “done” signal

pyrtl.rtllib.multipliers.
tree_multiplier
(A, B, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)¶ Build an fast unclocked multiplier for inputs A and B using a Wallace or Dada Tree.
Parameters:  A, B (WireVector) – two input wires for the multiplication
 reducer (function) – Reduce the tree using either a Dada recuder or a Wallace reducer determines whether it is a Wallace tree multiplier or a Dada tree multiplier
 adder_func (function) – an adder function that will be used to do the last addition
Return WireVector: The multiplied result
Delay is order logN, while area is order N^2.

pyrtl.rtllib.multipliers.
signed_tree_multiplier
(A, B, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)¶ Same as tree_multiplier, but uses two’scomplement signed integers

pyrtl.rtllib.multipliers.
fused_multiply_adder
(mult_A, mult_B, add, signed=False, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)¶ Generate efficient hardware for a*b+c.
Multiplies two wirevectors together and adds a third wirevector to the multiplication result, all in one step. By doing it this way (instead of separately), one reduces both the area and the timing delay of the circuit.
Parameters:  signed (Bool) – Currently not supported (will be added in the future) The default will likely be changed to True, so if you want the smallest set of wires in the future, specify this as False
 reducer – (advanced) The tree reducer to use
 adder_func – (advanced) The adder to use to add the two results at the end
Return WireVector: The result WireVector

pyrtl.rtllib.multipliers.
generalized_fma
(mult_pairs, add_wires, signed=False, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)¶ Generated an opimitized fused multiply adder.
A generalized FMA unit that multiplies each pair of numbers in mult_pairs, then adds the resulting numbers and and the values of the add wires all together to form an answer. This is faster than separate adders and multipliers because you avoid unnecessary adder structures for intermediate representations.
Parameters:  mult_pairs – Either None (if there are no pairs to multiply) or a list of pairs of wires to multiply: [(mult1_1, mult1_2), …]
 add_wires – Either None (if there are no individual items to add other than the mult_pairs), or a list of wires for adding on top of the result of the pair multiplication.
 signed (Bool) – Currently not supported (will be added in the future) The default will likely be changed to True, so if you want the smallest set of wires in the future, specify this as False
 reducer – (advanced) The tree reducer to use
 adder_func – (advanced) The adder to use to add the two results at the end
Return WireVector: The result WireVector
Muxes¶

pyrtl.rtllib.muxes.
prioritized_mux
(selects, vals)¶ Returns the value in the first wire for which its select bit is 1
Parameters:  selects ([WireVector]) – a list of WireVectors signaling whether a wire should be chosen
 vals ([WireVector]) – values to return when the corresponding select value is 1
Returns: WireVector
If none of the items are high, the last val is returned

pyrtl.rtllib.muxes.
sparse_mux
(sel, vals)¶ Mux that avoids instantiating unnecessary mux_2s when possible.
Parameters:  sel (WireVector) – Select wire, determines what is selected on a given cycle
 vals (dictionary) – dictionary of values at mux inputs (of type {int:WireVector})
Returns: WireVector that signifies the change
This mux supports not having a full specification. Indices that are not specified are treated as don’tcares
It also supports a specified default value, SparseDefault

class
pyrtl.rtllib.muxes.
MultiSelector
(signal_wire, *dest_wires)¶ Bases: :class:`object`
The MultiSelector allows you to specify multiple wire value results for a single select wire.
Useful for processors, finite state machines and other places where the result of many wire values are determined by a common wire signal (such as a ‘state’ wire).
Example:
 with muxes.MultiSelector(select, res0, res1, res2, …) as ms:
 ms.option(val1, data0, data1, data2, …) ms.option(val2, data0_2, data1_2, data2_2, …)
This means that when the select wire equals the val1 wire the results will have the values in the coresponding data wires (all ints are converted to wires)

__init__
(signal_wire, *dest_wires)¶ x.__init__(…) initializes x; see help(type(x)) for signature

__enter__
()¶  For compatibility with with statements, which is the recommended
 method of using a MultiSelector

option
(select_val, *data_signals)¶

default
(*data_signals)¶

finalize
()¶ Connects the wires.

pyrtl.rtllib.muxes.
demux
(select)¶ Demultiplexes a wire of arbitrary bitwidth
Parameters: select (WireVector) – indicates which wire to set on Return (WireVector, …): a tuple of wires corresponding to each demultiplexed wire
Testing Utilities¶

pyrtl.rtllib.testingutils.
calcuate_max_and_min_bitwidths
(max_bitwidth=None, exact_bitwidth=None)¶

pyrtl.rtllib.testingutils.
inverse_power_dist
(bitwidth)¶

pyrtl.rtllib.testingutils.
uniform_dist
(bitwidth)¶

pyrtl.rtllib.testingutils.
make_inputs_and_values
(num_wires, max_bitwidth=None, exact_bitwidth=None, dist=<function uniform_dist>, test_vals=20)¶ Generates multiple input wires and sets of test values for testing purposes
Parameters: dist (function) – function to generate the random values Returns: wires; list of values for the wires The list of values is a list of lists. the interior lists represent the values of a single wire for all of the simulation cycles

pyrtl.rtllib.testingutils.
an_input_and_vals
(bitwidth, test_vals=20, name='', random_dist=<function uniform_dist>)¶ Generates an input wire and a set of test values for testing purposes
Parameters:  bitwidth – The bitwidth of the value to be generated
 test_vals (int) – number of values to generate per wire
 name – name for the input wire to be generated
Returns: tuple consisting of input_wire, test_values

pyrtl.rtllib.testingutils.
generate_in_wire_and_values
(bitwidth, test_vals=20, name='', random_dist=<function uniform_dist>)¶ Generates an input wire and a set of test values for testing purposes
Parameters:  bitwidth – The bitwidth of the value to be generated
 test_vals (int) – number of values to generate per wire
 name – name for the input wire to be generated
Returns: tuple consisting of input_wire, test_values

pyrtl.rtllib.testingutils.
make_consts
(num_wires, max_bitwidth=None, exact_bitwidth=None, random_dist=<function inverse_power_dist>)¶ Returns: [Const_wires]; [Const_vals]

pyrtl.rtllib.testingutils.
sim_and_ret_out
(outwire, inwires, invals)¶ Simulates the net using inwires and invalues, and returns the output array. Used for rapid test development.
Parameters:  outwire – The wire to return the output of
 inwires – a list of wires to read in from ([Input, …])
 invals – a list of input value lists ([ [int, …], …])
Returns: a list of values from the output wire simulation result

pyrtl.rtllib.testingutils.
sim_and_ret_outws
(inwires, invals)¶ Simulates the net using inwires and invalues, and returns the output array. Used for rapid test development.
Parameters:  inwires – a list of wires to read in from ([Input, …])
 invals – a list of input value lists ([[int, …], …])
Returns: a list of values from the output wire simulation result

pyrtl.rtllib.testingutils.
sim_multicycle
(in_dict, hold_dict, hold_cycles, sim=None)¶ Simulation of a circuit that takes multiple cycles to complete.
Parameters:  in_dict –
 hold_dict –
 hold_cycles –
 sim –
Returns:

pyrtl.rtllib.testingutils.
multi_sim_multicycle
(in_dict, hold_dict, hold_cycles, sim=None)¶ Simulates a circuit that takes multiple cycles to complete multiple times.
Parameters:  in_dict – {in_wire: [in_values, …], …}
 hold_dict – {hold_wire: hold_value} The hold values for the
 hold_cycles –
 sim –
Returns: