From 828303791b5f4a50a52d4749be42caac9819bf2a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Feb 2017 11:11:00 +0100 Subject: [PATCH 1/8] Add "yosys -w" for suppressing warnings --- kernel/driver.cc | 14 ++++++++++++-- kernel/log.cc | 29 +++++++++++++++++++++-------- kernel/log.h | 2 +- 3 files changed, 34 insertions(+), 11 deletions(-) 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 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 log_files; std::vector log_streams; std::map> log_hdump; -std::vector log_warn_regexes; +std::vector 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 log_files; extern std::vector log_streams; extern std::map> log_hdump; -extern std::vector log_warn_regexes; +extern std::vector log_warn_regexes, log_nowarn_regexes; extern bool log_hdump_all; extern FILE *log_errfile; extern SHA1 *log_hasher; From 76c4ee096bba99f787dd042bd9a6e988cf72f2dc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 12 Feb 2017 17:42:57 +0100 Subject: [PATCH 2/8] Do not eagerly fix port widths on parameterized cells --- passes/hierarchy/hierarchy.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 4786aacaf..037fdb3b2 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -625,6 +625,9 @@ 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) From db7314bc02b4e8b1827993cd844eac9c7070579f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 13 Feb 2017 16:55:25 +0100 Subject: [PATCH 3/8] Fix techmap for inout ports connected to inout ports --- passes/techmap/techmap.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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") From 69468d5a16f87616af9c7f084f6ff247f3513050 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 13 Feb 2017 17:07:38 +0100 Subject: [PATCH 4/8] Do not fix port widths on any blackbox instances --- passes/hierarchy/hierarchy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/hierarchy/hierarchy.cc b/passes/hierarchy/hierarchy.cc index 037fdb3b2..3534cbcdb 100644 --- a/passes/hierarchy/hierarchy.cc +++ b/passes/hierarchy/hierarchy.cc @@ -630,7 +630,7 @@ struct HierarchyPass : public Pass { Module *m = design->module(cell->type); - if (m == nullptr) + if (m == nullptr || m->get_bool_attribute("\\blackbox")) continue; for (auto &conn : cell->connections()) From 794cec00166f46a3ea8480377ee7f773884a8f5d Mon Sep 17 00:00:00 2001 From: Adam Izraelevitz Date: Mon, 21 Nov 2016 17:28:17 -0800 Subject: [PATCH 5/8] More progress on Firrtl backend. Chisel -> Firrtl -> Verilog -> Firrtl -> Verilog is successful for a simple rocket-chip design. --- backends/firrtl/firrtl.cc | 122 ++++++++++++++++++++++++++++++++++++-- backends/firrtl/test.sh | 19 +++--- backends/firrtl/test.v | 67 ++++++++++++++++----- 3 files changed, 181 insertions(+), 27 deletions(-) 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 From 2a311c2c386ce173dca8c5e6e883a8f4f2d9ef00 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 14 Feb 2017 11:57:54 +0100 Subject: [PATCH 6/8] Fix double-call of log_pop() in synth_greenpak4 --- techlibs/greenpak4/synth_greenpak4.cc | 2 -- 1 file changed, 2 deletions(-) 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 ? "" : json_file.c_str())); } - - log_pop(); } } SynthGreenPAK4Pass; From 4e80ce97a8de55360a9aa5cb05c734fd4b0ba5c5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 14 Feb 2017 12:49:35 +0100 Subject: [PATCH 7/8] Add warning about x/z bits left unconnected in EDIF output --- backends/edif/edif.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 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] == '\\') From 4fb800717101c65344fe78a365b8ae6ca0a90d9e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 14 Feb 2017 15:10:59 +0100 Subject: [PATCH 8/8] Fix incorrect "incompatible re-declaration of wire" error in tasks/functions --- frontends/ast/simplify.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) 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