Beispiel #1
0
def test_feed_through_bench():
    G = read.bench(os.path.join(netlists, 'feed_through.bench'))
    assert G.nodes['N3']['type'] == 'INPUT'
    assert G.nodes['N3_BUFF']['type'] == 'BUFF'
    assert G.nodes['N3_BUFF_OUT']['type'] == 'OUTPUT'
    assert G.has_edge('N3', 'N3_BUFF')
    assert G.has_edge('N3_BUFF', 'N3_BUFF_OUT')
Beispiel #2
0
import os
from glob import glob
from pathlib import Path

import read
import write

benchmark_dir = 'Benchmarks'
ISCAS_85_sub_dir = 'ISCAS-85'
ITC_99_sub_dir = 'ITC-99'

verilog_benchmark_dir = 'VerilogBenchmarks'

for sub_dir in [ISCAS_85_sub_dir, ITC_99_sub_dir]:
    for file in glob(os.path.join(benchmark_dir, sub_dir, '*.bench')):
        graph = read.bench(file)
        print(file, graph.size())

        dest_dir = os.path.join(verilog_benchmark_dir, sub_dir)
        Path(dest_dir).mkdir(parents=True, exist_ok=True)
        write.verilog(graph, os.path.join(dest_dir, Path(file).stem))
Beispiel #3
0
def test_and_tree_bench():
    G_in = read.bench(os.path.join(netlists, 'and_tree.bench'))
    write.verilog(G_in, 'temp')
    G = read.verilog('temp.v')
    assert nx.is_isomorphic(G, G_in, lambda a, b: a['type'] == b['type'])
    os.remove('temp.v')
Beispiel #4
0
def benchmark_data(benchmark_file_path, format='bench'):
    """
    Function to find benchmark data

    Arguments:
        benchmark_file_path {string} -- Path to the benchmark design file

    Keyword Arguments:
        format {string} -- The format of the design file (default: {'bench'})

    Raises:
        ValueError: If format is unknown

    Returns:
        metrics [dictionary] -- Returns the metrics of the benchmark (in,out,dff,and,or,etc.)
    """

    # Read design from file
    if format == 'bench':
        circuit = read.bench(benchmark_file_path)
    elif format == 'verilog':
        circuit = read.verilog(benchmark_file_path)
    elif format == 'vhdl' or format == 'vhd':
        circuit = read.vhdl(benchmark_file_path)
    elif format == 'smv':
        circuit = read.smv(benchmark_file_path)
    else:
        raise ValueError(f"Unknown format {format}")

    # Find and return metrics
    metrics = {}
    metrics['input'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'INPUT'
    ])
    metrics['output'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'OUTPUT'
    ])
    metrics['dff'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'DFF'
    ])
    metrics['mux'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'MUX'
    ])
    metrics['and'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'AND'
    ])
    metrics['nand'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'NAND'
    ])
    metrics['or'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'OR'
    ])
    metrics['nor'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'NOR'
    ])
    metrics['xor'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'XOR'
    ])
    metrics['xnor'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'XNOR'
    ])
    metrics['not'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'NOT'
    ])
    metrics['buff'] = len([
        signal for signal, sigattr in circuit.nodes.items()
        if sigattr['type'] == 'BUFF' or sigattr['type'] == 'BUF'
    ])
    return metrics
Beispiel #5
0
def skew(netlist, skew_file_path):
    """
    Function to extract inputs, outputs, internal signals and gate types to find probability skew of all signals in the circuit.

    Arguments:
        netlist {networkx graph} : Graph generated by reading design using the read functions
        skew_file_path {string} : Path to file where the skew values are written. CSV file is preferable.

    Returns:
        None
    """

    # Function to calculate skew of output of a gate
    def calculate_gate_skew(gate_type, gate_input_skew_list):
        """
        Function that returns probability skew of a single gate output w.r.t skew of gate inputs based on the gate type.
        Supported gate types - AND, NAND, OR, NOR, NOT, BUFFER, DFF, 2-input XOR, 2-input XNOR, 2-input MUX
        :param gate_type: (string) highlights type of gate
        :param gate_input_skew_list: (list of numbers) probability skew values corresponding to each gate input
        :return: output_skew: (number) probability skew value of gate output
        """

        output_skew = 1
        gate_type = gate_type.strip()
        single_ip = True if len(gate_input_skew_list) < 2 else False
        if gate_type == "AND":
            if single_ip:
                return gate_input_skew_list[0]
            for signal_skew in gate_input_skew_list:
                output_skew *= (0.5 + signal_skew)
            output_skew -= 0.5
        elif gate_type == "NAND":
            if single_ip:
                return -1 * gate_input_skew_list[0]
            for signal_skew in gate_input_skew_list:
                output_skew *= (0.5 + signal_skew)
            output_skew = 0.5 - output_skew
        elif gate_type == "OR":
            if single_ip:
                return gate_input_skew_list[0]
            for signal_skew in gate_input_skew_list:
                output_skew *= (0.5 - signal_skew)
            output_skew = 0.5 - output_skew
        elif gate_type == "NOR":
            if single_ip:
                return -1 * gate_input_skew_list[0]
            for signal_skew in gate_input_skew_list:
                output_skew *= (0.5 - signal_skew)
            output_skew -= 0.5
        elif gate_type == "XOR":
            if single_ip:
                return -0.5
            output_skew = -2 * gate_input_skew_list[0] * gate_input_skew_list[1]
        elif gate_type == "XNOR":
            if single_ip:
                return 0.5
            output_skew = 2 * gate_input_skew_list[0] * gate_input_skew_list[1]
        elif gate_type == "MUX":
            if single_ip:
                return gate_input_skew_list[0]
            output_skew = (
                gate_input_skew_list[0] *
                (gate_input_skew_list[2] - gate_input_skew_list[1])) + (
                    (gate_input_skew_list[1] + gate_input_skew_list[2]) / 2)
        elif gate_type == "NOT":
            output_skew = -1 * gate_input_skew_list[0]
        elif gate_type == "BUFF" or gate_type == "BUF" or gate_type == "DFF" or gate_type == "OUTPUT":
            output_skew = gate_input_skew_list[0]
        else:
            print("Error : gate_type is " + gate_type)
            output_skew = 0
        return output_skew

    # Read netlist file if needed
    if isinstance(netlist, str):
        assert '.' in netlist, f"Design file extension must be provided"
        file_type = netlist[netlist.rfind('.') + 1:].strip()
        if file_type == 'bench':
            netlist = read.bench(netlist)
        elif file_type == 'verilog':
            netlist = read.verilog(netlist)
        else:
            raise ValueError(
                f"Skew calculation of design type {file_type} is not supported"
            )

    # Topologically sort the netlist
    try:
        sorted_nodes = list(nx.topological_sort(netlist))
    except (nx.NetworkXError, nx.NetworkXUnfeasible):
        raise ValueError("Netlist must be a DAG")

    # Find inputs, outputs and store file in list
    inputs = [
        signal for signal in netlist.nodes
        if netlist.nodes[signal]['type'] == 'INPUT'
    ]
    probability_skew = {}
    probability_skew = probability_skew.fromkeys(inputs, 0)

    # Find probability skew of all nodes in the netlist
    for signal in sorted_nodes:
        if signal in probability_skew:
            continue
        fanin = list(netlist.predecessors(signal))
        assert all(
            net in probability_skew for net in fanin
        ), f"Skew of some of the fan-in signals of {signal} has not been calculated"
        input_skew_list = [probability_skew[net] for net in fanin]
        probability_skew[signal] = calculate_gate_skew(
            netlist.nodes[signal]['type'], input_skew_list)
    assert all(signal in probability_skew for signal in sorted_nodes)

    # Write probability values to skew file
    if skew_file_path:
        with open(skew_file_path, 'w') as skew_file:
            skew_file.write("net,Prob0,Prob1\n")
            for signal in sorted(probability_skew.keys()):
                if netlist.nodes[signal]['type'] == 'OUTPUT':
                    continue
                p0, p1 = 0.5 - probability_skew[signal], probability_skew[
                    signal] + 0.5
                skew_file.write(signal + "," + str(p0) + "," + str(p1) + "\n")

    return probability_skew
Beispiel #6
0
def test_and_tree_bench():
    G = read.bench(os.path.join(netlists, 'and_tree.bench'))
    assert G.has_edge('N10', 'N14')
    assert G.has_node('N9')
    assert G.size() == 15
Beispiel #7
0
def test_buff_not_bench():
    G_bench = read.bench(os.path.join(netlists, 'buff_not.bench'))
    G_verilog = read.verilog(os.path.join(netlists, 'buff_not.v'))
    assert G_verilog.nodes['N3']['type'] == 'BUFF'
    assert G_verilog.nodes['N4']['type'] == 'NOT'
    assert nx.is_isomorphic(G_bench, G_verilog, lambda a, b: a['type'] == b['type'])
Beispiel #8
0
def test_feed_through_fan_out_bench():
    G = read.bench(os.path.join(netlists, 'feed_through_fan_out.bench'))
    for node, node_attr in G.nodes.items():
        # ensures no 'type'-less nodes were generated by adding an edge
        assert 'type' in node_attr