Example #1
0
 def add_rule_from_expr(self, pyeda_expr):
     self.rule = {}
     rule_tt = eda.expr2truthtable(pyeda_expr)
     for line in str(rule_tt).splitlines():
         if ':' in line:
             q = "".join(line.split(":")[-1].strip())
             x2 = "".join(line.split()[0].strip())
             x1 = "".join(line.split()[1].strip())
             self.rule[x2 + x1] = q
    def get_all_value(self):
        self.all_value = str(p.expr2truthtable(
            self.propositional_formula)).split('\n')
        self.all_value = self.all_value[1:-1]

        for counter in range(len(self.all_value)):
            self.all_value[counter] = re.findall(r'[\w]+',
                                                 self.all_value[counter])

        self.all_answers = [x for lst in self.all_value for x in lst[-1]]
Example #3
0
def calc_prep(cut, P, PVarList):
	"""!
	Function calculates representative function for given cut

	Function converts truthtable outvector to smallest p-representative using permutation trees . runtime = O(|V|+|E|) reduced due to using only smallest path in search tree
	@param [in] cut as pyeda formula
	@param [in] P as DiGraph of permutation tree of size (len(cut.inputs))

	@param [out] pRep as list containg the p-representative
	"""
	# create truthtable of cut
	T = expr2truthtable(cut)
	inputs = T.inputs

	# calculate the outvector of the truth table of cut
	outvec = list()

	for i, point in enumerate(boolfunc.iter_points(inputs)):
		#~ invec = [2 if point[v] else 1 for v in inputs]
		val = T.pcdata[i]
		if val == PC_ZERO:
			outvec.append(0)
		elif val == PC_ONE:
			outvec.append(1)
		elif val == PC_DC:
			outvec.append(2)

	# search permutation tree, to find smallest pRepresentative
	coefPerm = search_permut_tree(P, [nx.topological_sort(P)[0]], outvec)

	coefPerm = coefPerm.split("_")[1:]

	# find pRep from coefficent permutation and outvector of truth table
	pRep = []
	for i in range(len(outvec)):
		pRep.append(outvec[int(coefPerm[i])])

	for x in range(len(coefPerm)):
		coefPerm[x] = int(coefPerm[x])

	permDict = PVarList["perm" + str(int(math.log(len(coefPerm))/math.log(2)))]
	permut = permDict[str(coefPerm)]

	return pRep, permut
    def setup(self, expressions):
        """Configure CFGLUTs with new boolean expression.

        Parameters
        ----------
        expressions : list/dict
            The boolean expression to be configured.

        """

        if isinstance(expressions, list):
            for i in range(len(expressions)):
                self.expressions['Boolean expression {}'.format(i)] = \
                    deepcopy(expressions[i])
        elif isinstance(expressions, dict):
            self.expressions = deepcopy(expressions)
        else:
            raise ValueError("Expressions must be list or dict.")

        mailbox_addr = self.bg_mmio.base_addr
        mailbox_regs = [
            Register(addr)
            for addr in range(mailbox_addr, mailbox_addr + 4 * 64, 4)
        ]
        for offset in range(0, 32, 2):
            mailbox_regs[offset][31:0] = 0x1FFFFFF

        for index in range(0, 32):
            self.bg_mmio.write((index * 4), mailbox_regs[index][31:0])
        self.bg_mmio.write((62 * 4), 0x0000ffff)
        self.bg_mmio.write((63 * 4), (0x0000ffff | 0x80000000))
        self.bg_mmio.write((63 * 4), 0)  # was 0x0000ffff)

        for expr_label, expression in self.expressions.items():
            if not isinstance(expression, str):
                raise TypeError("Boolean expression has to be a string.")

            if "=" not in expression:
                raise ValueError(
                    "Boolean expression must have form Output = Function.")

            # Parse boolean expression into output & input string
            expr_out, expr_in = expression.split("=")
            expr_out = expr_out.strip()
            if expr_out in self.output_pins:
                raise ValueError("The same output pin should not be driven by "
                                 "multiple expressions.")
            self.output_pins.append(expr_out)
            if expr_out in self.intf_spec['output_pins']:
                output_pin_num = self.intf_spec['output_pins'][expr_out]
            else:
                raise ValueError("Invalid output pin {}.".format(expr_out))

            # Parse the used pins preserving the order
            non_unique_inputs = re.sub("\W+", " ", expr_in).strip().split(' ')
            unique_input_pins = list(OrderedDict.fromkeys(non_unique_inputs))
            if not 1 <= len(unique_input_pins) <= 5:
                raise ValueError("Expect 1 - 5 inputs for each LUT.")
            input_pins_with_dontcares = unique_input_pins[:]
            self.input_pins += unique_input_pins
            self.input_pins = list(set(self.input_pins))

            # Need 5 inputs - any unspecified inputs will be don't cares
            for i in range(len(input_pins_with_dontcares), 5):
                expr_in = '(({0}) & X{1})|(({0}) & ~X{1})'.format(expr_in, i)
                input_pins_with_dontcares.append('X{}'.format(i))

            # Map to truth table
            p0, p1, p2, p3, p4 = map(exprvar, input_pins_with_dontcares)
            expr_p = expr_in

            # Use regular expression to match and replace whole word only
            for orig_name, p_name in zip(input_pins_with_dontcares,
                                         ['p{}'.format(i) for i in range(5)]):
                expr_p = re.sub(r"\b{}\b".format(orig_name), p_name, expr_p)

            truth_table = expr2truthtable(eval(expr_p))

            # Parse truth table to send
            truth_list = str(truth_table).split("\n")
            truth_num = 0
            for i in range(32, 0, -1):
                truth_num = (truth_num << 1) + int(truth_list[i][-1])

            # Get current boolean generator bit enables
            bit_enables = self.bg_mmio.read(62 * 4)
            cfg_enables = self.bg_mmio.read(63 * 4)

            # Generate the input selects based on truth table and bit enables
            truth_table_inputs = [str(inp) for inp in truth_table.inputs]
            for i in range(5):
                lsb = i * 5
                msb = (i + 1) * 5 - 1
                if truth_table_inputs[i] in unique_input_pins:
                    if truth_table_inputs[i] in self.intf_spec[
                        'input_pins'] and truth_table_inputs[i] \
                            in self.intf_spec['input_pins']:
                        input_pin_ix = self.intf_spec['input_pins'][
                            truth_table_inputs[i]]
                    else:
                        raise ValueError("Invalid input pin "
                                         "{}.".format(truth_table_inputs[i]))
                else:
                    input_pin_ix = 0x1f
                mailbox_regs[output_pin_num * 2][msb:lsb] = input_pin_ix

            mailbox_regs[output_pin_num * 2 + 1][31:0] = truth_num
            mailbox_regs[62][31:0] = bit_enables
            mailbox_regs[62][output_pin_num] = 0

            mailbox_regs[63][31:0] = cfg_enables
            mailbox_regs[63][output_pin_num] = 1

        int_to_write_62 = int(mailbox_regs[62][31:0])
        int_to_write_63 = int(mailbox_regs[63][31:0])
        for index in range(0, 32):
            self.bg_mmio.write((index * 4), (mailbox_regs[index][31:0]))
        self.bg_mmio.write((62 * 4), int_to_write_62)
        self.bg_mmio.write((63 * 4), (int_to_write_63 | 0x80000000))
        self.bg_mmio.write((63 * 4), int_to_write_63)
Example #5
0
    def setup(self, expressions, frequency_mhz=DEFAULT_CLOCK_FREQUENCY_MHZ):
        """Configure the generator with new boolean expression.

        This method will bring the generator from 'RESET' to 
        'READY' state.

        Parameters
        ----------
        expressions : list/dict
            The boolean expression to be configured.
        frequency_mhz: float
            The frequency of the captured samples, in MHz.

        """
        try:
            from pyeda.inter import exprvar
            from pyeda.inter import expr2truthtable
        except ImportError:
            raise ImportError("Using Logictools requires pyeda")

        if not MIN_CLOCK_FREQUENCY_MHZ <= frequency_mhz <= \
                MAX_CLOCK_FREQUENCY_MHZ:
            raise ValueError("Clock frequency out of range "
                             "[{}, {}]".format(MIN_CLOCK_FREQUENCY_MHZ,
                                               MAX_CLOCK_FREQUENCY_MHZ))

        if not 1 <= len(expressions) <= self.intf_spec['interface_width'] + \
                len(self.intf_spec['non_traceable_outputs']):
            raise ValueError("Too many or no Boolean expressions specified.")

        if isinstance(expressions, list):
            for i in range(len(expressions)):
                self.expressions['Boolean expression {}'.format(i)] = \
                    deepcopy(expressions[i])
        elif isinstance(expressions, dict):
            self.expressions = deepcopy(expressions)
        else:
            raise ValueError("Expressions must be list or dict.")

        mailbox_addr = self.logictools_controller.mmio.base_addr + \
            MAILBOX_OFFSET
        mailbox_regs = [
            Register(addr)
            for addr in range(mailbox_addr, mailbox_addr + 4 * 64, 4)
        ]
        for offset in range(0, 48, 2):
            mailbox_regs[offset][31:0] = 0x1FFFFFF

        for expr_label, expression in self.expressions.items():
            if not isinstance(expression, str):
                raise TypeError("Boolean expression has to be a string.")

            if "=" not in expression:
                raise ValueError(
                    "Boolean expression must have form Output = Function.")

            # Parse boolean expression into output & input string
            expr_out, expr_in = expression.split("=")
            expr_out = expr_out.strip()
            if expr_out in self.output_pins:
                raise ValueError("The same output pin should not be driven by "
                                 "multiple expressions.")
            self.output_pins.append(expr_out)
            if expr_out in self.intf_spec['traceable_io_pins']:
                output_pin_num = self.intf_spec['traceable_io_pins'][expr_out]
            elif expr_out in self.intf_spec['non_traceable_outputs']:
                output_pin_num = self.intf_spec['non_traceable_outputs'][
                    expr_out]
            else:
                raise ValueError("Invalid output pin {}.".format(expr_out))

            # Parse the used pins preserving the order
            non_unique_inputs = re.sub(r"\W+", " ", expr_in).strip().split(' ')
            unique_input_pins = list(OrderedDict.fromkeys(non_unique_inputs))
            if not 1 <= len(unique_input_pins) <= 5:
                raise ValueError("Expect 1 - 5 inputs for each LUT.")
            input_pins_with_dontcares = unique_input_pins[:]
            self.input_pins += unique_input_pins
            self.input_pins = list(set(self.input_pins))

            # Need 5 inputs - any unspecified inputs will be don't cares
            for i in range(len(input_pins_with_dontcares), 5):
                expr_in = '(({0}) & X{1})|(({0}) & ~X{1})'.format(expr_in, i)
                input_pins_with_dontcares.append('X{}'.format(i))

            # Map to truth table
            p0, p1, p2, p3, p4 = map(exprvar, input_pins_with_dontcares)
            expr_p = expr_in

            # Use regular expression to match and replace whole word only
            for orig_name, p_name in zip(input_pins_with_dontcares,
                                         ['p{}'.format(i) for i in range(5)]):
                expr_p = re.sub(r"\b{}\b".format(orig_name), p_name, expr_p)

            truth_table = expr2truthtable(eval(expr_p))

            # Parse truth table to send
            truth_list = str(truth_table).split("\n")
            truth_num = 0
            for i in range(32, 0, -1):
                truth_num = (truth_num << 1) + int(truth_list[i][-1])

            # Get current boolean generator bit enables
            self.logictools_controller.write_command(
                CMD_READ_BOOLEAN_DIRECTION)
            bit_enables = mailbox_regs[0][31:0]

            # Generate the input selects based on truth table and bit enables
            truth_table_inputs = [str(inp) for inp in truth_table.inputs]
            for i in range(5):
                lsb = i * 5
                msb = (i + 1) * 5 - 1
                if truth_table_inputs[i] in unique_input_pins:
                    if truth_table_inputs[i] in self.intf_spec[
                        'traceable_io_pins'] and truth_table_inputs[i] \
                            in self.intf_spec['traceable_io_pins']:
                        input_pin_ix = self.intf_spec['traceable_io_pins'][
                            truth_table_inputs[i]]
                    elif truth_table_inputs[i] in self.intf_spec[
                            'non_traceable_inputs']:
                        input_pin_ix = self.intf_spec['non_traceable_inputs'][
                            truth_table_inputs[i]]
                    else:
                        raise ValueError("Invalid input pin "
                                         "{}.".format(truth_table_inputs[i]))
                else:
                    input_pin_ix = 0x1f
                mailbox_regs[output_pin_num * 2][msb:lsb] = input_pin_ix

            mailbox_regs[output_pin_num * 2 + 1][31:0] = truth_num
            mailbox_regs[62][31:0] = bit_enables
            mailbox_regs[62][output_pin_num] = 0

            mailbox_regs[63][31:0] = 0
            mailbox_regs[63][output_pin_num] = 1

            # Construct the command word
            self.logictools_controller.write_command(CMD_CONFIG_BOOLEAN)

            # Prepare the waveform object
            waveform_dict = {
                'signal': [['stimulus'], {}, ['analysis']],
                'head': {
                    'text': '{}: {}'.format(expr_label, expression)
                }
            }

            # Append four inputs and one output to waveform view
            stimulus_traced = False
            for pin_name in unique_input_pins:
                if pin_name in self.intf_spec['traceable_io_pins']:
                    stimulus_traced = True
                    waveform_dict['signal'][0].append({
                        'name': pin_name,
                        'pin': pin_name
                    })
            if not stimulus_traced:
                del (waveform_dict['signal'][0])

            if expr_out in self.intf_spec['traceable_io_pins']:
                waveform_dict['signal'][-1].append({
                    'name': expr_out,
                    'pin': expr_out
                })
            else:
                del (waveform_dict['signal'][-1])

            self.waveforms[expr_label] = Waveform(
                waveform_dict,
                stimulus_group_name='stimulus',
                analysis_group_name='analysis')

        # Check used pins on the controller
        for i in self.input_pins + self.output_pins:
            if self.logictools_controller.pin_map[i] != 'UNUSED':
                raise ValueError("Pin conflict: {} already in use.".format(
                    self.logictools_controller.pin_map[i]))

        # Reserve pins only if there are no conflicts for any pin
        for i in self.output_pins:
            self.logictools_controller.pin_map[i] = 'OUTPUT'
        for i in self.input_pins:
            self.logictools_controller.pin_map[i] = 'INPUT'

        # Configure the trace analyzer and frequency
        if self.analyzer is not None:
            self.analyzer.setup(self.num_analyzer_samples, frequency_mhz)
        else:
            self.logictools_controller.clk.fclk1_mhz = frequency_mhz
        self.frequency_mhz = frequency_mhz

        # Update generator status
        self.logictools_controller.check_status()
        self.logictools_controller.steps = 0
inputs = [x1, x2, x3, x4]
kardo_functions = set()
count = 0
for vec in list(itertools.product(range(3), repeat=12))[::-1]:
    d = dict(zip(all_vars, vec))
    #print("==============================")
    #print(d)
    function = (x1 & notx21 & notx31 & notx4) | (x1 & notx21 & x31 & x4) | (x1 & x21 & notx32 & x4) | (x1 & x21 & x32 & notx4) | (notx1 & notx22 & notx32 & x4) | (notx1 & notx22 & x32 & notx4) | (notx1 & x22 & notx31 & notx4) | (notx1 & x22 & x31 & x4)
    restrict_dict = {key:value for key, value in d.items() if value in (0, 1)}
    #print(restrict_dict)
    function = function.restrict(restrict_dict)
    #print(function)
    for var, vars_lst in equals:
        for v in vars_lst:
            function = function.compose({v: var})
    #print(function)
    fictitious_vars = [v for v in inputs if v not in function.inputs]
    for v in fictitious_vars:
        function = function & (v | ~v)
    #print(function)
    #print(expr2truthtable(function))
    kardo_functions.add(str(tuple(map(lambda x: x-1, list(expr2truthtable(function).pcdata)))))
    count += 1
    print(count)
    #if count > 1000:
    #    break

with open("results.txt", "w") as f:
    f.write("\n".join(sorted(kardo_functions)))

print("# functions: ", len(kardo_functions))
Example #7
0
elif scen == 3:

    # punishers don't cooperate and nefarious voters
    f = And(Not(And(p, c)),
            Or(c, ~c, simplify=False),
            Not(And(p, v)),
            simplify=False)

    # punish non-cooperators and non-voters
    poss_prules = [[And(~p, ~c)], [And(~p, ~v)]]
    suffix = '3_nefariousvots'

# find all possible species of individuals
# ---

tt = expr2truthtable(f)  # truth table, each truth is one possible individual

poss_behs = list()  # create a list of possible behaviours
for row in tt.iter_relation():  # for each row in the truth table

    if row[1].is_one():  # if this row is a true in the table

        # point2upoint creates something like (frozenset({1, 3, 5}), frozenset())
        # where the first set is false variables and the second set is true variables
        upoint = point2upoint(row[0])
        vv = [~uniqid2evar[u]
              for u in upoint[0]] + [uniqid2evar[u] for u in upoint[1]]
        poss_behs.append(And(*vv))

# awarder rules
# ---