Elaborate tran devices

The tran devices include tran, rtran, tranif0/1 and rtranif0/1. These
are all elaborated as options on a NetTran device. It is still not
clear the best way to present tran devices via the ivl_target.h API.
This commit is contained in:
Stephen Williams 2008-05-19 21:42:52 -07:00
parent 6966c26f27
commit ec773fe8cf
10 changed files with 163 additions and 7 deletions

View File

@ -106,7 +106,7 @@ eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
load_module.o netlist.o netmisc.o net_assign.o \
net_design.o net_event.o net_expr.o net_force.o net_func.o \
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
net_proc.o net_scope.o net_udp.o pad_to_width.o \
net_proc.o net_scope.o net_tran.o net_udp.o pad_to_width.o \
parse.o parse_misc.o pform.o pform_disciplines.o pform_dump.o pform_types.o \
set_width.o symbol_search.o sync.o sys_funcs.o \
verinum.o verireal.o target.o targets.o \

View File

@ -611,6 +611,17 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
o << setw(ind) << "" << "endtask" << endl;
}
void NetTran::dump_node(ostream&o, unsigned ind) const
{
const char*r = resistive_? "r" : "";
const char*ifx = enable_==0? "" : enable_>0? "if1" : "if0";
o << setw(ind) << "" << r << "tran" << ifx << " " << name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
void NetUDP::dump_node(ostream&o, unsigned ind) const
{
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";

View File

@ -419,7 +419,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
}
/* Allocate all the netlist nodes for the gates. */
NetLogic**cur = new NetLogic*[count];
NetNode**cur = new NetNode*[count];
assert(cur);
/* Calculate the gate delays from the delay expressions
@ -659,6 +659,67 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
cur[idx] = new NetLogic(scope, inm, pin_count(),
NetLogic::XOR, instance_width);
break;
case TRAN:
if (pin_count() != 2) {
cerr << get_fileline() << ": error: Pin count for "
<< "tran device." << endl;
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, false, 0);
}
break;
case RTRAN:
if (pin_count() != 2) {
cerr << get_fileline() << ": error: Pin count for "
<< "rtran device." << endl;
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, true, 0);
return;
}
break;
case TRANIF0:
if (pin_count() != 3) {
cerr << get_fileline() << ": error: Pin count for "
<< "tranif0 device." << endl;
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, false, -1);
}
break;
case RTRANIF0:
if (pin_count() != 3) {
cerr << get_fileline() << ": error: Pin count for "
<< "rtranif0 device." << endl;
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, true, -1);
}
break;
case TRANIF1:
if (pin_count() != 3) {
cerr << get_fileline() << ": error: Pin count for "
<< "tranif1 device." << endl;
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, false, 1);
}
break;
case RTRANIF1:
if (pin_count() != 3) {
cerr << get_fileline() << ": error: Pin count for "
<< "rtranif1 device." << endl;
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, true, 1);
}
break;
default:
cerr << get_fileline() << ": internal error: unhandled "
"gate type." << endl;
@ -670,13 +731,18 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
cur[idx]->attribute(attrib_list[adx].key,
attrib_list[adx].val);
cur[idx]->rise_time(rise_time);
cur[idx]->fall_time(fall_time);
cur[idx]->decay_time(decay_time);
/* The logic devices have some uniform processing. Then
all may have output delays and output drive strength. */
if (NetLogic*log = dynamic_cast<NetLogic*> (cur[idx])) {
log->rise_time(rise_time);
log->fall_time(fall_time);
log->decay_time(decay_time);
cur[idx]->pin(0).drive0(drive_type(strength0()));
cur[idx]->pin(0).drive1(drive_type(strength1()));
log->pin(0).drive0(drive_type(strength0()));
log->pin(0).drive1(drive_type(strength1()));
}
cur[idx]->set_line(*this);
des->add_node(cur[idx]);
}

View File

@ -165,6 +165,11 @@ bool NetUserFunc::emit_node(struct target_t*tgt) const
return tgt->net_function(this);
}
bool NetTran::emit_node(struct target_t*tgt) const
{
return tgt->tran(this);
}
bool NetBUFZ::emit_node(struct target_t*tgt) const
{
return tgt->bufz(this);

44
net_tran.cc Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2008 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
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
# include "config.h"
# include <iostream>
# include <typeinfo>
# include <cstdlib>
# include "compiler.h"
# include "netlist.h"
# include "netmisc.h"
# include "ivl_assert.h"
NetTran::NetTran(NetScope*scope, perm_string n, bool resistive, int enable)
: NetNode(scope, n, enable? 3 : 2)
{
pin(0).set_dir(Link::PASSIVE); pin(0).set_name(perm_string::literal("A"), 0);
pin(1).set_dir(Link::PASSIVE); pin(1).set_name(perm_string::literal("B"), 0);
if (enable) {
pin(2).set_dir(Link::INPUT);
pin(2).set_name(perm_string::literal("E"), 0);
}
}
NetTran::~NetTran()
{
}

View File

@ -1359,6 +1359,20 @@ class NetSysFunc : public NetNode {
const struct sfunc_return_type*def_;
};
class NetTran : public NetNode {
public:
NetTran(NetScope*scope, perm_string n, bool resistive, int enable);
~NetTran();
virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;
private:
bool resistive_;
bool enable_;
};
/* =========
* There are cases where expressions need to be represented. The
* NetExpr class is the root of a hierarchy that serves that purpose.

View File

@ -1008,6 +1008,13 @@ void dll_target::logic(const NetLogic*net)
scope_add_logic(scope, obj);
}
bool dll_target::tran(const NetTran*net)
{
cerr << net->get_fileline() << ": sorry: "
<< "trans devices not supported." << endl;
return false;
}
bool dll_target::sign_extend(const NetSignExtend*net)
{
struct ivl_lpm_s*obj = new struct ivl_lpm_s;

View File

@ -67,6 +67,7 @@ struct dll_target : public target_t, public expr_scan_t {
bool bufz(const NetBUFZ*);
void event(const NetEvent*);
void logic(const NetLogic*);
bool tran(const NetTran*);
bool ureduce(const NetUReduce*);
void net_case_cmp(const NetCaseCmp*);
void udp(const NetUDP*);

View File

@ -61,6 +61,13 @@ void target_t::logic(const NetLogic*)
"Unhandled logic gate" << endl;
}
bool target_t::tran(const NetTran*)
{
cerr << "target (" << typeid(*this).name() << "): "
<< "TRAN devices not supported." << endl;
return false;
}
bool target_t::bufz(const NetBUFZ*)
{
cerr << "target (" << typeid(*this).name() << "): "

View File

@ -86,6 +86,7 @@ struct target_t {
/* Output a gate (called for each gate) */
virtual void logic(const NetLogic*);
virtual bool tran(const NetTran*);
virtual bool ureduce(const NetUReduce*); /* unary reduction operator */
virtual bool bufz(const NetBUFZ*);
virtual void udp(const NetUDP*);