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