Enhanced support for asynchronous set/reset in synthesis.
Added the ability to coalesce set/reset values to different parts of the same vector. Also added a check that all bits of the vector are assigned a value. Enabled coalescence of asynchronous set/reset part-vectors
This commit is contained in:
parent
3fc0204b99
commit
f29935d8dd
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2015 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -102,6 +102,17 @@ bool Nexus::drivers_constant() const
|
|||
break;
|
||||
}
|
||||
|
||||
const NetSubstitute*ps = dynamic_cast<const NetSubstitute*>(cur->get_obj());
|
||||
if (ps) {
|
||||
if (ps->pin(1).nexus()->drivers_constant() &&
|
||||
ps->pin(2).nexus()->drivers_constant() ) {
|
||||
constant_drivers += 1;
|
||||
continue;
|
||||
}
|
||||
driven_ = VAR;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! dynamic_cast<const NetConst*>(cur->get_obj())) {
|
||||
driven_ = VAR;
|
||||
return false;
|
||||
|
|
@ -199,10 +210,12 @@ verinum Nexus::driven_vector() const
|
|||
const Link*cur = list_;
|
||||
|
||||
verinum val;
|
||||
verinum pval;
|
||||
unsigned width = 0;
|
||||
|
||||
for (cur = first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
|
||||
const NetSubstitute*ps;
|
||||
const NetConst*obj;
|
||||
const NetNet*sig;
|
||||
if ((obj = dynamic_cast<const NetConst*>(cur->get_obj()))) {
|
||||
|
|
@ -212,6 +225,18 @@ verinum Nexus::driven_vector() const
|
|||
val = obj->value();
|
||||
width = val.len();
|
||||
|
||||
} else if ((ps = dynamic_cast<const NetSubstitute*>(cur->get_obj()))) {
|
||||
if (cur->get_pin() != 0)
|
||||
continue;
|
||||
|
||||
// Multiple drivers are not currently supported.
|
||||
ivl_assert(*ps, val.len() == 0);
|
||||
val = ps->pin(1).nexus()->driven_vector();
|
||||
pval = ps->pin(2).nexus()->driven_vector();
|
||||
for (unsigned idx = 0; idx < pval.len(); idx += 1)
|
||||
val.set(ps->base() + idx, pval.get(idx));
|
||||
width = val.len();
|
||||
|
||||
} else if ((sig = dynamic_cast<const NetNet*>(cur->get_obj()))) {
|
||||
|
||||
width = sig->vector_width();
|
||||
|
|
|
|||
33
synth2.cc
33
synth2.cc
|
|
@ -413,22 +413,26 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
|||
tmp->local_flag(true);
|
||||
tmp->set_line(*this);
|
||||
|
||||
NetNet*use_lsig = nex_out.pin(ptr).nexus()->pick_any_net();
|
||||
if (use_lsig) {
|
||||
NetNet*isig = nex_out.pin(ptr).nexus()->pick_any_net();
|
||||
if (isig) {
|
||||
if (debug_synth2) {
|
||||
cerr << get_fileline() << ": NetAssignBase::synth_async: "
|
||||
<< " Found a use_sig:" << endl;
|
||||
<< " Found an isig:" << endl;
|
||||
nex_out.pin(ptr).dump_link(cerr, 8);
|
||||
}
|
||||
} else {
|
||||
if (debug_synth2) {
|
||||
cerr << get_fileline() << ": NetAssignBase::synth_async: "
|
||||
<< " Found no use_sig, resorting to lsig." << endl;
|
||||
<< " Found no isig, resorting to lsig." << endl;
|
||||
}
|
||||
use_lsig = lsig;
|
||||
isig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, NetNet::not_an_array, tmp_type);
|
||||
isig->local_flag(true);
|
||||
isig->set_line(*this);
|
||||
connect(isig->pin(0), nex_out.pin(ptr));
|
||||
}
|
||||
ivl_assert(*this, use_lsig);
|
||||
NetSubstitute*ps = new NetSubstitute(use_lsig, rsig, lsig_width, base_off);
|
||||
ivl_assert(*this, isig);
|
||||
NetSubstitute*ps = new NetSubstitute(isig, rsig, lsig_width, base_off);
|
||||
ps->set_line(*this);
|
||||
des->add_node(ps);
|
||||
|
||||
|
|
@ -1766,10 +1770,19 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
|
|||
for (unsigned pin = 0 ; pin < tmp_out.pin_count() ; pin += 1) {
|
||||
Nexus*rst_nex = tmp_out.pin(pin).nexus();
|
||||
|
||||
if (!all_bits_driven(tmp_masks[pin])) {
|
||||
cerr << get_fileline() << ": sorry: Not all bits of '"
|
||||
<< nex_map[idx].lnk.nexus()->pick_any_net()->name()
|
||||
<< "' are asynchronously set or reset. This is "
|
||||
<< "not currently supported in synthesis." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! rst_nex->drivers_constant() ||
|
||||
! tmp_ena.pin(pin).is_linked(scope->tie_hi()) ) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "Asynchronous LOAD not implemented." << endl;
|
||||
cerr << get_fileline() << ": sorry: Asynchronous load "
|
||||
<< "is not currently supported in synthesis." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1777,7 +1790,7 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
|
|||
if (ff_aclr.pin(pin).is_linked() ||
|
||||
ff_aset.pin(pin).is_linked()) {
|
||||
cerr << get_fileline() << ": sorry: More than "
|
||||
"one asynchronous set/reset signal is "
|
||||
"one asynchronous set/reset clause is "
|
||||
"not currently supported in synthesis." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue