|
6 | 6 | from ..wire import Const, WireVector
|
7 | 7 | from ..corecircuits import as_wires, concat, select
|
8 | 8 | from ..pyrtlexceptions import PyrtlError
|
| 9 | +from ..helperfuncs import formatted_str_to_val |
9 | 10 |
|
10 | 11 |
|
11 | 12 | class Matrix(object):
|
@@ -1342,3 +1343,58 @@ def matrix_wv_to_list(matrix_wv, rows, columns, bits):
|
1342 | 1343 | result[i][j] = int_value
|
1343 | 1344 | bit_pointer += bits
|
1344 | 1345 | return result
|
| 1346 | + |
| 1347 | + |
| 1348 | +def list_to_int(matrix, n_bits): |
| 1349 | + ''' Convert a Python matrix (a list of lists) into an integer. |
| 1350 | +
|
| 1351 | + :param list[list[int]] matrix: a pure Python list of lists representing a matrix |
| 1352 | + :param int n_bits: number of bits to be used to represent each element; if an |
| 1353 | + element doesn't fit in n_bits, it truncates the most significant bits. |
| 1354 | + :return int: a N*n_bits wide wirevector containing the elements of `matrix`, |
| 1355 | + where N is the number of elements in `matrix` |
| 1356 | +
|
| 1357 | + Integers that are signed will automatically be converted to their two's complement form. |
| 1358 | +
|
| 1359 | + This function is helpful for turning a pure Python list of lists |
| 1360 | + into a integer suitable for creating a Constant wirevector that can |
| 1361 | + be passed in to as a Matrix intializer's `value` argument, or for |
| 1362 | + passing into a Simulation's step function for a particular input wire. |
| 1363 | +
|
| 1364 | + For example, calling Matrix.list_to_int([3, 5], [7, 9], 4) produces 13,689, |
| 1365 | + which in binary looks like this:: |
| 1366 | +
|
| 1367 | + 0011 0101 0111 1001 |
| 1368 | +
|
| 1369 | + Note how the elements of the list of lists were added, 4 bits at a time, |
| 1370 | + in row order, such that the element at row 0, column 0 is in the most significant |
| 1371 | + 4 bits, and the element at row 1, column 1 is in the least significant 4 bits. |
| 1372 | +
|
| 1373 | + Here's an example of using it in simulation:: |
| 1374 | +
|
| 1375 | + a_vals = [[0, 1], [2, 3]] |
| 1376 | + b_vals = [[2, 4, 6], [8, 10, 12]] |
| 1377 | +
|
| 1378 | + a_in = pyrtl.Input(4 * 4, 'a_in') |
| 1379 | + b_in = pyrtl.Input(6 * 4, 'b_in') |
| 1380 | + a = Matrix.Matrix(2, 2, 4, value=a_in) |
| 1381 | + b = Matrix.Matrix(2, 3, 4, value=b_in) |
| 1382 | + ... |
| 1383 | +
|
| 1384 | + sim = pyrtl.Simulation() |
| 1385 | + sim.step({ |
| 1386 | + 'a_in': Matrix.list_to_int(a_vals) |
| 1387 | + 'b_in': Matrix.list_to_int(b_vals) |
| 1388 | + }) |
| 1389 | + ''' |
| 1390 | + if n_bits <= 0: |
| 1391 | + raise PyrtlError("Number of bits per element must be positive, instead got %d" % n_bits) |
| 1392 | + |
| 1393 | + result = 0 |
| 1394 | + |
| 1395 | + for i in range(len(matrix)): |
| 1396 | + for j in range(len(matrix[0])): |
| 1397 | + val = formatted_str_to_val(str(matrix[i][j]), 's' + str(n_bits)) |
| 1398 | + result = (result << n_bits) | val |
| 1399 | + |
| 1400 | + return result |
0 commit comments