Skip to content

Instantly share code, notes, and snippets.

@cfelton
Created July 10, 2015 19:09
Show Gist options
  • Save cfelton/6565f079f681ac16c939 to your computer and use it in GitHub Desktop.
Save cfelton/6565f079f681ac16c939 to your computer and use it in GitHub Desktop.
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