コード例 #1
0
 def test_no_dup(self):
     sel = pyrtl.WireVector(3)
     a = pyrtl.WireVector(3)
     b = pyrtl.WireVector(3)
     res = muxes.sparse_mux(sel, {6: a, 2: b})
     self.assertIsNot(res, a)
     self.assertIsNot(res, b)
コード例 #2
0
 def test_dup_consts2(self):
     sel = pyrtl.WireVector(3)
     c1 = pyrtl.Const(4)
     c2 = pyrtl.Const(4)
     res = muxes.sparse_mux(sel, {6: c1, 2: c2})
     self.assertIsInstance(res, pyrtl.Const)
     self.assertEqual(res.val, 4)
コード例 #3
0
def enum_mux(cntrl, table, default=None, strict=True):
    """ Build a mux for the control signals specified by an enum.

    :param cntrl: is a WireVector and control for the mux.
    :param table: is a dictionary of the form mapping enum->WireVector.
    :param default: is a WireVector to use when the key is not present. In addition
        it is possible to use the key 'otherwise' to specify a default value, but
        it is an error if both are supplied.
    :param strict: is flag, that when set, will cause enum_mux to check
        that the dictionary has an entry for every possible value in the enum.
        Note that if a default is set, then this check is not performed as
        the default will provide valid values for any underspecified keys.
    :return: a WireVector which is the result of the mux.

    Examples::

        from enum import IntEnum

        class Command(IntEnum):
            ADD = 1
            SUB = 2
        enum_mux(cntrl, {Command.ADD: a+b, Command.SUB: a-b})
        enum_mux(cntrl, {Command.ADD: a+b}, strict=False)  # SUB case undefined
        enum_mux(cntrl, {Command.ADD: a+b, otherwise: a-b})
        enum_mux(cntrl, {Command.ADD: a+b}, default=a-b)

    """
    # check dictionary keys are of the right type
    keytypeset = set(type(x) for x in table.keys() if x is not otherwise)
    if len(keytypeset) != 1:
        raise PyrtlError(
            'table mixes multiple types {} as keys'.format(keytypeset))
    keytype = list(keytypeset)[0]
    # check that dictionary is complete for the enum
    try:
        enumkeys = list(keytype.__members__.values())
    except AttributeError:
        raise PyrtlError(
            'type {} not an Enum and does not support the same interface'.
            format(keytype))
    missingkeys = [e for e in enumkeys if e not in table]

    # check for "otherwise" in table and move it to a default
    if otherwise in table:
        if default is not None:
            raise PyrtlError(
                'both "otherwise" and default provided to enum_mux')
        else:
            default = table[otherwise]

    if strict and default is None and missingkeys:
        raise PyrtlError(
            'table provided is incomplete, missing: {}'.format(missingkeys))

    # generate the actual mux
    vals = {k.value: d for k, d in table.items() if k is not otherwise}
    if default is not None:
        vals['default'] = default
    return muxes.sparse_mux(cntrl, vals)
コード例 #4
0
    def test_multiple_bitwidths(self):
        sel = pyrtl.Input(3)
        a1, a1_vals = gen_in(3)
        a2, a2_vals = gen_in(8)
        a3, a3_vals = gen_in(5)
        res = pyrtl.Output(name="output")

        m = muxes.sparse_mux(sel, {2: a1, 3: a2, 6: a3})
        self.assertEqual(len(m), 8)  # the biggest one
コード例 #5
0
    def test_two_vals(self):
        sel, sel_vals = gen_in(1)
        a1, a1_vals = gen_in(3)
        a2, a2_vals = gen_in(3)
        res = pyrtl.Output(name="output")

        res <<= muxes.sparse_mux(sel, {0: a1, 1: a2})
        in_vals = [sel_vals, a1_vals, a2_vals]
        out_res = utils.sim_and_ret_out(res, [sel, a1, a2], in_vals)

        expected_out = [e2 if sel else e1 for sel, e1, e2 in zip(*in_vals)]
        self.assertEqual(out_res, expected_out)
コード例 #6
0
    def test_two_big_close(self):
        sel = pyrtl.Input(3)
        a1, a1_vals = gen_in(3)
        a2, a2_vals = gen_in(3)
        res = pyrtl.Output(name="output")

        sel_vals = [utils.uniform_dist(1) for i in range(20)]
        real_sel = [6 if s else 5 for s in sel_vals]
        res <<= muxes.sparse_mux(sel, {5: a1, 6: a2})
        out_res = utils.sim_and_ret_out(res, [sel, a1, a2], [real_sel, a1_vals, a2_vals])

        expected_out = [e2 if sel else e1 for sel, e1, e2 in zip(sel_vals, a1_vals, a2_vals)]
        self.assertEqual(out_res, expected_out)
コード例 #7
0
    def test_default(self):
        sel, sel_vals = gen_in(3)
        a1, a1_vals = gen_in(3)
        a2, a2_vals = gen_in(3)
        default, default_vals = gen_in(3)
        res = pyrtl.Output(name="output")

        res <<= muxes.sparse_mux(sel, {5: a1, 6: a2, muxes.SparseDefault: default})
        out_res = utils.sim_and_ret_out(res, [sel, a1, a2, default],
                                        [sel_vals, a1_vals, a2_vals, default_vals])

        expected_out = [e2 if sel == 6 else e1 if sel == 5 else d
                        for sel, e1, e2, d in zip(sel_vals, a1_vals, a2_vals, default_vals)]
        self.assertEqual(out_res, expected_out)
コード例 #8
0
 def test_one_value(self):
     sel = pyrtl.WireVector(3)
     a = pyrtl.WireVector(1)
     self.assertIs(muxes.sparse_mux(sel, {6: a}), a)
コード例 #9
0
 def test_no_dup_2(self):
     sel = pyrtl.WireVector(3)
     c1 = pyrtl.Const(4)
     c2 = pyrtl.Const(6)
     res = muxes.sparse_mux(sel, {6: c1, 2: c2})
     self.assertNotIsInstance(res, pyrtl.Const)