RTL Library#

Useful circuits, functions, and testing utilities.

Adders#

pyrtl.rtllib.adders.carrysave_adder(a, b, c, final_adder=<function ripple_add>)[source]#

Adds three wirevectors up in an efficient manner

Parameters:
  • a (WireVector) – a wire to add up

  • b (WireVector) – a wire to add up

  • c (WireVector) – a wire to add up

  • final_adder (Callable) – The adder to use to do the final addition

Returns:

a WireVector with length 2 longer than the largest input

pyrtl.rtllib.adders.cla_adder(a, b, cin=0, la_unit_len=4)[source]#

Carry Lookahead Adder

Parameters:

la_unit_len (int) – 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 Kogge-Stone adder, but uses less area.

pyrtl.rtllib.adders.dada_reducer(wire_array_2, result_bitwidth, final_adder=<function kogge_stone>)[source]#

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 unnecessary wires.

  • final_adder – The adder used for the final addition

Returns:

WireVector of length result_bitwidth

pyrtl.rtllib.adders.fast_group_adder(wires_to_add, reducer=<function wallace_reducer>, final_adder=<function kogge_stone>)[source]#

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))
pyrtl.rtllib.adders.half_adder(a, b)[source]#
pyrtl.rtllib.adders.kogge_stone(a, b, cin=0)[source]#

Creates a Kogge-Stone adder given two inputs

Parameters:
  • a (WireVector) – A WireVector to add up (bitwidths don’t need to match)

  • b (WireVector) – A WireVector 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 Kogge-Stone adder is a fast tree-based 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)[source]#
pyrtl.rtllib.adders.ripple_add(a, b, cin=0)[source]#
pyrtl.rtllib.adders.ripple_half_add(a, cin=0)[source]#
pyrtl.rtllib.adders.wallace_reducer(wire_array_2, result_bitwidth, final_adder=<function kogge_stone>)[source]#

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 unnecessary wires.

  • final_adder – The adder used for the final addition

Returns:

WireVector of length result_bitwidth

AES-128#

A class for building a PyRTL AES circuit.

Currently this class only supports 128 bit AES encryption/decryption

Example:

import pyrtl
from pyrtl.rtllib.aes import AES

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, name='reset')
ready = pyrtl.Output(1, name='ready')
ready_out, aes_cipher = aes.encrypt_state_m(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[source]#
decryption(ciphertext, key)[source]#

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)[source]#

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.

encrypt_state_m(plaintext_in, key_in, reset)[source]#

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.

encryption(plaintext, key)[source]#

Builds a single cycle AES Encryption circuit

Parameters:
Returns:

a WireVector containing the ciphertext

Barrel#

pyrtl.rtllib.barrel.barrel_shifter(bits_to_shift, bit_in, direction, shift_dist, wrap_around=0)[source]#

Create a barrel shifter that operates on data based on the wire width.

Parameters:
  • bits_to_shift – the input wire

  • bit_in – the 1-bit 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)[source]#

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)[source]#

Partitions a wire into a list of N wires of size partition_size.

Parameters:
  • wire – Wire to partition

  • partition_size – Integer representing size of each partition

The wire’s bitwidth must be evenly divisible by parition_size.

pyrtl.rtllib.libutils.rev_twos_comp_repr(val, bitwidth)[source]#

Takes a two’s-complement 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

pyrtl.rtllib.libutils.str_to_int_array(string, base=16)[source]#

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)[source]#

Converts a value to its two’s-complement (positive) integer representation using a given bitwidth (only converts the value if it is negative).

Parameters:
  • val – Integer literal to convert to two’s complement

  • bitwidth – Size of val in bits

For use with Simulation.step() etc. in passing negative numbers, which it does not accept.

Multipliers#

Multipliers contains various PyRTL sample multipliers for people to use

pyrtl.rtllib.multipliers.complex_mult(A, B, shifts, start)[source]#

Generate shift-and-add multiplier that can shift and add multiple bits per clock cycle. Uses substantially more space than simple_mult() but is much faster.

Parameters:
  • A (WireVector) – input wire for the multiplication

  • B (WireVector) – input wire for the multiplication

  • shifts (int) – number of spaces Register is to be shifted per clock cycle (cannot be greater than the length of A or B)

  • start (bool) – start signal

Return [Register, bool]:

Register containing the product and the done signal

pyrtl.rtllib.multipliers.fused_multiply_adder(mult_A, mult_B, add, signed=False, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)[source]#

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>)[source]#

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 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

pyrtl.rtllib.multipliers.signed_tree_multiplier(A, B, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)[source]#

Same as tree_multiplier, but uses two’s-complement signed integers

pyrtl.rtllib.multipliers.simple_mult(A, B, start)[source]#

Builds a slow, small multiplier using the simple shift-and-add algorithm. Requires very small area (it uses only a single adder), but has long delay (worst case is len(A) cycles). start is a one-bit input to indicate inputs are ready. done is a one-bit output signal raised when the multiplication is finished.

Parameters:
  • A (WireVector) – input wire for the multiplication

  • B (WireVector) – input wire for the multiplication

Return [Register, bool]:

Register containing the product and the done signal

pyrtl.rtllib.multipliers.tree_multiplier(A, B, reducer=<function wallace_reducer>, adder_func=<function kogge_stone>)[source]#

Build an fast unclocked multiplier for inputs A and B using a Wallace or Dada Tree.

Parameters:
  • A (WireVector) – input wire for the multiplication

  • B (WireVector) – input wire for the multiplication

  • reducer (Callable) – Reduce the tree using either a Dada reducer or a Wallace reducer determines whether it is a Wallace tree multiplier or a Dada tree multiplier

  • adder_func (Callable) – an adder function that will be used to do the last addition

Return WireVector:

The multiplied result

Delay is O(log(N)), while area is O(N^2).

Muxes#

class pyrtl.rtllib.muxes.MultiSelector(signal_wire, *dest_wires)[source]#

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 data0, data1, data2, ... (all ints are converted to wires)

__enter__()[source]#

For compatibility with with statements, which is the recommended method of using a MultiSelector.

__init__(signal_wire, *dest_wires)[source]#
default(*data_signals)[source]#
finalize()[source]#

Connects the wires.

option(select_val, *data_signals)[source]#
pyrtl.rtllib.muxes.demux(select)[source]#

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

pyrtl.rtllib.muxes.prioritized_mux(selects, vals)[source]#

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 selects are high, the last val is returned

pyrtl.rtllib.muxes.sparse_mux(sel, vals)[source]#

Mux that avoids instantiating unnecessary mux_2s when possible.

Parameters:
  • sel (WireVector) – Select wire, determines what is selected on a given cycle

  • vals (dict[int, WireVector]) – dictionary of values at mux inputs

Returns:

WireVector that signifies the change

This mux supports not having a full specification. Indices that are not specified are treated as don’t-cares

It also supports a specified default value, SparseDefault

Matrix#

class pyrtl.rtllib.matrix.Matrix(rows, columns, bits, signed=False, value=None, max_bits=64)[source]#

Class for making a Matrix using PyRTL.

Provides the ability to perform different matrix operations.

__init__(rows, columns, bits, signed=False, value=None, max_bits=64)[source]#

Constructs a Matrix object.

Parameters:
  • rows (int) – the number of rows in the matrix. Must be greater than 0

  • columns (int) – the number of columns in the matrix. Must be greater than 0

  • bits (int) – The amount of bits per WireVector. Must be greater than 0

  • signed (bool) – Currently not supported (will be added in the future)

  • value ((WireVector/list)) – The value you want to initialize the Matrix with. If a WireVector, must be of size rows * columns * bits. If a list, must have rows rows and columns columns, and every element must fit in bits size. If not given, the matrix initializes to 0

  • max_bits (int) – The maximum number of bits each WireVector can have, even after operations like adding two matrices together results in larger resulting WireVectors

Returns:

a constructed Matrix object

property bits#

Gets the number of bits each value is allowed to hold.

Returns:

an integer representing the number of bits

copy()[source]#

Constructs a deep copy of the Matrix.

Returns:

a Matrix copy

flatten(order='C')[source]#

Flatten the matrix into a single row.

Parameters:

order (str) – C means row-major order (C-style), and F means column-major order (Fortran-style)

Returns:

A copy of the matrix flattened in to a row vector matrix

put(ind, v, mode='raise')[source]#

Replace specified elements of the matrix with given values

Parameters:
  • ind (int/list[int]/tuple[int]) – target indices

  • v (int/list[int]/tuple[int]/Matrix row-vector) – values to place in matrix at target indices; if v is shorter than ind, it is repeated as necessary

  • mode (str) – how out-of-bounds indices behave; raise raises an error, wrap wraps around, and clip clips to the range

Note that the index is on the flattened matrix.

reshape(*newshape, **order)[source]#

Create a matrix of the given shape from the current matrix.

Parameters:
  • newshape (int/ints/tuple[int]) – shape of the matrix to return; if a single int, will result in a 1-D row-vector of that length; if a tuple, will use values for number of rows and cols. Can also be a varargs.

  • order (str) – C means to read from self using row-major order (C-style), and F means to read from self using column-major order (Fortran-style).

Returns:

A copy of the matrix with same data, with a new number of rows/cols

One shape dimension in newshape can be -1; in this case, the value for that dimension is inferred from the other given dimension (if any) and the number of elements in the matrix.

Examples:

int_matrix = [[0, 1, 2, 3], [4, 5, 6, 7]]
matrix = Matrix.Matrix(2, 4, 4, value=int_matrix)

matrix.reshape(-1) == [[0, 1, 2, 3, 4, 5, 6, 7]]
matrix.reshape(8) == [[0, 1, 2, 3, 4, 5, 6, 7]]
matrix.reshape(1, 8) == [[0, 1, 2, 3, 4, 5, 6, 7]]
matrix.reshape((1, 8)) == [[0, 1, 2, 3, 4, 5, 6, 7]]
matrix.reshape((1, -1)) == [[0, 1, 2, 3, 4, 5, 6, 7]]

matrix.reshape(4, 2) == [[0, 1], [2, 3], [4, 5], [6, 7]]
matrix.reshape(-1, 2) == [[0, 1], [2, 3], [4, 5], [6, 7]]
matrix.reshape(4, -1) == [[0, 1], [2, 3], [4, 5], [6, 7]]
to_wirevector()[source]#

Outputs the PyRTL Matrix as a singular concatenated WireVector.

Returns:

a Wirevector representing the whole PyRTL matrix

For instance, if we had a 2 x 1 matrix [[wire_a, wire_b]] it would return the concatenated wire: wire = wire_a.wire_b

transpose()[source]#

Constructs the transpose of the matrix

Returns:

a Matrix object representing the transpose

pyrtl.rtllib.matrix.argmax(matrix, axis=None, bits=None)[source]#

Returns the index of the max value of the matrix.

Parameters:
  • matrix (Matrix/Wirevector) – the matrix to perform argmax operation on. If it is a WireVector, it will return itself

  • axis (None/int) – The axis to perform the operation on. None refers to argmax of all items. 0 is argmax of the columns. 1 is argmax of rows. Defaults to None

  • bits (int) – The bits per value of the argmax. Defaults to bits of old matrix

Returns:

A WireVector or Matrix representing the argmax value

NOTE: If there are two indices with the same max value, this function picks the first instance.

pyrtl.rtllib.matrix.concatenate(matrices, axis=0)[source]#

Join a sequence of matrices along an existing axis.

Parameters:
  • matrices (list[Matrix]) – a list of matrices to concatenate one after another

  • axis (int) – axis along which to join; 0 is horizontally, 1 is vertically (defaults to 0)

Returns:

a new Matrix composed of the given matrices joined together

This function essentially wraps hstack/vstack.

pyrtl.rtllib.matrix.dot(first, second)[source]#

Performs the dot product on two matrices.

Parameters:
  • first (Matrix) – the first matrix

  • second (Matrix) – the second matrix

Returns:

a PyRTL Matrix that contains the dot product of the two PyRTL Matrices

Specifically, the dot product on two matrices is:

  • If either first or second are WireVectors/have both rows and columns equal to 1, it is equivalent to Matrix.__mul__()

  • If both first and second are both arrays (have rows or columns equal to 1), it is inner product of vectors.

  • Otherwise it is Matrix.__matmul__() between first and second

NOTE: Row vectors and column vectors are both treated as arrays

pyrtl.rtllib.matrix.hstack(*matrices)[source]#

Stack matrices in sequence horizontally (column-wise).

Parameters:

matrices (list[Matrix]) – a list of matrices to concatenate one after another horizontally

Return Matrix:

a new Matrix, with the same number of rows as the original, with a bitwidth equal to the max of the bitwidths of all the matrices

All the matrices must have the same number of rows and same ‘signed’ value.

For example:

m1 = Matrix(2, 3, bits=5,  value=[[1,2,3],
                                  [4,5,6]])
m2 = Matrix(2, 1, bits=10, value=[[17],
                                  [23]]])
m3 = hstack(m1, m2)

m3 looks like:

[[1,2,3,17],
 [4,5,6,23]]
pyrtl.rtllib.matrix.list_to_int(matrix, n_bits)[source]#

Convert a Python matrix (a list of lists) into an integer.

Parameters:
  • matrix (list[list[int]]) – a pure Python list of lists representing a matrix

  • n_bits (int) – number of bits to be used to represent each element; if an element doesn’t fit in n_bits, it truncates the most significant bits

Return int:

a N * n_bits wide WireVector containing the elements of matrix, where N is the number of elements in matrix

Integers that are signed will automatically be converted to their two’s complement form.

This function is helpful for turning a pure Python list of lists into a integer suitable for creating a Constant WireVector that can be passed in to as a Matrix constructor’s value argument, or for passing into a Simulation’s step function for a particular input wire.

For example, calling Matrix.list_to_int([3, 5], [7, 9], 4) produces 13,689, which in binary looks like this:

0011 0101 0111 1001

Note how the elements of the list of lists were added, 4 bits at a time, in row order, such that the element at row 0, column 0 is in the most significant 4 bits, and the element at row 1, column 1 is in the least significant 4 bits.

Here’s an example of using it in simulation:

a_vals = [[0, 1], [2, 3]]
b_vals = [[2, 4, 6], [8, 10, 12]]

a_in = pyrtl.Input(4 * 4, 'a_in')
b_in = pyrtl.Input(6 * 4, 'b_in')
a = Matrix.Matrix(2, 2, 4, value=a_in)
b = Matrix.Matrix(2, 3, 4, value=b_in)
...

sim = pyrtl.Simulation()
sim.step({
    'a_in': Matrix.list_to_int(a_vals)
    'b_in': Matrix.list_to_int(b_vals)
})
pyrtl.rtllib.matrix.matrix_wv_to_list(matrix_wv, rows, columns, bits)[source]#

Convert a wirevector representing a matrix into a Python list of lists.

Parameters:
  • matrix_wv (WireVector) – result of calling to_wirevector() on a Matrix object

  • rows (int) – number of rows in the matrix matrix_wv represents

  • columns (int) – number of columns in the matrix matrix_wv represents

  • bits (int) – number of bits in each element of the matrix matrix_wv represents

Return list[list[int]]:

a Python list of lists

This is useful when printing the value of a wire you’ve inspected during Simulation that you know represnts a matrix.

Example:

values = [[1, 2, 3], [4, 5, 6]]
rows = 2
cols = 3
bits = 4
m = Matrix.Matrix(rows, cols, bits, values=values)

output = Output(name='output')
output <<= m.to_wirevector()

sim = Simulation()
sim.step({})

raw_matrix = Matrix.matrix_wv_to_list(sim.inspect('output'), rows, cols, bits)
print(raw_matrix)

# Produces:
# [[1, 2, 3], [4, 5, 6]]
pyrtl.rtllib.matrix.max(matrix, axis=None, bits=None)[source]#

Returns the max value in a matrix.

Parameters:
  • matrix (Matrix/Wirevector) – the matrix to perform max operation on. If it is a WireVector, it will return itself

  • axis (None/int) – The axis to perform the operation on None refers to max of all items. 0 is max of the columns. 1 is max of rows. Defaults to None

  • bits (int) – The bits per value of the max. Defaults to bits of old matrix

Returns:

A WireVector or Matrix representing the max value

pyrtl.rtllib.matrix.min(matrix, axis=None, bits=None)[source]#

Returns the minimum value in a matrix.

Parameters:
  • matrix (Matrix/Wirevector) – the matrix to perform min operation on. If it is a WireVector, it will return itself

  • axis (None/int) – The axis to perform the operation on None refers to min of all item. 0 is min of column. 1 is min of rows. Defaults to None

  • bits (int) – The bits per value of the min. Defaults to bits of old matrix

Returns:

A WireVector or Matrix representing the min value

pyrtl.rtllib.matrix.multiply(first, second)[source]#

Perform the elementwise or scalar multiplication operation.

Parameters:
  • first (Matrix) – first matrix

  • second (Matrix/Wirevector) – second matrix

Returns:

a Matrix object with the element wise or scalar multiplication being performed

pyrtl.rtllib.matrix.sum(matrix, axis=None, bits=None)[source]#

Returns the sum of all the values in a matrix

Parameters:
  • matrix (Matrix/Wirevector) – the matrix to perform sum operation on. If it is a WireVector, it will return itself

  • axis (None/int) – The axis to perform the operation on None refers to sum of all item. 0 is sum of column. 1 is sum of rows. Defaults to None

  • bits (int) – The bits per value of the sum. Defaults to bits of old matrix

Returns:

A WireVector or Matrix representing sum

pyrtl.rtllib.matrix.vstack(*matrices)[source]#

Stack matrices in sequence vertically (row-wise).

Parameters:

matrices (list[Matrix]) – a list of matrices to concatenate one after another vertically

Return Matrix:

a new Matrix, with the same number of columns as the original, with a bitwidth equal to the max of the bitwidths of all the matrices

All the matrices must have the same number of columns and same ‘signed’ value.

For example:

m1 = Matrix(2, 3, bits=5,  value=[[1,2,3],
                                  [4,5,6]])
m2 = Matrix(1, 3, bits=10, value=[[7,8,9]])
m3 = vstack(m1, m2)

m3 looks like:

[[1,2,3],
 [4,5,6],
 [7,8,9]]

Testing Utilities#

pyrtl.rtllib.testingutils.an_input_and_vals(bitwidth, test_vals=20, name='', random_dist=<function uniform_dist>)[source]#

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 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 of input_wire, test_values

pyrtl.rtllib.testingutils.make_consts(num_wires, max_bitwidth=None, exact_bitwidth=None, random_dist=<function inverse_power_dist>)[source]#
Returns:

[Const_wires]; [Const_vals]

pyrtl.rtllib.testingutils.make_inputs_and_values(num_wires, max_bitwidth=None, exact_bitwidth=None, dist=<function uniform_dist>, test_vals=20)[source]#

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.multi_sim_multicycle(in_dict, hold_dict, hold_cycles, sim=None)[source]#

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:

pyrtl.rtllib.testingutils.sim_and_ret_out(outwire, inwires, invals)[source]#

Simulates the net using inwires and invals, 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)[source]#

Simulates the net using inwires and invals, 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)[source]#

Simulation of a circuit that takes multiple cycles to complete.

Parameters:
  • in_dict

  • hold_dict

  • hold_cycles

  • sim

Returns: