Bring signal discipline all the way to the ivl_target API.

Signals may have VMA disciplines attached. Make the attached discipline
visible through the ivl_target.h API. Also, re-arrange the internal
handling of the discipline structure so that we can expose disciplines
through the ivl_target C API without creating new structures. The
t-dll-api implementations of the discipline access functions can look
at the elaborated discipline structure directly. This is possible since
the discipline parse and elaboration are very simple.
This commit is contained in:
Stephen Williams 2008-11-02 08:10:41 -08:00
parent b20019d8b6
commit f4687757f1
21 changed files with 107 additions and 64 deletions

View File

@ -198,13 +198,13 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
}
}
void PWire::set_discipline(discipline_t*d)
void PWire::set_discipline(ivl_discipline_t d)
{
assert(discipline_ == 0);
discipline_ = d;
}
discipline_t* PWire::get_discipline(void) const
ivl_discipline_t PWire::get_discipline(void) const
{
return discipline_;
}

10
PWire.h
View File

@ -18,9 +18,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: PWire.h,v 1.21 2007/05/24 04:07:11 steve Exp $"
#endif
# include "netlist.h"
# include "LineInfo.h"
@ -36,7 +33,6 @@ class ostream;
class PExpr;
class Design;
class discipline_t;
/*
* The different type of PWire::set_range() calls.
@ -82,8 +78,8 @@ class PWire : public LineInfo {
void set_memory_idx(PExpr*ldx, PExpr*rdx);
void set_discipline(discipline_t*);
discipline_t* get_discipline(void) const;
void set_discipline(ivl_discipline_t);
ivl_discipline_t get_discipline(void) const;
map<perm_string,PExpr*> attributes;
@ -115,7 +111,7 @@ class PWire : public LineInfo {
PExpr*lidx_;
PExpr*ridx_;
discipline_t*discipline_;
ivl_discipline_t discipline_;
private: // not implemented
PWire(const PWire&);

View File

@ -189,7 +189,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
break;
}
if (discipline_t*dis = get_discipline())
if (ivl_discipline_t dis = get_discipline())
o << " discipline=" << dis->name();
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";

View File

@ -28,12 +28,12 @@ nature_t::~nature_t()
{
}
discipline_t::discipline_t(perm_string name__, ddomain_t domain__,
nature_t*pot, nature_t*flow__)
ivl_discipline_s::ivl_discipline_s(perm_string name__, ivl_dis_domain_t domain__,
nature_t*pot, nature_t*flow__)
: name_(name__), domain_(domain__), potential_(pot), flow_(flow__)
{
}
discipline_t::~discipline_t()
ivl_discipline_s::~ivl_discipline_s()
{
}

View File

@ -28,10 +28,10 @@
# include "StringHeap.h"
# include <iostream>
# include <map>
# include "ivl_target.h"
# include "LineInfo.h"
typedef enum { DD_NONE, DD_DISCRETE, DD_CONTINUOUS } ddomain_t;
extern std::ostream& operator << (std::ostream&, ddomain_t);
extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
class nature_t : public LineInfo {
public:
@ -47,30 +47,30 @@ class nature_t : public LineInfo {
perm_string access_;
};
class discipline_t : public LineInfo {
class ivl_discipline_s : public LineInfo {
public:
explicit discipline_t (perm_string name, ddomain_t dom,
nature_t*pot, nature_t*flow);
~discipline_t();
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
nature_t*pot, nature_t*flow);
~ivl_discipline_s();
perm_string name() const { return name_; }
ddomain_t domain() const { return domain_; }
ivl_dis_domain_t domain() const { return domain_; }
const nature_t*potential() const { return potential_; }
const nature_t*flow() const { return flow_; }
private:
perm_string name_;
ddomain_t domain_;
ivl_dis_domain_t domain_;
nature_t*potential_;
nature_t*flow_;
private: // not implemented
discipline_t(const discipline_t&);
discipline_t& operator = (const discipline_t&);
ivl_discipline_s(const ivl_discipline_s&);
ivl_discipline_s& operator = (const ivl_discipline_s&);
};
extern map<perm_string,nature_t*> natures;
extern map<perm_string,discipline_t*> disciplines;
extern map<perm_string,ivl_discipline_t> disciplines;
// Map access function name to the nature that it accesses.
extern map<perm_string,nature_t*> access_function_nature;

View File

@ -1241,7 +1241,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope,
NetNet*sig = scope->find_signal(name);
ivl_assert(*this, sig);
discipline_t*dis = sig->get_discipline();
ivl_discipline_t dis = sig->get_discipline();
ivl_assert(*this, dis);
ivl_assert(*this, nature == dis->potential() || nature == dis->flow());

View File

@ -1055,7 +1055,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
sig->set_signed(get_signed());
sig->set_isint(get_isint());
if (discipline_t*dis = get_discipline()) {
if (ivl_discipline_t dis = get_discipline()) {
sig->set_discipline(dis);
}

View File

@ -15,6 +15,9 @@ ivl_const_signed
ivl_const_type
ivl_const_width
ivl_discipline_domain
ivl_discipline_name
ivl_event_any
ivl_event_basename
ivl_event_name
@ -172,6 +175,7 @@ ivl_signal_attr_val
ivl_signal_basename
ivl_signal_data_type
ivl_signal_dimensions
ivl_signal_discipline
ivl_signal_file
ivl_signal_integer
ivl_signal_lineno

View File

@ -151,6 +151,7 @@ _BEGIN_DECL
typedef struct ivl_array_s *ivl_array_t;
typedef struct ivl_delaypath_s*ivl_delaypath_t;
typedef struct ivl_design_s *ivl_design_t;
typedef struct ivl_discipline_s*ivl_discipline_t;
typedef struct ivl_event_s *ivl_event_t;
typedef struct ivl_expr_s *ivl_expr_t;
typedef struct ivl_island_s *ivl_island_t;
@ -159,6 +160,7 @@ typedef struct ivl_lval_s *ivl_lval_t;
typedef struct ivl_net_const_s*ivl_net_const_t;
typedef struct ivl_net_logic_s*ivl_net_logic_t;
typedef struct ivl_udp_s *ivl_udp_t;
typedef struct ivl_nature_s *ivl_nature_t;
typedef struct ivl_net_probe_s*ivl_net_probe_t;
typedef struct ivl_nexus_s *ivl_nexus_t;
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
@ -176,6 +178,12 @@ typedef struct ivl_statement_s*ivl_statement_t;
* changes and additions to the enumerations.
*/
typedef enum ivl_dis_domain_e {
IVL_DIS_NONE = 0,
IVL_DIS_DISCRETE = 1,
IVL_DIS_CONTINUOUS = 2
} ivl_dis_domain_t;
typedef enum ivl_drive_e {
IVL_DR_HiZ = 0,
IVL_DR_SMALL = 1,
@ -543,6 +551,13 @@ extern double ivl_const_real(ivl_net_const_t net);
/* extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx); */
/* extern unsigned ivl_const_pins(ivl_net_const_t net); */
/* DISCIPLINES
*
* Disciplines are a Verilog-AMS construct.
*/
extern const char*ivl_discipline_name(ivl_discipline_t net);
extern ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net);
/* EVENTS
*
* Events are a unification of named events and implicit events
@ -1584,6 +1599,8 @@ extern int ivl_scope_time_units(ivl_scope_t net);
* The signal may be an array (of vectors) in which case this
* function returns >0, the number of dimensions of the array.
*
* ivl_signal_discipline
*
* ivl_signal_msb
* ivl_signal_lsb
* ivl_signal_width
@ -1651,6 +1668,7 @@ extern ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word);
extern int ivl_signal_array_base(ivl_signal_t net);
extern unsigned ivl_signal_array_count(ivl_signal_t net);
extern unsigned ivl_signal_dimensions(ivl_signal_t net);
extern ivl_discipline_t ivl_signal_discipline(ivl_signal_t net);
extern int ivl_signal_msb(ivl_signal_t net);
extern int ivl_signal_lsb(ivl_signal_t net);
extern unsigned ivl_signal_width(ivl_signal_t net);

View File

@ -247,7 +247,7 @@ S [afpnumkKMGT]
value instead. */
if (rc == IDENTIFIER && gn_verilog_ams_flag) {
perm_string tmp = lex_strings.make(yylval.text);
map<perm_string,discipline_t*>::iterator cur = disciplines.find(tmp);
map<perm_string,ivl_discipline_t>::iterator cur = disciplines.find(tmp);
if (cur != disciplines.end()) {
yylval.discipline = (*cur).second;
rc = DISCIPLINE_IDENTIFIER;

View File

@ -705,7 +705,7 @@ int main(int argc, char*argv[])
pform_dump(out, (*cur).second);
}
out << "PFORM DUMP DISCIPLINES:" << endl;
for (map<perm_string,discipline_t*>::iterator cur = disciplines.begin()
for (map<perm_string,ivl_discipline_t>::iterator cur = disciplines.begin()
; cur != disciplines.end() ; cur ++ ) {
pform_dump(out, (*cur).second);
}

View File

@ -242,7 +242,7 @@ NetNode::~NetNode()
design_->del_node(this);
}
NetBranch::NetBranch(discipline_t*dis)
NetBranch::NetBranch(ivl_discipline_t dis)
: NetPins(2), discipline_(dis)
{
pin(0).set_dir(Link::PASSIVE);
@ -647,12 +647,12 @@ void NetNet::set_isint(bool flag)
isint_ = flag;
}
discipline_t* NetNet::get_discipline() const
ivl_discipline_t NetNet::get_discipline() const
{
return discipline_;
}
void NetNet::set_discipline(discipline_t*dis)
void NetNet::set_discipline(ivl_discipline_t dis)
{
ivl_assert(*this, discipline_ == 0);
discipline_ = dis;

View File

@ -69,7 +69,6 @@ class NetEvTrig;
class NetEvWait;
class nature_t;
class discipline_t;
struct target;
struct functor_t;
@ -173,12 +172,12 @@ class IslandBranch {
class NetBranch : public NetPins {
public:
explicit NetBranch(discipline_t*dis);
explicit NetBranch(discipline_t*dis, perm_string name);
explicit NetBranch(ivl_discipline_t dis);
explicit NetBranch(ivl_discipline_t dis, perm_string name);
~NetBranch();
private:
discipline_t*discipline_;
ivl_discipline_t discipline_;
perm_string name_;
};
@ -555,8 +554,8 @@ class NetNet : public NetObj {
void set_isint(bool);
/* Attach a discipline to the net. */
discipline_t* get_discipline() const;
void set_discipline(discipline_t*dis);
ivl_discipline_t get_discipline() const;
void set_discipline(ivl_discipline_t dis);
/* These methods return the msb and lsb indices for the most
significant and least significant bits. These are signed
@ -620,7 +619,7 @@ class NetNet : public NetObj {
ivl_variable_type_t data_type_;
bool signed_;
bool isint_; // original type of integer
discipline_t*discipline_;
ivl_discipline_t discipline_;
long msb_, lsb_;
const unsigned dimensions_;

View File

@ -142,7 +142,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
list<perm_string>*perm_strings;
pform_name_t*pform_name;
discipline_t*discipline;
ivl_discipline_t discipline;
hname_t*hier;
@ -704,9 +704,9 @@ discipline_items
discipline_item
: K_domain K_discrete ';'
{ pform_discipline_domain(@1, DD_DISCRETE); }
{ pform_discipline_domain(@1, IVL_DIS_DISCRETE); }
| K_domain K_continuous ';'
{ pform_discipline_domain(@1, DD_CONTINUOUS); }
{ pform_discipline_domain(@1, IVL_DIS_CONTINUOUS); }
| K_potential IDENTIFIER ';'
{ pform_discipline_potential(@1, $2); delete[] $2; }
| K_flow IDENTIFIER ';'

View File

@ -373,7 +373,6 @@ extern void pform_error_nested_modules();
* Functions for handling the parse of natures and disciplines. These
* functions are in pform_disciplines.cc
*/
class discipline_t;
extern void pform_start_nature(const char*name);
extern void pform_end_nature(const struct vlltype&loc);
@ -383,15 +382,15 @@ extern void pform_nature_access(const struct vlltype&loc, const char*name);
extern void pform_start_discipline(const char*name);
extern void pform_end_discipline(const struct vlltype&loc);
extern void pform_discipline_domain(const struct vlltype&loc, ddomain_t use_domain);
extern void pform_discipline_domain(const struct vlltype&loc, ivl_dis_domain_t use_domain);
extern void pform_discipline_potential(const struct vlltype&loc, const char*name);
extern void pform_discipline_flow(const struct vlltype&loc, const char*name);
extern void pform_attach_discipline(const struct vlltype&loc,
discipline_t*discipline, list<perm_string>*names);
ivl_discipline_t discipline, list<perm_string>*names);
extern void pform_dump(ostream&out, const nature_t*);
extern void pform_dump(ostream&out, const discipline_t*);
extern void pform_dump(ostream&out, const ivl_discipline_s*);
/* ** pform_analog.cc
*/

View File

@ -24,7 +24,7 @@
# include "discipline.h"
map<perm_string,nature_t*> natures;
map<perm_string,discipline_t*> disciplines;
map<perm_string,ivl_discipline_t> disciplines;
map<perm_string,nature_t*> access_function_nature;
static perm_string nature_name = perm_string::perm_string();
@ -88,21 +88,21 @@ void pform_end_nature(const struct vlltype&loc)
static perm_string discipline_name;
static ddomain_t discipline_domain = DD_NONE;
static ivl_dis_domain_t discipline_domain = IVL_DIS_NONE;
static nature_t* discipline_potential = 0;
static nature_t* discipline_flow = 0;
void pform_start_discipline(const char*name)
{
discipline_name = lex_strings.make(name);
discipline_domain = DD_NONE;
discipline_domain = IVL_DIS_NONE;
}
void pform_discipline_domain(const struct vlltype&loc, ddomain_t use_domain)
void pform_discipline_domain(const struct vlltype&loc, ivl_dis_domain_t use_domain)
{
assert(use_domain != DD_NONE);
assert(use_domain != IVL_DIS_NONE);
if (discipline_domain != DD_NONE) {
if (discipline_domain != IVL_DIS_NONE) {
cerr << loc.text << ":" << loc.first_line << ": error: "
<< "Too many domain attributes for discipline "
<< discipline_name << "." << endl;
@ -159,18 +159,20 @@ void pform_end_discipline(const struct vlltype&loc)
{
// If the domain is not otherwise specified, then take it to
// be continuous if potential or flow natures are given.
if (discipline_domain == DD_NONE && (discipline_potential||discipline_flow))
discipline_domain = DD_CONTINUOUS;
if (discipline_domain == IVL_DIS_NONE && (discipline_potential||discipline_flow))
discipline_domain = IVL_DIS_CONTINUOUS;
discipline_t*tmp = new discipline_t(discipline_name, discipline_domain,
discipline_potential, discipline_flow);
ivl_discipline_t tmp = new ivl_discipline_s(discipline_name,
discipline_domain,
discipline_potential,
discipline_flow);
disciplines[discipline_name] = tmp;
FILE_NAME(tmp, loc);
/* Clear the static variables for the next item. */
discipline_name = perm_string::perm_string();
discipline_domain = DD_NONE;
discipline_domain = IVL_DIS_NONE;
discipline_potential = 0;
discipline_flow = 0;
}
@ -183,7 +185,7 @@ void pform_end_discipline(const struct vlltype&loc)
* in the current lexical scope.
*/
void pform_attach_discipline(const struct vlltype&loc,
discipline_t*discipline, list<perm_string>*names)
ivl_discipline_t discipline, list<perm_string>*names)
{
for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; cur ++ ) {
@ -197,7 +199,7 @@ void pform_attach_discipline(const struct vlltype&loc,
assert(cur_net);
}
if (discipline_t*tmp = cur_net->get_discipline()) {
if (ivl_discipline_t tmp = cur_net->get_discipline()) {
cerr << loc.text << ":" << loc.first_line << ": error: "
<< "discipline " << discipline->name()
<< " cannot override existing discipline " << tmp->name()

View File

@ -148,16 +148,16 @@ std::ostream& operator << (std::ostream&out, ivl_process_type_t pt)
return out;
}
std::ostream& operator << (std::ostream&out, ddomain_t dom)
std::ostream& operator << (std::ostream&out, ivl_dis_domain_t dom)
{
switch (dom) {
case DD_NONE:
case IVL_DIS_NONE:
out << "no-domain";
break;
case DD_DISCRETE:
case IVL_DIS_DISCRETE:
out << "discrete";
break;
case DD_CONTINUOUS:
case IVL_DIS_CONTINUOUS:
out << "continuous";
break;
default:
@ -1300,7 +1300,7 @@ void pform_dump(std::ostream&out, const nature_t*nat)
out << "endnature" << endl;
}
void pform_dump(std::ostream&out, const discipline_t*dis)
void pform_dump(std::ostream&out, const ivl_discipline_s*dis)
{
out << "discipline " << dis->name() << endl;
out << " domain " << dis->domain() << ";" << endl;

View File

@ -20,6 +20,7 @@
# include "config.h"
# include "StringHeap.h"
# include "t-dll.h"
# include "discipline.h"
# include <stdlib.h>
# include <string.h>
#ifdef HAVE_MALLOC_H
@ -81,6 +82,16 @@ extern "C" ivl_net_const_t ivl_design_const(ivl_design_t des, unsigned idx)
return des->consts[idx];
}
extern "C" ivl_dis_domain_t ivl_discipline_domain(ivl_discipline_t net)
{
return net->domain();
}
extern "C" const char* ivl_discipline_name(ivl_discipline_t net)
{
return net->name();
}
extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net)
{
if (net == 0)
@ -1729,6 +1740,11 @@ extern "C" unsigned ivl_signal_dimensions(ivl_signal_t net)
return net->array_dimensions_;
}
extern "C" ivl_discipline_t ivl_signal_discipline(ivl_signal_t net)
{
return net->discipline;
}
extern "C" const char* ivl_signal_attr(ivl_signal_t net, const char*key)
{
if (net->nattr == 0)

View File

@ -2410,6 +2410,7 @@ void dll_target::signal(const NetNet*net)
obj->lsb_dist = net->msb() >= net->lsb() ? 1 : -1;
obj->isint_ = false;
obj->local_ = net->local_flag()? 1 : 0;
obj->discipline = net->get_discipline();
obj->array_dimensions_ = net->array_dimensions();

View File

@ -623,6 +623,7 @@ struct ivl_signal_s {
ivl_signal_type_t type_;
ivl_signal_port_t port_;
ivl_variable_type_t data_type;
ivl_discipline_t discipline;
perm_string file;
unsigned lineno;

View File

@ -1238,17 +1238,24 @@ static void show_signal(ivl_signal_t net)
break;
}
const char*discipline_txt = "NONE";
if (ivl_signal_discipline(net)) {
ivl_discipline_t dis = ivl_signal_discipline(net);
discipline_txt = ivl_discipline_name(dis);
}
for (idx = 0 ; idx < ivl_signal_array_count(net) ; idx += 1) {
nex = ivl_signal_nex(net, idx);
fprintf(out, " %s %s %s%s[%d:%d] %s[word=%u, adr=%d] <width=%u%s> nexus=%s\n",
fprintf(out, " %s %s %s%s[%d:%d] %s[word=%u, adr=%d] <width=%u%s> <discipline=%s> nexus=%s\n",
type, sign, port, data_type,
ivl_signal_msb(net), ivl_signal_lsb(net),
ivl_signal_basename(net),
idx, ivl_signal_array_base(net)+idx,
ivl_signal_width(net),
ivl_signal_local(net)? ", local":"",
discipline_txt,
ivl_nexus_name(nex));
show_nexus_details(net, nex);