mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-21 06:35:49 +00:00
Merge branch 'YosysHQ:main' into main
This commit is contained in:
commit
439d859bba
7 changed files with 255 additions and 27 deletions
|
|
@ -1750,7 +1750,38 @@ skip_identity:
|
|||
else if (inA == inB)
|
||||
ACTION_DO(ID::Y, cell->getPort(ID::A));
|
||||
}
|
||||
if (cell->type == ID($pow) && cell->getPort(ID::A).is_fully_const() && !cell->parameters[ID::B_SIGNED].as_bool()) {
|
||||
SigSpec sig_a = assign_map(cell->getPort(ID::A));
|
||||
SigSpec sig_y = assign_map(cell->getPort(ID::Y));
|
||||
int y_size = GetSize(sig_y);
|
||||
|
||||
int bit_idx;
|
||||
const auto onehot = sig_a.is_onehot(&bit_idx);
|
||||
|
||||
if (onehot) {
|
||||
if (bit_idx == 1) {
|
||||
log_debug("Replacing pow cell `%s' in module `%s' with left-shift\n",
|
||||
cell->name.c_str(), module->name.c_str());
|
||||
cell->type = ID($shl);
|
||||
cell->parameters[ID::A_WIDTH] = 1;
|
||||
cell->setPort(ID::A, Const(State::S1, 1));
|
||||
}
|
||||
else {
|
||||
log_debug("Replacing pow cell `%s' in module `%s' with multiply and left-shift\n",
|
||||
cell->name.c_str(), module->name.c_str());
|
||||
cell->type = ID($mul);
|
||||
cell->parameters[ID::A_SIGNED] = 0;
|
||||
cell->setPort(ID::A, Const(bit_idx, cell->parameters[ID::A_WIDTH].as_int()));
|
||||
|
||||
SigSpec y_wire = module->addWire(NEW_ID, y_size);
|
||||
cell->setPort(ID::Y, y_wire);
|
||||
|
||||
module->addShl(NEW_ID, Const(State::S1, 1), y_wire, sig_y);
|
||||
}
|
||||
did_something = true;
|
||||
goto next_cell;
|
||||
}
|
||||
}
|
||||
if (!keepdc && cell->type == ID($mul))
|
||||
{
|
||||
bool a_signed = cell->parameters[ID::A_SIGNED].as_bool();
|
||||
|
|
|
|||
|
|
@ -32,6 +32,61 @@
|
|||
|
||||
using namespace Yosys;
|
||||
|
||||
bool LibertyInputStream::extend_buffer_once()
|
||||
{
|
||||
if (eof)
|
||||
return false;
|
||||
|
||||
// To support unget we leave the last already read character in the buffer
|
||||
if (buf_pos > 1) {
|
||||
size_t move_pos = buf_pos - 1;
|
||||
memmove(buffer.data(), buffer.data() + move_pos, buf_end - move_pos);
|
||||
buf_pos -= move_pos;
|
||||
buf_end -= move_pos;
|
||||
}
|
||||
|
||||
const size_t chunk_size = 4096;
|
||||
if (buffer.size() < buf_end + chunk_size) {
|
||||
buffer.resize(buf_end + chunk_size);
|
||||
}
|
||||
|
||||
size_t read_size = f.rdbuf()->sgetn(buffer.data() + buf_end, chunk_size);
|
||||
buf_end += read_size;
|
||||
if (read_size < chunk_size)
|
||||
eof = true;
|
||||
return read_size != 0;
|
||||
}
|
||||
|
||||
bool LibertyInputStream::extend_buffer_at_least(size_t size) {
|
||||
while (buffered_size() < size) {
|
||||
if (!extend_buffer_once())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int LibertyInputStream::get_cold()
|
||||
{
|
||||
if (buf_pos == buf_end) {
|
||||
if (!extend_buffer_at_least())
|
||||
return EOF;
|
||||
}
|
||||
|
||||
int c = buffer[buf_pos];
|
||||
buf_pos += 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
int LibertyInputStream::peek_cold(size_t offset)
|
||||
{
|
||||
if (buf_pos + offset >= buf_end) {
|
||||
if (!extend_buffer_at_least(offset + 1))
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return buffer[buf_pos + offset];
|
||||
}
|
||||
|
||||
LibertyAst::~LibertyAst()
|
||||
{
|
||||
for (auto child : children)
|
||||
|
|
@ -237,15 +292,19 @@ int LibertyParser::lexer(std::string &str)
|
|||
|
||||
// search for identifiers, numbers, plus or minus.
|
||||
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.') {
|
||||
str = static_cast<char>(c);
|
||||
while (1) {
|
||||
c = f.get();
|
||||
f.unget();
|
||||
size_t i = 1;
|
||||
while (true) {
|
||||
c = f.peek(i);
|
||||
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.')
|
||||
str += c;
|
||||
i += 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
f.unget();
|
||||
str.clear();
|
||||
str.append(f.buffered_data(), f.buffered_data() + i);
|
||||
f.consume(i);
|
||||
|
||||
if (str == "+" || str == "-") {
|
||||
/* Single operator is not an identifier */
|
||||
// fprintf(stderr, "LEX: char >>%s<<\n", str.c_str());
|
||||
|
|
@ -260,23 +319,24 @@ int LibertyParser::lexer(std::string &str)
|
|||
// if it wasn't an identifer, number of array range,
|
||||
// maybe it's a string?
|
||||
if (c == '"') {
|
||||
str = "";
|
||||
#ifdef FILTERLIB
|
||||
str += c;
|
||||
#endif
|
||||
while (1) {
|
||||
c = f.get();
|
||||
if (c == '\n')
|
||||
line++;
|
||||
if (c == '"') {
|
||||
#ifdef FILTERLIB
|
||||
str += c;
|
||||
#endif
|
||||
size_t i = 0;
|
||||
while (true) {
|
||||
c = f.peek(i);
|
||||
line += (c == '\n');
|
||||
if (c != '"')
|
||||
i += 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
str += c;
|
||||
}
|
||||
// fprintf(stderr, "LEX: string >>%s<<\n", str.c_str());
|
||||
str.clear();
|
||||
#ifdef FILTERLIB
|
||||
f.unget();
|
||||
str.append(f.buffered_data(), f.buffered_data() + i + 2);
|
||||
f.consume(i + 2);
|
||||
#else
|
||||
str.append(f.buffered_data(), f.buffered_data() + i);
|
||||
f.consume(i + 1);
|
||||
#endif
|
||||
return 'v';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,12 +90,54 @@ namespace Yosys
|
|||
bool eval(dict<std::string, bool>& values);
|
||||
};
|
||||
|
||||
class LibertyInputStream {
|
||||
std::istream &f;
|
||||
std::vector<char> buffer;
|
||||
size_t buf_pos = 0;
|
||||
size_t buf_end = 0;
|
||||
bool eof = false;
|
||||
|
||||
bool extend_buffer_once();
|
||||
bool extend_buffer_at_least(size_t size = 1);
|
||||
|
||||
YS_COLD int get_cold();
|
||||
YS_COLD int peek_cold(size_t offset);
|
||||
|
||||
public:
|
||||
LibertyInputStream(std::istream &f) : f(f) {}
|
||||
|
||||
size_t buffered_size() { return buf_end - buf_pos; }
|
||||
const char *buffered_data() { return buffer.data() + buf_pos; }
|
||||
|
||||
int get() {
|
||||
if (buf_pos == buf_end)
|
||||
return get_cold();
|
||||
int c = buffer[buf_pos];
|
||||
buf_pos += 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
int peek(size_t offset = 0) {
|
||||
if (buf_pos + offset >= buf_end)
|
||||
return peek_cold(offset);
|
||||
return buffer[buf_pos + offset];
|
||||
}
|
||||
|
||||
void consume(size_t n = 1) {
|
||||
buf_pos += n;
|
||||
}
|
||||
|
||||
void unget() {
|
||||
buf_pos -= 1;
|
||||
}
|
||||
};
|
||||
|
||||
class LibertyMergedCells;
|
||||
class LibertyParser
|
||||
{
|
||||
friend class LibertyMergedCells;
|
||||
private:
|
||||
std::istream &f;
|
||||
LibertyInputStream f;
|
||||
int line;
|
||||
|
||||
/* lexer return values:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue