Beispiel #1
0
 def test_time_est_unchanged(self):
     a = pyrtl.Const(2, 8)
     b = pyrtl.Const(85, 8)
     zero = pyrtl.Const(0, 1)
     reg = pyrtl.Register(8)
     mem = pyrtl.MemBlock(8, 8)
     out = pyrtl.Output(8)
     nota, aLSB, athenb, aORb, aANDb, aNANDb, \
     aXORb, aequalsb, altb, agtb, aselectb, \
     aplusb, bminusa, atimesb, memread = [pyrtl.Output() for i in range(15)]
     out <<= zero
     nota <<= ~a
     aLSB <<= a[0]
     athenb <<= pyrtl.concat(a, b)
     aORb <<= a | b
     aANDb <<= a & b
     aNANDb <<= a.nand(b)
     aXORb <<= a ^ b
     aequalsb <<= a == b
     altb <<= a < b
     agtb <<= a > b
     aselectb <<= pyrtl.select(zero, a, b)
     reg.next <<= a
     aplusb <<= a + b
     bminusa <<= a - b
     atimesb <<= a * b
     memread <<= mem[0]
     mem[1] <<= a
     timing = estimate.TimingAnalysis()
     self.assertEqual(timing.max_freq(), 610.2770657878676)
     self.assertEquals(timing.max_length(), 1255.6000000000001)
Beispiel #2
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)
Beispiel #3
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()
Beispiel #4
0
def add_timing_info(net_graph=None,
                    net_attrs=None,
                    edge_attr=None,
                    timing=None,
                    scale=.4,
                    offset=50):
    net_graph, net_attrs, edge_attr = _check_graph_items(
        net_graph, net_attrs, edge_attr)
    if timing is None:
        from pyrtl.analysis import estimate
        timing = estimate.TimingAnalysis()

    wire_src, wire_dst = pyrtl.working_block().net_connections(
        include_virtual_nodes=True)

    tmap = timing.timing_map
    lDist = 'linkDistance'

    for wire, delay in tmap.items():
        item_offset = offset
        if isinstance(wire_src, (pyrtl.Input, pyrtl.Const, pyrtl.Register)):
            item_offset -= 40
        add_attr(net_attrs, 'depth', delay * scale + item_offset,
                 wire_src[wire])

    block = pyrtl.working_block()
    # deal with special cases
    for element in block.wirevector_subset(pyrtl.Output):
        add_attr(net_attrs, 'depth', tmap[element] * scale + offset + 20,
                 element)
        # add_attr(edge_attr, lDist, 30 + 20, element, element)  # add custom links

    for element in block.logic_subset('@r'):
        max_timing = max(*(tmap[w] for w in element.args))
        add_attr(net_attrs, 'depth', max_timing * scale + offset + 20, element)

    # now figure out the edges:
    for src_net, sn_dict in net_graph.items():
        for dst_net, dn_wire in sn_dict.items():
            depth_dist = net_attrs[dst_net]['depth'] - net_attrs[src_net][
                'depth']
            dist = math.sqrt(link_min_dist**2 + (depth_dist * 1.1)**2)
            add_attr(edge_attr, lDist, dist, src_net, dst_net)

    return net_attrs, edge_attr
Beispiel #5
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 = estimate.TimingAnalysis(block)
        sys.stdout = sys.__stdout__
        self.assertTrue(output.getvalue().startswith("Loop found:"))
# Timing and area usage are key considerations of any hardware block that one
# makes. PyRTL provides functions to do these operations.

# Creating a sample hardware block
pyrtl.reset_working_block()
const_wire = pyrtl.Const(6, bitwidth=4)
in_wire2 = pyrtl.Input(bitwidth=4, name="input2")
out_wire = pyrtl.Output(bitwidth=5, name="output")
out_wire <<= const_wire + in_wire2

# Now we will do the timing analysis as well as print out the critical path

# Generating timing analysis information
print("Pre Synthesis:")
timing = estimate.TimingAnalysis()
timing.print_max_length()

# We are also able to print out the critical paths as well as get them
# back as an array.
critical_path_info = timing.critical_path()

# --- Part 2: Area Analysis --------------------------------------------------

# PyRTL also provides estimates for the area that would be used up if the
# circuit was printed as an ASIC.

logic_area, mem_area = estimate.area_estimation(tech_in_nm=65)
est_area = logic_area + mem_area
print("Estimated Area of block", est_area, "sq mm")
print()