def check(filename, max_tests): c = circ.parse(filename) try: cnf = transform.transform(c) except Exception as e: print_error("Transformation of circuit '%s' failed." % c.name) print(e) print(traceback.format_exc()) return (False, 0, 0) inputs = c.getInputs() outputs = c.getOutputs() def validate(sol): invalues = dict() for i in inputs: try: invalues[i] = sol[i] except KeyError: invalues[i] = False result = c.simulate(invalues) for o in outputs: try: oval = sol[o] except KeyError: print_error( "Did not find value for output signal '%s' in solution" % o) return False if oval != result[o]: print_error("Inconsistent output value for signal '%s'" % o) return False return True tests = 0 good = 0 solutions = allSAT(cnf, c.getInputs()) while tests < max_tests: solution = next(solutions) if not solution: break if validate(solution): good += 1 tests += 1 return (True, good, tests)
#!/usr/bin/env python3 import sys import random import circuit.circuit as circ from circuit.cnf import SatVar, Solver # ===================================== Loading and simulating circuits print("===============================") # Load and simulate full adder circuit try: fa = circ.parse('benchmarks/fa.crc') except Exception as e: print("[INF] Could not load circuit. Good bye!") raise e # Write circuit graph to file with open('fa.dot', 'w') as f: f.write(fa.dot()) inputs = dict() print("{:^3}{:^3}{:^4}|{:^4}{:^3}".format('a', 'b', 'cin', 'cout', 's')) print("-" * 10 + "+" + "-" * 8) for i in range(8): # Convert i to a vector of Booleans bits = [b == '1' for b in format(i, '03b')] # Assign inputs
def test_adder(): from adder import mk_adder cnf = mk_adder() adder = circ.parse('benchmarks/fa.crc') if cnf is None: print_error("CNF is empty (None). Go do something about it...") return False # Function to constrain CNF with input conditions def constrain(cnf, test): def constr(x): return SatVar(x) if test[x] else ~SatVar(x) return cnf & constr('a') & constr('b') & constr('cin') # Functions to display test cases def head(): print_result("a b cin | cout s") print_result("--------+-------") def row(sim, sat): r = "%i %i %i | " % (sim['a'], sim['b'], sim['cin']) good = True complete = True if (not sat): r += red + '- -' + normal + ' [UNSAT]' good = False else: if not ('cout' in sat.keys()): r += red r += '- ' complete = False elif sim['cout'] == sat['cout']: r += green r += '%i ' % sim['cout'] else: r += red r += '%i ' % sat['cout'] good = False if not ('s' in sat.keys()): r += red r += '-' complete = False elif sim['s'] == sat['s']: r += green r += '%i' % sim['s'] + normal else: r += red r += '%i' % sat['s'] + normal good = False if not good: r += ' [wrong outputs]' if not complete: r += ' [incomplete solution]' print_result(r) return good and complete # test all input conditions B = [False, True] tests = [{'a':a, 'b':b, 'cin':c} for a in B for b in B for c in B] solver = Solver() head() pass_test = True for test in tests: sim = adder.simulate(test) sat = solver.solve(constrain(cnf, test)) pass_test = row(sim, sat) and pass_test return pass_test
def test_ec(): twoa = circ.parse('benchmarks/twoa.crc') twob = circ.parse('benchmarks/twob.crc') succ = True succ &= check_ec(twoa, twob, False) succ &= check_ec(twob, twoa, False) adder1 = circ.parse('benchmarks/fa.crc') adder2 = circ.parse('benchmarks/fa2.crc') adder3 = circ.parse('benchmarks/fa3.crc') adder4 = circ.parse('benchmarks/fa4.crc') # faulty adder # These should be equivalent succ &= check_ec(adder1, adder2, True) succ &= check_ec(adder2, adder3, True) succ &= check_ec(adder1, adder3, True) # Those aren't succ &= check_ec(adder1, adder4, False) succ &= check_ec(adder2, adder4, False) succ &= check_ec(adder3, adder4, False) # Those are completely different carry_ripple = circ.parse('benchmarks/cra8.crc') succ &= check_ec(adder1, carry_ripple, False) # That's a bigger one cra16 = circ.parse('benchmarks/cra16.crc') cla16 = circ.parse('benchmarks/cla16.crc') flt16 = circ.parse('benchmarks/faulty16.crc') succ &= check_ec(cra16, cla16, True) succ &= check_ec(flt16, cla16, False) succ &= check_ec(cra16, flt16, False) # And the biggest... cra32 = circ.parse('benchmarks/cra32.crc') cla32 = circ.parse('benchmarks/cla32.crc') flt32 = circ.parse('benchmarks/faulty32.crc') succ &= check_ec(cra32, cla32, True) succ &= check_ec(flt32, cla32, False) succ &= check_ec(cra32, flt32, False) return succ