mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-28 16:53:45 +02:00
More UDP consolidation from Stephan Boettcher.
This commit is contained in:
+50
-152
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001 Stephan Boettcher <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,128 +18,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_udp.cc,v 1.3 2000/12/15 01:24:17 steve Exp $"
|
||||
#ident "$Id: net_udp.cc,v 1.4 2001/04/22 23:09:46 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
bool NetUDP::set_table(const string&input, char output)
|
||||
{
|
||||
assert((output == '0') || (output == '1')
|
||||
|| (is_sequential() && (output == '-')));
|
||||
|
||||
cm_[input] = output;
|
||||
|
||||
if (is_sequential()) {
|
||||
assert(input.length() == pin_count());
|
||||
/* XXXX Need to check to make sure that the input vector
|
||||
contains a legal combination of characters. */
|
||||
return sequ_glob_(input, output);
|
||||
|
||||
} else {
|
||||
assert(input.length() == (pin_count()-1));
|
||||
/* XXXX Need to check to make sure that the input vector
|
||||
contains a legal combination of characters. In
|
||||
combinational UDPs, only 0, 1, x, and ? are allowed. */
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NetUDP::cleanup_table()
|
||||
{
|
||||
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; idx++) {
|
||||
string str = (*idx).first;
|
||||
state_t_*st = (*idx).second;
|
||||
assert(str[0] == st->out);
|
||||
|
||||
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
|
||||
if (st->pins[pin].zer && st->pins[pin].zer->out == 'x')
|
||||
st->pins[pin].zer = 0;
|
||||
if (st->pins[pin].one && st->pins[pin].one->out == 'x')
|
||||
st->pins[pin].one = 0;
|
||||
if (st->pins[pin].xxx && st->pins[pin].xxx->out == 'x')
|
||||
st->pins[pin].xxx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; ) {
|
||||
FSM_::iterator cur = idx;
|
||||
idx ++;
|
||||
|
||||
state_t_*st = (*cur).second;
|
||||
|
||||
if (st->out != 'x')
|
||||
continue;
|
||||
|
||||
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
|
||||
if (st->pins[pin].zer)
|
||||
goto break_label;
|
||||
if (st->pins[pin].one)
|
||||
goto break_label;
|
||||
if (st->pins[pin].xxx)
|
||||
goto break_label;
|
||||
}
|
||||
|
||||
//delete st;
|
||||
fsm_.erase(cur);
|
||||
|
||||
break_label:;
|
||||
}
|
||||
}
|
||||
|
||||
char NetUDP::table_lookup(const string&from, char to, unsigned pin) const
|
||||
{
|
||||
assert(pin <= pin_count());
|
||||
assert(from.length() == pin_count());
|
||||
FSM_::const_iterator idx = fsm_.find(from);
|
||||
if (idx == fsm_.end())
|
||||
return 'x';
|
||||
|
||||
state_t_*next;
|
||||
switch (to) {
|
||||
case '0':
|
||||
next = (*idx).second->pins[pin].zer;
|
||||
break;
|
||||
case '1':
|
||||
next = (*idx).second->pins[pin].one;
|
||||
break;
|
||||
case 'x':
|
||||
next = (*idx).second->pins[pin].xxx;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
next = 0;
|
||||
}
|
||||
|
||||
return next? next->out : 'x';
|
||||
}
|
||||
|
||||
void NetUDP::set_initial(char val)
|
||||
{
|
||||
assert(is_sequential());
|
||||
assert((val == '0') || (val == '1') || (val == 'x'));
|
||||
init_ = val;
|
||||
}
|
||||
|
||||
NetUDP::state_t_* NetUDP::find_state_(const string&str)
|
||||
{
|
||||
map<string,state_t_*>::iterator cur = fsm_.find(str);
|
||||
if (cur != fsm_.end())
|
||||
return (*cur).second;
|
||||
|
||||
state_t_*st = fsm_[str];
|
||||
if (st == 0) {
|
||||
st = new state_t_(pin_count());
|
||||
st->out = str[0];
|
||||
fsm_[str] = st;
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins, bool sequ)
|
||||
: NetNode(n, pins), sequential_(sequ)
|
||||
NetUDP::NetUDP(const string&n, unsigned pins, PUdp *u)
|
||||
: NetNode(n, pins), udp(u)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name("O", 0);
|
||||
@@ -148,52 +34,64 @@ NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins, bool sequ)
|
||||
}
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::set_table(const string&input, char output)
|
||||
bool NetUDP::first(string&inp, char&out) const
|
||||
{
|
||||
if ((output != '0') && (output != '1') && (output != 'x'))
|
||||
return false;
|
||||
table_idx = (unsigned) -1;
|
||||
return next(inp, out);
|
||||
}
|
||||
|
||||
bool NetUDP::next(string&inp, char&out) const
|
||||
{
|
||||
table_idx++;
|
||||
|
||||
assert((output == '0') || (output == '1') || (output == 'x'));
|
||||
assert(input.length() == (pin_count()-1));
|
||||
if (table_idx >= udp->tinput.count())
|
||||
return false;
|
||||
|
||||
/* XXXX Need to check to make sure that the input vector
|
||||
contains a legal combination of characters. In
|
||||
combinational UDPs, only 0, 1, x, and ? are allowed. */
|
||||
cm_[input] = output;
|
||||
if (is_sequential())
|
||||
{
|
||||
inp = string("") + udp->tcurrent[table_idx] + udp->tinput[table_idx];
|
||||
assert(inp.length() == pin_count());
|
||||
}
|
||||
else
|
||||
{
|
||||
inp = udp->tinput[table_idx];
|
||||
assert(inp.length() == (pin_count()-1));
|
||||
}
|
||||
|
||||
return true;
|
||||
out = udp->toutput[table_idx];
|
||||
assert( (out == '0')
|
||||
|| (out == '1')
|
||||
|| (out == 'x')
|
||||
|| (is_sequential() && (out == '-')));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetUDP_COMB::cleanup_table()
|
||||
char NetUDP::get_initial() const
|
||||
{
|
||||
assert (is_sequential());
|
||||
|
||||
switch (udp->initial)
|
||||
{
|
||||
case verinum::V0:
|
||||
return '0';
|
||||
case verinum::V1:
|
||||
return '1';
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
return 'x';
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 'x';
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::first(string&inp, char&out) const
|
||||
{
|
||||
idx_ = cm_.begin();
|
||||
if (idx_ == cm_.end())
|
||||
return false;
|
||||
|
||||
inp = (*idx_).first;
|
||||
out = (*idx_).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::next(string&inp, char&out) const
|
||||
{
|
||||
idx_ ++;
|
||||
if (idx_ == cm_.end())
|
||||
return false;
|
||||
|
||||
inp = (*idx_).first;
|
||||
out = (*idx_).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_udp.cc,v $
|
||||
* Revision 1.4 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.3 2000/12/15 01:24:17 steve
|
||||
* Accept x in outputs of primitive. (PR#84)
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user