def reduce2(din, cfg: TCfg, *, f, max_size): """Similar to the Python reduce function, applies a rolling computation to sequential pairs of values in a list. The ``din`` input is of type :class:`Queue` which holds the values to be used for computation while the ``cfg`` input is a :class:`Tuple` consisting of a ``reduce_size`` field and the ``init`` field holding the inital value. Args: f: Function to be performed max_size: Maximal length of the input `Queue` which is the depth of the FIFO used for storing intermediate values Returns: The result of the reduce operation """ acctype = cfg.dtype['init'] qtype = Queue[acctype, din.dtype.lvl - 1] temp_res = Intf(dtype=qtype) cfg_rep = cfg | replicate sec_opnd = (cfg_rep, temp_res) \ | priority_mux \ | fmap(f=union_collapse, fcat=czip, lvl=1) result = czip(din, sec_opnd) | decouple | fmap(f=f, fcat=czip, lvl=2) acc, fin_res = result | Union[qtype, qtype] | demux acc | fifo(intfs=[temp_res], depth=max_size) return fin_res
def test_queuemap_simple(): @gear def test(din: Uint[4]) -> Uint[2]: pass iout = fmap(Intf(Queue[Uint[4], 2]), f=test, lvl=2) assert iout.dtype == Queue[Uint[2], 2]
def test_unionmap_simple_asymmetric(): @gear def test(din: Uint['size']) -> Uint['size+1']: pass iout = fmap(Intf(Union[Uint[8], Uint[8]]), f=(test, None)) assert iout.dtype == Union[Uint[9], Uint[8]]
def test_unionmap_simple(): @gear def test(din: Uint['size']) -> Uint['size+1']: pass iout = fmap(Intf(Union[Uint[1], Uint[2]]), f=(test, test)) assert iout.dtype == Union[Uint[2], Uint[3]]
def test_queuemap_tuplemap(): @gear def test(din: Uint['size']) -> Uint['size+1']: pass iout = fmap(Intf(Queue[Tuple[Uint[1], Uint[2]], 2]), f=(test, test), lvl=3) assert iout.dtype == Queue[Tuple[Uint[2], Uint[3]], 2]
def dualcycle_wrap_comb_middle(din) -> b'din[0][0]': middle = Intf(din.dtype[0]) middle_back = (middle | fmap(f=(add(0), add(0)))) >> din.dtype[0] return dualcycle(din, middle_back, intfs={'dout0': middle}, sim_cls=partial(SimVerilated, timeout=1))
def test_queuemap_balance(): @gear def bal(din: 'tdin') -> b'tdin': pass @gear def test(din: Uint['size']) -> Uint['size-1']: pass iout = fmap(Intf(Queue[Uint[4], 2]), f=test, lvl=2, balance=bal) assert iout.dtype == Queue[Uint[3], 2]
def test_unionmap_balance(): @gear def bal(din: 'tdin') -> b'tdin': pass @gear def test(din: Uint['size']) -> Uint['size+1']: pass iout = fmap(Intf(Union[Uint[1], Uint[2]]), f=(test, test), balance=bal) assert iout.dtype == Union[Uint[2], Uint[3]]
def stereo_echo( din: Tuple[Fixp, Fixp], # audio samples *, feedback_gain, # feedback gain == echo gain sample_rate, # sample_rate in samples per second delay # delay in seconds ): mono_echo = echo(feedback_gain=feedback_gain, sample_rate=sample_rate, delay=delay) return din | fmap(f=(mono_echo, mono_echo))
def pulse(cfg: TCfg): """Generates pulse of variable length, width is clk cycles for value 0""" cnt = rng(0, cfg['period'], 1) return cart(cnt, cfg['width']) | fmap(f=gt)
def test_queuemap_simple_fail(): @gear def test(din: Uint[4]) -> Uint[2]: pass fmap(Intf(Queue[Uint[4], 2]), f=test)
def test_tuplemap_simple_fail(): @gear def test(din: Uint['size']) -> Uint['size+1']: pass fmap(Intf(Tuple[Uint[1], Uint[2]]), f=test)
from pygears.lib import drv, check, mul, fmap from pygears.typing import Uint, Tuple drv(t=Tuple[Uint[16], Uint[16]], seq=[(0, 0), (1, 10), (2, 20)]) \ | fmap(f=(mul(2), mul(2))) \ | check(ref=[(0, 0), (2, 20), (4, 40)])
from pygears.lib import drv, check, mul, fmap from pygears.typing import Queue, Uint drv(t=Queue[Uint[16]], seq=[[0, 1, 2, 3, 4]]) \ | fmap(f=mul(2)) \ | check(ref=[[0, 2, 4, 6, 8]])
from pygears.lib import drv, check, sub, fmap from pygears.typing import Int, Uint, Union drv(t=Union[Int[16], Uint[16]], seq=[(0, 1), (1, 1), (-10, 0), (-11, 0)]) \ | fmap(f=(sub(b=1), None)) \ | check(ref=[(0, 1), (1, 1), (-11, 0), (-12, 0)])