Example #1
0
 def test_memblock_with_write_enable_with_equalsign(self):
     we = pyrtl.Const(1, bitwidth=1)
     self.output1 <<= self.memory[self.mem_read_address1]
     self.output2 <<= self.memory[self.mem_read_address2]
     self.memory[self.mem_write_address] <<= \
         pyrtl.MemBlock.EnabledWrite(self.mem_write_data, enable=we)
     pyrtl.working_block().sanity_check()
Example #2
0
 def test_with_block_exception(self):
     pyrtl.set_working_block(self.block_a)
     with self.assertRaises(pyrtl.PyrtlInternalError):
         with pyrtl.set_working_block(self.block_b):
             self.assertIs(pyrtl.working_block(), self.block_b)
             raise pyrtl.PyrtlInternalError()
     self.assertIs(pyrtl.working_block(), self.block_a)
Example #3
0
 def test_memblock_assign_with_extention(self):
     big_output = pyrtl.Output(self.bitwidth+1, "big_output")
     big_output <<= self.memory[self.mem_read_address1]
     self.output1 <<= 1
     self.output2 <<= 2
     self.memory[self.mem_write_address] <<= self.mem_write_data
     pyrtl.working_block().sanity_check()
Example #4
0
 def test_async_check_should_pass_with_select(self):
     memory = pyrtl.MemBlock(
                 bitwidth=self.bitwidth, 
                 addrwidth=self.addrwidth-1,
                 name='memory')
     self.output1 <<= memory[self.mem_read_address1[0:-1]]
     pyrtl.working_block().sanity_check()
Example #5
0
 def test_unknown_wires(self):
     inp = pyrtl.Input(8, 'inp')
     out = pyrtl.Output(8, 'out')
     out <<= inp
     pyrtl.working_block().wirevector_set.discard(inp)
     with self.assertRaises(pyrtl.PyrtlInternalError):  # sanity_check_net()
         self.sanity_error("Unknown wires")
Example #6
0
 def test_async_check_should_pass(self):
     memory = pyrtl.MemBlock(
                 bitwidth=self.bitwidth, 
                 addrwidth=self.addrwidth,
                 name='memory')
     self.output1 <<= memory[self.mem_read_address1]
     memory[self.mem_write_address] <<= self.mem_write_data
     pyrtl.working_block().sanity_check()
Example #7
0
 def test_async_check_should_pass_with_cat(self):
     memory = pyrtl.MemBlock(
                 bitwidth=self.bitwidth, 
                 addrwidth=self.addrwidth,
                 name='memory')
     addr = pyrtl.concat(self.mem_read_address1[0], self.mem_read_address2[0:-1])
     self.output1 <<= memory[addr]
     memory[self.mem_write_address] <<= self.mem_write_data
     pyrtl.working_block().sanity_check()
Example #8
0
 def test_undriven_net(self):
     w = pyrtl.WireVector(name='testwire', bitwidth=3)
     self.assertRaises(pyrtl.PyrtlError, pyrtl.working_block().sanity_check)
     pyrtl.reset_working_block()
     r = pyrtl.Register(3)
     self.assertRaises(pyrtl.PyrtlError, pyrtl.working_block().sanity_check)
     pyrtl.reset_working_block()
     o = pyrtl.Output(3)
     self.assertRaises(pyrtl.PyrtlError, pyrtl.working_block().sanity_check)
Example #9
0
 def test_invalid_set_wb(self):
     x = pyrtl.WireVector()
     y = 1
     pyrtl.set_working_block(self.block_a)
     with self.assertRaises(pyrtl.PyrtlError):
         pyrtl.set_working_block(x)
     self.assertEqual(pyrtl.working_block(), self.block_a)
     with self.assertRaises(pyrtl.PyrtlError):
         pyrtl.set_working_block(y)
     self.assertEqual(pyrtl.working_block(), self.block_a)
Example #10
0
    def test_const_different_bitwidth_1(self):
        in_w = pyrtl.Input(5)
        const = pyrtl.Const(23, 5)
        const_2 = pyrtl.Const(23, 6)
        wire_1 = in_w + const
        wire_2 = in_w + const_2

        pyrtl.common_subexp_elimination()
        self.num_net_of_type('+', 2)
        pyrtl.working_block().sanity_check()
Example #11
0
    def test_const_values_2(self):
        in_w = pyrtl.Input(5)
        const = pyrtl.Const(23, 5)
        const_2 = pyrtl.Const(23, 5)
        wire_1 = in_w + const
        wire_2 = in_w + const_2

        pyrtl.common_subexp_elimination()
        self.num_net_of_type('+', 1)
        pyrtl.working_block().sanity_check()
Example #12
0
 def test_with_block_nested(self):
     self.block_c = pyrtl.Block()
     pyrtl.set_working_block(self.block_a)
     self.assertIs(pyrtl.working_block(), self.block_a)
     with pyrtl.set_working_block(self.block_b):
         self.assertIs(pyrtl.working_block(), self.block_b)
         with pyrtl.set_working_block(self.block_c):
             self.assertIs(pyrtl.working_block(), self.block_c)
         self.assertIs(pyrtl.working_block(), self.block_b)
     self.assertIs(pyrtl.working_block(), self.block_a)
Example #13
0
    def test_2read_1write(self):
        small_memory = pyrtl.MemBlock(bitwidth=self.bitwidth, addrwidth=self.addrwidth,
                                      name='small_memory', max_read_ports=2, max_write_ports=1)
        temp = small_memory[self.mem_read_address1]  # read
        temp2 = small_memory[self.mem_read_address2]  # read

        self.output1 <<= temp
        self.output2 <<= temp2
        small_memory[self.mem_write_address] <<= pyrtl.Const(6)  # write
        pyrtl.working_block().sanity_check()
Example #14
0
 def test_valid_slices(self):
     self.valid_slice(8, slice(6))
     self.valid_slice(8, slice(1, 4))
     self.valid_slice(8, slice(1, 8))  # Yes, supplying a end index out of bounds is valid python
     self.valid_slice(8, slice(1, 2, 2))
     self.valid_slice(8, slice(1, 4, 2))
     self.valid_slice(8, slice(7, 1, -2))
     self.valid_slice(8, slice(-2))
     self.valid_slice(8, slice(-6, -2, 3))
     pyrtl.working_block().sanity_check()
Example #15
0
 def test_async_check_should_notpass_with_add(self):
     memory = pyrtl.MemBlock(
                 bitwidth=self.bitwidth, 
                 addrwidth=self.addrwidth,
                 name='memory')
     addr = pyrtl.WireVector(self.bitwidth)
     addr <<= self.mem_read_address1 + self.mem_read_address2
     self.output1 <<= memory[addr]
     print(pyrtl.working_block())
     with self.assertRaises(pyrtl.PyrtlError):
         pyrtl.working_block().sanity_check()
Example #16
0
 def test_memblock_to_memblock_direct_operation(self):
     temp = (self.memory[self.mem_read_address1] == self.memory[self.mem_read_address2])
     temp = (self.memory[self.mem_read_address1] != self.memory[self.mem_read_address2])
     temp = (self.memory[self.mem_read_address1] & self.memory[self.mem_read_address2])
     temp = (self.memory[self.mem_read_address1] | self.memory[self.mem_read_address2])
     temp = (self.memory[self.mem_read_address1] + self.memory[self.mem_read_address2])
     temp = (self.memory[self.mem_read_address1] - self.memory[self.mem_read_address2])
     temp2 = (self.memory[self.mem_read_address1] * self.memory[self.mem_read_address2])
     self.output1 <<= temp
     self.output2 <<= temp2
     pyrtl.working_block().sanity_check()
Example #17
0
    def test_net_odd_wires(self):
        wire = pyrtl.WireVector(2, 'wire')
        net = self.new_net(args=(wire, wire))
        other_block = pyrtl.Block()
        wire._block = other_block
        self.invalid_net("net references different block", net)

        pyrtl.reset_working_block()
        wire = pyrtl.WireVector(2, 'wire')
        net = self.new_net(args=(wire,))
        pyrtl.working_block().remove_wirevector(wire)
        self.invalid_net("net with unknown source", net)
Example #18
0
 def test_invalid_with_set_wb(self):
     x = pyrtl.Input()
     y = True
     pyrtl.set_working_block(self.block_a)
     with self.assertRaises(pyrtl.PyrtlError):
         with pyrtl.set_working_block(x):
             pass
     self.assertEqual(pyrtl.working_block(), self.block_a)
     with self.assertRaises(pyrtl.PyrtlError):
         with pyrtl.set_working_block(y):
             pass
     self.assertEqual(pyrtl.working_block(), self.block_a)
Example #19
0
    def test_multiple_elimination(self):
        ins = [pyrtl.Input(5) for i in range(3)]
        out_1 = pyrtl.Output(5)
        a = ins[0] ^ ins[1]
        b = ins[0] ^ ins[1]
        c = ins[0] ^ ins[1]

        out_1 <<= a | b | c
        pyrtl.common_subexp_elimination()
        self.num_net_of_type('^', 1)
        self.num_net_of_type('|', 2)
        pyrtl.working_block().sanity_check()
Example #20
0
    def test_different_arg_order(self):
        ins = [pyrtl.Input(5) for i in range(2)]
        outs = [pyrtl.Output(5) for i in range(2)]
        outs[0] <<= ins[1] & ins[0]
        outs[1] <<= ins[0] & ins[1]

        pyrtl.common_subexp_elimination()
        self.num_net_of_type('&', 1)
        self.num_net_of_type('w', 2)
        self.assert_num_net(3)
        self.assert_num_wires(5)
        pyrtl.working_block().sanity_check()
Example #21
0
    def test_concat(self):
        # concat's args are order dependent, therefore we need to check
        # that we aren't mangling them
        ins = [pyrtl.Input(5) for i in range(2)]
        outs = [pyrtl.Output(10) for i in range(2)]
        outs[0] <<= pyrtl.concat(ins[1], ins[0])
        outs[1] <<= pyrtl.concat(ins[0], ins[1])

        pyrtl.common_subexp_elimination()
        self.num_net_of_type('c', 2)
        self.num_net_of_type('w', 2)
        self.assert_num_net(4)
        self.assert_num_wires(6)
        pyrtl.working_block().sanity_check()
Example #22
0
    def test_order_dependent_ops(self):
        # subtract, lt, gt simarlarly are order dependent.
        # therefore we need to check that we aren't mangling them
        for op, opcode in ((operator.sub, '-'), (operator.gt, '>'), (operator.lt, '<')):
            pyrtl.reset_working_block()
            ins = [pyrtl.Input(5) for i in range(2)]
            outs = [pyrtl.Output(10) for i in range(2)]
            outs[0] <<= op(ins[1], ins[0])
            outs[1] <<= op(ins[0], ins[1])

            pyrtl.common_subexp_elimination()
            self.num_net_of_type(opcode, 2)
            self.num_net_of_type('w', 2)
            pyrtl.working_block().sanity_check()
Example #23
0
    def test_const_values_1(self):
        in_w = pyrtl.Input(5)
        out = pyrtl.Output(5)
        const = pyrtl.Const(23, 5)
        wire_1 = in_w + const
        wire_2 = in_w + const
        out <<= wire_1 | wire_2

        pyrtl.common_subexp_elimination()
        self.num_net_of_type('+', 1)
        self.num_net_of_type('w', 1)
        self.assert_num_net(4)  # because we cut off a bit after the add
        self.assert_num_wires(6)
        pyrtl.working_block().sanity_check()
Example #24
0
    def test_nested_elimination(self):
        ins = [pyrtl.Input(5) for i in range(3)]
        out_1 = pyrtl.Output(5)
        a = ins[0] ^ ins[0]
        b = ins[0] ^ ins[0]

        a2 = a & ins[2]
        b2 = b & ins[2]

        out_1 <<= a2 | b2
        pyrtl.common_subexp_elimination()
        self.num_net_of_type('^', 1)
        self.num_net_of_type('&', 1)
        pyrtl.working_block().sanity_check()
Example #25
0
    def test_no_elimination_of_different_const_bitwidths(self):
        # trying to merge const wires with different bitwidths
        # together will cause mismatches in bitwidths of certain wires
        const_1 = pyrtl.Const(3, 3)
        const_2 = pyrtl.Const(3, 5)
        out_1 = pyrtl.Output(5)
        out_2 = pyrtl.Output(5)
        out_1 <<= const_1 | const_1
        out_2 <<= const_2 | const_2
        pyrtl.common_subexp_elimination()

        self.num_net_of_type('|', 2)
        self.num_net_of_type('w', 2)
        self.assert_num_net(6)
        self.assert_num_wires(9)
        pyrtl.working_block().sanity_check()
Example #26
0
    def check_graph_correctness(self, w_src_graph, w_dst_graph, has_virtual=False):
        for wire, net in w_src_graph.items():
            if isinstance(wire, (pyrtl.Input, pyrtl.Const)):
                if has_virtual:
                    self.assertIs(wire, net)
                else:
                    self.fail("Input or Const, {} should not have a src".format(str(wire)))
            else:
                self.assertTrue(any(wire is w for w in net.dests))

        for wire, nets in w_dst_graph.items():
            if isinstance(wire, pyrtl.Output):
                if has_virtual:
                    self.assertEqual(len(nets), 1)
                    self.assertIs(wire, nets[0])
                else:
                    self.fail("Output, {} should not have a dst".format(str(wire)))
            else:
                for net in nets:
                    self.assertTrue(any(wire is w for w in net.args))
            self.assertEqual(len(nets), len(set(nets)))

        for net in pyrtl.working_block().logic:
            for wire in net.args:
                self.assertIn(net, w_dst_graph[wire])
            for wire in net.dests:
                self.assertIs(w_src_graph[wire], net)
Example #27
0
def circuit_equivalence(equv_func, in_wires=None, out_wire=None, block=None, print_invalid=True):
    """
    Checks whether a circuit is equivalent to a python function

    :param equv_func: function to test circuit equivelence of. int args are passed
      in the order of the in_wires
    :param [Input] in_wires: wires for input (in order of args for equiv_func).
      default: all input wires, in their name's alphabetical order.
    :param Output out_wire: wire to use for output, default: find the only one
    :param Bool print_invalid:
    :return: bool
    """
    block = pyrtl.working_block(block)
    in_wires = _get_inputs(in_wires, block)
    out_wire = _get_output(out_wire, block)

    # now we get into the algorithm
    bits_to_test = sum(w.bitwidth for w in in_wires)

    sim = pyrtl.Simulation()
    for test_val in range(2**bits_to_test):
        vals = _create_seq_list(in_wires, test_val)
        sim.step({w: v for w, v in zip(in_wires, vals)})
        out_val = sim.inspect(out_wire)
        expected_val = equv_func(*vals)
        if not isinstance(expected_val, numbers.Integral):
            raise pyrtl.PyrtlError("Equv_func return %s, which is not an integer" %
                                   repr(expected_val))
        if out_val != expected_val:
            if print_invalid:
                situation_str = ', '.join(str(w) + ' = ' + str(v) for w, v in zip(in_wires, vals))
                print("in situation {}, got: {} expected: {}"
                      .format(situation_str, out_val, expected_val))
            return False
    return True
Example #28
0
def color_based_on_op(net_attrs=None, block=None, attr_name='fill',
                      net_colors=d3_category20_colors):
    net_color_dict = {op: color for op, color in zip(net_types, net_colors)}
    block = pyrtl.working_block(block)
    if net_attrs is None:
        net_attrs = {}
    for net in block.logic:
        add_attr(net_attrs, attr_name, net_color_dict[net.op], net)
    return net_attrs
Example #29
0
 def test_rename(self):
     block = pyrtl.working_block()
     w = pyrtl.WireVector(1, "test1")
     self.assertIn("test1", block.wirevector_by_name)
     self.assertIn(w, block.wirevector_set)
     w.name = "testJohn"
     self.assertNotIn("test1", block.wirevector_by_name)
     self.assertIn("testJohn", block.wirevector_by_name)
     self.assertIn(w, block.wirevector_set)
Example #30
0
    def everything_t_procedure(self, timing_val=None, opt_timing_val=None):
        # if there is a nondefault timing val supplied, then it will check
        # to make sure that the timing matches
        # this is a subprocess to do the synth and timing
        block = pyrtl.working_block()
        timing = estimate.TimingAnalysis(block)
        timing_max_length = timing.max_length()
        if timing_val is not None:
            self.assertEqual(timing_max_length, timing_val)
        critical_path = timing.critical_path()

        pyrtl.synthesize()
        pyrtl.optimize()

        block = pyrtl.working_block()
        timing = estimate.TimingAnalysis(block)
        timing_max_length = timing.max_length()
        if opt_timing_val is not None:
            self.assertEqual(timing_max_length, opt_timing_val)
        critical_path = timing.critical_path()

        pyrtl.and_inverter_synth()
        pyrtl.optimize()

        block = pyrtl.working_block()
        timing = estimate.TimingAnalysis(block)
        timing_max_length = timing.max_length()
        critical_path = timing.critical_path()
        block = pyrtl.working_block()
        self.num_net_of_type('|', 0, block)
        self.num_net_of_type('^', 0, block)

        pyrtl.nand_synth()
        pyrtl.optimize()

        block = pyrtl.working_block()
        timing = estimate.TimingAnalysis(block)
        timing_max_length = timing.max_length()
        critical_path = timing.critical_path()
        block.sanity_check()
        self.num_net_of_type('|', 0, block)
        self.num_net_of_type('^', 0, block)
        self.num_net_of_type('&', 0, block)
Example #31
0
    def test_basic_one_var_op_1(self):
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()

        outwire <<= ~constwire
        pyrtl.synthesize()
        pyrtl.optimize()

        block = pyrtl.working_block()
        self.num_net_of_type('~', 0, block)
        self.num_net_of_type('w', 1, block)
        self.assertEqual(len(block.logic), 1)
        self.assertEqual(len(block.wirevector_set), 2)
        self.num_wire_of_type(Const, 1, block)
Example #32
0
    def test_wirevector_1(self):
        inwire = pyrtl.Input(bitwidth=1)
        tempwire0, tempwire1 = pyrtl.WireVector(bitwidth=1), pyrtl.WireVector(
            bitwidth=1)
        tempwire2 = pyrtl.WireVector(bitwidth=1)
        outwire = pyrtl.Output()

        tempwire0 <<= inwire
        tempwire1 <<= tempwire0
        tempwire2 <<= tempwire1
        outwire <<= ~tempwire2
        self.everything_t_procedure(1, 1)
        block = pyrtl.working_block()
        self.assert_num_net(3, block)
Example #33
0
 def test_wire_net_removal_2(self):
     inwire = pyrtl.Input(bitwidth=3)
     tempwire = pyrtl.WireVector()
     tempwire2 = pyrtl.WireVector()
     outwire = pyrtl.Output()
     tempwire <<= inwire
     tempwire2 <<= tempwire
     outwire <<= tempwire
     pyrtl.synthesize()
     pyrtl.optimize()
     # should remove the middle wires but keep the input
     block = pyrtl.working_block()
     self.assert_num_net(5, block)
     self.assert_num_wires(6, block)
Example #34
0
    def test_replace_output(self):
        def f(wire):
            w = pyrtl.clone_wire(wire, 'w2')
            return w, wire

        a, b = pyrtl.input_list('a/1 b/1')
        w1 = a & b
        o = pyrtl.Output(1, 'o')
        o <<= w1

        src_nets, dst_nets = pyrtl.working_block().net_connections()
        self.assertEqual(dst_nets[w1],
                         [pyrtl.LogicNet('w', None, (w1, ), (o, ))])
        self.assertIn(o, src_nets)

        transform.wire_transform(f,
                                 select_types=pyrtl.Output,
                                 exclude_types=tuple())

        w2 = pyrtl.working_block().get_wirevector_by_name('w2')
        src_nets, dst_nets = pyrtl.working_block().net_connections()
        self.assertEqual(dst_nets[w1],
                         [pyrtl.LogicNet('w', None, (w1, ), (w2, ))])
        self.assertNotIn(o, src_nets)
Example #35
0
    def test_const_folding_basic_two_var_op_2(self):
        inwire = pyrtl.Input(bitwidth=1)
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()

        outwire <<= inwire | constwire
        pyrtl.optimize()
        # should remove the and block and replace it with a
        # wire net (to separate the const from the output)
        block = pyrtl.working_block(None)
        self.assertEqual(self.num_net_of_type('|', block), 0)
        self.assertEqual(self.num_net_of_type('w', block), 1)
        self.assertEqual(len(block.logic), 1)
        self.assertEqual(len(block.wirevector_set), 2)
        self.assertEqual(self.num_wire_of_type(pyrtl.wire.Const, block), 0)
Example #36
0
    def test_block(self):
        a = pyrtl.Const(23)
        b = pyrtl.Input(5)
        o = pyrtl.Output(5)
        o <<= ~a & b

        old_block = pyrtl.working_block()
        old_block.sanity_check()
        self.assert_num_wires(5, old_block)
        self.assert_num_net(3, old_block)

        new_block = transform.copy_block()
        new_block.sanity_check()
        self.assert_num_wires(5, new_block)
        self.assert_num_net(3, old_block)
Example #37
0
    def test_basic_two_var_op_2(self):
        inwire = pyrtl.Input(bitwidth=1)
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()

        outwire <<= inwire | constwire
        pyrtl.optimize()
        # should remove the or block and replace it with a
        # wire net (to separate the const from the output)
        block = pyrtl.working_block(None)
        self.num_net_of_type('|', 0, block)
        self.num_net_of_type('w', 1, block)
        self.assert_num_net(1, block)
        self.assert_num_wires(2, block)
        self.num_wire_of_type(Const, 0, block)
Example #38
0
    def test_timing_error(self):
        inwire, inwire2 = pyrtl.Input(bitwidth=1), pyrtl.Input(bitwidth=1)
        tempwire, tempwire2 = pyrtl.WireVector(1), pyrtl.WireVector(1)
        outwire = pyrtl.Output()

        tempwire <<= ~(inwire & tempwire2)
        tempwire2 <<= ~(inwire2 & tempwire)
        outwire <<= tempwire

        with self.assertRaises(pyrtl.PyrtlError):
            pyrtl.synthesize()
            pyrtl.optimize()
            block = pyrtl.working_block()
            timing = estimate.TimingAnalysis(block)
            timing_max_length = timing.max_length()
Example #39
0
 def test_combo_blif_input_has_correct_io_interface(self):
     pyrtl.input_from_blif(full_adder_blif)
     x, y, cin, sumw, cout, bad = [
         pyrtl.working_block().get_wirevector_by_name(s)
         for s in ['x', 'y', 'cin', 'sum', 'cout', 'bad']
     ]
     self.assertIsNotNone(x)
     self.assertIsNotNone(y)
     self.assertIsNotNone(cin)
     self.assertIsNotNone(sumw)
     self.assertIsNotNone(cout)
     self.assertIsNone(bad)
     self.assertEquals(len(x), 1)
     self.assertEquals(len(y), 1)
     self.assertEquals(len(cin), 1)
     self.assertEquals(len(sumw), 1)
     self.assertEquals(len(cout), 1)
     io_input = pyrtl.working_block().wirevector_subset(pyrtl.Input)
     self.assertIn(x, io_input)
     self.assertIn(y, io_input)
     self.assertIn(cin, io_input)
     io_output = pyrtl.working_block().wirevector_subset(pyrtl.Output)
     self.assertIn(sumw, io_output)
     self.assertIn(cout, io_output)
Example #40
0
    def test_const_folding_basic_two_var_op_3(self):
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()

        # playing with edge cases
        outwire <<= constwire ^ constwire
        pyrtl.synthesize()
        pyrtl.optimize()
        # should remove the and block and replace it with a
        # wirevector (to separate the input from the output)
        block = pyrtl.working_block(None)
        self.assertEqual(self.num_net_of_type('|', block), 0)
        self.assertEqual(self.num_net_of_type('w', block), 1)
        self.assertEqual(len(block.logic), 1)
        self.assertEqual(len(block.wirevector_set), 2)
        self.assertEqual(self.num_wire_of_type(pyrtl.wire.Const, block), 1)
Example #41
0
    def test_basic_two_var_op_3(self):
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()

        # playing with edge cases
        outwire <<= constwire ^ constwire
        pyrtl.synthesize()
        pyrtl.optimize()
        # should remove the and block and replace it with a
        # wirevector (to separate the input from the output)
        block = pyrtl.working_block(None)
        self.num_net_of_type('^', 0, block)
        self.num_net_of_type('w', 1, block)
        self.assert_num_net(1, block)
        self.assert_num_wires(2, block)
        self.num_wire_of_type(Const, 1, block)
Example #42
0
    def test_as_graph_memory(self):
        m = pyrtl.MemBlock(addrwidth=2,
                           bitwidth=2,
                           name='m',
                           max_read_ports=None)
        i = pyrtl.Register(bitwidth=2, name='i')
        o = pyrtl.WireVector(bitwidth=2, name='o')
        i.next <<= i + 1
        m[i] <<= pyrtl.mux((m[i] != 0), 0, m[i])
        o <<= m[i]

        b = pyrtl.working_block()
        src_g, dst_g = b.net_connections(False)
        self.check_graph_correctness(src_g, dst_g)

        src_g, dst_g = b.net_connections(True)
        self.check_graph_correctness(src_g, dst_g, True)
Example #43
0
    def test_replace_multiple_wires(self):
        j, n = pyrtl.Input(8), pyrtl.Output(8)
        o, h = pyrtl.WireVector(), pyrtl.WireVector()
        x, y = pyrtl.WireVector(8), pyrtl.WireVector(8)

        o <<= j
        h <<= o
        n <<= h
        block = pyrtl.working_block()
        src_nets, dst_nets = block.net_connections()
        transform.replace_wire_fast(o, x, x, src_nets, dst_nets)
        transform.replace_wire_fast(h, y, y, src_nets, dst_nets)
        for old_wire in (o, h):
            self.assertNotIn(old_wire, src_nets)
            self.assertNotIn(old_wire, dst_nets)
            self.assertNotIn(old_wire, block.wirevector_set)
        block.sanity_check()
Example #44
0
    def test_const_folding_adv_one_var_op_1(self):
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()
        tempwire = pyrtl.WireVector()
        reg = pyrtl.Register(1, 'test register')

        tempwire <<= ~constwire
        reg.next <<= tempwire
        outwire <<= reg
        pyrtl.synthesize()
        pyrtl.optimize()

        block = pyrtl.working_block(None)
        self.assertEqual(self.num_net_of_type('w', block), 1)
        self.assertEqual(len(block.logic), 1)
        self.assertEqual(len(block.wirevector_set), 2)
        self.assertEqual(self.num_wire_of_type(pyrtl.wire.Const, block), 1)
        self.assertEqual(self.num_wire_of_type(pyrtl.wire.Output, block), 1)
Example #45
0
    def test_adv_one_var_op_1(self):
        constwire = pyrtl.Const(0, 1)
        outwire = pyrtl.Output()
        tempwire = pyrtl.WireVector()
        reg = pyrtl.Register(1, 'test register')

        tempwire <<= ~constwire
        reg.next <<= tempwire
        outwire <<= reg
        pyrtl.synthesize()
        pyrtl.optimize()

        block = pyrtl.working_block(None)
        self.num_net_of_type('w', 1, block)
        self.assert_num_net(1, block)
        self.assert_num_wires(2, block)
        self.num_wire_of_type(Const, 1, block)
        self.num_wire_of_type(Output, 1, block)
Example #46
0
    def test_timing_error(self):
        inwire, inwire2 = pyrtl.Input(bitwidth=1), pyrtl.Input(bitwidth=1)
        tempwire, tempwire2 = pyrtl.WireVector(1), pyrtl.WireVector(1)
        outwire = pyrtl.Output()

        tempwire <<= ~(inwire & tempwire2)
        tempwire2 <<= ~(inwire2 & tempwire)
        outwire <<= tempwire

        output = six.StringIO()
        sys.stdout = output
        with self.assertRaises(pyrtl.PyrtlError):
            pyrtl.synthesize()
            pyrtl.optimize()
            block = pyrtl.working_block()
            _timing = pyrtl.TimingAnalysis(block)
        sys.stdout = sys.__stdout__
        self.assertTrue(output.getvalue().startswith("Loop found:"))
Example #47
0
    def test_two_var_op_produce_not(self):
        constwire = pyrtl.Const(1, 1)
        inwire = pyrtl.Input(bitwidth=1)
        outwire = pyrtl.Output()

        # playing with edge cases
        outwire <<= constwire ^ inwire
        pyrtl.synthesize()
        pyrtl.optimize()
        # should remove the and block and replace it with a
        # wirevector (to separate the input from the output)
        block = pyrtl.working_block(None)
        self.num_net_of_type('~', 1, block)
        self.num_net_of_type('w', 1, block)
        self.num_net_of_type('s', 1, block)  # due to synthesis
        self.assert_num_net(3, block)
        self.assert_num_wires(4, block)
        self.num_wire_of_type(Const, 0, block)
Example #48
0
    def test_wire_used_in_multiple_places(self):
        j, k = pyrtl.Input(8), pyrtl.Input(8)
        n, o = pyrtl.Output(8), pyrtl.Output(8)
        x = pyrtl.WireVector(8)

        r = j & k
        n <<= j | r
        o <<= r ^ k

        block = pyrtl.working_block()
        src_nets, dst_nets = block.net_connections()
        transform.replace_wire_fast(r, x, x, src_nets, dst_nets)

        for old_wire in (r, ):
            self.assertNotIn(old_wire, src_nets)
            self.assertNotIn(old_wire, dst_nets)
            self.assertNotIn(old_wire, block.wirevector_set)
        block.sanity_check()
Example #49
0
    def test_as_graph_duplicate_args(self):
        a = pyrtl.Input(3)
        x = pyrtl.Input(1)
        d = pyrtl.Output()
        b = a & a
        c = pyrtl.concat(a, a)
        m = pyrtl.MemBlock(addrwidth=3, bitwidth=3, name='m')
        m2 = pyrtl.MemBlock(addrwidth=1, bitwidth=1, name='m')
        d <<= m[a]
        m[a] <<= a
        m2[x] <<= pyrtl.MemBlock.EnabledWrite(x, x)

        b = pyrtl.working_block()
        src_g, dst_g = b.net_connections(False)
        self.check_graph_correctness(src_g, dst_g)

        src_g, dst_g = b.net_connections(True)
        self.check_graph_correctness(src_g, dst_g, True)
Example #50
0
    def test_step_with_internal_memory(self):
        def special_memory(read_addr, write_addr, data, wen):
            mem = pyrtl.MemBlock(bitwidth=32, addrwidth=5, name='special_mem')
            mem[write_addr] <<= pyrtl.MemBlock.EnabledWrite(
                data, wen & (write_addr > 0))
            return mem[read_addr]

        read_addr = pyrtl.Input(5, 'read_addr')
        write_addr = pyrtl.Input(5, 'write_addr')
        data = pyrtl.Input(32, 'data')
        wen = pyrtl.Input(1, 'wen')
        res = pyrtl.Output(32, 'res')

        res <<= special_memory(read_addr, write_addr, data, wen)

        # Can only access it after the `special_memory` block has been instantiated/called
        special_mem = pyrtl.working_block().get_memblock_by_name('special_mem')

        sim = self.sim(
            memory_value_map={special_mem: {
                0: 5,
                1: 6,
                2: 7,
                3: 8,
            }})

        inputs = {
            'read_addr': '012012',
            'write_addr': '012012',
            'data': '890333',
            'wen': '111000',
        }
        expected = {
            'res': '567590',
        }
        # This should not fail
        sim.step_multiple(inputs, expected)

        # Let's check the memory contents too
        mem_map = sim.inspect_mem(special_mem)
        self.assertEqual(mem_map[0], 5)
        self.assertEqual(mem_map[1], 9)
        self.assertEqual(mem_map[2], 0)
        self.assertEqual(mem_map[3], 8)
Example #51
0
    def test_as_graph_2(self):
        a = pyrtl.Input(2)
        b = pyrtl.Input(2)
        c = pyrtl.Input(2)
        e = pyrtl.Output()
        f = pyrtl.Output()
        g = pyrtl.Output()

        d = a & c
        f <<= b & c
        e <<= d
        g <<= ~(d | b)

        b = pyrtl.working_block()
        src_g, dst_g = b.net_connections(False)
        self.check_graph_correctness(src_g, dst_g)

        src_g, dst_g = b.net_connections(True)
        self.check_graph_correctness(src_g, dst_g, True)
Example #52
0
    def test_two_var_op_correct_wire_prop(self):
        ins = [pyrtl.Input(1) for i in range(3)]
        outwire = pyrtl.Output()
        const_w = pyrtl.Const(0)
        temp1 = ins[1] & ins[2]
        temp2 = temp1 ^ const_w
        temp3 = const_w | temp2

        outwire <<= temp3 & ins[2]

        pyrtl.optimize()
        block = pyrtl.working_block()
        block.sanity_check()  # just in case

        self.num_net_of_type('&', 2)
        self.num_net_of_type('w', 1)
        self.assert_num_net(3)
        self.assert_num_wires(6)
        self.num_wire_of_type(Const, 0)
Example #53
0
    def test_one_bit_selects(self):
        a = pyrtl.Const(0b101101001101)
        b = pyrtl.Output(6, 'b')
        b <<= a[::2]  # bits 0, 2, 4, 6, 8, and 10 of wire a

        block = pyrtl.working_block()
        select_nets = list(block.logic_subset(op='s'))
        self.assertEqual(len(select_nets), 1)
        self.assertEqual(tuple(select_nets[0].op_param), (0, 2, 4, 6, 8, 10))

        pyrtl.one_bit_selects()

        select_nets = list(block.logic_subset(op='s'))
        for net in select_nets:
            indices = net.op_param
            self.assertEqual(len(indices), 1)

        sim = pyrtl.Simulation()
        sim.step({})
        self.assertEqual(sim.inspect('b'), 0b00011011)
Example #54
0
def circuit_equivalence(equv_func,
                        in_wires=None,
                        out_wire=None,
                        block=None,
                        print_invalid=True):
    """
    Checks whether a circuit is equivalent to a python function

    :param equv_func: function to test circuit equivelence of. int args are passed
      in the order of the in_wires
    :param [Input] in_wires: wires for input (in order of args for equiv_func).
      default: all input wires, in their name's alphabetical order.
    :param Output out_wire: wire to use for output, default: find the only one
    :param Bool print_invalid:
    :return: bool
    """
    block = pyrtl.working_block(block)
    in_wires = _get_inputs(in_wires, block)
    out_wire = _get_output(out_wire, block)

    # now we get into the algorithm
    bits_to_test = sum(w.bitwidth for w in in_wires)

    sim = pyrtl.Simulation()
    for test_val in range(2**bits_to_test):
        vals = _create_seq_list(in_wires, test_val)
        sim.step({w: v for w, v in zip(in_wires, vals)})
        out_val = sim.inspect(out_wire)
        expected_val = equv_func(*vals)
        if not isinstance(expected_val, numbers.Integral):
            raise pyrtl.PyrtlError(
                "Equv_func return %s, which is not an integer" %
                repr(expected_val))
        if out_val != expected_val:
            if print_invalid:
                situation_str = ', '.join(
                    str(w) + ' = ' + str(v) for w, v in zip(in_wires, vals))
                print("in situation {}, got: {} expected: {}".format(
                    situation_str, out_val, expected_val))
            return False
    return True
Example #55
0
    def test_two_var_op_correct_not_wire_replacement(self):
        ins = [pyrtl.Input(1) for i in range(3)]
        outwire = pyrtl.Output()
        const_0 = pyrtl.Const(0)
        const_1 = pyrtl.Const(1)
        temp1 = ins[0] & ins[1]
        temp2 = const_0 | temp1
        temp3 = temp2 ^ const_1

        outwire <<= temp3 & ins[2]

        pyrtl.optimize()
        block = pyrtl.working_block()
        block.sanity_check()  # just in case

        self.num_net_of_type('&', 2)
        self.num_net_of_type('~', 1)
        self.num_net_of_type('w', 1)
        self.assert_num_net(4)
        self.assert_num_wires(7)
        self.num_wire_of_type(Const, 0)
Example #56
0
    def test_block_iterators(self):
        # testing to see that it properly runs a trivial case
        inwire = pyrtl.Input(bitwidth=1, name="inwire1")
        inwire2 = pyrtl.Input(bitwidth=1)
        inwire3 = pyrtl.Input(bitwidth=1)
        tempwire = pyrtl.WireVector()
        tempwire2 = pyrtl.WireVector()
        outwire = pyrtl.Output()

        tempwire <<= inwire | inwire2
        tempwire2 <<= ~tempwire
        outwire <<= tempwire2 & inwire3

        block = pyrtl.working_block()

        i = 0
        for net in block:
            self.assertFalse(i > 100, "Too many iterations happened")
            i += 1
            print(str(net))

        for net in block.logic:
            print(net)
Example #57
0
    def test_copy_mem(self):
        ins = [pyrtl.Input(5) for i in range(4)]
        out = pyrtl.Output(5)

        mem1 = pyrtl.MemBlock(5, 5)
        mem2 = pyrtl.MemBlock(5, 5)

        mem1_o1 = mem1[ins[0]]
        mem1[ins[1]] <<= ins[2]
        mem2_o2 = mem2[ins[3]]
        out <<= mem1_o1 & mem2_o2

        old_block = pyrtl.working_block()
        old_block.sanity_check()
        self.num_net_of_type('m', 2, old_block)
        self.num_net_of_type('@', 1, old_block)
        self.num_net_of_type('&', 1, old_block)
        self.num_memories(2, old_block)

        new_block = transform.copy_block()
        self.num_net_of_type('m', 2, new_block)
        self.num_net_of_type('@', 1, new_block)
        self.num_net_of_type('&', 1, new_block)
        self.num_memories(2, new_block)
Example #58
0
    def test_adv_one_var_op_2(self):
        # this one tests to see that an input wirevector is properly preserved

        inwire = pyrtl.Input(bitwidth=1)
        outwire = pyrtl.Output()
        tempwire = pyrtl.WireVector()
        reg = pyrtl.Register(1, 'test register')

        tempwire <<= ~inwire
        reg.next <<= tempwire
        outwire <<= reg
        pyrtl.synthesize()
        pyrtl.optimize()
        # should remove the and block and replace it with a
        # wire net (to separate the input from the output)
        block = pyrtl.working_block(None)

        # Note: the current implementation still sticks a wire net between
        # a register 'nextsetter' wire and the output wire
        self.num_net_of_type('w', 1, block)
        self.assert_num_net(4, block)
        self.assert_num_wires(5, block)
        self.num_wire_of_type(Const, 0, block)
        self.num_wire_of_type(Output, 1, block)
Example #59
0
    def test_as_graph_trivial(self):
        i = pyrtl.Input(1)
        o = pyrtl.Output(1)
        b = pyrtl.working_block()
        net = pyrtl.LogicNet('~', None, (i,), (o,))
        b.add_net(net)
        src_g, dst_g = b.net_connections(False)
        self.check_graph_correctness(src_g, dst_g)
        self.assertEqual(src_g[o], net)
        self.assertEqual(dst_g[i][0], net)
        self.assertEqual(len(dst_g[i]), 1)

        self.assertNotIn(i, src_g)
        self.assertNotIn(o, dst_g)

        src_g, dst_g = b.net_connections(True)
        self.check_graph_correctness(src_g, dst_g, True)
        self.assertEqual(src_g[o], net)
        self.assertEqual(dst_g[i][0], net)
        self.assertEqual(len(dst_g[i]), 1)

        self.assertIs(src_g[i], i)
        self.assertIs(dst_g[o][0], o)
        self.assertEqual(len(dst_g[o]), 1)
Example #60
0
1- 1
-1 1
.names cin ind2 $and$FA.v:19$12_Y
11 1
.names $and$FA.v:19$11_Y $and$FA.v:19$12_Y cout
1- 1
-1 1
.names $not$FA.v:11$1_Y y ind0
11 1
.end
"""

pyrtl.input_from_blif(full_adder_blif)
# Have to find the actual wire vectors generated from the names in the blif file
x, y, cin = [
    pyrtl.working_block().get_wirevector_by_name(s) for s in ['x', 'y', 'cin']
]
io_vectors = pyrtl.working_block().wirevector_subset(
    (pyrtl.Input, pyrtl.Output))

# We are only going to trace the input and output vectors for clarity
sim_trace = pyrtl.SimulationTrace(wires_to_track=io_vectors)
# Now simulate the logic with some random inputs
sim = pyrtl.Simulation(tracer=sim_trace)
for i in range(15):
    # here we actually generate random booleans for the inputs
    sim.step({
        'x': random.choice([0, 1]),
        'y': random.choice([0, 1]),
        'cin': random.choice([0, 1])
    })