from typing import List
import pyrtl.rtllib.matrix as Matrix
from pyrtl import Output, Simulation
def LOAD(matrix: Matrix.Matrix, start: int, count: int) -> Matrix.Matrix:
""" Load subportion of a matrix into a row vector.
:param Matrix matrix: matrix to load from
:param int start: element number to start from (counting elements row-wise)
:param int count: number of elements to take from matrix
:return: a row vector Matrix (size 1xN)
Given
a = [[a0, a1, a2],
[a3, a4, a5]]
LOAD(a, 1, 4) returns
[[a1, a2, a3, a4]]
"""
flattened = matrix.flatten()
return flattened[0, start:start+count]
def STORE(vec: Matrix.Matrix, matrix: Matrix.Matrix, start: int, count: int) -> None:
""" Store a row vector into a matrix starting from a particular
element index in the matrix row-wise.
:param Matrix vec: row vector (size 1xN) to store
:param Matrix matrix: matrix where vec will be stored; must have at least N elements
:param int start: where to start putting elements into matrix
:param int count: how many elements from vec to put into matrix
The argument `matrix` will be updated as a result (no return value).
Given
vec = [[v0, v1, v2, v3]]
matrix = [[m0, m1, m2],
[m3, m4, m5]]
STORE(vec, matrix, 0, 4) will change matrix to be
matrix = [[v0, v1, v2],
[v3, m4, m5]]
"""
matrix.put(list(range(start, start+count)), vec)
def SHUF(vec: Matrix.Matrix, poss: List[int]) -> Matrix.Matrix:
""" Shuffle the elements of a row-vector according to some given indices
:param Matrix vec: a row vector containing elements we'll access
:param list[int] poss: a list of column indices into vec for accessing elements
:return Matrix: a new row vector
Given
v = [[v0, v1, v2, v3]]
and
p = [0, 1, 2, 0]
SHUF(v, p) returns
[[v0, v1, v2, v0]]
"""
return Matrix.concatenate(Matrix.Matrix(1, 1, vec.bits, value=vec[0, i]) for i in poss)
def SHUF2(a: Matrix.Matrix, b: Matrix.Matrix, poss: List[int]) -> Matrix.Matrix:
""" Helper that simply combines a and b into a single vector before calling SHUF
:param a: a row vector containing elements we'll access
:param b: a row vector containing elements we'll access
:param list[int] poss: a list of column indices into vec for accessing elements
:return: a row vector Matrix
See SHUF for an example usage.
"""
return SHUF(Matrix.hstack(a, b), poss)
def MUL(a: Matrix.Matrix, b: Matrix.Matrix) -> Matrix.Matrix:
""" Does *element-wise* multiplication of two row vectors.
:param Matrix a: a row vector Matrix (size 1xN)
:param Matrix b: a row vector Matrix (size 1xN)
:return: a new matrix of size 1xN
Given
a = [a0, a1, a2, a3]
and
b = [b0, b1, b2, b3]
mul(a, b) returns
[a0*b0, a1*b1, a2*b2, a3*b3]
Both a and b must be vectors of the same size
"""
return a * b
def MAC(accumulator: Matrix.Matrix, a: Matrix.Matrix, b: Matrix.Matrix) -> None:
""" Multiply-accumulate operation.
:param Matrix accumulator: row vector to add to
:param Matrix a: row vector to multiply
:param Matrix b: row vector to multiply
Updates accumulator to be accum + a*b (does not return any value).
"""
accumulator += MUL(a, b)