Created
July 10, 2015 19:09
-
-
Save cfelton/6565f079f681ac16c939 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division | |
from __future__ import print_function | |
from myhdl import * | |
""" | |
This module contains two designs that implement bank permutations. The | |
bank permutator takes an array input and maps to a differently ordered | |
array output. | |
The input and outputs (bank_i and bank_o) are list-of-signals. The | |
permutations are defined by a NxM matrix (2D list). Each column is | |
a different bank mapping, example: | |
>>> permutations = np.random.randint(0, 8, size=(8, 3)) | |
array([[2, 1, 4], | |
[1, 0, 3], | |
[3, 7, 0], | |
[6, 0, 0], | |
[2, 3, 7], | |
[6, 6, 5], | |
[7, 5, 4], | |
[5, 5, 1]]) | |
The port `psel` selects the current permutation from `permutations`. | |
The component is essentially a mux that wires the inputs to outputs | |
differently. For the example above when `psel = 0` | |
bank_o[0] = bank_i[2] | |
bank_o[1] = bank_i[1] | |
bank_o[2] = bank_i[3] | |
... | |
bank_o[7] = bank_i[5] | |
This module doesn't require the mappings to be unique. Different | |
implementations that are all functionally equivalent are described | |
in this module. The different descriptions provide different synthesis | |
results (see ...). | |
""" | |
def bank_permuter_rom1(clock, bank_i, bank_o, psel, permutations): | |
""" | |
Ports | |
----- | |
clock | |
bank_i: array input (list-of-signals) | |
bank_o: array outputs (list-of-signals) | |
psel : permutation select | |
Parameters | |
---------- | |
permutations: an NxM matrix (2D list) that describes the | |
input to output mappings. | |
""" | |
assert len(bank_i) == len(bank_o) | |
assert len(bank_i) == len(permutations[:]) | |
assert psel.max >= len(permutations[0][:]) | |
N = len(bank_i) | |
M = len(permutations[0][:]) | |
# flatten the above to a single ROM look-up-table | |
rom_map = [None for _ in range(N*M)] | |
for col in range(M): | |
for row in range(N): | |
rom_map[col*N+row] = permutations[row][col] | |
rom_map = tuple(map(int, rom_map)) | |
# create a map of the offsets to each column in the flat ROM | |
off_map = tuple([col*N for col in range(M)]) | |
@always(clock.posedge) | |
def rtl_permute(): | |
for ii in range(N): | |
off = off_map[psel] | |
idx = rom_map[ii + off] | |
bank_o[ii].next = bank_i[idx] | |
return rtl_permute | |
def bank_permuter_swz1(clock, bank_i, bank_o, psel, permutations): | |
""" | |
Ports | |
----- | |
clock | |
bank_i: array input (list-of-signals) | |
bank_o: array outputs (list-of-signals) | |
psel : permutation select | |
Parameters | |
---------- | |
permutations: an NxM matrix (2D list) that describes the | |
input to output mappings. | |
""" | |
assert len(bank_i) == len(bank_o) | |
assert len(bank_i) == len(permutations[:]) | |
assert psel.max >= len(permutations[0][:]) | |
N = len(bank_i) | |
M = len(permutations[0][:]) | |
def assign(sig_i, sig_o): | |
@always_comb | |
def rtl_assign(): | |
sig_o.next = sig_i | |
return rtl_assign | |
g_assigns = [] | |
pbank = [Signal(bank_i[0].val) for _ in range(N*M)] | |
for col in range(M): | |
for row in range(N): | |
pidx = permutations[row][col] | |
g_assigns += [assign(bank_i[pidx], pbank[col*N+row])] | |
@always(clock.posedge) | |
def rtl_output(): | |
for ii in range(N): | |
bank_o[ii].next = pbank[ii*psel+ii] | |
return g_assigns, rtl_output |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment