Merge branch 'x-sizer3'
This commit is contained in:
commit
b1ef0997ed
|
|
@ -4029,7 +4029,7 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
|||
ev, NetEvProbe::ANYEDGE,
|
||||
nset->size());
|
||||
for (unsigned idx = 0 ; idx < nset->size() ; idx += 1)
|
||||
connect(nset->at(idx).nex, pr->pin(idx));
|
||||
connect(nset->at(idx).lnk, pr->pin(idx));
|
||||
|
||||
delete nset;
|
||||
des->add_node(pr);
|
||||
|
|
@ -4303,7 +4303,7 @@ NetProc* PEventStatement::elaborate_wait(Design*des, NetScope*scope,
|
|||
wait_event, NetEvProbe::ANYEDGE,
|
||||
wait_set->size());
|
||||
for (unsigned idx = 0; idx < wait_set->size() ; idx += 1)
|
||||
connect(wait_set->at(idx).nex, wait_pr->pin(idx));
|
||||
connect(wait_set->at(idx).lnk, wait_pr->pin(idx));
|
||||
|
||||
delete wait_set;
|
||||
des->add_node(wait_pr);
|
||||
|
|
|
|||
|
|
@ -1319,7 +1319,7 @@ static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
|
|||
nset->size());
|
||||
pr->set_line(*root);
|
||||
for (unsigned idx = 0 ; idx < nset->size() ; idx += 1)
|
||||
connect(nset->at(idx).nex, pr->pin(idx));
|
||||
connect(nset->at(idx).lnk, pr->pin(idx));
|
||||
|
||||
des->add_node(pr);
|
||||
|
||||
|
|
|
|||
31
net_link.cc
31
net_link.cc
|
|
@ -524,6 +524,8 @@ NexusSet::NexusSet()
|
|||
|
||||
NexusSet::~NexusSet()
|
||||
{
|
||||
for (size_t idx = 0 ; idx < items_.size() ; idx += 1)
|
||||
delete items_[idx];
|
||||
}
|
||||
|
||||
size_t NexusSet::size() const
|
||||
|
|
@ -534,7 +536,7 @@ size_t NexusSet::size() const
|
|||
void NexusSet::add(Nexus*that, unsigned base, unsigned wid)
|
||||
{
|
||||
assert(that);
|
||||
elem_t cur (that, base, wid);
|
||||
elem_t*cur = new elem_t(that, base, wid);
|
||||
|
||||
if (items_.size() == 0) {
|
||||
items_.resize(1);
|
||||
|
|
@ -542,8 +544,9 @@ void NexusSet::add(Nexus*that, unsigned base, unsigned wid)
|
|||
return;
|
||||
}
|
||||
|
||||
unsigned ptr = bsearch_(cur);
|
||||
unsigned ptr = bsearch_(*cur);
|
||||
if (ptr < items_.size()) {
|
||||
delete cur;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -552,26 +555,28 @@ void NexusSet::add(Nexus*that, unsigned base, unsigned wid)
|
|||
items_.push_back(cur);
|
||||
}
|
||||
|
||||
void NexusSet::add(const NexusSet&that)
|
||||
void NexusSet::add(NexusSet&that)
|
||||
{
|
||||
for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1)
|
||||
add(that.items_[idx].nex, that.items_[idx].base, that.items_[idx].wid);
|
||||
add(that.items_[idx]->lnk.nexus(), that.items_[idx]->base, that.items_[idx]->wid);
|
||||
}
|
||||
|
||||
void NexusSet::rem_(const NexusSet::elem_t&that)
|
||||
void NexusSet::rem_(const NexusSet::elem_t*that)
|
||||
{
|
||||
if (items_.empty())
|
||||
return;
|
||||
|
||||
unsigned ptr = bsearch_(that);
|
||||
unsigned ptr = bsearch_(*that);
|
||||
if (ptr >= items_.size())
|
||||
return;
|
||||
|
||||
if (items_.size() == 1) {
|
||||
delete items_[0];
|
||||
items_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
delete items_[ptr];
|
||||
for (unsigned idx = ptr ; idx < (items_.size()-1) ; idx += 1)
|
||||
items_[idx] = items_[idx+1];
|
||||
|
||||
|
|
@ -589,16 +594,16 @@ unsigned NexusSet::find_nexus(const NexusSet::elem_t&that) const
|
|||
return bsearch_(that);
|
||||
}
|
||||
|
||||
const NexusSet::elem_t& NexusSet::at (unsigned idx) const
|
||||
NexusSet::elem_t& NexusSet::at (unsigned idx)
|
||||
{
|
||||
assert(idx < items_.size());
|
||||
return items_[idx];
|
||||
return *items_[idx];
|
||||
}
|
||||
|
||||
size_t NexusSet::bsearch_(const NexusSet::elem_t&that) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
if (items_[idx]==that)
|
||||
if (*items_[idx] == that)
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
|
@ -607,7 +612,7 @@ size_t NexusSet::bsearch_(const NexusSet::elem_t&that) const
|
|||
|
||||
bool NexusSet::elem_t::contains(const struct elem_t&that) const
|
||||
{
|
||||
if (nex != that.nex)
|
||||
if (! lnk.is_linked(that.lnk))
|
||||
return false;
|
||||
if (that.base < base)
|
||||
return false;
|
||||
|
|
@ -620,7 +625,7 @@ bool NexusSet::elem_t::contains(const struct elem_t&that) const
|
|||
bool NexusSet::contains_(const NexusSet::elem_t&that) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
if (items_[idx].contains(that))
|
||||
if (items_[idx]->contains(that))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -629,7 +634,7 @@ bool NexusSet::contains_(const NexusSet::elem_t&that) const
|
|||
bool NexusSet::contains(const NexusSet&that) const
|
||||
{
|
||||
for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1) {
|
||||
if (! contains_(that.items_[idx]))
|
||||
if (! contains_(*that.items_[idx]))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -639,7 +644,7 @@ bool NexusSet::contains(const NexusSet&that) const
|
|||
bool NexusSet::intersect(const NexusSet&that) const
|
||||
{
|
||||
for (size_t idx = 0 ; idx < that.items_.size() ; idx += 1) {
|
||||
size_t where = bsearch_(that.items_[idx]);
|
||||
size_t where = bsearch_(*that.items_[idx]);
|
||||
if (where == items_.size())
|
||||
continue;
|
||||
|
||||
|
|
|
|||
63
netlist.h
63
netlist.h
|
|
@ -96,6 +96,7 @@ class Link {
|
|||
friend void connect(Link&, Link&);
|
||||
friend class NetPins;
|
||||
friend class Nexus;
|
||||
friend class NexusSet;
|
||||
|
||||
public:
|
||||
enum DIR { PASSIVE, INPUT, OUTPUT };
|
||||
|
|
@ -409,17 +410,25 @@ class NexusSet {
|
|||
public:
|
||||
struct elem_t {
|
||||
inline elem_t(Nexus*n, unsigned b, unsigned w)
|
||||
: nex(n), base(b), wid(w)
|
||||
{ }
|
||||
inline elem_t() : nex(0), base(0), wid(0) { }
|
||||
: base(b), wid(w)
|
||||
{
|
||||
lnk.set_dir(Link::PASSIVE);
|
||||
n->connect(lnk);
|
||||
}
|
||||
inline elem_t() : base(0), wid(0)
|
||||
{
|
||||
}
|
||||
inline bool operator == (const struct elem_t&that) const
|
||||
{ return nex==that.nex && base==that.base && wid==that.wid; }
|
||||
{ return lnk.is_linked(that.lnk) && base==that.base && wid==that.wid; }
|
||||
|
||||
bool contains(const struct elem_t&that) const;
|
||||
|
||||
Nexus*nex;
|
||||
Link lnk;
|
||||
unsigned base;
|
||||
unsigned wid;
|
||||
private:
|
||||
elem_t(const elem_t&);
|
||||
elem_t& operator= (elem_t&);
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -430,15 +439,15 @@ class NexusSet {
|
|||
|
||||
// Add the nexus/part to the set, if it is not already present.
|
||||
void add(Nexus*that, unsigned base, unsigned wid);
|
||||
void add(const NexusSet&that);
|
||||
void add(NexusSet&that);
|
||||
|
||||
// Remove the nexus from the set, if it is present.
|
||||
void rem(const NexusSet&that);
|
||||
|
||||
unsigned find_nexus(const elem_t&that) const;
|
||||
|
||||
const elem_t& at(unsigned idx) const;
|
||||
inline const elem_t& operator[] (unsigned idx) const { return at(idx); }
|
||||
elem_t& at(unsigned idx);
|
||||
inline elem_t& operator[] (unsigned idx) { return at(idx); }
|
||||
|
||||
// Return true if this set contains every nexus/part in that
|
||||
// set. That means that every bit of that set is accounted for
|
||||
|
|
@ -450,11 +459,11 @@ class NexusSet {
|
|||
|
||||
private:
|
||||
// NexSet items are canonical part selects of vectors.
|
||||
std::vector<struct elem_t> items_;
|
||||
std::vector<struct elem_t*> items_;
|
||||
|
||||
size_t bsearch_(const struct elem_t&that) const;
|
||||
void rem_(const struct elem_t&that);
|
||||
bool contains_(const elem_t&htat) const;
|
||||
void rem_(const struct elem_t*that);
|
||||
bool contains_(const elem_t&that) const;
|
||||
|
||||
private: // not implemented
|
||||
NexusSet(const NexusSet&);
|
||||
|
|
@ -2493,9 +2502,14 @@ class NetProc : public virtual LineInfo {
|
|||
// process. Most process types are not.
|
||||
virtual bool is_synchronous();
|
||||
|
||||
// Synthesize as asynchronous logic, and return true.
|
||||
// Synthesize as asynchronous logic, and return true. The
|
||||
// nex_out is where this function attaches its output
|
||||
// results. The accumulated_nex_out is used by sequential
|
||||
// blocks to show outputs from the previous code.
|
||||
virtual bool synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out);
|
||||
NexusSet&nex_map,
|
||||
NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out);
|
||||
|
||||
// Synthesize as synchronous logic, and return true. That
|
||||
// means binding the outputs to the data port of a FF, and the
|
||||
|
|
@ -2511,7 +2525,7 @@ class NetProc : public virtual LineInfo {
|
|||
// the flipflop being generated.
|
||||
virtual bool synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clock, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const std::vector<NetEvProbe*>&events);
|
||||
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
|
@ -2695,7 +2709,8 @@ class NetAssignBase : public NetProc {
|
|||
unsigned lwidth() const;
|
||||
|
||||
bool synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out);
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out);
|
||||
|
||||
// This dumps all the lval structures.
|
||||
void dump_lval(ostream&) const;
|
||||
|
|
@ -2780,11 +2795,12 @@ class NetBlock : public NetProc {
|
|||
|
||||
// synthesize as asynchronous logic, and return true.
|
||||
bool synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out);
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out);
|
||||
|
||||
bool synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clk, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const std::vector<NetEvProbe*>&events);
|
||||
|
||||
// This version of emit_recurse scans all the statements of
|
||||
|
|
@ -2837,7 +2853,8 @@ class NetCase : public NetProc {
|
|||
virtual void nex_output(NexusSet&out);
|
||||
|
||||
bool synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out);
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out);
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
|
@ -2912,11 +2929,12 @@ class NetCondit : public NetProc {
|
|||
|
||||
bool is_asynchronous();
|
||||
bool synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out);
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out);
|
||||
|
||||
bool synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clk, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const std::vector<NetEvProbe*>&events);
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
|
|
@ -3187,11 +3205,12 @@ class NetEvWait : public NetProc {
|
|||
virtual void nex_output(NexusSet&out);
|
||||
|
||||
virtual bool synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out);
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out);
|
||||
|
||||
virtual bool synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clk, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const std::vector<NetEvProbe*>&events);
|
||||
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
|
|
|||
130
synth2.cc
130
synth2.cc
|
|
@ -28,14 +28,14 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
bool NetProc::synth_async(Design*, NetScope*, const NexusSet&, NetBus&)
|
||||
bool NetProc::synth_async(Design*, NetScope*, NexusSet&, NetBus&, NetBus&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetProc::synth_sync(Design*des, NetScope*scope,
|
||||
NetNet* /* ff_clk */, NetNet* /* ff_ce */,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const vector<NetEvProbe*>&events)
|
||||
{
|
||||
if (events.size() > 0) {
|
||||
|
|
@ -45,7 +45,8 @@ bool NetProc::synth_sync(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
/* Synthesize the input to the DFF. */
|
||||
return synth_async(des, scope, nex_map, nex_out);
|
||||
NetBus accumulated_nex_out (scope, nex_out.pin_count());
|
||||
return synth_async(des, scope, nex_map, nex_out, accumulated_nex_out);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -60,7 +61,8 @@ bool NetProc::synth_sync(Design*des, NetScope*scope,
|
|||
* r-value.
|
||||
*/
|
||||
bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out)
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&)
|
||||
{
|
||||
NetNet*rsig = rval_->synthesize(des, scope, rval_);
|
||||
assert(rsig);
|
||||
|
|
@ -138,7 +140,8 @@ bool NetAssignBase::synth_async(Design*des, NetScope*scope,
|
|||
* substatements.
|
||||
*/
|
||||
bool NetBlock::synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out)
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out)
|
||||
{
|
||||
if (last_ == 0) {
|
||||
return true;
|
||||
|
|
@ -158,30 +161,48 @@ bool NetBlock::synth_async(Design*des, NetScope*scope,
|
|||
output from the synthesis. */
|
||||
NetBus tmp_out (scope, tmp_map.size());
|
||||
|
||||
bool ok_flag = cur->synth_async(des, scope, tmp_map, tmp_out);
|
||||
// Map (and move) the accumulated_nex_out for this block
|
||||
// to the version that we can pass to the next
|
||||
// statement. We will move the result back later.
|
||||
NetBus accumulated_tmp_out (scope, tmp_map.size());
|
||||
|
||||
for (unsigned idx = 0 ; idx < accumulated_nex_out.pin_count() ; idx += 1) {
|
||||
unsigned ptr = tmp_map.find_nexus(nex_map[idx]);
|
||||
if (ptr >= tmp_map.size())
|
||||
continue;
|
||||
|
||||
connect(accumulated_tmp_out.pin(ptr), accumulated_nex_out.pin(idx));
|
||||
accumulated_nex_out.pin(idx).unlink();
|
||||
}
|
||||
|
||||
bool ok_flag = cur->synth_async(des, scope, tmp_map, tmp_out, accumulated_tmp_out);
|
||||
|
||||
flag = flag && ok_flag;
|
||||
if (ok_flag == false)
|
||||
continue;
|
||||
|
||||
/* Now find the tmp_map pins in the nex_map global map,
|
||||
and use that to direct the connection to the nex_out
|
||||
output bus. Look for the nex_map pin that is linked
|
||||
to the tmp_map.pin(idx) pin, and link that to the
|
||||
tmp_out.pin(idx) output link. */
|
||||
// Now map the output from the substatement back to the
|
||||
// accumulated_nex_out for this block. Look for the
|
||||
// nex_map pin that is linked to the tmp_map.pin(idx)
|
||||
// pin, and link that to the tmp_out.pin(idx) output link.
|
||||
for (unsigned idx = 0 ; idx < tmp_out.pin_count() ; idx += 1) {
|
||||
unsigned ptr = nex_map.find_nexus(tmp_map[idx]);
|
||||
ivl_assert(*this, ptr < nex_out.pin_count());
|
||||
connect(nex_out.pin(ptr), tmp_out.pin(idx));
|
||||
ivl_assert(*this, ptr < accumulated_nex_out.pin_count());
|
||||
connect(accumulated_nex_out.pin(ptr), tmp_out.pin(idx));
|
||||
}
|
||||
|
||||
} while (cur != last_);
|
||||
|
||||
// The output from the block is now the accumulated outputs.
|
||||
for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1)
|
||||
connect(nex_out.pin(idx), accumulated_nex_out.pin(idx));
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool NetCase::synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out)
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&)
|
||||
{
|
||||
/* Synthesize the select expression. */
|
||||
NetNet*esig = expr_->synthesize(des, scope, expr_);
|
||||
|
|
@ -248,7 +269,8 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
|
||||
if (statement_default) {
|
||||
|
||||
statement_default->synth_async(des, scope, nex_map, default_bus);
|
||||
NetBus tmp (scope, nex_out.pin_count());
|
||||
statement_default->synth_async(des, scope, nex_map, default_bus, tmp);
|
||||
|
||||
// Get the signal from the synthesized statement. This
|
||||
// will be hooked to all the default cases.
|
||||
|
|
@ -304,7 +326,8 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
NetBus tmp (scope, nex_map.size());
|
||||
stmt->synth_async(des, scope, nex_map, tmp);
|
||||
NetBus accumulated_tmp (scope, nex_map.size());
|
||||
stmt->synth_async(des, scope, nex_map, tmp, accumulated_tmp);
|
||||
|
||||
ivl_assert(*this, tmp.pin_count() == mux.size());
|
||||
for (size_t mdx = 0 ; mdx < mux.size() ; mdx += 1) {
|
||||
|
|
@ -329,20 +352,34 @@ bool NetCase::synth_async(Design*des, NetScope*scope,
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* A condit statement (if (cond) ... else ... ;) infers an A-B mux,
|
||||
* with the cond expression acting as a select input. If the cond
|
||||
* expression is true, the if_ clause is selected, and if false, the
|
||||
* else_ clause is selected.
|
||||
*/
|
||||
bool NetCondit::synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out)
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out)
|
||||
{
|
||||
if (if_ == 0) {
|
||||
return false;
|
||||
}
|
||||
if (else_ == 0) {
|
||||
cerr << get_fileline() << ": error: Asynchronous if statement"
|
||||
<< " is missing the else clause." << endl;
|
||||
return false;
|
||||
bool latch_flag = false;
|
||||
for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) {
|
||||
if (! accumulated_nex_out.pin(idx).is_linked())
|
||||
latch_flag = true;
|
||||
}
|
||||
if (latch_flag) {
|
||||
cerr << get_fileline() << ": error: Asynchronous if statement"
|
||||
<< " cannot synthesize missing \"else\""
|
||||
<< " without generating latches." << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
assert(if_ != 0);
|
||||
assert(else_ != 0);
|
||||
ivl_assert(*this, if_ != 0);
|
||||
|
||||
// Synthesize the condition. This will act as a select signal
|
||||
// for a binary mux.
|
||||
|
|
@ -351,15 +388,25 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
|
|||
|
||||
bool flag;
|
||||
NetBus asig(scope, nex_out.pin_count());
|
||||
flag = if_->synth_async(des, scope, nex_map, asig);
|
||||
NetBus atmp(scope, nex_out.pin_count());
|
||||
flag = if_->synth_async(des, scope, nex_map, asig, atmp);
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NetBus btmp(scope, nex_out.pin_count());
|
||||
NetBus bsig(scope, nex_out.pin_count());
|
||||
flag = else_->synth_async(des, scope, nex_map, bsig);
|
||||
if (!flag) {
|
||||
return false;
|
||||
|
||||
if (else_==0) {
|
||||
for (unsigned idx = 0 ; idx < nex_out.pin_count() ; idx += 1) {
|
||||
connect(bsig.pin(idx), accumulated_nex_out.pin(idx));
|
||||
accumulated_nex_out.pin(idx).unlink();
|
||||
}
|
||||
} else {
|
||||
flag = else_->synth_async(des, scope, nex_map, bsig, btmp);
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ivl_assert(*this, nex_out.pin_count()==asig.pin_count());
|
||||
|
|
@ -405,9 +452,10 @@ bool NetCondit::synth_async(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
bool NetEvWait::synth_async(Design*des, NetScope*scope,
|
||||
const NexusSet&nex_map, NetBus&nex_out)
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
NetBus&accumulated_nex_out)
|
||||
{
|
||||
bool flag = statement_->synth_async(des, scope, nex_map, nex_out);
|
||||
bool flag = statement_->synth_async(des, scope, nex_map, nex_out, accumulated_nex_out);
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
|
@ -431,11 +479,11 @@ bool NetProcTop::synth_async(Design*des)
|
|||
|
||||
NetBus nex_q (scope(), nex_set.size());
|
||||
for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) {
|
||||
const NexusSet::elem_t&item = nex_set[idx];
|
||||
if (item.base != 0 || item.wid!=item.nex->vector_width()) {
|
||||
NexusSet::elem_t&item = nex_set[idx];
|
||||
if (item.base != 0 || item.wid!=item.lnk.nexus()->vector_width()) {
|
||||
ivl_variable_type_t tmp_data_type = IVL_VT_LOGIC;
|
||||
list<netrange_t>not_an_array;
|
||||
netvector_t*tmp_type = new netvector_t(tmp_data_type, item.nex->vector_width()-1,0);
|
||||
netvector_t*tmp_type = new netvector_t(tmp_data_type, item.lnk.nexus()->vector_width()-1,0);
|
||||
NetNet*tmp_sig = new NetNet(scope(), scope()->local_symbol(),
|
||||
NetNet::WIRE, not_an_array, tmp_type);
|
||||
tmp_sig->local_flag(true);
|
||||
|
|
@ -445,14 +493,15 @@ bool NetProcTop::synth_async(Design*des)
|
|||
des->add_node(tmp);
|
||||
tmp->set_line(*this);
|
||||
connect(tmp->pin(0), nex_q.pin(idx));
|
||||
connect(item.nex, tmp_sig->pin(0));
|
||||
connect(item.lnk, tmp_sig->pin(0));
|
||||
|
||||
} else {
|
||||
connect(item.nex, nex_q.pin(idx));
|
||||
connect(item.lnk, nex_q.pin(idx));
|
||||
}
|
||||
}
|
||||
|
||||
bool flag = statement_->synth_async(des, scope(), nex_set, nex_q);
|
||||
NetBus tmp_q (scope(), nex_set.size());
|
||||
bool flag = statement_->synth_async(des, scope(), nex_set, nex_q, tmp_q);
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
|
@ -472,7 +521,7 @@ bool NetProcTop::synth_async(Design*des)
|
|||
*/
|
||||
bool NetBlock::synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clk, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const vector<NetEvProbe*>&events_in)
|
||||
{
|
||||
bool flag = true;
|
||||
|
|
@ -531,7 +580,7 @@ bool NetBlock::synth_sync(Design*des, NetScope*scope,
|
|||
*/
|
||||
bool NetCondit::synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clk, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const vector<NetEvProbe*>&events_in)
|
||||
{
|
||||
/* First try to turn the condition expression into an
|
||||
|
|
@ -689,7 +738,8 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
|
|||
/* If this is an if/then/else, then it is likely a
|
||||
combinational if, and I should synthesize it that way. */
|
||||
if (if_ && else_) {
|
||||
bool flag = synth_async(des, scope, nex_map, nex_out);
|
||||
NetBus tmp (scope, nex_out.pin_count());
|
||||
bool flag = synth_async(des, scope, nex_map, nex_out, tmp);
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
|
@ -740,7 +790,7 @@ bool NetCondit::synth_sync(Design*des, NetScope*scope,
|
|||
|
||||
bool NetEvWait::synth_sync(Design*des, NetScope*scope,
|
||||
NetNet*ff_clk, NetNet*ff_ce,
|
||||
const NexusSet&nex_map, NetBus&nex_out,
|
||||
NexusSet&nex_map, NetBus&nex_out,
|
||||
const vector<NetEvProbe*>&events_in)
|
||||
{
|
||||
if (events_in.size() > 0) {
|
||||
|
|
@ -853,7 +903,7 @@ bool NetProcTop::synth_sync(Design*des)
|
|||
pass the nex_q as a map to the statement's synth_sync
|
||||
method to map it to the correct nex_d pin. */
|
||||
for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) {
|
||||
connect(nex_set[idx].nex, nex_q.pin(idx));
|
||||
connect(nex_set[idx].lnk, nex_q.pin(idx));
|
||||
}
|
||||
|
||||
// Connect the input later.
|
||||
|
|
@ -869,7 +919,7 @@ bool NetProcTop::synth_sync(Design*des)
|
|||
|
||||
for (unsigned idx = 0 ; idx < nex_set.size() ; idx += 1) {
|
||||
|
||||
ivl_assert(*this, nex_set[idx].nex);
|
||||
//ivl_assert(*this, nex_set[idx].nex);
|
||||
if (debug_synth2) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Top level making a "
|
||||
|
|
|
|||
|
|
@ -46,6 +46,21 @@ static void scans_lpms_add(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&s
|
|||
stats.gate_count += 2*wid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count mux devices as 2m gates.
|
||||
*/
|
||||
static void scan_lpms_mux(ivl_scope_t, ivl_lpm_t lpm, struct sizer_statistics&stats)
|
||||
{
|
||||
// For now, don't generate statistics for wide mux devices.
|
||||
if (ivl_lpm_size(lpm) > 2) {
|
||||
stats.lpm_bytype[ivl_lpm_type(lpm)] += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned wid = ivl_lpm_width(lpm);
|
||||
stats.gate_count += 2*wid;
|
||||
}
|
||||
|
||||
void scan_lpms(ivl_scope_t scope, struct sizer_statistics&stats)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ivl_scope_lpms(scope) ; idx += 1) {
|
||||
|
|
@ -70,6 +85,10 @@ void scan_lpms(ivl_scope_t scope, struct sizer_statistics&stats)
|
|||
scan_lpms_ff(scope, lpm, stats);
|
||||
break;
|
||||
|
||||
case IVL_LPM_MUX:
|
||||
scan_lpms_mux(scope, lpm, stats);
|
||||
break;
|
||||
|
||||
default:
|
||||
stats.lpm_bytype[ivl_lpm_type(lpm)] += 1;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -116,6 +116,15 @@ int target_design(ivl_design_t des)
|
|||
*/
|
||||
static int process_scan_fun(ivl_process_t net, void* /*raw*/)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ivl_process_attr_cnt(net) ; idx += 1) {
|
||||
ivl_attribute_t att = ivl_process_attr_val(net, idx);
|
||||
|
||||
// If synthesis is explicitly turned off for this
|
||||
// process, then we just ignore it.
|
||||
if (strcmp(att->key, "ivl_synthesis_off") == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s:%u: SIZER: Processes not synthesized for statistics.\n",
|
||||
ivl_process_file(net), ivl_process_lineno(net));
|
||||
sizer_errors += 1;
|
||||
|
|
@ -124,6 +133,7 @@ static int process_scan_fun(ivl_process_t net, void* /*raw*/)
|
|||
|
||||
static void emit_sizer_scope(ivl_design_t des, ivl_scope_t scope, struct sizer_statistics&stats)
|
||||
{
|
||||
|
||||
fprintf(sizer_out, "**** module/scope: %s\n", ivl_scope_name(scope));
|
||||
|
||||
scan_logs(scope, stats);
|
||||
|
|
|
|||
Loading…
Reference in New Issue