Skip to content

Commit

Permalink
Bring switch information out to the ivl_target API.
Browse files Browse the repository at this point in the history
This involves defining the API for switches and cleaning up the
elaborated form to match the defined ivl_target API. Also add t-dll
code to support the ivl_switch_t functions, and add stub code that
checks the results.
  • Loading branch information
steveicarus committed May 24, 2008
1 parent 8831367 commit ca756f3
Show file tree
Hide file tree
Showing 13 changed files with 342 additions and 21 deletions.
31 changes: 26 additions & 5 deletions design_dump.cc
Expand Up @@ -88,6 +88,31 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
return o;
}

ostream& operator << (ostream&o, ivl_switch_type_t val)
{
switch (val) {
case IVL_SW_TRAN:
o << "tran";
break;
case IVL_SW_TRANIF0:
o << "tranif0";
break;
case IVL_SW_TRANIF1:
o << "tranif1";
break;
case IVL_SW_RTRAN:
o << "rtran";
break;
case IVL_SW_RTRANIF0:
o << "rtranif0";
break;
case IVL_SW_RTRANIF1:
o << "rtranif1";
break;
}
return o;
}

static inline void dump_scope_path(ostream&o, const NetScope*scope)
{
if (const NetScope*parent = scope->parent()) {
Expand Down Expand Up @@ -613,11 +638,7 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const

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;

o << setw(ind) << "" << type_ << " " << name() << endl;
dump_node_pins(o, ind+4);
dump_obj_attr(o, ind+4);
}
Expand Down
12 changes: 6 additions & 6 deletions elaborate.cc
Expand Up @@ -666,7 +666,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, false, 0);
cur[idx] = new NetTran(scope, inm, IVL_SW_TRAN);
}
break;
case RTRAN:
Expand All @@ -676,7 +676,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, true, 0);
cur[idx] = new NetTran(scope, inm, IVL_SW_RTRAN);
return;
}
break;
Expand All @@ -687,7 +687,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, false, -1);
cur[idx] = new NetTran(scope, inm, IVL_SW_TRANIF0);
}
break;
case RTRANIF0:
Expand All @@ -697,7 +697,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, true, -1);
cur[idx] = new NetTran(scope, inm, IVL_SW_RTRANIF0);
}
break;
case TRANIF1:
Expand All @@ -707,7 +707,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, false, 1);
cur[idx] = new NetTran(scope, inm, IVL_SW_TRANIF1);
}
break;
case RTRANIF1:
Expand All @@ -717,7 +717,7 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
des->errors += 1;
return;
} else {
cur[idx] = new NetTran(scope, inm, true, 1);
cur[idx] = new NetTran(scope, inm, IVL_SW_RTRANIF1);
}
break;
default:
Expand Down
11 changes: 11 additions & 0 deletions ivl.def
Expand Up @@ -152,6 +152,8 @@ ivl_scope_port
ivl_scope_ports
ivl_scope_sigs
ivl_scope_sig
ivl_scope_switch
ivl_scope_switches
ivl_scope_time_precision
ivl_scope_time_units
ivl_scope_type
Expand Down Expand Up @@ -216,6 +218,15 @@ ivl_stmt_parm_count
ivl_stmt_rval
ivl_stmt_sub_stmt

ivl_switch_a
ivl_switch_b
ivl_switch_basename
ivl_switch_enable
ivl_switch_scope
ivl_switch_type
ivl_switch_attr_cnt;
ivl_switch_attr_val;

ivl_udp_init
ivl_udp_name
ivl_udp_nin
Expand Down
52 changes: 52 additions & 0 deletions ivl_target.h
Expand Up @@ -123,6 +123,9 @@ _BEGIN_DECL
* ivl_process_t object holds one of these, but a statement may in
* turn contain other statements.
*
* ivl_switch_t
* Switches are the tran/tranif devices in the design.
*
* -- A Note About Bit Sets --
* Some objects hold a value as an array of bits. In these cases there
* is some method that retrieves the width of the value and another
Expand Down Expand Up @@ -155,6 +158,7 @@ typedef struct ivl_parameter_s*ivl_parameter_t;
typedef struct ivl_process_s *ivl_process_t;
typedef struct ivl_scope_s *ivl_scope_t;
typedef struct ivl_signal_s *ivl_signal_t;
typedef struct ivl_switch_s *ivl_switch_t;
typedef struct ivl_memory_s *ivl_memory_t; /* DEPRECATED */
typedef struct ivl_statement_s*ivl_statement_t;

Expand Down Expand Up @@ -226,6 +230,16 @@ typedef enum ivl_logic_e {
IVL_LO_UDP = 21
} ivl_logic_t;

/* This is the type of a ivl_switch_t object */
typedef enum ivl_switch_type_e {
IVL_SW_TRAN = 0,
IVL_SW_TRANIF0 = 1,
IVL_SW_TRANIF1 = 2,
IVL_SW_RTRAN = 3,
IVL_SW_RTRANIF0 = 4,
IVL_SW_RTRANIF1 = 5
} ivl_switch_type_t;

/* This is the type of an LPM object. */
typedef enum ivl_lpm_type_e {
IVL_LPM_ABS = 32,
Expand Down Expand Up @@ -1501,6 +1515,8 @@ extern unsigned ivl_scope_ports(ivl_scope_t net);
extern ivl_signal_t ivl_scope_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);
extern ivl_switch_t ivl_scope_switch(ivl_scope_t net, unsigned idx);
extern ivl_scope_type_t ivl_scope_type(ivl_scope_t net);
extern const char* ivl_scope_tname(ivl_scope_t net);
extern int ivl_scope_time_precision(ivl_scope_t net);
Expand Down Expand Up @@ -1826,6 +1842,42 @@ extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
IVL_ST_WAIT, IVL_ST_WHILE */
extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);

/* SWITCHES
*
* The switches represent the tran devices in the design.
*
* FUNCTION SUMMARY
*
* ivl_switch_type
* Return the enumerated value that is the type of the switch.
*
* ivl_switch_basename
* This is the name given to the device in the source code.
*
* ivl_switch_scope
* The scope where the switch device appears.
*
* ivl_switch_a
* ivl_switch_b
* The a and b ports are the two ports of the switch.
*
* ivl_switch_enable
* If the device has an enable (tranifX) then this is the enable
* port.
*
* SEMANTIC NOTES
* The a/b ports can be any type, but the types must exactly
* match. The enable must be a scalar.
*/
extern ivl_switch_type_t ivl_switch_type(ivl_switch_t net);
extern const char*ivl_switch_basename(ivl_switch_t net);
extern ivl_scope_t ivl_switch_scope(ivl_switch_t net);
extern ivl_nexus_t ivl_switch_a(ivl_switch_t net);
extern ivl_nexus_t ivl_switch_b(ivl_switch_t net);
extern ivl_nexus_t ivl_switch_enable(ivl_switch_t net);

extern unsigned ivl_switch_attr_cnt(ivl_switch_t net);
extern ivl_attribute_t ivl_switch_attr_val(ivl_switch_t net, unsigned idx);

#if defined(__MINGW32__) || defined (__CYGWIN32__)
# define DLLEXPORT __declspec(dllexport)
Expand Down
19 changes: 16 additions & 3 deletions net_tran.cc
Expand Up @@ -28,12 +28,25 @@
# include "netmisc.h"
# include "ivl_assert.h"

NetTran::NetTran(NetScope*scope, perm_string n, bool resistive, int enable)
: NetNode(scope, n, enable? 3 : 2)
static bool has_enable(ivl_switch_type_t tt)
{
switch (tt) {
case IVL_SW_TRANIF0:
case IVL_SW_TRANIF1:
case IVL_SW_RTRANIF0:
case IVL_SW_RTRANIF1:
return true;
default:
return false;
}
}

NetTran::NetTran(NetScope*scope, perm_string n, ivl_switch_type_t tt)
: NetNode(scope, n, has_enable(tt)? 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) {
if (pin_count() == 3) {
pin(2).set_dir(Link::INPUT);
pin(2).set_name(perm_string::literal("E"), 0);
}
Expand Down
7 changes: 4 additions & 3 deletions netlist.h
Expand Up @@ -1362,15 +1362,16 @@ class NetSysFunc : public NetNode {
class NetTran : public NetNode {

public:
NetTran(NetScope*scope, perm_string n, bool resistive, int enable);
NetTran(NetScope*scope, perm_string n, ivl_switch_type_t type);
~NetTran();

ivl_switch_type_t type() const { return type_; }

virtual void dump_node(ostream&, unsigned ind) const;
virtual bool emit_node(struct target_t*) const;

private:
bool resistive_;
bool enable_;
ivl_switch_type_t type_;
};

/* =========
Expand Down
38 changes: 38 additions & 0 deletions t-dll-api.cc
Expand Up @@ -1627,6 +1627,19 @@ extern "C" ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx)
return net->sigs_[idx];
}

extern "C" unsigned ivl_scope_switches(ivl_scope_t net)
{
assert(net);
return net->switches.size();
}

extern "C" ivl_switch_t ivl_scope_switch(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->switches.size());
return net->switches[idx];
}

extern "C" int ivl_scope_time_precision(ivl_scope_t net)
{
assert(net);
Expand Down Expand Up @@ -2143,3 +2156,28 @@ extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)

return 0;
}

extern "C" const char*ivl_switch_basename(ivl_switch_t net)
{
return net->name;
}

extern "C" ivl_switch_type_t ivl_switch_type(ivl_switch_t net)
{
return net->type;
}

extern "C" ivl_nexus_t ivl_switch_a(ivl_switch_t net)
{
return net->pins[0];
}

extern "C" ivl_nexus_t ivl_switch_b(ivl_switch_t net)
{
return net->pins[1];
}

extern "C" ivl_nexus_t ivl_switch_enable(ivl_switch_t net)
{
return net->pins[2];
}
60 changes: 57 additions & 3 deletions t-dll.cc
Expand Up @@ -380,6 +380,19 @@ static void nexus_lpm_add(ivl_nexus_t nex, ivl_lpm_t net, unsigned pin,
nex->ptrs_[top-1].l.lpm= net;
}

static void nexus_switch_add(ivl_nexus_t nex, ivl_switch_t net, unsigned pin)
{
unsigned top = nex->nptr_ + 1;
nex->ptrs_ = (struct ivl_nexus_ptr_s*)
realloc(nex->ptrs_, top*sizeof(struct ivl_nexus_ptr_s));
nex->nptr_ = top;

nex->ptrs_[top-1].type_= __NEXUS_PTR_SWI;
nex->ptrs_[top-1].drive0 = IVL_DR_HiZ;
nex->ptrs_[top-1].drive1 = IVL_DR_HiZ;
nex->ptrs_[top-1].pin_ = pin;
nex->ptrs_[top-1].l.swi= net;
}

void scope_add_logic(ivl_scope_t scope, ivl_net_logic_t net)
{
Expand Down Expand Up @@ -431,6 +444,11 @@ static void scope_add_lpm(ivl_scope_t scope, ivl_lpm_t net)
}
}

static void scope_add_switch(ivl_scope_t scope, ivl_switch_t net)
{
scope->switches.push_back(net);
}

ivl_parameter_t dll_target::scope_find_param(ivl_scope_t scope,
const char*name)
{
Expand Down Expand Up @@ -621,6 +639,13 @@ int dll_target::end_design(const Design*)
return rc;
}

void dll_target::switch_attributes(struct ivl_switch_s *obj,
const NetNode*net)
{
obj->nattr = net->attr_cnt();
obj->attr = fill_in_attributes(net);
}

void dll_target::logic_attributes(struct ivl_net_logic_s *obj,
const NetNode*net)
{
Expand Down Expand Up @@ -1010,9 +1035,38 @@ void dll_target::logic(const NetLogic*net)

bool dll_target::tran(const NetTran*net)
{
cerr << net->get_fileline() << ": sorry: "
<< "trans devices not supported." << endl;
return false;
struct ivl_switch_s*obj = new struct ivl_switch_s;
obj->type = net->type();
obj->name = net->name();
obj->scope = find_scope(des_, net->scope());
assert(obj->scope);

const Nexus*nex;

nex = net->pin(0).nexus();
assert(nex->t_cookie());
obj->pins[0] = nex->t_cookie();

nex = net->pin(1).nexus();
assert(nex->t_cookie());
obj->pins[1] = nex->t_cookie();

nexus_switch_add(obj->pins[0], obj, 0);
nexus_switch_add(obj->pins[1], obj, 1);

if (net->pin_count() > 2) {
nex = net->pin(2).nexus();
assert(nex->t_cookie());
obj->pins[2] = nex->t_cookie();
nexus_switch_add(obj->pins[2], obj, 2);
} else {
obj->pins[2] = 0;
}

switch_attributes(obj, net);
scope_add_switch(obj->scope, obj);

return true;
}

bool dll_target::sign_extend(const NetSignExtend*net)
Expand Down

0 comments on commit ca756f3

Please sign in to comment.