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')
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))
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')
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
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
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
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'])
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