Example #1
0
File: Synth.cpp Project: 5nizza/sdf
BDD Synth::get_bdd_for_sign_lit(uint lit) {
    /* lit is an AIGER variable index with a 'sign' */

    if (bdd_by_aiger_unlit.find(STRIP_LIT(lit)) != bdd_by_aiger_unlit.end()) {
        BDD res = bdd_by_aiger_unlit[STRIP_LIT(lit)];
        if (IS_NEGATED(lit))
            return ~res;
    }

    uint stripped_lit = STRIP_LIT(lit);
    BDD res;

    if (stripped_lit == 0) {
        res = cudd.bddZero();
    }
    else if (aiger_is_input(aiger_spec, stripped_lit) ||
             aiger_is_latch(aiger_spec, stripped_lit)) {
        res = cudd.ReadVars(cudd_by_aiger[stripped_lit]);
//        MASSERT(res.NodeReadIndex() == stripped_lit/2, "that bug again: impossible: " << res.NodeReadIndex() << " vs " << stripped_lit/2 );
    }
    else { // aiger_and
        aiger_and *and_ = aiger_is_and(aiger_spec, stripped_lit);
        res = get_bdd_for_sign_lit(and_->rhs0) & get_bdd_for_sign_lit(and_->rhs1);
    }

    bdd_by_aiger_unlit[stripped_lit] = res;

    return IS_NEGATED(lit) ? (~res):res;
}
Example #2
0
File: Synth.cpp Project: 5nizza/sdf
void Synth::model_to_aiger(const BDD &c_signal, const BDD &func) {
    /// Update AIGER spec with a definition of `c_signal`

    uint c_lit = aiger_by_cudd[c_signal.NodeReadIndex()];
    string output_name = string(aiger_is_input(aiger_spec, c_lit)->name);  // save the name before it is freed

    uint func_as_aiger_lit = walk(func.getNode());

    aiger_redefine_input_as_and(aiger_spec, c_lit, func_as_aiger_lit, func_as_aiger_lit);

    if (print_full_model)
        aiger_add_output(aiger_spec, c_lit, output_name.c_str());
}
Example #3
0
static const char *
next_symbol (unsigned idx, int slice)
{
  aiger_symbol *input_symbol;
  const char *unsliced_name;
  unsigned len, pos;

  assert (!strip);
  assert (1 <= idx);
  assert (idx <= model->maxvar);
  assert (slice >= 0);

  input_symbol = aiger_is_input (model, 2 * idx);
  assert (input_symbol);
  unsliced_name = input_symbol->name;

  len = unsliced_name ? strlen (unsliced_name) : 20;
  len += 30;

  if (size_buffer < len)
    {
      if (size_buffer)
	{
	  while (size_buffer < len)
	    size_buffer *= 2;

	  buffer = realloc (buffer, size_buffer);
	}
      else
	buffer = malloc (size_buffer = len);
    }

  pos = input_symbol - model->inputs;
  assert (pos < model->num_inputs);

  if (unsliced_name)
    sprintf (buffer, "%d %s %u", slice, unsliced_name, pos);
  else
    sprintf (buffer, "%d %u %u", slice, 2 * idx, pos);

  return buffer;
}
Example #4
0
File: Synth.cpp Project: 5nizza/sdf
hmap<uint,BDD> Synth::extract_output_funcs() {
    /** The result vector respects the order of the controllable variables **/

    L_INF("extract_output_funcs..");

    cudd.FreeTree();    // ordering that worked for win region computation might not work here

    hmap<uint,BDD> model_by_cuddidx;

    vector<BDD> controls = get_controllable_vars_bdds();

    while (!controls.empty()) {
        BDD c = controls.back(); controls.pop_back();

        aiger_symbol *aiger_input = aiger_is_input(aiger_spec, aiger_by_cudd[c.NodeReadIndex()]);
        L_INF("getting output function for " << aiger_input->name);

        BDD c_arena;
        if (controls.size() > 0) {
            BDD cube = cudd.bddComputeCube(controls.data(), NULL, (int)controls.size());
            c_arena = non_det_strategy.ExistAbstract(cube);
        }
        else { //no other signals left
            c_arena = non_det_strategy;
        }
        // Now we have: c_arena(t,u,c) = ∃c_others: nondet(t,u,c)
        // (i.e., c_arena talks about this particular c, about t and u)

        BDD c_can_be_true = c_arena.Cofactor(c);
        BDD c_can_be_false = c_arena.Cofactor(~c);

        BDD c_must_be_true = ~c_can_be_false & c_can_be_true;
        BDD c_must_be_false = c_can_be_false & ~c_can_be_true;
        // Note that we cannot use `c_must_be_true = ~c_can_be_false`,
        // since the negation can cause including tuples (t,i,o) that violate non_det_strategy.

        auto support_indices = cudd.SupportIndices(vector<BDD>({c_must_be_false, c_must_be_true}));
        for (auto const var_cudd_idx : support_indices) {
            auto v = cudd.ReadVars(var_cudd_idx);
            auto new_c_must_be_false = c_must_be_false.ExistAbstract(v);
            auto new_c_must_be_true = c_must_be_true.ExistAbstract(v);

            if ((new_c_must_be_false & new_c_must_be_true) == cudd.bddZero()) {
                c_must_be_false = new_c_must_be_false;
                c_must_be_true = new_c_must_be_true;
            }
        }

        // We use 'restrict' operation, but we could also just do:
        //     c_model = care_set -> must_be_true
        // but this is (presumably) less efficient (in time? in size?).
        // (intuitively, because we always set c_model to 1 if !care_set, but we could set it to 0)
        //
        // The result of restrict operation satisfies:
        //     on c_care_set: c_must_be_true <-> must_be_true.Restrict(c_care_set)

        BDD c_model = c_must_be_true.Restrict(c_must_be_true | c_must_be_false);

        model_by_cuddidx[c.NodeReadIndex()] = c_model;

        //killing node refs
        c_must_be_false = c_must_be_true = c_can_be_false = c_can_be_true = c_arena = cudd.bddZero();

        //TODO: ak: strange -- the python version for the example amba_02_9n produces a smaller circuit (~5-10 times)!
        non_det_strategy = non_det_strategy.Compose(c_model, c.NodeReadIndex());
        //non_det_strategy = non_det_strategy & ((c & c_model) | (~c & ~c_model));
    }

    return model_by_cuddidx;
}