mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-23 09:05:32 +00:00
tidy up generic functional backend, add generic scope class, tidy up c++ functional backend
This commit is contained in:
parent
39bf4f04f7
commit
eb2bb8c45b
3 changed files with 156 additions and 162 deletions
|
@ -33,7 +33,7 @@ class CellSimplifier {
|
|||
} else {
|
||||
reduced_b_width = new_width;
|
||||
T lower_b = factory.slice(b, b_width, 0, new_width);
|
||||
T overflow = factory.ugt(b, factory.constant(RTLIL::Const(y_width, b_width)), b_width);
|
||||
T overflow = factory.unsigned_greater_than(b, factory.constant(RTLIL::Const(y_width, b_width)), b_width);
|
||||
return factory.mux(lower_b, factory.constant(RTLIL::Const(y_width, new_width)), overflow, new_width);
|
||||
}
|
||||
}
|
||||
|
@ -102,17 +102,17 @@ public:
|
|||
T a = extend(inputs.at(ID(A)), a_width, width, is_signed);
|
||||
T b = extend(inputs.at(ID(B)), b_width, width, is_signed);
|
||||
if(cellType.in({ID($eq), ID($eqx)}))
|
||||
return extend(factory.eq(a, b, width), 1, y_width, false);
|
||||
return extend(factory.equal(a, b, width), 1, y_width, false);
|
||||
else if(cellType.in({ID($ne), ID($nex)}))
|
||||
return extend(factory.ne(a, b, width), 1, y_width, false);
|
||||
return extend(factory.not_equal(a, b, width), 1, y_width, false);
|
||||
else if(cellType == ID($lt))
|
||||
return extend(is_signed ? factory.gt(b, a, width) : factory.ugt(b, a, width), 1, y_width, false);
|
||||
return extend(is_signed ? factory.signed_greater_than(b, a, width) : factory.unsigned_greater_than(b, a, width), 1, y_width, false);
|
||||
else if(cellType == ID($le))
|
||||
return extend(is_signed ? factory.ge(b, a, width) : factory.uge(b, a, width), 1, y_width, false);
|
||||
return extend(is_signed ? factory.signed_greater_equal(b, a, width) : factory.unsigned_greater_equal(b, a, width), 1, y_width, false);
|
||||
else if(cellType == ID($gt))
|
||||
return extend(is_signed ? factory.gt(a, b, width) : factory.ugt(a, b, width), 1, y_width, false);
|
||||
return extend(is_signed ? factory.signed_greater_than(a, b, width) : factory.unsigned_greater_than(a, b, width), 1, y_width, false);
|
||||
else if(cellType == ID($ge))
|
||||
return extend(is_signed ? factory.ge(a, b, width) : factory.uge(a, b, width), 1, y_width, false);
|
||||
return extend(is_signed ? factory.signed_greater_equal(a, b, width) : factory.unsigned_greater_equal(a, b, width), 1, y_width, false);
|
||||
else
|
||||
log_abort();
|
||||
}else if(cellType.in({ID($logic_or), ID($logic_and)})){
|
||||
|
@ -127,7 +127,7 @@ public:
|
|||
return extend(inputs.at(ID(A)), a_width, y_width, a_signed);
|
||||
}else if(cellType == ID($neg)){
|
||||
T a = extend(inputs.at(ID(A)), a_width, y_width, a_signed);
|
||||
return factory.neg(a, y_width);
|
||||
return factory.unary_minus(a, y_width);
|
||||
}else if(cellType == ID($logic_not)){
|
||||
T a = reduce_or(inputs.at(ID(A)), a_width);
|
||||
T y = factory.bitwise_not(a, 1);
|
||||
|
@ -161,7 +161,7 @@ public:
|
|||
T shr = logical_shift_right(a, b, width, b_width);
|
||||
if(b_signed) {
|
||||
T sign_b = factory.slice(b, b_width, b_width - 1, 1);
|
||||
T shl = logical_shift_left(a, factory.neg(b, b_width), width, b_width);
|
||||
T shl = logical_shift_left(a, factory.unary_minus(b, b_width), width, b_width);
|
||||
T y = factory.mux(shr, shl, sign_b, width);
|
||||
return extend(y, width, y_width, false);
|
||||
} else {
|
||||
|
@ -237,10 +237,10 @@ public:
|
|||
if(results.size() == 0)
|
||||
return factory.undriven(0);
|
||||
T node = results[0];
|
||||
int size = results[0].size();
|
||||
int size = results[0].width();
|
||||
for(size_t i = 1; i < results.size(); i++) {
|
||||
node = factory.concat(node, size, results[i], results[i].size());
|
||||
size += results[i].size();
|
||||
node = factory.concat(node, size, results[i], results[i].width());
|
||||
size += results[i].width();
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
@ -405,6 +405,13 @@ void FunctionalIR::topological_sort() {
|
|||
if(scc) log_error("combinational loops, aborting\n");
|
||||
}
|
||||
|
||||
IdString merge_name(IdString a, IdString b) {
|
||||
if(a[0] == '$' && b[0] == '\\')
|
||||
return b;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
void FunctionalIR::forward_buf() {
|
||||
std::vector<int> perm, alias;
|
||||
perm.clear();
|
||||
|
@ -416,10 +423,15 @@ void FunctionalIR::forward_buf() {
|
|||
{
|
||||
int target_index = alias[node.arg(0).index()];
|
||||
auto target_node = _graph[perm[target_index]];
|
||||
if(!target_node.has_sparse_attr() && node.has_sparse_attr()){
|
||||
IdString id = node.sparse_attr();
|
||||
target_node.sparse_attr() = id;
|
||||
}
|
||||
if(node.has_sparse_attr()) {
|
||||
if(target_node.has_sparse_attr()) {
|
||||
IdString id = merge_name(node.sparse_attr(), target_node.sparse_attr());
|
||||
target_node.sparse_attr() = id;
|
||||
} else {
|
||||
IdString id = node.sparse_attr();
|
||||
target_node.sparse_attr() = id;
|
||||
}
|
||||
}
|
||||
alias.push_back(target_index);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -29,6 +29,58 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
||||
namespace FunctionalTools {
|
||||
class Scope {
|
||||
const char *_illegal_characters;
|
||||
pool<std::string> _used_names;
|
||||
dict<int, std::string> _by_id;
|
||||
dict<IdString, std::string> _by_name;
|
||||
std::string allocate_name(IdString suggestion) {
|
||||
std::string str = RTLIL::unescape_id(suggestion);
|
||||
for(size_t i = 0; i < str.size(); i++)
|
||||
if(strchr(_illegal_characters, str[i]))
|
||||
str[i] = '_';
|
||||
if(_used_names.count(str) == 0) {
|
||||
_used_names.insert(str);
|
||||
return str;
|
||||
}
|
||||
for (int idx = 0 ; ; idx++){
|
||||
std::string suffixed = str + "_" + std::to_string(idx);
|
||||
if(_used_names.count(suffixed) == 0) {
|
||||
_used_names.insert(suffixed);
|
||||
return suffixed;
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
Scope(const char *illegal_characters = "", const char **keywords = nullptr) {
|
||||
_illegal_characters = illegal_characters;
|
||||
if(keywords != nullptr)
|
||||
for(const char **p = keywords; *p != nullptr; p++)
|
||||
reserve(*p);
|
||||
}
|
||||
void reserve(std::string name) {
|
||||
_used_names.insert(std::move(name));
|
||||
}
|
||||
std::string operator()(int id, IdString suggestion) {
|
||||
auto it = _by_id.find(id);
|
||||
if(it != _by_id.end())
|
||||
return it->second;
|
||||
std::string str = allocate_name(suggestion);
|
||||
_by_id.insert({id, str});
|
||||
return str;
|
||||
}
|
||||
std::string operator()(IdString idstring) {
|
||||
auto it = _by_name.find(idstring);
|
||||
if(it != _by_name.end())
|
||||
return it->second;
|
||||
std::string str = allocate_name(idstring);
|
||||
_by_name.insert({idstring, str});
|
||||
return str;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class FunctionalIR {
|
||||
enum class Fn {
|
||||
invalid,
|
||||
|
@ -133,7 +185,7 @@ public:
|
|||
friend class Factory;
|
||||
friend class FunctionalIR;
|
||||
Graph::Ref _ref;
|
||||
Node(Graph::Ref ref) : _ref(ref) { }
|
||||
explicit Node(Graph::Ref ref) : _ref(ref) { }
|
||||
operator Graph::Ref() { return _ref; }
|
||||
template<class NodePrinter> struct PrintVisitor {
|
||||
NodePrinter np;
|
||||
|
@ -225,7 +277,6 @@ public:
|
|||
{
|
||||
return visit(PrintVisitor(np));
|
||||
}
|
||||
/* TODO: delete */ int size() const { return sort().width(); }
|
||||
};
|
||||
class Factory {
|
||||
FunctionalIR &_ir;
|
||||
|
@ -235,7 +286,7 @@ public:
|
|||
Graph::Ref ref = _ir._graph.add(std::move(fn), {std::move(sort)});
|
||||
for (auto arg : args)
|
||||
ref.append_arg(Graph::Ref(arg));
|
||||
return ref;
|
||||
return Node(ref);
|
||||
}
|
||||
void check_basic_binary(Node const &a, Node const &b) { log_assert(a.sort().is_signal() && a.sort() == b.sort()); }
|
||||
void check_shift(Node const &a, Node const &b) { log_assert(a.sort().is_signal() && b.sort().is_signal()); }
|
||||
|
@ -341,39 +392,30 @@ public:
|
|||
void suggest_name(Node node, IdString name) {
|
||||
node._ref.sparse_attr() = name;
|
||||
}
|
||||
|
||||
/* TODO delete this later*/
|
||||
Node eq(Node a, Node b, int) { return equal(a, b, 0); }
|
||||
Node ne(Node a, Node b, int) { return not_equal(a, b, 0); }
|
||||
Node gt(Node a, Node b, int) { return signed_greater_than(a, b, 0); }
|
||||
Node ge(Node a, Node b, int) { return signed_greater_equal(a, b, 0); }
|
||||
Node ugt(Node a, Node b, int) { return unsigned_greater_than(a, b, 0); }
|
||||
Node uge(Node a, Node b, int) { return unsigned_greater_equal(a, b, 0); }
|
||||
Node neg(Node a, int) { return unary_minus(a, 0); }
|
||||
};
|
||||
static FunctionalIR from_module(Module *module);
|
||||
Factory factory() { return Factory(*this); }
|
||||
int size() const { return _graph.size(); }
|
||||
Node operator[](int i) { return _graph[i]; }
|
||||
Node operator[](int i) { return Node(_graph[i]); }
|
||||
void topological_sort();
|
||||
void forward_buf();
|
||||
dict<IdString, Sort> inputs() const { return _inputs; }
|
||||
dict<IdString, Sort> outputs() const { return _outputs; }
|
||||
dict<IdString, Sort> state() const { return _state; }
|
||||
Node get_output_node(IdString name) { return _graph({name, false}); }
|
||||
Node get_state_next_node(IdString name) { return _graph({name, true}); }
|
||||
Node get_output_node(IdString name) { return Node(_graph({name, false})); }
|
||||
Node get_state_next_node(IdString name) { return Node(_graph({name, true})); }
|
||||
class Iterator {
|
||||
friend class FunctionalIR;
|
||||
FunctionalIR &_ir;
|
||||
FunctionalIR *_ir;
|
||||
int _index;
|
||||
Iterator(FunctionalIR &ir, int index) : _ir(ir), _index(index) {}
|
||||
Iterator(FunctionalIR *ir, int index) : _ir(ir), _index(index) {}
|
||||
public:
|
||||
Node operator*() { return _ir._graph[_index]; }
|
||||
Node operator*() { return Node(_ir->_graph[_index]); }
|
||||
Iterator &operator++() { _index++; return *this; }
|
||||
bool operator!=(Iterator const &other) const { return _index != other._index; }
|
||||
};
|
||||
Iterator begin() { return Iterator(*this, 0); }
|
||||
Iterator end() { return Iterator(*this, _graph.size()); }
|
||||
Iterator begin() { return Iterator(this, 0); }
|
||||
Iterator end() { return Iterator(this, _graph.size()); }
|
||||
};
|
||||
|
||||
YOSYS_NAMESPACE_END
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue