aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Zonenberg <azonenberg@drawersteak.com>2017-02-14 08:29:37 -0800
committerAndrew Zonenberg <azonenberg@drawersteak.com>2017-02-14 08:29:37 -0800
commit6fed2dc996a57b0f7c4205e1d76da865dd410982 (patch)
treeab980df43bc10a3aeefb2220b17885e210eeb0a7
parent203b521a781ccc4c8dba05d2cc73e4625bcf2a8e (diff)
parent4fb800717101c65344fe78a365b8ae6ca0a90d9e (diff)
downloadyosys-6fed2dc996a57b0f7c4205e1d76da865dd410982.tar.gz
yosys-6fed2dc996a57b0f7c4205e1d76da865dd410982.tar.bz2
yosys-6fed2dc996a57b0f7c4205e1d76da865dd410982.zip
Merge https://github.com/cliffordwolf/yosys
-rw-r--r--backends/edif/edif.cc7
-rw-r--r--backends/firrtl/firrtl.cc122
-rw-r--r--backends/firrtl/test.sh19
-rw-r--r--backends/firrtl/test.v67
-rw-r--r--frontends/ast/simplify.cc11
-rw-r--r--kernel/driver.cc14
-rw-r--r--kernel/log.cc29
-rw-r--r--kernel/log.h2
-rw-r--r--passes/hierarchy/hierarchy.cc5
-rw-r--r--passes/techmap/techmap.cc9
-rw-r--r--techlibs/greenpak4/synth_greenpak4.cc2
11 files changed, 240 insertions, 47 deletions
diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc
index d16f18316..6414bc6e5 100644
--- a/backends/edif/edif.cc
+++ b/backends/edif/edif.cc
@@ -323,7 +323,10 @@ struct EdifBackend : public Backend {
for (auto &p : cell->connections()) {
RTLIL::SigSpec sig = sigmap(p.second);
for (int i = 0; i < GetSize(sig); i++)
- if (sig.size() == 1)
+ if (sig[i].wire == NULL && sig[i] != RTLIL::State::S0 && sig[i] != RTLIL::State::S1)
+ log_warning("Bit %d of cell port %s.%s.%s driven by %s will be left unconnected in EDIF output.\n",
+ i, log_id(module), log_id(cell), log_id(p.first), log_signal(sig[i]));
+ else if (sig.size() == 1)
net_join_db[sig[i]].insert(stringf("(portRef %s (instanceRef %s))", EDIF_REF(p.first), EDIF_REF(cell->name)));
else
net_join_db[sig[i]].insert(stringf("(portRef (member %s %d) (instanceRef %s))", EDIF_REF(p.first), i, EDIF_REF(cell->name)));
@@ -332,7 +335,7 @@ struct EdifBackend : public Backend {
for (auto &it : net_join_db) {
RTLIL::SigBit sig = it.first;
if (sig.wire == NULL && sig != RTLIL::State::S0 && sig != RTLIL::State::S1)
- continue;
+ log_abort();
std::string netname = log_signal(sig);
for (size_t i = 0; i < netname.size(); i++)
if (netname[i] == ' ' || netname[i] == '\\')
diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc
index 0d1c1889d..06cbc9b2b 100644
--- a/backends/firrtl/firrtl.cc
+++ b/backends/firrtl/firrtl.cc
@@ -157,7 +157,53 @@ struct FirrtlWorker
for (auto cell : module->cells())
{
- if (cell->type.in("$add", "$sub", "$xor"))
+ if (cell->type.in("$not", "$logic_not", "$neg", "$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_bool", "$reduce_xnor"))
+ {
+ string y_id = make_id(cell->name);
+ bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool();
+ int y_width = cell->parameters.at("\\Y_WIDTH").as_int();
+ string a_expr = make_expr(cell->getPort("\\A"));
+ wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
+
+ if (cell->parameters.at("\\A_SIGNED").as_bool()) {
+ a_expr = "asSInt(" + a_expr + ")";
+ }
+
+ a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
+
+ string primop;
+ bool always_uint = false;
+ if (cell->type == "$not") primop = "not";
+ if (cell->type == "$neg") primop = "neg";
+ if (cell->type == "$logic_not") {
+ primop = "eq";
+ a_expr = stringf("%s, UInt(0)", a_expr.c_str());
+ }
+ if (cell->type == "$reduce_and") primop = "andr";
+ if (cell->type == "$reduce_or") primop = "orr";
+ if (cell->type == "$reduce_xor") primop = "xorr";
+ if (cell->type == "$reduce_xnor") {
+ primop = "not";
+ a_expr = stringf("xorr(%s)", a_expr.c_str());
+ }
+ if (cell->type == "$reduce_bool") {
+ primop = "neq";
+ a_expr = stringf("%s, UInt(0)", a_expr.c_str());
+ }
+
+ string expr = stringf("%s(%s)", primop.c_str(), a_expr.c_str());
+
+ if ((is_signed && !always_uint))
+ expr = stringf("asUInt(%s)", expr.c_str());
+
+ cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
+ register_reverse_wire_map(y_id, cell->getPort("\\Y"));
+
+ continue;
+ }
+ if (cell->type.in("$add", "$sub", "$mul", "$div", "$mod", "$xor", "$and", "$or", "$eq", "$eqx",
+ "$gt", "$ge", "$lt", "$le", "$ne", "$nex", "$shr", "$sshr", "$sshl", "$shl",
+ "$logic_and", "$logic_or"))
{
string y_id = make_id(cell->name);
bool is_signed = cell->parameters.at("\\A_SIGNED").as_bool();
@@ -166,22 +212,88 @@ struct FirrtlWorker
string b_expr = make_expr(cell->getPort("\\B"));
wire_decls.push_back(stringf(" wire %s: UInt<%d>\n", y_id.c_str(), y_width));
- if (is_signed) {
+ if (cell->parameters.at("\\A_SIGNED").as_bool()) {
a_expr = "asSInt(" + a_expr + ")";
+ }
+ if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type != "$shr")) {
b_expr = "asSInt(" + b_expr + ")";
}
a_expr = stringf("pad(%s, %d)", a_expr.c_str(), y_width);
- b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
+
+ if ((cell->type != "$shl") && (cell->type != "$sshl")) {
+ b_expr = stringf("pad(%s, %d)", b_expr.c_str(), y_width);
+ }
+
+ if (cell->parameters.at("\\A_SIGNED").as_bool() & (cell->type == "$shr")) {
+ a_expr = "asUInt(" + a_expr + ")";
+ }
string primop;
+ bool always_uint = false;
if (cell->type == "$add") primop = "add";
if (cell->type == "$sub") primop = "sub";
- if (cell->type == "$xor") primop = "xor";
+ if (cell->type == "$mul") primop = "mul";
+ if (cell->type == "$div") primop = "div";
+ if (cell->type == "$mod") primop = "rem";
+ if (cell->type == "$and") {
+ primop = "and";
+ always_uint = true;
+ }
+ if (cell->type == "$or" ) {
+ primop = "or";
+ always_uint = true;
+ }
+ if (cell->type == "$xor") {
+ primop = "xor";
+ always_uint = true;
+ }
+ if ((cell->type == "$eq") | (cell->type == "$eqx")) {
+ primop = "eq";
+ always_uint = true;
+ }
+ if ((cell->type == "$ne") | (cell->type == "$nex")) {
+ primop = "neq";
+ always_uint = true;
+ }
+ if (cell->type == "$gt") {
+ primop = "gt";
+ always_uint = true;
+ }
+ if (cell->type == "$ge") {
+ primop = "geq";
+ always_uint = true;
+ }
+ if (cell->type == "$lt") {
+ primop = "lt";
+ always_uint = true;
+ }
+ if (cell->type == "$le") {
+ primop = "leq";
+ always_uint = true;
+ }
+ if ((cell->type == "$shl") | (cell->type == "$sshl")) primop = "dshl";
+ if ((cell->type == "$shr") | (cell->type == "$sshr")) primop = "dshr";
+ if ((cell->type == "$logic_and")) {
+ primop = "and";
+ a_expr = "neq(" + a_expr + ", UInt(0))";
+ b_expr = "neq(" + b_expr + ", UInt(0))";
+ always_uint = true;
+ }
+ if ((cell->type == "$logic_or")) {
+ primop = "or";
+ a_expr = "neq(" + a_expr + ", UInt(0))";
+ b_expr = "neq(" + b_expr + ", UInt(0))";
+ always_uint = true;
+ }
+
+ if (!cell->parameters.at("\\B_SIGNED").as_bool()) {
+ b_expr = "asUInt(" + b_expr + ")";
+ }
string expr = stringf("%s(%s, %s)", primop.c_str(), a_expr.c_str(), b_expr.c_str());
- if ((is_signed && !cell->type.in("$xor")) || cell->type.in("$sub"))
+ if ((is_signed && !always_uint) || cell->type.in("$sub"))
expr = stringf("asUInt(%s)", expr.c_str());
cell_exprs.push_back(stringf(" %s <= %s\n", y_id.c_str(), expr.c_str()));
diff --git a/backends/firrtl/test.sh b/backends/firrtl/test.sh
index 0a7151afa..fe7e3a329 100644
--- a/backends/firrtl/test.sh
+++ b/backends/firrtl/test.sh
@@ -1,16 +1,20 @@
#!/bin/bash
set -ex
-../../yosys -p 'prep -nordff; write_firrtl test.fir' test.v
+cd ../../
+make
+cd backends/firrtl
-firrtl -i test.fir -o test_out.v
+../../yosys -q -p 'prep -nordff; write_firrtl test.fir' $1
-../../yosys -p '
- read_verilog test.v
- rename test gold
+firrtl -i test.fir -o test_out.v -ll Info
+
+../../yosys -p "
+ read_verilog $1
+ rename Top gold
read_verilog test_out.v
- rename test gate
+ rename Top gate
prep
memory_map
@@ -18,5 +22,4 @@ firrtl -i test.fir -o test_out.v
hierarchy -top miter
sat -verify -prove trigger 0 -set-init-zero -seq 10 miter
-'
-
+"
diff --git a/backends/firrtl/test.v b/backends/firrtl/test.v
index 1c7088ab8..c6d62a847 100644
--- a/backends/firrtl/test.v
+++ b/backends/firrtl/test.v
@@ -1,24 +1,63 @@
module test(
input clk, wen,
- input [4:0] waddr, raddr,
- input [31:0] wdata,
- output reg [31:0] rdata,
- signed input [7:0] a, b, x,
- output [15:0] s, d, y, z, u, q
+ input [7:0] uns,
+ input signed [7:0] a, b,
+ input signed [23:0] c,
+ input signed [2:0] sel,
+ output [15:0] s, d, y, z, u, q, p, mul, div, mod, mux, And, Or, Xor, eq, neq, gt, lt, geq, leq, eqx, shr, sshr, shl, sshl, Land, Lor, Lnot, Not, Neg, pos, Andr, Orr, Xorr, Xnorr, Reduce_bool,
+ output [7:0] PMux
);
- reg [31:0] memory [0:31];
-
- always @(posedge clk) begin
- rdata <= memory[raddr];
- if (wen) memory[waddr] <= wdata;
- end
-
+ //initial begin
+ //$display("shr = %b", shr);
+ //end
assign s = a+{b[6:2], 2'b1};
assign d = a-b;
assign y = x;
assign z[7:0] = s+d;
assign z[15:8] = s-d;
+ assign p = a & b | x;
+ assign mul = a * b;
+ assign div = a / b;
+ assign mod = a % b;
+ assign mux = x[0] ? a : b;
+ assign And = a & b;
+ assign Or = a | b;
+ assign Xor = a ^ b;
+ assign Not = ~a;
+ assign Neg = -a;
+ assign eq = a == b;
+ assign neq = a != b;
+ assign gt = a > b;
+ assign lt = a < b;
+ assign geq = a >= b;
+ assign leq = a <= b;
+ assign eqx = a === b;
+ assign shr = a >> b; //0111111111000000
+ assign sshr = a >>> b;
+ assign shl = a << b;
+ assign sshl = a <<< b;
+ assign Land = a && b;
+ assign Lor = a || b;
+ assign Lnot = !a;
+ assign pos = $signed(uns);
+ assign Andr = &a;
+ assign Orr = |a;
+ assign Xorr = ^a;
+ assign Xnorr = ~^a;
+ always @*
+ if(!a) begin
+ Reduce_bool = a;
+ end else begin
+ Reduce_bool = b;
+ end
+ //always @(sel or c or a)
+ // begin
+ // case (sel)
+ // 3'b000: PMux = a;
+ // 3'b001: PMux = c[7:0];
+ // 3'b010: PMux = c[15:8];
+ // 3'b100: PMux = c[23:16];
+ // endcase
+ // end
- always @(posedge clk)
- q <= s ^ d ^ x;
endmodule
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index eecc04132..f7fcbc479 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -2183,9 +2183,16 @@ skip_dynamic_range_lvalue_expansion:;
if (wire->children.empty()) {
for (auto c : child->children)
wire->children.push_back(c->clone());
- } else {
- if (!child->children.empty())
+ } else if (!child->children.empty()) {
+ while (child->simplify(true, false, false, stage, -1, false, false)) { }
+ if (GetSize(child->children) == GetSize(wire->children)) {
+ for (int i = 0; i < GetSize(child->children); i++)
+ if (*child->children.at(i) != *wire->children.at(i))
+ goto tcall_incompatible_wires;
+ } else {
+ tcall_incompatible_wires:
log_error("Incompatible re-declaration of wire %s at %s:%d.\n", child->str.c_str(), filename.c_str(), linenum);
+ }
}
}
else
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 3652ff4f1..7d714d079 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -219,7 +219,11 @@ int main(int argc, char **argv)
printf(" Use 'ALL' as <header_id> to dump at every header.\n");
printf("\n");
printf(" -W regex\n");
- printf(" print a warning for all log messages matching the regex \n");
+ 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(" message instead.\n");
printf("\n");
printf(" -V\n");
printf(" print version information and exit\n");
@@ -241,7 +245,7 @@ int main(int argc, char **argv)
}
int opt;
- while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:D:")) != -1)
+ while ((opt = getopt(argc, argv, "MXAQTVSm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:D:")) != -1)
{
switch (opt)
{
@@ -329,6 +333,12 @@ int main(int argc, char **argv)
std::regex_constants::optimize |
std::regex_constants::egrep));
break;
+ case 'w':
+ log_nowarn_regexes.push_back(std::regex(optarg,
+ std::regex_constants::nosubs |
+ std::regex_constants::optimize |
+ std::regex_constants::egrep));
+ break;
case 'D':
{
auto args = split_tokens(optarg, ":");
diff --git a/kernel/log.cc b/kernel/log.cc
index 956d93fd1..c7240d540 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -41,7 +41,7 @@ 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;
+std::vector<std::regex> log_warn_regexes, log_nowarn_regexes;
bool log_hdump_all = false;
FILE *log_errfile = NULL;
SHA1 *log_hasher = NULL;
@@ -202,15 +202,28 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap)
void logv_warning(const char *format, va_list ap)
{
- if (log_errfile != NULL && !log_quiet_warnings)
- log_files.push_back(log_errfile);
+ std::string message = vstringf(format, ap);
+ bool suppressed = false;
- log("Warning: ");
- logv(format, ap);
- log_flush();
+ for (auto &re : log_nowarn_regexes)
+ if (std::regex_search(message, re))
+ suppressed = true;
- if (log_errfile != NULL && !log_quiet_warnings)
- log_files.pop_back();
+ if (suppressed)
+ {
+ log("Suppressed warning: %s", message.c_str());
+ }
+ else
+ {
+ if (log_errfile != NULL && !log_quiet_warnings)
+ log_files.push_back(log_errfile);
+
+ log("Warning: %s", message.c_str());
+ log_flush();
+
+ if (log_errfile != NULL && !log_quiet_warnings)
+ log_files.pop_back();
+ }
}
void logv_error(const char *format, va_list ap)
diff --git a/kernel/log.h b/kernel/log.h
index 34b8ac3a5..34c309016 100644
--- a/kernel/log.h
+++ b/kernel/log.h
@@ -49,7 +49,7 @@ 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;
+extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes;
extern bool log_hdump_all;
extern FILE *log_errfile;
extern SHA1 *log_hasher;
diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc
index 4786aacaf..3534cbcdb 100644
--- a/passes/hierarchy/hierarchy.cc
+++ b/passes/hierarchy/hierarchy.cc
@@ -625,9 +625,12 @@ struct HierarchyPass : public Pass {
for (auto module : design->modules())
for (auto cell : module->cells())
{
+ if (GetSize(cell->parameters) != 0)
+ continue;
+
Module *m = design->module(cell->type);
- if (m == nullptr)
+ if (m == nullptr || m->get_bool_attribute("\\blackbox"))
continue;
for (auto &conn : cell->connections())
diff --git a/passes/techmap/techmap.cc b/passes/techmap/techmap.cc
index 6784f48c3..b351d3be8 100644
--- a/passes/techmap/techmap.cc
+++ b/passes/techmap/techmap.cc
@@ -305,10 +305,15 @@ struct TechmapWorker
// approach that yields nicer outputs:
// replace internal wires that are connected to external wires
- if (w->port_output)
+ if (w->port_output && !w->port_input) {
port_signal_map.add(c.second, c.first);
- else
+ } else
+ if (!w->port_output && w->port_input) {
port_signal_map.add(c.first, c.second);
+ } else {
+ module->connect(c);
+ extra_connect = SigSig();
+ }
for (auto &attr : w->attributes) {
if (attr.first == "\\src")
diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc
index be12ab495..92bcc8de7 100644
--- a/techlibs/greenpak4/synth_greenpak4.cc
+++ b/techlibs/greenpak4/synth_greenpak4.cc
@@ -204,8 +204,6 @@ struct SynthGreenPAK4Pass : public ScriptPass
if (!json_file.empty() || help_mode)
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
}
-
- log_pop();
}
} SynthGreenPAK4Pass;