iverilog/t-dll-api.cc

2235 lines
44 KiB
C++
Raw Normal View History

/*
* Copyright (c) 2000-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 "StringHeap.h"
# include "t-dll.h"
# include <stdlib.h>
# include <string.h>
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
static StringHeap api_strings;
/* THE FOLLOWING ARE FUNCTIONS THAT ARE CALLED FROM THE TARGET. */
extern "C" const char*ivl_design_flag(ivl_design_t des, const char*key)
{
return des->self->get_flag(key);
}
extern "C" int ivl_design_process(ivl_design_t des,
ivl_process_f func,
void*cd)
{
for (ivl_process_t idx = des->threads_; idx; idx = idx->next_) {
int rc = (func)(idx, cd);
if (rc != 0)
return rc;
}
return 0;
}
extern "C" ivl_scope_t ivl_design_root(ivl_design_t des)
{
2005-04-01 08:04:30 +02:00
cerr << "ANACHRONISM: ivl_design_root called. "
"Use ivl_design_roots instead." << endl;
assert (des->nroots_);
return des->roots_[0];
}
extern "C" void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes,
unsigned int *nscopes)
{
assert (nscopes && scopes);
*scopes = &des->roots_[0];
*nscopes = des->nroots_;
}
extern "C" int ivl_design_time_precision(ivl_design_t des)
{
return des->time_precision;
}
extern "C" unsigned ivl_design_consts(ivl_design_t des)
{
return des->nconsts;
}
extern "C" ivl_net_const_t ivl_design_const(ivl_design_t des, unsigned idx)
{
assert(idx < des->nconsts);
return des->consts[idx];
}
extern "C" ivl_expr_type_t ivl_expr_type(ivl_expr_t net)
{
if (net == 0)
return IVL_EX_NONE;
return net->type_;
}
extern "C" const char*ivl_expr_file(ivl_expr_t net)
{
assert(net);
return net->file.str();
}
extern "C" unsigned ivl_expr_lineno(ivl_expr_t net)
{
assert(net);
return net->lineno;
}
inline static const char *basename(ivl_scope_t scope, const char *inst)
{
inst += strlen(ivl_scope_name(scope));
assert(*inst == '.');
return inst+1;
}
2005-07-07 18:22:49 +02:00
extern "C" ivl_variable_type_t ivl_const_type(ivl_net_const_t net)
{
assert(net);
return net->type;
}
2000-10-05 07:03:01 +02:00
extern "C" const char*ivl_const_bits(ivl_net_const_t net)
{
assert(net);
2005-07-07 18:22:49 +02:00
switch (net->type) {
case IVL_VT_LOGIC:
if (net->width_ <= sizeof(net->b.bit_))
return net->b.bit_;
else
return net->b.bits_;
default:
return 0;
}
}
extern "C" ivl_expr_t ivl_const_delay(ivl_net_const_t net, unsigned transition)
{
assert(transition < 3);
return net->delay[transition];
}
extern "C" ivl_nexus_t ivl_const_nex(ivl_net_const_t net)
{
assert(net);
return net->pin_;
2000-10-05 07:03:01 +02:00
}
2005-07-07 18:22:49 +02:00
extern "C" double ivl_const_real(ivl_net_const_t net)
{
assert(net);
assert(net->type == IVL_VT_REAL);
return net->b.real_value;
}
extern "C" int ivl_const_signed(ivl_net_const_t net)
2000-10-05 07:03:01 +02:00
{
assert(net);
return net->signed_;
2000-10-05 07:03:01 +02:00
}
extern "C" unsigned ivl_const_width(ivl_net_const_t net)
2000-10-05 07:03:01 +02:00
{
assert(net);
return net->width_;
2000-10-05 07:03:01 +02:00
}
extern "C" const char* ivl_event_name(ivl_event_t net)
{
2003-03-06 02:24:37 +01:00
static char*name_buffer = 0;
static unsigned name_size = 0;
ivl_scope_t scope = net->scope;
const char*sn = ivl_scope_name(scope);
unsigned need = strlen(sn) + 1 + strlen(net->name) + 1;
2003-03-06 05:32:40 +01:00
if (need > name_size) {
2003-03-06 02:24:37 +01:00
name_buffer = (char*)realloc(name_buffer, need);
name_size = need;
}
strcpy(name_buffer, sn);
char*tmp = name_buffer + strlen(sn);
*tmp++ = '.';
strcpy(tmp, net->name);
cerr << "ANACHRONISM: Call to anachronistic ivl_event_name." << endl;
return name_buffer;
}
extern "C" const char* ivl_event_basename(ivl_event_t net)
{
2003-03-06 02:24:37 +01:00
return net->name;
}
extern "C" ivl_scope_t ivl_event_scope(ivl_event_t net)
{
return net->scope;
}
extern "C" unsigned ivl_event_nany(ivl_event_t net)
{
assert(net);
return net->nany;
}
extern "C" ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx)
{
assert(net);
assert(idx < net->nany);
return net->pins[idx];
}
extern "C" unsigned ivl_event_nneg(ivl_event_t net)
{
assert(net);
return net->nneg;
}
extern "C" ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx)
{
assert(net);
assert(idx < net->nneg);
return net->pins[net->nany + idx];
}
extern "C" unsigned ivl_event_npos(ivl_event_t net)
{
assert(net);
return net->npos;
}
extern "C" ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx)
{
assert(net);
assert(idx < net->npos);
return net->pins[net->nany + net->nneg + idx];
}
extern "C" const char* ivl_expr_bits(ivl_expr_t net)
{
assert(net && (net->type_ == IVL_EX_NUMBER));
return net->u_.number_.bits_;
}
extern "C" ivl_scope_t ivl_expr_def(ivl_expr_t net)
{
assert(net);
switch (net->type_) {
case IVL_EX_UFUNC:
return net->u_.ufunc_.def;
default:
assert(0);
}
return 0;
}
extern "C" double ivl_expr_dvalue(ivl_expr_t net)
{
assert(net->type_ == IVL_EX_REALNUM);
return net->u_.real_.value;
}
2000-09-24 04:21:53 +02:00
extern "C" const char* ivl_expr_name(ivl_expr_t net)
{
2000-10-05 07:03:01 +02:00
switch (net->type_) {
case IVL_EX_SFUNC:
return net->u_.sfunc_.name_;
case IVL_EX_SIGNAL:
return net->u_.signal_.sig->name_;
2002-08-07 04:17:14 +02:00
2000-10-05 07:03:01 +02:00
default:
assert(0);
}
return 0;
2000-09-24 04:21:53 +02:00
}
extern "C" char ivl_expr_opcode(ivl_expr_t net)
{
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
return net->u_.binary_.op_;
2001-03-29 04:52:39 +02:00
case IVL_EX_UNARY:
return net->u_.unary_.op_;
default:
assert(0);
}
return 0;
}
extern "C" ivl_expr_t ivl_expr_oper1(ivl_expr_t net)
{
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
case IVL_EX_SELECT:
return net->u_.binary_.lef_;
2001-03-29 04:52:39 +02:00
case IVL_EX_UNARY:
return net->u_.unary_.sub_;
case IVL_EX_MEMORY:
return net->u_.memory_.idx_;
case IVL_EX_SIGNAL:
return net->u_.signal_.word;
2001-05-17 06:37:02 +02:00
case IVL_EX_TERNARY:
return net->u_.ternary_.cond;
default:
assert(0);
}
return 0;
}
extern "C" ivl_expr_t ivl_expr_oper2(ivl_expr_t net)
{
assert(net);
switch (net->type_) {
case IVL_EX_BINARY:
case IVL_EX_SELECT:
return net->u_.binary_.rig_;
2001-05-17 06:37:02 +02:00
case IVL_EX_TERNARY:
return net->u_.ternary_.true_e;
default:
assert(0);
}
return 0;
}
extern "C" ivl_expr_t ivl_expr_oper3(ivl_expr_t net)
{
assert(net);
2001-05-17 06:37:02 +02:00
switch (net->type_) {
case IVL_EX_TERNARY:
return net->u_.ternary_.false_e;
default:
assert(0);
}
return 0;
}
extern "C" ivl_parameter_t ivl_expr_parameter(ivl_expr_t net)
{
switch (net->type_) {
case IVL_EX_NUMBER:
return net->u_.number_.parameter;
case IVL_EX_STRING:
return net->u_.string_.parameter;
case IVL_EX_REALNUM:
return net->u_.real_.parameter;
default:
return 0;
}
}
2000-10-29 00:32:34 +02:00
extern "C" ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx)
{
assert(net);
switch (net->type_) {
2000-10-29 00:32:34 +02:00
case IVL_EX_CONCAT:
assert(idx < net->u_.concat_.parms);
return net->u_.concat_.parm[idx];
2001-07-07 22:20:10 +02:00
case IVL_EX_SFUNC:
assert(idx < net->u_.sfunc_.parms);
return net->u_.sfunc_.parm[idx];
case IVL_EX_UFUNC:
assert(idx < net->u_.ufunc_.parms);
return net->u_.ufunc_.parm[idx];
2000-10-29 00:32:34 +02:00
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_expr_parms(ivl_expr_t net)
{
assert(net);
switch (net->type_) {
2000-10-29 00:32:34 +02:00
case IVL_EX_CONCAT:
return net->u_.concat_.parms;
2001-05-20 03:06:16 +02:00
case IVL_EX_SFUNC:
2001-07-07 22:20:10 +02:00
return net->u_.sfunc_.parms;
2001-05-20 03:06:16 +02:00
case IVL_EX_UFUNC:
return net->u_.ufunc_.parms;
2000-10-29 00:32:34 +02:00
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_expr_repeat(ivl_expr_t net)
{
assert(net);
assert(net->type_ == IVL_EX_CONCAT);
return net->u_.concat_.rept;
}
extern "C" ivl_event_t ivl_expr_event(ivl_expr_t net)
{
assert(net);
assert(net->type_ == IVL_EX_EVENT);
return net->u_.event_.event;
}
2001-04-02 02:28:35 +02:00
extern "C" ivl_scope_t ivl_expr_scope(ivl_expr_t net)
{
assert(net);
assert(net->type_ == IVL_EX_SCOPE);
return net->u_.scope_.scope;
}
extern "C" ivl_signal_t ivl_expr_signal(ivl_expr_t net)
{
assert(net);
switch (net->type_) {
case IVL_EX_SIGNAL:
case IVL_EX_ARRAY:
return net->u_.signal_.sig;
default:
assert(0);
return 0;
}
}
extern "C" int ivl_expr_signed(ivl_expr_t net)
{
assert(net);
return net->signed_;
}
extern "C" const char* ivl_expr_string(ivl_expr_t net)
{
assert(net->type_ == IVL_EX_STRING);
return net->u_.string_.value_;
}
extern "C" unsigned long ivl_expr_uvalue(ivl_expr_t net)
{
switch (net->type_) {
case IVL_EX_ULONG:
return net->u_.ulong_.value;
case IVL_EX_NUMBER: {
unsigned long val = 0;
for (unsigned long idx = 0 ; idx < net->width_ ; idx += 1) {
if (net->u_.number_.bits_[idx] == '1')
val |= 1UL << idx;
}
return val;
}
default:
assert(0);
}
}
extern "C" ivl_variable_type_t ivl_expr_value(ivl_expr_t net)
{
assert(net);
return net->value_;
}
2000-09-24 04:21:53 +02:00
extern "C" unsigned ivl_expr_width(ivl_expr_t net)
{
assert(net);
return net->width_;
}
/*
* ivl_file_table_index puts entries in the map as needed and returns
* the appropriate index.
* ivl_file_table_size returns the number of entries in the table.
* ivl_file_table_item returns the file name for the given index.
*/
struct ltstr
{
bool operator()(const char*s1, const char*s2) const
{
return strcmp(s1, s2) < 0;
}
};
static map<const char*, unsigned, ltstr> fn_map;
static vector<const char*> fn_vector;
static void ivl_file_table_init()
{
/* The first two index entries do not depend on a real
* file name and are always available. */
fn_vector.push_back("N/A");
fn_map["N/A"] = 0;
fn_vector.push_back("<interactive>");
fn_map["<interactive>"] = 1;
}
extern "C" const char* ivl_file_table_item(unsigned idx)
{
if (fn_vector.empty()) {
ivl_file_table_init();
}
assert(idx < fn_vector.size());
return fn_vector[idx];
}
extern "C" unsigned ivl_file_table_index(const char*name)
{
if (fn_vector.empty()) {
ivl_file_table_init();
}
if (name == NULL) return 0;
/* The new index is the current map size. This is inserted only
* if the file name is not currently in the map. */
pair<map<const char*, unsigned, ltstr>::iterator, bool> result;
result = fn_map.insert(make_pair(name, fn_vector.size()));
if (result.second) {
fn_vector.push_back(name);
}
return result.first->second;
}
extern "C" unsigned ivl_file_table_size()
{
if (fn_vector.empty()) {
ivl_file_table_init();
}
return fn_vector.size();
}
extern "C" int ivl_island_flag_set(ivl_island_t net, int flag, int value)
{
if (flag >= net->flags.size()) {
if (value == 0)
return 0;
else
net->flags.resize(flag+1, false);
}
int old_flag = net->flags[flag];
net->flags[flag] = value != 0;
return old_flag;
}
extern "C" int ivl_island_flag_test(ivl_island_t net, int flag)
{
if (flag >= net->flags.size())
return 0;
else
return net->flags[flag];
}
2001-09-17 00:19:42 +02:00
extern "C" const char* ivl_logic_attr(ivl_net_logic_t net, const char*key)
{
assert(net);
unsigned idx;
for (idx = 0 ; idx < net->nattr ; idx += 1) {
2001-09-17 00:19:42 +02:00
if (strcmp(net->attr[idx].key, key) == 0)
return net->attr[idx].type == IVL_ATT_STR
? net->attr[idx].val.str
: 0;
2001-09-17 00:19:42 +02:00
}
return 0;
}
extern "C" unsigned ivl_logic_attr_cnt(ivl_net_logic_t net)
{
return net->nattr;
}
extern "C" ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net,
unsigned idx)
{
assert(idx < net->nattr);
return net->attr + idx;
}
2005-04-13 08:35:11 +02:00
extern "C" ivl_drive_t ivl_logic_drive0(ivl_net_logic_t net)
{
ivl_nexus_t nex = ivl_logic_pin(net, 0);
for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx);
if (ivl_nexus_ptr_log(cur) != net)
continue;
if (ivl_nexus_ptr_pin(cur) != 0)
continue;
return ivl_nexus_ptr_drive0(cur);
}
assert(0);
2005-06-14 01:22:37 +02:00
return IVL_DR_STRONG;
2005-04-13 08:35:11 +02:00
}
extern "C" ivl_drive_t ivl_logic_drive1(ivl_net_logic_t net)
{
ivl_nexus_t nex = ivl_logic_pin(net, 0);
for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex) ; idx += 1) {
ivl_nexus_ptr_t cur = ivl_nexus_ptr(nex, idx);
if (ivl_nexus_ptr_log(cur) != net)
continue;
if (ivl_nexus_ptr_pin(cur) != 0)
continue;
return ivl_nexus_ptr_drive1(cur);
}
assert(0);
2005-06-14 01:22:37 +02:00
return IVL_DR_STRONG;
2005-04-13 08:35:11 +02:00
}
extern "C" const char* ivl_logic_name(ivl_net_logic_t net)
{
assert(net);
cerr << "ANACHRONISM: Call to anachronistic ivl_logic_name." << endl;
return net->name_;
}
extern "C" const char* ivl_logic_basename(ivl_net_logic_t net)
{
assert(net);
return net->name_;
}
extern "C" ivl_scope_t ivl_logic_scope(ivl_net_logic_t net)
{
assert(net);
return net->scope_;
}
2000-10-05 07:03:01 +02:00
extern "C" ivl_logic_t ivl_logic_type(ivl_net_logic_t net)
{
return net->type_;
}
2000-10-05 07:03:01 +02:00
extern "C" unsigned ivl_logic_pins(ivl_net_logic_t net)
{
return net->npins_;
}
2000-10-05 07:03:01 +02:00
extern "C" ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin)
{
assert(pin < net->npins_);
return net->pins_[pin];
}
extern "C" ivl_udp_t ivl_logic_udp(ivl_net_logic_t net)
{
assert(net->type_ == IVL_LO_UDP);
assert(net->udp);
return net->udp;
}
extern "C" ivl_expr_t ivl_logic_delay(ivl_net_logic_t net, unsigned transition)
{
assert(transition < 3);
return net->delay[transition];
}
extern "C" unsigned ivl_logic_width(ivl_net_logic_t net)
{
assert(net);
return net->width_;
}
2005-04-01 08:04:30 +02:00
extern "C" int ivl_udp_sequ(ivl_udp_t net)
{
return net->sequ;
}
extern "C" unsigned ivl_udp_nin(ivl_udp_t net)
{
return net->nin;
}
extern "C" unsigned ivl_udp_init(ivl_udp_t net)
{
return net->init;
}
extern "C" const char* ivl_udp_row(ivl_udp_t net, unsigned idx)
{
assert(idx < net->nrows);
assert(net->table);
assert(net->table[idx]);
return net->table[idx];
}
extern "C" unsigned ivl_udp_rows(ivl_udp_t net)
{
return net->nrows;
}
extern "C" const char* ivl_udp_name(ivl_udp_t net)
{
assert(net->name);
return net->name;
}
extern "C" const char* ivl_lpm_basename(ivl_lpm_t net)
{
return net->name;
}
extern "C" ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net)
{
assert(net);
switch(net->type) {
case IVL_LPM_FF:
return net->u_.ff.aclr;
default:
assert(0);
return 0;
}
}
extern "C" ivl_nexus_t ivl_lpm_sync_clr(ivl_lpm_t net)
{
assert(net);
switch(net->type) {
case IVL_LPM_FF:
return net->u_.ff.sclr;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_lpm_delay(ivl_lpm_t net, unsigned transition)
{
assert(transition < 3);
return net->delay[transition];
}
extern "C" ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net)
{
assert(net);
switch(net->type) {
case IVL_LPM_FF:
return net->u_.ff.aset;
default:
assert(0);
return 0;
}
}
extern "C" ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net)
{
assert(net);
switch(net->type) {
case IVL_LPM_FF:
return net->u_.ff.sset;
default:
assert(0);
return 0;
}
}
extern "C" ivl_signal_t ivl_lpm_array(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_ARRAY:
return net->u_.array.sig;
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_lpm_base(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
2005-08-06 19:58:16 +02:00
case IVL_LPM_PART_BI:
return net->u_.part.base;
default:
assert(0);
return 0;
}
}
extern "C" ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
return net->u_.ff.clk;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
return net->u_.ff.aset_value;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
return net->u_.ff.sset_value;
default:
assert(0);
return 0;
}
}
extern "C" ivl_scope_t ivl_lpm_define(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_UFUNC:
return net->u_.ufunc.def;
default:
assert(0);
return 0;
}
}
extern "C" ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
2001-09-01 00:58:39 +02:00
case IVL_LPM_FF:
return net->u_.ff.we;
default:
assert(0);
return 0;
}
}
/* The file name and line number are only set for system functions! */
extern "C" const char* ivl_lpm_file(ivl_lpm_t net)
{
return net->file.str();
}
extern "C" unsigned ivl_lpm_lineno(ivl_lpm_t net)
{
return net->lineno;
}
extern "C" ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx)
2000-11-12 18:47:29 +01:00
{
assert(net);
switch (net->type) {
case IVL_LPM_ABS:
assert(idx == 0);
return net->u_.arith.a;
2001-06-07 04:12:43 +02:00
case IVL_LPM_ADD:
case IVL_LPM_CMP_EEQ:
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
2005-03-09 06:52:03 +01:00
case IVL_LPM_CMP_NEE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_POW:
2001-06-07 05:09:37 +02:00
case IVL_LPM_SUB:
assert(idx <= 1);
if (idx == 0)
return net->u_.arith.a;
else
return net->u_.arith.b;
2001-06-07 04:12:43 +02:00
case IVL_LPM_MUX:
assert(idx < net->u_.mux.size);
return net->u_.mux.d[idx];
case IVL_LPM_RE_AND:
case IVL_LPM_RE_OR:
case IVL_LPM_RE_XOR:
case IVL_LPM_RE_NAND:
case IVL_LPM_RE_NOR:
case IVL_LPM_RE_XNOR:
2005-05-24 03:44:27 +02:00
case IVL_LPM_SIGN_EXT:
assert(idx == 0);
return net->u_.reduce.a;
2001-07-05 00:59:25 +02:00
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
2005-02-19 03:43:38 +01:00
assert(idx <= 1);
if (idx == 0)
return net->u_.shift.d;
else
return net->u_.shift.s;
2001-07-05 00:59:25 +02:00
2005-04-06 07:29:08 +02:00
case IVL_LPM_FF:
2005-04-25 01:44:01 +02:00
assert(idx == 0);
return net->u_.ff.d.pin;
case IVL_LPM_CONCAT:
assert(idx < net->u_.concat.inputs);
return net->u_.concat.pins[idx+1];
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
2005-08-06 19:58:16 +02:00
case IVL_LPM_PART_BI:
2005-05-09 01:40:14 +02:00
assert(idx <= 1);
if (idx == 0)
return net->u_.part.a;
else
return net->u_.part.s;
case IVL_LPM_REPEAT:
assert(idx == 0);
return net->u_.repeat.a;
case IVL_LPM_SFUNC:
// Skip the return port.
assert(idx < (net->u_.sfunc.ports-1));
return net->u_.sfunc.pins[idx+1];
case IVL_LPM_UFUNC:
// Skip the return port.
assert(idx < (net->u_.ufunc.ports-1));
return net->u_.ufunc.pins[idx+1];
default:
assert(0);
return 0;
}
2000-11-12 18:47:29 +01:00
}
2001-06-07 04:12:43 +02:00
extern "C" ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx)
{
cerr << "ANACHRONISM: Call to anachronistic ivl_lpm_datab." << endl;
2001-06-07 04:12:43 +02:00
assert(net);
switch (net->type) {
case IVL_LPM_ADD:
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_POW:
2001-06-07 05:09:37 +02:00
case IVL_LPM_SUB:
assert(idx == 0);
return net->u_.arith.b;
2001-06-07 04:12:43 +02:00
default:
assert(0);
return 0;
}
}
/*
* This function returns the hierarchical name for the LPM device. The
* name needs to be built up from the scope name and the lpm base
* name.
*
* Anachronism: This function is provided for
* compatibility. Eventually, it will be removed.
*/
extern "C" const char* ivl_lpm_name(ivl_lpm_t net)
{
static char*name_buffer = 0;
static unsigned name_size = 0;
ivl_scope_t scope = ivl_lpm_scope(net);
const char*sn = ivl_scope_name(scope);
unsigned need = strlen(sn) + 1 + strlen(net->name) + 1;
2003-03-06 05:32:40 +01:00
if (need > name_size) {
name_buffer = (char*)realloc(name_buffer, need);
name_size = need;
}
strcpy(name_buffer, sn);
char*tmp = name_buffer + strlen(sn);
*tmp++ = '.';
strcpy(tmp, net->name);
return name_buffer;
2000-11-12 18:47:29 +01:00
}
extern "C" ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx)
2000-11-12 18:47:29 +01:00
{
assert(net);
switch (net->type) {
case IVL_LPM_ABS:
2001-06-07 04:12:43 +02:00
case IVL_LPM_ADD:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_POW:
2001-06-07 05:09:37 +02:00
case IVL_LPM_SUB:
assert(idx == 0);
return net->u_.arith.q;
2001-06-07 04:12:43 +02:00
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_NE:
case IVL_LPM_CMP_EEQ:
2005-03-09 06:52:03 +01:00
case IVL_LPM_CMP_NEE:
assert(idx == 0);
return net->u_.arith.q;
2005-04-06 07:29:08 +02:00
case IVL_LPM_FF:
2005-04-25 01:44:01 +02:00
assert(idx == 0);
return net->u_.ff.q.pin;
case IVL_LPM_MUX:
assert(idx == 0);
return net->u_.mux.q;
case IVL_LPM_RE_AND:
case IVL_LPM_RE_OR:
case IVL_LPM_RE_XOR:
case IVL_LPM_RE_NAND:
case IVL_LPM_RE_NOR:
case IVL_LPM_RE_XNOR:
2005-05-24 03:44:27 +02:00
case IVL_LPM_SIGN_EXT:
assert(idx == 0);
return net->u_.reduce.q;
2001-07-05 00:59:25 +02:00
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
2005-02-19 03:43:38 +01:00
assert(idx == 0);
return net->u_.shift.q;
2001-07-05 00:59:25 +02:00
case IVL_LPM_SFUNC:
assert(idx == 0);
return net->u_.sfunc.pins[0];
2002-03-09 03:10:22 +01:00
case IVL_LPM_UFUNC:
assert(idx == 0);
return net->u_.ufunc.pins[0];
2002-03-09 03:10:22 +01:00
case IVL_LPM_CONCAT:
return net->u_.concat.pins[0];
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
2005-08-06 19:58:16 +02:00
case IVL_LPM_PART_BI:
assert(idx == 0);
return net->u_.part.q;
case IVL_LPM_REPEAT:
assert(idx == 0);
return net->u_.repeat.q;
case IVL_LPM_ARRAY:
assert(idx == 0);
return net->u_.array.q;
default:
assert(0);
return 0;
}
2000-11-12 18:47:29 +01:00
}
extern "C" ivl_scope_t ivl_lpm_scope(ivl_lpm_t net)
{
assert(net);
return net->scope;
}
2005-04-06 07:29:08 +02:00
extern "C" ivl_nexus_t ivl_lpm_select(ivl_lpm_t net)
{
switch (net->type) {
case IVL_LPM_MUX:
return net->u_.mux.s;
case IVL_LPM_ARRAY:
return net->u_.array.a;
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_lpm_selects(ivl_lpm_t net)
{
switch (net->type) {
case IVL_LPM_MUX:
return net->u_.mux.swid;
case IVL_LPM_ARRAY:
return net->u_.array.swid;
case IVL_LPM_CONCAT:
return net->u_.concat.inputs;
default:
assert(0);
return 0;
}
}
extern "C" int ivl_lpm_signed(ivl_lpm_t net)
{
assert(net);
switch (net->type) {
case IVL_LPM_FF:
case IVL_LPM_MUX:
return 0;
case IVL_LPM_ABS:
case IVL_LPM_ADD:
case IVL_LPM_CMP_EEQ:
case IVL_LPM_CMP_EQ:
case IVL_LPM_CMP_GE:
case IVL_LPM_CMP_GT:
case IVL_LPM_CMP_NE:
2005-03-09 06:52:03 +01:00
case IVL_LPM_CMP_NEE:
case IVL_LPM_DIVIDE:
case IVL_LPM_MOD:
case IVL_LPM_MULT:
case IVL_LPM_POW:
case IVL_LPM_SUB:
return net->u_.arith.signed_flag;
case IVL_LPM_RE_AND:
case IVL_LPM_RE_OR:
case IVL_LPM_RE_XOR:
case IVL_LPM_RE_NAND:
case IVL_LPM_RE_NOR:
case IVL_LPM_RE_XNOR:
return 0;
case IVL_LPM_SHIFTL:
case IVL_LPM_SHIFTR:
return net->u_.shift.signed_flag;
2005-05-24 03:44:27 +02:00
case IVL_LPM_SIGN_EXT: // Sign extend is always signed.
return 1;
case IVL_LPM_SFUNC:
return 0;
case IVL_LPM_UFUNC:
return 0;
case IVL_LPM_CONCAT: // Concatenations are always unsigned
return 0;
case IVL_LPM_PART_VP:
case IVL_LPM_PART_PV:
2005-08-06 19:58:16 +02:00
case IVL_LPM_PART_BI:
return net->u_.part.signed_flag;
case IVL_LPM_REPEAT:
return 0;
case IVL_LPM_ARRAY: // Array ports take the signedness of the array.
return net->u_.array.sig->signed_;
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_lpm_size(ivl_lpm_t net)
{
switch (net->type) {
case IVL_LPM_MUX:
return net->u_.mux.size;
case IVL_LPM_SFUNC:
return net->u_.sfunc.ports - 1;
case IVL_LPM_UFUNC:
return net->u_.ufunc.ports - 1;
case IVL_LPM_REPEAT:
return net->u_.repeat.count;
default:
assert(0);
return 0;
}
}
extern "C" const char* ivl_lpm_string(ivl_lpm_t net)
{
assert(net->type == IVL_LPM_SFUNC);
return net->u_.sfunc.fun_name;
}
extern "C" ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net)
{
return net->type;
}
extern "C" unsigned ivl_lpm_width(ivl_lpm_t net)
{
assert(net);
return net->width;
}
extern "C" ivl_expr_t ivl_lval_mux(ivl_lval_t net)
{
assert(net);
if (net->type_ == IVL_LVAL_MUX)
return net->idx;
return 0x0;
}
extern "C" ivl_expr_t ivl_lval_idx(ivl_lval_t net)
{
assert(net);
2007-01-17 05:39:18 +01:00
if (net->type_ == IVL_LVAL_ARR)
return net->idx;
return 0x0;
}
extern "C" ivl_expr_t ivl_lval_part_off(ivl_lval_t net)
{
assert(net);
return net->loff;
}
extern "C" unsigned ivl_lval_width(ivl_lval_t net)
{
assert(net);
return net->width_;
}
extern "C" ivl_signal_t ivl_lval_sig(ivl_lval_t net)
{
assert(net);
2005-07-07 18:22:49 +02:00
switch (net->type_) {
case IVL_LVAL_REG:
case IVL_LVAL_NET:
case IVL_LVAL_MUX:
case IVL_LVAL_ARR:
2005-07-07 18:22:49 +02:00
return net->n.sig;
default:
return 0;
}
}
/*
* The nexus name is rarely needed. (Shouldn't be needed at all!) This
* function will calculate the name if it is not already calculated.
*/
2000-10-05 07:03:01 +02:00
extern "C" const char* ivl_nexus_name(ivl_nexus_t net)
{
assert(net);
if (net->name_ == 0) {
net->name_ = api_strings.add(net->nexus_->name());
}
return net->name_;
}
extern "C" void* ivl_nexus_get_private(ivl_nexus_t net)
{
assert(net);
return net->private_data;
}
extern "C" void ivl_nexus_set_private(ivl_nexus_t net, void*data)
{
assert(net);
net->private_data = data;
}
extern "C" unsigned ivl_nexus_ptrs(ivl_nexus_t net)
{
assert(net);
return net->nptr_;
}
extern "C" ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx)
{
assert(net);
assert(idx < net->nptr_);
return net->ptrs_ + idx;
}
extern "C" ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net)
{
assert(net);
return (ivl_drive_t)(net->drive0);
}
extern "C" ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net)
{
assert(net);
return (ivl_drive_t)(net->drive1);
}
2000-10-25 07:41:24 +02:00
extern "C" unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net)
{
assert(net);
return net->pin_;
}
extern "C" ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net)
{
if (net == 0)
return 0;
if (net->type_ != __NEXUS_PTR_CON)
return 0;
return net->l.con;
}
extern "C" ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net)
{
if (net == 0)
return 0;
if (net->type_ != __NEXUS_PTR_LOG)
return 0;
return net->l.log;
}
extern "C" ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net)
{
if (net == 0)
return 0;
if (net->type_ != __NEXUS_PTR_LPM)
return 0;
return net->l.lpm;
}
2000-10-25 07:41:24 +02:00
extern "C" ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net)
{
if (net == 0)
return 0;
if (net->type_ != __NEXUS_PTR_SIG)
return 0;
return net->l.sig;
}
extern "C" ivl_switch_t ivl_nexus_ptr_switch(ivl_nexus_ptr_t net)
{
if (net == 0)
return 0;
if (net->type_ != __NEXUS_PTR_SWI)
return 0;
return net->l.swi;
}
extern "C" const char* ivl_parameter_basename(ivl_parameter_t net)
{
assert(net);
return net->basename;
}
extern "C" ivl_expr_t ivl_parameter_expr(ivl_parameter_t net)
{
assert(net);
return net->value;
}
extern "C" const char* ivl_parameter_file(ivl_parameter_t net)
{
assert(net);
return net->file.str();
}
extern "C" unsigned ivl_parameter_lineno(ivl_parameter_t net)
{
assert(net);
return net->lineno;
}
extern "C" ivl_scope_t ivl_parameter_scope(ivl_parameter_t net)
{
assert(net);
return net->scope;
}
extern "C" ivl_nexus_t ivl_path_condit(ivl_delaypath_t obj)
{
assert(obj);
return obj->condit;
}
extern "C" int ivl_path_is_condit(ivl_delaypath_t obj)
{
assert(obj);
return obj->conditional ? 1 : 0;
}
2006-09-23 06:57:19 +02:00
extern uint64_t ivl_path_delay(ivl_delaypath_t obj, ivl_path_edge_t edg)
{
assert(obj);
return obj->delay[edg];
}
extern ivl_scope_t ivl_path_scope(ivl_delaypath_t obj)
{
assert(obj);
assert(obj->scope);
return obj->scope;
}
2006-09-23 06:57:19 +02:00
extern ivl_nexus_t ivl_path_source(ivl_delaypath_t net)
{
return net->src;
}
extern int ivl_path_source_posedge(ivl_delaypath_t net)
{
return net->posedge ? 1 : 0;
}
extern int ivl_path_source_negedge(ivl_delaypath_t net)
{
return net->negedge ? 1 : 0;
}
2000-10-05 07:03:01 +02:00
extern "C" ivl_process_type_t ivl_process_type(ivl_process_t net)
{
return net->type_;
}
2001-03-20 02:44:13 +01:00
extern "C" ivl_scope_t ivl_process_scope(ivl_process_t net)
{
return net->scope_;
}
2000-10-05 07:03:01 +02:00
extern "C" ivl_statement_t ivl_process_stmt(ivl_process_t net)
{
return net->stmt_;
}
extern "C" unsigned ivl_process_attr_cnt(ivl_process_t net)
{
return net->nattr;
}
extern "C" ivl_attribute_t ivl_process_attr_val(ivl_process_t net,
unsigned idx)
{
assert(idx < net->nattr);
return net->attr + idx;
}
extern "C" unsigned ivl_scope_attr_cnt(ivl_scope_t net)
{
assert(net);
return net->nattr;
}
extern "C" ivl_attribute_t ivl_scope_attr_val(ivl_scope_t net,
unsigned idx)
{
assert(idx < net->nattr);
return net->attr + idx;
}
extern "C" const char* ivl_scope_basename(ivl_scope_t net)
{
assert(net);
2003-03-03 03:22:41 +01:00
return net->name_;
}
extern "C" int ivl_scope_children(ivl_scope_t net,
ivl_scope_f func,
void*cd)
{
for (ivl_scope_t cur = net->child_; cur; cur = cur->sibling_) {
int rc = func(cur, cd);
if (rc != 0)
return rc;
}
return 0;
}
2001-04-02 04:28:12 +02:00
extern "C" ivl_statement_t ivl_scope_def(ivl_scope_t net)
{
assert(net);
return net->def;
}
extern "C" const char*ivl_scope_def_file(ivl_scope_t net)
{
assert(net);
return net->def_file.str();
}
extern "C" unsigned ivl_scope_def_lineno(ivl_scope_t net)
{
assert(net);
return net->def_lineno;
}
extern "C" unsigned ivl_scope_events(ivl_scope_t net)
{
assert(net);
return net->nevent_;
}
extern "C" ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nevent_);
return net->event_[idx];
}
extern "C" const char*ivl_scope_file(ivl_scope_t net)
{
assert(net);
return net->file.str();
}
extern "C" unsigned ivl_scope_lineno(ivl_scope_t net)
{
assert(net);
return net->lineno;
}
extern "C" unsigned ivl_scope_logs(ivl_scope_t net)
{
assert(net);
return net->nlog_;
}
extern "C" ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nlog_);
return net->log_[idx];
}
extern "C" unsigned ivl_scope_lpms(ivl_scope_t net)
{
assert(net);
return net->nlpm_;
}
extern "C" ivl_lpm_t ivl_scope_lpm(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nlpm_);
return net->lpm_[idx];
}
static unsigned scope_name_len(ivl_scope_t net)
{
unsigned len = 0;
for (ivl_scope_t cur = net ; cur ; cur = cur->parent)
len += strlen(cur->name_) + 1;
return len;
}
2003-03-03 03:22:41 +01:00
static void push_scope_basename(ivl_scope_t net, char*buf)
{
if (net->parent == 0) {
strcpy(buf, net->name_);
return;
}
push_scope_basename(net->parent, buf);
strcat(buf, ".");
strcat(buf, net->name_);
}
extern "C" const char* ivl_scope_name(ivl_scope_t net)
{
2003-03-03 03:22:41 +01:00
static char*name_buffer = 0;
static unsigned name_size = 0;
if (net->parent == 0)
return net->name_;
unsigned needlen = scope_name_len(net);
2003-03-03 03:22:41 +01:00
if (name_size < needlen) {
name_buffer = (char*)realloc(name_buffer, needlen);
name_size = needlen;
}
push_scope_basename(net, name_buffer);
return name_buffer;
}
extern "C" unsigned ivl_scope_params(ivl_scope_t net)
{
assert(net);
return net->nparam_;
}
extern "C" ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nparam_);
return net->param_ + idx;
}
extern "C" ivl_scope_t ivl_scope_parent(ivl_scope_t net)
{
assert(net);
return net->parent;
}
extern "C" unsigned ivl_scope_ports(ivl_scope_t net)
{
assert(net);
assert(net->type_ == IVL_SCT_FUNCTION);
return net->ports;
}
extern "C" ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(net->type_ == IVL_SCT_FUNCTION);
assert(idx < net->ports);
return net->port[idx];
}
extern "C" unsigned ivl_scope_sigs(ivl_scope_t net)
{
assert(net);
return net->nsigs_;
}
extern "C" ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx)
{
assert(net);
assert(idx < net->nsigs_);
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);
return net->time_precision;
}
extern "C" int ivl_scope_time_units(ivl_scope_t net)
{
assert(net);
return net->time_units;
}
extern "C" ivl_scope_type_t ivl_scope_type(ivl_scope_t net)
{
assert(net);
return net->type_;
}
extern "C" const char* ivl_scope_tname(ivl_scope_t net)
{
assert(net);
return net->tname_;
}
extern "C" int ivl_signal_array_base(ivl_signal_t net)
{
return net->array_base;
}
extern "C" unsigned ivl_signal_array_count(ivl_signal_t net)
{
return net->array_words;
}
2007-04-02 03:12:34 +02:00
extern "C" unsigned ivl_signal_dimensions(ivl_signal_t net)
{
return net->array_dimensions_;
}
extern "C" const char* ivl_signal_attr(ivl_signal_t net, const char*key)
{
2002-05-24 06:36:23 +02:00
if (net->nattr == 0)
return 0;
2002-05-24 06:36:23 +02:00
for (unsigned idx = 0 ; idx < net->nattr ; idx += 1)
2002-05-24 06:36:23 +02:00
if (strcmp(key, net->attr[idx].key) == 0)
return net->attr[idx].type == IVL_ATT_STR
? net->attr[idx].val.str
: 0;
return 0;
}
2002-05-24 06:36:23 +02:00
extern "C" unsigned ivl_signal_attr_cnt(ivl_signal_t net)
{
return net->nattr;
}
extern "C" ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx)
{
assert(idx < net->nattr);
return net->attr + idx;
}
extern "C" const char* ivl_signal_basename(ivl_signal_t net)
{
return net->name_;
}
extern "C" const char* ivl_signal_name(ivl_signal_t net)
{
static char*name_buffer = 0;
static unsigned name_size = 0;
unsigned needlen = scope_name_len(net->scope_);
needlen += strlen(net->name_) + 2;
if (name_size < needlen) {
name_buffer = (char*)realloc(name_buffer, needlen);
name_size = needlen;
}
push_scope_basename(net->scope_, name_buffer);
strcat(name_buffer, ".");
strcat(name_buffer, net->name_);
return name_buffer;
}
extern "C" ivl_nexus_t ivl_signal_nex(ivl_signal_t net, unsigned word)
{
assert(word < net->array_words);
if (net->array_words > 1)
return net->pins[word];
else
return net->pin;
}
extern "C" int ivl_signal_msb(ivl_signal_t net)
{
assert(net->lsb_dist == 1 || net->lsb_dist == -1);
return net->lsb_index + net->lsb_dist * (net->width_ - 1);
}
extern "C" int ivl_signal_lsb(ivl_signal_t net)
{
return net->lsb_index;
}
extern "C" unsigned ivl_signal_width(ivl_signal_t net)
{
return net->width_;
}
extern "C" ivl_signal_port_t ivl_signal_port(ivl_signal_t net)
{
return net->port_;
}
extern "C" int ivl_signal_local(ivl_signal_t net)
{
return net->local_;
}
extern "C" int ivl_signal_signed(ivl_signal_t net)
{
return net->signed_;
}
extern "C" const char* ivl_signal_file(ivl_signal_t net)
{
assert(net);
return net->file.str();
}
extern "C" unsigned ivl_signal_lineno(ivl_signal_t net)
{
assert(net);
return net->lineno;
}
extern "C" int ivl_signal_integer(ivl_signal_t net)
{
return net->isint_;
}
2005-07-07 18:22:49 +02:00
extern "C" ivl_variable_type_t ivl_signal_data_type(ivl_signal_t net)
{
return net->data_type;
}
2006-09-23 06:57:19 +02:00
extern "C" unsigned ivl_signal_npath(ivl_signal_t net)
{
return net->npath;
}
extern "C" ivl_delaypath_t ivl_signal_path(ivl_signal_t net, unsigned idx)
{
assert(idx < net->npath);
return net->path + idx;
}
extern "C" ivl_signal_type_t ivl_signal_type(ivl_signal_t net)
{
return net->type_;
}
extern "C" ivl_statement_type_t ivl_statement_type(ivl_statement_t net)
{
return net->type_;
}
extern "C" const char* ivl_stmt_file(ivl_statement_t net)
{
return net->file.str();
}
extern "C" unsigned ivl_stmt_lineno(ivl_statement_t net)
{
return net->lineno;
}
extern "C" ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_BLOCK:
case IVL_ST_FORK:
return net->u_.block_.scope;
default:
assert(0);
return 0;
}
}
extern "C" unsigned ivl_stmt_block_count(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_BLOCK:
case IVL_ST_FORK:
return net->u_.block_.nstmt_;
default:
assert(0);
return 0;
}
}
extern "C" ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net,
unsigned i)
{
switch (net->type_) {
case IVL_ST_BLOCK:
case IVL_ST_FORK:
return net->u_.block_.stmt_ + i;
default:
assert(0);
return 0;
}
}
2001-04-02 04:28:12 +02:00
extern "C" ivl_scope_t ivl_stmt_call(ivl_statement_t net)
{
switch (net->type_) {
2001-04-21 02:55:46 +02:00
case IVL_ST_DISABLE:
return net->u_.disable_.scope;
2001-04-02 04:28:12 +02:00
case IVL_ST_UTASK:
return net->u_.utask_.def;
default:
assert(0);
return 0;
}
}
2001-03-31 19:36:38 +02:00
extern "C" unsigned ivl_stmt_case_count(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_CASE:
case IVL_ST_CASER:
2001-03-31 19:36:38 +02:00
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
return net->u_.case_.ncase;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_CASE:
case IVL_ST_CASER:
2001-03-31 19:36:38 +02:00
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
assert(idx < net->u_.case_.ncase);
return net->u_.case_.case_ex[idx];
default:
assert(0);
return 0;
}
}
extern "C" ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_CASE:
case IVL_ST_CASER:
2001-03-31 19:36:38 +02:00
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
assert(idx < net->u_.case_.ncase);
return net->u_.case_.case_st + idx;
default:
assert(0);
return 0;
}
}
extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net)
{
2001-03-31 19:36:38 +02:00
switch (net->type_) {
case IVL_ST_CONDIT:
return net->u_.condit_.cond_;
case IVL_ST_CASE:
case IVL_ST_CASER:
2001-03-31 19:36:38 +02:00
case IVL_ST_CASEX:
case IVL_ST_CASEZ:
return net->u_.case_.cond;
case IVL_ST_REPEAT:
2001-04-01 08:52:27 +02:00
case IVL_ST_WHILE:
return net->u_.while_.cond_;
2001-03-31 19:36:38 +02:00
default:
assert(0);
return 0;
}
}
extern "C" ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net)
{
assert(net->type_ == IVL_ST_CONDIT);
if (net->u_.condit_.stmt_[1].type_ == IVL_ST_NONE)
return 0;
else
return net->u_.condit_.stmt_ + 1;
}
extern "C" ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net)
{
assert(net->type_ == IVL_ST_CONDIT);
if (net->u_.condit_.stmt_[0].type_ == IVL_ST_NONE)
return 0;
else
return net->u_.condit_.stmt_ + 0;
}
extern "C" ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_ASSIGN:
case IVL_ST_ASSIGN_NB:
return net->u_.assign_.delay;
2001-07-19 06:55:06 +02:00
case IVL_ST_DELAYX:
return net->u_.delayx_.expr;
default:
assert(0);
return 0;
}
}
2006-08-08 07:11:37 +02:00
extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net)
{
assert(net->type_ == IVL_ST_DELAY);
return net->u_.delay_.delay_;
}
extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net)
2001-03-27 08:27:40 +02:00
{
2001-03-29 05:47:38 +02:00
switch (net->type_) {
case IVL_ST_WAIT:
return net->u_.wait_.nevent;
case IVL_ST_TRIGGER:
return 1;
default:
assert(0);
}
return 0;
}
extern "C" ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_WAIT:
assert(idx < net->u_.wait_.nevent);
if (net->u_.wait_.nevent == 1)
return net->u_.wait_.event;
else
return net->u_.wait_.events[idx];
2001-03-29 05:47:38 +02:00
case IVL_ST_TRIGGER:
assert(idx == 0);
return net->u_.wait_.event;
2001-03-29 05:47:38 +02:00
default:
assert(0);
}
return 0;
2001-03-27 08:27:40 +02:00
}
extern "C" ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_ASSIGN:
2001-04-03 06:50:37 +02:00
case IVL_ST_ASSIGN_NB:
case IVL_ST_CASSIGN:
case IVL_ST_DEASSIGN:
case IVL_ST_FORCE:
case IVL_ST_RELEASE:
assert(idx < net->u_.assign_.lvals_);
return net->u_.assign_.lval_ + idx;
default:
assert(0);
}
return 0;
}
extern "C" unsigned ivl_stmt_lvals(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_ASSIGN:
2001-04-03 06:50:37 +02:00
case IVL_ST_ASSIGN_NB:
case IVL_ST_CASSIGN:
case IVL_ST_DEASSIGN:
case IVL_ST_FORCE:
case IVL_ST_RELEASE:
return net->u_.assign_.lvals_;
default:
assert(0);
}
return 0;
}
extern "C" unsigned ivl_stmt_lwidth(ivl_statement_t net)
{
2001-04-03 06:50:37 +02:00
assert((net->type_ == IVL_ST_ASSIGN)
|| (net->type_ == IVL_ST_ASSIGN_NB)
|| (net->type_ == IVL_ST_CASSIGN)
2004-12-15 18:10:40 +01:00
|| (net->type_ == IVL_ST_DEASSIGN)
|| (net->type_ == IVL_ST_FORCE)
|| (net->type_ == IVL_ST_RELEASE));
2001-04-03 06:50:37 +02:00
unsigned sum = 0;
unsigned nlvals;
struct ivl_lval_s*lvals;
nlvals = net->u_.assign_.lvals_;
lvals = net->u_.assign_.lval_;
for (unsigned idx = 0 ; idx < nlvals ; idx += 1) {
ivl_lval_t cur = lvals + idx;
switch(cur->type_) {
case IVL_LVAL_MUX:
sum += 1;
break;
case IVL_LVAL_REG:
case IVL_LVAL_ARR:
sum += ivl_lval_width(cur);
break;
default:
assert(0);
}
}
return sum;
}
extern "C" const char* ivl_stmt_name(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_STASK:
return net->u_.stask_.name_;
default:
assert(0);
}
return 0;
}
extern "C" ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx)
{
switch (net->type_) {
case IVL_ST_STASK:
assert(idx < net->u_.stask_.nparm_);
return net->u_.stask_.parms_[idx];
default:
assert(0);
}
return 0;
}
extern "C" unsigned ivl_stmt_parm_count(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_STASK:
return net->u_.stask_.nparm_;
default:
assert(0);
}
return 0;
}
extern "C" ivl_expr_t ivl_stmt_rval(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_ASSIGN:
2001-04-03 06:50:37 +02:00
case IVL_ST_ASSIGN_NB:
case IVL_ST_CASSIGN:
2004-12-15 18:10:40 +01:00
case IVL_ST_FORCE:
return net->u_.assign_.rval_;
default:
assert(0);
}
return 0;
}
extern "C" ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net)
{
switch (net->type_) {
case IVL_ST_DELAY:
return net->u_.delay_.stmt_;
2001-07-19 06:55:06 +02:00
case IVL_ST_DELAYX:
return net->u_.delayx_.stmt_;
case IVL_ST_FOREVER:
return net->u_.forever_.stmt_;
case IVL_ST_WAIT:
return net->u_.wait_.stmt_;
case IVL_ST_REPEAT:
case IVL_ST_WHILE:
return net->u_.while_.stmt_;
default:
assert(0);
}
return 0;
}
extern "C" const char*ivl_switch_basename(ivl_switch_t net)
{
return net->name;
}
extern "C" ivl_scope_t ivl_switch_scope(ivl_switch_t net)
{
return net->scope;
}
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];
}
extern "C" const char* ivl_switch_file(ivl_switch_t net)
{
return net->file;
}
extern "C" ivl_island_t ivl_switch_island(ivl_switch_t net)
{
return net->island;
}
extern "C" unsigned ivl_switch_lineno(ivl_switch_t net)
{
return net->lineno;
}