mirror of https://github.com/YosysHQ/yosys.git
Added SigBit struct and refactored RTLIL::SigSpec::extract
This commit is contained in:
parent
7b01ba384f
commit
8e58bb330d
109
kernel/rtlil.cc
109
kernel/rtlil.cc
|
@ -840,6 +840,15 @@ RTLIL::SigChunk::SigChunk(RTLIL::State bit, int width)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
|
||||||
|
{
|
||||||
|
wire = bit.wire;
|
||||||
|
if (wire == NULL)
|
||||||
|
data = RTLIL::Const(bit.data);
|
||||||
|
offset = bit.offset;
|
||||||
|
width = 1;
|
||||||
|
}
|
||||||
|
|
||||||
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
|
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
|
||||||
{
|
{
|
||||||
RTLIL::SigChunk ret;
|
RTLIL::SigChunk ret;
|
||||||
|
@ -927,14 +936,34 @@ RTLIL::SigSpec::SigSpec(const std::string &str)
|
||||||
RTLIL::SigSpec::SigSpec(int val, int width)
|
RTLIL::SigSpec::SigSpec(int val, int width)
|
||||||
{
|
{
|
||||||
chunks.push_back(RTLIL::SigChunk(val, width));
|
chunks.push_back(RTLIL::SigChunk(val, width));
|
||||||
this->width = chunks.back().width;
|
this->width = width;
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
|
RTLIL::SigSpec::SigSpec(RTLIL::State bit, int width)
|
||||||
{
|
{
|
||||||
chunks.push_back(RTLIL::SigChunk(bit, width));
|
chunks.push_back(RTLIL::SigChunk(bit, width));
|
||||||
this->width = chunks.back().width;
|
this->width = width;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::SigSpec::SigSpec(RTLIL::SigBit bit, int width)
|
||||||
|
{
|
||||||
|
if (bit.wire == NULL)
|
||||||
|
chunks.push_back(RTLIL::SigChunk(bit.data, width));
|
||||||
|
else
|
||||||
|
for (int i = 0; i < width; i++)
|
||||||
|
chunks.push_back(bit);
|
||||||
|
this->width = width;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::SigSpec::SigSpec(std::vector<RTLIL::SigBit> bits)
|
||||||
|
{
|
||||||
|
chunks.reserve(bits.size());
|
||||||
|
for (auto &bit : bits)
|
||||||
|
chunks.push_back(bit);
|
||||||
|
this->width = bits.size();
|
||||||
check();
|
check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,29 +1129,23 @@ restart:
|
||||||
|
|
||||||
RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const
|
RTLIL::SigSpec RTLIL::SigSpec::extract(RTLIL::SigSpec pattern, RTLIL::SigSpec *other) const
|
||||||
{
|
{
|
||||||
int pos = 0;
|
|
||||||
RTLIL::SigSpec ret;
|
|
||||||
pattern.sort_and_unify();
|
|
||||||
assert(other == NULL || width == other->width);
|
assert(other == NULL || width == other->width);
|
||||||
for (size_t i = 0; i < chunks.size(); i++) {
|
|
||||||
const RTLIL::SigChunk &ch1 = chunks[i];
|
std::set<RTLIL::SigBit> pat = pattern.to_sigbit_set();
|
||||||
if (chunks[i].wire != NULL)
|
std::vector<RTLIL::SigBit> bits_match = to_sigbit_vector();
|
||||||
for (size_t j = 0; j < pattern.chunks.size(); j++) {
|
RTLIL::SigSpec ret;
|
||||||
RTLIL::SigChunk &ch2 = pattern.chunks[j];
|
|
||||||
assert(ch2.wire != NULL);
|
if (other) {
|
||||||
if (ch1.wire == ch2.wire) {
|
std::vector<RTLIL::SigBit> bits_other = other ? other->to_sigbit_vector() : bits_match;
|
||||||
int lower = std::max(ch1.offset, ch2.offset);
|
for (int i = 0; i < width; i++)
|
||||||
int upper = std::min(ch1.offset + ch1.width, ch2.offset + ch2.width);
|
if (bits_match[i].wire && pat.count(bits_match[i]))
|
||||||
if (lower < upper) {
|
ret.append_bit(bits_other[i]);
|
||||||
if (other)
|
} else {
|
||||||
ret.append(other->extract(pos+lower-ch1.offset, upper-lower));
|
for (int i = 0; i < width; i++)
|
||||||
else
|
if (bits_match[i].wire && pat.count(bits_match[i]))
|
||||||
ret.append(extract(pos+lower-ch1.offset, upper-lower));
|
ret.append_bit(bits_match[i]);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pos += chunks[i].width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.check();
|
ret.check();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1234,7 +1257,26 @@ void RTLIL::SigSpec::append(const RTLIL::SigSpec &signal)
|
||||||
chunks.push_back(signal.chunks[i]);
|
chunks.push_back(signal.chunks[i]);
|
||||||
width += signal.chunks[i].width;
|
width += signal.chunks[i].width;
|
||||||
}
|
}
|
||||||
check();
|
// check();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTLIL::SigSpec::append_bit(const RTLIL::SigBit &bit)
|
||||||
|
{
|
||||||
|
if (chunks.size() == 0)
|
||||||
|
chunks.push_back(bit);
|
||||||
|
else
|
||||||
|
if (bit.wire == NULL)
|
||||||
|
if (chunks.back().wire == NULL)
|
||||||
|
chunks.back().data.bits.push_back(bit.data);
|
||||||
|
else
|
||||||
|
chunks.push_back(bit);
|
||||||
|
else
|
||||||
|
if (chunks.back().wire == bit.wire && chunks.back().offset + chunks.back().width == bit.offset)
|
||||||
|
chunks.back().width++;
|
||||||
|
else
|
||||||
|
chunks.push_back(bit);
|
||||||
|
width++;
|
||||||
|
// check();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool override)
|
bool RTLIL::SigSpec::combine(RTLIL::SigSpec signal, RTLIL::State freeState, bool override)
|
||||||
|
@ -1469,6 +1511,25 @@ bool RTLIL::SigSpec::match(std::string pattern) const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_set() const
|
||||||
|
{
|
||||||
|
std::set<RTLIL::SigBit> sigbits;
|
||||||
|
for (auto &c : chunks)
|
||||||
|
for (int i = 0; i < c.width; i++)
|
||||||
|
sigbits.insert(RTLIL::SigBit(c, i));
|
||||||
|
return sigbits;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RTLIL::SigBit> RTLIL::SigSpec::to_sigbit_vector() const
|
||||||
|
{
|
||||||
|
std::vector<RTLIL::SigBit> sigbits;
|
||||||
|
sigbits.reserve(width);
|
||||||
|
for (auto &c : chunks)
|
||||||
|
for (int i = 0; i < c.width; i++)
|
||||||
|
sigbits.push_back(RTLIL::SigBit(c, i));
|
||||||
|
return sigbits;
|
||||||
|
}
|
||||||
|
|
||||||
static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
|
static void sigspec_parse_split(std::vector<std::string> &tokens, const std::string &text, char sep)
|
||||||
{
|
{
|
||||||
size_t start = 0, end = 0;
|
size_t start = 0, end = 0;
|
||||||
|
|
|
@ -58,6 +58,7 @@ namespace RTLIL
|
||||||
struct Memory;
|
struct Memory;
|
||||||
struct Cell;
|
struct Cell;
|
||||||
struct SigChunk;
|
struct SigChunk;
|
||||||
|
struct SigBit;
|
||||||
struct SigSpec;
|
struct SigSpec;
|
||||||
struct CaseRule;
|
struct CaseRule;
|
||||||
struct SwitchRule;
|
struct SwitchRule;
|
||||||
|
@ -309,6 +310,7 @@ struct RTLIL::SigChunk {
|
||||||
SigChunk(const std::string &str);
|
SigChunk(const std::string &str);
|
||||||
SigChunk(int val, int width = 32);
|
SigChunk(int val, int width = 32);
|
||||||
SigChunk(RTLIL::State bit, int width = 1);
|
SigChunk(RTLIL::State bit, int width = 1);
|
||||||
|
SigChunk(RTLIL::SigBit bit);
|
||||||
RTLIL::SigChunk extract(int offset, int length) const;
|
RTLIL::SigChunk extract(int offset, int length) const;
|
||||||
bool operator <(const RTLIL::SigChunk &other) const;
|
bool operator <(const RTLIL::SigChunk &other) const;
|
||||||
bool operator ==(const RTLIL::SigChunk &other) const;
|
bool operator ==(const RTLIL::SigChunk &other) const;
|
||||||
|
@ -316,6 +318,28 @@ struct RTLIL::SigChunk {
|
||||||
static bool compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b);
|
static bool compare(const RTLIL::SigChunk &a, const RTLIL::SigChunk &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RTLIL::SigBit {
|
||||||
|
RTLIL::Wire *wire;
|
||||||
|
RTLIL::State data;
|
||||||
|
int offset;
|
||||||
|
SigBit() : wire(NULL), data(RTLIL::State::S0), offset(0) { }
|
||||||
|
SigBit(RTLIL::State bit) : wire(NULL), data(bit), offset(0) { }
|
||||||
|
SigBit(RTLIL::Wire *wire) : wire(wire), data(RTLIL::State::S0), offset(0) { assert(!wire || wire->width == 1); }
|
||||||
|
SigBit(RTLIL::Wire *wire, int offset) : wire(wire), data(RTLIL::State::S0), offset(offset) { }
|
||||||
|
SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[0]), offset(chunk.offset) { assert(chunk.width == 1); }
|
||||||
|
SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire), data(chunk.wire ? RTLIL::State::S0 : chunk.data.bits[index]), offset(chunk.wire ? chunk.offset + index : 0) { }
|
||||||
|
SigBit(const RTLIL::SigSpec &sig);
|
||||||
|
bool operator <(const RTLIL::SigBit &other) const {
|
||||||
|
return (wire != other.wire) ? (wire < other.wire) : wire ? (offset < other.offset) : (data < other.data);
|
||||||
|
}
|
||||||
|
bool operator ==(const RTLIL::SigBit &other) const {
|
||||||
|
return (wire == other.wire) && (wire ? (offset == other.offset) : (data == other.data));
|
||||||
|
}
|
||||||
|
bool operator !=(const RTLIL::SigBit &other) const {
|
||||||
|
return (wire != other.wire) || (wire ? (offset != other.offset) : (data != other.data));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct RTLIL::SigSpec {
|
struct RTLIL::SigSpec {
|
||||||
std::vector<RTLIL::SigChunk> chunks; // LSB at index 0
|
std::vector<RTLIL::SigChunk> chunks; // LSB at index 0
|
||||||
int width;
|
int width;
|
||||||
|
@ -326,6 +350,8 @@ struct RTLIL::SigSpec {
|
||||||
SigSpec(const std::string &str);
|
SigSpec(const std::string &str);
|
||||||
SigSpec(int val, int width = 32);
|
SigSpec(int val, int width = 32);
|
||||||
SigSpec(RTLIL::State bit, int width = 1);
|
SigSpec(RTLIL::State bit, int width = 1);
|
||||||
|
SigSpec(RTLIL::SigBit bit, int width = 1);
|
||||||
|
SigSpec(std::vector<RTLIL::SigBit> bits);
|
||||||
void expand();
|
void expand();
|
||||||
void optimize();
|
void optimize();
|
||||||
void sort();
|
void sort();
|
||||||
|
@ -341,6 +367,7 @@ struct RTLIL::SigSpec {
|
||||||
void remove(int offset, int length);
|
void remove(int offset, int length);
|
||||||
RTLIL::SigSpec extract(int offset, int length) const;
|
RTLIL::SigSpec extract(int offset, int length) const;
|
||||||
void append(const RTLIL::SigSpec &signal);
|
void append(const RTLIL::SigSpec &signal);
|
||||||
|
void append_bit(const RTLIL::SigBit &bit);
|
||||||
bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool override = false);
|
bool combine(RTLIL::SigSpec signal, RTLIL::State freeState = RTLIL::State::Sz, bool override = false);
|
||||||
void extend(int width, bool is_signed = false);
|
void extend(int width, bool is_signed = false);
|
||||||
void extend_u0(int width, bool is_signed = false);
|
void extend_u0(int width, bool is_signed = false);
|
||||||
|
@ -357,10 +384,17 @@ struct RTLIL::SigSpec {
|
||||||
std::string as_string() const;
|
std::string as_string() const;
|
||||||
RTLIL::Const as_const() const;
|
RTLIL::Const as_const() const;
|
||||||
bool match(std::string pattern) const;
|
bool match(std::string pattern) const;
|
||||||
|
std::set<RTLIL::SigBit> to_sigbit_set() const;
|
||||||
|
std::vector<RTLIL::SigBit> to_sigbit_vector() const;
|
||||||
static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
|
static bool parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
|
||||||
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
|
static bool parse_rhs(const RTLIL::SigSpec &lhs, RTLIL::SigSpec &sig, RTLIL::Module *module, std::string str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline RTLIL::SigBit::SigBit(const RTLIL::SigSpec &sig) {
|
||||||
|
assert(sig.width == 1 && sig.chunks.size() == 1);
|
||||||
|
*this = SigBit(sig.chunks[0]);
|
||||||
|
}
|
||||||
|
|
||||||
struct RTLIL::CaseRule {
|
struct RTLIL::CaseRule {
|
||||||
std::vector<RTLIL::SigSpec> compare;
|
std::vector<RTLIL::SigSpec> compare;
|
||||||
std::vector<RTLIL::SigSig> actions;
|
std::vector<RTLIL::SigSig> actions;
|
||||||
|
|
Loading…
Reference in New Issue