Follow non-canonical bit numbering.

The signal bit numbering should be used for signals. This is
necessary for .model ports because the user specified numbers
are part of the interface, but once that is done, it is trivial
to follow it internally as well.
This commit is contained in:
Stephen Williams 2013-07-19 20:02:14 -07:00
parent e0c9efd129
commit dddaacc6fd
5 changed files with 93 additions and 75 deletions

View File

@ -112,25 +112,10 @@ static void print_signal_bits(FILE*fd, ivl_signal_t sig)
{
ivl_nexus_t nex = ivl_signal_nex(sig, 0);
blif_nex_data_t* ned = blif_nex_data_t::get_nex_data(nex);
ned->set_name(ivl_signal_basename(sig));
ned->set_name(sig);
if (ivl_signal_packed_dimensions(sig) == 0) {
fprintf(fd, " %s", ivl_signal_basename(sig));
return;
}
assert(ivl_signal_packed_dimensions(sig) == 1);
int msb = ivl_signal_packed_msb(sig,0);
int lsb = ivl_signal_packed_lsb(sig,0);
if (msb < lsb) {
int tmp = msb;
msb = lsb;
lsb = tmp;
}
for (int idx = msb ; idx >= lsb ; idx -= 1) {
fprintf(fd, " %s[%d]", ivl_signal_basename(sig), idx);
for (unsigned idx = 0 ; idx < ned->get_width() ; idx += 1) {
fprintf(fd, " %s%s", ned->get_name(), ned->get_name_index(idx));
}
}

View File

@ -28,31 +28,19 @@ static void print_constant(FILE*fd, ivl_net_const_t net)
ivl_nexus_t nex = ivl_const_nex(net);
blif_nex_data_t*ned = blif_nex_data_t::get_nex_data(nex);
if (wid == 1) {
switch (val[0]) {
case '1':
fprintf(fd, ".names %s # const 1\n1\n", ned->get_name());
break;
case '0':
fprintf(fd, ".names %s # const 0\n", ned->get_name());
break;
default:
fprintf(fd, ".names %s # const %c\n", ned->get_name(), val[0]);
break;
}
return;
}
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
switch (val[idx]) {
case '1':
fprintf(fd, ".names %s[%u]\n # const 1\n", ned->get_name(), idx);
fprintf(fd, ".names %s%s # const 1\n1\n",
ned->get_name(), ned->get_name_index(idx));
break;
case '0':
fprintf(fd, ".names %s[%u]\n # const 0", ned->get_name(), idx);
fprintf(fd, ".names %s%s # const 0\n",
ned->get_name(), ned->get_name_index(idx));
break;
default:
fprintf(fd, ".names %s[%u]\n # const %c", ned->get_name(), idx, val[idx]);
fprintf(fd, ".names %s%s # const %c\n",
ned->get_name(), ned->get_name_index(idx), val[idx]);
break;
}
}

View File

@ -55,15 +55,9 @@ static int print_concat(FILE*fd, ivl_lpm_t net)
ned_d = blif_nex_data_t::get_nex_data(nex_d);
}
char dsub[8];
if (ned_d->get_width() > 1)
snprintf(dsub, sizeof dsub, "[%u]", dpos);
else
dsub[0] = 0;
fprintf(fd, ".names %s%s %s[%u]\n1 1\n",
ned_d->get_name(), dsub,
ned_q->get_name(), wid);
fprintf(fd, ".names %s%s %s%s\n1 1\n",
ned_d->get_name(), ned_d->get_name_index(dpos),
ned_q->get_name(), ned_q->get_name_index(wid));
dpos += 1;
}
@ -93,7 +87,9 @@ static int print_part_vp(FILE*fd, ivl_lpm_t net)
assert(bit_sel < ned_in->get_width());
fprintf(fd, ".names %s[%u] %s\n1 1\n", ned_in->get_name(), bit_sel, ned_out->get_name());
fprintf(fd, ".names %s%s %s%s\n1 1\n",
ned_in->get_name(), ned_in->get_name_index(bit_sel),
ned_out->get_name(), ned_out->get_name_index(0));
return rc;
}

View File

@ -27,13 +27,16 @@
using namespace std;
inline blif_nex_data_t::blif_nex_data_t(ivl_nexus_t nex)
: nex_(nex), name_(0), width_(0)
: nex_(nex), name_(0)
{
}
blif_nex_data_t::~blif_nex_data_t()
{
if (name_) free(name_);
for (size_t idx = 0 ; idx < name_index_.size() ; idx += 1)
if (name_index_[idx]) free(name_index_[idx]);
}
blif_nex_data_t* blif_nex_data_t::get_nex_data(ivl_nexus_t nex)
@ -46,10 +49,43 @@ blif_nex_data_t* blif_nex_data_t::get_nex_data(ivl_nexus_t nex)
return data;
}
void blif_nex_data_t::set_name(const char*txt)
void blif_nex_data_t::make_name_from_sig_(ivl_signal_t sig)
{
assert(name_ == 0);
name_ = strdup(txt);
string tmp = ivl_signal_basename(sig);
for (ivl_scope_t sscope = ivl_signal_scope(sig) ; ivl_scope_parent(sscope) ; sscope = ivl_scope_parent(sscope)) {
tmp = ivl_scope_basename(sscope) + string("/") + tmp;
}
name_ = strdup(tmp.c_str());
assert(name_index_.size()==0);
if (ivl_signal_width(sig) > 1) {
name_index_.resize(ivl_signal_width(sig));
assert(ivl_signal_packed_dimensions(sig) == 1);
int msb = ivl_signal_packed_msb(sig,0);
int lsb = ivl_signal_packed_lsb(sig,0);
int dir = (lsb <= msb)? 1 : -1;
int val = lsb;
for (unsigned idx = 0 ; idx < ivl_signal_width(sig) ; idx += 1) {
char buf[64];
snprintf(buf, sizeof buf, "[%d]", val);
name_index_[idx] = strdup(buf);
val += dir;
}
}
}
void blif_nex_data_t::set_name(ivl_signal_t sig)
{
assert(name_ == 0);
assert(ivl_signal_nex(sig,0) == nex_);
make_name_from_sig_(sig);
}
const char* blif_nex_data_t::get_name(void)
@ -62,14 +98,7 @@ const char* blif_nex_data_t::get_name(void)
if (sig == 0)
continue;
string tmp = ivl_signal_basename(sig);
for (ivl_scope_t sscope = ivl_signal_scope(sig) ; ivl_scope_parent(sscope) ; sscope = ivl_scope_parent(sscope)) {
tmp = ivl_scope_basename(sscope) + string("/") + tmp;
}
name_ = strdup(tmp.c_str());
width_ = ivl_signal_width(sig);
assert(width_ > 0);
make_name_from_sig_(sig);
break;
}
@ -83,24 +112,33 @@ const char* blif_nex_data_t::get_name(void)
return name_;
}
const char* blif_nex_data_t::get_name_index(unsigned bit)
{
if (name_index_.size()==0)
return "";
assert(bit < name_index_.size());
if (name_index_[bit] != 0)
return name_index_[bit];
// FIXME: For now, just use the canonical address in
// brackets. This is WRONG!
char tmp[64];
snprintf(tmp, sizeof tmp, "[%u]", bit);
name_index_[bit] = strdup(tmp);
return name_index_[bit];
}
/*
* Get the width from any signal that is attached to the nexus.
*/
size_t blif_nex_data_t::get_width(void)
{
if (width_ > 0)
return width_;
// Special case: If the nexus width is 1 bit, then there is no
// need for index_name maps, so the name_index_ will be empty.
if (name_index_.size()==0)
return 1;
for (unsigned idx = 0 ; idx < ivl_nexus_ptrs(nex_) ; idx += 1) {
ivl_nexus_ptr_t ptr = ivl_nexus_ptr(nex_, idx);
ivl_signal_t sig = ivl_nexus_ptr_sig(ptr);
if (sig == 0)
continue;
width_ = ivl_signal_width(sig);
break;
}
assert(width_ > 0);
return width_;
return name_index_.size();
}

View File

@ -20,6 +20,7 @@
*/
# include "ivl_target.h"
# include <vector>
# include <cstddef>
/*
@ -44,20 +45,30 @@ class blif_nex_data_t {
// In certain situations, we know a priori what we want the
// nexus name to be. In those cases, the context can use this
// method to set the name. Note that this must be called
// before the name is otherwise queried.
void set_name(const char*);
// method to set the name (by the signal from width the name
// is derived). Note that this must be called before the name
// is otherwise queried.
void set_name(ivl_signal_t sig);
// Get the symbolic name chosen for this nexus.
const char*get_name(void);
// Map a canonical bit index (0 : width-1) to the bit number
// as understood by the signal. This is normally a null
// mapping, but sometimes the signal name used for the mapping
// has a non-canonical bit numbering.
const char*get_name_index(unsigned bit);
// Get the vector width for this nexus.
size_t get_width(void);
public:
ivl_nexus_t nex_;
char*name_;
size_t width_;
std::vector<char*> name_index_;
private:
void make_name_from_sig_(ivl_signal_t sig);
};
#endif