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)
This commit is contained in:
parent
7b82bd26f5
commit
1e3af45335
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
1
emit.cc
1
emit.cc
|
|
@ -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
|
||||
|
|
|
|||
1
ivl.def
1
ivl.def
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
21
net_scope.cc
21
net_scope.cc
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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_;
|
||||
|
|
|
|||
13
t-dll-api.cc
13
t-dll-api.cc
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
31
t-dll.cc
31
t-dll.cc
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
7
t-dll.h
7
t-dll.h
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
6
target.h
6
target.h
|
|
@ -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*);
|
||||
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
Loading…
Reference in New Issue