Permalink
Browse files

Pass some module port information and fix a few bugs.

This patch adds some preliminary module port information to the ivl
interface. This may change as I investigate exactly what is needed.
It also fixes a few minor bugs (a missed local variable and spacing)
  • Loading branch information...
1 parent 7b82bd2 commit 1e3af453357eea62e322d57e7899b5092c5f37bf @caryr caryr committed with Mar 7, 2011
Showing with 96 additions and 16 deletions.
  1. +6 −1 elab_net.cc
  2. +1 −0 emit.cc
  3. +1 −0 ivl.def
  4. +1 −0 ivl_target.h
  5. +20 −1 net_scope.cc
  6. +6 −0 netlist.h
  7. +11 −2 t-dll-api.cc
  8. +5 −5 t-dll-proc.cc
  9. +28 −3 t-dll.cc
  10. +6 −1 t-dll.h
  11. +5 −1 target.cc
  12. +5 −1 target.h
  13. +1 −1 vvp/parse.y
View
@@ -638,6 +638,7 @@ NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
*/
NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
{
+ assert(scope->type() == NetScope::MODULE);
NetNet*sig = des->find_signal(scope, path_);
if (sig == 0) {
cerr << get_fileline() << ": error: no wire/reg " << path_
@@ -690,8 +691,10 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
/* If this is a part select of the entire signal (or no part
select at all) then we're done. */
- if ((lidx == 0) && (midx == (long)sig->vector_width()-1))
+ if ((lidx == 0) && (midx == (long)sig->vector_width()-1)) {
+ scope->add_module_port(sig);
return sig;
+ }
unsigned swid = abs(midx - lidx) + 1;
ivl_assert(*this, swid > 0 && swid < sig->vector_width());
@@ -701,6 +704,7 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
tmp->port_type(sig->port_type());
tmp->data_type(sig->data_type());
tmp->set_line(*this);
+ tmp->local_flag(true);
NetNode*ps = 0;
switch (sig->port_type()) {
@@ -732,5 +736,6 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
ps->set_line(*this);
des->add_node(ps);
+ scope->add_module_port(sig);
return sig;
}
View
@@ -409,6 +409,7 @@ void NetScope::emit_scope(struct target_t*tgt) const
tgt->signal_paths(cur->second);
}
+ if (type_ == MODULE) tgt->convert_module_ports(this);
}
bool NetScope::emit_defs(struct target_t*tgt) const
View
@@ -189,6 +189,7 @@ ivl_scope_logs
ivl_scope_log
ivl_scope_lpms
ivl_scope_lpm
+ivl_scope_mod_port
ivl_scope_name
ivl_scope_param
ivl_scope_params
View
@@ -1712,6 +1712,7 @@ extern ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx);
extern ivl_scope_t ivl_scope_parent(ivl_scope_t net);
extern unsigned ivl_scope_ports(ivl_scope_t net);
extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx);
+extern ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_sigs(ivl_scope_t net);
extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx);
extern unsigned ivl_scope_switches(ivl_scope_t net);
View
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2010 Stephen Williams (steve@icarus.com)
+ * Copyright (c) 2000-2011 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
@@ -359,6 +359,25 @@ perm_string NetScope::module_name() const
return module_name_;
}
+void NetScope::add_module_port(NetNet*port)
+{
+ assert(type_ == MODULE);
+ ports_.push_back(port);
+}
+
+unsigned NetScope::module_ports() const
+{
+ assert(type_ == MODULE);
+ return ports_.size();
+}
+
+NetNet* NetScope::module_port(unsigned idx) const
+{
+ assert(type_ == MODULE);
+ assert(idx < ports_.size());
+ return ports_[idx];
+}
+
void NetScope::time_unit(int val)
{
time_unit_ = val;
View
@@ -804,6 +804,11 @@ class NetScope : public Attrib {
/* If the scope represents a module instance, the module_name
is the name of the module itself. */
perm_string module_name() const;
+ /* If the scope is a module then it may have ports that we need
+ * to keep track of. */
+ void add_module_port(NetNet*port);
+ unsigned module_ports() const;
+ NetNet*module_port(unsigned idx) const;
/* Scopes have their own time units and time precision. The
unit and precision are given as power of 10, i.e., -3 is
@@ -944,6 +949,7 @@ class NetScope : public Attrib {
typedef std::map<perm_string,NetNet*>::const_iterator signals_map_iter_t;
std::map <perm_string,NetNet*> signals_map_;
perm_string module_name_;
+ vector<NetNet*>ports_;
union {
NetTaskDef*task_;
NetFuncDef*func_;
View
@@ -1928,7 +1928,8 @@ extern "C" ivl_scope_t ivl_scope_parent(ivl_scope_t net)
extern "C" unsigned ivl_scope_ports(ivl_scope_t net)
{
assert(net);
- if (net->type_ == IVL_SCT_FUNCTION ||
+ if (net->type_ == IVL_SCT_MODULE ||
+ net->type_ == IVL_SCT_FUNCTION ||
net->type_ == IVL_SCT_TASK) return net->ports;
return 0;
}
@@ -1939,7 +1940,15 @@ extern "C" ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx)
assert(net->type_ == IVL_SCT_FUNCTION ||
net->type_ == IVL_SCT_TASK);
assert(idx < net->ports);
- return net->port[idx];
+ return net->u_.port[idx];
+}
+
+extern "C" ivl_nexus_t ivl_scope_mod_port(ivl_scope_t net, unsigned idx)
+{
+ assert(net);
+ assert(net->type_ == IVL_SCT_MODULE);
+ assert(idx < net->ports);
+ return net->u_.nex[idx];
}
extern "C" unsigned ivl_scope_sigs(ivl_scope_t net)
View
@@ -88,9 +88,9 @@ void dll_target::task_def(const NetScope*net)
scop->ports = def->port_count();
if (scop->ports > 0) {
- scop->port = new ivl_signal_t[scop->ports];
+ scop->u_.port = new ivl_signal_t[scop->ports];
for (unsigned idx = 0 ; idx < scop->ports ; idx += 1)
- scop->port[idx] = find_signal(des_, def->port(idx));
+ scop->u_.port[idx] = find_signal(des_, def->port(idx));
}
}
@@ -110,9 +110,9 @@ bool dll_target::func_def(const NetScope*net)
scop->ports = def->port_count() + 1;
if (scop->ports > 0) {
- scop->port = new ivl_signal_t[scop->ports];
+ scop->u_.port = new ivl_signal_t[scop->ports];
for (unsigned idx = 1 ; idx < scop->ports ; idx += 1)
- scop->port[idx] = find_signal(des_, def->port(idx-1));
+ scop->u_.port[idx] = find_signal(des_, def->port(idx-1));
}
/* FIXME: the ivl_target API expects port-0 to be the output
@@ -121,7 +121,7 @@ bool dll_target::func_def(const NetScope*net)
this, but that will break code generators that use this
result. */
if (const NetNet*ret_sig = def->return_sig()) {
- scop->port[0] = find_signal(des_, ret_sig);
+ scop->u_.port[0] = find_signal(des_, ret_sig);
return true;
}
View
@@ -563,6 +563,13 @@ void dll_target::add_root(ivl_design_s &des__, const NetScope *s)
root_->attr = fill_in_attributes(s);
root_->is_auto = 0;
root_->is_cell = s->is_cell();
+ root_->ports = s->module_ports();
+ if (root_->ports > 0) {
+ root_->u_.net = new NetNet*[root_->ports];
+ for (unsigned idx = 0; idx < root_->ports; idx += 1) {
+ root_->u_.net[idx] = s->module_port(idx);
+ }
+ }
des__.nroots_++;
if (des__.roots_)
@@ -2273,6 +2280,7 @@ void dll_target::scope(const NetScope*net)
FILE_NAME(scop, net);
scop->parent = find_scope(des_, net->parent());
assert(scop->parent);
+ scop->parent->children[net->fullname()] = scop;
scop->nsigs_ = 0;
scop->sigs_ = 0;
scop->nlog_ = 0;
@@ -2294,6 +2302,13 @@ void dll_target::scope(const NetScope*net)
case NetScope::MODULE:
scop->type_ = IVL_SCT_MODULE;
scop->tname_ = net->module_name();
+ scop->ports = net->module_ports();
+ if (scop->ports > 0) {
+ scop->u_.net = new NetNet*[scop->ports];
+ for (unsigned idx = 0; idx < scop->ports; idx += 1) {
+ scop->u_.net[idx] = net->module_port(idx);
+ }
+ }
break;
case NetScope::TASK: {
const NetTaskDef*def = net->task_def();
@@ -2324,10 +2339,20 @@ void dll_target::scope(const NetScope*net)
scop->tname_ = scop->name_;
break;
}
+ }
+}
- assert(scop->parent != 0);
-
- scop->parent->children[net->fullname()] = scop;
+void dll_target::convert_module_ports(const NetScope*net)
+{
+ ivl_scope_t scop = find_scope(des_, net);
+ if (scop->ports > 0) {
+ NetNet**nets = scop->u_.net;
+ scop->u_.nex = new ivl_nexus_t[scop->ports];
+ for (unsigned idx = 0; idx < scop->ports; idx += 1) {
+ ivl_signal_t sig = find_signal(des_, nets[idx]);
+ scop->u_.nex[idx] = nexus_sig_make(sig, 0);
+ }
+ delete nets;
}
}
View
@@ -93,6 +93,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool process(const NetProcTop*);
bool process(const NetAnalogTop*);
void scope(const NetScope*);
+ void convert_module_ports(const NetScope*);
void signal(const NetNet*);
bool signal_paths(const NetNet*);
ivl_dll_t dll_;
@@ -646,7 +647,11 @@ struct ivl_scope_s {
unsigned is_cell;
unsigned ports;
- ivl_signal_t*port;
+ union {
+ ivl_signal_t*port;
+ ivl_nexus_t*nex;
+ NetNet**net;
+ } u_;
std::vector<ivl_switch_t>switches;
View
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2010 Stephen Williams <steve@icarus.com>
+ * Copyright (c) 1998-2011 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
@@ -32,6 +32,10 @@ void target_t::scope(const NetScope*)
{
}
+void target_t::convert_module_ports(const NetScope*)
+{
+}
+
bool target_t::branch(const NetBranch*obj)
{
cerr << obj->get_fileline() << ": error: target (" << typeid(*this).name()
View
@@ -1,7 +1,7 @@
#ifndef __target_H
#define __target_H
/*
- * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
+ * Copyright (c) 1998-2011 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
@@ -56,6 +56,10 @@ struct target_t {
anything else is called. */
virtual void scope(const NetScope*);
+ /* This is called to convert module ports from a NetNet* to an
+ * ivl_signal_t object. */
+ virtual void convert_module_ports(const NetScope*);
+
/* Output an event object. Called for each named event in the scope. */
virtual void event(const NetEvent*);
View
@@ -560,7 +560,7 @@ statement
requirements so are handled by their own rules. */
| label_opt K_file_line T_NUMBER T_NUMBER T_STRING ';'
{ compile_file_line($1, $3, $4, $5); }
-
+
| label_opt K_file_line T_NUMBER T_NUMBER T_NUMBER ';'
{ assert($5 == 0);
compile_file_line($1, $3, $4, 0); }

0 comments on commit 1e3af45

Please sign in to comment.