aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cellaigs.cc198
-rw-r--r--kernel/celledges.cc42
-rw-r--r--kernel/celledges.h6
-rw-r--r--kernel/celltypes.h300
-rw-r--r--kernel/consteval.h100
-rw-r--r--kernel/cost.h126
-rw-r--r--kernel/driver.cc175
-rw-r--r--kernel/hashlib.h6
-rw-r--r--kernel/log.cc169
-rw-r--r--kernel/log.h65
-rw-r--r--kernel/macc.h62
-rw-r--r--kernel/modtools.h10
-rw-r--r--kernel/register.cc198
-rw-r--r--kernel/register.h26
-rw-r--r--kernel/rtlil.cc1484
-rw-r--r--kernel/rtlil.h340
-rw-r--r--kernel/satgen.h528
-rw-r--r--kernel/sigtools.h11
-rw-r--r--kernel/yosys.cc312
-rw-r--r--kernel/yosys.h40
20 files changed, 2757 insertions, 1441 deletions
diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc
index 5fd76afe5..02854edb2 100644
--- a/kernel/cellaigs.cc
+++ b/kernel/cellaigs.cc
@@ -268,9 +268,9 @@ Aig::Aig(Cell *cell)
cell->parameters.sort();
for (auto p : cell->parameters)
{
- if (p.first == "\\A_WIDTH" && mkname_a_signed) {
+ if (p.first == ID(A_WIDTH) && mkname_a_signed) {
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
- } else if (p.first == "\\B_WIDTH" && mkname_b_signed) {
+ } else if (p.first == ID(B_WIDTH) && mkname_b_signed) {
name = mkname_last + stringf(":%d%c", p.second.as_int(), mkname_is_signed ? 'S' : 'U');
} else {
mkname_last = name;
@@ -280,181 +280,183 @@ Aig::Aig(Cell *cell)
mkname_a_signed = false;
mkname_b_signed = false;
mkname_is_signed = false;
- if (p.first == "\\A_SIGNED") {
+ if (p.first == ID(A_SIGNED)) {
mkname_a_signed = true;
mkname_is_signed = p.second.as_bool();
}
- if (p.first == "\\B_SIGNED") {
+ if (p.first == ID(B_SIGNED)) {
mkname_b_signed = true;
mkname_is_signed = p.second.as_bool();
}
}
- if (cell->type.in("$not", "$_NOT_", "$pos", "$_BUF_"))
+ if (cell->type.in(ID($not), ID($_NOT_), ID($pos), ID($_BUF_)))
{
- for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
- int A = mk.inport("\\A", i);
- int Y = cell->type.in("$not", "$_NOT_") ? mk.not_gate(A) : A;
- mk.outport(Y, "\\Y", i);
+ for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
+ int A = mk.inport(ID::A, i);
+ int Y = cell->type.in(ID($not), ID($_NOT_)) ? mk.not_gate(A) : A;
+ mk.outport(Y, ID::Y, i);
}
goto optimize;
}
- if (cell->type.in("$and", "$_AND_", "$_NAND_", "$or", "$_OR_", "$_NOR_", "$xor", "$xnor", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_"))
- {
- for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
- int A = mk.inport("\\A", i);
- int B = mk.inport("\\B", i);
- int Y = cell->type.in("$and", "$_AND_") ? mk.and_gate(A, B) :
- cell->type.in("$_NAND_") ? mk.nand_gate(A, B) :
- cell->type.in("$or", "$_OR_") ? mk.or_gate(A, B) :
- cell->type.in("$_NOR_") ? mk.nor_gate(A, B) :
- cell->type.in("$xor", "$_XOR_") ? mk.xor_gate(A, B) :
- cell->type.in("$xnor", "$_XNOR_") ? mk.xnor_gate(A, B) :
- cell->type.in("$_ANDNOT_") ? mk.andnot_gate(A, B) :
- cell->type.in("$_ORNOT_") ? mk.ornot_gate(A, B) : -1;
- mk.outport(Y, "\\Y", i);
+ if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_), ID($or), ID($_OR_), ID($_NOR_), ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_)))
+ {
+ for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
+ int A = mk.inport(ID::A, i);
+ int B = mk.inport(ID::B, i);
+ int Y = cell->type.in(ID($and), ID($_AND_)) ? mk.and_gate(A, B) :
+ cell->type.in(ID($_NAND_)) ? mk.nand_gate(A, B) :
+ cell->type.in(ID($or), ID($_OR_)) ? mk.or_gate(A, B) :
+ cell->type.in(ID($_NOR_)) ? mk.nor_gate(A, B) :
+ cell->type.in(ID($xor), ID($_XOR_)) ? mk.xor_gate(A, B) :
+ cell->type.in(ID($xnor), ID($_XNOR_)) ? mk.xnor_gate(A, B) :
+ cell->type.in(ID($_ANDNOT_)) ? mk.andnot_gate(A, B) :
+ cell->type.in(ID($_ORNOT_)) ? mk.ornot_gate(A, B) : -1;
+ mk.outport(Y, ID::Y, i);
}
goto optimize;
}
- if (cell->type.in("$mux", "$_MUX_"))
+ if (cell->type.in(ID($mux), ID($_MUX_)))
{
- int S = mk.inport("\\S");
- for (int i = 0; i < GetSize(cell->getPort("\\Y")); i++) {
- int A = mk.inport("\\A", i);
- int B = mk.inport("\\B", i);
+ int S = mk.inport(ID(S));
+ for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) {
+ int A = mk.inport(ID::A, i);
+ int B = mk.inport(ID::B, i);
int Y = mk.mux_gate(A, B, S);
- mk.outport(Y, "\\Y", i);
+ if (cell->type == ID($_NMUX_))
+ Y = mk.not_gate(Y);
+ mk.outport(Y, ID::Y, i);
}
goto optimize;
}
- if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool"))
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool)))
{
- int Y = mk.inport("\\A", 0);
- for (int i = 1; i < GetSize(cell->getPort("\\A")); i++) {
- int A = mk.inport("\\A", i);
- if (cell->type == "$reduce_and") Y = mk.and_gate(A, Y);
- if (cell->type == "$reduce_or") Y = mk.or_gate(A, Y);
- if (cell->type == "$reduce_bool") Y = mk.or_gate(A, Y);
- if (cell->type == "$reduce_xor") Y = mk.xor_gate(A, Y);
- if (cell->type == "$reduce_xnor") Y = mk.xor_gate(A, Y);
+ int Y = mk.inport(ID::A, 0);
+ for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++) {
+ int A = mk.inport(ID::A, i);
+ if (cell->type == ID($reduce_and)) Y = mk.and_gate(A, Y);
+ if (cell->type == ID($reduce_or)) Y = mk.or_gate(A, Y);
+ if (cell->type == ID($reduce_bool)) Y = mk.or_gate(A, Y);
+ if (cell->type == ID($reduce_xor)) Y = mk.xor_gate(A, Y);
+ if (cell->type == ID($reduce_xnor)) Y = mk.xor_gate(A, Y);
}
- if (cell->type == "$reduce_xnor")
+ if (cell->type == ID($reduce_xnor))
Y = mk.not_gate(Y);
- mk.outport(Y, "\\Y", 0);
- for (int i = 1; i < GetSize(cell->getPort("\\Y")); i++)
- mk.outport(mk.bool_node(false), "\\Y", i);
+ mk.outport(Y, ID::Y, 0);
+ for (int i = 1; i < GetSize(cell->getPort(ID::Y)); i++)
+ mk.outport(mk.bool_node(false), ID::Y, i);
goto optimize;
}
- if (cell->type.in("$logic_not", "$logic_and", "$logic_or"))
+ if (cell->type.in(ID($logic_not), ID($logic_and), ID($logic_or)))
{
- int A = mk.inport("\\A", 0), Y = -1;
- for (int i = 1; i < GetSize(cell->getPort("\\A")); i++)
- A = mk.or_gate(mk.inport("\\A", i), A);
- if (cell->type.in("$logic_and", "$logic_or")) {
- int B = mk.inport("\\B", 0);
- for (int i = 1; i < GetSize(cell->getPort("\\B")); i++)
- B = mk.or_gate(mk.inport("\\B", i), B);
- if (cell->type == "$logic_and") Y = mk.and_gate(A, B);
- if (cell->type == "$logic_or") Y = mk.or_gate(A, B);
+ int A = mk.inport(ID::A, 0), Y = -1;
+ for (int i = 1; i < GetSize(cell->getPort(ID::A)); i++)
+ A = mk.or_gate(mk.inport(ID::A, i), A);
+ if (cell->type.in(ID($logic_and), ID($logic_or))) {
+ int B = mk.inport(ID::B, 0);
+ for (int i = 1; i < GetSize(cell->getPort(ID::B)); i++)
+ B = mk.or_gate(mk.inport(ID::B, i), B);
+ if (cell->type == ID($logic_and)) Y = mk.and_gate(A, B);
+ if (cell->type == ID($logic_or)) Y = mk.or_gate(A, B);
} else {
- if (cell->type == "$logic_not") Y = mk.not_gate(A);
+ if (cell->type == ID($logic_not)) Y = mk.not_gate(A);
}
- mk.outport_bool(Y, "\\Y");
+ mk.outport_bool(Y, ID::Y);
goto optimize;
}
- if (cell->type.in("$add", "$sub"))
+ if (cell->type.in(ID($add), ID($sub)))
{
- int width = GetSize(cell->getPort("\\Y"));
- vector<int> A = mk.inport_vec("\\A", width);
- vector<int> B = mk.inport_vec("\\B", width);
+ int width = GetSize(cell->getPort(ID::Y));
+ vector<int> A = mk.inport_vec(ID::A, width);
+ vector<int> B = mk.inport_vec(ID::B, width);
int carry = mk.bool_node(false);
- if (cell->type == "$sub") {
+ if (cell->type == ID($sub)) {
for (auto &n : B)
n = mk.not_gate(n);
carry = mk.not_gate(carry);
}
vector<int> Y = mk.adder(A, B, carry);
- mk.outport_vec(Y, "\\Y");
+ mk.outport_vec(Y, ID::Y);
goto optimize;
}
- if (cell->type == "$alu")
+ if (cell->type == ID($alu))
{
- int width = GetSize(cell->getPort("\\Y"));
- vector<int> A = mk.inport_vec("\\A", width);
- vector<int> B = mk.inport_vec("\\B", width);
- int carry = mk.inport("\\CI");
- int binv = mk.inport("\\BI");
+ int width = GetSize(cell->getPort(ID::Y));
+ vector<int> A = mk.inport_vec(ID::A, width);
+ vector<int> B = mk.inport_vec(ID::B, width);
+ int carry = mk.inport(ID(CI));
+ int binv = mk.inport(ID(BI));
for (auto &n : B)
n = mk.xor_gate(n, binv);
vector<int> X(width), CO(width);
vector<int> Y = mk.adder(A, B, carry, &X, &CO);
for (int i = 0; i < width; i++)
X[i] = mk.xor_gate(A[i], B[i]);
- mk.outport_vec(Y, "\\Y");
- mk.outport_vec(X, "\\X");
- mk.outport_vec(CO, "\\CO");
+ mk.outport_vec(Y, ID::Y);
+ mk.outport_vec(X, ID(X));
+ mk.outport_vec(CO, ID(CO));
goto optimize;
}
- if (cell->type.in("$eq", "$ne"))
+ if (cell->type.in(ID($eq), ID($ne)))
{
- int width = max(GetSize(cell->getPort("\\A")), GetSize(cell->getPort("\\B")));
- vector<int> A = mk.inport_vec("\\A", width);
- vector<int> B = mk.inport_vec("\\B", width);
+ int width = max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B)));
+ vector<int> A = mk.inport_vec(ID::A, width);
+ vector<int> B = mk.inport_vec(ID::B, width);
int Y = mk.bool_node(false);
for (int i = 0; i < width; i++)
Y = mk.or_gate(Y, mk.xor_gate(A[i], B[i]));
- if (cell->type == "$eq")
+ if (cell->type == ID($eq))
Y = mk.not_gate(Y);
- mk.outport_bool(Y, "\\Y");
+ mk.outport_bool(Y, ID::Y);
goto optimize;
}
- if (cell->type == "$_AOI3_")
+ if (cell->type == ID($_AOI3_))
{
- int A = mk.inport("\\A");
- int B = mk.inport("\\B");
- int C = mk.inport("\\C");
+ int A = mk.inport(ID::A);
+ int B = mk.inport(ID::B);
+ int C = mk.inport(ID(C));
int Y = mk.nor_gate(mk.and_gate(A, B), C);
- mk.outport(Y, "\\Y");
+ mk.outport(Y, ID::Y);
goto optimize;
}
- if (cell->type == "$_OAI3_")
+ if (cell->type == ID($_OAI3_))
{
- int A = mk.inport("\\A");
- int B = mk.inport("\\B");
- int C = mk.inport("\\C");
+ int A = mk.inport(ID::A);
+ int B = mk.inport(ID::B);
+ int C = mk.inport(ID(C));
int Y = mk.nand_gate(mk.or_gate(A, B), C);
- mk.outport(Y, "\\Y");
+ mk.outport(Y, ID::Y);
goto optimize;
}
- if (cell->type == "$_AOI4_")
+ if (cell->type == ID($_AOI4_))
{
- int A = mk.inport("\\A");
- int B = mk.inport("\\B");
- int C = mk.inport("\\C");
- int D = mk.inport("\\D");
+ int A = mk.inport(ID::A);
+ int B = mk.inport(ID::B);
+ int C = mk.inport(ID(C));
+ int D = mk.inport(ID(D));
int Y = mk.nor_gate(mk.and_gate(A, B), mk.and_gate(C, D));
- mk.outport(Y, "\\Y");
+ mk.outport(Y, ID::Y);
goto optimize;
}
- if (cell->type == "$_OAI4_")
+ if (cell->type == ID($_OAI4_))
{
- int A = mk.inport("\\A");
- int B = mk.inport("\\B");
- int C = mk.inport("\\C");
- int D = mk.inport("\\D");
- int Y = mk.nand_gate(mk.nor_gate(A, B), mk.nor_gate(C, D));
- mk.outport(Y, "\\Y");
+ int A = mk.inport(ID::A);
+ int B = mk.inport(ID::B);
+ int C = mk.inport(ID(C));
+ int D = mk.inport(ID(D));
+ int Y = mk.nand_gate(mk.or_gate(A, B), mk.or_gate(C, D));
+ mk.outport(Y, ID::Y);
goto optimize;
}
diff --git a/kernel/celledges.cc b/kernel/celledges.cc
index 556e8b826..d0bb99e83 100644
--- a/kernel/celledges.cc
+++ b/kernel/celledges.cc
@@ -24,9 +24,9 @@ PRIVATE_NAMESPACE_BEGIN
void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", Y = "\\Y";
+ IdString A = ID::A, Y = ID::Y;
- bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
+ bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int y_width = GetSize(cell->getPort(Y));
@@ -41,14 +41,14 @@ void bitwise_unary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", B = "\\B", Y = "\\Y";
+ IdString A = ID::A, B = ID::B, Y = ID::Y;
- bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
+ bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
int y_width = GetSize(cell->getPort(Y));
- if (cell->type == "$and" && !is_signed) {
+ if (cell->type == ID($and) && !is_signed) {
if (a_width > b_width)
a_width = b_width;
else
@@ -71,9 +71,9 @@ void bitwise_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", Y = "\\Y";
+ IdString A = ID::A, Y = ID::Y;
- bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
+ bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int y_width = GetSize(cell->getPort(Y));
@@ -87,14 +87,14 @@ void arith_neg_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", B = "\\B", Y = "\\Y";
+ IdString A = ID::A, B = ID::B, Y = ID::Y;
- bool is_signed = cell->getParam("\\A_SIGNED").as_bool();
+ bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
int y_width = GetSize(cell->getPort(Y));
- if (!is_signed && cell->type != "$sub") {
+ if (!is_signed && cell->type != ID($sub)) {
int ab_width = std::max(a_width, b_width);
y_width = std::min(y_width, ab_width+1);
}
@@ -114,7 +114,7 @@ void arith_binary_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", Y = "\\Y";
+ IdString A = ID::A, Y = ID::Y;
int a_width = GetSize(cell->getPort(A));
@@ -124,7 +124,7 @@ void reduce_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", B = "\\B", Y = "\\Y";
+ IdString A = ID::A, B = ID::B, Y = ID::Y;
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
@@ -138,7 +138,7 @@ void compare_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
void mux_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell)
{
- IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y";
+ IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
int a_width = GetSize(cell->getPort(A));
int b_width = GetSize(cell->getPort(B));
@@ -160,43 +160,43 @@ PRIVATE_NAMESPACE_END
bool YOSYS_NAMESPACE_PREFIX AbstractCellEdgesDatabase::add_edges_from_cell(RTLIL::Cell *cell)
{
- if (cell->type.in("$not", "$pos")) {
+ if (cell->type.in(ID($not), ID($pos))) {
bitwise_unary_op(this, cell);
return true;
}
- if (cell->type.in("$and", "$or", "$xor", "$xnor")) {
+ if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
bitwise_binary_op(this, cell);
return true;
}
- if (cell->type == "$neg") {
+ if (cell->type == ID($neg)) {
arith_neg_op(this, cell);
return true;
}
- if (cell->type.in("$add", "$sub")) {
+ if (cell->type.in(ID($add), ID($sub))) {
arith_binary_op(this, cell);
return true;
}
- if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool", "$logic_not")) {
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not))) {
reduce_op(this, cell);
return true;
}
// FIXME:
- // if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) {
+ // if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx))) {
// shift_op(this, cell);
// return true;
// }
- if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) {
+ if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
compare_op(this, cell);
return true;
}
- if (cell->type.in("$mux", "$pmux")) {
+ if (cell->type.in(ID($mux), ID($pmux))) {
mux_op(this, cell);
return true;
}
diff --git a/kernel/celledges.h b/kernel/celledges.h
index 6aab9ed43..2cc297cb2 100644
--- a/kernel/celledges.h
+++ b/kernel/celledges.h
@@ -1,4 +1,4 @@
-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
@@ -38,7 +38,7 @@ struct FwdCellEdgesDatabase : AbstractCellEdgesDatabase
dict<SigBit, pool<SigBit>> db;
FwdCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { }
- virtual void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override {
+ void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) YS_OVERRIDE {
SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]);
SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]);
db[from_sigbit].insert(to_sigbit);
@@ -51,7 +51,7 @@ struct RevCellEdgesDatabase : AbstractCellEdgesDatabase
dict<SigBit, pool<SigBit>> db;
RevCellEdgesDatabase(SigMap &sigmap) : sigmap(sigmap) { }
- virtual void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) override {
+ void add_edge(RTLIL::Cell *cell, RTLIL::IdString from_port, int from_bit, RTLIL::IdString to_port, int to_bit, int) YS_OVERRIDE {
SigBit from_sigbit = sigmap(cell->getPort(from_port)[from_bit]);
SigBit to_sigbit = sigmap(cell->getPort(to_port)[to_bit]);
db[to_sigbit].insert(from_sigbit);
diff --git a/kernel/celltypes.h b/kernel/celltypes.h
index 9f775cde7..bc96fd602 100644
--- a/kernel/celltypes.h
+++ b/kernel/celltypes.h
@@ -20,7 +20,7 @@
#ifndef CELLTYPES_H
#define CELLTYPES_H
-#include <kernel/yosys.h>
+#include "kernel/yosys.h"
YOSYS_NAMESPACE_BEGIN
@@ -82,22 +82,48 @@ struct CellTypes
void setup_internals()
{
+ setup_internals_eval();
+
+ IdString A = ID::A, B = ID::B, EN = ID(EN), Y = ID::Y;
+ IdString SRC = ID(SRC), DST = ID(DST), DAT = ID(DAT);
+ IdString EN_SRC = ID(EN_SRC), EN_DST = ID(EN_DST);
+
+ setup_type(ID($tribuf), {A, EN}, {Y}, true);
+
+ setup_type(ID($assert), {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($assume), {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($live), {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($fair), {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($cover), {A, EN}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($initstate), pool<RTLIL::IdString>(), {Y}, true);
+ setup_type(ID($anyconst), pool<RTLIL::IdString>(), {Y}, true);
+ setup_type(ID($anyseq), pool<RTLIL::IdString>(), {Y}, true);
+ setup_type(ID($allconst), pool<RTLIL::IdString>(), {Y}, true);
+ setup_type(ID($allseq), pool<RTLIL::IdString>(), {Y}, true);
+ setup_type(ID($equiv), {A, B}, {Y}, true);
+ setup_type(ID($specify2), {EN, SRC, DST}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($specify3), {EN, SRC, DST, DAT}, pool<RTLIL::IdString>(), true);
+ setup_type(ID($specrule), {EN_SRC, EN_DST, SRC, DST}, pool<RTLIL::IdString>(), true);
+ }
+
+ void setup_internals_eval()
+ {
std::vector<RTLIL::IdString> unary_ops = {
- "$not", "$pos", "$neg",
- "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
- "$logic_not", "$slice", "$lut", "$sop"
+ ID($not), ID($pos), ID($neg),
+ ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
+ ID($logic_not), ID($slice), ID($lut), ID($sop)
};
std::vector<RTLIL::IdString> binary_ops = {
- "$and", "$or", "$xor", "$xnor",
- "$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
- "$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
- "$add", "$sub", "$mul", "$div", "$mod", "$pow",
- "$logic_and", "$logic_or", "$concat", "$macc"
+ ID($and), ID($or), ID($xor), ID($xnor),
+ ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
+ ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
+ ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow),
+ ID($logic_and), ID($logic_or), ID($concat), ID($macc)
};
- IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y";
- IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X";
- IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN";
+ IdString A = ID::A, B = ID::B, S = ID(S), Y = ID::Y;
+ IdString P = ID(P), G = ID(G), C = ID(C), X = ID(X);
+ IdString BI = ID(BI), CI = ID(CI), CO = ID(CO), EN = ID(EN);
for (auto type : unary_ops)
setup_type(type, {A}, {Y}, true);
@@ -105,85 +131,91 @@ struct CellTypes
for (auto type : binary_ops)
setup_type(type, {A, B}, {Y}, true);
- for (auto type : std::vector<RTLIL::IdString>({"$mux", "$pmux"}))
+ for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)}))
setup_type(type, {A, B, S}, {Y}, true);
- setup_type("$lcu", {P, G, CI}, {CO}, true);
- setup_type("$alu", {A, B, CI, BI}, {X, Y, CO}, true);
- setup_type("$fa", {A, B, C}, {X, Y}, true);
-
- setup_type("$tribuf", {A, EN}, {Y}, true);
-
- setup_type("$assert", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$assume", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$live", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$fair", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$cover", {A, EN}, pool<RTLIL::IdString>(), true);
- setup_type("$initstate", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$anyconst", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$anyseq", pool<RTLIL::IdString>(), {Y}, true);
- setup_type("$equiv", {A, B}, {Y}, true);
+ setup_type(ID($lcu), {P, G, CI}, {CO}, true);
+ setup_type(ID($alu), {A, B, CI, BI}, {X, Y, CO}, true);
+ setup_type(ID($fa), {A, B, C}, {X, Y}, true);
+ }
+
+ void setup_internals_ff()
+ {
+ IdString SET = ID(SET), CLR = ID(CLR), CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
+ IdString Q = ID(Q), D = ID(D);
+
+ setup_type(ID($sr), {SET, CLR}, {Q});
+ setup_type(ID($ff), {D}, {Q});
+ setup_type(ID($dff), {CLK, D}, {Q});
+ setup_type(ID($dffe), {CLK, EN, D}, {Q});
+ setup_type(ID($dffsr), {CLK, SET, CLR, D}, {Q});
+ setup_type(ID($adff), {CLK, ARST, D}, {Q});
+ setup_type(ID($dlatch), {EN, D}, {Q});
+ setup_type(ID($dlatchsr), {EN, SET, CLR, D}, {Q});
+
}
void setup_internals_mem()
{
- IdString SET = "\\SET", CLR = "\\CLR", CLK = "\\CLK", ARST = "\\ARST", EN = "\\EN";
- IdString Q = "\\Q", D = "\\D", ADDR = "\\ADDR", DATA = "\\DATA", RD_EN = "\\RD_EN";
- IdString RD_CLK = "\\RD_CLK", RD_ADDR = "\\RD_ADDR", WR_CLK = "\\WR_CLK", WR_EN = "\\WR_EN";
- IdString WR_ADDR = "\\WR_ADDR", WR_DATA = "\\WR_DATA", RD_DATA = "\\RD_DATA";
- IdString CTRL_IN = "\\CTRL_IN", CTRL_OUT = "\\CTRL_OUT";
-
- setup_type("$sr", {SET, CLR}, {Q});
- setup_type("$ff", {D}, {Q});
- setup_type("$dff", {CLK, D}, {Q});
- setup_type("$dffe", {CLK, EN, D}, {Q});
- setup_type("$dffsr", {CLK, SET, CLR, D}, {Q});
- setup_type("$adff", {CLK, ARST, D}, {Q});
- setup_type("$dlatch", {EN, D}, {Q});
- setup_type("$dlatchsr", {EN, SET, CLR, D}, {Q});
-
- setup_type("$memrd", {CLK, EN, ADDR}, {DATA});
- setup_type("$memwr", {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
- setup_type("$meminit", {ADDR, DATA}, pool<RTLIL::IdString>());
- setup_type("$mem", {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
-
- setup_type("$fsm", {CLK, ARST, CTRL_IN}, {CTRL_OUT});
+ setup_internals_ff();
+
+ IdString CLK = ID(CLK), ARST = ID(ARST), EN = ID(EN);
+ IdString ADDR = ID(ADDR), DATA = ID(DATA), RD_EN = ID(RD_EN);
+ IdString RD_CLK = ID(RD_CLK), RD_ADDR = ID(RD_ADDR), WR_CLK = ID(WR_CLK), WR_EN = ID(WR_EN);
+ IdString WR_ADDR = ID(WR_ADDR), WR_DATA = ID(WR_DATA), RD_DATA = ID(RD_DATA);
+ IdString CTRL_IN = ID(CTRL_IN), CTRL_OUT = ID(CTRL_OUT);
+
+ setup_type(ID($memrd), {CLK, EN, ADDR}, {DATA});
+ setup_type(ID($memwr), {CLK, EN, ADDR, DATA}, pool<RTLIL::IdString>());
+ setup_type(ID($meminit), {ADDR, DATA}, pool<RTLIL::IdString>());
+ setup_type(ID($mem), {RD_CLK, RD_EN, RD_ADDR, WR_CLK, WR_EN, WR_ADDR, WR_DATA}, {RD_DATA});
+
+ setup_type(ID($fsm), {CLK, ARST, CTRL_IN}, {CTRL_OUT});
}
void setup_stdcells()
{
- IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D";
- IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H";
- IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L";
- IdString M = "\\I", N = "\\N", O = "\\O", P = "\\P";
- IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V";
- IdString Y = "\\Y";
-
- setup_type("$_BUF_", {A}, {Y}, true);
- setup_type("$_NOT_", {A}, {Y}, true);
- setup_type("$_AND_", {A, B}, {Y}, true);
- setup_type("$_NAND_", {A, B}, {Y}, true);
- setup_type("$_OR_", {A, B}, {Y}, true);
- setup_type("$_NOR_", {A, B}, {Y}, true);
- setup_type("$_XOR_", {A, B}, {Y}, true);
- setup_type("$_XNOR_", {A, B}, {Y}, true);
- setup_type("$_ANDNOT_", {A, B}, {Y}, true);
- setup_type("$_ORNOT_", {A, B}, {Y}, true);
- setup_type("$_MUX_", {A, B, S}, {Y}, true);
- setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true);
- setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
- setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);
- setup_type("$_AOI3_", {A, B, C}, {Y}, true);
- setup_type("$_OAI3_", {A, B, C}, {Y}, true);
- setup_type("$_AOI4_", {A, B, C, D}, {Y}, true);
- setup_type("$_OAI4_", {A, B, C, D}, {Y}, true);
- setup_type("$_TBUF_", {A, E}, {Y}, true);
+ setup_stdcells_eval();
+
+ IdString A = ID::A, E = ID(E), Y = ID::Y;
+
+ setup_type(ID($_TBUF_), {A, E}, {Y}, true);
+ }
+
+ void setup_stdcells_eval()
+ {
+ IdString A = ID::A, B = ID::B, C = ID(C), D = ID(D);
+ IdString E = ID(E), F = ID(F), G = ID(G), H = ID(H);
+ IdString I = ID(I), J = ID(J), K = ID(K), L = ID(L);
+ IdString M = ID(M), N = ID(N), O = ID(O), P = ID(P);
+ IdString S = ID(S), T = ID(T), U = ID(U), V = ID(V);
+ IdString Y = ID::Y;
+
+ setup_type(ID($_BUF_), {A}, {Y}, true);
+ setup_type(ID($_NOT_), {A}, {Y}, true);
+ setup_type(ID($_AND_), {A, B}, {Y}, true);
+ setup_type(ID($_NAND_), {A, B}, {Y}, true);
+ setup_type(ID($_OR_), {A, B}, {Y}, true);
+ setup_type(ID($_NOR_), {A, B}, {Y}, true);
+ setup_type(ID($_XOR_), {A, B}, {Y}, true);
+ setup_type(ID($_XNOR_), {A, B}, {Y}, true);
+ setup_type(ID($_ANDNOT_), {A, B}, {Y}, true);
+ setup_type(ID($_ORNOT_), {A, B}, {Y}, true);
+ setup_type(ID($_MUX_), {A, B, S}, {Y}, true);
+ setup_type(ID($_NMUX_), {A, B, S}, {Y}, true);
+ setup_type(ID($_MUX4_), {A, B, C, D, S, T}, {Y}, true);
+ setup_type(ID($_MUX8_), {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true);
+ setup_type(ID($_MUX16_), {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true);
+ setup_type(ID($_AOI3_), {A, B, C}, {Y}, true);
+ setup_type(ID($_OAI3_), {A, B, C}, {Y}, true);
+ setup_type(ID($_AOI4_), {A, B, C, D}, {Y}, true);
+ setup_type(ID($_OAI4_), {A, B, C, D}, {Y}, true);
}
void setup_stdcells_mem()
{
- IdString S = "\\S", R = "\\R", C = "\\C";
- IdString D = "\\D", Q = "\\Q", E = "\\E";
+ IdString S = ID(S), R = ID(R), C = ID(C);
+ IdString D = ID(D), Q = ID(Q), E = ID(E);
std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
@@ -191,7 +223,7 @@ struct CellTypes
for (auto c2 : list_np)
setup_type(stringf("$_SR_%c%c_", c1, c2), {S, R}, {Q});
- setup_type("$_FF_", {D}, {Q});
+ setup_type(ID($_FF_), {D}, {Q});
for (auto c1 : list_np)
setup_type(stringf("$_DFF_%c_", c1), {C, D}, {Q});
@@ -224,24 +256,24 @@ struct CellTypes
cell_types.clear();
}
- bool cell_known(RTLIL::IdString type)
+ bool cell_known(RTLIL::IdString type) const
{
return cell_types.count(type) != 0;
}
- bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
+ bool cell_output(RTLIL::IdString type, RTLIL::IdString port) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.outputs.count(port) != 0;
}
- bool cell_input(RTLIL::IdString type, RTLIL::IdString port)
+ bool cell_input(RTLIL::IdString type, RTLIL::IdString port) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.inputs.count(port) != 0;
}
- bool cell_evaluable(RTLIL::IdString type)
+ bool cell_evaluable(RTLIL::IdString type) const
{
auto it = cell_types.find(type);
return it != cell_types.end() && it->second.is_evaluable;
@@ -250,20 +282,20 @@ struct CellTypes
static RTLIL::Const eval_not(RTLIL::Const v)
{
for (auto &bit : v.bits)
- if (bit == RTLIL::S0) bit = RTLIL::S1;
- else if (bit == RTLIL::S1) bit = RTLIL::S0;
+ if (bit == State::S0) bit = State::S1;
+ else if (bit == State::S1) bit = State::S0;
return v;
}
- static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len)
+ static RTLIL::Const eval(RTLIL::IdString type, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len, bool *errp = nullptr)
{
- if (type == "$sshr" && !signed1)
- type = "$shr";
- if (type == "$sshl" && !signed1)
- type = "$shl";
+ if (type == ID($sshr) && !signed1)
+ type = ID($shr);
+ if (type == ID($sshl) && !signed1)
+ type = ID($shl);
- if (type != "$sshr" && type != "$sshl" && type != "$shr" && type != "$shl" && type != "$shift" && type != "$shiftx" &&
- type != "$pos" && type != "$neg" && type != "$not") {
+ if (type != ID($sshr) && type != ID($sshl) && type != ID($shr) && type != ID($shl) && type != ID($shift) && type != ID($shiftx) &&
+ type != ID($pos) && type != ID($neg) && type != ID($not)) {
if (!signed1 || !signed2)
signed1 = false, signed2 = false;
}
@@ -306,61 +338,66 @@ struct CellTypes
HANDLE_CELL_TYPE(neg)
#undef HANDLE_CELL_TYPE
- if (type == "$_BUF_")
+ if (type == ID($_BUF_))
return arg1;
- if (type == "$_NOT_")
+ if (type == ID($_NOT_))
return eval_not(arg1);
- if (type == "$_AND_")
+ if (type == ID($_AND_))
return const_and(arg1, arg2, false, false, 1);
- if (type == "$_NAND_")
+ if (type == ID($_NAND_))
return eval_not(const_and(arg1, arg2, false, false, 1));
- if (type == "$_OR_")
+ if (type == ID($_OR_))
return const_or(arg1, arg2, false, false, 1);
- if (type == "$_NOR_")
+ if (type == ID($_NOR_))
return eval_not(const_or(arg1, arg2, false, false, 1));
- if (type == "$_XOR_")
+ if (type == ID($_XOR_))
return const_xor(arg1, arg2, false, false, 1);
- if (type == "$_XNOR_")
+ if (type == ID($_XNOR_))
return const_xnor(arg1, arg2, false, false, 1);
- if (type == "$_ANDNOT_")
+ if (type == ID($_ANDNOT_))
return const_and(arg1, eval_not(arg2), false, false, 1);
- if (type == "$_ORNOT_")
+ if (type == ID($_ORNOT_))
return const_or(arg1, eval_not(arg2), false, false, 1);
+ if (errp != nullptr) {
+ *errp = true;
+ return State::Sm;
+ }
+
log_abort();
}
- static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2)
+ static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool *errp = nullptr)
{
- if (cell->type == "$slice") {
+ if (cell->type == ID($slice)) {
RTLIL::Const ret;
- int width = cell->parameters.at("\\Y_WIDTH").as_int();
- int offset = cell->parameters.at("\\OFFSET").as_int();
+ int width = cell->parameters.at(ID(Y_WIDTH)).as_int();
+ int offset = cell->parameters.at(ID(OFFSET)).as_int();
ret.bits.insert(ret.bits.end(), arg1.bits.begin()+offset, arg1.bits.begin()+offset+width);
return ret;
}
- if (cell->type == "$concat") {
+ if (cell->type == ID($concat)) {
RTLIL::Const ret = arg1;
ret.bits.insert(ret.bits.end(), arg2.bits.begin(), arg2.bits.end());
return ret;
}
- if (cell->type == "$lut")
+ if (cell->type == ID($lut))
{
- int width = cell->parameters.at("\\WIDTH").as_int();
+ int width = cell->parameters.at(ID(WIDTH)).as_int();
- std::vector<RTLIL::State> t = cell->parameters.at("\\LUT").bits;
+ std::vector<RTLIL::State> t = cell->parameters.at(ID(LUT)).bits;
while (GetSize(t) < (1 << width))
- t.push_back(RTLIL::S0);
+ t.push_back(State::S0);
t.resize(1 << width);
for (int i = width-1; i >= 0; i--) {
RTLIL::State sel = arg1.bits.at(i);
std::vector<RTLIL::State> new_t;
- if (sel == RTLIL::S0)
+ if (sel == State::S0)
new_t = std::vector<RTLIL::State>(t.begin(), t.begin() + GetSize(t)/2);
- else if (sel == RTLIL::S1)
+ else if (sel == State::S1)
new_t = std::vector<RTLIL::State>(t.begin() + GetSize(t)/2, t.end());
else
for (int j = 0; j < GetSize(t)/2; j++)
@@ -372,14 +409,14 @@ struct CellTypes
return t;
}
- if (cell->type == "$sop")
+ if (cell->type == ID($sop))
{
- int width = cell->parameters.at("\\WIDTH").as_int();
- int depth = cell->parameters.at("\\DEPTH").as_int();
- std::vector<RTLIL::State> t = cell->parameters.at("\\TABLE").bits;
+ int width = cell->parameters.at(ID(WIDTH)).as_int();
+ int depth = cell->parameters.at(ID(DEPTH)).as_int();
+ std::vector<RTLIL::State> t = cell->parameters.at(ID(TABLE)).bits;
while (GetSize(t) < width*depth*2)
- t.push_back(RTLIL::S0);
+ t.push_back(State::S0);
RTLIL::State default_ret = State::S0;
@@ -410,15 +447,15 @@ struct CellTypes
return default_ret;
}
- bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
- bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
- int result_len = cell->parameters.count("\\Y_WIDTH") > 0 ? cell->parameters["\\Y_WIDTH"].as_int() : -1;
- return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len);
+ bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool();
+ bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool();
+ int result_len = cell->parameters.count(ID(Y_WIDTH)) > 0 ? cell->parameters[ID(Y_WIDTH)].as_int() : -1;
+ return eval(cell->type, arg1, arg2, signed_a, signed_b, result_len, errp);
}
- static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
+ static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
{
- if (cell->type.in("$mux", "$pmux", "$_MUX_")) {
+ if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {
RTLIL::Const ret = arg1;
for (size_t i = 0; i < arg3.bits.size(); i++)
if (arg3.bits[i] == RTLIL::State::S1) {
@@ -428,24 +465,24 @@ struct CellTypes
return ret;
}
- if (cell->type == "$_AOI3_")
+ if (cell->type == ID($_AOI3_))
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1));
- if (cell->type == "$_OAI3_")
+ if (cell->type == ID($_OAI3_))
return eval_not(const_and(const_or(arg1, arg2, false, false, 1), arg3, false, false, 1));
log_assert(arg3.bits.size() == 0);
- return eval(cell, arg1, arg2);
+ return eval(cell, arg1, arg2, errp);
}
- static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4)
+ static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, const RTLIL::Const &arg4, bool *errp = nullptr)
{
- if (cell->type == "$_AOI4_")
+ if (cell->type == ID($_AOI4_))
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
- if (cell->type == "$_OAI4_")
- return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_and(arg3, arg4, false, false, 1), false, false, 1));
+ if (cell->type == ID($_OAI4_))
+ return eval_not(const_and(const_or(arg1, arg2, false, false, 1), const_or(arg3, arg4, false, false, 1), false, false, 1));
log_assert(arg4.bits.size() == 0);
- return eval(cell, arg1, arg2, arg3);
+ return eval(cell, arg1, arg2, arg3, errp);
}
};
@@ -455,4 +492,3 @@ extern CellTypes yosys_celltypes;
YOSYS_NAMESPACE_END
#endif
-
diff --git a/kernel/consteval.h b/kernel/consteval.h
index 0229f5045..7a83d28e7 100644
--- a/kernel/consteval.h
+++ b/kernel/consteval.h
@@ -89,12 +89,12 @@ struct ConstEval
bool eval(RTLIL::Cell *cell, RTLIL::SigSpec &undef)
{
- if (cell->type == "$lcu")
+ if (cell->type == ID($lcu))
{
- RTLIL::SigSpec sig_p = cell->getPort("\\P");
- RTLIL::SigSpec sig_g = cell->getPort("\\G");
- RTLIL::SigSpec sig_ci = cell->getPort("\\CI");
- RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort("\\CO")));
+ RTLIL::SigSpec sig_p = cell->getPort(ID(P));
+ RTLIL::SigSpec sig_g = cell->getPort(ID(G));
+ RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
+ RTLIL::SigSpec sig_co = values_map(assign_map(cell->getPort(ID(CO))));
if (sig_co.is_fully_const())
return true;
@@ -114,8 +114,8 @@ struct ConstEval
bool carry = sig_ci.as_bool();
for (int i = 0; i < GetSize(coval); i++) {
- carry = (sig_g[i] == RTLIL::S1) || (sig_p[i] == RTLIL::S1 && carry);
- coval.bits[i] = carry ? RTLIL::S1 : RTLIL::S0;
+ carry = (sig_g[i] == State::S1) || (sig_p[i] == RTLIL::S1 && carry);
+ coval.bits[i] = carry ? State::S1 : State::S0;
}
set(sig_co, coval);
@@ -128,24 +128,24 @@ struct ConstEval
RTLIL::SigSpec sig_a, sig_b, sig_s, sig_y;
- log_assert(cell->hasPort("\\Y"));
- sig_y = values_map(assign_map(cell->getPort("\\Y")));
+ log_assert(cell->hasPort(ID::Y));
+ sig_y = values_map(assign_map(cell->getPort(ID::Y)));
if (sig_y.is_fully_const())
return true;
- if (cell->hasPort("\\S")) {
- sig_s = cell->getPort("\\S");
+ if (cell->hasPort(ID(S))) {
+ sig_s = cell->getPort(ID(S));
if (!eval(sig_s, undef, cell))
return false;
}
- if (cell->hasPort("\\A"))
- sig_a = cell->getPort("\\A");
+ if (cell->hasPort(ID::A))
+ sig_a = cell->getPort(ID::A);
- if (cell->hasPort("\\B"))
- sig_b = cell->getPort("\\B");
+ if (cell->hasPort(ID::B))
+ sig_b = cell->getPort(ID::B);
- if (cell->type == "$mux" || cell->type == "$pmux" || cell->type == "$_MUX_")
+ if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_), ID($_NMUX_)))
{
std::vector<RTLIL::SigSpec> y_candidates;
int count_maybe_set_s_bits = 0;
@@ -175,7 +175,10 @@ struct ConstEval
for (auto &yc : y_candidates) {
if (!eval(yc, undef, cell))
return false;
- y_values.push_back(yc.as_const());
+ if (cell->type == ID($_NMUX_))
+ y_values.push_back(RTLIL::const_not(yc.as_const(), Const(), false, false, GetSize(yc)));
+ else
+ y_values.push_back(yc.as_const());
}
if (y_values.size() > 1)
@@ -195,10 +198,10 @@ struct ConstEval
else
set(sig_y, y_values.front());
}
- else if (cell->type == "$fa")
+ else if (cell->type == ID($fa))
{
- RTLIL::SigSpec sig_c = cell->getPort("\\C");
- RTLIL::SigSpec sig_x = cell->getPort("\\X");
+ RTLIL::SigSpec sig_c = cell->getPort(ID(C));
+ RTLIL::SigSpec sig_x = cell->getPort(ID(X));
int width = GetSize(sig_c);
if (!eval(sig_a, undef, cell))
@@ -224,13 +227,13 @@ struct ConstEval
set(sig_y, val_y);
set(sig_x, val_x);
}
- else if (cell->type == "$alu")
+ else if (cell->type == ID($alu))
{
- bool signed_a = cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool();
- bool signed_b = cell->parameters.count("\\B_SIGNED") > 0 && cell->parameters["\\B_SIGNED"].as_bool();
+ bool signed_a = cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool();
+ bool signed_b = cell->parameters.count(ID(B_SIGNED)) > 0 && cell->parameters[ID(B_SIGNED)].as_bool();
- RTLIL::SigSpec sig_ci = cell->getPort("\\CI");
- RTLIL::SigSpec sig_bi = cell->getPort("\\BI");
+ RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
+ RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
if (!eval(sig_a, undef, cell))
return false;
@@ -244,15 +247,15 @@ struct ConstEval
if (!eval(sig_bi, undef, cell))
return false;
- RTLIL::SigSpec sig_x = cell->getPort("\\X");
- RTLIL::SigSpec sig_co = cell->getPort("\\CO");
+ RTLIL::SigSpec sig_x = cell->getPort(ID(X));
+ RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
bool any_input_undef = !(sig_a.is_fully_def() && sig_b.is_fully_def() && sig_ci.is_fully_def() && sig_bi.is_fully_def());
sig_a.extend_u0(GetSize(sig_y), signed_a);
sig_b.extend_u0(GetSize(sig_y), signed_b);
- bool carry = sig_ci[0] == RTLIL::S1;
- bool b_inv = sig_bi[0] == RTLIL::S1;
+ bool carry = sig_ci[0] == State::S1;
+ bool b_inv = sig_bi[0] == State::S1;
for (int i = 0; i < GetSize(sig_y); i++)
{
@@ -261,26 +264,26 @@ struct ConstEval
if (!x_inputs.is_fully_def()) {
set(sig_x[i], RTLIL::Sx);
} else {
- bool bit_a = sig_a[i] == RTLIL::S1;
- bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv;
+ bool bit_a = sig_a[i] == State::S1;
+ bool bit_b = (sig_b[i] == State::S1) != b_inv;
bool bit_x = bit_a != bit_b;
- set(sig_x[i], bit_x ? RTLIL::S1 : RTLIL::S0);
+ set(sig_x[i], bit_x ? State::S1 : State::S0);
}
if (any_input_undef) {
set(sig_y[i], RTLIL::Sx);
set(sig_co[i], RTLIL::Sx);
} else {
- bool bit_a = sig_a[i] == RTLIL::S1;
- bool bit_b = (sig_b[i] == RTLIL::S1) != b_inv;
+ bool bit_a = sig_a[i] == State::S1;
+ bool bit_b = (sig_b[i] == State::S1) != b_inv;
bool bit_y = (bit_a != bit_b) != carry;
carry = (bit_a && bit_b) || (bit_a && carry) || (bit_b && carry);
- set(sig_y[i], bit_y ? RTLIL::S1 : RTLIL::S0);
- set(sig_co[i], carry ? RTLIL::S1 : RTLIL::S0);
+ set(sig_y[i], bit_y ? State::S1 : State::S0);
+ set(sig_co[i], carry ? State::S1 : State::S0);
}
}
}
- else if (cell->type == "$macc")
+ else if (cell->type == ID($macc))
{
Macc macc;
macc.from_cell(cell);
@@ -295,21 +298,21 @@ struct ConstEval
return false;
}
- RTLIL::Const result(0, GetSize(cell->getPort("\\Y")));
+ RTLIL::Const result(0, GetSize(cell->getPort(ID::Y)));
if (!macc.eval(result))
log_abort();
- set(cell->getPort("\\Y"), result);
+ set(cell->getPort(ID::Y), result);
}
else
{
RTLIL::SigSpec sig_c, sig_d;
- if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_")) {
- if (cell->hasPort("\\C"))
- sig_c = cell->getPort("\\C");
- if (cell->hasPort("\\D"))
- sig_d = cell->getPort("\\D");
+ if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_))) {
+ if (cell->hasPort(ID(C)))
+ sig_c = cell->getPort(ID(C));
+ if (cell->hasPort(ID(D)))
+ sig_d = cell->getPort(ID(D));
}
if (sig_a.size() > 0 && !eval(sig_a, undef, cell))
@@ -321,8 +324,13 @@ struct ConstEval
if (sig_d.size() > 0 && !eval(sig_d, undef, cell))
return false;
- set(sig_y, CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(),
- sig_c.as_const(), sig_d.as_const()));
+ bool eval_err = false;
+ RTLIL::Const eval_ret = CellTypes::eval(cell, sig_a.as_const(), sig_b.as_const(), sig_c.as_const(), sig_d.as_const(), &eval_err);
+
+ if (eval_err)
+ return false;
+
+ set(sig_y, eval_ret);
}
return true;
diff --git a/kernel/cost.h b/kernel/cost.h
index 84fd6cd6d..ea2a4c1f0 100644
--- a/kernel/cost.h
+++ b/kernel/cost.h
@@ -20,66 +20,96 @@
#ifndef COST_H
#define COST_H
-#include <kernel/yosys.h>
+#include "kernel/yosys.h"
YOSYS_NAMESPACE_BEGIN
-int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr);
-
-int get_cell_cost(RTLIL::IdString type, const dict<RTLIL::IdString, RTLIL::Const> &parameters = dict<RTLIL::IdString, RTLIL::Const>(),
- RTLIL::Design *design = nullptr, dict<RTLIL::IdString, int> *mod_cost_cache = nullptr)
+struct CellCosts
{
- static dict<RTLIL::IdString, int> gate_cost = {
- { "$_BUF_", 1 },
- { "$_NOT_", 2 },
- { "$_AND_", 4 },
- { "$_NAND_", 4 },
- { "$_OR_", 4 },
- { "$_NOR_", 4 },
- { "$_ANDNOT_", 4 },
- { "$_ORNOT_", 4 },
- { "$_XOR_", 8 },
- { "$_XNOR_", 8 },
- { "$_AOI3_", 6 },
- { "$_OAI3_", 6 },
- { "$_AOI4_", 8 },
- { "$_OAI4_", 8 },
- { "$_MUX_", 4 }
- };
-
- if (gate_cost.count(type))
- return gate_cost.at(type);
-
- if (parameters.empty() && design && design->module(type))
+ static const dict<RTLIL::IdString, int>& default_gate_cost() {
+ static const dict<RTLIL::IdString, int> db = {
+ { ID($_BUF_), 1 },
+ { ID($_NOT_), 2 },
+ { ID($_AND_), 4 },
+ { ID($_NAND_), 4 },
+ { ID($_OR_), 4 },
+ { ID($_NOR_), 4 },
+ { ID($_ANDNOT_), 4 },
+ { ID($_ORNOT_), 4 },
+ { ID($_XOR_), 5 },
+ { ID($_XNOR_), 5 },
+ { ID($_AOI3_), 6 },
+ { ID($_OAI3_), 6 },
+ { ID($_AOI4_), 7 },
+ { ID($_OAI4_), 7 },
+ { ID($_MUX_), 4 },
+ { ID($_NMUX_), 4 }
+ };
+ return db;
+ }
+
+ static const dict<RTLIL::IdString, int>& cmos_gate_cost() {
+ static const dict<RTLIL::IdString, int> db = {
+ { ID($_BUF_), 1 },
+ { ID($_NOT_), 2 },
+ { ID($_AND_), 6 },
+ { ID($_NAND_), 4 },
+ { ID($_OR_), 6 },
+ { ID($_NOR_), 4 },
+ { ID($_ANDNOT_), 6 },
+ { ID($_ORNOT_), 6 },
+ { ID($_XOR_), 12 },
+ { ID($_XNOR_), 12 },
+ { ID($_AOI3_), 6 },
+ { ID($_OAI3_), 6 },
+ { ID($_AOI4_), 8 },
+ { ID($_OAI4_), 8 },
+ { ID($_MUX_), 12 },
+ { ID($_NMUX_), 10 }
+ };
+ return db;
+ }
+
+ dict<RTLIL::IdString, int> mod_cost_cache;
+ const dict<RTLIL::IdString, int> *gate_cost = nullptr;
+ Design *design = nullptr;
+
+ int get(RTLIL::IdString type) const
{
- RTLIL::Module *mod = design->module(type);
+ if (gate_cost && gate_cost->count(type))
+ return gate_cost->at(type);
- if (mod->attributes.count("\\cost"))
- return mod->attributes.at("\\cost").as_int();
+ log_warning("Can't determine cost of %s cell.\n", log_id(type));
+ return 1;
+ }
- dict<RTLIL::IdString, int> local_mod_cost_cache;
- if (mod_cost_cache == nullptr)
- mod_cost_cache = &local_mod_cost_cache;
+ int get(RTLIL::Cell *cell)
+ {
+ if (gate_cost && gate_cost->count(cell->type))
+ return gate_cost->at(cell->type);
- if (mod_cost_cache->count(mod->name))
- return mod_cost_cache->at(mod->name);
+ if (design && design->module(cell->type) && cell->parameters.empty())
+ {
+ RTLIL::Module *mod = design->module(cell->type);
- int module_cost = 1;
- for (auto c : mod->cells())
- module_cost += get_cell_cost(c, mod_cost_cache);
+ if (mod->attributes.count(ID(cost)))
+ return mod->attributes.at(ID(cost)).as_int();
- (*mod_cost_cache)[mod->name] = module_cost;
- return module_cost;
- }
+ if (mod_cost_cache.count(mod->name))
+ return mod_cost_cache.at(mod->name);
- log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(type), GetSize(parameters));
- return 1;
-}
+ int module_cost = 1;
+ for (auto c : mod->cells())
+ module_cost += get(c);
-int get_cell_cost(RTLIL::Cell *cell, dict<RTLIL::IdString, int> *mod_cost_cache)
-{
- return get_cell_cost(cell->type, cell->parameters, cell->module->design, mod_cost_cache);
-}
+ mod_cost_cache[mod->name] = module_cost;
+ return module_cost;
+ }
+
+ log_warning("Can't determine cost of %s cell (%d parameters).\n", log_id(cell->type), GetSize(cell->parameters));
+ return 1;
+ }
+};
YOSYS_NAMESPACE_END
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 1fe61b499..9040408bc 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -25,16 +25,26 @@
# include <readline/history.h>
#endif
+#ifdef YOSYS_ENABLE_EDITLINE
+# include <editline/readline.h>
+#endif
+
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
-#ifdef __linux__
+#if defined (__linux__) || defined(__FreeBSD__)
+# include <sys/resource.h>
# include <sys/types.h>
# include <unistd.h>
#endif
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+# include <sys/user.h>
+#endif
+
#if !defined(_WIN32) || defined(__MINGW32__)
# include <unistd.h>
#else
@@ -75,20 +85,41 @@ USING_YOSYS_NAMESPACE
#ifdef EMSCRIPTEN
# include <sys/stat.h>
# include <sys/types.h>
+# include <emscripten.h>
extern "C" int main(int, char**);
extern "C" void run(const char*);
extern "C" const char *errmsg();
extern "C" const char *prompt();
-int main(int, char**)
+int main(int argc, char **argv)
{
+ EM_ASM(
+ if (ENVIRONMENT_IS_NODE)
+ {
+ FS.mkdir('/hostcwd');
+ FS.mount(NODEFS, { root: '.' }, '/hostcwd');
+ FS.mkdir('/hostfs');
+ FS.mount(NODEFS, { root: '/' }, '/hostfs');
+ }
+ );
+
mkdir("/work", 0777);
chdir("/work");
log_files.push_back(stdout);
log_error_stderr = true;
yosys_banner();
yosys_setup();
+#ifdef WITH_PYTHON
+ PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
+ PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
+#endif
+
+ if (argc == 2)
+ {
+ // Run the first argument as a script file
+ run_frontend(argv[1], "script", 0, 0, 0);
+ }
}
void run(const char *command)
@@ -119,37 +150,45 @@ const char *prompt()
#else /* EMSCRIPTEN */
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
int yosys_history_offset = 0;
std::string yosys_history_file;
#endif
void yosys_atexit()
{
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
if (!yosys_history_file.empty()) {
+#if defined(YOSYS_ENABLE_READLINE)
if (yosys_history_offset > 0) {
history_truncate_file(yosys_history_file.c_str(), 100);
append_history(where_history() - yosys_history_offset, yosys_history_file.c_str());
} else
write_history(yosys_history_file.c_str());
+#else
+ write_history(yosys_history_file.c_str());
+#endif
}
clear_history();
+#if defined(YOSYS_ENABLE_READLINE)
HIST_ENTRY **hist_list = history_list();
if (hist_list != NULL)
free(hist_list);
#endif
+#endif
}
int main(int argc, char **argv)
{
std::string frontend_command = "auto";
std::string backend_command = "auto";
+ std::vector<std::string> vlog_defines;
std::vector<std::string> passes_commands;
std::vector<std::string> plugin_filenames;
std::string output_filename = "";
std::string scriptfile = "";
+ std::string depsfile = "";
bool scriptfile_tcl = false;
bool got_output_filename = false;
bool print_banner = true;
@@ -159,7 +198,7 @@ int main(int argc, char **argv)
bool mode_v = false;
bool mode_q = false;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
if (getenv("HOME") != NULL) {
yosys_history_file = stringf("%s/.yosys_history", getenv("HOME"));
read_history(yosys_history_file.c_str());
@@ -234,7 +273,10 @@ int main(int argc, char **argv)
printf(" -A\n");
printf(" will call abort() at the end of the script. for debugging\n");
printf("\n");
- printf(" -D <header_id>[:<filename>]\n");
+ printf(" -D <macro>[=<value>]\n");
+ printf(" set the specified Verilog define (via \"read -define\")\n");
+ printf("\n");
+ printf(" -P <header_id>[:<filename>]\n");
printf(" dump the design when printing the specified log header to a file.\n");
printf(" yosys_dump_<header_id>.il is used as filename if none is specified.\n");
printf(" Use 'ALL' as <header_id> to dump at every header.\n");
@@ -243,9 +285,22 @@ int main(int argc, char **argv)
printf(" print a warning for all log messages matching the regex.\n");
printf("\n");
printf(" -w regex\n");
- printf(" if a warning message matches the regex, it is printes as regular\n");
+ printf(" if a warning message matches the regex, it is printed as regular\n");
printf(" message instead.\n");
printf("\n");
+ printf(" -e regex\n");
+ printf(" if a warning message matches the regex, it is printed as error\n");
+ printf(" message instead and the tool terminates with a nonzero return code.\n");
+ printf("\n");
+ printf(" -E <depsfile>\n");
+ printf(" write a Makefile dependencies file with in- and output file names\n");
+ printf("\n");
+ printf(" -x <feature>\n");
+ printf(" do not print warnings for the specified experimental feature\n");
+ printf("\n");
+ printf(" -g\n");
+ printf(" globally enable debug log messages\n");
+ printf("\n");
printf(" -V\n");
printf(" print version information and exit\n");
printf("\n");
@@ -265,8 +320,14 @@ int main(int argc, char **argv)
exit(0);
}
+ if (argc == 2 && (!strcmp(argv[1], "-V") || !strcmp(argv[1], "-version") || !strcmp(argv[1], "--version")))
+ {
+ printf("%s\n", yosys_version_str);
+ exit(0);
+ }
+
int opt;
- while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:D:")) != -1)
+ while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:P:E:x:")) != -1)
{
switch (opt)
{
@@ -291,6 +352,9 @@ int main(int argc, char **argv)
case 'S':
passes_commands.push_back("synth");
break;
+ case 'g':
+ log_force_debug++;
+ break;
case 'm':
plugin_filenames.push_back(optarg);
break;
@@ -360,7 +424,16 @@ int main(int argc, char **argv)
std::regex_constants::optimize |
std::regex_constants::egrep));
break;
+ case 'e':
+ log_werror_regexes.push_back(std::regex(optarg,
+ std::regex_constants::nosubs |
+ std::regex_constants::optimize |
+ std::regex_constants::egrep));
+ break;
case 'D':
+ vlog_defines.push_back(optarg);
+ break;
+ case 'P':
{
auto args = split_tokens(optarg, ":");
if (!args.empty() && args[0] == "ALL") {
@@ -382,6 +455,12 @@ int main(int argc, char **argv)
}
}
break;
+ case 'E':
+ depsfile = optarg;
+ break;
+ case 'x':
+ log_experimentals_ignored.insert(optarg);
+ break;
default:
fprintf(stderr, "Run '%s -h' for help.\n", argv[0]);
exit(1);
@@ -399,7 +478,23 @@ int main(int argc, char **argv)
if (print_stats)
log_hasher = new SHA1;
+#if defined(__linux__)
+ // set stack size to >= 128 MB
+ {
+ struct rlimit rl;
+ const rlim_t stack_size = 128L * 1024L * 1024L;
+ if (getrlimit(RLIMIT_STACK, &rl) == 0 && rl.rlim_cur < stack_size) {
+ rl.rlim_cur = stack_size;
+ setrlimit(RLIMIT_STACK, &rl);
+ }
+ }
+#endif
+
yosys_setup();
+#ifdef WITH_PYTHON
+ PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
+ PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
+#endif
log_error_atexit = yosys_atexit;
for (auto &fn : plugin_filenames)
@@ -411,6 +506,13 @@ int main(int argc, char **argv)
shell(yosys_design);
}
+ if (!vlog_defines.empty()) {
+ std::string vdef_cmd = "read -define";
+ for (auto vdef : vlog_defines)
+ vdef_cmd += " " + vdef;
+ run_pass(vdef_cmd);
+ }
+
while (optind < argc)
run_frontend(argv[optind++], frontend_command, output_filename == "-" ? &backend_command : NULL);
@@ -432,6 +534,30 @@ int main(int argc, char **argv)
if (!backend_command.empty())
run_backend(output_filename, backend_command);
+ yosys_design->check();
+ for (auto it : saved_designs)
+ it.second->check();
+ for (auto it : pushed_designs)
+ it->check();
+
+ if (!depsfile.empty())
+ {
+ FILE *f = fopen(depsfile.c_str(), "wt");
+ if (f == nullptr)
+ log_error("Can't open dependencies file for writing: %s\n", strerror(errno));
+ bool first = true;
+ for (auto fn : yosys_output_files) {
+ fprintf(f, "%s%s", first ? "" : " ", escape_filename_spaces(fn).c_str());
+ first = false;
+ }
+ fprintf(f, ":");
+ for (auto fn : yosys_input_files) {
+ if (yosys_output_files.count(fn) == 0)
+ fprintf(f, " %s", escape_filename_spaces(fn).c_str());
+ }
+ fprintf(f, "\n");
+ }
+
if (print_stats)
{
std::string hash = log_hasher->final().substr(0, 10);
@@ -445,26 +571,33 @@ int main(int argc, char **argv)
if (mode_v && !mode_q)
log_files.push_back(stderr);
+ if (log_warnings_count)
+ log("Warnings: %d unique messages, %d total\n", GetSize(log_warnings), log_warnings_count);
+
+ if (!log_experimentals.empty())
+ log("Warnings: %d experimental features used (not excluded with -x).\n", GetSize(log_experimentals));
+
#ifdef _WIN32
log("End of script. Logfile hash: %s\n", hash.c_str());
#else
std::string meminfo;
std::string stats_divider = ", ";
-# ifdef __linux__
- std::ifstream statm;
- statm.open(stringf("/proc/%lld/statm", (long long)getpid()));
- if (statm.is_open()) {
- int sz_total, sz_resident;
- statm >> sz_total >> sz_resident;
- meminfo = stringf(", MEM: %.2f MB total, %.2f MB resident",
- sz_total * (getpagesize() / 1024.0 / 1024.0),
- sz_resident * (getpagesize() / 1024.0 / 1024.0));
- stats_divider = "\n";
- }
-# endif
struct rusage ru_buffer;
getrusage(RUSAGE_SELF, &ru_buffer);
+ if (yosys_design->scratchpad_get_bool("print_stats.include_children")) {
+ struct rusage ru_buffer_children;
+ getrusage(RUSAGE_CHILDREN, &ru_buffer_children);
+ ru_buffer.ru_utime.tv_sec += ru_buffer_children.ru_utime.tv_sec;
+ ru_buffer.ru_utime.tv_usec += ru_buffer_children.ru_utime.tv_usec;
+ ru_buffer.ru_stime.tv_sec += ru_buffer_children.ru_stime.tv_sec;
+ ru_buffer.ru_stime.tv_usec += ru_buffer_children.ru_stime.tv_usec;
+ ru_buffer.ru_maxrss = std::max(ru_buffer.ru_maxrss, ru_buffer_children.ru_maxrss);
+ }
+# if defined(__linux__) || defined(__FreeBSD__)
+ meminfo = stringf(", MEM: %.2f MB peak",
+ ru_buffer.ru_maxrss / 1024.0);
+#endif
log("End of script. Logfile hash: %s%sCPU: user %.2fs system %.2fs%s\n", hash.c_str(),
stats_divider.c_str(), ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec,
ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec, meminfo.c_str());
@@ -504,7 +637,7 @@ int main(int argc, char **argv)
}
}
-#if defined(YOSYS_ENABLE_COVER) && defined(__linux__)
+#if defined(YOSYS_ENABLE_COVER) && (defined(__linux__) || defined(__FreeBSD__))
if (getenv("YOSYS_COVER_DIR") || getenv("YOSYS_COVER_FILE"))
{
string filename;
diff --git a/kernel/hashlib.h b/kernel/hashlib.h
index df534ec1b..e7cb312ed 100644
--- a/kernel/hashlib.h
+++ b/kernel/hashlib.h
@@ -557,9 +557,11 @@ public:
void clear() { hashtable.clear(); entries.clear(); }
iterator begin() { return iterator(this, int(entries.size())-1); }
+ iterator element(int n) { return iterator(this, int(entries.size())-1-n); }
iterator end() { return iterator(nullptr, -1); }
const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
+ const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
const_iterator end() const { return const_iterator(nullptr, -1); }
};
@@ -881,9 +883,11 @@ public:
void clear() { hashtable.clear(); entries.clear(); }
iterator begin() { return iterator(this, int(entries.size())-1); }
+ iterator element(int n) { return iterator(this, int(entries.size())-1-n); }
iterator end() { return iterator(nullptr, -1); }
const_iterator begin() const { return const_iterator(this, int(entries.size())-1); }
+ const_iterator element(int n) const { return const_iterator(this, int(entries.size())-1-n); }
const_iterator end() const { return const_iterator(nullptr, -1); }
};
@@ -952,6 +956,7 @@ public:
void clear() { database.clear(); }
const_iterator begin() const { return database.begin(); }
+ const_iterator element(int n) const { return database.element(n); }
const_iterator end() const { return database.end(); }
};
@@ -1051,6 +1056,7 @@ public:
void clear() { database.clear(); parents.clear(); }
const_iterator begin() const { return database.begin(); }
+ const_iterator element(int n) const { return database.element(n); }
const_iterator end() const { return database.end(); }
};
diff --git a/kernel/log.cc b/kernel/log.cc
index 7be95204b..f5d6c488e 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -25,7 +25,7 @@
# include <sys/time.h>
#endif
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
# include <dlfcn.h>
#endif
@@ -41,7 +41,9 @@ YOSYS_NAMESPACE_BEGIN
std::vector<FILE*> log_files;
std::vector<std::ostream*> log_streams;
std::map<std::string, std::set<std::string>> log_hdump;
-std::vector<std::regex> log_warn_regexes, log_nowarn_regexes;
+std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
+std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
+int log_warnings_count = 0;
bool log_hdump_all = false;
FILE *log_errfile = NULL;
SHA1 *log_hasher = NULL;
@@ -54,8 +56,12 @@ int log_verbose_level;
string log_last_error;
void (*log_error_atexit)() = NULL;
+int log_make_debug = 0;
+int log_force_debug = 0;
+int log_debug_suppressed = 0;
+
vector<int> header_count;
-pool<RTLIL::IdString> log_id_cache;
+vector<char*> log_id_cache;
vector<shared_str> string_buf;
int string_buf_index = -1;
@@ -63,6 +69,13 @@ static struct timeval initial_tv = { 0, 0 };
static bool next_print_log = false;
static int log_newline_count = 0;
+static void log_id_cache_clear()
+{
+ for (auto p : log_id_cache)
+ free(p);
+ log_id_cache.clear();
+}
+
#if defined(_WIN32) && !defined(__MINGW32__)
// this will get time information and return it in timeval, simulating gettimeofday()
int gettimeofday(struct timeval *tv, struct timezone *tz)
@@ -90,6 +103,9 @@ void logv(const char *format, va_list ap)
format++;
}
+ if (log_make_debug && !ys_debug(1))
+ return;
+
std::string str = vstringf(format, ap);
if (str.empty())
@@ -194,14 +210,19 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap)
if (log_hdump.count(header_id) && design != nullptr)
for (auto &filename : log_hdump.at(header_id)) {
log("Dumping current design to '%s'.\n", filename.c_str());
+ if (yosys_xtrace)
+ IdString::xtrace_db_dump();
Pass::call(design, {"dump", "-o", filename});
+ if (yosys_xtrace)
+ log("#X# -- end of dump --\n");
}
if (pop_errfile)
log_files.pop_back();
}
-void logv_warning(const char *format, va_list ap)
+static void logv_warning_with_prefix(const char *prefix,
+ const char *format, va_list ap)
{
std::string message = vstringf(format, ap);
bool suppressed = false;
@@ -212,52 +233,83 @@ void logv_warning(const char *format, va_list ap)
if (suppressed)
{
- log("Suppressed warning: %s", message.c_str());
+ log("Suppressed %s%s", prefix, message.c_str());
}
else
{
- if (log_errfile != NULL && !log_quiet_warnings)
- log_files.push_back(log_errfile);
+ int bak_log_make_debug = log_make_debug;
+ log_make_debug = 0;
- log("Warning: %s", message.c_str());
- log_flush();
+ for (auto &re : log_werror_regexes)
+ if (std::regex_search(message, re))
+ log_error("%s", message.c_str());
- if (log_errfile != NULL && !log_quiet_warnings)
- log_files.pop_back();
+ if (log_warnings.count(message))
+ {
+ log("%s%s", prefix, message.c_str());
+ log_flush();
+ }
+ else
+ {
+ if (log_errfile != NULL && !log_quiet_warnings)
+ log_files.push_back(log_errfile);
+
+ log("%s%s", prefix, message.c_str());
+ log_flush();
+
+ if (log_errfile != NULL && !log_quiet_warnings)
+ log_files.pop_back();
+
+ log_warnings.insert(message);
+ }
+
+ log_warnings_count++;
+ log_make_debug = bak_log_make_debug;
}
}
-void logv_warning_noprefix(const char *format, va_list ap)
+void logv_warning(const char *format, va_list ap)
{
- std::string message = vstringf(format, ap);
- bool suppressed = false;
-
- for (auto &re : log_nowarn_regexes)
- if (std::regex_search(message, re))
- suppressed = true;
+ logv_warning_with_prefix("Warning: ", format, ap);
+}
- if (suppressed)
- {
- log("%s", message.c_str());
- }
- else
- {
- if (log_errfile != NULL && !log_quiet_warnings)
- log_files.push_back(log_errfile);
+void logv_warning_noprefix(const char *format, va_list ap)
+{
+ logv_warning_with_prefix("", format, ap);
+}
- log("%s", message.c_str());
- log_flush();
+void log_file_warning(const std::string &filename, int lineno,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ std::string prefix = stringf("%s:%d: Warning: ",
+ filename.c_str(), lineno);
+ logv_warning_with_prefix(prefix.c_str(), format, ap);
+ va_end(ap);
+}
- if (log_errfile != NULL && !log_quiet_warnings)
- log_files.pop_back();
- }
+void log_file_info(const std::string &filename, int lineno,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ std::string fmt = stringf("%s:%d: Info: %s",
+ filename.c_str(), lineno, format);
+ logv(fmt.c_str(), ap);
+ va_end(ap);
}
-void logv_error(const char *format, va_list ap)
+YS_ATTRIBUTE(noreturn)
+static void logv_error_with_prefix(const char *prefix,
+ const char *format, va_list ap)
{
#ifdef EMSCRIPTEN
auto backup_log_files = log_files;
#endif
+ int bak_log_make_debug = log_make_debug;
+ log_make_debug = 0;
+ log_suppressed();
if (log_errfile != NULL)
log_files.push_back(log_errfile);
@@ -268,9 +320,11 @@ void logv_error(const char *format, va_list ap)
f = stderr;
log_last_error = vstringf(format, ap);
- log("ERROR: %s", log_last_error.c_str());
+ log("%s%s", prefix, log_last_error.c_str());
log_flush();
+ log_make_debug = bak_log_make_debug;
+
if (log_error_atexit)
log_error_atexit();
@@ -284,6 +338,21 @@ void logv_error(const char *format, va_list ap)
#endif
}
+void logv_error(const char *format, va_list ap)
+{
+ logv_error_with_prefix("ERROR: ", format, ap);
+}
+
+void log_file_error(const string &filename, int lineno,
+ const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ std::string prefix = stringf("%s:%d: ERROR: ",
+ filename.c_str(), lineno);
+ logv_error_with_prefix(prefix.c_str(), format, ap);
+}
+
void log(const char *format, ...)
{
va_list ap;
@@ -308,6 +377,19 @@ void log_warning(const char *format, ...)
va_end(ap);
}
+void log_experimental(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ string s = vstringf(format, ap);
+ va_end(ap);
+
+ if (log_experimentals_ignored.count(s) == 0 && log_experimentals.count(s) == 0) {
+ log_warning("Feature '%s' is experimental.\n", s.c_str());
+ log_experimentals.insert(s);
+ }
+}
+
void log_warning_noprefix(const char *format, ...)
{
va_list ap;
@@ -352,13 +434,13 @@ void log_push()
void log_pop()
{
header_count.pop_back();
- log_id_cache.clear();
+ log_id_cache_clear();
string_buf.clear();
string_buf_index = -1;
log_flush();
}
-#if defined(__linux__) && defined(YOSYS_ENABLE_PLUGINS)
+#if (defined(__linux__) || defined(__FreeBSD__)) && defined(YOSYS_ENABLE_PLUGINS)
void log_backtrace(const char *prefix, int levels)
{
if (levels <= 0) return;
@@ -375,6 +457,9 @@ void log_backtrace(const char *prefix, int levels)
if (levels <= 1) return;
+#ifndef DEBUG
+ log("%sframe #2: [build Yosys with ENABLE_DEBUG for deeper backtraces]\n", prefix);
+#else
if ((p = __builtin_extract_return_addr(__builtin_return_address(1))) && dladdr(p, &dli)) {
log("%sframe #2: %p %s(%p) %s(%p)\n", prefix, p, dli.dli_fname, dli.dli_fbase, dli.dli_sname, dli.dli_saddr);
} else {
@@ -446,6 +531,7 @@ void log_backtrace(const char *prefix, int levels)
}
if (levels <= 9) return;
+#endif
}
#else
void log_backtrace(const char*, int) { }
@@ -455,7 +541,7 @@ void log_reset_stack()
{
while (header_count.size() > 1)
header_count.pop_back();
- log_id_cache.clear();
+ log_id_cache_clear();
string_buf.clear();
string_buf_index = -1;
log_flush();
@@ -478,6 +564,10 @@ void log_dump_val_worker(RTLIL::SigSpec v) {
log("%s", log_signal(v));
}
+void log_dump_val_worker(RTLIL::State v) {
+ log("%s", log_signal(v));
+}
+
const char *log_signal(const RTLIL::SigSpec &sig, bool autoint)
{
std::stringstream buf;
@@ -514,8 +604,8 @@ const char *log_const(const RTLIL::Const &value, bool autoint)
const char *log_id(RTLIL::IdString str)
{
- log_id_cache.insert(str);
- const char *p = str.c_str();
+ log_id_cache.push_back(strdup(str.c_str()));
+ const char *p = log_id_cache.back();
if (p[0] != '\\')
return p;
if (p[1] == '$' || p[1] == '\\' || p[1] == 0)
@@ -549,7 +639,7 @@ void log_wire(RTLIL::Wire *wire, std::string indent)
// ---------------------------------------------------
// This is the magic behind the code coverage counters
// ---------------------------------------------------
-#if defined(YOSYS_ENABLE_COVER) && defined(__linux__)
+#if defined(YOSYS_ENABLE_COVER) && (defined(__linux__) || defined(__FreeBSD__))
dict<std::string, std::pair<std::string, int>> extra_coverage_data;
@@ -598,4 +688,3 @@ dict<std::string, std::pair<std::string, int>> get_coverage_data()
#endif
YOSYS_NAMESPACE_END
-
diff --git a/kernel/log.h b/kernel/log.h
index e27dafab9..9db8efaa5 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -49,7 +49,9 @@ struct log_cmd_error_exception { };
extern std::vector<FILE*> log_files;
extern std::vector<std::ostream*> log_streams;
extern std::map<std::string, std::set<std::string>> log_hdump;
-extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes;
+extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
+extern std::set<std::string> log_warnings, log_experimentals, log_experimentals_ignored;
+extern int log_warnings_count;
extern bool log_hdump_all;
extern FILE *log_errfile;
extern SHA1 *log_hasher;
@@ -62,6 +64,10 @@ extern int log_verbose_level;
extern string log_last_error;
extern void (*log_error_atexit)();
+extern int log_make_debug;
+extern int log_force_debug;
+extern int log_debug_suppressed;
+
void logv(const char *format, va_list ap);
void logv_header(RTLIL::Design *design, const char *format, va_list ap);
void logv_warning(const char *format, va_list ap);
@@ -71,10 +77,56 @@ YS_NORETURN void logv_error(const char *format, va_list ap) YS_ATTRIBUTE(noretur
void log(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(format(printf, 2, 3));
void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
+void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
+
+// Log with filename to report a problem in a source file.
+void log_file_warning(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
+void log_file_info(const std::string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4));
+
void log_warning_noprefix(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2));
YS_NORETURN void log_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn);
+void log_file_error(const string &filename, int lineno, const char *format, ...) YS_ATTRIBUTE(format(printf, 3, 4), noreturn);
YS_NORETURN void log_cmd_error(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2), noreturn);
+#ifndef NDEBUG
+static inline bool ys_debug(int n = 0) { if (log_force_debug) return true; log_debug_suppressed += n; return false; }
+# define log_debug(...) do { if (ys_debug(1)) log(__VA_ARGS__); } while (0)
+#else
+static inline bool ys_debug(int = 0) { return false; }
+# define log_debug(_fmt, ...) do { } while (0)
+#endif
+
+static inline void log_suppressed() {
+ if (log_debug_suppressed && !log_make_debug) {
+ log("<suppressed ~%d debug messages>\n", log_debug_suppressed);
+ log_debug_suppressed = 0;
+ }
+}
+
+struct LogMakeDebugHdl {
+ bool status = false;
+ LogMakeDebugHdl(bool start_on = false) {
+ if (start_on)
+ on();
+ }
+ ~LogMakeDebugHdl() {
+ off();
+ }
+ void on() {
+ if (status) return;
+ status=true;
+ log_make_debug++;
+ }
+ void off_silent() {
+ if (!status) return;
+ status=false;
+ log_make_debug--;
+ }
+ void off() {
+ off_silent();
+ }
+};
+
void log_spacer();
void log_push();
void log_pop();
@@ -87,7 +139,9 @@ const char *log_signal(const RTLIL::SigSpec &sig, bool autoint = true);
const char *log_const(const RTLIL::Const &value, bool autoint = true);
const char *log_id(RTLIL::IdString id);
-template<typename T> static inline const char *log_id(T *obj) {
+template<typename T> static inline const char *log_id(T *obj, const char *nullstr = nullptr) {
+ if (nullstr && obj == nullptr)
+ return nullstr;
return log_id(obj->name);
}
@@ -112,7 +166,7 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi
// This is the magic behind the code coverage counters
// ---------------------------------------------------
-#if defined(YOSYS_ENABLE_COVER) && defined(__linux__)
+#if defined(YOSYS_ENABLE_COVER) && (defined(__linux__) || defined(__FreeBSD__))
#define cover(_id) do { \
static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1), used)) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \
@@ -171,7 +225,7 @@ struct PerformanceTimer
}
static int64_t query() {
-# if _WIN32
+# ifdef _WIN32
return 0;
# elif defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
struct timespec ts;
@@ -188,7 +242,7 @@ struct PerformanceTimer
t += 1000000000ULL * (int64_t) rusage.ru_stime.tv_sec + (int64_t) rusage.ru_stime.tv_usec * 1000ULL;
return t;
# else
-# error Dont know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?).
+# error "Don't know how to measure per-process CPU time. Need alternative method (times()/clocks()/gettimeofday()?)."
# endif
}
@@ -239,6 +293,7 @@ static inline void log_dump_val_worker(PerformanceTimer p) { log("%f seconds", p
static inline void log_dump_args_worker(const char *p YS_ATTRIBUTE(unused)) { log_assert(*p == 0); }
void log_dump_val_worker(RTLIL::IdString v);
void log_dump_val_worker(RTLIL::SigSpec v);
+void log_dump_val_worker(RTLIL::State v);
template<typename K, typename T, typename OPS>
static inline void log_dump_val_worker(dict<K, T, OPS> &v) {
diff --git a/kernel/macc.h b/kernel/macc.h
index 286ce567f..371f6737d 100644
--- a/kernel/macc.h
+++ b/kernel/macc.h
@@ -70,9 +70,9 @@ struct Macc
while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == port.in_b[GetSize(port.in_b)-2])
port.in_b.remove(GetSize(port.in_b)-1);
} else {
- while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == RTLIL::S0)
+ while (GetSize(port.in_a) > 1 && port.in_a[GetSize(port.in_a)-1] == State::S0)
port.in_a.remove(GetSize(port.in_a)-1);
- while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == RTLIL::S0)
+ while (GetSize(port.in_b) > 1 && port.in_b[GetSize(port.in_b)-1] == State::S0)
port.in_b.remove(GetSize(port.in_b)-1);
}
@@ -80,9 +80,9 @@ struct Macc
}
for (auto &bit : bit_ports)
- if (bit == RTLIL::S1)
+ if (bit == State::S1)
off = const_add(off, RTLIL::Const(1, width), false, false, width);
- else if (bit != RTLIL::S0)
+ else if (bit != State::S0)
new_bit_ports.append(bit);
if (off.as_bool()) {
@@ -99,24 +99,24 @@ struct Macc
void from_cell(RTLIL::Cell *cell)
{
- RTLIL::SigSpec port_a = cell->getPort("\\A");
+ RTLIL::SigSpec port_a = cell->getPort(ID::A);
ports.clear();
- bit_ports = cell->getPort("\\B");
+ bit_ports = cell->getPort(ID::B);
- std::vector<RTLIL::State> config_bits = cell->getParam("\\CONFIG").bits;
+ std::vector<RTLIL::State> config_bits = cell->getParam(ID(CONFIG)).bits;
int config_cursor = 0;
#ifndef NDEBUG
- int config_width = cell->getParam("\\CONFIG_WIDTH").as_int();
+ int config_width = cell->getParam(ID(CONFIG_WIDTH)).as_int();
log_assert(GetSize(config_bits) >= config_width);
#endif
int num_bits = 0;
- if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 1;
- if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 2;
- if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 4;
- if (config_bits[config_cursor++] == RTLIL::S1) num_bits |= 8;
+ if (config_bits[config_cursor++] == State::S1) num_bits |= 1;
+ if (config_bits[config_cursor++] == State::S1) num_bits |= 2;
+ if (config_bits[config_cursor++] == State::S1) num_bits |= 4;
+ if (config_bits[config_cursor++] == State::S1) num_bits |= 8;
int port_a_cursor = 0;
while (port_a_cursor < GetSize(port_a))
@@ -124,12 +124,12 @@ struct Macc
log_assert(config_cursor + 2 + 2*num_bits <= config_width);
port_t this_port;
- this_port.is_signed = config_bits[config_cursor++] == RTLIL::S1;
- this_port.do_subtract = config_bits[config_cursor++] == RTLIL::S1;
+ this_port.is_signed = config_bits[config_cursor++] == State::S1;
+ this_port.do_subtract = config_bits[config_cursor++] == State::S1;
int size_a = 0;
for (int i = 0; i < num_bits; i++)
- if (config_bits[config_cursor++] == RTLIL::S1)
+ if (config_bits[config_cursor++] == State::S1)
size_a |= 1 << i;
this_port.in_a = port_a.extract(port_a_cursor, size_a);
@@ -137,7 +137,7 @@ struct Macc
int size_b = 0;
for (int i = 0; i < num_bits; i++)
- if (config_bits[config_cursor++] == RTLIL::S1)
+ if (config_bits[config_cursor++] == State::S1)
size_b |= 1 << i;
this_port.in_b = port_a.extract(port_a_cursor, size_b);
@@ -166,43 +166,43 @@ struct Macc
num_bits++, max_size /= 2;
log_assert(num_bits < 16);
- config_bits.push_back(num_bits & 1 ? RTLIL::S1 : RTLIL::S0);
- config_bits.push_back(num_bits & 2 ? RTLIL::S1 : RTLIL::S0);
- config_bits.push_back(num_bits & 4 ? RTLIL::S1 : RTLIL::S0);
- config_bits.push_back(num_bits & 8 ? RTLIL::S1 : RTLIL::S0);
+ config_bits.push_back(num_bits & 1 ? State::S1 : State::S0);
+ config_bits.push_back(num_bits & 2 ? State::S1 : State::S0);
+ config_bits.push_back(num_bits & 4 ? State::S1 : State::S0);
+ config_bits.push_back(num_bits & 8 ? State::S1 : State::S0);
for (auto &port : ports)
{
if (GetSize(port.in_a) == 0)
continue;
- config_bits.push_back(port.is_signed ? RTLIL::S1 : RTLIL::S0);
- config_bits.push_back(port.do_subtract ? RTLIL::S1 : RTLIL::S0);
+ config_bits.push_back(port.is_signed ? State::S1 : State::S0);
+ config_bits.push_back(port.do_subtract ? State::S1 : State::S0);
int size_a = GetSize(port.in_a);
for (int i = 0; i < num_bits; i++)
- config_bits.push_back(size_a & (1 << i) ? RTLIL::S1 : RTLIL::S0);
+ config_bits.push_back(size_a & (1 << i) ? State::S1 : State::S0);
int size_b = GetSize(port.in_b);
for (int i = 0; i < num_bits; i++)
- config_bits.push_back(size_b & (1 << i) ? RTLIL::S1 : RTLIL::S0);
+ config_bits.push_back(size_b & (1 << i) ? State::S1 : State::S0);
port_a.append(port.in_a);
port_a.append(port.in_b);
}
- cell->setPort("\\A", port_a);
- cell->setPort("\\B", bit_ports);
- cell->setParam("\\CONFIG", config_bits);
- cell->setParam("\\CONFIG_WIDTH", GetSize(config_bits));
- cell->setParam("\\A_WIDTH", GetSize(port_a));
- cell->setParam("\\B_WIDTH", GetSize(bit_ports));
+ cell->setPort(ID::A, port_a);
+ cell->setPort(ID::B, bit_ports);
+ cell->setParam(ID(CONFIG), config_bits);
+ cell->setParam(ID(CONFIG_WIDTH), GetSize(config_bits));
+ cell->setParam(ID(A_WIDTH), GetSize(port_a));
+ cell->setParam(ID(B_WIDTH), GetSize(bit_ports));
}
bool eval(RTLIL::Const &result) const
{
for (auto &bit : result.bits)
- bit = RTLIL::S0;
+ bit = State::S0;
for (auto &port : ports)
{
diff --git a/kernel/modtools.h b/kernel/modtools.h
index ffcb48d44..409562eb9 100644
--- a/kernel/modtools.h
+++ b/kernel/modtools.h
@@ -1,4 +1,4 @@
-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
@@ -158,7 +158,7 @@ struct ModIndex : public RTLIL::Monitor
#endif
}
- virtual void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
+ void notify_connect(RTLIL::Cell *cell, const RTLIL::IdString &port, const RTLIL::SigSpec &old_sig, RTLIL::SigSpec &sig) YS_OVERRIDE
{
log_assert(module == cell->module);
@@ -169,7 +169,7 @@ struct ModIndex : public RTLIL::Monitor
port_add(cell, port, sig);
}
- virtual void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const RTLIL::SigSig &sigsig) YS_OVERRIDE
+ void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const RTLIL::SigSig &sigsig) YS_OVERRIDE
{
log_assert(module == mod);
@@ -214,13 +214,13 @@ struct ModIndex : public RTLIL::Monitor
}
}
- virtual void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const std::vector<RTLIL::SigSig>&) YS_OVERRIDE
+ void notify_connect(RTLIL::Module *mod YS_ATTRIBUTE(unused), const std::vector<RTLIL::SigSig>&) YS_OVERRIDE
{
log_assert(module == mod);
auto_reload_module = true;
}
- virtual void notify_blackout(RTLIL::Module *mod YS_ATTRIBUTE(unused)) YS_OVERRIDE
+ void notify_blackout(RTLIL::Module *mod YS_ATTRIBUTE(unused)) YS_OVERRIDE
{
log_assert(module == mod);
auto_reload_module = true;
diff --git a/kernel/register.cc b/kernel/register.cc
index 983577682..e59d59654 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -25,6 +25,65 @@
#include <stdio.h>
#include <errno.h>
+#ifdef YOSYS_ENABLE_ZLIB
+#include <zlib.h>
+
+PRIVATE_NAMESPACE_BEGIN
+#define GZ_BUFFER_SIZE 8192
+void decompress_gzip(const std::string &filename, std::stringstream &out)
+{
+ char buffer[GZ_BUFFER_SIZE];
+ int bytes_read;
+ gzFile gzf = gzopen(filename.c_str(), "rb");
+ while(!gzeof(gzf)) {
+ bytes_read = gzread(gzf, reinterpret_cast<void *>(buffer), GZ_BUFFER_SIZE);
+ out.write(buffer, bytes_read);
+ }
+ gzclose(gzf);
+}
+
+/*
+An output stream that uses a stringbuf to buffer data internally,
+using zlib to write gzip-compressed data every time the stream is flushed.
+*/
+class gzip_ostream : public std::ostream {
+public:
+ gzip_ostream() : std::ostream(nullptr)
+ {
+ rdbuf(&outbuf);
+ }
+ bool open(const std::string &filename)
+ {
+ return outbuf.open(filename);
+ }
+private:
+ class gzip_streambuf : public std::stringbuf {
+ public:
+ gzip_streambuf() { };
+ bool open(const std::string &filename)
+ {
+ gzf = gzopen(filename.c_str(), "wb");
+ return gzf != nullptr;
+ }
+ virtual int sync() override
+ {
+ gzwrite(gzf, reinterpret_cast<const void *>(str().c_str()), unsigned(str().size()));
+ str("");
+ return 0;
+ }
+ virtual ~gzip_streambuf()
+ {
+ sync();
+ gzclose(gzf);
+ }
+ private:
+ gzFile gzf = nullptr;
+ } outbuf;
+};
+PRIVATE_NAMESPACE_END
+
+#endif
+
YOSYS_NAMESPACE_BEGIN
#define MAX_REG_COUNT 1000
@@ -55,20 +114,35 @@ void Pass::run_register()
void Pass::init_register()
{
+ vector<Pass*> added_passes;
while (first_queued_pass) {
+ added_passes.push_back(first_queued_pass);
first_queued_pass->run_register();
first_queued_pass = first_queued_pass->next_queued_pass;
}
+ for (auto added_pass : added_passes)
+ added_pass->on_register();
}
void Pass::done_register()
{
+ for (auto &it : pass_register)
+ it.second->on_shutdown();
+
frontend_register.clear();
pass_register.clear();
backend_register.clear();
log_assert(first_queued_pass == NULL);
}
+void Pass::on_register()
+{
+}
+
+void Pass::on_shutdown()
+{
+}
+
Pass::~Pass()
{
}
@@ -86,6 +160,9 @@ Pass::pre_post_exec_state_t Pass::pre_execute()
void Pass::post_execute(Pass::pre_post_exec_state_t state)
{
+ IdString::checkpoint();
+ log_suppressed();
+
int64_t time_ns = PerformanceTimer::query() - state.begin_ns;
runtime_ns += time_ns;
current_pass = state.parent_pass;
@@ -138,7 +215,7 @@ void Pass::extra_args(std::vector<std::string> args, size_t argidx, RTLIL::Desig
{
std::string arg = args[argidx];
- if (arg.substr(0, 1) == "-")
+ if (arg.compare(0, 1, "-") == 0)
cmd_error(args, argidx, "Unknown option or option in arguments.");
if (!select)
@@ -227,14 +304,15 @@ void Pass::call(RTLIL::Design *design, std::vector<std::string> args)
if (pass_register.count(args[0]) == 0)
log_cmd_error("No such command: %s (type 'help' for a command overview)\n", args[0].c_str());
+ if (pass_register[args[0]]->experimental_flag)
+ log_experimental("%s", args[0].c_str());
+
size_t orig_sel_stack_pos = design->selection_stack.size();
auto state = pass_register[args[0]]->pre_execute();
pass_register[args[0]]->execute(args, design);
pass_register[args[0]]->post_execute(state);
while (design->selection_stack.size() > orig_sel_stack_pos)
design->selection_stack.pop_back();
-
- design->check();
}
void Pass::call_on_selection(RTLIL::Design *design, const RTLIL::Selection &selection, std::string command)
@@ -316,8 +394,10 @@ void ScriptPass::run(std::string command, std::string info)
log(" %s\n", command.c_str());
else
log(" %s %s\n", command.c_str(), info.c_str());
- } else
+ } else {
Pass::call(active_design, command);
+ active_design->check();
+ }
}
void ScriptPass::run_script(RTLIL::Design *design, std::string run_from, std::string run_to)
@@ -377,7 +457,7 @@ void Frontend::execute(std::vector<std::string> args, RTLIL::Design *design)
FILE *Frontend::current_script_file = NULL;
std::string Frontend::last_here_document;
-void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx)
+void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_input)
{
bool called_with_fp = f != NULL;
@@ -387,7 +467,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
{
std::string arg = args[argidx];
- if (arg.substr(0, 1) == "-")
+ if (arg.compare(0, 1, "-") == 0)
cmd_error(args, argidx, "Unknown option or option in arguments.");
if (f != NULL)
cmd_error(args, argidx, "Extra filename argument in direct file mode.");
@@ -395,7 +475,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
filename = arg;
if (filename == "<<" && argidx+1 < args.size())
filename += args[++argidx];
- if (filename.substr(0, 2) == "<<") {
+ if (filename.compare(0, 2, "<<") == 0) {
if (Frontend::current_script_file == NULL)
log_error("Unexpected here document '%s' outside of script!\n", filename.c_str());
if (filename.size() <= 2)
@@ -413,7 +493,7 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
break;
}
size_t indent = buffer.find_first_not_of(" \t\r\n");
- if (indent != std::string::npos && buffer.substr(indent, eot_marker.size()) == eot_marker)
+ if (indent != std::string::npos && buffer.compare(indent, eot_marker.size(), eot_marker) == 0)
break;
last_here_document += buffer;
}
@@ -427,17 +507,48 @@ void Frontend::extra_args(std::istream *&f, std::string &filename, std::vector<s
next_args.insert(next_args.end(), filenames.begin()+1, filenames.end());
}
std::ifstream *ff = new std::ifstream;
- ff->open(filename.c_str());
+ ff->open(filename.c_str(), bin_input ? std::ifstream::binary : std::ifstream::in);
+ yosys_input_files.insert(filename);
if (ff->fail())
delete ff;
else
f = ff;
+ if (f != NULL) {
+ // Check for gzip magic
+ unsigned char magic[3];
+ int n = 0;
+ while (n < 3)
+ {
+ int c = ff->get();
+ if (c != EOF) {
+ magic[n] = (unsigned char) c;
+ }
+ n++;
+ }
+ if (n == 3 && magic[0] == 0x1f && magic[1] == 0x8b) {
+ #ifdef YOSYS_ENABLE_ZLIB
+ log("Found gzip magic in file `%s', decompressing using zlib.\n", filename.c_str());
+ if (magic[2] != 8)
+ log_cmd_error("gzip file `%s' uses unsupported compression type %02x\n",
+ filename.c_str(), unsigned(magic[2]));
+ delete ff;
+ std::stringstream *df = new std::stringstream();
+ decompress_gzip(filename, *df);
+ f = df;
+ #else
+ log_cmd_error("File `%s' is a gzip file, but Yosys is compiled without zlib.\n", filename.c_str());
+ #endif
+ } else {
+ ff->clear();
+ ff->seekg(0, std::ios::beg);
+ }
+ }
}
if (f == NULL)
log_cmd_error("Can't open input file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
for (size_t i = argidx+1; i < args.size(); i++)
- if (args[i].substr(0, 1) == "-")
+ if (args[i].compare(0, 1, "-") == 0)
cmd_error(args, i, "Found option, expected arguments.");
if (argidx+1 < args.size()) {
@@ -488,8 +599,6 @@ void Frontend::frontend_call(RTLIL::Design *design, std::istream *f, std::string
args.push_back(filename);
frontend_register[args[0]]->execute(args, design);
}
-
- design->check();
}
Backend::Backend(std::string name, std::string short_help) :
@@ -521,7 +630,7 @@ void Backend::execute(std::vector<std::string> args, RTLIL::Design *design)
delete f;
}
-void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx)
+void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_output)
{
bool called_with_fp = f != NULL;
@@ -529,7 +638,7 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
{
std::string arg = args[argidx];
- if (arg.substr(0, 1) == "-" && arg != "-")
+ if (arg.compare(0, 1, "-") == 0 && arg != "-")
cmd_error(args, argidx, "Unknown option or option in arguments.");
if (f != NULL)
cmd_error(args, argidx, "Extra filename argument in direct file mode.");
@@ -541,13 +650,29 @@ void Backend::extra_args(std::ostream *&f, std::string &filename, std::vector<st
}
filename = arg;
- std::ofstream *ff = new std::ofstream;
- ff->open(filename.c_str(), std::ofstream::trunc);
- if (ff->fail()) {
- delete ff;
- log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ rewrite_filename(filename);
+ if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".gz") == 0) {
+#ifdef YOSYS_ENABLE_ZLIB
+ gzip_ostream *gf = new gzip_ostream;
+ if (!gf->open(filename)) {
+ delete gf;
+ log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ }
+ yosys_output_files.insert(filename);
+ f = gf;
+#else
+ log_cmd_error("Yosys is compiled without zlib support, unable to write gzip output.\n");
+#endif
+ } else {
+ std::ofstream *ff = new std::ofstream;
+ ff->open(filename.c_str(), bin_output ? (std::ofstream::trunc | std::ofstream::binary) : std::ofstream::trunc);
+ yosys_output_files.insert(filename);
+ if (ff->fail()) {
+ delete ff;
+ log_cmd_error("Can't open output file `%s' for writing: %s\n", filename.c_str(), strerror(errno));
+ }
+ f = ff;
}
- f = ff;
}
if (called_with_fp)
@@ -597,8 +722,6 @@ void Backend::backend_call(RTLIL::Design *design, std::ostream *f, std::string f
while (design->selection_stack.size() > orig_sel_stack_pos)
design->selection_stack.pop_back();
-
- design->check();
}
static struct CellHelpMessages {
@@ -613,7 +736,7 @@ static struct CellHelpMessages {
struct HelpPass : public Pass {
HelpPass() : Pass("help", "display help messages") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
log("\n");
log(" help ................ list all commands\n");
@@ -682,7 +805,7 @@ struct HelpPass : public Pass {
fclose(f);
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design*)
+ void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE
{
if (args.size() == 1) {
log("\n");
@@ -704,6 +827,11 @@ struct HelpPass : public Pass {
log("=");
log("\n");
it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
}
}
else if (args[1] == "-cells") {
@@ -726,6 +854,11 @@ struct HelpPass : public Pass {
std::ostringstream buf;
log_streams.push_back(&buf);
it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
log_streams.pop_back();
write_tex(f, it.first, it.second->short_help, buf.str());
}
@@ -738,6 +871,11 @@ struct HelpPass : public Pass {
std::ostringstream buf;
log_streams.push_back(&buf);
it.second->help();
+ if (it.second->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", it.first.c_str());
+ log("\n");
+ }
log_streams.pop_back();
write_html(f, it.first, it.second->short_help, buf.str());
}
@@ -745,6 +883,11 @@ struct HelpPass : public Pass {
}
else if (pass_register.count(args[1])) {
pass_register.at(args[1])->help();
+ if (pass_register.at(args[1])->experimental_flag) {
+ log("\n");
+ log("WARNING: THE '%s' COMMAND IS EXPERIMENTAL.\n", args[1].c_str());
+ log("\n");
+ }
}
else if (cell_help_messages.cell_help.count(args[1])) {
log("%s", cell_help_messages.cell_help.at(args[1]).c_str());
@@ -766,7 +909,7 @@ struct HelpPass : public Pass {
struct EchoPass : public Pass {
EchoPass() : Pass("echo", "turning echoing back of commands on and off") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
log("\n");
log(" echo on\n");
@@ -779,7 +922,7 @@ struct EchoPass : public Pass {
log("Do not print all commands to log before executing them. (default)\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design*)
+ void execute(std::vector<std::string> args, RTLIL::Design*) YS_OVERRIDE
{
if (args.size() > 2)
cmd_error(args, 2, "Unexpected argument.");
@@ -804,10 +947,9 @@ struct MinisatSatSolver : public SatSolver {
MinisatSatSolver() : SatSolver("minisat") {
yosys_satsolver = this;
}
- virtual ezSAT *create() YS_OVERRIDE {
+ ezSAT *create() YS_OVERRIDE {
return new ezMiniSAT();
}
} MinisatSatSolver;
YOSYS_NAMESPACE_END
-
diff --git a/kernel/register.h b/kernel/register.h
index 8024c56a0..4622845b6 100644
--- a/kernel/register.h
+++ b/kernel/register.h
@@ -1,4 +1,4 @@
-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
@@ -36,6 +36,11 @@ struct Pass
int call_counter;
int64_t runtime_ns;
+ bool experimental_flag = false;
+
+ void experimental() {
+ experimental_flag = true;
+ }
struct pre_post_exec_state_t {
Pass *parent_pass;
@@ -62,6 +67,9 @@ struct Pass
virtual void run_register();
static void init_register();
static void done_register();
+
+ virtual void on_register();
+ virtual void on_shutdown();
};
struct ScriptPass : Pass
@@ -88,13 +96,13 @@ struct Frontend : Pass
std::string frontend_name;
Frontend(std::string name, std::string short_help = "** document me **");
- virtual void run_register() YS_OVERRIDE;
- virtual ~Frontend();
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL;
+ void run_register() YS_OVERRIDE;
+ ~Frontend() YS_OVERRIDE;
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL;
virtual void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) = 0;
static std::vector<std::string> next_args;
- void extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx);
+ void extra_args(std::istream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_input = false);
static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command);
static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::vector<std::string> args);
@@ -104,12 +112,12 @@ struct Backend : Pass
{
std::string backend_name;
Backend(std::string name, std::string short_help = "** document me **");
- virtual void run_register() YS_OVERRIDE;
- virtual ~Backend();
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL;
+ void run_register() YS_OVERRIDE;
+ ~Backend() YS_OVERRIDE;
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE YS_FINAL;
virtual void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) = 0;
- void extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx);
+ void extra_args(std::ostream *&f, std::string &filename, std::vector<std::string> args, size_t argidx, bool bin_output = false);
static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::string command);
static void backend_call(RTLIL::Design *design, std::ostream *f, std::string filename, std::vector<std::string> args);
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc
index 8c3d2962c..f286d139f 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -29,10 +29,24 @@
YOSYS_NAMESPACE_BEGIN
RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard;
-std::vector<int> RTLIL::IdString::global_refcount_storage_;
std::vector<char*> RTLIL::IdString::global_id_storage_;
dict<char*, int, hash_cstr_ops> RTLIL::IdString::global_id_index_;
+#ifndef YOSYS_NO_IDS_REFCNT
+std::vector<int> RTLIL::IdString::global_refcount_storage_;
std::vector<int> RTLIL::IdString::global_free_idx_list_;
+#endif
+#ifdef YOSYS_USE_STICKY_IDS
+int RTLIL::IdString::last_created_idx_[8];
+int RTLIL::IdString::last_created_idx_ptr_;
+#endif
+
+IdString RTLIL::ID::A;
+IdString RTLIL::ID::B;
+IdString RTLIL::ID::Y;
+IdString RTLIL::ID::keep;
+IdString RTLIL::ID::whitebox;
+IdString RTLIL::ID::blackbox;
+dict<std::string, std::string> RTLIL::constpad;
RTLIL::Const::Const()
{
@@ -45,7 +59,7 @@ RTLIL::Const::Const(std::string str)
for (int i = str.size()-1; i >= 0; i--) {
unsigned char ch = str[i];
for (int j = 0; j < 8; j++) {
- bits.push_back((ch & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
+ bits.push_back((ch & 1) != 0 ? State::S1 : State::S0);
ch = ch >> 1;
}
}
@@ -55,7 +69,7 @@ RTLIL::Const::Const(int val, int width)
{
flags = RTLIL::CONST_FLAG_NONE;
for (int i = 0; i < width; i++) {
- bits.push_back((val & 1) != 0 ? RTLIL::S1 : RTLIL::S0);
+ bits.push_back((val & 1) != 0 ? State::S1 : State::S0);
val = val >> 1;
}
}
@@ -71,7 +85,14 @@ RTLIL::Const::Const(const std::vector<bool> &bits)
{
flags = RTLIL::CONST_FLAG_NONE;
for (auto b : bits)
- this->bits.push_back(b ? RTLIL::S1 : RTLIL::S0);
+ this->bits.push_back(b ? State::S1 : State::S0);
+}
+
+RTLIL::Const::Const(const RTLIL::Const &c)
+{
+ flags = c.flags;
+ for (auto b : c.bits)
+ this->bits.push_back(b);
}
bool RTLIL::Const::operator <(const RTLIL::Const &other) const
@@ -97,7 +118,7 @@ bool RTLIL::Const::operator !=(const RTLIL::Const &other) const
bool RTLIL::Const::as_bool() const
{
for (size_t i = 0; i < bits.size(); i++)
- if (bits[i] == RTLIL::S1)
+ if (bits[i] == State::S1)
return true;
return false;
}
@@ -106,9 +127,9 @@ int RTLIL::Const::as_int(bool is_signed) const
{
int32_t ret = 0;
for (size_t i = 0; i < bits.size() && i < 32; i++)
- if (bits[i] == RTLIL::S1)
+ if (bits[i] == State::S1)
ret |= 1 << i;
- if (is_signed && bits.back() == RTLIL::S1)
+ if (is_signed && bits.back() == State::S1)
for (size_t i = bits.size(); i < 32; i++)
ret |= 1 << i;
return ret;
@@ -172,6 +193,17 @@ bool RTLIL::Const::is_fully_zero() const
return true;
}
+bool RTLIL::Const::is_fully_ones() const
+{
+ cover("kernel.rtlil.const.is_fully_ones");
+
+ for (auto bit : bits)
+ if (bit != RTLIL::State::S1)
+ return false;
+
+ return true;
+}
+
bool RTLIL::Const::is_fully_def() const
{
cover("kernel.rtlil.const.is_fully_def");
@@ -194,16 +226,23 @@ bool RTLIL::Const::is_fully_undef() const
return true;
}
-void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id)
+void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value)
{
- attributes[id] = RTLIL::Const(1);
+ if (value)
+ attributes[id] = RTLIL::Const(1);
+ else {
+ const auto it = attributes.find(id);
+ if (it != attributes.end())
+ attributes.erase(it);
+ }
}
bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const
{
- if (attributes.count(id) == 0)
+ const auto it = attributes.find(id);
+ if (it == attributes.end())
return false;
- return attributes.at(id).as_bool();
+ return it->second.as_bool();
}
void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool<string> &data)
@@ -237,16 +276,16 @@ pool<string> RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const
void RTLIL::AttrObject::set_src_attribute(const std::string &src)
{
if (src.empty())
- attributes.erase("\\src");
+ attributes.erase(ID(src));
else
- attributes["\\src"] = src;
+ attributes[ID(src)] = src;
}
std::string RTLIL::AttrObject::get_src_attribute() const
{
std::string src;
- if (attributes.count("\\src"))
- src = attributes.at("\\src").decode_string();
+ if (attributes.count(ID(src)))
+ src = attributes.at(ID(src)).decode_string();
return src;
}
@@ -347,6 +386,10 @@ RTLIL::Design::Design()
refcount_modules_ = 0;
selection_stack.push_back(RTLIL::Selection());
+
+#ifdef WITH_PYTHON
+ RTLIL::Design::get_all_designs()->insert(std::pair<unsigned int, RTLIL::Design*>(hashidx_, this));
+#endif
}
RTLIL::Design::~Design()
@@ -357,8 +400,19 @@ RTLIL::Design::~Design()
delete n;
for (auto n : verilog_globals)
delete n;
+#ifdef WITH_PYTHON
+ RTLIL::Design::get_all_designs()->erase(hashidx_);
+#endif
}
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Design*> all_designs;
+std::map<unsigned int, RTLIL::Design*> *RTLIL::Design::get_all_designs(void)
+{
+ return &all_designs;
+}
+#endif
+
RTLIL::ObjRange<RTLIL::Module*> RTLIL::Design::modules()
{
return RTLIL::ObjRange<RTLIL::Module*>(&modules_, &refcount_modules_);
@@ -375,7 +429,7 @@ RTLIL::Module *RTLIL::Design::top_module()
int module_count = 0;
for (auto mod : selected_modules()) {
- if (mod->get_bool_attribute("\\top"))
+ if (mod->get_bool_attribute(ID(top)))
return mod;
module_count++;
module = mod;
@@ -576,7 +630,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
+ if (selected_module(it.first) && !it.second->get_blackbox_attribute())
result.push_back(it.second);
return result;
}
@@ -586,7 +640,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (selected_whole_module(it.first) && !it.second->get_bool_attribute("\\blackbox"))
+ if (selected_whole_module(it.first) && !it.second->get_blackbox_attribute())
result.push_back(it.second);
return result;
}
@@ -596,7 +650,7 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_whole_modules_warn() const
std::vector<RTLIL::Module*> result;
result.reserve(modules_.size());
for (auto &it : modules_)
- if (it.second->get_bool_attribute("\\blackbox"))
+ if (it.second->get_blackbox_attribute())
continue;
else if (selected_whole_module(it.first))
result.push_back(it.second);
@@ -614,6 +668,10 @@ RTLIL::Module::Module()
design = nullptr;
refcount_wires_ = 0;
refcount_cells_ = 0;
+
+#ifdef WITH_PYTHON
+ RTLIL::Module::get_all_modules()->insert(std::pair<unsigned int, RTLIL::Module*>(hashidx_, this));
+#endif
}
RTLIL::Module::~Module()
@@ -626,10 +684,60 @@ RTLIL::Module::~Module()
delete it->second;
for (auto it = processes.begin(); it != processes.end(); ++it)
delete it->second;
+#ifdef WITH_PYTHON
+ RTLIL::Module::get_all_modules()->erase(hashidx_);
+#endif
}
-RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>)
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Module*> all_modules;
+std::map<unsigned int, RTLIL::Module*> *RTLIL::Module::get_all_modules(void)
{
+ return &all_modules;
+}
+#endif
+
+void RTLIL::Module::makeblackbox()
+{
+ pool<RTLIL::Wire*> delwires;
+
+ for (auto it = wires_.begin(); it != wires_.end(); ++it)
+ if (!it->second->port_input && !it->second->port_output)
+ delwires.insert(it->second);
+
+ for (auto it = memories.begin(); it != memories.end(); ++it)
+ delete it->second;
+ memories.clear();
+
+ for (auto it = cells_.begin(); it != cells_.end(); ++it)
+ delete it->second;
+ cells_.clear();
+
+ for (auto it = processes.begin(); it != processes.end(); ++it)
+ delete it->second;
+ processes.clear();
+
+ remove(delwires);
+ set_bool_attribute(ID::blackbox);
+}
+
+void RTLIL::Module::reprocess_module(RTLIL::Design *, dict<RTLIL::IdString, RTLIL::Module *>)
+{
+ log_error("Cannot reprocess_module module `%s' !\n", id2cstr(name));
+}
+
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, bool mayfail)
+{
+ if (mayfail)
+ return RTLIL::IdString();
+ log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
+}
+
+
+RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, dict<RTLIL::IdString, RTLIL::Const>, dict<RTLIL::IdString, RTLIL::Module*>, dict<RTLIL::IdString, RTLIL::IdString>, bool mayfail)
+{
+ if (mayfail)
+ return RTLIL::IdString();
log_error("Module `%s' is used with parameters but is not parametric!\n", id2cstr(name));
}
@@ -658,7 +766,7 @@ namespace {
cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str());
}
- int param(const char *name)
+ int param(RTLIL::IdString name)
{
if (cell->parameters.count(name) == 0)
error(__LINE__);
@@ -666,7 +774,7 @@ namespace {
return cell->parameters.at(name).as_int();
}
- int param_bool(const char *name)
+ int param_bool(RTLIL::IdString name)
{
int v = param(name);
if (cell->parameters.at(name).bits.size() > 32)
@@ -676,14 +784,22 @@ namespace {
return v;
}
- void param_bits(const char *name, int width)
+ int param_bool(RTLIL::IdString name, bool expected)
+ {
+ int v = param_bool(name);
+ if (v != expected)
+ error(__LINE__);
+ return v;
+ }
+
+ void param_bits(RTLIL::IdString name, int width)
{
param(name);
if (int(cell->parameters.at(name).bits.size()) != width)
error(__LINE__);
}
- void port(const char *name, int width)
+ void port(RTLIL::IdString name, int width)
{
if (!cell->hasPort(name))
error(__LINE__);
@@ -701,9 +817,9 @@ namespace {
if (expected_ports.count(conn.first) == 0)
error(__LINE__);
- if (expected_params.count("\\A_SIGNED") != 0 && expected_params.count("\\B_SIGNED") && check_matched_sign) {
- bool a_is_signed = param("\\A_SIGNED") != 0;
- bool b_is_signed = param("\\B_SIGNED") != 0;
+ if (expected_params.count(ID(A_SIGNED)) != 0 && expected_params.count(ID(B_SIGNED)) && check_matched_sign) {
+ bool a_is_signed = param(ID(A_SIGNED)) != 0;
+ bool b_is_signed = param(ID(B_SIGNED)) != 0;
if (a_is_signed != b_is_signed)
error(__LINE__);
}
@@ -732,441 +848,492 @@ namespace {
void check()
{
- if (cell->type.substr(0, 1) != "$" || cell->type.substr(0, 3) == "$__" || cell->type.substr(0, 8) == "$paramod" ||
- cell->type.substr(0, 9) == "$verific$" || cell->type.substr(0, 7) == "$array:" || cell->type.substr(0, 8) == "$extern:")
+ if (!cell->type.begins_with("$") || cell->type.begins_with("$__") || cell->type.begins_with("$paramod") || cell->type.begins_with("$fmcombine") ||
+ cell->type.begins_with("$verific$") || cell->type.begins_with("$array:") || cell->type.begins_with("$extern:"))
return;
- if (cell->type.in("$not", "$pos", "$neg")) {
- param_bool("\\A_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
+ if (cell->type.in(ID($not), ID($pos), ID($neg))) {
+ param_bool(ID(A_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
check_expected();
return;
}
- if (cell->type.in("$and", "$or", "$xor", "$xnor")) {
- param_bool("\\A_SIGNED");
- param_bool("\\B_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
+ if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor))) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
check_expected();
return;
}
- if (cell->type.in("$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool")) {
- param_bool("\\A_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool))) {
+ param_bool(ID(A_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
check_expected();
return;
}
- if (cell->type.in("$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx")) {
- param_bool("\\A_SIGNED");
- param_bool("\\B_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
- check_expected(false);
+ if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED), /*expected=*/false);
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
+ check_expected(/*check_matched_sign=*/false);
return;
}
- if (cell->type.in("$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt")) {
- param_bool("\\A_SIGNED");
- param_bool("\\B_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
+ if (cell->type.in(ID($shift), ID($shiftx))) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
+ check_expected(/*check_matched_sign=*/false);
+ return;
+ }
+
+ if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt))) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
check_expected();
return;
}
- if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$pow")) {
- param_bool("\\A_SIGNED");
- param_bool("\\B_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
- check_expected(cell->type != "$pow");
+ if (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow))) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
+ check_expected(cell->type != ID($pow));
return;
}
- if (cell->type == "$fa") {
- port("\\A", param("\\WIDTH"));
- port("\\B", param("\\WIDTH"));
- port("\\C", param("\\WIDTH"));
- port("\\X", param("\\WIDTH"));
- port("\\Y", param("\\WIDTH"));
+ if (cell->type == ID($fa)) {
+ port(ID::A, param(ID(WIDTH)));
+ port(ID::B, param(ID(WIDTH)));
+ port(ID(C), param(ID(WIDTH)));
+ port(ID(X), param(ID(WIDTH)));
+ port(ID::Y, param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$lcu") {
- port("\\P", param("\\WIDTH"));
- port("\\G", param("\\WIDTH"));
- port("\\CI", 1);
- port("\\CO", param("\\WIDTH"));
+ if (cell->type == ID($lcu)) {
+ port(ID(P), param(ID(WIDTH)));
+ port(ID(G), param(ID(WIDTH)));
+ port(ID(CI), 1);
+ port(ID(CO), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$alu") {
- param_bool("\\A_SIGNED");
- param_bool("\\B_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\CI", 1);
- port("\\BI", 1);
- port("\\X", param("\\Y_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
- port("\\CO", param("\\Y_WIDTH"));
+ if (cell->type == ID($alu)) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID(CI), 1);
+ port(ID(BI), 1);
+ port(ID(X), param(ID(Y_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
+ port(ID(CO), param(ID(Y_WIDTH)));
check_expected();
return;
}
- if (cell->type == "$macc") {
- param("\\CONFIG");
- param("\\CONFIG_WIDTH");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
+ if (cell->type == ID($macc)) {
+ param(ID(CONFIG));
+ param(ID(CONFIG_WIDTH));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
check_expected();
Macc().from_cell(cell);
return;
}
- if (cell->type == "$logic_not") {
- param_bool("\\A_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
+ if (cell->type == ID($logic_not)) {
+ param_bool(ID(A_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
check_expected();
return;
}
- if (cell->type == "$logic_and" || cell->type == "$logic_or") {
- param_bool("\\A_SIGNED");
- param_bool("\\B_SIGNED");
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
- check_expected(false);
+ if (cell->type.in(ID($logic_and), ID($logic_or))) {
+ param_bool(ID(A_SIGNED));
+ param_bool(ID(B_SIGNED));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
+ check_expected(/*check_matched_sign=*/false);
return;
}
- if (cell->type == "$slice") {
- param("\\OFFSET");
- port("\\A", param("\\A_WIDTH"));
- port("\\Y", param("\\Y_WIDTH"));
- if (param("\\OFFSET") + param("\\Y_WIDTH") > param("\\A_WIDTH"))
+ if (cell->type == ID($slice)) {
+ param(ID(OFFSET));
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::Y, param(ID(Y_WIDTH)));
+ if (param(ID(OFFSET)) + param(ID(Y_WIDTH)) > param(ID(A_WIDTH)))
error(__LINE__);
check_expected();
return;
}
- if (cell->type == "$concat") {
- port("\\A", param("\\A_WIDTH"));
- port("\\B", param("\\B_WIDTH"));
- port("\\Y", param("\\A_WIDTH") + param("\\B_WIDTH"));
+ if (cell->type == ID($concat)) {
+ port(ID::A, param(ID(A_WIDTH)));
+ port(ID::B, param(ID(B_WIDTH)));
+ port(ID::Y, param(ID(A_WIDTH)) + param(ID(B_WIDTH)));
+ check_expected();
+ return;
+ }
+
+ if (cell->type == ID($mux)) {
+ port(ID::A, param(ID(WIDTH)));
+ port(ID::B, param(ID(WIDTH)));
+ port(ID(S), 1);
+ port(ID::Y, param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$mux") {
- port("\\A", param("\\WIDTH"));
- port("\\B", param("\\WIDTH"));
- port("\\S", 1);
- port("\\Y", param("\\WIDTH"));
+ if (cell->type == ID($pmux)) {
+ port(ID::A, param(ID(WIDTH)));
+ port(ID::B, param(ID(WIDTH)) * param(ID(S_WIDTH)));
+ port(ID(S), param(ID(S_WIDTH)));
+ port(ID::Y, param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$pmux") {
- port("\\A", param("\\WIDTH"));
- port("\\B", param("\\WIDTH") * param("\\S_WIDTH"));
- port("\\S", param("\\S_WIDTH"));
- port("\\Y", param("\\WIDTH"));
+ if (cell->type == ID($lut)) {
+ param(ID(LUT));
+ port(ID::A, param(ID(WIDTH)));
+ port(ID::Y, 1);
check_expected();
return;
}
- if (cell->type == "$lut") {
- param("\\LUT");
- port("\\A", param("\\WIDTH"));
- port("\\Y", 1);
+ if (cell->type == ID($sop)) {
+ param(ID(DEPTH));
+ param(ID(TABLE));
+ port(ID::A, param(ID(WIDTH)));
+ port(ID::Y, 1);
check_expected();
return;
}
- if (cell->type == "$sop") {
- param("\\DEPTH");
- param("\\TABLE");
- port("\\A", param("\\WIDTH"));
- port("\\Y", 1);
+ if (cell->type == ID($sr)) {
+ param_bool(ID(SET_POLARITY));
+ param_bool(ID(CLR_POLARITY));
+ port(ID(SET), param(ID(WIDTH)));
+ port(ID(CLR), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$sr") {
- param_bool("\\SET_POLARITY");
- param_bool("\\CLR_POLARITY");
- port("\\SET", param("\\WIDTH"));
- port("\\CLR", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($ff)) {
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$ff") {
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($dff)) {
+ param_bool(ID(CLK_POLARITY));
+ port(ID(CLK), 1);
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$dff") {
- param_bool("\\CLK_POLARITY");
- port("\\CLK", 1);
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($dffe)) {
+ param_bool(ID(CLK_POLARITY));
+ param_bool(ID(EN_POLARITY));
+ port(ID(CLK), 1);
+ port(ID(EN), 1);
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$dffe") {
- param_bool("\\CLK_POLARITY");
- param_bool("\\EN_POLARITY");
- port("\\CLK", 1);
- port("\\EN", 1);
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($dffsr)) {
+ param_bool(ID(CLK_POLARITY));
+ param_bool(ID(SET_POLARITY));
+ param_bool(ID(CLR_POLARITY));
+ port(ID(CLK), 1);
+ port(ID(SET), param(ID(WIDTH)));
+ port(ID(CLR), param(ID(WIDTH)));
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$dffsr") {
- param_bool("\\CLK_POLARITY");
- param_bool("\\SET_POLARITY");
- param_bool("\\CLR_POLARITY");
- port("\\CLK", 1);
- port("\\SET", param("\\WIDTH"));
- port("\\CLR", param("\\WIDTH"));
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($adff)) {
+ param_bool(ID(CLK_POLARITY));
+ param_bool(ID(ARST_POLARITY));
+ param_bits(ID(ARST_VALUE), param(ID(WIDTH)));
+ port(ID(CLK), 1);
+ port(ID(ARST), 1);
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$adff") {
- param_bool("\\CLK_POLARITY");
- param_bool("\\ARST_POLARITY");
- param_bits("\\ARST_VALUE", param("\\WIDTH"));
- port("\\CLK", 1);
- port("\\ARST", 1);
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($dlatch)) {
+ param_bool(ID(EN_POLARITY));
+ port(ID(EN), 1);
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$dlatch") {
- param_bool("\\EN_POLARITY");
- port("\\EN", 1);
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($dlatchsr)) {
+ param_bool(ID(EN_POLARITY));
+ param_bool(ID(SET_POLARITY));
+ param_bool(ID(CLR_POLARITY));
+ port(ID(EN), 1);
+ port(ID(SET), param(ID(WIDTH)));
+ port(ID(CLR), param(ID(WIDTH)));
+ port(ID(D), param(ID(WIDTH)));
+ port(ID(Q), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$dlatchsr") {
- param_bool("\\EN_POLARITY");
- param_bool("\\SET_POLARITY");
- param_bool("\\CLR_POLARITY");
- port("\\EN", 1);
- port("\\SET", param("\\WIDTH"));
- port("\\CLR", param("\\WIDTH"));
- port("\\D", param("\\WIDTH"));
- port("\\Q", param("\\WIDTH"));
+ if (cell->type == ID($fsm)) {
+ param(ID(NAME));
+ param_bool(ID(CLK_POLARITY));
+ param_bool(ID(ARST_POLARITY));
+ param(ID(STATE_BITS));
+ param(ID(STATE_NUM));
+ param(ID(STATE_NUM_LOG2));
+ param(ID(STATE_RST));
+ param_bits(ID(STATE_TABLE), param(ID(STATE_BITS)) * param(ID(STATE_NUM)));
+ param(ID(TRANS_NUM));
+ param_bits(ID(TRANS_TABLE), param(ID(TRANS_NUM)) * (2*param(ID(STATE_NUM_LOG2)) + param(ID(CTRL_IN_WIDTH)) + param(ID(CTRL_OUT_WIDTH))));
+ port(ID(CLK), 1);
+ port(ID(ARST), 1);
+ port(ID(CTRL_IN), param(ID(CTRL_IN_WIDTH)));
+ port(ID(CTRL_OUT), param(ID(CTRL_OUT_WIDTH)));
check_expected();
return;
}
- if (cell->type == "$fsm") {
- param("\\NAME");
- param_bool("\\CLK_POLARITY");
- param_bool("\\ARST_POLARITY");
- param("\\STATE_BITS");
- param("\\STATE_NUM");
- param("\\STATE_NUM_LOG2");
- param("\\STATE_RST");
- param_bits("\\STATE_TABLE", param("\\STATE_BITS") * param("\\STATE_NUM"));
- param("\\TRANS_NUM");
- param_bits("\\TRANS_TABLE", param("\\TRANS_NUM") * (2*param("\\STATE_NUM_LOG2") + param("\\CTRL_IN_WIDTH") + param("\\CTRL_OUT_WIDTH")));
- port("\\CLK", 1);
- port("\\ARST", 1);
- port("\\CTRL_IN", param("\\CTRL_IN_WIDTH"));
- port("\\CTRL_OUT", param("\\CTRL_OUT_WIDTH"));
+ if (cell->type == ID($memrd)) {
+ param(ID(MEMID));
+ param_bool(ID(CLK_ENABLE));
+ param_bool(ID(CLK_POLARITY));
+ param_bool(ID(TRANSPARENT));
+ port(ID(CLK), 1);
+ port(ID(EN), 1);
+ port(ID(ADDR), param(ID(ABITS)));
+ port(ID(DATA), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$memrd") {
- param("\\MEMID");
- param_bool("\\CLK_ENABLE");
- param_bool("\\CLK_POLARITY");
- param_bool("\\TRANSPARENT");
- port("\\CLK", 1);
- port("\\EN", 1);
- port("\\ADDR", param("\\ABITS"));
- port("\\DATA", param("\\WIDTH"));
+ if (cell->type == ID($memwr)) {
+ param(ID(MEMID));
+ param_bool(ID(CLK_ENABLE));
+ param_bool(ID(CLK_POLARITY));
+ param(ID(PRIORITY));
+ port(ID(CLK), 1);
+ port(ID(EN), param(ID(WIDTH)));
+ port(ID(ADDR), param(ID(ABITS)));
+ port(ID(DATA), param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$memwr") {
- param("\\MEMID");
- param_bool("\\CLK_ENABLE");
- param_bool("\\CLK_POLARITY");
- param("\\PRIORITY");
- port("\\CLK", 1);
- port("\\EN", param("\\WIDTH"));
- port("\\ADDR", param("\\ABITS"));
- port("\\DATA", param("\\WIDTH"));
+ if (cell->type == ID($meminit)) {
+ param(ID(MEMID));
+ param(ID(PRIORITY));
+ port(ID(ADDR), param(ID(ABITS)));
+ port(ID(DATA), param(ID(WIDTH)) * param(ID(WORDS)));
check_expected();
return;
}
- if (cell->type == "$meminit") {
- param("\\MEMID");
- param("\\PRIORITY");
- port("\\ADDR", param("\\ABITS"));
- port("\\DATA", param("\\WIDTH") * param("\\WORDS"));
+ if (cell->type == ID($mem)) {
+ param(ID(MEMID));
+ param(ID(SIZE));
+ param(ID(OFFSET));
+ param(ID(INIT));
+ param_bits(ID(RD_CLK_ENABLE), max(1, param(ID(RD_PORTS))));
+ param_bits(ID(RD_CLK_POLARITY), max(1, param(ID(RD_PORTS))));
+ param_bits(ID(RD_TRANSPARENT), max(1, param(ID(RD_PORTS))));
+ param_bits(ID(WR_CLK_ENABLE), max(1, param(ID(WR_PORTS))));
+ param_bits(ID(WR_CLK_POLARITY), max(1, param(ID(WR_PORTS))));
+ port(ID(RD_CLK), param(ID(RD_PORTS)));
+ port(ID(RD_EN), param(ID(RD_PORTS)));
+ port(ID(RD_ADDR), param(ID(RD_PORTS)) * param(ID(ABITS)));
+ port(ID(RD_DATA), param(ID(RD_PORTS)) * param(ID(WIDTH)));
+ port(ID(WR_CLK), param(ID(WR_PORTS)));
+ port(ID(WR_EN), param(ID(WR_PORTS)) * param(ID(WIDTH)));
+ port(ID(WR_ADDR), param(ID(WR_PORTS)) * param(ID(ABITS)));
+ port(ID(WR_DATA), param(ID(WR_PORTS)) * param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type == "$mem") {
- param("\\MEMID");
- param("\\SIZE");
- param("\\OFFSET");
- param("\\INIT");
- param_bits("\\RD_CLK_ENABLE", max(1, param("\\RD_PORTS")));
- param_bits("\\RD_CLK_POLARITY", max(1, param("\\RD_PORTS")));
- param_bits("\\RD_TRANSPARENT", max(1, param("\\RD_PORTS")));
- param_bits("\\WR_CLK_ENABLE", max(1, param("\\WR_PORTS")));
- param_bits("\\WR_CLK_POLARITY", max(1, param("\\WR_PORTS")));
- port("\\RD_CLK", param("\\RD_PORTS"));
- port("\\RD_EN", param("\\RD_PORTS"));
- port("\\RD_ADDR", param("\\RD_PORTS") * param("\\ABITS"));
- port("\\RD_DATA", param("\\RD_PORTS") * param("\\WIDTH"));
- port("\\WR_CLK", param("\\WR_PORTS"));
- port("\\WR_EN", param("\\WR_PORTS") * param("\\WIDTH"));
- port("\\WR_ADDR", param("\\WR_PORTS") * param("\\ABITS"));
- port("\\WR_DATA", param("\\WR_PORTS") * param("\\WIDTH"));
+ if (cell->type == ID($tribuf)) {
+ port(ID::A, param(ID(WIDTH)));
+ port(ID::Y, param(ID(WIDTH)));
+ port(ID(EN), 1);
check_expected();
return;
}
- if (cell->type == "$tribuf") {
- port("\\A", param("\\WIDTH"));
- port("\\Y", param("\\WIDTH"));
- port("\\EN", 1);
+ if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
+ port(ID::A, 1);
+ port(ID(EN), 1);
check_expected();
return;
}
- if (cell->type.in("$assert", "$assume", "$live", "$fair", "$cover")) {
- port("\\A", 1);
- port("\\EN", 1);
+ if (cell->type == ID($initstate)) {
+ port(ID::Y, 1);
check_expected();
return;
}
- if (cell->type == "$initstate") {
- port("\\Y", 1);
+ if (cell->type.in(ID($anyconst), ID($anyseq), ID($allconst), ID($allseq))) {
+ port(ID::Y, param(ID(WIDTH)));
check_expected();
return;
}
- if (cell->type.in("$anyconst", "$anyseq")) {
- port("\\Y", param("\\WIDTH"));
+ if (cell->type == ID($equiv)) {
+ port(ID::A, 1);
+ port(ID::B, 1);
+ port(ID::Y, 1);
check_expected();
return;
}
- if (cell->type == "$equiv") {
- port("\\A", 1);
- port("\\B", 1);
- port("\\Y", 1);
+ if (cell->type.in(ID($specify2), ID($specify3))) {
+ param_bool(ID(FULL));
+ param_bool(ID(SRC_DST_PEN));
+ param_bool(ID(SRC_DST_POL));
+ param(ID(T_RISE_MIN));
+ param(ID(T_RISE_TYP));
+ param(ID(T_RISE_MAX));
+ param(ID(T_FALL_MIN));
+ param(ID(T_FALL_TYP));
+ param(ID(T_FALL_MAX));
+ port(ID(EN), 1);
+ port(ID(SRC), param(ID(SRC_WIDTH)));
+ port(ID(DST), param(ID(DST_WIDTH)));
+ if (cell->type == ID($specify3)) {
+ param_bool(ID(EDGE_EN));
+ param_bool(ID(EDGE_POL));
+ param_bool(ID(DAT_DST_PEN));
+ param_bool(ID(DAT_DST_POL));
+ port(ID(DAT), param(ID(DST_WIDTH)));
+ }
check_expected();
return;
}
- if (cell->type == "$_BUF_") { check_gate("AY"); return; }
- if (cell->type == "$_NOT_") { check_gate("AY"); return; }
- if (cell->type == "$_AND_") { check_gate("ABY"); return; }
- if (cell->type == "$_NAND_") { check_gate("ABY"); return; }
- if (cell->type == "$_OR_") { check_gate("ABY"); return; }
- if (cell->type == "$_NOR_") { check_gate("ABY"); return; }
- if (cell->type == "$_XOR_") { check_gate("ABY"); return; }
- if (cell->type == "$_XNOR_") { check_gate("ABY"); return; }
- if (cell->type == "$_ANDNOT_") { check_gate("ABY"); return; }
- if (cell->type == "$_ORNOT_") { check_gate("ABY"); return; }
- if (cell->type == "$_MUX_") { check_gate("ABSY"); return; }
- if (cell->type == "$_AOI3_") { check_gate("ABCY"); return; }
- if (cell->type == "$_OAI3_") { check_gate("ABCY"); return; }
- if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; }
- if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; }
-
- if (cell->type == "$_TBUF_") { check_gate("AYE"); return; }
-
- if (cell->type == "$_MUX4_") { check_gate("ABCDSTY"); return; }
- if (cell->type == "$_MUX8_") { check_gate("ABCDEFGHSTUY"); return; }
- if (cell->type == "$_MUX16_") { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; }
-
- if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; }
- if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; }
- if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; }
- if (cell->type == "$_SR_PP_") { check_gate("SRQ"); return; }
-
- if (cell->type == "$_FF_") { check_gate("DQ"); return; }
- if (cell->type == "$_DFF_N_") { check_gate("DQC"); return; }
- if (cell->type == "$_DFF_P_") { check_gate("DQC"); return; }
-
- if (cell->type == "$_DFFE_NN_") { check_gate("DQCE"); return; }
- if (cell->type == "$_DFFE_NP_") { check_gate("DQCE"); return; }
- if (cell->type == "$_DFFE_PN_") { check_gate("DQCE"); return; }
- if (cell->type == "$_DFFE_PP_") { check_gate("DQCE"); return; }
-
- if (cell->type == "$_DFF_NN0_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_NN1_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_NP0_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_NP1_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_PN0_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_PN1_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_PP0_") { check_gate("DQCR"); return; }
- if (cell->type == "$_DFF_PP1_") { check_gate("DQCR"); return; }
-
- if (cell->type == "$_DFFSR_NNN_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_NNP_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_NPN_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_NPP_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_PNN_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_PNP_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_PPN_") { check_gate("CSRDQ"); return; }
- if (cell->type == "$_DFFSR_PPP_") { check_gate("CSRDQ"); return; }
-
- if (cell->type == "$_DLATCH_N_") { check_gate("EDQ"); return; }
- if (cell->type == "$_DLATCH_P_") { check_gate("EDQ"); return; }
-
- if (cell->type == "$_DLATCHSR_NNN_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_NNP_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_NPN_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_NPP_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_PNN_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_PNP_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_PPN_") { check_gate("ESRDQ"); return; }
- if (cell->type == "$_DLATCHSR_PPP_") { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($specrule)) {
+ param(ID(TYPE));
+ param_bool(ID(SRC_PEN));
+ param_bool(ID(SRC_POL));
+ param_bool(ID(DST_PEN));
+ param_bool(ID(DST_POL));
+ param(ID(T_LIMIT));
+ param(ID(T_LIMIT2));
+ port(ID(SRC_EN), 1);
+ port(ID(DST_EN), 1);
+ port(ID(SRC), param(ID(SRC_WIDTH)));
+ port(ID(DST), param(ID(DST_WIDTH)));
+ check_expected();
+ return;
+ }
+
+ if (cell->type == ID($_BUF_)) { check_gate("AY"); return; }
+ if (cell->type == ID($_NOT_)) { check_gate("AY"); return; }
+ if (cell->type == ID($_AND_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_NAND_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_OR_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_NOR_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_XOR_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_XNOR_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_ANDNOT_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_ORNOT_)) { check_gate("ABY"); return; }
+ if (cell->type == ID($_MUX_)) { check_gate("ABSY"); return; }
+ if (cell->type == ID($_NMUX_)) { check_gate("ABSY"); return; }
+ if (cell->type == ID($_AOI3_)) { check_gate("ABCY"); return; }
+ if (cell->type == ID($_OAI3_)) { check_gate("ABCY"); return; }
+ if (cell->type == ID($_AOI4_)) { check_gate("ABCDY"); return; }
+ if (cell->type == ID($_OAI4_)) { check_gate("ABCDY"); return; }
+
+ if (cell->type == ID($_TBUF_)) { check_gate("AYE"); return; }
+
+ if (cell->type == ID($_MUX4_)) { check_gate("ABCDSTY"); return; }
+ if (cell->type == ID($_MUX8_)) { check_gate("ABCDEFGHSTUY"); return; }
+ if (cell->type == ID($_MUX16_)) { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; }
+
+ if (cell->type == ID($_SR_NN_)) { check_gate("SRQ"); return; }
+ if (cell->type == ID($_SR_NP_)) { check_gate("SRQ"); return; }
+ if (cell->type == ID($_SR_PN_)) { check_gate("SRQ"); return; }
+ if (cell->type == ID($_SR_PP_)) { check_gate("SRQ"); return; }
+
+ if (cell->type == ID($_FF_)) { check_gate("DQ"); return; }
+ if (cell->type == ID($_DFF_N_)) { check_gate("DQC"); return; }
+ if (cell->type == ID($_DFF_P_)) { check_gate("DQC"); return; }
+
+ if (cell->type == ID($_DFFE_NN_)) { check_gate("DQCE"); return; }
+ if (cell->type == ID($_DFFE_NP_)) { check_gate("DQCE"); return; }
+ if (cell->type == ID($_DFFE_PN_)) { check_gate("DQCE"); return; }
+ if (cell->type == ID($_DFFE_PP_)) { check_gate("DQCE"); return; }
+
+ if (cell->type == ID($_DFF_NN0_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_NN1_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_NP0_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_NP1_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_PN0_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_PN1_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_PP0_)) { check_gate("DQCR"); return; }
+ if (cell->type == ID($_DFF_PP1_)) { check_gate("DQCR"); return; }
+
+ if (cell->type == ID($_DFFSR_NNN_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_NNP_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_NPN_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_NPP_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_PNN_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_PNP_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_PPN_)) { check_gate("CSRDQ"); return; }
+ if (cell->type == ID($_DFFSR_PPP_)) { check_gate("CSRDQ"); return; }
+
+ if (cell->type == ID($_DLATCH_N_)) { check_gate("EDQ"); return; }
+ if (cell->type == ID($_DLATCH_P_)) { check_gate("EDQ"); return; }
+
+ if (cell->type == ID($_DLATCHSR_NNN_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_NNP_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_NPN_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_NPP_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_PNN_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_PNP_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_PPN_)) { check_gate("ESRDQ"); return; }
+ if (cell->type == ID($_DLATCHSR_PPP_)) { check_gate("ESRDQ"); return; }
error(__LINE__);
}
@@ -1245,7 +1412,34 @@ void RTLIL::Module::check()
for (auto &it : processes) {
log_assert(it.first == it.second->name);
log_assert(!it.first.empty());
- // FIXME: More checks here..
+ log_assert(it.second->root_case.compare.empty());
+ std::vector<CaseRule*> all_cases = {&it.second->root_case};
+ for (size_t i = 0; i < all_cases.size(); i++) {
+ for (auto &switch_it : all_cases[i]->switches) {
+ for (auto &case_it : switch_it->cases) {
+ for (auto &compare_it : case_it->compare) {
+ log_assert(switch_it->signal.size() == compare_it.size());
+ }
+ all_cases.push_back(case_it);
+ }
+ }
+ }
+ for (auto &sync_it : it.second->syncs) {
+ switch (sync_it->type) {
+ case SyncType::ST0:
+ case SyncType::ST1:
+ case SyncType::STp:
+ case SyncType::STn:
+ case SyncType::STe:
+ log_assert(!sync_it->signal.empty());
+ break;
+ case SyncType::STa:
+ case SyncType::STg:
+ case SyncType::STi:
+ log_assert(sync_it->signal.empty());
+ break;
+ }
+ }
}
for (auto &it : connections_) {
@@ -1353,7 +1547,7 @@ std::vector<RTLIL::Wire*> RTLIL::Module::selected_wires() const
std::vector<RTLIL::Cell*> RTLIL::Module::selected_cells() const
{
std::vector<RTLIL::Cell*> result;
- result.reserve(wires_.size());
+ result.reserve(cells_.size());
for (auto &it : cells_)
if (design->selected(this, it.second))
result.push_back(it.second);
@@ -1378,7 +1572,10 @@ void RTLIL::Module::add(RTLIL::Cell *cell)
cell->module = this;
}
-namespace {
+void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
+{
+ log_assert(refcount_wires_ == 0);
+
struct DeleteWireWorker
{
RTLIL::Module *module;
@@ -1393,17 +1590,29 @@ namespace {
}
sig = chunks;
}
- };
-}
-void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires)
-{
- log_assert(refcount_wires_ == 0);
+ void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) {
+ log_assert(GetSize(lhs) == GetSize(rhs));
+ RTLIL::SigSpec new_lhs, new_rhs;
+ for (int i = 0; i < GetSize(lhs); i++) {
+ RTLIL::SigBit lhs_bit = lhs[i];
+ if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire))
+ continue;
+ RTLIL::SigBit rhs_bit = rhs[i];
+ if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire))
+ continue;
+ new_lhs.append(lhs_bit);
+ new_rhs.append(rhs_bit);
+ }
+ lhs = new_lhs;
+ rhs = new_rhs;
+ }
+ };
DeleteWireWorker delete_wire_worker;
delete_wire_worker.module = this;
delete_wire_worker.wires_p = &wires;
- rewrite_sigspecs(delete_wire_worker);
+ rewrite_sigspecs2(delete_wire_worker);
for (auto &it : wires) {
log_assert(wires_.count(it->name) != 0);
@@ -1638,11 +1847,11 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth
#define DEF_METHOD(_func, _y_size, _type) \
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters["\\A_SIGNED"] = is_signed; \
- cell->parameters["\\A_WIDTH"] = sig_a.size(); \
- cell->parameters["\\Y_WIDTH"] = sig_y.size(); \
- cell->setPort("\\A", sig_a); \
- cell->setPort("\\Y", sig_y); \
+ cell->parameters[ID(A_SIGNED)] = is_signed; \
+ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
+ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->setPort(ID::A, sig_a); \
+ cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
@@ -1651,28 +1860,28 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth
add ## _func(name, sig_a, sig_y, is_signed, src); \
return sig_y; \
}
-DEF_METHOD(Not, sig_a.size(), "$not")
-DEF_METHOD(Pos, sig_a.size(), "$pos")
-DEF_METHOD(Neg, sig_a.size(), "$neg")
-DEF_METHOD(ReduceAnd, 1, "$reduce_and")
-DEF_METHOD(ReduceOr, 1, "$reduce_or")
-DEF_METHOD(ReduceXor, 1, "$reduce_xor")
-DEF_METHOD(ReduceXnor, 1, "$reduce_xnor")
-DEF_METHOD(ReduceBool, 1, "$reduce_bool")
-DEF_METHOD(LogicNot, 1, "$logic_not")
+DEF_METHOD(Not, sig_a.size(), ID($not))
+DEF_METHOD(Pos, sig_a.size(), ID($pos))
+DEF_METHOD(Neg, sig_a.size(), ID($neg))
+DEF_METHOD(ReduceAnd, 1, ID($reduce_and))
+DEF_METHOD(ReduceOr, 1, ID($reduce_or))
+DEF_METHOD(ReduceXor, 1, ID($reduce_xor))
+DEF_METHOD(ReduceXnor, 1, ID($reduce_xnor))
+DEF_METHOD(ReduceBool, 1, ID($reduce_bool))
+DEF_METHOD(LogicNot, 1, ID($logic_not))
#undef DEF_METHOD
#define DEF_METHOD(_func, _y_size, _type) \
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters["\\A_SIGNED"] = is_signed; \
- cell->parameters["\\B_SIGNED"] = is_signed; \
- cell->parameters["\\A_WIDTH"] = sig_a.size(); \
- cell->parameters["\\B_WIDTH"] = sig_b.size(); \
- cell->parameters["\\Y_WIDTH"] = sig_y.size(); \
- cell->setPort("\\A", sig_a); \
- cell->setPort("\\B", sig_b); \
- cell->setPort("\\Y", sig_y); \
+ cell->parameters[ID(A_SIGNED)] = is_signed; \
+ cell->parameters[ID(B_SIGNED)] = is_signed; \
+ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
+ cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
+ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->setPort(ID::A, sig_a); \
+ cell->setPort(ID::B, sig_b); \
+ cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
@@ -1681,42 +1890,63 @@ DEF_METHOD(LogicNot, 1, "$logic_not")
add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
return sig_y; \
}
-DEF_METHOD(And, max(sig_a.size(), sig_b.size()), "$and")
-DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), "$or")
-DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), "$xor")
-DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), "$xnor")
-DEF_METHOD(Shl, sig_a.size(), "$shl")
-DEF_METHOD(Shr, sig_a.size(), "$shr")
-DEF_METHOD(Sshl, sig_a.size(), "$sshl")
-DEF_METHOD(Sshr, sig_a.size(), "$sshr")
-DEF_METHOD(Shift, sig_a.size(), "$shift")
-DEF_METHOD(Shiftx, sig_a.size(), "$shiftx")
-DEF_METHOD(Lt, 1, "$lt")
-DEF_METHOD(Le, 1, "$le")
-DEF_METHOD(Eq, 1, "$eq")
-DEF_METHOD(Ne, 1, "$ne")
-DEF_METHOD(Eqx, 1, "$eqx")
-DEF_METHOD(Nex, 1, "$nex")
-DEF_METHOD(Ge, 1, "$ge")
-DEF_METHOD(Gt, 1, "$gt")
-DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), "$add")
-DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), "$sub")
-DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), "$mul")
-DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), "$div")
-DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), "$mod")
-DEF_METHOD(LogicAnd, 1, "$logic_and")
-DEF_METHOD(LogicOr, 1, "$logic_or")
+DEF_METHOD(And, max(sig_a.size(), sig_b.size()), ID($and))
+DEF_METHOD(Or, max(sig_a.size(), sig_b.size()), ID($or))
+DEF_METHOD(Xor, max(sig_a.size(), sig_b.size()), ID($xor))
+DEF_METHOD(Xnor, max(sig_a.size(), sig_b.size()), ID($xnor))
+DEF_METHOD(Shift, sig_a.size(), ID($shift))
+DEF_METHOD(Shiftx, sig_a.size(), ID($shiftx))
+DEF_METHOD(Lt, 1, ID($lt))
+DEF_METHOD(Le, 1, ID($le))
+DEF_METHOD(Eq, 1, ID($eq))
+DEF_METHOD(Ne, 1, ID($ne))
+DEF_METHOD(Eqx, 1, ID($eqx))
+DEF_METHOD(Nex, 1, ID($nex))
+DEF_METHOD(Ge, 1, ID($ge))
+DEF_METHOD(Gt, 1, ID($gt))
+DEF_METHOD(Add, max(sig_a.size(), sig_b.size()), ID($add))
+DEF_METHOD(Sub, max(sig_a.size(), sig_b.size()), ID($sub))
+DEF_METHOD(Mul, max(sig_a.size(), sig_b.size()), ID($mul))
+DEF_METHOD(Div, max(sig_a.size(), sig_b.size()), ID($div))
+DEF_METHOD(Mod, max(sig_a.size(), sig_b.size()), ID($mod))
+DEF_METHOD(LogicAnd, 1, ID($logic_and))
+DEF_METHOD(LogicOr, 1, ID($logic_or))
+#undef DEF_METHOD
+
+#define DEF_METHOD(_func, _y_size, _type) \
+ RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool is_signed, const std::string &src) { \
+ RTLIL::Cell *cell = addCell(name, _type); \
+ cell->parameters[ID(A_SIGNED)] = is_signed; \
+ cell->parameters[ID(B_SIGNED)] = false; \
+ cell->parameters[ID(A_WIDTH)] = sig_a.size(); \
+ cell->parameters[ID(B_WIDTH)] = sig_b.size(); \
+ cell->parameters[ID(Y_WIDTH)] = sig_y.size(); \
+ cell->setPort(ID::A, sig_a); \
+ cell->setPort(ID::B, sig_b); \
+ cell->setPort(ID::Y, sig_y); \
+ cell->set_src_attribute(src); \
+ return cell; \
+ } \
+ RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, bool is_signed, const std::string &src) { \
+ RTLIL::SigSpec sig_y = addWire(NEW_ID, _y_size); \
+ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \
+ return sig_y; \
+ }
+DEF_METHOD(Shl, sig_a.size(), ID($shl))
+DEF_METHOD(Shr, sig_a.size(), ID($shr))
+DEF_METHOD(Sshl, sig_a.size(), ID($sshl))
+DEF_METHOD(Sshr, sig_a.size(), ID($sshr))
#undef DEF_METHOD
#define DEF_METHOD(_func, _type, _pmux) \
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_s, RTLIL::SigSpec sig_y, const std::string &src) { \
RTLIL::Cell *cell = addCell(name, _type); \
- cell->parameters["\\WIDTH"] = sig_a.size(); \
- if (_pmux) cell->parameters["\\S_WIDTH"] = sig_s.size(); \
- cell->setPort("\\A", sig_a); \
- cell->setPort("\\B", sig_b); \
- cell->setPort("\\S", sig_s); \
- cell->setPort("\\Y", sig_y); \
+ cell->parameters[ID(WIDTH)] = sig_a.size(); \
+ if (_pmux) cell->parameters[ID(S_WIDTH)] = sig_s.size(); \
+ cell->setPort(ID::A, sig_a); \
+ cell->setPort(ID::B, sig_b); \
+ cell->setPort(ID(S), sig_s); \
+ cell->setPort(ID::Y, sig_y); \
cell->set_src_attribute(src); \
return cell; \
} \
@@ -1725,8 +1955,8 @@ DEF_METHOD(LogicOr, 1, "$logic_or")
add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \
return sig_y; \
}
-DEF_METHOD(Mux, "$mux", 0)
-DEF_METHOD(Pmux, "$pmux", 1)
+DEF_METHOD(Mux, ID($mux), 0)
+DEF_METHOD(Pmux, ID($pmux), 1)
#undef DEF_METHOD
#define DEF_METHOD_2(_func, _type, _P1, _P2) \
@@ -1787,21 +2017,22 @@ DEF_METHOD(Pmux, "$pmux", 1)
add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \
return sig5; \
}
-DEF_METHOD_2(BufGate, "$_BUF_", A, Y)
-DEF_METHOD_2(NotGate, "$_NOT_", A, Y)
-DEF_METHOD_3(AndGate, "$_AND_", A, B, Y)
-DEF_METHOD_3(NandGate, "$_NAND_", A, B, Y)
-DEF_METHOD_3(OrGate, "$_OR_", A, B, Y)
-DEF_METHOD_3(NorGate, "$_NOR_", A, B, Y)
-DEF_METHOD_3(XorGate, "$_XOR_", A, B, Y)
-DEF_METHOD_3(XnorGate, "$_XNOR_", A, B, Y)
-DEF_METHOD_3(AndnotGate, "$_ANDNOT_", A, B, Y)
-DEF_METHOD_3(OrnotGate, "$_ORNOT_", A, B, Y)
-DEF_METHOD_4(MuxGate, "$_MUX_", A, B, S, Y)
-DEF_METHOD_4(Aoi3Gate, "$_AOI3_", A, B, C, Y)
-DEF_METHOD_4(Oai3Gate, "$_OAI3_", A, B, C, Y)
-DEF_METHOD_5(Aoi4Gate, "$_AOI4_", A, B, C, D, Y)
-DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y)
+DEF_METHOD_2(BufGate, ID($_BUF_), A, Y)
+DEF_METHOD_2(NotGate, ID($_NOT_), A, Y)
+DEF_METHOD_3(AndGate, ID($_AND_), A, B, Y)
+DEF_METHOD_3(NandGate, ID($_NAND_), A, B, Y)
+DEF_METHOD_3(OrGate, ID($_OR_), A, B, Y)
+DEF_METHOD_3(NorGate, ID($_NOR_), A, B, Y)
+DEF_METHOD_3(XorGate, ID($_XOR_), A, B, Y)
+DEF_METHOD_3(XnorGate, ID($_XNOR_), A, B, Y)
+DEF_METHOD_3(AndnotGate, ID($_ANDNOT_), A, B, Y)
+DEF_METHOD_3(OrnotGate, ID($_ORNOT_), A, B, Y)
+DEF_METHOD_4(MuxGate, ID($_MUX_), A, B, S, Y)
+DEF_METHOD_4(NmuxGate, ID($_NMUX_), A, B, S, Y)
+DEF_METHOD_4(Aoi3Gate, ID($_AOI3_), A, B, C, Y)
+DEF_METHOD_4(Oai3Gate, ID($_OAI3_), A, B, C, Y)
+DEF_METHOD_5(Aoi4Gate, ID($_AOI4_), A, B, C, D, Y)
+DEF_METHOD_5(Oai4Gate, ID($_OAI4_), A, B, C, D, Y)
#undef DEF_METHOD_2
#undef DEF_METHOD_3
#undef DEF_METHOD_4
@@ -1809,165 +2040,165 @@ DEF_METHOD_5(Oai4Gate, "$_OAI4_", A, B, C, D, Y)
RTLIL::Cell* RTLIL::Module::addPow(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, bool a_signed, bool b_signed, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$pow");
- cell->parameters["\\A_SIGNED"] = a_signed;
- cell->parameters["\\B_SIGNED"] = b_signed;
- cell->parameters["\\A_WIDTH"] = sig_a.size();
- cell->parameters["\\B_WIDTH"] = sig_b.size();
- cell->parameters["\\Y_WIDTH"] = sig_y.size();
- cell->setPort("\\A", sig_a);
- cell->setPort("\\B", sig_b);
- cell->setPort("\\Y", sig_y);
+ RTLIL::Cell *cell = addCell(name, ID($pow));
+ cell->parameters[ID(A_SIGNED)] = a_signed;
+ cell->parameters[ID(B_SIGNED)] = b_signed;
+ cell->parameters[ID(A_WIDTH)] = sig_a.size();
+ cell->parameters[ID(B_WIDTH)] = sig_b.size();
+ cell->parameters[ID(Y_WIDTH)] = sig_y.size();
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID::B, sig_b);
+ cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addSlice(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const offset, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$slice");
- cell->parameters["\\A_WIDTH"] = sig_a.size();
- cell->parameters["\\Y_WIDTH"] = sig_y.size();
- cell->parameters["\\OFFSET"] = offset;
- cell->setPort("\\A", sig_a);
- cell->setPort("\\Y", sig_y);
+ RTLIL::Cell *cell = addCell(name, ID($slice));
+ cell->parameters[ID(A_WIDTH)] = sig_a.size();
+ cell->parameters[ID(Y_WIDTH)] = sig_y.size();
+ cell->parameters[ID(OFFSET)] = offset;
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addConcat(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$concat");
- cell->parameters["\\A_WIDTH"] = sig_a.size();
- cell->parameters["\\B_WIDTH"] = sig_b.size();
- cell->setPort("\\A", sig_a);
- cell->setPort("\\B", sig_b);
- cell->setPort("\\Y", sig_y);
+ RTLIL::Cell *cell = addCell(name, ID($concat));
+ cell->parameters[ID(A_WIDTH)] = sig_a.size();
+ cell->parameters[ID(B_WIDTH)] = sig_b.size();
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID::B, sig_b);
+ cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addLut(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_y, RTLIL::Const lut, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$lut");
- cell->parameters["\\LUT"] = lut;
- cell->parameters["\\WIDTH"] = sig_a.size();
- cell->setPort("\\A", sig_a);
- cell->setPort("\\Y", sig_y);
+ RTLIL::Cell *cell = addCell(name, ID($lut));
+ cell->parameters[ID(LUT)] = lut;
+ cell->parameters[ID(WIDTH)] = sig_a.size();
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addTribuf(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_y, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$tribuf");
- cell->parameters["\\WIDTH"] = sig_a.size();
- cell->setPort("\\A", sig_a);
- cell->setPort("\\EN", sig_en);
- cell->setPort("\\Y", sig_y);
+ RTLIL::Cell *cell = addCell(name, ID($tribuf));
+ cell->parameters[ID(WIDTH)] = sig_a.size();
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addAssert(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$assert");
- cell->setPort("\\A", sig_a);
- cell->setPort("\\EN", sig_en);
+ RTLIL::Cell *cell = addCell(name, ID($assert));
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addAssume(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$assume");
- cell->setPort("\\A", sig_a);
- cell->setPort("\\EN", sig_en);
+ RTLIL::Cell *cell = addCell(name, ID($assume));
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addLive(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$live");
- cell->setPort("\\A", sig_a);
- cell->setPort("\\EN", sig_en);
+ RTLIL::Cell *cell = addCell(name, ID($live));
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addFair(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$fair");
- cell->setPort("\\A", sig_a);
- cell->setPort("\\EN", sig_en);
+ RTLIL::Cell *cell = addCell(name, ID($fair));
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addCover(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_en, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$cover");
- cell->setPort("\\A", sig_a);
- cell->setPort("\\EN", sig_en);
+ RTLIL::Cell *cell = addCell(name, ID($cover));
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID(EN), sig_en);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addEquiv(RTLIL::IdString name, RTLIL::SigSpec sig_a, RTLIL::SigSpec sig_b, RTLIL::SigSpec sig_y, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$equiv");
- cell->setPort("\\A", sig_a);
- cell->setPort("\\B", sig_b);
- cell->setPort("\\Y", sig_y);
+ RTLIL::Cell *cell = addCell(name, ID($equiv));
+ cell->setPort(ID::A, sig_a);
+ cell->setPort(ID::B, sig_b);
+ cell->setPort(ID::Y, sig_y);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addSr(RTLIL::IdString name, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr, RTLIL::SigSpec sig_q, bool set_polarity, bool clr_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$sr");
- cell->parameters["\\SET_POLARITY"] = set_polarity;
- cell->parameters["\\CLR_POLARITY"] = clr_polarity;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\SET", sig_set);
- cell->setPort("\\CLR", sig_clr);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($sr));
+ cell->parameters[ID(SET_POLARITY)] = set_polarity;
+ cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(SET), sig_set);
+ cell->setPort(ID(CLR), sig_clr);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addFf(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$ff");
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($ff));
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addDff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$dff");
- cell->parameters["\\CLK_POLARITY"] = clk_polarity;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\CLK", sig_clk);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($dff));
+ cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(CLK), sig_clk);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$dffe");
- cell->parameters["\\CLK_POLARITY"] = clk_polarity;
- cell->parameters["\\EN_POLARITY"] = en_polarity;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\CLK", sig_clk);
- cell->setPort("\\EN", sig_en);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($dffe));
+ cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
+ cell->parameters[ID(EN_POLARITY)] = en_polarity;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(CLK), sig_clk);
+ cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -1975,16 +2206,16 @@ RTLIL::Cell* RTLIL::Module::addDffe(RTLIL::IdString name, RTLIL::SigSpec sig_clk
RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$dffsr");
- cell->parameters["\\CLK_POLARITY"] = clk_polarity;
- cell->parameters["\\SET_POLARITY"] = set_polarity;
- cell->parameters["\\CLR_POLARITY"] = clr_polarity;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\CLK", sig_clk);
- cell->setPort("\\SET", sig_set);
- cell->setPort("\\CLR", sig_clr);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($dffsr));
+ cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
+ cell->parameters[ID(SET_POLARITY)] = set_polarity;
+ cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(CLK), sig_clk);
+ cell->setPort(ID(SET), sig_set);
+ cell->setPort(ID(CLR), sig_clr);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -1992,27 +2223,27 @@ RTLIL::Cell* RTLIL::Module::addDffsr(RTLIL::IdString name, RTLIL::SigSpec sig_cl
RTLIL::Cell* RTLIL::Module::addAdff(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_arst, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q,
RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$adff");
- cell->parameters["\\CLK_POLARITY"] = clk_polarity;
- cell->parameters["\\ARST_POLARITY"] = arst_polarity;
- cell->parameters["\\ARST_VALUE"] = arst_value;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\CLK", sig_clk);
- cell->setPort("\\ARST", sig_arst);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($adff));
+ cell->parameters[ID(CLK_POLARITY)] = clk_polarity;
+ cell->parameters[ID(ARST_POLARITY)] = arst_polarity;
+ cell->parameters[ID(ARST_VALUE)] = arst_value;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(CLK), sig_clk);
+ cell->setPort(ID(ARST), sig_arst);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$dlatch");
- cell->parameters["\\EN_POLARITY"] = en_polarity;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\EN", sig_en);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($dlatch));
+ cell->parameters[ID(EN_POLARITY)] = en_polarity;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2020,25 +2251,25 @@ RTLIL::Cell* RTLIL::Module::addDlatch(RTLIL::IdString name, RTLIL::SigSpec sig_e
RTLIL::Cell* RTLIL::Module::addDlatchsr(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_set, RTLIL::SigSpec sig_clr,
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$dlatchsr");
- cell->parameters["\\EN_POLARITY"] = en_polarity;
- cell->parameters["\\SET_POLARITY"] = set_polarity;
- cell->parameters["\\CLR_POLARITY"] = clr_polarity;
- cell->parameters["\\WIDTH"] = sig_q.size();
- cell->setPort("\\EN", sig_en);
- cell->setPort("\\SET", sig_set);
- cell->setPort("\\CLR", sig_clr);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($dlatchsr));
+ cell->parameters[ID(EN_POLARITY)] = en_polarity;
+ cell->parameters[ID(SET_POLARITY)] = set_polarity;
+ cell->parameters[ID(CLR_POLARITY)] = clr_polarity;
+ cell->parameters[ID(WIDTH)] = sig_q.size();
+ cell->setPort(ID(EN), sig_en);
+ cell->setPort(ID(SET), sig_set);
+ cell->setPort(ID(CLR), sig_clr);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, const std::string &src)
{
- RTLIL::Cell *cell = addCell(name, "$_FF_");
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ RTLIL::Cell *cell = addCell(name, ID($_FF_));
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2046,9 +2277,9 @@ RTLIL::Cell* RTLIL::Module::addFfGate(RTLIL::IdString name, RTLIL::SigSpec sig_d
RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N'));
- cell->setPort("\\C", sig_clk);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ cell->setPort(ID(C), sig_clk);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2056,10 +2287,10 @@ RTLIL::Cell* RTLIL::Module::addDffGate(RTLIL::IdString name, RTLIL::SigSpec sig_
RTLIL::Cell* RTLIL::Module::addDffeGate(RTLIL::IdString name, RTLIL::SigSpec sig_clk, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool en_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
- cell->setPort("\\C", sig_clk);
- cell->setPort("\\E", sig_en);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ cell->setPort(ID(C), sig_clk);
+ cell->setPort(ID(E), sig_en);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2068,11 +2299,11 @@ RTLIL::Cell* RTLIL::Module::addDffsrGate(RTLIL::IdString name, RTLIL::SigSpec si
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
- cell->setPort("\\C", sig_clk);
- cell->setPort("\\S", sig_set);
- cell->setPort("\\R", sig_clr);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ cell->setPort(ID(C), sig_clk);
+ cell->setPort(ID(S), sig_set);
+ cell->setPort(ID(R), sig_clr);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2081,10 +2312,10 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig
bool arst_value, bool clk_polarity, bool arst_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0'));
- cell->setPort("\\C", sig_clk);
- cell->setPort("\\R", sig_arst);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ cell->setPort(ID(C), sig_clk);
+ cell->setPort(ID(R), sig_arst);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2092,9 +2323,9 @@ RTLIL::Cell* RTLIL::Module::addAdffGate(RTLIL::IdString name, RTLIL::SigSpec sig
RTLIL::Cell* RTLIL::Module::addDlatchGate(RTLIL::IdString name, RTLIL::SigSpec sig_en, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N'));
- cell->setPort("\\E", sig_en);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ cell->setPort(ID(E), sig_en);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2103,11 +2334,11 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec
RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const std::string &src)
{
RTLIL::Cell *cell = addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N'));
- cell->setPort("\\E", sig_en);
- cell->setPort("\\S", sig_set);
- cell->setPort("\\R", sig_clr);
- cell->setPort("\\D", sig_d);
- cell->setPort("\\Q", sig_q);
+ cell->setPort(ID(E), sig_en);
+ cell->setPort(ID(S), sig_set);
+ cell->setPort(ID(R), sig_clr);
+ cell->setPort(ID(D), sig_d);
+ cell->setPort(ID(Q), sig_q);
cell->set_src_attribute(src);
return cell;
}
@@ -2115,9 +2346,9 @@ RTLIL::Cell* RTLIL::Module::addDlatchsrGate(RTLIL::IdString name, RTLIL::SigSpec
RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const std::string &src)
{
RTLIL::SigSpec sig = addWire(NEW_ID, width);
- Cell *cell = addCell(name, "$anyconst");
- cell->setParam("\\WIDTH", width);
- cell->setPort("\\Y", sig);
+ Cell *cell = addCell(name, ID($anyconst));
+ cell->setParam(ID(WIDTH), width);
+ cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
}
@@ -2125,9 +2356,29 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const st
RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std::string &src)
{
RTLIL::SigSpec sig = addWire(NEW_ID, width);
- Cell *cell = addCell(name, "$anyseq");
- cell->setParam("\\WIDTH", width);
- cell->setPort("\\Y", sig);
+ Cell *cell = addCell(name, ID($anyseq));
+ cell->setParam(ID(WIDTH), width);
+ cell->setPort(ID::Y, sig);
+ cell->set_src_attribute(src);
+ return sig;
+}
+
+RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const std::string &src)
+{
+ RTLIL::SigSpec sig = addWire(NEW_ID, width);
+ Cell *cell = addCell(name, ID($allconst));
+ cell->setParam(ID(WIDTH), width);
+ cell->setPort(ID::Y, sig);
+ cell->set_src_attribute(src);
+ return sig;
+}
+
+RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const std::string &src)
+{
+ RTLIL::SigSpec sig = addWire(NEW_ID, width);
+ Cell *cell = addCell(name, ID($allseq));
+ cell->setParam(ID(WIDTH), width);
+ cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
}
@@ -2135,8 +2386,8 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const std:
RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string &src)
{
RTLIL::SigSpec sig = addWire(NEW_ID);
- Cell *cell = addCell(name, "$initstate");
- cell->setPort("\\Y", sig);
+ Cell *cell = addCell(name, ID($initstate));
+ cell->setPort(ID::Y, sig);
cell->set_src_attribute(src);
return sig;
}
@@ -2154,8 +2405,27 @@ RTLIL::Wire::Wire()
port_input = false;
port_output = false;
upto = false;
+
+#ifdef WITH_PYTHON
+ RTLIL::Wire::get_all_wires()->insert(std::pair<unsigned int, RTLIL::Wire*>(hashidx_, this));
+#endif
+}
+
+RTLIL::Wire::~Wire()
+{
+#ifdef WITH_PYTHON
+ RTLIL::Wire::get_all_wires()->erase(hashidx_);
+#endif
}
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Wire*> all_wires;
+std::map<unsigned int, RTLIL::Wire*> *RTLIL::Wire::get_all_wires(void)
+{
+ return &all_wires;
+}
+#endif
+
RTLIL::Memory::Memory()
{
static unsigned int hashidx_count = 123456789;
@@ -2165,6 +2435,9 @@ RTLIL::Memory::Memory()
width = 1;
start_offset = 0;
size = 0;
+#ifdef WITH_PYTHON
+ RTLIL::Memory::get_all_memorys()->insert(std::pair<unsigned int, RTLIL::Memory*>(hashidx_, this));
+#endif
}
RTLIL::Cell::Cell() : module(nullptr)
@@ -2175,8 +2448,27 @@ RTLIL::Cell::Cell() : module(nullptr)
// log("#memtrace# %p\n", this);
memhasher();
+
+#ifdef WITH_PYTHON
+ RTLIL::Cell::get_all_cells()->insert(std::pair<unsigned int, RTLIL::Cell*>(hashidx_, this));
+#endif
}
+RTLIL::Cell::~Cell()
+{
+#ifdef WITH_PYTHON
+ RTLIL::Cell::get_all_cells()->erase(hashidx_);
+#endif
+}
+
+#ifdef WITH_PYTHON
+static std::map<unsigned int, RTLIL::Cell*> all_cells;
+std::map<unsigned int, RTLIL::Cell*> *RTLIL::Cell::get_all_cells(void)
+{
+ return &all_cells;
+}
+#endif
+
bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const
{
return connections_.count(portname) != 0;
@@ -2312,57 +2604,60 @@ void RTLIL::Cell::check()
void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
{
- if (type.substr(0, 1) != "$" || type.substr(0, 2) == "$_" || type.substr(0, 8) == "$paramod" ||
- type.substr(0, 9) == "$verific$" || type.substr(0, 7) == "$array:" || type.substr(0, 8) == "$extern:")
+ if (!type.begins_with("$") || type.begins_with("$_") || type.begins_with("$paramod") || type.begins_with("$fmcombine") ||
+ type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:"))
return;
- if (type == "$mux" || type == "$pmux") {
- parameters["\\WIDTH"] = GetSize(connections_["\\Y"]);
- if (type == "$pmux")
- parameters["\\S_WIDTH"] = GetSize(connections_["\\S"]);
+ if (type == ID($mux) || type == ID($pmux)) {
+ parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
+ if (type == ID($pmux))
+ parameters[ID(S_WIDTH)] = GetSize(connections_[ID(S)]);
check();
return;
}
- if (type == "$lut" || type == "$sop") {
- parameters["\\WIDTH"] = GetSize(connections_["\\A"]);
+ if (type == ID($lut) || type == ID($sop)) {
+ parameters[ID(WIDTH)] = GetSize(connections_[ID::A]);
return;
}
- if (type == "$fa") {
- parameters["\\WIDTH"] = GetSize(connections_["\\Y"]);
+ if (type == ID($fa)) {
+ parameters[ID(WIDTH)] = GetSize(connections_[ID::Y]);
return;
}
- if (type == "$lcu") {
- parameters["\\WIDTH"] = GetSize(connections_["\\CO"]);
+ if (type == ID($lcu)) {
+ parameters[ID(WIDTH)] = GetSize(connections_[ID(CO)]);
return;
}
- bool signedness_ab = !type.in("$slice", "$concat", "$macc");
+ bool signedness_ab = !type.in(ID($slice), ID($concat), ID($macc));
- if (connections_.count("\\A")) {
+ if (connections_.count(ID::A)) {
if (signedness_ab) {
if (set_a_signed)
- parameters["\\A_SIGNED"] = true;
- else if (parameters.count("\\A_SIGNED") == 0)
- parameters["\\A_SIGNED"] = false;
+ parameters[ID(A_SIGNED)] = true;
+ else if (parameters.count(ID(A_SIGNED)) == 0)
+ parameters[ID(A_SIGNED)] = false;
}
- parameters["\\A_WIDTH"] = GetSize(connections_["\\A"]);
+ parameters[ID(A_WIDTH)] = GetSize(connections_[ID::A]);
}
- if (connections_.count("\\B")) {
+ if (connections_.count(ID::B)) {
if (signedness_ab) {
if (set_b_signed)
- parameters["\\B_SIGNED"] = true;
- else if (parameters.count("\\B_SIGNED") == 0)
- parameters["\\B_SIGNED"] = false;
+ parameters[ID(B_SIGNED)] = true;
+ else if (parameters.count(ID(B_SIGNED)) == 0)
+ parameters[ID(B_SIGNED)] = false;
}
- parameters["\\B_WIDTH"] = GetSize(connections_["\\B"]);
+ parameters[ID(B_WIDTH)] = GetSize(connections_[ID::B]);
}
- if (connections_.count("\\Y"))
- parameters["\\Y_WIDTH"] = GetSize(connections_["\\Y"]);
+ if (connections_.count(ID::Y))
+ parameters[ID(Y_WIDTH)] = GetSize(connections_[ID::Y]);
+
+ if (connections_.count(ID(Q)))
+ parameters[ID(WIDTH)] = GetSize(connections_[ID(Q)]);
check();
}
@@ -2433,6 +2728,14 @@ RTLIL::SigChunk::SigChunk(RTLIL::SigBit bit)
width = 1;
}
+RTLIL::SigChunk::SigChunk(const RTLIL::SigChunk &sigchunk) : data(sigchunk.data)
+{
+ wire = sigchunk.wire;
+ data = sigchunk.data;
+ width = sigchunk.width;
+ offset = sigchunk.offset;
+}
+
RTLIL::SigChunk RTLIL::SigChunk::extract(int offset, int length) const
{
RTLIL::SigChunk ret;
@@ -2820,6 +3123,7 @@ void RTLIL::SigSpec::replace(const dict<RTLIL::SigBit, RTLIL::SigBit> &rules, RT
log_assert(other != NULL);
log_assert(width_ == other->width_);
+ if (rules.empty()) return;
unpack();
other->unpack();
@@ -2844,6 +3148,7 @@ void RTLIL::SigSpec::replace(const std::map<RTLIL::SigBit, RTLIL::SigBit> &rules
log_assert(other != NULL);
log_assert(width_ == other->width_);
+ if (rules.empty()) return;
unpack();
other->unpack();
@@ -3186,7 +3491,7 @@ void RTLIL::SigSpec::extend_u0(int width, bool is_signed)
remove(width, width_ - width);
if (width_ < width) {
- RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::S0;
+ RTLIL::SigBit padding = width_ > 0 ? (*this)[width_ - 1] : RTLIL::State::Sx;
if (!is_signed)
padding = RTLIL::State::S0;
while (width_ < width)
@@ -3289,10 +3594,16 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
if (width_ != other.width_)
return false;
+ // Without this, SigSpec() == SigSpec(State::S0, 0) will fail
+ // since the RHS will contain one SigChunk of width 0 causing
+ // the size check below to fail
+ if (width_ == 0)
+ return true;
+
pack();
other.pack();
- if (chunks_.size() != chunks_.size())
+ if (chunks_.size() != other.chunks_.size())
return false;
updhash();
@@ -3353,6 +3664,21 @@ bool RTLIL::SigSpec::is_fully_zero() const
return true;
}
+bool RTLIL::SigSpec::is_fully_ones() const
+{
+ cover("kernel.rtlil.sigspec.is_fully_ones");
+
+ pack();
+ for (auto it = chunks_.begin(); it != chunks_.end(); it++) {
+ if (it->width > 0 && it->wire != NULL)
+ return false;
+ for (size_t i = 0; i < it->data.size(); i++)
+ if (it->data[i] != RTLIL::State::S1)
+ return false;
+ }
+ return true;
+}
+
bool RTLIL::SigSpec::is_fully_def() const
{
cover("kernel.rtlil.sigspec.is_fully_def");
@@ -3732,6 +4058,11 @@ RTLIL::CaseRule::~CaseRule()
delete *it;
}
+bool RTLIL::CaseRule::empty() const
+{
+ return actions.empty() && switches.empty();
+}
+
RTLIL::CaseRule *RTLIL::CaseRule::clone() const
{
RTLIL::CaseRule *new_caserule = new RTLIL::CaseRule;
@@ -3748,6 +4079,11 @@ RTLIL::SwitchRule::~SwitchRule()
delete *it;
}
+bool RTLIL::SwitchRule::empty() const
+{
+ return cases.empty();
+}
+
RTLIL::SwitchRule *RTLIL::SwitchRule::clone() const
{
RTLIL::SwitchRule *new_switchrule = new RTLIL::SwitchRule;
@@ -3792,5 +4128,15 @@ RTLIL::Process *RTLIL::Process::clone() const
return new_proc;
}
+#ifdef WITH_PYTHON
+RTLIL::Memory::~Memory()
+{
+ RTLIL::Memory::get_all_memorys()->erase(hashidx_);
+}
+static std::map<unsigned int, RTLIL::Memory*> all_memorys;
+std::map<unsigned int, RTLIL::Memory*> *RTLIL::Memory::get_all_memorys(void)
+{
+ return &all_memorys;
+}
+#endif
YOSYS_NAMESPACE_END
-
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index 6ce9b6748..58c5d9674 100644
--- a/kernel/rtlil.h
+++ b/kernel/rtlil.h
@@ -1,4 +1,4 @@
-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
@@ -50,7 +50,7 @@ namespace RTLIL
CONST_FLAG_NONE = 0,
CONST_FLAG_STRING = 1,
CONST_FLAG_SIGNED = 2, // only used for parameters
- CONST_FLAG_REAL = 4 // unused -- to be used for parameters
+ CONST_FLAG_REAL = 4 // only used for parameters
};
struct Const;
@@ -76,6 +76,11 @@ namespace RTLIL
struct IdString
{
+ #undef YOSYS_XTRACE_GET_PUT
+ #undef YOSYS_SORT_ID_FREE_LIST
+ #undef YOSYS_USE_STICKY_IDS
+ #undef YOSYS_NO_IDS_REFCNT
+
// the global id string cache
static struct destruct_guard_t {
@@ -84,33 +89,89 @@ namespace RTLIL
~destruct_guard_t() { ok = false; }
} destruct_guard;
- static std::vector<int> global_refcount_storage_;
static std::vector<char*> global_id_storage_;
static dict<char*, int, hash_cstr_ops> global_id_index_;
+ #ifndef YOSYS_NO_IDS_REFCNT
+ static std::vector<int> global_refcount_storage_;
static std::vector<int> global_free_idx_list_;
+ #endif
+
+ #ifdef YOSYS_USE_STICKY_IDS
+ static int last_created_idx_ptr_;
+ static int last_created_idx_[8];
+ #endif
+
+ static inline void xtrace_db_dump()
+ {
+ #ifdef YOSYS_XTRACE_GET_PUT
+ for (int idx = 0; idx < GetSize(global_id_storage_); idx++)
+ {
+ if (global_id_storage_.at(idx) == nullptr)
+ log("#X# DB-DUMP index %d: FREE\n", idx);
+ else
+ log("#X# DB-DUMP index %d: '%s' (ref %d)\n", idx, global_id_storage_.at(idx), global_refcount_storage_.at(idx));
+ }
+ #endif
+ }
+
+ static inline void checkpoint()
+ {
+ #ifdef YOSYS_USE_STICKY_IDS
+ last_created_idx_ptr_ = 0;
+ for (int i = 0; i < 8; i++) {
+ if (last_created_idx_[i])
+ put_reference(last_created_idx_[i]);
+ last_created_idx_[i] = 0;
+ }
+ #endif
+ #ifdef YOSYS_SORT_ID_FREE_LIST
+ std::sort(global_free_idx_list_.begin(), global_free_idx_list_.end(), std::greater<int>());
+ #endif
+ }
static inline int get_reference(int idx)
{
- global_refcount_storage_.at(idx)++;
+ if (idx) {
+ #ifndef YOSYS_NO_IDS_REFCNT
+ global_refcount_storage_[idx]++;
+ #endif
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace)
+ log("#X# GET-BY-INDEX '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
+ #endif
+ }
return idx;
}
- static inline int get_reference(const char *p)
+ static int get_reference(const char *p)
{
log_assert(destruct_guard.ok);
- if (p[0]) {
- log_assert(p[1] != 0);
- log_assert(p[0] == '$' || p[0] == '\\');
- }
+ if (!p[0])
+ return 0;
+
+ log_assert(p[0] == '$' || p[0] == '\\');
+ log_assert(p[1] != 0);
auto it = global_id_index_.find((char*)p);
if (it != global_id_index_.end()) {
+ #ifndef YOSYS_NO_IDS_REFCNT
global_refcount_storage_.at(it->second)++;
+ #endif
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace)
+ log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(it->second), it->second, global_refcount_storage_.at(it->second));
+ #endif
return it->second;
}
+ #ifndef YOSYS_NO_IDS_REFCNT
if (global_free_idx_list_.empty()) {
+ if (global_id_storage_.empty()) {
+ global_refcount_storage_.push_back(0);
+ global_id_storage_.push_back((char*)"");
+ global_id_index_[global_id_storage_.back()] = 0;
+ }
log_assert(global_id_storage_.size() < 0x40000000);
global_free_idx_list_.push_back(global_id_storage_.size());
global_id_storage_.push_back(nullptr);
@@ -122,33 +183,59 @@ namespace RTLIL
global_id_storage_.at(idx) = strdup(p);
global_id_index_[global_id_storage_.at(idx)] = idx;
global_refcount_storage_.at(idx)++;
-
- // Avoid Create->Delete->Create pattern
- static IdString last_created_id;
- put_reference(last_created_id.index_);
- last_created_id.index_ = idx;
- get_reference(last_created_id.index_);
+ #else
+ if (global_id_storage_.empty()) {
+ global_id_storage_.push_back((char*)"");
+ global_id_index_[global_id_storage_.back()] = 0;
+ }
+ int idx = global_id_storage_.size();
+ global_id_storage_.push_back(strdup(p));
+ global_id_index_[global_id_storage_.back()] = idx;
+ #endif
if (yosys_xtrace) {
log("#X# New IdString '%s' with index %d.\n", p, idx);
log_backtrace("-X- ", yosys_xtrace-1);
}
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace)
+ log("#X# GET-BY-NAME '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
+ #endif
+
+ #ifdef YOSYS_USE_STICKY_IDS
+ // Avoid Create->Delete->Create pattern
+ if (last_created_idx_[last_created_idx_ptr_])
+ put_reference(last_created_idx_[last_created_idx_ptr_]);
+ last_created_idx_[last_created_idx_ptr_] = idx;
+ get_reference(last_created_idx_[last_created_idx_ptr_]);
+ last_created_idx_ptr_ = (last_created_idx_ptr_ + 1) & 7;
+ #endif
+
return idx;
}
+ #ifndef YOSYS_NO_IDS_REFCNT
static inline void put_reference(int idx)
{
// put_reference() may be called from destructors after the destructor of
// global_refcount_storage_ has been run. in this case we simply do nothing.
- if (!destruct_guard.ok)
+ if (!destruct_guard.ok || !idx)
return;
- log_assert(global_refcount_storage_.at(idx) > 0);
+ #ifdef YOSYS_XTRACE_GET_PUT
+ if (yosys_xtrace) {
+ log("#X# PUT '%s' (index %d, refcount %d)\n", global_id_storage_.at(idx), idx, global_refcount_storage_.at(idx));
+ }
+ #endif
+
+ int &refcount = global_refcount_storage_[idx];
- if (--global_refcount_storage_.at(idx) != 0)
+ if (--refcount > 0)
return;
+ log_assert(refcount == 0);
+
if (yosys_xtrace) {
log("#X# Removed IdString '%s' with index %d.\n", global_id_storage_.at(idx), idx);
log_backtrace("-X- ", yosys_xtrace-1);
@@ -159,46 +246,50 @@ namespace RTLIL
global_id_storage_.at(idx) = nullptr;
global_free_idx_list_.push_back(idx);
}
+ #else
+ static inline void put_reference(int) { }
+ #endif
// the actual IdString object is just is a single int
int index_;
- IdString() : index_(get_reference("")) { }
- IdString(const char *str) : index_(get_reference(str)) { }
- IdString(const IdString &str) : index_(get_reference(str.index_)) { }
- IdString(const std::string &str) : index_(get_reference(str.c_str())) { }
- ~IdString() { put_reference(index_); }
+ inline IdString() : index_(0) { }
+ inline IdString(const char *str) : index_(get_reference(str)) { }
+ inline IdString(const IdString &str) : index_(get_reference(str.index_)) { }
+ inline IdString(IdString &&str) : index_(str.index_) { str.index_ = 0; }
+ inline IdString(const std::string &str) : index_(get_reference(str.c_str())) { }
+ inline ~IdString() { put_reference(index_); }
- void operator=(const IdString &rhs) {
+ inline void operator=(const IdString &rhs) {
put_reference(index_);
index_ = get_reference(rhs.index_);
}
- void operator=(const char *rhs) {
+ inline void operator=(const char *rhs) {
IdString id(rhs);
*this = id;
}
- void operator=(const std::string &rhs) {
+ inline void operator=(const std::string &rhs) {
IdString id(rhs);
*this = id;
}
- const char *c_str() const {
+ inline const char *c_str() const {
return global_id_storage_.at(index_);
}
- std::string str() const {
+ inline std::string str() const {
return std::string(global_id_storage_.at(index_));
}
- bool operator<(const IdString &rhs) const {
+ inline bool operator<(const IdString &rhs) const {
return index_ < rhs.index_;
}
- bool operator==(const IdString &rhs) const { return index_ == rhs.index_; }
- bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }
+ inline bool operator==(const IdString &rhs) const { return index_ == rhs.index_; }
+ inline bool operator!=(const IdString &rhs) const { return index_ != rhs.index_; }
// The methods below are just convenience functions for better compatibility with std::string.
@@ -222,8 +313,24 @@ namespace RTLIL
return std::string(c_str() + pos, len);
}
+ int compare(size_t pos, size_t len, const char* s) const {
+ return strncmp(c_str()+pos, s, len);
+ }
+
+ bool begins_with(const char* prefix) const {
+ size_t len = strlen(prefix);
+ if (size() < len) return false;
+ return compare(0, len, prefix) == 0;
+ }
+
+ bool ends_with(const char* suffix) const {
+ size_t len = strlen(suffix);
+ if (size() < len) return false;
+ return compare(size()-len, len, suffix) == 0;
+ }
+
size_t size() const {
- return str().size();
+ return strlen(c_str());
}
bool empty() const {
@@ -262,6 +369,16 @@ namespace RTLIL
bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }
};
+ namespace ID {
+ // defined in rtlil.cc, initialized in yosys.cc
+ extern IdString A, B, Y;
+ extern IdString keep;
+ extern IdString whitebox;
+ extern IdString blackbox;
+ };
+
+ extern dict<std::string, std::string> constpad;
+
static inline std::string escape_id(std::string str) {
if (str.size() > 0 && str[0] != '\\' && str[0] != '$')
return "\\" + str;
@@ -354,8 +471,12 @@ namespace RTLIL
// It maintains a reference counter that is used to make sure that the container is not modified while being iterated over.
template<typename T>
- struct ObjIterator
- {
+ struct ObjIterator {
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = T;
+ using difference_type = ptrdiff_t;
+ using pointer = T*;
+ using reference = T&;
typename dict<RTLIL::IdString, T>::iterator it;
dict<RTLIL::IdString, T> *list_p;
int *refcount_p;
@@ -408,13 +529,25 @@ namespace RTLIL
return it != other.it;
}
- inline void operator++() {
+
+ inline bool operator==(const RTLIL::ObjIterator<T> &other) const {
+ return !(*this != other);
+ }
+
+ inline ObjIterator<T>& operator++() {
log_assert(list_p != nullptr);
if (++it == list_p->end()) {
(*refcount_p)--;
list_p = nullptr;
refcount_p = nullptr;
}
+ return *this;
+ }
+
+ inline const ObjIterator<T> operator++(int) {
+ ObjIterator<T> result(*this);
+ ++(*this);
+ return result;
}
};
@@ -463,6 +596,8 @@ struct RTLIL::Const
Const(RTLIL::State bit, int width = 1);
Const(const std::vector<RTLIL::State> &bits) : bits(bits) { flags = CONST_FLAG_NONE; }
Const(const std::vector<bool> &bits);
+ Const(const RTLIL::Const &c);
+ RTLIL::Const &operator =(const RTLIL::Const &other) = default;
bool operator <(const RTLIL::Const &other) const;
bool operator ==(const RTLIL::Const &other) const;
@@ -476,10 +611,14 @@ struct RTLIL::Const
std::string decode_string() const;
inline int size() const { return bits.size(); }
+ inline bool empty() const { return bits.empty(); }
inline RTLIL::State &operator[](int index) { return bits.at(index); }
inline const RTLIL::State &operator[](int index) const { return bits.at(index); }
+ inline decltype(bits)::iterator begin() { return bits.begin(); }
+ inline decltype(bits)::iterator end() { return bits.end(); }
bool is_fully_zero() const;
+ bool is_fully_ones() const;
bool is_fully_def() const;
bool is_fully_undef() const;
@@ -491,6 +630,14 @@ struct RTLIL::Const
return ret;
}
+ void extu(int width) {
+ bits.resize(width, RTLIL::State::S0);
+ }
+
+ void exts(int width) {
+ bits.resize(width, bits.empty() ? RTLIL::State::Sx : bits.back());
+ }
+
inline unsigned int hash() const {
unsigned int h = mkhash_init;
for (auto b : bits)
@@ -503,9 +650,13 @@ struct RTLIL::AttrObject
{
dict<RTLIL::IdString, RTLIL::Const> attributes;
- void set_bool_attribute(RTLIL::IdString id);
+ void set_bool_attribute(RTLIL::IdString id, bool value=true);
bool get_bool_attribute(RTLIL::IdString id) const;
+ bool get_blackbox_attribute(bool ignore_wb=false) const {
+ return get_bool_attribute(ID::blackbox) || (!ignore_wb && get_bool_attribute(ID::whitebox));
+ }
+
void set_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
void add_strpool_attribute(RTLIL::IdString id, const pool<string> &data);
pool<string> get_strpool_attribute(RTLIL::IdString id) const;
@@ -528,8 +679,11 @@ struct RTLIL::SigChunk
SigChunk(int val, int width = 32);
SigChunk(RTLIL::State bit, int width = 1);
SigChunk(RTLIL::SigBit bit);
+ SigChunk(const RTLIL::SigChunk &sigchunk);
+ RTLIL::SigChunk &operator =(const RTLIL::SigChunk &other) = default;
RTLIL::SigChunk extract(int offset, int length) const;
+ inline int size() const { return width; }
bool operator <(const RTLIL::SigChunk &other) const;
bool operator ==(const RTLIL::SigChunk &other) const;
@@ -552,6 +706,8 @@ struct RTLIL::SigBit
SigBit(const RTLIL::SigChunk &chunk);
SigBit(const RTLIL::SigChunk &chunk, int index);
SigBit(const RTLIL::SigSpec &sig);
+ SigBit(const RTLIL::SigBit &sigbit);
+ RTLIL::SigBit &operator =(const RTLIL::SigBit &other) = default;
bool operator <(const RTLIL::SigBit &other) const;
bool operator ==(const RTLIL::SigBit &other) const;
@@ -686,6 +842,7 @@ public:
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other = NULL) const;
RTLIL::SigSpec extract(const pool<RTLIL::SigBit> &pattern, const RTLIL::SigSpec *other = NULL) const;
RTLIL::SigSpec extract(int offset, int length = 1) const;
+ RTLIL::SigSpec extract_end(int offset) const { return extract(offset, width_ - offset); }
void append(const RTLIL::SigSpec &signal);
void append_bit(const RTLIL::SigBit &bit);
@@ -694,6 +851,8 @@ public:
RTLIL::SigSpec repeat(int num) const;
+ void reverse() { inline_unpack(); std::reverse(bits_.begin(), bits_.end()); }
+
bool operator <(const RTLIL::SigSpec &other) const;
bool operator ==(const RTLIL::SigSpec &other) const;
inline bool operator !=(const RTLIL::SigSpec &other) const { return !(*this == other); }
@@ -704,6 +863,7 @@ public:
bool is_fully_const() const;
bool is_fully_zero() const;
+ bool is_fully_ones() const;
bool is_fully_def() const;
bool is_fully_undef() const;
bool has_const() const;
@@ -731,6 +891,7 @@ public:
operator std::vector<RTLIL::SigChunk>() const { return chunks(); }
operator std::vector<RTLIL::SigBit>() const { return bits(); }
+ RTLIL::SigBit at(int offset, const RTLIL::SigBit &defval) { return offset < width_ ? (*this)[offset] : defval; }
unsigned int hash() const { if (!hash_) updhash(); return hash_; };
@@ -872,9 +1033,13 @@ struct RTLIL::Design
}
}
+
std::vector<RTLIL::Module*> selected_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules_warn() const;
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Design*> *get_all_designs(void);
+#endif
};
struct RTLIL::Module : public RTLIL::AttrObject
@@ -904,12 +1069,15 @@ public:
Module();
virtual ~Module();
- virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters);
+ virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail = false);
+ virtual RTLIL::IdString derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail = false);
virtual size_t count_id(RTLIL::IdString id);
+ virtual void reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module *> local_interfaces);
virtual void sort();
virtual void check();
virtual void optimize();
+ virtual void makeblackbox();
void connect(const RTLIL::SigSig &conn);
void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs);
@@ -920,6 +1088,7 @@ public:
void fixup_ports();
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
void cloneInto(RTLIL::Module *new_mod) const;
virtual RTLIL::Module *clone() const;
@@ -1043,6 +1212,7 @@ public:
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addMuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
+ RTLIL::Cell* addNmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_y, const std::string &src = "");
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, RTLIL::SigBit sig_y, const std::string &src = "");
@@ -1118,6 +1288,7 @@ public:
RTLIL::SigBit AndnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit OrnotGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, const std::string &src = "");
RTLIL::SigBit MuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
+ RTLIL::SigBit NmuxGate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_s, const std::string &src = "");
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, const std::string &src = "");
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, RTLIL::SigBit sig_a, RTLIL::SigBit sig_b, RTLIL::SigBit sig_c, RTLIL::SigBit sig_d, const std::string &src = "");
@@ -1125,7 +1296,13 @@ public:
RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
+ RTLIL::SigSpec Allconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
+ RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = "");
+
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Module*> *get_all_modules(void);
+#endif
};
struct RTLIL::Wire : public RTLIL::AttrObject
@@ -1137,7 +1314,7 @@ protected:
// use module->addWire() and module->remove() to create or destroy wires
friend struct RTLIL::Module;
Wire();
- ~Wire() { };
+ ~Wire();
public:
// do not simply copy wires
@@ -1148,6 +1325,10 @@ public:
RTLIL::IdString name;
int width, start_offset, port_id;
bool port_input, port_output, upto;
+
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void);
+#endif
};
struct RTLIL::Memory : public RTLIL::AttrObject
@@ -1159,6 +1340,10 @@ struct RTLIL::Memory : public RTLIL::AttrObject
RTLIL::IdString name;
int width, start_offset, size;
+#ifdef WITH_PYTHON
+ ~Memory();
+ static std::map<unsigned int, RTLIL::Memory*> *get_all_memorys(void);
+#endif
};
struct RTLIL::Cell : public RTLIL::AttrObject
@@ -1170,6 +1355,7 @@ protected:
// use module->addCell() and module->remove() to create or destroy cells
friend struct RTLIL::Module;
Cell();
+ ~Cell();
public:
// do not simply copy cells
@@ -1205,14 +1391,19 @@ public:
void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false);
bool has_keep_attr() const {
- return get_bool_attribute("\\keep") || (module && module->design && module->design->module(type) &&
- module->design->module(type)->get_bool_attribute("\\keep"));
+ return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) &&
+ module->design->module(type)->get_bool_attribute(ID::keep));
}
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
+
+#ifdef WITH_PYTHON
+ static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void);
+#endif
};
-struct RTLIL::CaseRule
+struct RTLIL::CaseRule : public RTLIL::AttrObject
{
std::vector<RTLIL::SigSpec> compare;
std::vector<RTLIL::SigSig> actions;
@@ -1221,7 +1412,10 @@ struct RTLIL::CaseRule
~CaseRule();
void optimize();
+ bool empty() const;
+
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::CaseRule *clone() const;
};
@@ -1232,7 +1426,10 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject
~SwitchRule();
+ bool empty() const;
+
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::SwitchRule *clone() const;
};
@@ -1243,6 +1440,7 @@ struct RTLIL::SyncRule
std::vector<RTLIL::SigSig> actions;
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::SyncRule *clone() const;
};
@@ -1255,24 +1453,26 @@ struct RTLIL::Process : public RTLIL::AttrObject
~Process();
template<typename T> void rewrite_sigspecs(T &functor);
+ template<typename T> void rewrite_sigspecs2(T &functor);
RTLIL::Process *clone() const;
};
inline RTLIL::SigBit::SigBit() : wire(NULL), data(RTLIL::State::S0) { }
inline RTLIL::SigBit::SigBit(RTLIL::State bit) : wire(NULL), data(bit) { }
-inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? RTLIL::S1 : RTLIL::S0) { }
+inline RTLIL::SigBit::SigBit(bool bit) : wire(NULL), data(bit ? State::S1 : State::S0) { }
inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire) : wire(wire), offset(0) { log_assert(wire && wire->width == 1); }
inline RTLIL::SigBit::SigBit(RTLIL::Wire *wire, int offset) : wire(wire), offset(offset) { log_assert(wire != nullptr); }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk) : wire(chunk.wire) { log_assert(chunk.width == 1); if (wire) offset = chunk.offset; else data = chunk.data[0]; }
inline RTLIL::SigBit::SigBit(const RTLIL::SigChunk &chunk, int index) : wire(chunk.wire) { if (wire) offset = chunk.offset + index; else data = chunk.data[index]; }
+inline RTLIL::SigBit::SigBit(const RTLIL::SigBit &sigbit) : wire(sigbit.wire), data(sigbit.data){if(wire) offset = sigbit.offset;}
inline bool RTLIL::SigBit::operator<(const RTLIL::SigBit &other) const {
if (wire == other.wire)
return wire ? (offset < other.offset) : (data < other.data);
if (wire != nullptr && other.wire != nullptr)
return wire->name < other.wire->name;
- return wire < other.wire;
+ return (wire != nullptr) < (other.wire != nullptr);
}
inline bool RTLIL::SigBit::operator==(const RTLIL::SigBit &other) const {
@@ -1316,12 +1516,30 @@ void RTLIL::Module::rewrite_sigspecs(T &functor)
}
template<typename T>
+void RTLIL::Module::rewrite_sigspecs2(T &functor)
+{
+ for (auto &it : cells_)
+ it.second->rewrite_sigspecs2(functor);
+ for (auto &it : processes)
+ it.second->rewrite_sigspecs2(functor);
+ for (auto &it : connections_) {
+ functor(it.first, it.second);
+ }
+}
+
+template<typename T>
void RTLIL::Cell::rewrite_sigspecs(T &functor) {
for (auto &it : connections_)
functor(it.second);
}
template<typename T>
+void RTLIL::Cell::rewrite_sigspecs2(T &functor) {
+ for (auto &it : connections_)
+ functor(it.second);
+}
+
+template<typename T>
void RTLIL::CaseRule::rewrite_sigspecs(T &functor) {
for (auto &it : compare)
functor(it);
@@ -1334,6 +1552,17 @@ void RTLIL::CaseRule::rewrite_sigspecs(T &functor) {
}
template<typename T>
+void RTLIL::CaseRule::rewrite_sigspecs2(T &functor) {
+ for (auto &it : compare)
+ functor(it);
+ for (auto &it : actions) {
+ functor(it.first, it.second);
+ }
+ for (auto it : switches)
+ it->rewrite_sigspecs2(functor);
+}
+
+template<typename T>
void RTLIL::SwitchRule::rewrite_sigspecs(T &functor)
{
functor(signal);
@@ -1342,6 +1571,14 @@ void RTLIL::SwitchRule::rewrite_sigspecs(T &functor)
}
template<typename T>
+void RTLIL::SwitchRule::rewrite_sigspecs2(T &functor)
+{
+ functor(signal);
+ for (auto it : cases)
+ it->rewrite_sigspecs2(functor);
+}
+
+template<typename T>
void RTLIL::SyncRule::rewrite_sigspecs(T &functor)
{
functor(signal);
@@ -1352,6 +1589,15 @@ void RTLIL::SyncRule::rewrite_sigspecs(T &functor)
}
template<typename T>
+void RTLIL::SyncRule::rewrite_sigspecs2(T &functor)
+{
+ functor(signal);
+ for (auto &it : actions) {
+ functor(it.first, it.second);
+ }
+}
+
+template<typename T>
void RTLIL::Process::rewrite_sigspecs(T &functor)
{
root_case.rewrite_sigspecs(functor);
@@ -1359,6 +1605,14 @@ void RTLIL::Process::rewrite_sigspecs(T &functor)
it->rewrite_sigspecs(functor);
}
+template<typename T>
+void RTLIL::Process::rewrite_sigspecs2(T &functor)
+{
+ root_case.rewrite_sigspecs2(functor);
+ for (auto it : syncs)
+ it->rewrite_sigspecs2(functor);
+}
+
YOSYS_NAMESPACE_END
#endif
diff --git a/kernel/satgen.h b/kernel/satgen.h
index 8d760fff7..133389eee 100644
--- a/kernel/satgen.h
+++ b/kernel/satgen.h
@@ -1,4 +1,4 @@
-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
@@ -224,8 +224,8 @@ struct SatGen
void extendSignalWidth(std::vector<int> &vec_a, std::vector<int> &vec_b, RTLIL::Cell *cell, size_t y_width = 0, bool forced_signed = false)
{
bool is_signed = forced_signed;
- if (!forced_signed && cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters.count("\\B_SIGNED") > 0)
- is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool();
+ if (!forced_signed && cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters.count(ID(B_SIGNED)) > 0)
+ is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();
while (vec_a.size() < vec_b.size() || vec_a.size() < y_width)
vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);
while (vec_b.size() < vec_a.size() || vec_b.size() < y_width)
@@ -241,7 +241,7 @@ struct SatGen
void extendSignalWidthUnary(std::vector<int> &vec_a, std::vector<int> &vec_y, RTLIL::Cell *cell, bool forced_signed = false)
{
- bool is_signed = forced_signed || (cell->parameters.count("\\A_SIGNED") > 0 && cell->parameters["\\A_SIGNED"].as_bool());
+ bool is_signed = forced_signed || (cell->parameters.count(ID(A_SIGNED)) > 0 && cell->parameters[ID(A_SIGNED)].as_bool());
while (vec_a.size() < vec_y.size())
vec_a.push_back(is_signed && vec_a.size() > 0 ? vec_a.back() : ez->CONST_FALSE);
while (vec_y.size() < vec_a.size())
@@ -277,13 +277,13 @@ struct SatGen
bool importCell(RTLIL::Cell *cell, int timestep = -1)
{
bool arith_undef_handled = false;
- bool is_arith_compare = cell->type.in("$lt", "$le", "$ge", "$gt");
+ bool is_arith_compare = cell->type.in(ID($lt), ID($le), ID($ge), ID($gt));
- if (model_undef && (cell->type.in("$add", "$sub", "$mul", "$div", "$mod") || is_arith_compare))
+ if (model_undef && (cell->type.in(ID($add), ID($sub), ID($mul), ID($div), ID($mod)) || is_arith_compare))
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
if (is_arith_compare)
extendSignalWidth(undef_a, undef_b, cell, true);
else
@@ -293,8 +293,8 @@ struct SatGen
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
int undef_y_bit = ez->OR(undef_any_a, undef_any_b);
- if (cell->type == "$div" || cell->type == "$mod") {
- std::vector<int> b = importSigSpec(cell->getPort("\\B"), timestep);
+ if (cell->type.in(ID($div), ID($mod))) {
+ std::vector<int> b = importSigSpec(cell->getPort(ID::B), timestep);
undef_y_bit = ez->OR(undef_y_bit, ez->NOT(ez->expression(ezSAT::OpOr, b)));
}
@@ -310,68 +310,68 @@ struct SatGen
arith_undef_handled = true;
}
- if (cell->type.in("$_AND_", "$_NAND_", "$_OR_", "$_NOR_", "$_XOR_", "$_XNOR_", "$_ANDNOT_", "$_ORNOT_",
- "$and", "$or", "$xor", "$xnor", "$add", "$sub"))
+ if (cell->type.in(ID($_AND_), ID($_NAND_), ID($_OR_), ID($_NOR_), ID($_XOR_), ID($_XNOR_), ID($_ANDNOT_), ID($_ORNOT_),
+ ID($and), ID($or), ID($xor), ID($xnor), ID($add), ID($sub)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
- if (cell->type == "$and" || cell->type == "$_AND_")
+ if (cell->type.in(ID($and), ID($_AND_)))
ez->assume(ez->vec_eq(ez->vec_and(a, b), yy));
- if (cell->type == "$_NAND_")
+ if (cell->type == ID($_NAND_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_and(a, b)), yy));
- if (cell->type == "$or" || cell->type == "$_OR_")
+ if (cell->type.in(ID($or), ID($_OR_)))
ez->assume(ez->vec_eq(ez->vec_or(a, b), yy));
- if (cell->type == "$_NOR_")
+ if (cell->type == ID($_NOR_))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_or(a, b)), yy));
- if (cell->type == "$xor" || cell->type == "$_XOR_")
+ if (cell->type.in(ID($xor), ID($_XOR_)))
ez->assume(ez->vec_eq(ez->vec_xor(a, b), yy));
- if (cell->type == "$xnor" || cell->type == "$_XNOR_")
+ if (cell->type.in(ID($xnor), ID($_XNOR_)))
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_xor(a, b)), yy));
- if (cell->type == "$_ANDNOT_")
+ if (cell->type == ID($_ANDNOT_))
ez->assume(ez->vec_eq(ez->vec_and(a, ez->vec_not(b)), yy));
- if (cell->type == "$_ORNOT_")
+ if (cell->type == ID($_ORNOT_))
ez->assume(ez->vec_eq(ez->vec_or(a, ez->vec_not(b)), yy));
- if (cell->type == "$add")
+ if (cell->type == ID($add))
ez->assume(ez->vec_eq(ez->vec_add(a, b), yy));
- if (cell->type == "$sub")
+ if (cell->type == ID($sub))
ez->assume(ez->vec_eq(ez->vec_sub(a, b), yy));
if (model_undef && !arith_undef_handled)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell, false);
- if (cell->type.in("$and", "$_AND_", "$_NAND_")) {
+ if (cell->type.in(ID($and), ID($_AND_), ID($_NAND_))) {
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b0)));
ez->assume(ez->vec_eq(yX, undef_y));
}
- else if (cell->type.in("$or", "$_OR_", "$_NOR_")) {
+ else if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_))) {
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b1)));
ez->assume(ez->vec_eq(yX, undef_y));
}
- else if (cell->type.in("$xor", "$xnor", "$_XOR_", "$_XNOR_")) {
+ else if (cell->type.in(ID($xor), ID($xnor), ID($_XOR_), ID($_XNOR_))) {
std::vector<int> yX = ez->vec_or(undef_a, undef_b);
ez->assume(ez->vec_eq(yX, undef_y));
}
- else if (cell->type == "$_ANDNOT_") {
+ else if (cell->type == ID($_ANDNOT_)) {
std::vector<int> a0 = ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a));
std::vector<int> b1 = ez->vec_and(b, ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a0, b1)));
ez->assume(ez->vec_eq(yX, undef_y));
}
- else if (cell->type == "$_ORNOT_") {
+ else if (cell->type == ID($_ORNOT_)) {
std::vector<int> a1 = ez->vec_and(a, ez->vec_not(undef_a));
std::vector<int> b0 = ez->vec_and(ez->vec_not(b), ez->vec_not(undef_b));
std::vector<int> yX = ez->vec_and(ez->vec_or(undef_a, undef_b), ez->vec_not(ez->vec_or(a1, b0)));
@@ -384,36 +384,36 @@ struct SatGen
}
else if (model_undef)
{
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y);
}
return true;
}
- if (cell->type.in("$_AOI3_", "$_OAI3_", "$_AOI4_", "$_OAI4_"))
+ if (cell->type.in(ID($_AOI3_), ID($_OAI3_), ID($_AOI4_), ID($_OAI4_)))
{
- bool aoi_mode = cell->type.in("$_AOI3_", "$_AOI4_");
- bool three_mode = cell->type.in("$_AOI3_", "$_OAI3_");
-
- int a = importDefSigSpec(cell->getPort("\\A"), timestep).at(0);
- int b = importDefSigSpec(cell->getPort("\\B"), timestep).at(0);
- int c = importDefSigSpec(cell->getPort("\\C"), timestep).at(0);
- int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort("\\D"), timestep).at(0);
- int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0);
+ bool aoi_mode = cell->type.in(ID($_AOI3_), ID($_AOI4_));
+ bool three_mode = cell->type.in(ID($_AOI3_), ID($_OAI3_));
+
+ int a = importDefSigSpec(cell->getPort(ID::A), timestep).at(0);
+ int b = importDefSigSpec(cell->getPort(ID::B), timestep).at(0);
+ int c = importDefSigSpec(cell->getPort(ID(C)), timestep).at(0);
+ int d = three_mode ? (aoi_mode ? ez->CONST_TRUE : ez->CONST_FALSE) : importDefSigSpec(cell->getPort(ID(D)), timestep).at(0);
+ int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
int yy = model_undef ? ez->literal() : y;
- if (cell->type.in("$_AOI3_", "$_AOI4_"))
+ if (cell->type.in(ID($_AOI3_), ID($_AOI4_)))
ez->assume(ez->IFF(ez->NOT(ez->OR(ez->AND(a, b), ez->AND(c, d))), yy));
else
ez->assume(ez->IFF(ez->NOT(ez->AND(ez->OR(a, b), ez->OR(c, d))), yy));
if (model_undef)
{
- int undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep).at(0);
- int undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep).at(0);
- int undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep).at(0);
- int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort("\\D"), timestep).at(0);
- int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0);
+ int undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep).at(0);
+ int undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep).at(0);
+ int undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep).at(0);
+ int undef_d = three_mode ? ez->CONST_FALSE : importUndefSigSpec(cell->getPort(ID(D)), timestep).at(0);
+ int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);
if (aoi_mode)
{
@@ -456,18 +456,18 @@ struct SatGen
return true;
}
- if (cell->type == "$_NOT_" || cell->type == "$not")
+ if (cell->type.in(ID($_NOT_), ID($not)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(a, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
ez->assume(ez->vec_eq(ez->vec_not(a), yy));
if (model_undef) {
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell, false);
ez->assume(ez->vec_eq(undef_a, undef_y));
undefGating(y, yy, undef_y);
@@ -475,22 +475,25 @@ struct SatGen
return true;
}
- if (cell->type == "$_MUX_" || cell->type == "$mux")
+ if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> s = importDefSigSpec(cell->getPort("\\S"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
- ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
+ if (cell->type == ID($_NMUX_))
+ ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy));
+ else
+ ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
@@ -501,12 +504,12 @@ struct SatGen
return true;
}
- if (cell->type == "$pmux")
+ if (cell->type == ID($pmux))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> s = importDefSigSpec(cell->getPort("\\S"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> s = importDefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@@ -519,10 +522,10 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_s = importUndefSigSpec(cell->getPort("\\S"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_s = importUndefSigSpec(cell->getPort(ID(S)), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int maybe_a = ez->CONST_TRUE;
@@ -552,15 +555,15 @@ struct SatGen
return true;
}
- if (cell->type == "$pos" || cell->type == "$neg")
+ if (cell->type.in(ID($pos), ID($neg)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(a, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
- if (cell->type == "$pos") {
+ if (cell->type == ID($pos)) {
ez->assume(ez->vec_eq(a, yy));
} else {
std::vector<int> zero(a.size(), ez->CONST_FALSE);
@@ -569,11 +572,11 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell);
- if (cell->type == "$pos") {
+ if (cell->type == ID($pos)) {
ez->assume(ez->vec_eq(undef_a, undef_y));
} else {
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@@ -586,42 +589,41 @@ struct SatGen
return true;
}
- if (cell->type == "$reduce_and" || cell->type == "$reduce_or" || cell->type == "$reduce_xor" ||
- cell->type == "$reduce_xnor" || cell->type == "$reduce_bool" || cell->type == "$logic_not")
+ if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool), ID($logic_not)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
- if (cell->type == "$reduce_and")
+ if (cell->type == ID($reduce_and))
ez->SET(ez->expression(ez->OpAnd, a), yy.at(0));
- if (cell->type == "$reduce_or" || cell->type == "$reduce_bool")
+ if (cell->type.in(ID($reduce_or), ID($reduce_bool)))
ez->SET(ez->expression(ez->OpOr, a), yy.at(0));
- if (cell->type == "$reduce_xor")
+ if (cell->type == ID($reduce_xor))
ez->SET(ez->expression(ez->OpXor, a), yy.at(0));
- if (cell->type == "$reduce_xnor")
+ if (cell->type == ID($reduce_xnor))
ez->SET(ez->NOT(ez->expression(ez->OpXor, a)), yy.at(0));
- if (cell->type == "$logic_not")
+ if (cell->type == ID($logic_not))
ez->SET(ez->NOT(ez->expression(ez->OpOr, a)), yy.at(0));
for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i));
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int aX = ez->expression(ezSAT::OpOr, undef_a);
- if (cell->type == "$reduce_and") {
+ if (cell->type == ID($reduce_and)) {
int a0 = ez->expression(ezSAT::OpOr, ez->vec_and(ez->vec_not(a), ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a0), aX), undef_y.at(0)));
}
- else if (cell->type == "$reduce_or" || cell->type == "$reduce_bool" || cell->type == "$logic_not") {
+ else if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) {
int a1 = ez->expression(ezSAT::OpOr, ez->vec_and(a, ez->vec_not(undef_a)));
ez->assume(ez->IFF(ez->AND(ez->NOT(a1), aX), undef_y.at(0)));
}
- else if (cell->type == "$reduce_xor" || cell->type == "$reduce_xnor") {
+ else if (cell->type.in(ID($reduce_xor), ID($reduce_xnor))) {
ez->assume(ez->IFF(aX, undef_y.at(0)));
} else
log_abort();
@@ -634,18 +636,18 @@ struct SatGen
return true;
}
- if (cell->type == "$logic_and" || cell->type == "$logic_or")
+ if (cell->type.in(ID($logic_and), ID($logic_or)))
{
- std::vector<int> vec_a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> vec_b = importDefSigSpec(cell->getPort("\\B"), timestep);
+ std::vector<int> vec_a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> vec_b = importDefSigSpec(cell->getPort(ID::B), timestep);
int a = ez->expression(ez->OpOr, vec_a);
int b = ez->expression(ez->OpOr, vec_b);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
- if (cell->type == "$logic_and")
+ if (cell->type == ID($logic_and))
ez->SET(ez->expression(ez->OpAnd, a, b), yy.at(0));
else
ez->SET(ez->expression(ez->OpOr, a, b), yy.at(0));
@@ -654,9 +656,9 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
int a0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_a), ez->expression(ezSAT::OpOr, undef_a)));
int b0 = ez->NOT(ez->OR(ez->expression(ezSAT::OpOr, vec_b), ez->expression(ezSAT::OpOr, undef_b)));
@@ -665,9 +667,9 @@ struct SatGen
int aX = ez->expression(ezSAT::OpOr, undef_a);
int bX = ez->expression(ezSAT::OpOr, undef_b);
- if (cell->type == "$logic_and")
+ if (cell->type == ID($logic_and))
ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a1, b1)), ez->NOT(a0), ez->NOT(b0)), undef_y.at(0));
- else if (cell->type == "$logic_or")
+ else if (cell->type == ID($logic_or))
ez->SET(ez->AND(ez->OR(aX, bX), ez->NOT(ez->AND(a0, b0)), ez->NOT(a1), ez->NOT(b1)), undef_y.at(0));
else
log_abort();
@@ -680,47 +682,47 @@ struct SatGen
return true;
}
- if (cell->type == "$lt" || cell->type == "$le" || cell->type == "$eq" || cell->type == "$ne" || cell->type == "$eqx" || cell->type == "$nex" || cell->type == "$ge" || cell->type == "$gt")
+ if (cell->type.in(ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt)))
{
- bool is_signed = cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool();
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ bool is_signed = cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool();
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
- if (model_undef && (cell->type == "$eqx" || cell->type == "$nex")) {
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
+ if (model_undef && cell->type.in(ID($eqx), ID($nex))) {
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
extendSignalWidth(undef_a, undef_b, cell, true);
a = ez->vec_or(a, undef_a);
b = ez->vec_or(b, undef_b);
}
- if (cell->type == "$lt")
+ if (cell->type == ID($lt))
ez->SET(is_signed ? ez->vec_lt_signed(a, b) : ez->vec_lt_unsigned(a, b), yy.at(0));
- if (cell->type == "$le")
+ if (cell->type == ID($le))
ez->SET(is_signed ? ez->vec_le_signed(a, b) : ez->vec_le_unsigned(a, b), yy.at(0));
- if (cell->type == "$eq" || cell->type == "$eqx")
+ if (cell->type.in(ID($eq), ID($eqx)))
ez->SET(ez->vec_eq(a, b), yy.at(0));
- if (cell->type == "$ne" || cell->type == "$nex")
+ if (cell->type.in(ID($ne), ID($nex)))
ez->SET(ez->vec_ne(a, b), yy.at(0));
- if (cell->type == "$ge")
+ if (cell->type == ID($ge))
ez->SET(is_signed ? ez->vec_ge_signed(a, b) : ez->vec_ge_unsigned(a, b), yy.at(0));
- if (cell->type == "$gt")
+ if (cell->type == ID($gt))
ez->SET(is_signed ? ez->vec_gt_signed(a, b) : ez->vec_gt_unsigned(a, b), yy.at(0));
for (size_t i = 1; i < y.size(); i++)
ez->SET(ez->CONST_FALSE, yy.at(i));
- if (model_undef && (cell->type == "$eqx" || cell->type == "$nex"))
+ if (model_undef && cell->type.in(ID($eqx), ID($nex)))
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(undef_a, undef_b, cell, true);
- if (cell->type == "$eqx")
+ if (cell->type == ID($eqx))
yy.at(0) = ez->AND(yy.at(0), ez->vec_eq(undef_a, undef_b));
else
yy.at(0) = ez->OR(yy.at(0), ez->vec_ne(undef_a, undef_b));
@@ -730,11 +732,11 @@ struct SatGen
ez->assume(ez->vec_eq(y, yy));
}
- else if (model_undef && (cell->type == "$eq" || cell->type == "$ne"))
+ else if (model_undef && cell->type.in(ID($eq), ID($ne)))
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(undef_a, undef_b, cell, true);
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
@@ -756,7 +758,7 @@ struct SatGen
else
{
if (model_undef) {
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y);
}
log_assert(!model_undef || arith_undef_handled);
@@ -764,15 +766,15 @@ struct SatGen
return true;
}
- if (cell->type == "$shl" || cell->type == "$shr" || cell->type == "$sshl" || cell->type == "$sshr" || cell->type == "$shift" || cell->type == "$shiftx")
+ if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
int extend_bit = ez->CONST_FALSE;
- if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool())
+ if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())
extend_bit = a.back();
while (y.size() < a.size())
@@ -783,29 +785,29 @@ struct SatGen
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> shifted_a;
- if (cell->type == "$shl" || cell->type == "$sshl")
+ if (cell->type.in( ID($shl), ID($sshl)))
shifted_a = ez->vec_shift_left(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$shr")
+ if (cell->type == ID($shr))
shifted_a = ez->vec_shift_right(a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$sshr")
- shifted_a = ez->vec_shift_right(a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
+ if (cell->type == ID($sshr))
+ shifted_a = ez->vec_shift_right(a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$shift" || cell->type == "$shiftx")
- shifted_a = ez->vec_shift_right(a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
+ if (cell->type.in(ID($shift), ID($shiftx)))
+ shifted_a = ez->vec_shift_right(a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
ez->assume(ez->vec_eq(shifted_a, yy));
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> undef_a_shifted;
- extend_bit = cell->type == "$shiftx" ? ez->CONST_TRUE : ez->CONST_FALSE;
- if (!cell->type.in("$shift", "$shiftx") && cell->parameters["\\A_SIGNED"].as_bool())
+ extend_bit = cell->type == ID($shiftx) ? ez->CONST_TRUE : ez->CONST_FALSE;
+ if (!cell->type.in(ID($shift), ID($shiftx)) && cell->parameters[ID(A_SIGNED)].as_bool())
extend_bit = undef_a.back();
while (undef_y.size() < undef_a.size())
@@ -813,20 +815,20 @@ struct SatGen
while (undef_y.size() > undef_a.size())
undef_a.push_back(extend_bit);
- if (cell->type == "$shl" || cell->type == "$sshl")
+ if (cell->type.in(ID($shl), ID($sshl)))
undef_a_shifted = ez->vec_shift_left(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$shr")
+ if (cell->type == ID($shr))
undef_a_shifted = ez->vec_shift_right(undef_a, b, false, ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$sshr")
- undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters["\\A_SIGNED"].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
+ if (cell->type == ID($sshr))
+ undef_a_shifted = ez->vec_shift_right(undef_a, b, false, cell->parameters[ID(A_SIGNED)].as_bool() ? undef_a.back() : ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$shift")
- undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
+ if (cell->type == ID($shift))
+ undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_FALSE, ez->CONST_FALSE);
- if (cell->type == "$shiftx")
- undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters["\\B_SIGNED"].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
+ if (cell->type == ID($shiftx))
+ undef_a_shifted = ez->vec_shift_right(undef_a, b, cell->parameters[ID(B_SIGNED)].as_bool(), ez->CONST_TRUE, ez->CONST_TRUE);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
std::vector<int> undef_all_y_bits(undef_y.size(), undef_any_b);
@@ -836,11 +838,11 @@ struct SatGen
return true;
}
- if (cell->type == "$mul")
+ if (cell->type == ID($mul))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
@@ -857,17 +859,17 @@ struct SatGen
if (model_undef) {
log_assert(arith_undef_handled);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y);
}
return true;
}
- if (cell->type == "$macc")
+ if (cell->type == ID($macc))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
Macc macc;
macc.from_cell(cell);
@@ -916,13 +918,13 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
int undef_any_a = ez->expression(ezSAT::OpOr, undef_a);
int undef_any_b = ez->expression(ezSAT::OpOr, undef_b);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
ez->assume(ez->vec_eq(undef_y, std::vector<int>(GetSize(y), ez->OR(undef_any_a, undef_any_b))));
undefGating(y, tmp, undef_y);
@@ -933,17 +935,17 @@ struct SatGen
return true;
}
- if (cell->type == "$div" || cell->type == "$mod")
+ if (cell->type.in(ID($div), ID($mod)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidth(a, b, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> a_u, b_u;
- if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) {
+ if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) {
a_u = ez->vec_ite(a.back(), ez->vec_neg(a), a);
b_u = ez->vec_ite(b.back(), ez->vec_neg(b), b);
} else {
@@ -968,13 +970,13 @@ struct SatGen
}
std::vector<int> y_tmp = ignore_div_by_zero ? yy : ez->vec_var(y.size());
- if (cell->type == "$div") {
- if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool())
+ if (cell->type == ID($div)) {
+ if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(ez->XOR(a.back(), b.back()), ez->vec_neg(y_u), y_u)));
else
ez->assume(ez->vec_eq(y_tmp, y_u));
} else {
- if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool())
+ if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
ez->assume(ez->vec_eq(y_tmp, ez->vec_ite(a.back(), ez->vec_neg(chain_buf), chain_buf)));
else
ez->assume(ez->vec_eq(y_tmp, chain_buf));
@@ -984,20 +986,20 @@ struct SatGen
ez->assume(ez->expression(ezSAT::OpOr, b));
} else {
std::vector<int> div_zero_result;
- if (cell->type == "$div") {
- if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool()) {
+ if (cell->type == ID($div)) {
+ if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool()) {
std::vector<int> all_ones(y.size(), ez->CONST_TRUE);
std::vector<int> only_first_one(y.size(), ez->CONST_FALSE);
only_first_one.at(0) = ez->CONST_TRUE;
div_zero_result = ez->vec_ite(a.back(), only_first_one, all_ones);
} else {
- div_zero_result.insert(div_zero_result.end(), cell->getPort("\\A").size(), ez->CONST_TRUE);
+ div_zero_result.insert(div_zero_result.end(), cell->getPort(ID::A).size(), ez->CONST_TRUE);
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
}
} else {
- int copy_a_bits = min(cell->getPort("\\A").size(), cell->getPort("\\B").size());
+ int copy_a_bits = min(cell->getPort(ID::A).size(), cell->getPort(ID::B).size());
div_zero_result.insert(div_zero_result.end(), a.begin(), a.begin() + copy_a_bits);
- if (cell->parameters["\\A_SIGNED"].as_bool() && cell->parameters["\\B_SIGNED"].as_bool())
+ if (cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool())
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), div_zero_result.back());
else
div_zero_result.insert(div_zero_result.end(), y.size() - div_zero_result.size(), ez->CONST_FALSE);
@@ -1007,27 +1009,27 @@ struct SatGen
if (model_undef) {
log_assert(arith_undef_handled);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
undefGating(y, yy, undef_y);
}
return true;
}
- if (cell->type == "$lut")
+ if (cell->type == ID($lut))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> lut;
- for (auto bit : cell->getParam("\\LUT").bits)
- lut.push_back(bit == RTLIL::S1 ? ez->CONST_TRUE : ez->CONST_FALSE);
+ for (auto bit : cell->getParam(ID(LUT)).bits)
+ lut.push_back(bit == State::S1 ? ez->CONST_TRUE : ez->CONST_FALSE);
while (GetSize(lut) < (1 << GetSize(a)))
lut.push_back(ez->CONST_FALSE);
lut.resize(1 << GetSize(a));
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
std::vector<int> t(lut), u(GetSize(t), ez->CONST_FALSE);
for (int i = GetSize(a)-1; i >= 0; i--)
@@ -1045,7 +1047,7 @@ struct SatGen
log_assert(GetSize(t) == 1);
log_assert(GetSize(u) == 1);
undefGating(y, t, u);
- ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort("\\Y"), timestep), u));
+ ez->assume(ez->vec_eq(importUndefSigSpec(cell->getPort(ID::Y), timestep), u));
}
else
{
@@ -1063,15 +1065,15 @@ struct SatGen
return true;
}
- if (cell->type == "$sop")
+ if (cell->type == ID($sop))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- int y = importDefSigSpec(cell->getPort("\\Y"), timestep).at(0);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ int y = importDefSigSpec(cell->getPort(ID::Y), timestep).at(0);
- int width = cell->getParam("\\WIDTH").as_int();
- int depth = cell->getParam("\\DEPTH").as_int();
+ int width = cell->getParam(ID(WIDTH)).as_int();
+ int depth = cell->getParam(ID(DEPTH)).as_int();
- vector<State> table_raw = cell->getParam("\\TABLE").bits;
+ vector<State> table_raw = cell->getParam(ID(TABLE)).bits;
while (GetSize(table_raw) < 2*width*depth)
table_raw.push_back(State::S0);
@@ -1094,8 +1096,8 @@ struct SatGen
if (model_undef)
{
std::vector<int> products, undef_products;
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- int undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep).at(0);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ int undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep).at(0);
for (int i = 0; i < depth; i++)
{
@@ -1145,13 +1147,13 @@ struct SatGen
return true;
}
- if (cell->type == "$fa")
+ if (cell->type == ID($fa))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> c = importDefSigSpec(cell->getPort("\\C"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
- std::vector<int> x = importDefSigSpec(cell->getPort("\\X"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> c = importDefSigSpec(cell->getPort(ID(C)), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
+ std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
std::vector<int> xx = model_undef ? ez->vec_var(x.size()) : x;
@@ -1165,12 +1167,12 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_c = importUndefSigSpec(cell->getPort("\\C"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_c = importUndefSigSpec(cell->getPort(ID(C)), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
- std::vector<int> undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
+ std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);
ez->assume(ez->vec_eq(undef_y, ez->vec_or(ez->vec_or(undef_a, undef_b), undef_c)));
ez->assume(ez->vec_eq(undef_x, undef_y));
@@ -1181,12 +1183,12 @@ struct SatGen
return true;
}
- if (cell->type == "$lcu")
+ if (cell->type == ID($lcu))
{
- std::vector<int> p = importDefSigSpec(cell->getPort("\\P"), timestep);
- std::vector<int> g = importDefSigSpec(cell->getPort("\\G"), timestep);
- std::vector<int> ci = importDefSigSpec(cell->getPort("\\CI"), timestep);
- std::vector<int> co = importDefSigSpec(cell->getPort("\\CO"), timestep);
+ std::vector<int> p = importDefSigSpec(cell->getPort(ID(P)), timestep);
+ std::vector<int> g = importDefSigSpec(cell->getPort(ID(G)), timestep);
+ std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
+ std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);
std::vector<int> yy = model_undef ? ez->vec_var(co.size()) : co;
@@ -1195,10 +1197,10 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_p = importUndefSigSpec(cell->getPort("\\P"), timestep);
- std::vector<int> undef_g = importUndefSigSpec(cell->getPort("\\G"), timestep);
- std::vector<int> undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep);
- std::vector<int> undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep);
+ std::vector<int> undef_p = importUndefSigSpec(cell->getPort(ID(P)), timestep);
+ std::vector<int> undef_g = importUndefSigSpec(cell->getPort(ID(G)), timestep);
+ std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
+ std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);
int undef_any_p = ez->expression(ezSAT::OpOr, undef_p);
int undef_any_g = ez->expression(ezSAT::OpOr, undef_g);
@@ -1213,15 +1215,15 @@ struct SatGen
return true;
}
- if (cell->type == "$alu")
+ if (cell->type == ID($alu))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
- std::vector<int> x = importDefSigSpec(cell->getPort("\\X"), timestep);
- std::vector<int> ci = importDefSigSpec(cell->getPort("\\CI"), timestep);
- std::vector<int> bi = importDefSigSpec(cell->getPort("\\BI"), timestep);
- std::vector<int> co = importDefSigSpec(cell->getPort("\\CO"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
+ std::vector<int> x = importDefSigSpec(cell->getPort(ID(X)), timestep);
+ std::vector<int> ci = importDefSigSpec(cell->getPort(ID(CI)), timestep);
+ std::vector<int> bi = importDefSigSpec(cell->getPort(ID(BI)), timestep);
+ std::vector<int> co = importDefSigSpec(cell->getPort(ID(CO)), timestep);
extendSignalWidth(a, b, y, cell);
extendSignalWidth(a, b, x, cell);
@@ -1246,14 +1248,14 @@ struct SatGen
if (model_undef)
{
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep);
- std::vector<int> undef_ci = importUndefSigSpec(cell->getPort("\\CI"), timestep);
- std::vector<int> undef_bi = importUndefSigSpec(cell->getPort("\\BI"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
+ std::vector<int> undef_ci = importUndefSigSpec(cell->getPort(ID(CI)), timestep);
+ std::vector<int> undef_bi = importUndefSigSpec(cell->getPort(ID(BI)), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
- std::vector<int> undef_x = importUndefSigSpec(cell->getPort("\\X"), timestep);
- std::vector<int> undef_co = importUndefSigSpec(cell->getPort("\\CO"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
+ std::vector<int> undef_x = importUndefSigSpec(cell->getPort(ID(X)), timestep);
+ std::vector<int> undef_co = importUndefSigSpec(cell->getPort(ID(CO)), timestep);
extendSignalWidth(undef_a, undef_b, undef_y, cell);
extendSignalWidth(undef_a, undef_b, undef_x, cell);
@@ -1279,19 +1281,19 @@ struct SatGen
return true;
}
- if (cell->type == "$slice")
+ if (cell->type == ID($slice))
{
- RTLIL::SigSpec a = cell->getPort("\\A");
- RTLIL::SigSpec y = cell->getPort("\\Y");
- ez->assume(signals_eq(a.extract(cell->parameters.at("\\OFFSET").as_int(), y.size()), y, timestep));
+ RTLIL::SigSpec a = cell->getPort(ID::A);
+ RTLIL::SigSpec y = cell->getPort(ID::Y);
+ ez->assume(signals_eq(a.extract(cell->parameters.at(ID(OFFSET)).as_int(), y.size()), y, timestep));
return true;
}
- if (cell->type == "$concat")
+ if (cell->type == ID($concat))
{
- RTLIL::SigSpec a = cell->getPort("\\A");
- RTLIL::SigSpec b = cell->getPort("\\B");
- RTLIL::SigSpec y = cell->getPort("\\Y");
+ RTLIL::SigSpec a = cell->getPort(ID::A);
+ RTLIL::SigSpec b = cell->getPort(ID::B);
+ RTLIL::SigSpec y = cell->getPort(ID::Y);
RTLIL::SigSpec ab = a;
ab.append(b);
@@ -1300,24 +1302,24 @@ struct SatGen
return true;
}
- if (timestep > 0 && cell->type.in("$ff", "$dff", "$_FF_", "$_DFF_N_", "$_DFF_P_"))
+ if (timestep > 0 && cell->type.in(ID($ff), ID($dff), ID($_FF_), ID($_DFF_N_), ID($_DFF_P_)))
{
if (timestep == 1)
{
- initial_state.add((*sigmap)(cell->getPort("\\Q")));
+ initial_state.add((*sigmap)(cell->getPort(ID(Q))));
}
else
{
- std::vector<int> d = importDefSigSpec(cell->getPort("\\D"), timestep-1);
- std::vector<int> q = importDefSigSpec(cell->getPort("\\Q"), timestep);
+ std::vector<int> d = importDefSigSpec(cell->getPort(ID(D)), timestep-1);
+ std::vector<int> q = importDefSigSpec(cell->getPort(ID(Q)), timestep);
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
ez->assume(ez->vec_eq(d, qq));
if (model_undef)
{
- std::vector<int> undef_d = importUndefSigSpec(cell->getPort("\\D"), timestep-1);
- std::vector<int> undef_q = importUndefSigSpec(cell->getPort("\\Q"), timestep);
+ std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID(D)), timestep-1);
+ std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID(Q)), timestep);
ez->assume(ez->vec_eq(undef_d, undef_q));
undefGating(q, qq, undef_q);
@@ -1326,21 +1328,21 @@ struct SatGen
return true;
}
- if (cell->type == "$anyconst")
+ if (cell->type == ID($anyconst))
{
if (timestep < 2)
return true;
- std::vector<int> d = importDefSigSpec(cell->getPort("\\Y"), timestep-1);
- std::vector<int> q = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> d = importDefSigSpec(cell->getPort(ID::Y), timestep-1);
+ std::vector<int> q = importDefSigSpec(cell->getPort(ID::Y), timestep);
std::vector<int> qq = model_undef ? ez->vec_var(q.size()) : q;
ez->assume(ez->vec_eq(d, qq));
if (model_undef)
{
- std::vector<int> undef_d = importUndefSigSpec(cell->getPort("\\Y"), timestep-1);
- std::vector<int> undef_q = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_d = importUndefSigSpec(cell->getPort(ID::Y), timestep-1);
+ std::vector<int> undef_q = importUndefSigSpec(cell->getPort(ID::Y), timestep);
ez->assume(ez->vec_eq(undef_d, undef_q));
undefGating(q, qq, undef_q);
@@ -1348,23 +1350,23 @@ struct SatGen
return true;
}
- if (cell->type == "$anyseq")
+ if (cell->type == ID($anyseq))
{
return true;
}
- if (cell->type == "$_BUF_" || cell->type == "$equiv")
+ if (cell->type.in(ID($_BUF_), ID($equiv)))
{
- std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(a, y, cell);
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
ez->assume(ez->vec_eq(a, yy));
if (model_undef) {
- std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep);
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
extendSignalWidthUnary(undef_a, undef_y, cell, false);
ez->assume(ez->vec_eq(undef_a, undef_y));
undefGating(y, yy, undef_y);
@@ -1372,18 +1374,18 @@ struct SatGen
return true;
}
- if (cell->type == "$initstate")
+ if (cell->type == ID($initstate))
{
auto key = make_pair(prefix, timestep);
if (initstates.count(key) == 0)
initstates[key] = false;
- std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
log_assert(GetSize(y) == 1);
ez->SET(y[0], initstates[key] ? ez->CONST_TRUE : ez->CONST_FALSE);
if (model_undef) {
- std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep);
+ std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
log_assert(GetSize(undef_y) == 1);
ez->SET(undef_y[0], ez->CONST_FALSE);
}
@@ -1391,19 +1393,19 @@ struct SatGen
return true;
}
- if (cell->type == "$assert")
+ if (cell->type == ID($assert))
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
- asserts_a[pf].append((*sigmap)(cell->getPort("\\A")));
- asserts_en[pf].append((*sigmap)(cell->getPort("\\EN")));
+ asserts_a[pf].append((*sigmap)(cell->getPort(ID::A)));
+ asserts_en[pf].append((*sigmap)(cell->getPort(ID(EN))));
return true;
}
- if (cell->type == "$assume")
+ if (cell->type == ID($assume))
{
std::string pf = prefix + (timestep == -1 ? "" : stringf("@%d:", timestep));
- assumes_a[pf].append((*sigmap)(cell->getPort("\\A")));
- assumes_en[pf].append((*sigmap)(cell->getPort("\\EN")));
+ assumes_a[pf].append((*sigmap)(cell->getPort(ID::A)));
+ assumes_en[pf].append((*sigmap)(cell->getPort(ID(EN))));
return true;
}
diff --git a/kernel/sigtools.h b/kernel/sigtools.h
index 4e97bb775..2517d6de3 100644
--- a/kernel/sigtools.h
+++ b/kernel/sigtools.h
@@ -135,9 +135,11 @@ struct SigPool
}
};
-template <typename T, class Compare = std::less<T>>
+template <typename T, class Compare = void>
struct SigSet
{
+ static_assert(!std::is_same<Compare,void>::value, "Default value for `Compare' class not found for SigSet<T>. Please specify.");
+
struct bitDef_t : public std::pair<RTLIL::Wire*, int> {
bitDef_t() : std::pair<RTLIL::Wire*, int>(NULL, 0) { }
bitDef_t(const RTLIL::SigBit &bit) : std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset) { }
@@ -220,6 +222,13 @@ struct SigSet
}
};
+template<typename T>
+class SigSet<T, typename std::enable_if<!std::is_pointer<T>::value>::type> : public SigSet<T, std::less<T>> {};
+template<typename T>
+using sort_by_name_id_guard = typename std::enable_if<std::is_same<T,RTLIL::Cell*>::value>::type;
+template<typename T>
+class SigSet<T, sort_by_name_id_guard<T>> : public SigSet<T, RTLIL::sort_by_name_id<typename std::remove_pointer<T>::type>> {};
+
struct SigMap
{
mfp<SigBit> database;
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index e5b22eba7..8190d8902 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -25,11 +25,15 @@
# include <readline/history.h>
#endif
+#ifdef YOSYS_ENABLE_EDITLINE
+# include <editline/readline.h>
+#endif
+
#ifdef YOSYS_ENABLE_PLUGINS
# include <dlfcn.h>
#endif
-#ifdef _WIN32
+#if defined(_WIN32)
# include <windows.h>
# include <io.h>
#elif defined(__APPLE__)
@@ -37,15 +41,32 @@
# include <unistd.h>
# include <dirent.h>
# include <sys/stat.h>
-# include <glob.h>
#else
# include <unistd.h>
# include <dirent.h>
# include <sys/types.h>
+# include <sys/wait.h>
# include <sys/stat.h>
+#endif
+
+#if !defined(_WIN32) && defined(YOSYS_ENABLE_GLOB)
# include <glob.h>
#endif
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+#endif
+
+#ifdef WITH_PYTHON
+#if PY_MAJOR_VERSION >= 3
+# define INIT_MODULE PyInit_libyosys
+ extern "C" PyObject* INIT_MODULE();
+#else
+# define INIT_MODULE initlibyosys
+ extern "C" void INIT_MODULE();
+#endif
+#endif
+
#include <limits.h>
#include <errno.h>
@@ -60,13 +81,15 @@ CellTypes yosys_celltypes;
Tcl_Interp *yosys_tcl_interp = NULL;
#endif
+std::set<std::string> yosys_input_files, yosys_output_files;
+
bool memhasher_active = false;
uint32_t memhasher_rng = 123456;
std::vector<void*> memhasher_store;
void memhasher_on()
{
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
memhasher_rng += time(NULL) << 16 ^ getpid();
#endif
memhasher_store.resize(0x10000);
@@ -106,7 +129,7 @@ void yosys_banner()
log(" | |\n");
log(" | yosys -- Yosys Open SYnthesis Suite |\n");
log(" | |\n");
- log(" | Copyright (C) 2012 - 2016 Clifford Wolf <clifford@clifford.at> |\n");
+ log(" | Copyright (C) 2012 - 2019 Clifford Wolf <clifford@clifford.at> |\n");
log(" | |\n");
log(" | Permission to use, copy, modify, and/or distribute this software for any |\n");
log(" | purpose with or without fee is hereby granted, provided that the above |\n");
@@ -128,14 +151,16 @@ void yosys_banner()
int ceil_log2(int x)
{
+#if defined(__GNUC__)
+ return x > 1 ? (8*sizeof(int)) - __builtin_clz(x-1) : 0;
+#else
if (x <= 0)
return 0;
-
for (int i = 0; i < 32; i++)
if (((x-1) >> i) == 0)
return i;
-
log_abort();
+#endif
}
std::string stringf(const char *fmt, ...)
@@ -155,7 +180,7 @@ std::string vstringf(const char *fmt, va_list ap)
std::string string;
char *str = NULL;
-#ifdef _WIN32
+#if defined(_WIN32 )|| defined(__CYGWIN__)
int sz = 64, rc;
while (1) {
va_list apc;
@@ -205,12 +230,18 @@ std::string next_token(std::string &text, const char *sep, bool long_strings)
if (long_strings && pos_begin != text.size() && text[pos_begin] == '"') {
string sep_string = sep;
- for (size_t i = pos_begin+1; i < text.size(); i++)
+ for (size_t i = pos_begin+1; i < text.size(); i++) {
if (text[i] == '"' && (i+1 == text.size() || sep_string.find(text[i+1]) != std::string::npos)) {
std::string token = text.substr(pos_begin, i-pos_begin+1);
text = text.substr(i+1);
return token;
}
+ if (i+1 < text.size() && text[i] == '"' && text[i+1] == ';' && (i+2 == text.size() || sep_string.find(text[i+2]) != std::string::npos)) {
+ std::string token = text.substr(pos_begin, i-pos_begin+1);
+ text = text.substr(i+2);
+ return token + ";";
+ }
+ }
}
size_t pos_end = text.find_first_of(sep, pos_begin);
@@ -453,17 +484,45 @@ void remove_directory(std::string dirname)
#endif
}
+std::string escape_filename_spaces(const std::string& filename)
+{
+ std::string out;
+ out.reserve(filename.size());
+ for (auto c : filename)
+ {
+ if (c == ' ')
+ out += "\\ ";
+ else
+ out.push_back(c);
+ }
+ return out;
+}
+
int GetSize(RTLIL::Wire *wire)
{
return wire->width;
}
+bool already_setup = false;
+
void yosys_setup()
{
- // if there are already IdString objects then we have a global initialization order bug
- IdString empty_id;
- log_assert(empty_id.index_ == 0);
- IdString::get_reference(empty_id.index_);
+ if(already_setup)
+ return;
+ already_setup = true;
+
+ RTLIL::ID::A = "\\A";
+ RTLIL::ID::B = "\\B";
+ RTLIL::ID::Y = "\\Y";
+ RTLIL::ID::keep = "\\keep";
+ RTLIL::ID::whitebox = "\\whitebox";
+ RTLIL::ID::blackbox = "\\blackbox";
+
+ #ifdef WITH_PYTHON
+ PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
+ Py_Initialize();
+ PyRun_SimpleString("import sys");
+ #endif
Pass::init_register();
yosys_design = new RTLIL::Design;
@@ -471,10 +530,22 @@ void yosys_setup()
log_push();
}
+bool yosys_already_setup()
+{
+ return already_setup;
+}
+
+bool already_shutdown = false;
+
void yosys_shutdown()
{
+ if(already_shutdown)
+ return;
+ already_shutdown = true;
log_pop();
+ Pass::done_register();
+
delete yosys_design;
yosys_design = NULL;
@@ -484,7 +555,6 @@ void yosys_shutdown()
log_errfile = NULL;
log_files.clear();
- Pass::done_register();
yosys_celltypes.clear();
#ifdef YOSYS_ENABLE_TCL
@@ -500,11 +570,15 @@ void yosys_shutdown()
dlclose(it.second);
loaded_plugins.clear();
+#ifdef WITH_PYTHON
+ loaded_python_plugins.clear();
+#endif
loaded_plugin_aliases.clear();
#endif
- IdString empty_id;
- IdString::put_reference(empty_id.index_);
+#ifdef WITH_PYTHON
+ Py_Finalize();
+#endif
}
RTLIL::IdString new_id(std::string file, int line, std::string func)
@@ -553,7 +627,7 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern)
{
std::vector<std::string> results;
-#ifdef _WIN32
+#if defined(_WIN32) || !defined(YOSYS_ENABLE_GLOB)
results.push_back(filename_pattern);
#else
glob_t globbuf;
@@ -574,10 +648,14 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern)
void rewrite_filename(std::string &filename)
{
- if (filename.substr(0, 1) == "\"" && filename.substr(GetSize(filename)-1) == "\"")
+ if (filename.compare(0, 1, "\"") == 0 && filename.compare(GetSize(filename)-1, std::string::npos, "\"") == 0)
filename = filename.substr(1, GetSize(filename)-2);
- if (filename.substr(0, 2) == "+/")
+ if (filename.compare(0, 2, "+/") == 0)
filename = proc_share_dirname() + filename.substr(2);
+#ifndef _WIN32
+ if (filename.compare(0, 2, "~/") == 0)
+ filename = filename.replace(0, 1, getenv("HOME"));
+#endif
}
#ifdef YOSYS_ENABLE_TCL
@@ -592,6 +670,8 @@ static int tcl_yosys_cmd(ClientData, Tcl_Interp *interp, int argc, const char *a
std::string tcl_command_name = it.first;
if (tcl_command_name == "proc")
tcl_command_name = "procs";
+ else if (tcl_command_name == "rename")
+ tcl_command_name = "renames";
Tcl_CmdInfo info;
if (Tcl_GetCommandInfo(interp, tcl_command_name.c_str(), &info) != 0) {
log("[TCL: yosys -import] Command name collision: found pre-existing command `%s' -> skip.\n", it.first.c_str());
@@ -623,26 +703,37 @@ extern Tcl_Interp *yosys_get_tcl_interp()
struct TclPass : public Pass {
TclPass() : Pass("tcl", "execute a TCL script file") { }
- virtual void help() {
+ void help() YS_OVERRIDE {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
- log(" tcl <filename>\n");
+ log(" tcl <filename> [args]\n");
log("\n");
log("This command executes the tcl commands in the specified file.\n");
log("Use 'yosys cmd' to run the yosys command 'cmd' from tcl.\n");
log("\n");
log("The tcl command 'yosys -import' can be used to import all yosys\n");
- log("commands directly as tcl commands to the tcl shell. The yosys\n");
- log("command 'proc' is wrapped using the tcl command 'procs' in order\n");
- log("to avoid a name collision with the tcl builtin command 'proc'.\n");
+ log("commands directly as tcl commands to the tcl shell. Yosys commands\n");
+ log("'proc' and 'rename' are wrapped to tcl commands 'procs' and 'renames'\n");
+ log("in order to avoid a name collision with the built in commands.\n");
+ log("\n");
+ log("If any arguments are specified, these arguments are provided to the script via\n");
+ log("the standard $argc and $argv variables.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
+ void execute(std::vector<std::string> args, RTLIL::Design *) YS_OVERRIDE {
if (args.size() < 2)
log_cmd_error("Missing script file.\n");
- if (args.size() > 2)
- extra_args(args, 1, design, false);
- if (Tcl_EvalFile(yosys_get_tcl_interp(), args[1].c_str()) != TCL_OK)
- log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp()));
+
+ std::vector<Tcl_Obj*> script_args;
+ for (auto it = args.begin() + 2; it != args.end(); ++it)
+ script_args.push_back(Tcl_NewStringObj((*it).c_str(), (*it).size()));
+
+ Tcl_Interp *interp = yosys_get_tcl_interp();
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argc", 4), NULL, Tcl_NewIntObj(script_args.size()), 0);
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv", 4), NULL, Tcl_NewListObj(script_args.size(), script_args.data()), 0);
+ Tcl_ObjSetVar2(interp, Tcl_NewStringObj("argv0", 5), NULL, Tcl_NewStringObj(args[1].c_str(), args[1].size()), 0);
+ if (Tcl_EvalFile(interp, args[1].c_str()) != TCL_OK)
+ log_cmd_error("TCL interpreter returned an error: %s\n", Tcl_GetStringResult(interp));
}
} TclPass;
#endif
@@ -659,6 +750,26 @@ std::string proc_self_dirname()
buflen--;
return std::string(path, buflen);
}
+#elif defined(__FreeBSD__)
+std::string proc_self_dirname()
+{
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
+ size_t buflen;
+ char *buffer;
+ std::string path;
+ if (sysctl(mib, 4, NULL, &buflen, NULL, 0) != 0)
+ log_error("sysctl failed: %s\n", strerror(errno));
+ buffer = (char*)malloc(buflen);
+ if (buffer == NULL)
+ log_error("malloc failed: %s\n", strerror(errno));
+ if (sysctl(mib, 4, buffer, &buflen, NULL, 0) != 0)
+ log_error("sysctl failed: %s\n", strerror(errno));
+ while (buflen > 0 && buffer[buflen-1] != '/')
+ buflen--;
+ path.assign(buffer, buflen);
+ free(buffer);
+ return path;
+}
#elif defined(__APPLE__)
std::string proc_self_dirname()
{
@@ -700,13 +811,13 @@ std::string proc_self_dirname()
return "/";
}
#else
- #error Dont know how to determine process executable base path!
+ #error "Don't know how to determine process executable base path!"
#endif
#ifdef EMSCRIPTEN
std::string proc_share_dirname()
{
- return "/share";
+ return "/share/";
}
#else
std::string proc_share_dirname()
@@ -766,7 +877,7 @@ static void handle_label(std::string &command, bool &from_to_active, const std::
while (pos < GetSize(command) && command[pos] != ' ' && command[pos] != '\t' && command[pos] != '\r' && command[pos] != '\n')
label += command[pos++];
- if (label.back() == ':' && GetSize(label) > 1)
+ if (GetSize(label) > 1 && label.back() == ':')
{
label = label.substr(0, GetSize(label)-1);
command = command.substr(pos);
@@ -784,21 +895,26 @@ void run_frontend(std::string filename, std::string command, std::string *backen
design = yosys_design;
if (command == "auto") {
- if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v")
+ std::string filename_trim = filename;
+ if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".gz") == 0)
+ filename_trim.erase(filename_trim.size()-3);
+ if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-2, std::string::npos, ".v") == 0)
command = "verilog";
- else if (filename.size() > 2 && filename.substr(filename.size()-3) == ".sv")
+ else if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".sv") == 0)
command = "verilog -sv";
- else if (filename.size() > 2 && filename.substr(filename.size()-4) == ".vhd")
+ else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vhd") == 0)
command = "vhdl";
- else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".blif")
+ else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".blif") == 0)
command = "blif";
- else if (filename.size() > 4 && filename.substr(filename.size()-5) == ".json")
+ else if (filename_trim.size() > 5 && filename_trim.compare(filename_trim.size()-6, std::string::npos, ".eblif") == 0)
+ command = "blif";
+ else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".json") == 0)
command = "json";
- else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il")
+ else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".il") == 0)
command = "ilang";
- else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".ys")
+ else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".ys") == 0)
command = "script";
- else if (filename.size() > 2 && filename.substr(filename.size()-4) == ".tcl")
+ else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".tcl") == 0)
command = "tcl";
else if (filename == "-")
command = "script";
@@ -827,8 +943,10 @@ void run_frontend(std::string filename, std::string command, std::string *backen
FILE *f = stdin;
- if (filename != "-")
+ if (filename != "-") {
f = fopen(filename.c_str(), "r");
+ yosys_input_files.insert(filename);
+ }
if (f == NULL)
log_error("Can't open script file `%s' for reading: %s\n", filename.c_str(), strerror(errno));
@@ -847,14 +965,18 @@ void run_frontend(std::string filename, std::string command, std::string *backen
command += next_line;
}
handle_label(command, from_to_active, run_from, run_to);
- if (from_to_active)
+ if (from_to_active) {
Pass::call(design, command);
+ design->check();
+ }
}
if (!command.empty()) {
handle_label(command, from_to_active, run_from, run_to);
- if (from_to_active)
+ if (from_to_active) {
Pass::call(design, command);
+ design->check();
+ }
}
}
catch (...) {
@@ -883,6 +1005,7 @@ void run_frontend(std::string filename, std::string command, std::string *backen
Pass::call(design, vector<string>({command, filename}));
else
Frontend::frontend_call(design, NULL, filename, command);
+ design->check();
}
void run_frontend(std::string filename, std::string command, RTLIL::Design *design)
@@ -906,17 +1029,17 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
design = yosys_design;
if (command == "auto") {
- if (filename.size() > 2 && filename.substr(filename.size()-2) == ".v")
+ if (filename.size() > 2 && filename.compare(filename.size()-2, std::string::npos, ".v") == 0)
command = "verilog";
- else if (filename.size() > 3 && filename.substr(filename.size()-3) == ".il")
+ else if (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0)
command = "ilang";
- else if (filename.size() > 4 && filename.substr(filename.size()-4) == ".aig")
+ else if (filename.size() > 4 && filename.compare(filename.size()-4, std::string::npos, ".aig") == 0)
command = "aiger";
- else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".blif")
+ else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".blif") == 0)
command = "blif";
- else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".edif")
+ else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".edif") == 0)
command = "edif";
- else if (filename.size() > 5 && filename.substr(filename.size()-5) == ".json")
+ else if (filename.size() > 5 && filename.compare(filename.size()-5, std::string::npos, ".json") == 0)
command = "json";
else if (filename == "-")
command = "ilang";
@@ -938,7 +1061,7 @@ void run_backend(std::string filename, std::string command, RTLIL::Design *desig
Backend::backend_call(design, NULL, filename, command);
}
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
static char *readline_cmd_generator(const char *text, int state)
{
static std::map<std::string, Pass*>::iterator it;
@@ -950,7 +1073,7 @@ static char *readline_cmd_generator(const char *text, int state)
}
for (; it != pass_register.end(); it++) {
- if (it->first.substr(0, len) == text)
+ if (it->first.compare(0, len, text) == 0)
return strdup((it++)->first.c_str());
}
return NULL;
@@ -972,7 +1095,7 @@ static char *readline_obj_generator(const char *text, int state)
if (design->selected_active_module.empty())
{
for (auto &it : design->modules_)
- if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
}
else
@@ -981,19 +1104,19 @@ static char *readline_obj_generator(const char *text, int state)
RTLIL::Module *module = design->modules_.at(design->selected_active_module);
for (auto &it : module->wires_)
- if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
for (auto &it : module->memories)
- if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
for (auto &it : module->cells_)
- if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
for (auto &it : module->processes)
- if (RTLIL::unescape_id(it.first).substr(0, len) == text)
+ if (RTLIL::unescape_id(it.first).compare(0, len, text) == 0)
obj_names.push_back(strdup(RTLIL::id2cstr(it.first)));
}
@@ -1025,14 +1148,14 @@ void shell(RTLIL::Design *design)
recursion_counter++;
log_cmd_error_throw = true;
-#ifdef YOSYS_ENABLE_READLINE
- rl_readline_name = "yosys";
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
+ rl_readline_name = (char*)"yosys";
rl_attempted_completion_function = readline_completion;
- rl_basic_word_break_characters = " \t\n";
+ rl_basic_word_break_characters = (char*)" \t\n";
#endif
char *command = NULL;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
while ((command = readline(create_prompt(design, recursion_counter))) != NULL)
{
#else
@@ -1046,7 +1169,7 @@ void shell(RTLIL::Design *design)
#endif
if (command[strspn(command, " \t\r\n")] == 0)
continue;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
add_history(command);
#endif
@@ -1066,6 +1189,7 @@ void shell(RTLIL::Design *design)
design->selection_stack.pop_back();
log_reset_stack();
}
+ design->check();
}
if (command == NULL)
printf("exit\n");
@@ -1076,7 +1200,7 @@ void shell(RTLIL::Design *design)
struct ShellPass : public Pass {
ShellPass() : Pass("shell", "enter interactive command mode") { }
- virtual void help() {
+ void help() YS_OVERRIDE {
log("\n");
log(" shell\n");
log("\n");
@@ -1108,16 +1232,16 @@ struct ShellPass : public Pass {
log("Press Ctrl-D or type 'exit' to leave the interactive shell.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
extra_args(args, 1, design, false);
shell(design);
}
} ShellPass;
-#ifdef YOSYS_ENABLE_READLINE
+#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
struct HistoryPass : public Pass {
HistoryPass() : Pass("history", "show last interactive commands") { }
- virtual void help() {
+ void help() YS_OVERRIDE {
log("\n");
log(" history\n");
log("\n");
@@ -1126,33 +1250,73 @@ struct HistoryPass : public Pass {
log("from executed scripts.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
extra_args(args, 1, design, false);
+#ifdef YOSYS_ENABLE_READLINE
for(HIST_ENTRY **list = history_list(); *list != NULL; list++)
log("%s\n", (*list)->line);
+#else
+ for (int i = where_history(); history_get(i); i++)
+ log("%s\n", history_get(i)->line);
+#endif
}
} HistoryPass;
#endif
struct ScriptCmdPass : public Pass {
- ScriptCmdPass() : Pass("script", "execute commands from script file") { }
- virtual void help() {
+ ScriptCmdPass() : Pass("script", "execute commands from file or wire") { }
+ void help() YS_OVERRIDE {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" script <filename> [<from_label>:<to_label>]\n");
+ log(" script -scriptwire [selection]\n");
log("\n");
- log("This command executes the yosys commands in the specified file.\n");
+ log("This command executes the yosys commands in the specified file (default\n");
+ log("behaviour), or commands embedded in the constant text value connected to the\n");
+ log("selected wires.\n");
log("\n");
- log("The 2nd argument can be used to only execute the section of the\n");
- log("file between the specified labels. An empty from label is synonymous\n");
- log("for the beginning of the file and an empty to label is synonymous\n");
- log("for the end of the file.\n");
+ log("In the default (file) case, the 2nd argument can be used to only execute the\n");
+ log("section of the file between the specified labels. An empty from label is\n");
+ log("synonymous with the beginning of the file and an empty to label is synonymous\n");
+ log("with the end of the file.\n");
log("\n");
log("If only one label is specified (without ':') then only the block\n");
log("marked with that label (until the next label) is executed.\n");
log("\n");
+ log("In \"-scriptwire\" mode, the commands on the selected wire(s) will be executed\n");
+ log("in the scope of (and thus, relative to) the wires' owning module(s). This\n");
+ log("'-module' mode can be exited by using the 'cd' command.\n");
+ log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design) {
- if (args.size() < 2)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ bool scriptwire = false;
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++) {
+ if (args[argidx] == "-scriptwire") {
+ scriptwire = true;
+ continue;
+ }
+ break;
+ }
+ if (scriptwire) {
+ extra_args(args, argidx, design);
+
+ for (auto mod : design->selected_modules())
+ for (auto &c : mod->connections()) {
+ if (!c.first.is_wire())
+ continue;
+ auto w = c.first.as_wire();
+ if (!mod->selected(w))
+ continue;
+ if (!c.second.is_fully_const())
+ log_error("RHS of selected wire %s.%s is not constant.\n", log_id(mod), log_id(w));
+ auto v = c.second.as_const();
+ Pass::call_on_module(design, mod, v.decode_string());
+ }
+ }
+ else if (args.size() < 2)
log_cmd_error("Missing script file.\n");
else if (args.size() == 2)
run_frontend(args[1], "script", design);
diff --git a/kernel/yosys.h b/kernel/yosys.h
index 5ec681b32..179bfe07a 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -1,4 +1,4 @@
-/*
+/* -*- c++ -*-
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
@@ -52,6 +52,7 @@
#include <stdexcept>
#include <memory>
#include <cmath>
+#include <cstddef>
#include <sstream>
#include <fstream>
@@ -66,6 +67,10 @@
#include <stdio.h>
#include <limits.h>
+#ifdef WITH_PYTHON
+#include <Python.h>
+#endif
+
#ifndef _YOSYS_
# error It looks like you are trying to build Yosys without the config defines set. \
When building Yosys with a custom make system, make sure you set all the \
@@ -83,6 +88,10 @@ extern int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName);
extern void Tcl_Finalize(void);
extern int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr);
extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
+extern Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length);
+extern Tcl_Obj *Tcl_NewIntObj(int intValue);
+extern Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]);
+extern Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags);
# endif
#endif
@@ -115,6 +124,7 @@ extern const char *Tcl_GetStringResult(Tcl_Interp *interp);
# define PATH_MAX 4096
#endif
+#define YOSYS_NAMESPACE Yosys
#define PRIVATE_NAMESPACE_BEGIN namespace {
#define PRIVATE_NAMESPACE_END }
#define YOSYS_NAMESPACE_BEGIN namespace Yosys {
@@ -200,6 +210,7 @@ namespace RTLIL {
struct Module;
struct Design;
struct Monitor;
+ enum State : unsigned char;
}
namespace AST {
@@ -239,7 +250,7 @@ extern bool memhasher_active;
inline void memhasher() { if (memhasher_active) memhasher_do(); }
void yosys_banner();
-int ceil_log2(int x);
+int ceil_log2(int x) YS_ATTRIBUTE(const);
std::string stringf(const char *fmt, ...) YS_ATTRIBUTE(format(printf, 1, 2));
std::string vstringf(const char *fmt, va_list ap);
int readsome(std::istream &f, char *s, int n);
@@ -252,6 +263,7 @@ std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX");
bool check_file_exists(std::string filename, bool is_exec = false);
bool is_absolute_path(std::string filename);
void remove_directory(std::string dirname);
+std::string escape_filename_spaces(const std::string& filename);
template<typename T> int GetSize(const T &obj) { return obj.size(); }
int GetSize(RTLIL::Wire *wire);
@@ -276,6 +288,11 @@ namespace hashlib {
}
void yosys_setup();
+
+#ifdef WITH_PYTHON
+bool yosys_already_setup();
+#endif
+
void yosys_shutdown();
#ifdef YOSYS_ENABLE_TCL
@@ -289,8 +306,17 @@ RTLIL::IdString new_id(std::string file, int line, std::string func);
#define NEW_ID \
YOSYS_NAMESPACE_PREFIX new_id(__FILE__, __LINE__, __FUNCTION__)
-#define ID(_str) \
- ([]() { static YOSYS_NAMESPACE_PREFIX RTLIL::IdString _id(_str); return _id; })()
+// Create a statically allocated IdString object, using for example ID(A) or ID($add).
+//
+// Recipe for Converting old code that is using conversion of strings like "\\A" and
+// "$add" for creating IdStrings: Run below SED command on the .cc file and then use for
+// example "meld foo.cc foo.cc.orig" to manually compile errors, if necessary.
+//
+// sed -i.orig -r 's/"\\\\([a-zA-Z0-9_]+)"/ID(\1)/g; s/"(\$[a-zA-Z0-9_]+)"/ID(\1)/g;' <filename>
+//
+#define ID(_id) ([]() { const char *p = "\\" #_id, *q = p[1] == '$' ? p+1 : p; \
+ static const YOSYS_NAMESPACE_PREFIX RTLIL::IdString id(q); return id; })()
+namespace ID = RTLIL::ID;
RTLIL::Design *yosys_get_design();
std::string proc_self_dirname();
@@ -305,6 +331,9 @@ void run_frontend(std::string filename, std::string command, RTLIL::Design *desi
void run_backend(std::string filename, std::string command, RTLIL::Design *design = nullptr);
void shell(RTLIL::Design *design);
+// journal of all input and output files read (for "yosys -E")
+extern std::set<std::string> yosys_input_files, yosys_output_files;
+
// from kernel/version_*.o (cc source generated from Makefile)
extern const char *yosys_version_str;
@@ -314,6 +343,9 @@ extern std::vector<RTLIL::Design*> pushed_designs;
// from passes/cmds/pluginc.cc
extern std::map<std::string, void*> loaded_plugins;
+#ifdef WITH_PYTHON
+extern std::map<std::string, void*> loaded_python_plugins;
+#endif
extern std::map<std::string, std::string> loaded_plugin_aliases;
void load_plugin(std::string filename, std::vector<std::string> aliases);