diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | frontends/verific/verific.cc | 8 | ||||
-rw-r--r-- | misc/py_wrap_generator.py | 1 | ||||
-rw-r--r-- | passes/cmds/setundef.cc | 118 | ||||
-rw-r--r-- | passes/opt/opt_clean.cc | 2 | ||||
-rw-r--r-- | passes/opt/opt_rmdff.cc | 4 | ||||
-rw-r--r-- | passes/sat/fmcombine.cc | 4 | ||||
-rw-r--r-- | passes/sat/sim.cc | 5 | ||||
-rw-r--r-- | passes/techmap/shregmap.cc | 3 | ||||
-rw-r--r-- | techlibs/ecp5/cells_map.v | 15 | ||||
-rw-r--r-- | techlibs/xilinx/synth_xilinx.cc | 11 |
11 files changed, 135 insertions, 38 deletions
@@ -413,7 +413,7 @@ Verilog Attributes and non-standard features $ yosys -p 'plugin -a foo -i /lib/libm.so; read_verilog dpitest.v' - Sized constants (the syntax ``<size>'s?[bodh]<value>``) support constant - expressions as <size>. If the expression is not a simple identifier, it + expressions as ``<size>``. If the expression is not a simple identifier, it must be put in parentheses. Examples: ``WIDTH'd42``, ``(4+2)'b101010`` - The system tasks ``$finish``, ``$stop`` and ``$display`` are supported in diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 33d2ac7a8..2bf99e58e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -48,6 +48,14 @@ USING_YOSYS_NAMESPACE #include "VhdlUnits.h" #include "VeriLibrary.h" +#ifndef SYMBIOTIC_VERIFIC_API_VERSION +# error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific." +#endif + +#if SYMBIOTIC_VERIFIC_API_VERSION < 1 +# error "Please update your version of Symbiotic EDA flavored Verific." +#endif + #ifdef __clang__ #pragma clang diagnostic pop #endif diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index 09f934040..9f2c72915 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -2060,7 +2060,6 @@ namespace YOSYS_PYTHON { Yosys::log_streams.push_back(&std::cout); Yosys::log_error_stderr = true; Yosys::yosys_setup(); - Yosys::yosys_banner(); } } diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index f6949c820..3eedc86b8 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -393,44 +393,112 @@ struct SetundefPass : public Pass { ffbits.insert(bit); } - for (auto wire : module->wires()) + auto process_initwires = [&]() { - if (!wire->attributes.count("\\init")) - continue; + dict<Wire*, int> wire_weights; - for (auto bit : sigmap(wire)) - ffbits.erase(bit); + for (auto wire : initwires) + { + int weight = 0; - initwires.insert(wire); - } + for (auto bit : sigmap(wire)) + weight += ffbits.count(bit) ? +1 : -1; + + wire_weights[wire] = weight; + } + + initwires.sort([&](Wire *a, Wire *b) { return wire_weights.at(a) > wire_weights.at(b); }); + + for (auto wire : initwires) + { + Const &initval = wire->attributes["\\init"]; + initval.bits.resize(GetSize(wire), State::Sx); + + for (int i = 0; i < GetSize(wire); i++) { + SigBit bit = sigmap(SigBit(wire, i)); + if (initval[i] == State::Sx && ffbits.count(bit)) { + initval[i] = worker.next_bit(); + ffbits.erase(bit); + } + } + + if (initval.is_fully_undef()) + wire->attributes.erase("\\init"); + } + + initwires.clear(); + }; for (int wire_types = 0; wire_types < 2; wire_types++) - for (auto wire : module->wires()) + { + // prioritize wires that already have an init attribute + if (!ffbits.empty()) { - if (wire->name[0] == (wire_types ? '\\' : '$')) - next_wire: - continue; + for (auto wire : module->wires()) + { + if (wire->name[0] == (wire_types ? '\\' : '$')) + continue; - for (auto bit : sigmap(wire)) - if (!ffbits.count(bit)) - goto next_wire; + if (!wire->attributes.count("\\init")) + continue; - for (auto bit : sigmap(wire)) - ffbits.erase(bit); + Const &initval = wire->attributes["\\init"]; + initval.bits.resize(GetSize(wire), State::Sx); + + if (initval.is_fully_undef()) { + wire->attributes.erase("\\init"); + continue; + } - initwires.insert(wire); + for (int i = 0; i < GetSize(wire); i++) + if (initval[i] != State::Sx) + ffbits.erase(sigmap(SigBit(wire, i))); + + initwires.insert(wire); + } + + process_initwires(); } - for (auto wire : initwires) - { - Const &initval = wire->attributes["\\init"]; + // next consider wires that completely contain bits to be initialized + if (!ffbits.empty()) + { + for (auto wire : module->wires()) + { + if (wire->name[0] == (wire_types ? '\\' : '$')) + continue; - for (int i = 0; i < GetSize(wire); i++) - if (GetSize(initval) <= i) - initval.bits.push_back(worker.next_bit()); - else if (initval.bits[i] == State::Sx) - initval.bits[i] = worker.next_bit(); + for (auto bit : sigmap(wire)) + if (!ffbits.count(bit)) + goto next_wire; + + initwires.insert(wire); + + next_wire: + continue; + } + + process_initwires(); + } + + // finally use whatever wire we can find. + if (!ffbits.empty()) + { + for (auto wire : module->wires()) + { + if (wire->name[0] == (wire_types ? '\\' : '$')) + continue; + + for (auto bit : sigmap(wire)) + if (ffbits.count(bit)) + initwires.insert(wire); + } + + process_initwires(); + } } + + log_assert(ffbits.empty()); } module->rewrite_sigspecs(worker); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 7011d4602..cfb0f788a 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -106,7 +106,7 @@ void rmunused_module_cells(Module *module, bool verbose) if (raw_bit.wire == nullptr) continue; auto bit = sigmap(raw_bit); - if (bit.wire == nullptr) + if (bit.wire == nullptr && ct_all.cell_known(cell->type)) driver_driver_logs[raw_sigmap(raw_bit)].push_back(stringf("Driver-driver conflict " "for %s between cell %s.%s and constant %s in %s: Resolved using constant.", log_signal(raw_bit), log_id(cell), log_id(it2.first), log_signal(bit), log_id(module))); diff --git a/passes/opt/opt_rmdff.cc b/passes/opt/opt_rmdff.cc index 2abffa2a9..eeb992a3e 100644 --- a/passes/opt/opt_rmdff.cc +++ b/passes/opt/opt_rmdff.cc @@ -292,8 +292,8 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff) sig_q = dff->getPort("\\Q"); sig_c = dff->getPort("\\C"); sig_e = dff->getPort("\\E"); - val_cp = RTLIL::Const(dff->type[6] == 'P', 1); - val_ep = RTLIL::Const(dff->type[7] == 'P', 1); + val_cp = RTLIL::Const(dff->type[7] == 'P', 1); + val_ep = RTLIL::Const(dff->type[8] == 'P', 1); } else if (dff->type == "$ff") { sig_d = dff->getPort("\\D"); diff --git a/passes/sat/fmcombine.cc b/passes/sat/fmcombine.cc index f64d99dc2..00c098542 100644 --- a/passes/sat/fmcombine.cc +++ b/passes/sat/fmcombine.cc @@ -332,7 +332,7 @@ struct FmcombinePass : public Pass { gate_cell = module->cell(gate_name); if (gate_cell == nullptr) - log_cmd_error("Gold cell %s not found in module %s.\n", log_id(gate_name), log_id(module)); + log_cmd_error("Gate cell %s not found in module %s.\n", log_id(gate_name), log_id(module)); } else { @@ -351,7 +351,7 @@ struct FmcombinePass : public Pass { if (!gold_cell->parameters.empty()) log_cmd_error("Gold cell has unresolved instance parameters.\n"); if (!gate_cell->parameters.empty()) - log_cmd_error("Gold cell has unresolved instance parameters.\n"); + log_cmd_error("Gate cell has unresolved instance parameters.\n"); FmcombineWorker worker(design, gold_cell->type, opts); worker.generate(); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 53e248adf..4c3022c70 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -88,6 +88,8 @@ struct SimInstance SimInstance(SimShared *shared, Module *module, Cell *instance = nullptr, SimInstance *parent = nullptr) : shared(shared), module(module), instance(instance), parent(parent), sigmap(module) { + log_assert(module); + if (parent) { log_assert(parent->children.count(instance) == 0); parent->children[instance] = this; @@ -848,6 +850,9 @@ struct SimPass : public Pass { if (design->full_selection()) { top_mod = design->top_module(); + + if (!top_mod) + log_cmd_error("Design has no top module, use the 'hierarchy' command to specify one.\n"); } else { auto mods = design->selected_whole_modules(); if (GetSize(mods) != 1) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 75eedfbcc..21dfe9619 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -606,6 +606,9 @@ struct ShregmapPass : public Pass { log(" -tech greenpak4\n"); log(" map to greenpak4 shift registers.\n"); log("\n"); + log(" -tech xilinx\n"); + log(" map to xilinx dynamic-length shift registers.\n"); + log("\n"); } void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { diff --git a/techlibs/ecp5/cells_map.v b/techlibs/ecp5/cells_map.v index 6ab4b69f2..f6c71a03d 100644 --- a/techlibs/ecp5/cells_map.v +++ b/techlibs/ecp5/cells_map.v @@ -47,6 +47,21 @@ module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED" module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule +// Diamond I/O buffers +module IB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPU (input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPD (input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module OB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I)); endmodule +module OBZ (input I, T, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPU(input I, T, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPD(input I, T, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBCO (input I, output OT, OC); OLVDS _TECHMAP_REPLACE_ (.A(I), .Z(OT), .ZN(OC)); endmodule +module BB (input I, T, output O, inout B); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module BBPU (input I, T, output O, inout B); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module BBPD (input I, T, output O, inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module ILVDS(input A, AN, output Z); TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(A), .O(Z)); endmodule +module OLVDS(input A, output Z, ZN); TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(Z), .I(A)); endmodule + // For Diamond compatibility, FIXME: add all Diamond flipflop mappings module FD1S3BX(input PD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc index c20cac09b..a293081f1 100644 --- a/techlibs/xilinx/synth_xilinx.cc +++ b/techlibs/xilinx/synth_xilinx.cc @@ -229,11 +229,6 @@ struct SynthXilinxPass : public ScriptPass run("dff2dffe"); run("opt -full"); - if (!vpr || help_mode) - run("techmap -map +/xilinx/arith_map.v"); - else - run("techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY"); - if (!nosrl || help_mode) { // shregmap operates on bit-level flops, not word-level, // so break those down here @@ -242,7 +237,11 @@ struct SynthXilinxPass : public ScriptPass run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')"); } - run("techmap"); + if (!vpr || help_mode) + run("techmap -map +/techmap.v -map +/xilinx/arith_map.v"); + else + run("techmap -map +/techmap.v +/xilinx/arith_map.v -D _EXPLICIT_CARRY"); + run("opt -fast"); } |