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:
parent
e0c9efd129
commit
dddaacc6fd
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue