From 822c7b0341064c3d0d9b142dc6ce61c66797159a Mon Sep 17 00:00:00 2001 From: Lofty Date: Wed, 25 Jan 2023 09:26:58 +0000 Subject: [PATCH 001/303] muxcover: do not add decode muxes with x inputs --- passes/techmap/muxcover.cc | 5 +---- tests/various/muxcover.ys | 40 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/passes/techmap/muxcover.cc b/passes/techmap/muxcover.cc index a90d8198578..2656f30ce56 100644 --- a/passes/techmap/muxcover.cc +++ b/passes/techmap/muxcover.cc @@ -179,7 +179,7 @@ struct MuxcoverWorker int prepare_decode_mux(SigBit &A, SigBit B, SigBit sel, SigBit bit) { - if (A == B || sel == State::Sx) + if (A == B || A == State::Sx || B == State::Sx || sel == State::Sx) return 0; tuple key(A, B, sel); @@ -197,9 +197,6 @@ struct MuxcoverWorker if (std::get<2>(entry)) return 0; - if (A == State::Sx || B == State::Sx) - return 0; - return cost_dmux / GetSize(std::get<1>(entry)); } diff --git a/tests/various/muxcover.ys b/tests/various/muxcover.ys index 67e9625e6da..37a90dcb075 100644 --- a/tests/various/muxcover.ys +++ b/tests/various/muxcover.ys @@ -508,3 +508,43 @@ design -import gate -as gate miter -equiv -flatten -make_assert -make_outputs -ignore_gold_x gold gate miter sat -verify -prove-asserts -show-ports miter + +## implement a mux6 as a mux8 :: https://github.com/YosysHQ/yosys/issues/3591 + +design -reset +read_verilog << EOF +module test (A, S, Y); + parameter INPUTS = 6; + + input [INPUTS-1:0] A; + input [$clog2(INPUTS)-1:0] S; + + wire [15:0] AA = {{(16-INPUTS){1'b0}}, A}; + wire [3:0] SS = {{(4-$clog2(INPUTS)){1'b0}}, S}; + + output Y = SS[3] ? (SS[2] ? SS[1] ? (SS[0] ? AA[15] : AA[14]) + : (SS[0] ? AA[13] : AA[12]) + : SS[1] ? (SS[0] ? AA[11] : AA[10]) + : (SS[0] ? AA[9] : AA[8])) + : (SS[2] ? SS[1] ? (SS[0] ? AA[7] : AA[6]) + : (SS[0] ? AA[5] : AA[4]) + : SS[1] ? (SS[0] ? AA[3] : AA[2]) + : (SS[0] ? AA[1] : AA[0])); +endmodule +EOF + +prep +design -save gold +simplemap t:\$mux +muxcover +opt_clean -purge +select -assert-count 1 t:$_MUX8_ +select -assert-none t:$_MUX8_ %% t:* %D +techmap -map +/simcells.v t:$_MUX8_ +design -stash gate + +design -import gold -as gold +design -import gate -as gate + +miter -equiv -flatten -make_assert -make_outputs -ignore_gold_x gold gate miter +sat -verify -prove-asserts -show-ports miter From dbc8b77222c74dcf8a1c2cc57118a0fb25a82787 Mon Sep 17 00:00:00 2001 From: martell Date: Sun, 29 Jan 2023 20:48:43 -0800 Subject: [PATCH 002/303] gowin: Add support for emulated differential output --- techlibs/gowin/cells_sim.v | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index ab8207ef107..51f781b1d34 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -582,6 +582,14 @@ module IOBUF (O, IO, I, OEN); assign I = IO; endmodule +module ELVDS_OBUF (I, O, OB); + input I; + output O; + output OB; + assign O = I; + assign OB = ~I; +endmodule + module TLVDS_OBUF (I, O, OB); input I; output O; From ea6f562d49caf109a7da2f50d21d3e3dd5c149bc Mon Sep 17 00:00:00 2001 From: uis Date: Mon, 6 Feb 2023 21:34:32 +0000 Subject: [PATCH 003/303] gowin: Add new types of oscillator --- techlibs/gowin/cells_sim.v | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index ab8207ef107..73bf400c0cb 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -1632,3 +1632,20 @@ output OSCOUT; parameter FREQ_DIV = 96; endmodule + +(* blackbox *) +module OSCW(OSCOUT); +output OSCOUT; + +parameter FREQ_DIV = 80; +endmodule + +(* blackbox *) +module OSCO(OSCOUT, OSCEN); +input OSCEN; + +output OSCOUT; + +parameter FREQ_DIV = 100; +parameter REGULATOR_EN = 1'b0; +endmodule From 131b5577278e4aa77d31a978f06d5aab51d2d58c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 19 Dec 2022 08:54:47 +0100 Subject: [PATCH 004/303] Initial implementation of synthesizable assertions --- passes/sat/Makefile.inc | 1 + passes/sat/synthprop.cc | 230 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 passes/sat/synthprop.cc diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index ebe3dc53682..cc89cc0c8ce 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -19,3 +19,4 @@ OBJS += passes/sat/fminit.o ifeq ($(DISABLE_SPAWN),0) OBJS += passes/sat/qbfsat.o endif +OBJS += passes/sat/synthprop.o diff --git a/passes/sat/synthprop.cc b/passes/sat/synthprop.cc new file mode 100644 index 00000000000..5bc1520bc8c --- /dev/null +++ b/passes/sat/synthprop.cc @@ -0,0 +1,230 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2022 Miodrag Milanovic + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +struct TrackingItem +{ + pool assertion_cells; + std::vector names; +}; + +typedef dict TrackingData; + +struct SynthPropWorker +{ + // pointer to main design + RTLIL::Design *design; + + RTLIL::IdString top_name; + + RTLIL::Module *module; + + std::string map_file; + + bool or_outputs; + + IdString port_name; + + // basic contrcutor + SynthPropWorker(RTLIL::Design *design) : design(design), or_outputs(false), port_name(RTLIL::escape_id("assertions")) {} + + void tracing(RTLIL::Module *mod, int depth, TrackingData &tracing_data, std::string hier_path); + void run(); +}; + +void SynthPropWorker::tracing(RTLIL::Module *mod, int depth, TrackingData &tracing_data, std::string hier_path) +{ + log("%*sTracing in module %s..\n", 2*depth, "", log_id(mod)); + tracing_data[mod] = TrackingItem(); + int cnt = 0; + for (auto cell : mod->cells()) { + if (cell->type == ID($assert)) { + log("%*sFound assert %s..\n", 2*(depth+1), "", log_id(cell)); + tracing_data[mod].assertion_cells.emplace(cell); + if (!or_outputs) { + tracing_data[mod].names.push_back(hier_path + "." + log_id(cell)); + } + cnt++; + } + else if (RTLIL::Module *submod = design->module(cell->type)) { + tracing(submod, depth+1, tracing_data, hier_path + "." + log_id(cell)); + if (!or_outputs) { + for (size_t i = 0; i < tracing_data[submod].names.size(); i++) + tracing_data[mod].names.push_back(tracing_data[submod].names[i]); + } else { + cnt += tracing_data[submod].names.size(); + } + } + } + if (or_outputs && (cnt > 0)) { + tracing_data[mod].names.push_back("merged_asserts"); + } +} + +void SynthPropWorker::run() +{ + if (!module->get_bool_attribute(ID::top)) + log_error("Module is not TOP module\n"); + + TrackingData tracing_data; + tracing(module, 0, tracing_data, log_id(module->name)); + + for (auto &data : tracing_data) { + if (data.second.names.size() == 0) continue; + RTLIL::Wire *wire = data.first->addWire(port_name, data.second.names.size()); + wire->port_output = true; + data.first->fixup_ports(); + } + + for (auto &data : tracing_data) { + int num = 0; + RTLIL::Wire *port_wire = data.first->wire(port_name); + pool connected; + for (auto cell : data.second.assertion_cells) { + if (cell->type == ID($assert)) { + RTLIL::Wire *neg_wire = data.first->addWire(NEW_ID); + RTLIL::Wire *result_wire = data.first->addWire(NEW_ID); + data.first->addNot(NEW_ID, cell->getPort(ID::A), neg_wire); + data.first->addAnd(NEW_ID, cell->getPort(ID::EN), neg_wire, result_wire); + if (!or_outputs) { + data.first->connect(SigBit(port_wire,num), result_wire); + } else { + connected.emplace(result_wire); + } + num++; + } + } + + for (auto cell : data.first->cells()) { + if (RTLIL::Module *submod = design->module(cell->type)) { + if (tracing_data[submod].names.size() > 0) { + if (!or_outputs) { + cell->setPort(port_name, SigChunk(port_wire, num, tracing_data[submod].names.size())); + } else { + RTLIL::Wire *result_wire = data.first->addWire(NEW_ID); + cell->setPort(port_name, result_wire); + connected.emplace(result_wire); + } + num += tracing_data[submod].names.size(); + } + } + } + if (or_outputs && connected.size() > 0) { + RTLIL::Wire *prev_wire = nullptr; + for (auto wire : connected ) { + if (!prev_wire) { + prev_wire = wire; + } else { + RTLIL::Wire *result = data.first->addWire(NEW_ID); + data.first->addOr(NEW_ID, prev_wire, wire, result); + prev_wire = result; + } + } + data.first->connect(port_wire, prev_wire); + } + } + + if (!map_file.empty()) { + std::ofstream fout; + fout.open(map_file, std::ios::out | std::ios::trunc); + if (!fout.is_open()) + log_error("Could not open file \"%s\" with write access.\n", map_file.c_str()); + + for (auto name : tracing_data[module].names) { + fout << name << std::endl; + } + } +} + +struct SyntProperties : public Pass { + SyntProperties() : Pass("synthprop", "synthesize SVA properties") { } + + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synthprop [options]\n"); + log("\n"); + log("This creates synthesizable properties for selected module.\n"); + log("\n"); + log("\n"); + log(" -name \n"); + log("\n"); + log("Name output port for assertions (default: assertions).\n"); + log("\n"); + log("\n"); + log(" -map \n"); + log("\n"); + log("Write port mapping for synthesizable properties.\n"); + log("\n"); + log("\n"); + log(" -or_outputs\n"); + log("\n"); + log("Or all outputs together to create a single output that goes high when any\n"); + log("property is violated, instead of generating individual output bits.\n"); + log("\n"); + log("\n"); + log(" -latch \n"); + log("\n"); + log("Latch a high state on the generated outputs until an asynchronous top-level\n"); + log("reset input is activated.\n"); + log("\n"); + log("\n"); + } + + virtual void execute(std::vector args, RTLIL::Design* design) + { + log_header(design, "Executing SYNTHPROP pass.\n"); + SynthPropWorker worker(design); + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-name" && argidx+1 < args.size()) { + worker.port_name = RTLIL::escape_id(args[++argidx]); + continue; + } + if (args[argidx] == "-map" && argidx+1 < args.size()) { + worker.map_file = args[++argidx]; + continue; + } + if (args[argidx] == "-latch" && argidx+2 < args.size()) { + continue; + } + if (args[argidx] == "-or_outputs") { + worker.or_outputs = true; + continue; + } + break; + } + + if (args.size() != argidx) + cmd_error(args, argidx, "Extra argument."); + + auto *top = design->top_module(); + if (top == nullptr) + log_cmd_error("Can't find top module in current design!\n"); + + worker.module = top; + worker.run(); + } +} SyntProperties; + +YOSYS_NAMESPACE_END From 713b7d3e262c777be649707112b81512bff94b5a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 19 Dec 2022 11:40:50 +0100 Subject: [PATCH 005/303] added support for latched output reset --- passes/sat/synthprop.cc | 47 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/passes/sat/synthprop.cc b/passes/sat/synthprop.cc index 5bc1520bc8c..5dd1fefdf45 100644 --- a/passes/sat/synthprop.cc +++ b/passes/sat/synthprop.cc @@ -43,6 +43,10 @@ struct SynthPropWorker IdString port_name; + IdString reset_name; + + bool reset_pol; + // basic contrcutor SynthPropWorker(RTLIL::Design *design) : design(design), or_outputs(false), port_name(RTLIL::escape_id("assertions")) {} @@ -94,9 +98,14 @@ void SynthPropWorker::run() data.first->fixup_ports(); } + RTLIL::Wire *output = nullptr; for (auto &data : tracing_data) { int num = 0; RTLIL::Wire *port_wire = data.first->wire(port_name); + if (!reset_name.empty() && data.first == module) { + port_wire = data.first->addWire(NEW_ID, data.second.names.size()); + output = port_wire; + } pool connected; for (auto cell : data.second.assertion_cells) { if (cell->type == ID($assert)) { @@ -142,6 +151,17 @@ void SynthPropWorker::run() } } + // If no assertions found + if (tracing_data[module].names.size() == 0) return; + + if (!reset_name.empty()) { + int width = tracing_data[module].names.size(); + SigSpec reset = module->wire(reset_name); + reset.extend_u0(width, true); + + module->addDlatchsr(NEW_ID, State::S1, Const(State::S0,width), reset, output, module->wire(port_name), true, true, reset_pol); + } + if (!map_file.empty()) { std::ofstream fout; fout.open(map_file, std::ios::out | std::ios::trunc); @@ -166,7 +186,7 @@ struct SyntProperties : public Pass { log("This creates synthesizable properties for selected module.\n"); log("\n"); log("\n"); - log(" -name \n"); + log(" -name \n"); log("\n"); log("Name output port for assertions (default: assertions).\n"); log("\n"); @@ -182,10 +202,16 @@ struct SyntProperties : public Pass { log("property is violated, instead of generating individual output bits.\n"); log("\n"); log("\n"); - log(" -latch \n"); + log(" -reset \n"); log("\n"); - log("Latch a high state on the generated outputs until an asynchronous top-level\n"); - log("reset input is activated.\n"); + log("Name of top-level reset input. Latch a high state on the generated outputs\n"); + log("until an asynchronous top-level reset input is activated.\n"); + log("\n"); + log("\n"); + log(" -resetn \n"); + log("\n"); + log("Name of top-level reset input (inverse polarity). Latch a high state on the\n"); + log("generated outputs until an asynchronous top-level reset input is activated.\n"); log("\n"); log("\n"); } @@ -205,7 +231,14 @@ struct SyntProperties : public Pass { worker.map_file = args[++argidx]; continue; } - if (args[argidx] == "-latch" && argidx+2 < args.size()) { + if (args[argidx] == "-reset" && argidx+1 < args.size()) { + worker.reset_name = RTLIL::escape_id(args[++argidx]); + worker.reset_pol = true; + continue; + } + if (args[argidx] == "-resetn" && argidx+1 < args.size()) { + worker.reset_name = RTLIL::escape_id(args[++argidx]); + worker.reset_pol = false; continue; } if (args[argidx] == "-or_outputs") { @@ -222,6 +255,10 @@ struct SyntProperties : public Pass { if (top == nullptr) log_cmd_error("Can't find top module in current design!\n"); + auto *reset = top->wire(worker.reset_name); + if (!worker.reset_name.empty() && reset == nullptr) + log_cmd_error("Can't find reset line in current design!\n"); + worker.module = top; worker.run(); } From 550a5b7b6b903be2691eb2e188e715ca121db2fb Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 5 Jan 2023 16:04:07 +0100 Subject: [PATCH 006/303] Update license --- passes/sat/synthprop.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/passes/sat/synthprop.cc b/passes/sat/synthprop.cc index 5dd1fefdf45..25416b6c4c3 100644 --- a/passes/sat/synthprop.cc +++ b/passes/sat/synthprop.cc @@ -1,7 +1,9 @@ /* * yosys -- Yosys Open SYnthesis Suite * - * Copyright (C) 2022 Miodrag Milanovic + * Copyright (C) 2023 Miodrag Milanovic + * Copyright (C) 2023 + * National Technology & Engineering Solutions of Sandia, LLC (NTESS) * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above From b562b54c14349bcc8284c3210a234e6eb696f01d Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 15 Feb 2023 12:53:46 +0100 Subject: [PATCH 007/303] dfflegalize: allow setting mince and minsrst args from scratchpad --- passes/techmap/dfflegalize.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/dfflegalize.cc b/passes/techmap/dfflegalize.cc index c6c3a58c588..64f07b708c6 100644 --- a/passes/techmap/dfflegalize.cc +++ b/passes/techmap/dfflegalize.cc @@ -1021,8 +1021,8 @@ struct DffLegalizePass : public Pass { supported_cells_neg[i][j] = 0; supported_cells[i] = 0; } - mince = 0; - minsrst = 0; + mince = design->scratchpad_get_int("dfflegalize.mince", 0); + minsrst = design->scratchpad_get_int("dfflegalize.minsrst", 0); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) From 2c7ba0e75225dff710fb7c5e87dd43bf881dcdd2 Mon Sep 17 00:00:00 2001 From: Patrick Urban Date: Wed, 15 Feb 2023 17:29:01 +0100 Subject: [PATCH 008/303] gatemate: Enable register initialization --- techlibs/gatemate/cells_sim.v | 12 +++++++----- techlibs/gatemate/reg_map.v | 10 ++++++++-- techlibs/gatemate/synth_gatemate.cc | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v index 7ed6d83ff49..12e01d2dfe9 100644 --- a/techlibs/gatemate/cells_sim.v +++ b/techlibs/gatemate/cells_sim.v @@ -242,7 +242,8 @@ module CC_DFF #( parameter [0:0] CLK_INV = 1'b0, parameter [0:0] EN_INV = 1'b0, parameter [0:0] SR_INV = 1'b0, - parameter [0:0] SR_VAL = 1'b0 + parameter [0:0] SR_VAL = 1'b0, + parameter [0:0] INIT = 1'bx )( input D, (* clkbuf_sink *) @@ -256,7 +257,7 @@ module CC_DFF #( assign en = (EN_INV) ? ~EN : EN; assign sr = (SR_INV) ? ~SR : SR; - initial Q = 1'bX; + initial Q = INIT; always @(posedge clk or posedge sr) begin @@ -272,9 +273,10 @@ endmodule module CC_DLT #( - parameter [0:0] G_INV = 1'b0, + parameter [0:0] G_INV = 1'b0, parameter [0:0] SR_INV = 1'b0, - parameter [0:0] SR_VAL = 1'b0 + parameter [0:0] SR_VAL = 1'b0, + parameter [0:0] INIT = 1'bx )( input D, input G, @@ -285,7 +287,7 @@ module CC_DLT #( assign en = (G_INV) ? ~G : G; assign sr = (SR_INV) ? ~SR : SR; - initial Q = 1'bX; + initial Q = INIT; always @(*) begin diff --git a/techlibs/gatemate/reg_map.v b/techlibs/gatemate/reg_map.v index 6a2c7fb915a..6ec170a9d91 100644 --- a/techlibs/gatemate/reg_map.v +++ b/techlibs/gatemate/reg_map.v @@ -21,25 +21,31 @@ module \$_DFFE_xxxx_ (input D, C, R, E, output Q); parameter _TECHMAP_CELLTYPE_ = ""; + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; CC_DFF #( .CLK_INV(_TECHMAP_CELLTYPE_[39:32] == "N"), .EN_INV(_TECHMAP_CELLTYPE_[15:8] == "N"), .SR_INV(_TECHMAP_CELLTYPE_[31:24] == "N"), - .SR_VAL(_TECHMAP_CELLTYPE_[23:16] == "1") + .SR_VAL(_TECHMAP_CELLTYPE_[23:16] == "1"), + .INIT(_TECHMAP_WIREINIT_Q_) ) _TECHMAP_REPLACE_ (.D(D), .EN(E), .CLK(C), .SR(R), .Q(Q)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule (* techmap_celltype = "$_DLATCH_[NP][NP][01]_" *) module \$_DLATCH_xxx_ (input E, R, D, output Q); parameter _TECHMAP_CELLTYPE_ = ""; + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; CC_DLT #( .G_INV(_TECHMAP_CELLTYPE_[31:24] == "N"), .SR_INV(_TECHMAP_CELLTYPE_[23:16] == "N"), - .SR_VAL(_TECHMAP_CELLTYPE_[15:8] == "1") + .SR_VAL(_TECHMAP_CELLTYPE_[15:8] == "1"), + .INIT(_TECHMAP_WIREINIT_Q_) ) _TECHMAP_REPLACE_ (.D(D), .G(E), .SR(R), .Q(Q)); + wire _TECHMAP_REMOVEINIT_Q_ = 1; endmodule diff --git a/techlibs/gatemate/synth_gatemate.cc b/techlibs/gatemate/synth_gatemate.cc index dd4fde64368..1d46d79295c 100644 --- a/techlibs/gatemate/synth_gatemate.cc +++ b/techlibs/gatemate/synth_gatemate.cc @@ -283,7 +283,7 @@ struct SynthGateMatePass : public ScriptPass if (check_label("map_regs")) { run("opt_clean"); - run("dfflegalize -cell $_DFFE_????_ x -cell $_DLATCH_???_ x"); + run("dfflegalize -cell $_DFFE_????_ 01 -cell $_DLATCH_???_ 01"); run("techmap -map +/gatemate/reg_map.v"); run("opt_expr -mux_undef"); run("simplemap"); From 1cfedc90ce7b2bd63d75883a4e8c36fd44f0e4e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 17 Feb 2023 00:18:18 +0000 Subject: [PATCH 009/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0f3e1eba090..2a836aef57d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+34 +YOSYS_VER := 0.26+36 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From fc56978703b5e942ba728970e13e065100a34cd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20Kesz=C3=B6cze?= Date: Fri, 17 Feb 2023 17:54:41 +0100 Subject: [PATCH 010/303] Check DREG attribute The DSP48E1 implementation checked the wrong attribute (i.e. CREG) to initialize the D input register. This PR fixes 3680 --- techlibs/xilinx/cells_sim.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index ee5a89e2272..e6e15b16ead 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -3614,7 +3614,7 @@ module DSP48E1 ( if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= C; end else always @* Cr <= C; - if (CREG == 1) initial Dr = 25'b0; + if (DREG == 1) initial Dr = 25'b0; if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end else always @* Dr <= D; From f0116330bce4e787dcbbf81c6e901a44715589a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 18 Feb 2023 00:17:33 +0000 Subject: [PATCH 011/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2a836aef57d..396aeb9275c 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+36 +YOSYS_VER := 0.26+39 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 79043cb849e01b494e1ab432dc52f5f99d5ff4af Mon Sep 17 00:00:00 2001 From: Dag Lem Date: Sun, 19 Feb 2023 23:25:08 +0100 Subject: [PATCH 012/303] Out of bounds checking for struct/union members Currently, only constant indices are checked. --- frontends/ast/genrtlil.cc | 23 ++++++++++++++++++----- tests/gen-tests-makefile.sh | 2 +- tests/svtypes/struct_array.sv | 3 +++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 1016ef636c1..9f458530d2d 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1444,6 +1444,19 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_error(filename, location.first_line, "Single range expected.\n"); int source_width = id2ast->range_left - id2ast->range_right + 1; int source_offset = id2ast->range_right; + int item_left = source_width - 1; + int item_right = 0; + + // Check for item in struct/union. + AST::AstNode *item_node; + if (attributes.count(ID::wiretype) && (item_node = attributes[ID::wiretype]) && + (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT || item_node->type == AST_UNION)) + { + // Clamp chunk to range of item within struct/union. + item_left = item_node->range_left; + item_right = item_node->range_right; + } + if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); @@ -1481,7 +1494,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) chunk.offset = children[0]->range_right - source_offset; if (id2ast->range_swapped) chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width); - if (chunk.offset >= source_width || chunk.offset + chunk.width < 0) { + if (chunk.offset > item_left || chunk.offset + chunk.width < item_right) { if (chunk.width == 1) log_file_warning(filename, location.first_line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", str.c_str()); @@ -1490,12 +1503,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width); chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width); } else { - if (chunk.width + chunk.offset > source_width) { - add_undef_bits_msb = (chunk.width + chunk.offset) - source_width; + if (chunk.offset + chunk.width - 1 > item_left) { + add_undef_bits_msb = (chunk.offset + chunk.width - 1) - item_left; chunk.width -= add_undef_bits_msb; } - if (chunk.offset < 0) { - add_undef_bits_lsb = -chunk.offset; + if (chunk.offset < item_right) { + add_undef_bits_lsb = item_right - chunk.offset; chunk.width -= add_undef_bits_lsb; chunk.offset += add_undef_bits_lsb; } diff --git a/tests/gen-tests-makefile.sh b/tests/gen-tests-makefile.sh index cde9ab1b941..3df36a963b1 100755 --- a/tests/gen-tests-makefile.sh +++ b/tests/gen-tests-makefile.sh @@ -75,7 +75,7 @@ generate_tests() { if [[ $do_sv = true ]]; then for x in *.sv; do if [ ! -f "${x%.sv}.ys" ]; then - generate_ys_test "$x" "-p \"prep -top top; sat -verify -prove-asserts\" $yosys_args" + generate_ys_test "$x" "-p \"prep -top top; sat -enable_undef -verify -prove-asserts\" $yosys_args" fi; done fi; diff --git a/tests/svtypes/struct_array.sv b/tests/svtypes/struct_array.sv index a0b84640de6..b87f936aae6 100644 --- a/tests/svtypes/struct_array.sv +++ b/tests/svtypes/struct_array.sv @@ -18,6 +18,9 @@ module top; end always_comb assert(s==64'h4200_0012_3400_FFFC); + always_comb assert(s.b[23:16]===8'hxx); + always_comb assert(s.b[19:12]===8'hxf); + always_comb assert(s.a[0][3:-4]===8'h0x); struct packed { bit [7:0] [7:0] a; // 8 element packed array of bytes From ac5fa9a83883ede45fac38c7288f8ade1887ade5 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 10 May 2022 10:31:42 +1200 Subject: [PATCH 013/303] Addings tests for #1836 and #3205 --- tests/arch/ecp5/bug1836.mem | 32 +++++++++++++++++++++ tests/arch/ecp5/bug1836.ys | 31 ++++++++++++++++++++ tests/arch/ecp5/bug3205.ys | 57 +++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 tests/arch/ecp5/bug1836.mem create mode 100644 tests/arch/ecp5/bug1836.ys create mode 100644 tests/arch/ecp5/bug3205.ys diff --git a/tests/arch/ecp5/bug1836.mem b/tests/arch/ecp5/bug1836.mem new file mode 100644 index 00000000000..1e904d87cf6 --- /dev/null +++ b/tests/arch/ecp5/bug1836.mem @@ -0,0 +1,32 @@ +0x8000,0x8324,0x8647,0x896a,0x8c8b,0x8fab,0x92c7,0x95e1, +0x98f8,0x9c0b,0x9f19,0xa223,0xa527,0xa826,0xab1f,0xae10, +0xb0fb,0xb3de,0xb6b9,0xb98c,0xbc56,0xbf17,0xc1cd,0xc47a, +0xc71c,0xc9b3,0xcc3f,0xcebf,0xd133,0xd39a,0xd5f5,0xd842, +0xda82,0xdcb3,0xded7,0xe0eb,0xe2f1,0xe4e8,0xe6cf,0xe8a6, +0xea6d,0xec23,0xedc9,0xef5e,0xf0e2,0xf254,0xf3b5,0xf504, +0xf641,0xf76b,0xf884,0xf989,0xfa7c,0xfb5c,0xfc29,0xfce3, +0xfd89,0xfe1d,0xfe9c,0xff09,0xff61,0xffa6,0xffd8,0xfff5, +0xffff,0xfff5,0xffd8,0xffa6,0xff61,0xff09,0xfe9c,0xfe1d, +0xfd89,0xfce3,0xfc29,0xfb5c,0xfa7c,0xf989,0xf884,0xf76b, +0xf641,0xf504,0xf3b5,0xf254,0xf0e2,0xef5e,0xedc9,0xec23, +0xea6d,0xe8a6,0xe6cf,0xe4e8,0xe2f1,0xe0eb,0xded7,0xdcb3, +0xda82,0xd842,0xd5f5,0xd39a,0xd133,0xcebf,0xcc3f,0xc9b3, +0xc71c,0xc47a,0xc1cd,0xbf17,0xbc56,0xb98c,0xb6b9,0xb3de, +0xb0fb,0xae10,0xab1f,0xa826,0xa527,0xa223,0x9f19,0x9c0b, +0x98f8,0x95e1,0x92c7,0x8fab,0x8c8b,0x896a,0x8647,0x8324, +0x8000,0x7cdb,0x79b8,0x7695,0x7374,0x7054,0x6d38,0x6a1e, +0x6707,0x63f4,0x60e6,0x5ddc,0x5ad8,0x57d9,0x54e0,0x51ef, +0x4f04,0x4c21,0x4946,0x4673,0x43a9,0x40e8,0x3e32,0x3b85, +0x38e3,0x364c,0x33c0,0x3140,0x2ecc,0x2c65,0x2a0a,0x27bd, +0x257d,0x234c,0x2128,0x1f14,0x1d0e,0x1b17,0x1930,0x1759, +0x1592,0x13dc,0x1236,0x10a1,0xf1d,0xdab,0xc4a,0xafb, +0x9be,0x894,0x77b,0x676,0x583,0x4a3,0x3d6,0x31c, +0x276,0x1e2,0x163,0xf6,0x9e,0x59,0x27,0xa, +0x0,0xa,0x27,0x59,0x9e,0xf6,0x163,0x1e2, +0x276,0x31c,0x3d6,0x4a3,0x583,0x676,0x77b,0x894, +0x9be,0xafb,0xc4a,0xdab,0xf1d,0x10a1,0x1236,0x13dc, +0x1592,0x1759,0x1930,0x1b17,0x1d0e,0x1f14,0x2128,0x234c, +0x257d,0x27bd,0x2a0a,0x2c65,0x2ecc,0x3140,0x33c0,0x364c, +0x38e3,0x3b85,0x3e32,0x40e8,0x43a9,0x4673,0x4946,0x4c21, +0x4f04,0x51ef,0x54e0,0x57d9,0x5ad8,0x5ddc,0x60e6,0x63f4, +0x6707,0x6a1e,0x6d38,0x7054,0x7374,0x7695,0x79b8,0x7cdb, \ No newline at end of file diff --git a/tests/arch/ecp5/bug1836.ys b/tests/arch/ecp5/bug1836.ys new file mode 100644 index 00000000000..d8533441e1c --- /dev/null +++ b/tests/arch/ecp5/bug1836.ys @@ -0,0 +1,31 @@ +read_verilog < Date: Thu, 7 Jul 2022 10:22:14 +1200 Subject: [PATCH 014/303] Asymmetric port ram tests with Xilinx Uses verilog code from User Guide 901 (2021.1) --- tests/arch/xilinx/asym_ram_sdp.ys | 50 ++++++++++++++ tests/arch/xilinx/asym_ram_sdp_read_wider.v | 72 ++++++++++++++++++++ tests/arch/xilinx/asym_ram_sdp_write_wider.v | 71 +++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 tests/arch/xilinx/asym_ram_sdp.ys create mode 100644 tests/arch/xilinx/asym_ram_sdp_read_wider.v create mode 100644 tests/arch/xilinx/asym_ram_sdp_write_wider.v diff --git a/tests/arch/xilinx/asym_ram_sdp.ys b/tests/arch/xilinx/asym_ram_sdp.ys new file mode 100644 index 00000000000..37f6f314d39 --- /dev/null +++ b/tests/arch/xilinx/asym_ram_sdp.ys @@ -0,0 +1,50 @@ +# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RAMB18E1 + +# w4b | r16b +design -reset +read_verilog asym_ram_sdp_read_wider.v +synth_xilinx -top asym_ram_sdp_read_wider -noiopad +select -assert-count 1 t:RAMB18E1 + +# w8b | r16b +design -reset +read_verilog asym_ram_sdp_read_wider.v +chparam -set WIDTHA 8 -set SIZEA 512 -set ADDRWIDTHA 9 asym_ram_sdp_read_wider +synth_xilinx -top asym_ram_sdp_read_wider -noiopad +select -assert-count 1 t:RAMB18E1 + +# w4b | r32b +design -reset +read_verilog asym_ram_sdp_read_wider.v +chparam -set WIDTHB 32 -set SIZEB 128 -set ADDRWIDTHB 7 asym_ram_sdp_read_wider +synth_xilinx -top asym_ram_sdp_read_wider -noiopad +select -assert-count 1 t:RAMB18E1 + +# w16b | r4b +design -reset +read_verilog asym_ram_sdp_write_wider.v +synth_xilinx -top asym_ram_sdp_write_wider -noiopad +select -assert-count 1 t:RAMB18E1 + +# w16b | r8b +design -reset +read_verilog asym_ram_sdp_write_wider.v +chparam -set WIDTHB 8 -set SIZEB 512 -set ADDRWIDTHB 9 asym_ram_sdp_read_wider +synth_xilinx -top asym_ram_sdp_write_wider -noiopad +select -assert-count 1 t:RAMB18E1 + +# w32b | r4b +design -reset +read_verilog asym_ram_sdp_write_wider.v +chparam -set WIDTHA 32 -set SIZEA 128 -set ADDRWIDTHA 7 asym_ram_sdp_read_wider +synth_xilinx -top asym_ram_sdp_write_wider -noiopad +select -assert-count 1 t:RAMB18E1 + +# w4b | r24b +design -reset +read_verilog asym_ram_sdp_read_wider.v +chparam -set SIZEA 768 +chparam -set WIDTHB 24 -set SIZEB 128 -set ADDRWIDTHB 7 asym_ram_sdp_read_wider +synth_xilinx -top asym_ram_sdp_read_wider -noiopad +select -assert-count 1 t:RAMB18E1 + diff --git a/tests/arch/xilinx/asym_ram_sdp_read_wider.v b/tests/arch/xilinx/asym_ram_sdp_read_wider.v new file mode 100644 index 00000000000..8743209e313 --- /dev/null +++ b/tests/arch/xilinx/asym_ram_sdp_read_wider.v @@ -0,0 +1,72 @@ +// Asymmetric port RAM +// Read Wider than Write. Read Statement in loop +//asym_ram_sdp_read_wider.v +module asym_ram_sdp_read_wider (clkA, clkB, enaA, weA, enaB, addrA, addrB, diA, doB); + parameter WIDTHA = 4; + parameter SIZEA = 1024; + parameter ADDRWIDTHA = 10; + + parameter WIDTHB = 16; + parameter SIZEB = 256; + parameter ADDRWIDTHB = 8; + + input clkA; + input clkB; + input weA; + input enaA, enaB; + input [ADDRWIDTHA-1:0] addrA; + input [ADDRWIDTHB-1:0] addrB; + input [WIDTHA-1:0] diA; + output [WIDTHB-1:0] doB; + + `define max(a,b) {(a) > (b) ? (a) : (b)} + `define min(a,b) {(a) < (b) ? (a) : (b)} + + function integer log2; + input integer value; + reg [31:0] shifted; + integer res; + begin + if (value < 2) + log2 = value; + else + begin + shifted = value-1; + for (res=0; shifted>0; res=res+1) + shifted = shifted>>1; + log2 = res; + end + end + endfunction + + localparam maxSIZE = `max(SIZEA, SIZEB); + localparam maxWIDTH = `max(WIDTHA, WIDTHB); + localparam minWIDTH = `min(WIDTHA, WIDTHB); + + localparam RATIO = maxWIDTH / minWIDTH; + localparam log2RATIO = log2(RATIO); + + reg [minWIDTH-1:0] RAM [0:maxSIZE-1]; + reg [WIDTHB-1:0] readB; + + always @(posedge clkA) + begin + if (enaA) begin + if (weA) + RAM[addrA] <= diA; + end + end + + always @(posedge clkB) + begin : ramread + integer i; + reg [log2RATIO-1:0] lsbaddr; + if (enaB) begin + for (i = 0; i < RATIO; i = i+1) begin + lsbaddr = i; + readB[(i+1)*minWIDTH-1 -: minWIDTH] <= RAM[{addrB, lsbaddr}]; + end + end + end + assign doB = readB; +endmodule \ No newline at end of file diff --git a/tests/arch/xilinx/asym_ram_sdp_write_wider.v b/tests/arch/xilinx/asym_ram_sdp_write_wider.v new file mode 100644 index 00000000000..cd61a3ccc75 --- /dev/null +++ b/tests/arch/xilinx/asym_ram_sdp_write_wider.v @@ -0,0 +1,71 @@ +// Asymmetric port RAM +// Write wider than Read. Write Statement in a loop. +// asym_ram_sdp_write_wider.v +module asym_ram_sdp_write_wider (clkA, clkB, weA, enaA, enaB, addrA, addrB, diA, doB); + parameter WIDTHB = 4; + parameter SIZEB = 1024; + parameter ADDRWIDTHB = 10; + + parameter WIDTHA = 16; + parameter SIZEA = 256; + parameter ADDRWIDTHA = 8; + + input clkA; + input clkB; + input weA; + input enaA, enaB; + input [ADDRWIDTHA-1:0] addrA; + input [ADDRWIDTHB-1:0] addrB; + input [WIDTHA-1:0] diA; + output [WIDTHB-1:0] doB; + + `define max(a,b) {(a) > (b) ? (a) : (b)} + `define min(a,b) {(a) < (b) ? (a) : (b)} + + function integer log2; + input integer value; + reg [31:0] shifted; + integer res; + begin + if (value < 2) + log2 = value; + else + begin + shifted = value-1; + for (res=0; shifted>0; res=res+1) + shifted = shifted>>1; + log2 = res; + end + end + endfunction + + localparam maxSIZE = `max(SIZEA, SIZEB); + localparam maxWIDTH = `max(WIDTHA, WIDTHB); + localparam minWIDTH = `min(WIDTHA, WIDTHB); + + localparam RATIO = maxWIDTH / minWIDTH; + localparam log2RATIO = log2(RATIO); + + reg [minWIDTH-1:0] RAM [0:maxSIZE-1]; + reg [WIDTHB-1:0] readB; + + always @(posedge clkB) begin + if (enaB) begin + readB <= RAM[addrB]; + end + end + assign doB = readB; + + always @(posedge clkA) + begin : ramwrite + integer i; + reg [log2RATIO-1:0] lsbaddr; + for (i=0; i< RATIO; i= i+ 1) begin : write1 + lsbaddr = i; + if (enaA) begin + if (weA) + RAM[{addrA, lsbaddr}] <= diA[(i+1)*minWIDTH-1 -: minWIDTH]; + end + end + end +endmodule \ No newline at end of file From de2f140c090742ec8ccded4cfacc2dc6bac2a562 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Tue, 5 Jul 2022 11:18:43 +1200 Subject: [PATCH 015/303] Testing TDP synth mapping New common sync_ram_tdp. Used in ecp5 and gatemate mem*.ys. --- tests/arch/common/blockram.v | 31 +++++++++++++++++++++++++++++++ tests/arch/ecp5/memories.ys | 10 ++++++++++ tests/arch/gatemate/memory.ys | 8 ++++++++ 3 files changed, 49 insertions(+) diff --git a/tests/arch/common/blockram.v b/tests/arch/common/blockram.v index 5ed0736d01b..6b557fdca3d 100644 --- a/tests/arch/common/blockram.v +++ b/tests/arch/common/blockram.v @@ -45,3 +45,34 @@ module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) endmodule // sync_ram_sdp + +`default_nettype none +module sync_ram_tdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) + (input wire clk_a, clk_b, + input wire write_enable_a, write_enable_b, + input wire read_enable_a, read_enable_b, + input wire [DATA_WIDTH-1:0] write_data_a, write_data_b, + input wire [ADDRESS_WIDTH-1:0] addr_a, addr_b, + output reg [DATA_WIDTH-1:0] read_data_a, read_data_b); + + localparam WORD = (DATA_WIDTH-1); + localparam DEPTH = (2**ADDRESS_WIDTH-1); + + reg [WORD:0] mem [0:DEPTH]; + + always @(posedge clk_a) begin + if (write_enable_a) + mem[addr_a] <= write_data_a; + else + read_data_a <= mem[addr_a]; + end + + always @(posedge clk_b) begin + if (write_enable_b) + mem[addr_b] <= write_data_b; + else + read_data_b <= mem[addr_b]; + end + +endmodule // sync_ram_tdp + diff --git a/tests/arch/ecp5/memories.ys b/tests/arch/ecp5/memories.ys index 5cddcb9525f..f075182c8b5 100644 --- a/tests/arch/ecp5/memories.ys +++ b/tests/arch/ecp5/memories.ys @@ -260,3 +260,13 @@ setattr -set logic_block 1 m:memory synth_ecp5 -top sync_rom; cd sync_rom select -assert-count 0 t:DP16KD # requested LUTROM explicitly select -assert-min 9 t:LUT4 + +# ============================== TDP RAM ============================== +# RAM bits <= 18K; Data width <= 18x2; Address width <= 9: -> DP16KD + +design -reset; read_verilog -defer ../common/blockram.v +chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 18 sync_ram_tdp +hierarchy -top sync_ram_tdp +synth_ecp5 -top sync_ram_tdp; cd sync_ram_tdp +select -assert-count 1 t:DP16KD +select -assert-none t:LUT4 diff --git a/tests/arch/gatemate/memory.ys b/tests/arch/gatemate/memory.ys index e919920f893..c4bf11cd357 100644 --- a/tests/arch/gatemate/memory.ys +++ b/tests/arch/gatemate/memory.ys @@ -6,6 +6,14 @@ cd sync_ram_sdp select -assert-count 1 t:CC_BUFG select -assert-count 1 t:CC_BRAM_20K +# 512 x 20 bit x 2 -> CC_BRAM_20K TDP RAM +design -reset +read_verilog ../common/blockram.v +chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 20 sync_ram_tdp +synth_gatemate -top sync_ram_tdp -noiopad +select -assert-count 2 t:CC_BUFG +select -assert-count 1 t:CC_BRAM_20K + # 512 x 80 bit -> CC_BRAM_40K SDP RAM design -reset read_verilog ../common/blockram.v From af1b9c9e070dd5873871c73c5762fbefd345a8c9 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 7 Jul 2022 10:27:54 +1200 Subject: [PATCH 016/303] Tests for ram_style = "huge" iCE40 SPRAM and Xilinx URAM --- tests/arch/ice40/spram.v | 22 +++++ tests/arch/ice40/spram.ys | 15 ++++ tests/arch/xilinx/priority_memory.v | 122 +++++++++++++++++++++++++++ tests/arch/xilinx/priority_memory.ys | 60 +++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 tests/arch/ice40/spram.v create mode 100644 tests/arch/ice40/spram.ys create mode 100644 tests/arch/xilinx/priority_memory.v create mode 100644 tests/arch/xilinx/priority_memory.ys diff --git a/tests/arch/ice40/spram.v b/tests/arch/ice40/spram.v new file mode 100644 index 00000000000..4e1aef2c601 --- /dev/null +++ b/tests/arch/ice40/spram.v @@ -0,0 +1,22 @@ +module top (clk, write_enable, read_enable, write_data, addr, read_data); +parameter DATA_WIDTH = 8; +parameter ADDR_WIDTH = 8; +parameter SKIP_RDEN = 1; + +input clk; +input write_enable, read_enable; +input [DATA_WIDTH - 1 : 0] write_data; +input [ADDR_WIDTH - 1 : 0] addr; +output [DATA_WIDTH - 1 : 0] read_data; + +(* ram_style = "huge" *) +reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + +always @(posedge clk) begin + if (write_enable) + mem[addr] <= write_data; + else if (SKIP_RDEN || read_enable) + read_data <= mem[addr]; +end + +endmodule diff --git a/tests/arch/ice40/spram.ys b/tests/arch/ice40/spram.ys new file mode 100644 index 00000000000..709c218621e --- /dev/null +++ b/tests/arch/ice40/spram.ys @@ -0,0 +1,15 @@ +read_verilog spram.v +hierarchy -top top +synth_ice40 +select -assert-count 1 t:SB_SPRAM256KA +select -assert-none t:SB_SPRAM256KA %% t:* %D + +# Testing with pattern as described in pattern document +design -reset +read_verilog spram.v +chparam -set SKIP_RDEN 0 +hierarchy -top top +synth_ice40 +select -assert-count 1 t:SB_SPRAM256KA +# Below fails due to extra SB_LUT4 +# select -assert-none t:SB_SPRAM256KA %% t:* %D diff --git a/tests/arch/xilinx/priority_memory.v b/tests/arch/xilinx/priority_memory.v new file mode 100644 index 00000000000..fc943e20951 --- /dev/null +++ b/tests/arch/xilinx/priority_memory.v @@ -0,0 +1,122 @@ +module priority_memory ( + clk, wren_a, rden_a, addr_a, wdata_a, rdata_a, + wren_b, rden_b, addr_b, wdata_b, rdata_b + ); + + parameter ABITS = 12; + parameter WIDTH = 72; + + input clk; + input wren_a, rden_a, wren_b, rden_b; + input [ABITS-1:0] addr_a, addr_b; + input [WIDTH-1:0] wdata_a, wdata_b; + output reg [WIDTH-1:0] rdata_a, rdata_b; + + `ifdef USE_HUGE + (* ram_style = "huge" *) + `endif + reg [WIDTH-1:0] mem [0:2**ABITS-1]; + + integer i; + initial begin + rdata_a <= 'h0; + rdata_b <= 'h0; + end + + `ifndef FLIP_PORTS + always @(posedge clk) begin + // A port + if (wren_a) + mem[addr_a] <= wdata_a; + else if (rden_a) + rdata_a <= mem[addr_a]; + + // B port + if (wren_b) + mem[addr_b] <= wdata_b; + else if (rden_b) + if (wren_a && addr_a == addr_b) + rdata_b <= wdata_a; + else + rdata_b <= mem[addr_b]; + end + `else // FLIP PORTS + always @(posedge clk) begin + // A port + if (wren_b) + mem[addr_b] <= wdata_b; + else if (rden_b) + rdata_b <= mem[addr_b]; + + // B port + if (wren_a) + mem[addr_a] <= wdata_a; + else if (rden_a) + if (wren_b && addr_a == addr_b) + rdata_a <= wdata_b; + else + rdata_a <= mem[addr_a]; + end + `endif +endmodule + +module sp_write_first (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a); + + parameter ABITS = 12; + parameter WIDTH = 72; + + input clk; + input wren_a, rden_a; + input [ABITS-1:0] addr_a; + input [WIDTH-1:0] wdata_a; + output reg [WIDTH-1:0] rdata_a; + + (* ram_style = "huge" *) + reg [WIDTH-1:0] mem [0:2**ABITS-1]; + + integer i; + initial begin + rdata_a <= 'h0; + end + + + always @(posedge clk) begin + // A port + if (wren_a) + mem[addr_a] <= wdata_a; + if (rden_a) + if (wren_a) + rdata_a <= wdata_a; + else + rdata_a <= mem[addr_a]; + end +endmodule + +module sp_read_first (clk, wren_a, rden_a, addr_a, wdata_a, rdata_a); + + parameter ABITS = 12; + parameter WIDTH = 72; + + input clk; + input wren_a, rden_a; + input [ABITS-1:0] addr_a; + input [WIDTH-1:0] wdata_a; + output reg [WIDTH-1:0] rdata_a; + + (* ram_style = "huge" *) + reg [WIDTH-1:0] mem [0:2**ABITS-1]; + + integer i; + initial begin + rdata_a <= 'h0; + end + + + always @(posedge clk) begin + // A port + if (wren_a) + mem[addr_a] <= wdata_a; + if (rden_a) + rdata_a <= mem[addr_a]; + end +endmodule diff --git a/tests/arch/xilinx/priority_memory.ys b/tests/arch/xilinx/priority_memory.ys new file mode 100644 index 00000000000..d0b2a16adc9 --- /dev/null +++ b/tests/arch/xilinx/priority_memory.ys @@ -0,0 +1,60 @@ + +# no uram by default +design -reset +read_verilog priority_memory.v +synth_xilinx -family xcup -top priority_memory +select -assert-none t:URAM288 + +# uram parameter +design -reset +read -define USE_HUGE +read_verilog priority_memory.v +synth_xilinx -family xcup -top priority_memory -noiopad +select -assert-count 1 t:URAM288 + +# uram option +design -reset +read_verilog priority_memory.v +synth_xilinx -family xcup -top priority_memory -noiopad -uram +# check for URAM block +select -assert-count 1 t:URAM288 +# check port A in code maps to port A in hardware: +# %co:+[DOUT_A] selects everything connected to a URAM288.DOUT_A port +# w:rdata_a selects the wire rdata_a +# %i finds the intersection of the two above selections +# if the result is 1 then the wire rdata_a is connected to Port A correctly +select -assert-count 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i +# we expect no more than 2 LUT2s to control the hardware priority +# if there are extra LUTs, then it is likely emulating logic it shouldn't +# ignore anything using blif, since that doesn't seem to support priority logic +# and is indicative of using verific/tabby +select -assert-max 2 t:LUT* n:*blif* %d + +# reverse priority +design -reset +read -define FLIP_PORTS +read_verilog priority_memory.v +synth_xilinx -family xcup -top priority_memory -noiopad -uram +# test priority is mapped correctly, rdata_a should now be connected to Port B +# see above for details +select -assert-count 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i + +# sp write first +design -reset +read_verilog priority_memory.v +synth_xilinx -family xcup -top sp_write_first -noiopad +select -assert-count 1 t:URAM288 +# write first connects rdata_a to port B +# similar to above, but also tests that rdata_a *isn't* connected to port A +select -assert-none 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i +select -assert-count 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i + +# sp read first +design -reset +read_verilog priority_memory.v +synth_xilinx -family xcup -top sp_read_first -noiopad +select -assert-count 1 t:URAM288 +# read first connects rdata_a to port A +# see above for details +select -assert-count 1 t:URAM288 %co:+[DOUT_A] w:rdata_a %i +select -assert-none 1 t:URAM288 %co:+[DOUT_B] w:rdata_a %i From 7f033d3c1f4604d303da237fbc7a38ee503416ad Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Thu, 7 Jul 2022 11:10:33 +1200 Subject: [PATCH 017/303] More tests in memlib/generate.py Covers most of the todo list, at least functionally. Some minor issues with not always using hardware features. --- tests/memlib/generate.py | 677 +++++++++++++++++++++++++- tests/memlib/memlib_9b1B.txt | 31 ++ tests/memlib/memlib_9b1B.v | 68 +++ tests/memlib/memlib_block_sp_full.txt | 61 +++ tests/memlib/memlib_block_sp_full.v | 82 ++++ tests/memlib/memlib_clock_sdp.txt | 76 +++ tests/memlib/memlib_clock_sdp.v | 36 ++ tests/memlib/memlib_lut.txt | 18 +- tests/memlib/memlib_lut.v | 9 +- tests/memlib/memlib_multilut.txt | 19 + tests/memlib/memlib_multilut.v | 45 ++ tests/memlib/memlib_wren.txt | 37 ++ tests/memlib/memlib_wren.v | 33 ++ 13 files changed, 1180 insertions(+), 12 deletions(-) create mode 100644 tests/memlib/memlib_9b1B.txt create mode 100644 tests/memlib/memlib_9b1B.v create mode 100644 tests/memlib/memlib_block_sp_full.txt create mode 100644 tests/memlib/memlib_block_sp_full.v create mode 100644 tests/memlib/memlib_clock_sdp.txt create mode 100644 tests/memlib/memlib_clock_sdp.v create mode 100644 tests/memlib/memlib_multilut.txt create mode 100644 tests/memlib/memlib_multilut.v create mode 100644 tests/memlib/memlib_wren.txt create mode 100644 tests/memlib/memlib_wren.v diff --git a/tests/memlib/generate.py b/tests/memlib/generate.py index 3414865841b..f40210501db 100644 --- a/tests/memlib/generate.py +++ b/tests/memlib/generate.py @@ -1,13 +1,6 @@ # TODO: -# - memory initialization -# - clock polarity combinations -# - CE/srst/rdwr/be interactions # - priority logic -# - byte enables, wrbe_separate -# - duplication for read ports -# - abits/dbits determination -# - mixed width # - swizzles for weird width progressions @@ -22,6 +15,7 @@ def __init__(self, name, src, libs, defs, cells): TESTS = [] ### basic sanity tests +# Asynchronous-read RAM ASYNC = """ module top(clk, ra, wa, rd, wd, we); @@ -56,6 +50,7 @@ def __init__(self, name, src, libs, defs, cells): Test("async_small_block", ASYNC_SMALL, ["block_tdp"], [], {"RAM_BLOCK_TDP": 0}), ] +# Synchronous SDP read first SYNC = """ module top(clk, ra, wa, rd, wd, we); @@ -95,6 +90,261 @@ def __init__(self, name, src, libs, defs, cells): Test("sync_small_block_attr", SYNC_SMALL_BLOCK, ["lut", "block_tdp"], [], {"RAM_BLOCK_TDP": 1}), ] +### initialization values testing +LUT_INIT = """ +module top(clk, ra, wa, rd, wd, we); + +localparam ABITS = {abits}; +localparam DBITS = {dbits}; + +input wire clk; +input wire we; +input wire [ABITS-1:0] ra, wa; +input wire [DBITS-1:0] wd; +output wire [DBITS-1:0] rd; + +reg [DBITS-1:0] mem [0:2**ABITS-1]; + +integer i; +initial + for (i = 0; i < 2**ABITS-1; i = i + 1) + mem[i] = {ival}; + +always @(posedge clk) + if (we) + mem[wa] <= wd; + +assign rd = mem[ra]; + +endmodule +""" + +INIT_LUT_ZEROS = LUT_INIT.format(abits=4, dbits=4, ival=0); +INIT_LUT_VAL = LUT_INIT.format(abits=4, dbits=4, ival=5); +INIT_LUT_VAL2 = LUT_INIT.format(abits=6, dbits=6, ival="6'h12"); +INIT_LUT_X = LUT_INIT.format(abits=4, dbits=4, ival="4'hx") + +TESTS += [ + Test("init_lut_zeros_zero", INIT_LUT_ZEROS, ["lut"], ["INIT_ZERO"], {"RAM_LUT":1}), + Test("init_lut_zeros_any", INIT_LUT_ZEROS, ["lut"], ["INIT_ANY"], {"RAM_LUT":1}), + Test("init_lut_val_zero", INIT_LUT_VAL, ["lut"], ["INIT_ZERO"], {"RAM_LUT":0}), #CHECK: no emulation? + Test("init_lut_val_any", INIT_LUT_VAL, ["lut"], ["INIT_ANY"], {"RAM_LUT":1}), + Test("init_lut_val_no_undef", INIT_LUT_VAL, ["lut"], ["INIT_NO_UNDEF"], {"RAM_LUT":1}), + Test("init_lut_val2_any", INIT_LUT_VAL2, ["lut"], ["INIT_ANY"], {"RAM_LUT":8}), + Test("init_lut_val2_no_undef", INIT_LUT_VAL2, ["lut"], ["INIT_NO_UNDEF"], {"RAM_LUT":8}), + Test("init_lut_x_none", INIT_LUT_X, ["lut"], ["INIT_NONE"], {"RAM_LUT":1}), + Test("init_lut_x_zero", INIT_LUT_X, ["lut"], ["INIT_ZERO"], {"RAM_LUT":1}), + Test("init_lut_x_any", INIT_LUT_X, ["lut"], ["INIT_ANY"], {"RAM_LUT":1}), + Test("init_lut_x_no_undef", INIT_LUT_X, ["lut"], ["INIT_NO_UNDEF"], {"RAM_LUT":1}), +] + +### width testing 9-bit-per-byte +RAM_9b1B = """ +module top(clk, ra, wa, rd, wd, we); + +localparam ABITS = {abits}; +localparam DBITS = {dbits}; + +input wire clk; +input wire we; +input wire [ABITS-1:0] ra, wa; +input wire [DBITS-1:0] wd; +output reg [DBITS-1:0] rd; + +reg [DBITS-1:0] mem [0:2**ABITS-1]; + +always @(posedge clk) + if (we) + mem[wa] <= wd; + +always @(posedge clk) + rd <= mem[ra]; + +endmodule +""" + +RAM_18b2B = RAM_9b1B.format(abits=3, dbits=18); +RAM_9b1B = RAM_9b1B.format(abits=4, dbits=9); +RAM_4b1B = RAM_9b1B.format(abits=5, dbits=4); +RAM_2b1B = RAM_9b1B.format(abits=6, dbits=2); +RAM_1b1B = RAM_9b1B.format(abits=7, dbits=1); + +TESTS += [ + Test("ram_18b2B", RAM_18b2B, ["9b1B"], [], {"RAM_9b1B":1}), + Test("ram_9b1B", RAM_9b1B, ["9b1B"], [], {"RAM_9b1B":1}), + Test("ram_4b1B", RAM_4b1B, ["9b1B"], [], {"RAM_9b1B":1}), + Test("ram_2b1B", RAM_2b1B, ["9b1B"], [], {"RAM_9b1B":1}), + Test("ram_1b1B", RAM_1b1B, ["9b1B"], [], {"RAM_9b1B":1}), +] + +### initializing 9-bits-per-byte +RAM_9b1B_init = """ +module top(clk, ra, wa, rd, wd, we); + +localparam ABITS = {abits}; +localparam DBITS = {dbits}; + +input wire clk; +input wire we; +input wire [ABITS-1:0] ra, wa; +input wire [DBITS-1:0] wd; +output reg [DBITS-1:0] rd; + +reg [DBITS-1:0] mem [0:2**ABITS-1]; + +integer i; +initial + for (i = 0; i < 2**ABITS-1; i = i + 1) + mem[i] = {ival}; + +always @(posedge clk) + if (we) + mem[wa] <= wd; + +always @(posedge clk) + rd <= mem[ra]; + +endmodule +""" + +INIT_9b1B_ZEROS = RAM_9b1B_init.format(abits=4, dbits=9, ival=0); +INIT_9b1B_VAL = RAM_9b1B_init.format(abits=4, dbits=9, ival=275); +INIT_13b2B_VAL = RAM_9b1B_init.format(abits=3, dbits=13, ival="13'h01f3") +INIT_18b2B_VAL = RAM_9b1B_init.format(abits=4, dbits=18, ival="18'h1f39a"); +INIT_4b1B_X = RAM_9b1B_init.format(abits=5, dbits=4, ival="4'hx") + +TESTS += [ + Test("init_9b1B_zeros_zero", INIT_9b1B_ZEROS, ["9b1B"], ["INIT_ZERO"], {"RAM_9b1B":1}), + Test("init_9b1B_zeros_any", INIT_9b1B_ZEROS, ["9b1B"], ["INIT_ANY"], {"RAM_9b1B":1}), + Test("init_9b1B_val_zero", INIT_9b1B_VAL, ["9b1B"], ["INIT_ZERO"], {"RAM_9b1B":0}), #CHECK: no emulation? + Test("init_9b1B_val_any", INIT_9b1B_VAL, ["9b1B"], ["INIT_ANY"], {"RAM_9b1B":1}), + Test("init_9b1B_val_no_undef", INIT_9b1B_VAL, ["9b1B"], ["INIT_NO_UNDEF"], {"RAM_9b1B":1}), + Test("init_13b2B_val_any", INIT_13b2B_VAL, ["9b1B"], ["INIT_ANY"], {"RAM_9b1B":1}), + Test("init_18b2B_val_any", INIT_18b2B_VAL, ["9b1B"], ["INIT_ANY"], {"RAM_9b1B":2}), + Test("init_18b2B_val_no_undef", INIT_18b2B_VAL, ["9b1B"], ["INIT_NO_UNDEF"], {"RAM_9b1B":2}), + Test("init_4b1B_x_none", INIT_4b1B_X, ["9b1B"], ["INIT_NONE"], {"RAM_9b1B":1}), + Test("init_4b1B_x_zero", INIT_4b1B_X, ["9b1B"], ["INIT_ZERO"], {"RAM_9b1B":1}), + Test("init_4b1B_x_any", INIT_4b1B_X, ["9b1B"], ["INIT_ANY"], {"RAM_9b1B":1}), + Test("init_4b1B_x_no_undef", INIT_4b1B_X, ["9b1B"], ["INIT_NO_UNDEF"], {"RAM_9b1B":1}), +] + +### Clock polarity combinations +# I'm not entirely convinced auto-test is correctly testing clock edging +# but they do at least all gen/synth +SYNCCLOCK = """ +module top(clk, ra, wa, rd, wd, we); + +localparam ABITS = {abits}; +localparam DBITS = 8; + +input wire clk; +input wire we; +input wire [ABITS-1:0] ra, wa; +input wire [DBITS-1:0] wd; +output reg [DBITS-1:0] rd; + +reg [DBITS-1:0] mem [0:2**ABITS-1]; + +always @(posedge clk) + if (we) + mem[wa] <= wd; + +always @(posedge clk) + rd <= mem[ra]; + +endmodule +""" +for (abits, cnt, wclk, rclk, shared) in [ + (4, 1, "ANY","ANY", False), + (4, 1, "ANY","NEG", False), + (4, 1, "ANY","POS", False), + (4, 1, "NEG","ANY", False), + (4, 1, "NEG","POS", False), + (4, 1, "NEG","NEG", False), + (4, 1, "POS","ANY", False), + (4, 1, "POS","NEG", False), + (4, 1, "POS","POS", False), + (4, 1, "ANY","ANY", True), + (4, 0, "NEG","POS", True), # FF mapping + (4, 1, "NEG","NEG", True), + (4, 0, "POS","NEG", True), # FF mapping + (4, 1, "POS","POS", True), + # cannot combine "ANY" with "POS|NEG" when using shared clock +]: + name = f"clock_a{abits}_w{wclk}r{rclk}s{shared}" + defs = ["WCLK_" + wclk, "RCLK_" + rclk] + if (shared): + defs.append("SHARED_CLK") + TESTS.append(Test( + name, SYNCCLOCK.format(abits=abits), + ["clock_sdp"], defs, {"RAM_CLOCK_SDP": cnt} + )) + +### mixed width testing +# Wide write port +MIXED_WRITE = """ +module top(clk, ra, wa, rd, wd, we); + +localparam WABITS = {wabits}; +localparam WDBITS = {wdbits}; + +localparam RABITS = {rabits}; +localparam RDBITS = {rdbits}; + +input wire clk; +input wire we; +input wire [WABITS-1:0] wa; +input wire [WDBITS-1:0] wd; +input wire [RABITS-1:0] ra; +output reg [RDBITS-1:0] rd; + +localparam DEPTH = (2**WABITS); + +localparam OFFSET = RABITS-WABITS; + +(* syn_ramstyle = "block_ram" *) +reg [WDBITS-1:0] mem [0:DEPTH-1]; + +always @(posedge clk) + if (we) + mem[wa] <= wd; + +if (OFFSET > 0) begin + reg [WDBITS-1:0] mem_read; + reg [OFFSET-1:0] subaddr_r; + always @(posedge clk) begin + mem_read <= mem[ra[RABITS-1:OFFSET]]; + subaddr_r <= ra[OFFSET-1:0]; + end + + always @(mem_read, subaddr_r) + rd <= mem_read[subaddr_r*RDBITS+:RDBITS]; +end +else +begin + always @(posedge clk) + case (OFFSET) + 0: rd <= mem[ra]; + -1: rd <= {{ mem[ra], mem[ra+1] }}; + endcase +end +endmodule +""" + +UNMIXED = MIXED_WRITE.format(wabits=4, wdbits=9, rabits=4, rdbits=9) +MIXED_9_18 = MIXED_WRITE.format(wabits=5, wdbits=9, rabits=4, rdbits=18) +MIXED_18_9 = MIXED_WRITE.format(wabits=3, wdbits=18, rabits=4, rdbits=9) +MIXED_36_9 = MIXED_WRITE.format(wabits=3, wdbits=36, rabits=5, rdbits=9) +MIXED_4_2 = MIXED_WRITE.format(wabits=5, wdbits=4, rabits=6, rdbits=2); + +TESTS += [ + Test("unmixed", UNMIXED, ["9b1B"], [], {"RAM_9b1B":1}), + Test("mixed_9_18", MIXED_9_18, ["9b1B"], [], {"RAM_9b1B":4}), #CHECK: only using half the memory + Test("mixed_18_9", MIXED_18_9, ["9b1B"], [], {"RAM_9b1B":1}), + Test("mixed_36_9", MIXED_36_9, ["9b1B"], [], {"RAM_9b1B":2}), + Test("mixed_4_2", MIXED_4_2, ["9b1B"], [], {"RAM_9b1B":1}), +] + ### basic TDP test TDP = """ @@ -131,7 +381,7 @@ def __init__(self, name, src, libs, defs, cells): ] # shared clock - +# Synchronous SDP with clock domain crossing SYNC_2CLK = """ module top(rclk, wclk, ra, wa, rd, wd, we); @@ -163,7 +413,7 @@ def __init__(self, name, src, libs, defs, cells): ] # inter-port transparency - +# Synchronous SDP with write-first behaviour SYNC_TRANS = """ module top(clk, ra, wa, rd, wd, we); @@ -201,7 +451,7 @@ def __init__(self, name, src, libs, defs, cells): ] # rdwr checks - +# Synchronous single-port RAM with mutually exclusive read/write SP_NO_CHANGE = """ module top(clk, addr, rd, wd, we); @@ -247,6 +497,7 @@ def __init__(self, name, src, libs, defs, cells): endmodule """ +# Synchronous single-port RAM with write-first behaviour SP_NEW = """ module top(clk, addr, rd, wd, we); @@ -295,6 +546,7 @@ def __init__(self, name, src, libs, defs, cells): endmodule """ +# Synchronous single-port RAM with read-first behaviour SP_OLD = """ module top(clk, addr, rd, wd, we); @@ -373,6 +625,7 @@ def __init__(self, name, src, libs, defs, cells): Test("sp_old_auto_be", SP_OLD_BE, ["block_sp"], ["RDWR_NO_CHANGE", "RDWR_OLD", "RDWR_NEW"], {"RAM_BLOCK_SP": (1, {"OPTION_RDWR": "OLD"})}), ] +# Synchronous read port with initial value SP_INIT = """ module top(clk, addr, rd, wd, we, re); @@ -418,6 +671,7 @@ def __init__(self, name, src, libs, defs, cells): Test("sp_init_v_any_re", SP_INIT_V, ["block_sp"], ["RDINIT_ANY", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}), ] +# Synchronous read port with asynchronous reset SP_ARST = """ module top(clk, addr, rd, wd, we, re, ar); @@ -488,6 +742,7 @@ def __init__(self, name, src, libs, defs, cells): Test("sp_arst_n_init_re", SP_ARST_N, ["block_sp"], ["RDINIT_ANY", "RDARST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}), ] +# Synchronous read port with synchronous reset (reset priority over enable) SP_SRST = """ module top(clk, addr, rd, wd, we, re, sr); @@ -515,6 +770,7 @@ def __init__(self, name, src, libs, defs, cells): endmodule """ +# Synchronous read port with synchronous reet (enable priority over reset) SP_SRST_G = """ module top(clk, addr, rd, wd, we, re, sr); @@ -602,6 +858,180 @@ def __init__(self, name, src, libs, defs, cells): Test("sp_srst_gv_init_re", SP_SRST_GV, ["block_sp"], ["RDINIT_ANY", "RDSRST_INIT", "RDEN", "RDWR_OLD"], {"RAM_BLOCK_SP": 1}), ] +# Byte enables, wrbe_separate +SYNC_ENABLE = """ +module top(clk, rwa, rd, wd, we); + +localparam ABITS = {abits}; +localparam DBITS = {dbits}; + +input wire clk; +input wire we; +input wire [ABITS-1:0] rwa; +input wire [DBITS-1:0] wd; +output reg [DBITS-1:0] rd; + +reg [DBITS-1:0] mem [0:2**ABITS-1]; + +always @(posedge clk) begin + if (we) + mem[rwa] <= wd; + else + rd <= mem[rwa]; +end + +endmodule +""" + +for (abits, dbits, sep, defs, cells) in [ + (4, 4, False, ["NO_BYTE"], {"RAM_WREN": 1}), + (5, 4, False, ["NO_BYTE"], {"RAM_WREN": 2}), + (6, 4, False, ["NO_BYTE"], {"RAM_WREN": 4}), + # (4, 4, True, ["NO_BYTE"], {"RAM_WREN": 1}), # should throw an error + (3, 8, False, ["NO_BYTE"], {"RAM_WREN": 2}), # needs two write ports + (4, 8, False, ["NO_BYTE"], {"RAM_WREN": 2}), + (4, 4, False, ["W4_B4"], {"RAM_WREN": 1}), + (4, 8, True, ["W4_B4"], {"RAM_WREN": 2}), + (4, 8, False, ["W8_B4"], {"RAM_WREN": 1}), + (4, 8, True, ["W8_B4"], {"RAM_WREN": 1}), + (4, 8, False, ["W8_B8"], {"RAM_WREN": 1}), + (4, 8, True, ["W8_B8"], {"RAM_WREN": 1}), + +]: + name = f"wren_a{abits}d{dbits}_{defs[0]}" + if (sep): + defs.append("WRBE_SEPARATE") + name += "_separate" + + TESTS.append(Test( + name, SYNC_ENABLE.format(abits=abits, dbits=dbits), + ["wren"], defs, cells + )) + +# Write port with byte enables +ENABLES = """ +module top(clk, we, be, rwa, wd, rd); + +localparam ABITS = {abits}; +localparam WBITS = {wbits}; +localparam WORDS = {words}; + +input wire clk; +input wire we; +input wire [WORDS-1:0] be; +input wire [ABITS-1:0] rwa; +input wire [(WBITS*WORDS)-1:0] wd; +output reg [(WBITS*WORDS)-1:0] rd; + +reg [(WBITS*WORDS)-1:0] mem [0:2**ABITS-1]; + +integer i; +always @(posedge clk) + for (i=0; i Date: Mon, 11 Jul 2022 12:31:38 +1200 Subject: [PATCH 018/303] Fix for sync_ram_sdp not being final module Explicitly declare -top in synth_intel_alm. --- tests/arch/intel_alm/blockram.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/arch/intel_alm/blockram.ys b/tests/arch/intel_alm/blockram.ys index 3b61b93390c..21b5ecbfb60 100644 --- a/tests/arch/intel_alm/blockram.ys +++ b/tests/arch/intel_alm/blockram.ys @@ -1,6 +1,6 @@ read_verilog ../common/blockram.v chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 10 sync_ram_sdp -synth_intel_alm -family cyclonev -noiopad -noclkbuf +synth_intel_alm -top sync_ram_sdp -family cyclonev -noiopad -noclkbuf cd sync_ram_sdp select -assert-count 1 t:MISTRAL_NOT select -assert-count 1 t:MISTRAL_M10K From 51c2d476c2209b3dad9e0a0199648274b5c3ea82 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Mon, 25 Jul 2022 10:10:21 +1200 Subject: [PATCH 019/303] Removing extra `default_nettype` lines --- tests/arch/common/blockram.v | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/arch/common/blockram.v b/tests/arch/common/blockram.v index 6b557fdca3d..c06ac96d5bc 100644 --- a/tests/arch/common/blockram.v +++ b/tests/arch/common/blockram.v @@ -22,7 +22,6 @@ module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) endmodule // sync_ram_sp -`default_nettype none module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) (input wire clk, write_enable, input wire [DATA_WIDTH-1:0] data_in, @@ -46,7 +45,6 @@ module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) endmodule // sync_ram_sdp -`default_nettype none module sync_ram_tdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10) (input wire clk_a, clk_b, input wire write_enable_a, write_enable_b, From 445a801a8587d75d3f0767cf9ba15776f50c5287 Mon Sep 17 00:00:00 2001 From: KrystalDelusion Date: Mon, 25 Jul 2022 10:12:30 +1200 Subject: [PATCH 020/303] bug3205.ys removed Made redundant by TDP test(s) in memories.ys --- tests/arch/ecp5/bug3205.ys | 57 -------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 tests/arch/ecp5/bug3205.ys diff --git a/tests/arch/ecp5/bug3205.ys b/tests/arch/ecp5/bug3205.ys deleted file mode 100644 index f2e9365307f..00000000000 --- a/tests/arch/ecp5/bug3205.ys +++ /dev/null @@ -1,57 +0,0 @@ -read_verilog < Date: Mon, 25 Jul 2022 10:21:00 +1200 Subject: [PATCH 021/303] Genericising bug1836.ys --- tests/arch/ecp5/bug1836.ys | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/tests/arch/ecp5/bug1836.ys b/tests/arch/ecp5/bug1836.ys index d8533441e1c..15cdf422868 100644 --- a/tests/arch/ecp5/bug1836.ys +++ b/tests/arch/ecp5/bug1836.ys @@ -1,31 +1,23 @@ read_verilog < Date: Tue, 21 Feb 2023 00:17:40 +0000 Subject: [PATCH 022/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 396aeb9275c..44a59c8c211 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+39 +YOSYS_VER := 0.26+50 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 5d9bd0af9296fd143cae98e683743cc42242ff94 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 23 Feb 2023 01:48:08 +0000 Subject: [PATCH 023/303] Update abc. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 44a59c8c211..2b5f2c0790d 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = a8f0ef2 +ABCREV = 2c1c83f ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From 8216b23fb7b0ee1944403943eb066e0689129ba9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 00:16:59 +0000 Subject: [PATCH 024/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2b5f2c0790d..43b90355b59 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+50 +YOSYS_VER := 0.26+53 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a30894e5facf9d0f3e814a4c00e376000d3eed6c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 17 Feb 2023 09:45:41 +0100 Subject: [PATCH 025/303] Handle more wide case selector types --- frontends/verific/verific.cc | 56 +++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index c1e9fc7d027..ab3e5542774 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1043,21 +1043,49 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr sw->signal = sig_select; current_case->switches.push_back(sw); - int select_width = inst->InputSize(); - int data_width = inst->OutputSize(); - int select_num = inst->Input1Size() / inst->InputSize(); - - int offset_select = 0; - int offset_data = 0; - - for (int i = 0; i < select_num; i++) { - RTLIL::CaseRule *cs = new RTLIL::CaseRule; - cs->compare.push_back(sig_select_values.extract(offset_select, select_width)); - cs->actions.push_back(SigSig(sig_out_val, sig_data_values.extract(offset_data, data_width))); - sw->cases.push_back(cs); - - offset_select += select_width; + unsigned select_width = inst->InputSize(); + unsigned data_width = inst->OutputSize(); + unsigned offset_data = 0; + unsigned offset_select = 0; + + OperWideCaseSelector* selector = (OperWideCaseSelector*) inst->View(); + + for (unsigned i = 0 ; i < selector->GetNumBranches() ; ++i) { + + SigSig action(sig_out_val, sig_data_values.extract(offset_data, data_width)); offset_data += data_width; + + for (unsigned j = 0 ; j < selector->GetNumConditions(i) ; ++j) { + Array left_bound, right_bound ; + selector->GetCondition(i, j, &left_bound, &right_bound); + + SigSpec sel_left = sig_select_values.extract(offset_select, select_width); + offset_select += select_width; + + if (right_bound.Size()) { + SigSpec sel_right = sig_select_values.extract(offset_select, select_width); + offset_select += select_width; + + log_assert(sel_right.is_fully_const() && sel_right.is_fully_def()); + log_assert(sel_left.is_fully_const() && sel_right.is_fully_def()); + + int32_t left = sel_left.as_int(); + int32_t right = sel_right.as_int(); + int width = sel_left.size(); + + for (int32_t i = right; icompare.push_back(RTLIL::Const(i,width)); + cs->actions.push_back(action); + sw->cases.push_back(cs); + } + } + + RTLIL::CaseRule *cs = new RTLIL::CaseRule; + cs->compare.push_back(sel_left); + cs->actions.push_back(action); + sw->cases.push_back(cs); + } } RTLIL::CaseRule *cs_default = new RTLIL::CaseRule; cs_default->actions.push_back(SigSig(sig_out_val, sig_data_default)); From 53a4f0fb56f298880c9b91dfa8c2e69a383cd5bc Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 23 Feb 2023 14:58:02 +0100 Subject: [PATCH 026/303] Add test example --- tests/verific/.gitignore | 3 +++ tests/verific/case.sv | 28 ++++++++++++++++++++++++++++ tests/verific/case.ys | 16 ++++++++++++++++ tests/verific/run-test.sh | 4 ++++ 4 files changed, 51 insertions(+) create mode 100644 tests/verific/.gitignore create mode 100644 tests/verific/case.sv create mode 100644 tests/verific/case.ys create mode 100755 tests/verific/run-test.sh diff --git a/tests/verific/.gitignore b/tests/verific/.gitignore new file mode 100644 index 00000000000..b48f808a1e3 --- /dev/null +++ b/tests/verific/.gitignore @@ -0,0 +1,3 @@ +/*.log +/*.out +/run-test.mk diff --git a/tests/verific/case.sv b/tests/verific/case.sv new file mode 100644 index 00000000000..ed8529b91d7 --- /dev/null +++ b/tests/verific/case.sv @@ -0,0 +1,28 @@ +module top ( + input clk, + input [5:0] currentstate, + output reg [1:0] o + ); + always @ (posedge clk) + begin + case (currentstate) + 5'd1,5'd2, 5'd3: + begin + o <= 2'b01; + end + 5'd4: + begin + o <= 2'b10; + end + 5'd5,5'd6,5'd7: + begin + o <= 2'b11; + end + default : + begin + o <= 2'b00; + end + endcase + end +endmodule + diff --git a/tests/verific/case.ys b/tests/verific/case.ys new file mode 100644 index 00000000000..a181b39cf2b --- /dev/null +++ b/tests/verific/case.ys @@ -0,0 +1,16 @@ +verific -cfg db_abstract_case_statement_synthesis 0 +read -sv case.sv +verific -import top +prep +rename top gold + +verific -cfg db_abstract_case_statement_synthesis 1 +read -sv case.sv +verific -import top +prep +rename top gate + +miter -equiv -flatten -make_assert gold gate miter +prep -top miter +clk2fflogic +sat -set-init-zero -tempinduct -prove-asserts -verify diff --git a/tests/verific/run-test.sh b/tests/verific/run-test.sh new file mode 100755 index 00000000000..2f91cf0fd4e --- /dev/null +++ b/tests/verific/run-test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +source ../gen-tests-makefile.sh +run_tests --yosys-scripts --bash From d8cefec1691988a5a842371819be8adb981608de Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 23 Feb 2023 15:04:31 +0100 Subject: [PATCH 027/303] Added ranged case check --- tests/verific/range_case.sv | 11 +++++++++++ tests/verific/range_case.ys | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/verific/range_case.sv create mode 100644 tests/verific/range_case.ys diff --git a/tests/verific/range_case.sv b/tests/verific/range_case.sv new file mode 100644 index 00000000000..9843feafe33 --- /dev/null +++ b/tests/verific/range_case.sv @@ -0,0 +1,11 @@ +module top(input clk, input signed [3:0] sel_w , output reg out); + +always @ (posedge clk) +begin + case (sel_w) inside + [-4:3] : out <= 1'b1; + [4:5] : out <= 1'b0; + endcase +end + +endmodule diff --git a/tests/verific/range_case.ys b/tests/verific/range_case.ys new file mode 100644 index 00000000000..27afbbc1743 --- /dev/null +++ b/tests/verific/range_case.ys @@ -0,0 +1,16 @@ +verific -cfg db_abstract_case_statement_synthesis 0 +read -sv range_case.sv +verific -import top +proc +rename top gold + +verific -cfg db_abstract_case_statement_synthesis 1 +read -sv range_case.sv +verific -import top +proc +rename top gate + +miter -equiv -flatten -make_assert gold gate miter +prep -top miter +clk2fflogic +sat -set-init-zero -tempinduct -prove-asserts -verify From 28c4aac234b878e7f466185ed67232738d69b8e2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 27 Feb 2023 09:27:04 +0100 Subject: [PATCH 028/303] run verific tests in test target --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 43b90355b59..645b5103f71 100644 --- a/Makefile +++ b/Makefile @@ -837,6 +837,9 @@ ABCOPT="" endif test: $(TARGETS) $(EXTRA_TARGETS) +ifeq ($(ENABLE_VERIFIC),1) + +cd tests/verific && bash run-test.sh $(SEEDOPT) +endif +cd tests/simple && bash run-test.sh $(SEEDOPT) +cd tests/simple_abc9 && bash run-test.sh $(SEEDOPT) +cd tests/hana && bash run-test.sh $(SEEDOPT) From 2ab3747cc95986e179453ca149508d3781a94a71 Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 20 Feb 2023 12:49:48 +0100 Subject: [PATCH 029/303] fabulous: Add support for mapping carry chains Signed-off-by: gatecat --- techlibs/fabulous/Makefile.inc | 1 + techlibs/fabulous/arith_map.v | 65 +++++++++++++++++++++++++++++ techlibs/fabulous/prims.v | 14 +++++++ techlibs/fabulous/synth_fabulous.cc | 15 ++++++- tests/arch/fabulous/carry.ys | 9 ++++ 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 techlibs/fabulous/arith_map.v create mode 100644 tests/arch/fabulous/carry.ys diff --git a/techlibs/fabulous/Makefile.inc b/techlibs/fabulous/Makefile.inc index 44d57542b90..28b0d5ef026 100644 --- a/techlibs/fabulous/Makefile.inc +++ b/techlibs/fabulous/Makefile.inc @@ -8,3 +8,4 @@ $(eval $(call add_share_file,share/fabulous,techlibs/fabulous/ff_map.v)) $(eval $(call add_share_file,share/fabulous,techlibs/fabulous/ram_regfile.txt)) $(eval $(call add_share_file,share/fabulous,techlibs/fabulous/regfile_map.v)) $(eval $(call add_share_file,share/fabulous,techlibs/fabulous/io_map.v)) +$(eval $(call add_share_file,share/fabulous,techlibs/fabulous/arith_map.v)) diff --git a/techlibs/fabulous/arith_map.v b/techlibs/fabulous/arith_map.v new file mode 100644 index 00000000000..eca96855693 --- /dev/null +++ b/techlibs/fabulous/arith_map.v @@ -0,0 +1,65 @@ +`default_nettype none + +`ifdef ARITH_ha +(* techmap_celltype = "$alu" *) +module _80_fabulous_ha_alu (A, B, CI, BI, X, Y, CO); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 1; +parameter B_WIDTH = 1; +parameter Y_WIDTH = 1; + +parameter _TECHMAP_CONSTMSK_CI_ = 0; +parameter _TECHMAP_CONSTVAL_CI_ = 0; + +(* force_downto *) +input [A_WIDTH-1:0] A; +(* force_downto *) +input [B_WIDTH-1:0] B; +input CI, BI; +(* force_downto *) +output [Y_WIDTH-1:0] X, Y, CO; + +(* force_downto *) +wire [Y_WIDTH-1:0] A_buf, B_buf; +\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); +\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + +(* force_downto *) +wire [Y_WIDTH-1:0] AA = A_buf; +(* force_downto *) +wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; +wire [Y_WIDTH:0] CARRY; + + +LUT4_HA #( + .INIT(16'b0), + .I0MUX(1'b1) +) carry_statrt ( + .I0(), .I1(CI), .I2(CI), .I3(), + .Ci(), + .Co(CARRY[0]) +); + +// Carry chain +genvar i; +generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice + LUT4_HA #( + .INIT(16'b1001_0110_1001_0110), // full adder sum over (I2, I1, I0) + .I0MUX(1'b1) + ) lut_i ( + .I0(), .I1(AA[i]), .I2(BB[i]), .I3(), + .Ci(CARRY[i]), + .O(Y[i]), + .Co(CARRY[i+1]) + ); + + assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); +end endgenerate + +assign X = AA ^ BB; + +endmodule +`endif + diff --git a/techlibs/fabulous/prims.v b/techlibs/fabulous/prims.v index bd0af906a58..fe3e8536aa8 100644 --- a/techlibs/fabulous/prims.v +++ b/techlibs/fabulous/prims.v @@ -24,6 +24,20 @@ module LUT4(output O, input I0, I1, I2, I3); assign O = I0 ? s1[1] : s1[0]; endmodule +module LUT4_HA(output O, Co, input I0, I1, I2, I3, Ci); + parameter [15:0] INIT = 0; + parameter I0MUX = 1'b1; + + wire [ 7: 0] s3 = I3 ? INIT[15: 8] : INIT[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + + wire I0_sel = I0MUX ? Ci : I0; + assign O = I0_sel ? s1[1] : s1[0]; + + assign Co = (Ci & I1) | (Ci & I2) | (I1 & I2); +endmodule + module LUTFF(input CLK, D, output reg O); initial O = 1'b0; always @ (posedge CLK) begin diff --git a/techlibs/fabulous/synth_fabulous.cc b/techlibs/fabulous/synth_fabulous.cc index d7c45e094c6..b4a7ab2dc6f 100644 --- a/techlibs/fabulous/synth_fabulous.cc +++ b/techlibs/fabulous/synth_fabulous.cc @@ -83,6 +83,9 @@ struct SynthPass : public ScriptPass log(" do not run 'alumacc' pass. i.e. keep arithmetic operators in\n"); log(" their direct form ($add, $sub, etc.).\n"); log("\n"); + log(" -carry \n"); + log(" carry mapping style (none, half-adders, ...) default=none\n"); + log("\n"); log(" -noregfile\n"); log(" do not map register files\n"); log("\n"); @@ -119,7 +122,7 @@ struct SynthPass : public ScriptPass log("\n"); } - string top_module, json_file, blif_file, plib, fsm_opts, memory_opts; + string top_module, json_file, blif_file, plib, fsm_opts, memory_opts, carry_mode; std::vector extra_plib, extra_map; bool autotop, forvpr, noalumacc, nofsm, noshare, noregfile, iopad, complexdff, flatten; @@ -137,6 +140,7 @@ struct SynthPass : public ScriptPass noshare = false; iopad = false; complexdff = false; + carry_mode = "none"; flatten = true; json_file = ""; blif_file = ""; @@ -229,6 +233,12 @@ struct SynthPass : public ScriptPass complexdff = true; continue; } + if (args[argidx] == "-carry") { + carry_mode = args[++argidx]; + if (carry_mode != "none" && carry_mode != "ha") + log_cmd_error("Unsupported carry style: %s\n", carry_mode.c_str()); + continue; + } if (args[argidx] == "-noflatten") { flatten = false; continue; @@ -326,7 +336,8 @@ struct SynthPass : public ScriptPass if (check_label("map_gates")) { run("opt -full"); - run("techmap -map +/techmap.v"); + run(stringf("techmap -map +/techmap.v -map +/fabulous/arith_map.v -D ARITH_%s", + help_mode ? "" : carry_mode.c_str())); run("opt -fast"); } diff --git a/tests/arch/fabulous/carry.ys b/tests/arch/fabulous/carry.ys new file mode 100644 index 00000000000..bba969d37d1 --- /dev/null +++ b/tests/arch/fabulous/carry.ys @@ -0,0 +1,9 @@ +read_verilog ../common/add_sub.v +hierarchy -top top +proc +equiv_opt -assert -map +/fabulous/prims.v synth_fabulous -carry ha # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-max 10 t:LUT4_HA +select -assert-max 4 t:LUT1 +select -assert-none t:LUT1 t:LUT4_HA %% t:* %D From 4bb173e25609b836fc83473b544f404f8f76d2ff Mon Sep 17 00:00:00 2001 From: Catherine Date: Mon, 27 Feb 2023 20:24:47 +0000 Subject: [PATCH 030/303] yosys-smtbmc: support -h/--help (and exit with code 0). --- backends/smt2/smtbmc.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index cb21eb3aa4b..6b81740a272 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -59,9 +59,12 @@ so = SmtOpts() -def usage(): +def help(): print(os.path.basename(sys.argv[0]) + """ [options] + -h, --help + show this message + -t -t : -t :: @@ -181,19 +184,25 @@ def usage(): (this feature is experimental and incomplete) """ + so.helpmsg()) + +def usage(): + help() sys.exit(1) try: - opts, args = getopt.getopt(sys.argv[1:], so.shortopts + "t:igcm:", so.longopts + - ["final-only", "assume-skipped=", "smtc=", "cex=", "aig=", "aig-noheader", "yw=", "btorwit=", "presat", + opts, args = getopt.getopt(sys.argv[1:], so.shortopts + "t:higcm:", so.longopts + + ["help", "final-only", "assume-skipped=", "smtc=", "cex=", "aig=", "aig-noheader", "yw=", "btorwit=", "presat", "dump-vcd=", "dump-yw=", "dump-vlogtb=", "vlogtb-top=", "dump-smtc=", "dump-all", "noinfo", "append=", "smtc-init", "smtc-top=", "noinit", "binary", "keep-going", "check-witness", "detect-loops"]) except: usage() for o, a in opts: - if o == "-t": + if o in ("-h", "--help"): + help() + sys.exit(0) + elif o == "-t": got_topt = True a = a.split(":") if len(a) == 1: From 71c59d9fab7f6da52604f790d275dbf10a3aa4db Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Feb 2023 00:17:33 +0000 Subject: [PATCH 031/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 645b5103f71..d7c2afacc38 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+53 +YOSYS_VER := 0.26+62 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 57897927ff803d5372e3269786df441bdf0dc2f2 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Tue, 28 Feb 2023 17:12:55 +0100 Subject: [PATCH 032/303] stat: pass down quiet arg --- passes/cmds/stat.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/stat.cc b/passes/cmds/stat.cc index 522957f3959..f0021cf8769 100644 --- a/passes/cmds/stat.cc +++ b/passes/cmds/stat.cc @@ -316,7 +316,7 @@ statdata_t hierarchy_worker(std::map &mod_stat, RTL if (mod_stat.count(it.first) > 0) { if (!quiet) log(" %*s%-*s %6u\n", 2*level, "", 26-2*level, log_id(it.first), it.second); - mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1) * it.second; + mod_data = mod_data + hierarchy_worker(mod_stat, it.first, level+1, quiet) * it.second; mod_data.num_cells -= it.second; } else { mod_data.num_cells_by_type[it.first] += it.second; From 3f173c21807625da3c8f876396d5fd2f39b26f14 Mon Sep 17 00:00:00 2001 From: Catherine Date: Thu, 23 Feb 2023 01:38:14 +0000 Subject: [PATCH 033/303] Makefile: fix GIT_REV extraction if Yosys is built as submodule. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 44a59c8c211..0ef947583d0 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,7 @@ YOSYS_VER := 0.26+50 # back to calling git directly. TARBALL_GIT_REV := $(shell cat $(YOSYS_SRC)/.gitcommit) ifeq ($(TARBALL_GIT_REV),$$Format:%h$$) -GIT_REV := $(shell git ls-remote $(YOSYS_SRC) HEAD -q | $(AWK) 'BEGIN {R = "UNKNOWN"}; ($$2 == "HEAD") {R = substr($$1, 1, 9); exit} END {print R}') +GIT_REV := $(shell GIT_DIR=$(YOSYS_SRC)/.git git rev-parse --short=9 HEAD || echo UNKNOWN) else GIT_REV := $(TARBALL_GIT_REV) endif From 9747e55d9520631c4405ec42c02d5197c2ea57ab Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 00:18:47 +0000 Subject: [PATCH 034/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d7c2afacc38..5d70ef693a1 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+62 +YOSYS_VER := 0.26+73 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 0d3423ddea1c24aea74206d64e6dc5196959ad5e Mon Sep 17 00:00:00 2001 From: Dag Lem Date: Tue, 28 Feb 2023 18:45:55 +0100 Subject: [PATCH 035/303] Index struct/union members within corresponding wire chunks This guards against access to bits outside of struct/union members via dynamic indexing. --- frontends/ast/ast.cc | 8 +++++- frontends/ast/ast.h | 1 + frontends/ast/genrtlil.cc | 46 ++++++++++++++++++++--------------- frontends/ast/simplify.cc | 44 ++++++++++++++++++++++++--------- tests/svtypes/struct_array.sv | 3 ++- 5 files changed, 69 insertions(+), 33 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 982943d1ba9..5a2ade04a90 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -524,7 +524,13 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const break; case AST_IDENTIFIER: - fprintf(f, "%s", id2vl(str).c_str()); + { + AST::AstNode *member_node = AST::get_struct_member(this); + if (member_node) + fprintf(f, "%s[%d:%d]", id2vl(str).c_str(), member_node->range_left, member_node->range_right); + else + fprintf(f, "%s", id2vl(str).c_str()); + } for (auto child : children) child->dumpVlog(f, ""); break; diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 142ec0801d4..25a600f00b8 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -380,6 +380,7 @@ namespace AST // struct helper exposed from simplify for genrtlil AstNode *make_struct_member_range(AstNode *node, AstNode *member_node); + AstNode *get_struct_member(const AstNode *node); // generate standard $paramod... derived module name; parameters should be // in the order they are declared in the instantiated module diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 9f458530d2d..8da4b0b0a09 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1375,6 +1375,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigChunk chunk; bool is_interface = false; + AST::AstNode *member_node = NULL; int add_undef_bits_msb = 0; int add_undef_bits_lsb = 0; @@ -1438,23 +1439,26 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) chunk.width = wire->width; chunk.offset = 0; + if ((member_node = get_struct_member(this))) { + // Clamp wire chunk to range of member within struct/union. + chunk.width = member_node->range_left - member_node->range_right + 1; + chunk.offset = member_node->range_right; + } + use_const_chunk: if (children.size() != 0) { if (children[0]->type != AST_RANGE) log_file_error(filename, location.first_line, "Single range expected.\n"); int source_width = id2ast->range_left - id2ast->range_right + 1; int source_offset = id2ast->range_right; - int item_left = source_width - 1; - int item_right = 0; - - // Check for item in struct/union. - AST::AstNode *item_node; - if (attributes.count(ID::wiretype) && (item_node = attributes[ID::wiretype]) && - (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT || item_node->type == AST_UNION)) - { - // Clamp chunk to range of item within struct/union. - item_left = item_node->range_left; - item_right = item_node->range_right; + int chunk_left = source_width - 1; + int chunk_right = 0; + + if (member_node) { + // Clamp wire chunk to range of member within struct/union. + log_assert(!source_offset && !id2ast->range_swapped); + chunk_left = chunk.offset + chunk.width - 1; + chunk_right = chunk.offset; } if (!children[0]->range_valid) { @@ -1468,14 +1472,16 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); + if (member_node) + fake_ast->children[0]->attributes[ID::wiretype] = member_node->clone(); int fake_ast_width = 0; bool fake_ast_sign = true; fake_ast->children[1]->detectSignWidth(fake_ast_width, fake_ast_sign); RTLIL::SigSpec shift_val = fake_ast->children[1]->genRTLIL(fake_ast_width, fake_ast_sign); - if (id2ast->range_right != 0) { - shift_val = current_module->Sub(NEW_ID, shift_val, id2ast->range_right, fake_ast_sign); + if (source_offset != 0) { + shift_val = current_module->Sub(NEW_ID, shift_val, source_offset, fake_ast_sign); fake_ast->children[1]->is_signed = true; } if (id2ast->range_swapped) { @@ -1491,10 +1497,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return sig; } else { chunk.width = children[0]->range_left - children[0]->range_right + 1; - chunk.offset = children[0]->range_right - source_offset; + chunk.offset += children[0]->range_right - source_offset; if (id2ast->range_swapped) - chunk.offset = (id2ast->range_left - id2ast->range_right + 1) - (chunk.offset + chunk.width); - if (chunk.offset > item_left || chunk.offset + chunk.width < item_right) { + chunk.offset = source_width - (chunk.offset + chunk.width); + if (chunk.offset > chunk_left || chunk.offset + chunk.width < chunk_right) { if (chunk.width == 1) log_file_warning(filename, location.first_line, "Range select out of bounds on signal `%s': Setting result bit to undef.\n", str.c_str()); @@ -1503,12 +1509,12 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) children[0]->range_left, children[0]->range_right, str.c_str(), chunk.width); chunk = RTLIL::SigChunk(RTLIL::State::Sx, chunk.width); } else { - if (chunk.offset + chunk.width - 1 > item_left) { - add_undef_bits_msb = (chunk.offset + chunk.width - 1) - item_left; + if (chunk.offset + chunk.width - 1 > chunk_left) { + add_undef_bits_msb = (chunk.offset + chunk.width - 1) - chunk_left; chunk.width -= add_undef_bits_msb; } - if (chunk.offset < item_right) { - add_undef_bits_lsb = item_right - chunk.offset; + if (chunk.offset < chunk_right) { + add_undef_bits_lsb = chunk_right - chunk.offset; chunk.width -= add_undef_bits_lsb; chunk.offset += add_undef_bits_lsb; } diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 7edff38d96d..dfb1b890c7f 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -445,7 +445,7 @@ static AstNode *struct_index_lsb_offset(AstNode *lsb_offset, AstNode *rnode, Ast stride /= get_struct_range_width(member_node, dimension); auto right = normalize_struct_index(rnode->children.back(), member_node, dimension); auto offset = stride > 1 ? multiply_by_const(right, stride) : right; - return new AstNode(AST_ADD, lsb_offset, offset); + return lsb_offset ? new AstNode(AST_ADD, lsb_offset, offset) : offset; } static AstNode *struct_index_msb_offset(AstNode *lsb_offset, AstNode *rnode, AstNode *member_node, int dimension, int stride) @@ -484,7 +484,7 @@ AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node) int range_right = member_node->range_right; if (node->children.empty()) { // no range operations apply, return the whole width - return make_range(range_left, range_right); + return make_range(range_left - range_right, 0); } if (node->children.size() != 1) { @@ -493,7 +493,7 @@ AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node) // Range operations auto rnode = node->children[0]; - auto lsb_offset = node_int(member_node->range_right); + AstNode *lsb_offset = NULL; int stride = range_left - range_right + 1; size_t i = 0; @@ -520,6 +520,17 @@ AstNode *AST::make_struct_member_range(AstNode *node, AstNode *member_node) return new AstNode(AST_RANGE, msb_offset, lsb_offset); } +AstNode *AST::get_struct_member(const AstNode *node) +{ + AST::AstNode *member_node; + if (node->attributes.count(ID::wiretype) && (member_node = node->attributes.at(ID::wiretype)) && + (member_node->type == AST_STRUCT_ITEM || member_node->type == AST_STRUCT || member_node->type == AST_UNION)) + { + return member_node; + } + return NULL; +} + static void add_members_to_scope(AstNode *snode, std::string name) { // add all the members in a struct or union to local scope @@ -2696,7 +2707,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, goto skip_dynamic_range_lvalue_expansion; int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1; + int source_offset = children[0]->id2ast->range_right; int result_width = 1; + AST::AstNode *member_node = get_struct_member(children[0]); + if (member_node) { + // Clamp chunk to range of member within struct/union. + log_assert(!source_offset && !children[0]->id2ast->range_swapped); + source_width = member_node->range_left - member_node->range_right + 1; + } AstNode *shift_expr = NULL; AstNode *range = children[0]->children[0]; @@ -2737,11 +2755,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; newNode = new AstNode(AST_CASE, shift_expr); for (int i = 0; i < source_width; i++) { - int start_bit = children[0]->id2ast->range_right + i; + int start_bit = source_offset + i; int end_bit = std::min(start_bit+result_width,source_width) - 1; AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true)); AstNode *lvalue = children[0]->clone(); lvalue->delete_children(); + if (member_node) + lvalue->attributes[ID::wiretype] = member_node->clone(); lvalue->children.push_back(new AstNode(AST_RANGE, mkconst_int(end_bit, true), mkconst_int(start_bit, true))); cond->children.push_back(new AstNode(AST_BLOCK, new AstNode(type, lvalue, children[1]->clone()))); @@ -2783,6 +2803,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *lvalue = children[0]->clone(); lvalue->delete_children(); + if (member_node) + lvalue->attributes[ID::wiretype] = member_node->clone(); AstNode *ref_mask = new AstNode(AST_IDENTIFIER); ref_mask->str = wire_mask->str; @@ -2813,7 +2835,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, shamt = new AstNode(AST_TO_SIGNED, shamt); // offset the shift amount by the lower bound of the dimension - int start_bit = children[0]->id2ast->range_right; + int start_bit = source_offset; shamt = new AstNode(AST_SUB, shamt, mkconst_int(start_bit, true)); // reflect the shift amount if the dimension is swapped @@ -3403,11 +3425,8 @@ skip_dynamic_range_lvalue_expansion:; log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); // Check for item in packed struct / union - AST::AstNode *item_node; - if (id_ast->type == AST_WIRE && - buf->attributes.count(ID::wiretype) && (item_node = buf->attributes[ID::wiretype]) && - (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT || item_node->type == AST_UNION)) - { + AST::AstNode *item_node = get_struct_member(buf); + if (id_ast->type == AST_WIRE && item_node) { // The dimension of the original array expression is saved in the 'integer' field dim += buf->integer; if (item_node->multirange_dimensions.empty()) { @@ -4082,10 +4101,13 @@ replace_fcall_later:; tmp_range_left = (param_width + 2*param_offset) - children[0]->range_right - 1; tmp_range_right = (param_width + 2*param_offset) - children[0]->range_left - 1; } + AST::AstNode *member_node = get_struct_member(this); + int chunk_offset = member_node ? member_node->range_right : 0; + log_assert(!(chunk_offset && param_upto)); for (int i = tmp_range_right; i <= tmp_range_left; i++) { int index = i - param_offset; if (0 <= index && index < param_width) - data.push_back(current_scope[str]->children[0]->bits[index]); + data.push_back(current_scope[str]->children[0]->bits[chunk_offset + index]); else data.push_back(RTLIL::State::Sx); } diff --git a/tests/svtypes/struct_array.sv b/tests/svtypes/struct_array.sv index b87f936aae6..bedc05b6f26 100644 --- a/tests/svtypes/struct_array.sv +++ b/tests/svtypes/struct_array.sv @@ -12,15 +12,16 @@ module top; s.a[2:1] = 16'h1234; s.a[5] = 8'h42; + s.a[-1] = '0; s.b = '1; s.b[1:0] = '0; end always_comb assert(s==64'h4200_0012_3400_FFFC); + always_comb assert(s.a[0][3:-4]===8'h0x); always_comb assert(s.b[23:16]===8'hxx); always_comb assert(s.b[19:12]===8'hxf); - always_comb assert(s.a[0][3:-4]===8'h0x); struct packed { bit [7:0] [7:0] a; // 8 element packed array of bytes From 5f88c218b58cabc20f001c4bf77733670305864e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 6 Mar 2023 08:47:51 +0100 Subject: [PATCH 036/303] Release version 0.27 --- CHANGELOG | 13 ++++++++++++- Makefile | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 18874a04eb4..e2b6a1ba976 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,19 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.26 .. Yosys 0.26-dev +Yosys 0.26 .. Yosys 0.27 -------------------------- + * New commands and options + - Added option "-make_assert" to "equiv_make" pass. + - Added option "-coverenable" to "chformal" pass. + + * Verilog + - Resolve package types in interfaces. + - Handle range offsets in packed arrays within packed structs. + - Support for data and array queries on struct/union item expressions. + + * GateMate support + - Enable register initialization. Yosys 0.25 .. Yosys 0.26 -------------------------- diff --git a/Makefile b/Makefile index 5d70ef693a1..4622fd6d911 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.26+73 +YOSYS_VER := 0.27 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 7e58866.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 7e58866.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 368f2984cdd8f0fd8046d54af3a2939bda48290a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 6 Mar 2023 08:50:14 +0100 Subject: [PATCH 037/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e2b6a1ba976..80672a8cc0d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.27 .. Yosys 0.27-dev +-------------------------- + Yosys 0.26 .. Yosys 0.27 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index 4622fd6d911..fb818e20e39 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27 +YOSYS_VER := 0.27+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 7e58866.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 5f88c21.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From b58664d441764b4de1d01c4efcdd45094ba71535 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 7 Mar 2023 00:18:51 +0000 Subject: [PATCH 038/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 105042b0a88..0581cba83d2 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+0 +YOSYS_VER := 0.27+3 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 1af7d6121f697b60e6eaabcabd50c49c90d09402 Mon Sep 17 00:00:00 2001 From: Dag Lem Date: Wed, 8 Mar 2023 20:25:39 +0100 Subject: [PATCH 039/303] Added test for dynamic indexing within struct members --- tests/svtypes/struct_dynamic_range.sv | 67 +++++++++++++++++++++++++++ tests/svtypes/struct_dynamic_range.ys | 4 ++ 2 files changed, 71 insertions(+) create mode 100644 tests/svtypes/struct_dynamic_range.sv create mode 100644 tests/svtypes/struct_dynamic_range.ys diff --git a/tests/svtypes/struct_dynamic_range.sv b/tests/svtypes/struct_dynamic_range.sv new file mode 100644 index 00000000000..ce1f1467005 --- /dev/null +++ b/tests/svtypes/struct_dynamic_range.sv @@ -0,0 +1,67 @@ +module range_shift_mask( + input logic [2:0] addr_i, + input logic [7:0] data_i, + input logic [2:0] addr_o, + output logic [7:0] data_o +); + // (* nowrshmsk = 0 *) + struct packed { + logic [7:0] msb; + logic [0:3][7:0] data; + logic [7:0] lsb; + } s; + + always_comb begin + s = '1; + s.data[addr_i] = data_i; + data_o = s.data[addr_o]; + end +endmodule + +module range_case( + input logic [2:0] addr_i, + input logic [7:0] data_i, + input logic [2:0] addr_o, + output logic [7:0] data_o +); + // (* nowrshmsk = 1 *) + struct packed { + logic [7:0] msb; + logic [0:3][7:0] data; + logic [7:0] lsb; + } s; + + always_comb begin + s = '1; + s.data[addr_i] = data_i; + data_o = s.data[addr_o]; + end +endmodule + +module top; + logic [7:0] data_shift_mask1; + range_shift_mask range_shift_mask1(3'd1, 8'h7e, 3'd1, data_shift_mask1); + logic [7:0] data_shift_mask2; + range_shift_mask range_shift_mask2(3'd1, 8'h7e, 3'd2, data_shift_mask2); + logic [7:0] data_shift_mask3; + range_shift_mask range_shift_mask3(3'd1, 8'h7e, 3'd4, data_shift_mask3); + + always_comb begin + assert(data_shift_mask1 === 8'h7e); + assert(data_shift_mask2 === 8'hff); + assert(data_shift_mask3 === 8'hxx); + end + + logic [7:0] data_case1; + range_case range_case1(3'd1, 8'h7e, 3'd1, data_case1); + logic [7:0] data_case2; + range_case range_case2(3'd1, 8'h7e, 3'd2, data_case2); + logic [7:0] data_case3; + range_case range_case3(3'd1, 8'h7e, 3'd4, data_case3); + + always_comb begin + assert(data_case1 === 8'h7e); + assert(data_case2 === 8'hff); + assert(data_case3 === 8'hxx); + end +endmodule diff --git a/tests/svtypes/struct_dynamic_range.ys b/tests/svtypes/struct_dynamic_range.ys new file mode 100644 index 00000000000..d09e1924dec --- /dev/null +++ b/tests/svtypes/struct_dynamic_range.ys @@ -0,0 +1,4 @@ +read_verilog -sv struct_dynamic_range.sv +prep -top top +flatten +sat -enable_undef -verify -prove-asserts From baa3659ea54aed3a714ed2fcb8b5242f5332ef37 Mon Sep 17 00:00:00 2001 From: Stefan Riesenberger Date: Sat, 5 Nov 2022 10:05:08 +0100 Subject: [PATCH 040/303] ice40: Fix path delay definitions Parallel connections do not allow matching different bit widths. A full connection has to be used instead. Allows iverilog to parse the simulation library with hardware path delays enabled. --- techlibs/ice40/cells_sim.v | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index 52e8e2e3acc..8943815bff4 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -1674,7 +1674,7 @@ module SB_RAM40_4K ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLK, 133); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 - (posedge RCLK => (RDATA : 16'bx)) = 2146; + (posedge RCLK *> (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP @@ -1696,7 +1696,7 @@ module SB_RAM40_4K ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLK, 196); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 - (posedge RCLK => (RDATA : 16'bx)) = 3163; + (posedge RCLK *> (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U @@ -1718,7 +1718,7 @@ module SB_RAM40_4K ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLK, 252); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 - (posedge RCLK => (RDATA : 16'bx)) = 1179; + (posedge RCLK *> (RDATA : 16'bx)) = 1179; endspecify `endif endmodule @@ -1810,7 +1810,7 @@ module SB_RAM40_4KNR ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLK, 133); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 - (posedge RCLKN => (RDATA : 16'bx)) = 2146; + (posedge RCLKN *> (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP @@ -1832,7 +1832,7 @@ module SB_RAM40_4KNR ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLK, 196); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 - (posedge RCLKN => (RDATA : 16'bx)) = 3163; + (posedge RCLKN *> (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U @@ -1854,7 +1854,7 @@ module SB_RAM40_4KNR ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLK, 252); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 - (posedge RCLKN => (RDATA : 16'bx)) = 1179; + (posedge RCLKN *> (RDATA : 16'bx)) = 1179; endspecify `endif endmodule @@ -1946,7 +1946,7 @@ module SB_RAM40_4KNW ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLKN, 133); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 - (posedge RCLK => (RDATA : 16'bx)) = 2146; + (posedge RCLK *> (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP @@ -1968,7 +1968,7 @@ module SB_RAM40_4KNW ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLKN, 196); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 - (posedge RCLK => (RDATA : 16'bx)) = 3163; + (posedge RCLK *> (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U @@ -1990,7 +1990,7 @@ module SB_RAM40_4KNW ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLKN, 252); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 - (posedge RCLK => (RDATA : 16'bx)) = 1179; + (posedge RCLK *> (RDATA : 16'bx)) = 1179; endspecify `endif endmodule @@ -2082,7 +2082,7 @@ module SB_RAM40_4KNRNW ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L400 $setup(WE, posedge WCLKN, 133); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401 - (posedge RCLKN => (RDATA : 16'bx)) = 2146; + (posedge RCLKN *> (RDATA : 16'bx)) = 2146; endspecify `endif `ifdef ICE40_LP @@ -2104,7 +2104,7 @@ module SB_RAM40_4KNRNW ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L400 $setup(WE, posedge WCLKN, 196); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401 - (posedge RCLKN => (RDATA : 16'bx)) = 3163; + (posedge RCLKN *> (RDATA : 16'bx)) = 3163; endspecify `endif `ifdef ICE40_U @@ -2126,7 +2126,7 @@ module SB_RAM40_4KNRNW ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13025 $setup(WE, posedge WCLKN, 252); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026 - (posedge RCLKN => (RDATA : 16'bx)) = 1179; + (posedge RCLKN *> (RDATA : 16'bx)) = 1179; endspecify `endif endmodule @@ -2653,9 +2653,9 @@ module SB_SPRAM256KA ( // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13206 $setup(WREN, posedge CLOCK, 289); // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13207-L13222 - (posedge CLOCK => (DATAOUT : 16'bx)) = 1821; + (posedge CLOCK *> (DATAOUT : 16'bx)) = 1821; // https://github.com/YosysHQ/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13223-L13238 - (posedge SLEEP => (DATAOUT : 16'b0)) = 1099; + (posedge SLEEP *> (DATAOUT : 16'b0)) = 1099; endspecify `endif endmodule From 101d19bb6aef187653e240f5c6859e4d2efde1b5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 11 Mar 2023 00:15:30 +0000 Subject: [PATCH 041/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0581cba83d2..602e3edc90b 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+3 +YOSYS_VER := 0.27+9 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 390d1c583a4529bb190684ddbf18545e34c07663 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 14 Mar 2023 19:13:18 +0100 Subject: [PATCH 042/303] verific: Fix enum_values support and signed attribute values This uses the same constant parsing for enum_values and for attributes and extends it to handle signed values as those are used for enums that implicitly use the int type. --- frontends/verific/verific.cc | 67 ++++++++++++++++++------------------ tests/verific/enum_values.sv | 37 ++++++++++++++++++++ tests/verific/enum_values.ys | 19 ++++++++++ 3 files changed, 89 insertions(+), 34 deletions(-) create mode 100644 tests/verific/enum_values.sv create mode 100644 tests/verific/enum_values.ys diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index ab3e5542774..605dcdfb277 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -200,14 +200,6 @@ RTLIL::IdString VerificImporter::new_verific_id(Verific::DesignObj *obj) return s; } -static bool isNumber(const string& str) -{ - for (auto &c : str) { - if (std::isdigit(c) == 0) return false; - } - return true; -} - // When used as attributes or parameter values Verific constants come already processed. // - Real string values are already under quotes // - Numeric values with specified width are always converted to binary @@ -215,19 +207,37 @@ static bool isNumber(const string& str) // - There could be some internal values that are strings without quotes // so we check if value is all digits or not // -static const RTLIL::Const verific_const(const char *value) +// Note: For signed values, verific uses 'sb and decimal values can +// also be negative. +static const RTLIL::Const verific_const(const char *value, bool allow_string = true, bool output_signed = false) { + size_t found; + char *end; + int decimal; + bool is_signed = false; + RTLIL::Const c; std::string val = std::string(value); - if (val.size()>1 && val[0]=='\"' && val.back()=='\"') - return RTLIL::Const(val.substr(1,val.size()-2)); - else - if (val.find("'b") != std::string::npos) - return RTLIL::Const::from_string(val.substr(val.find("'b") + 2)); - else - if (isNumber(val)) - return RTLIL::Const(std::stoi(val),32); - else - return RTLIL::Const(val); + if (allow_string && val.size()>1 && val[0]=='\"' && val.back()=='\"') { + c = RTLIL::Const(val.substr(1,val.size()-2)); + } else if ((found = val.find("'sb")) != std::string::npos) { + is_signed = output_signed; + c = RTLIL::Const::from_string(val.substr(found + 3)); + } else if ((found = val.find("'b")) != std::string::npos) { + c = RTLIL::Const::from_string(val.substr(found + 2)); + } else if ((value[0] == '-' || (value[0] >= '0' && value[0] <= '9')) && + ((decimal = std::strtol(value, &end, 10)), !end[0])) { + is_signed = output_signed; + c = RTLIL::Const((int)decimal, 32); + } else if (allow_string) { + c = RTLIL::Const(val); + } else { + log_error("expected numeric constant but found '%s'", value); + } + + if (is_signed) + c.flags |= RTLIL::CONST_FLAG_SIGNED; + + return c; } void VerificImporter::import_attributes(dict &attributes, DesignObj *obj, Netlist *nl) @@ -263,21 +273,9 @@ void VerificImporter::import_attributes(dict &att const char *k, *v; FOREACH_MAP_ITEM(type_range->GetEnumIdMap(), mi, &k, &v) { if (nl->IsFromVerilog()) { - // Expect 'b - auto p = strchr(v, '\''); - if (p) { - if (*(p+1) != 'b') - p = nullptr; - else - for (auto q = p+2; *q != '\0'; q++) - if (*q != '0' && *q != '1' && *q != 'x' && *q != 'z') { - p = nullptr; - break; - } - } - if (p == nullptr) - log_error("Expected TypeRange value '%s' to be of form 'b.\n", v); - attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k)); + auto const value = verific_const(v, false); + + attributes.emplace(stringf("\\enum_value_%s", value.as_string().c_str()), RTLIL::escape_id(k)); } #ifdef VERIFIC_VHDL_SUPPORT else if (nl->IsFromVhdl()) { @@ -1467,6 +1465,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma import_attributes(wire->attributes, net, nl); break; } + import_attributes(wire->attributes, netbus, nl); RTLIL::Const initval = Const(State::Sx, GetSize(wire)); bool initval_valid = false; diff --git a/tests/verific/enum_values.sv b/tests/verific/enum_values.sv new file mode 100644 index 00000000000..69b53fd8e64 --- /dev/null +++ b/tests/verific/enum_values.sv @@ -0,0 +1,37 @@ +typedef enum { + WA, WB, WC, WD +} wide_state_t; + +typedef enum logic [1:0] { + A = 3, B = 0, C, D +} state_t; + +module top(input clk, output z); + + wide_state_t wide_state = WA; + + always @(posedge clk) begin + case (wide_state) + WA: wide_state <= WB; + WB: wide_state <= WC; + WC: wide_state <= WD; + default: wide_state <= WA; + endcase + end + + (* some_attribute = shortint'(42) *) + (* another_attribute = -1 *) + state_t state = A; + + always @(posedge clk) begin + case (state) + A: state <= B; + B: state <= C; + C: state <= D; + default: state <= A; + endcase + end + + assign z = (wide_state == WB) ^ (state == B); + +endmodule diff --git a/tests/verific/enum_values.ys b/tests/verific/enum_values.ys new file mode 100644 index 00000000000..f580ded8aed --- /dev/null +++ b/tests/verific/enum_values.ys @@ -0,0 +1,19 @@ +read -sv enum_values.sv +hierarchy -top top +printattrs a:* + +select -assert-count 1 a:some_attribute=16'd42 +# currently select doesn't support negative values in attributes +select -assert-count 1 a:another_attribute=32'hffffffff + +select -assert-count 1 top/state a:wiretype=\state_t %i +select -assert-count 1 top/state a:enum_value_11=\A %i +select -assert-count 1 top/state a:enum_value_00=\B %i +select -assert-count 1 top/state a:enum_value_01=\C %i +select -assert-count 1 top/state a:enum_value_10=\D %i + +select -assert-count 1 top/wide_state a:wiretype=\wide_state_t %i +select -assert-count 1 top/wide_state a:enum_value_00000000000000000000000000000000=\WA %i +select -assert-count 1 top/wide_state a:enum_value_00000000000000000000000000000001=\WB %i +select -assert-count 1 top/wide_state a:enum_value_00000000000000000000000000000010=\WC %i +select -assert-count 1 top/wide_state a:enum_value_00000000000000000000000000000011=\WD %i From ceef00c35e6417ba480ae40c3fe919b50e18e1be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Mar 2023 00:17:57 +0000 Subject: [PATCH 043/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 602e3edc90b..5337d0c8d70 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+9 +YOSYS_VER := 0.27+12 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 10589c57bfd0e5dd29c739e9d9db044cdb8ad8ed Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 17 Mar 2023 16:15:43 +0100 Subject: [PATCH 044/303] insert IO buffers for ECP5, off by default --- techlibs/ecp5/synth_ecp5.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index f2dc534f90e..82e23486844 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -100,6 +100,9 @@ struct SynthEcp5Pass : public ScriptPass log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\n"); log("\n"); + log(" -iopad\n"); + log(" insert IO buffers\n"); + log("\n"); log(" -nodsp\n"); log(" do not map multipliers to MULT18X18D\n"); log("\n"); @@ -115,7 +118,7 @@ struct SynthEcp5Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, nodsp, vpr, no_rw_check; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, vpr, no_rw_check; void clear_flags() override { @@ -135,6 +138,7 @@ struct SynthEcp5Pass : public ScriptPass abc2 = false; vpr = false; abc9 = false; + iopad = false; nodsp = false; no_rw_check = false; } @@ -223,6 +227,10 @@ struct SynthEcp5Pass : public ScriptPass abc9 = true; continue; } + if (args[argidx] == "-iopad") { + iopad = true; + continue; + } if (args[argidx] == "-nodsp") { nodsp = true; continue; @@ -319,6 +327,11 @@ struct SynthEcp5Pass : public ScriptPass run("techmap"); else run("techmap -map +/techmap.v -map +/ecp5/arith_map.v"); + if (help_mode || iopad) { + run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); + run("attrmvcp -attr src -attr LOC t:OB %x:+[O] t:OBZ %x:+[O] t:BB %x:+[B]"); + run("attrmvcp -attr src -attr LOC -driven t:IB %x:+[I]"); + } run("opt -fast"); if (retime || help_mode) run("abc -dff -D 1", "(only if -retime)"); From db367bd69ee4053f0846c55657b4680d62a1eb27 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 17 Mar 2023 16:45:03 +0100 Subject: [PATCH 045/303] Add iopad_external_pin to some basic io primitives --- techlibs/ecp5/cells_io.vh | 24 ++++++++++++------------ techlibs/ecp5/cells_sim.v | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/techlibs/ecp5/cells_io.vh b/techlibs/ecp5/cells_io.vh index 02e66e8a579..220460c4467 100644 --- a/techlibs/ecp5/cells_io.vh +++ b/techlibs/ecp5/cells_io.vh @@ -1,14 +1,14 @@ // 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 IB ((* iopad_external_pin *) input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPU ((* iopad_external_pin *) input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPD ((* iopad_external_pin *) input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module OB (input I, (* iopad_external_pin *) output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I)); endmodule +module OBZ (input I, T, (* iopad_external_pin *) output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPU(input I, T, (* iopad_external_pin *) output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPD(input I, T, (* iopad_external_pin *) 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 olvds (.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 +module BB (input I, T, output O, (* iopad_external_pin *) 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, (* iopad_external_pin *) 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, (* iopad_external_pin *) inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module ILVDS(input A, AN, (* iopad_external_pin *) output Z ); TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(A), .O(Z)); endmodule +module OLVDS(input A, (* iopad_external_pin *) output Z, output ZN); TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(Z), .I(A)); endmodule diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index f9d503deb7a..95f612cfa8b 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -378,6 +378,7 @@ endmodule // --------------------------------------- (* keep *) module TRELLIS_IO( + (* iopad_external_pin *) inout B, input I, input T, From 4d7e9e2e5d34a899d0ebff2b666b0fccfa9405bc Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 17 Mar 2023 17:23:26 +0100 Subject: [PATCH 046/303] Add additional iopad_external_pin attributes --- techlibs/ecp5/cells_bb.v | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v index fc352a52c5c..316671f3ce1 100644 --- a/techlibs/ecp5/cells_bb.v +++ b/techlibs/ecp5/cells_bb.v @@ -187,8 +187,16 @@ endmodule (* blackbox *) (* keep *) module JTAGG( - input TCK, TMS, TDI, JTDO2, JTDO1, - output TDO, JTDI, JTCK, JRTI2, JRTI1, + (* iopad_external_pin *) + input TCK, + (* iopad_external_pin *) + input TMS, + (* iopad_external_pin *) + input TDI, + input JTDO2, JTDO1, + (* iopad_external_pin *) + output TDO, + output JTDI, JTCK, JRTI2, JRTI1, output JSHIFT, JUPDATE, JRSTN, JCE2, JCE1 ); parameter ER1 = "ENABLED"; @@ -390,7 +398,14 @@ endmodule (* blackbox *) (* keep *) module DCUA( - input CH0_HDINP, CH1_HDINP, CH0_HDINN, CH1_HDINN, + (* iopad_external_pin *) + input CH0_HDINP, + (* iopad_external_pin *) + input CH1_HDINP, + (* iopad_external_pin *) + input CH0_HDINN, + (* iopad_external_pin *) + input CH1_HDINN, input D_TXBIT_CLKP_FROM_ND, D_TXBIT_CLKN_FROM_ND, D_SYNC_ND, D_TXPLL_LOL_FROM_ND, input CH0_RX_REFCLK, CH1_RX_REFCLK, CH0_FF_RXI_CLK, CH1_FF_RXI_CLK, CH0_FF_TXI_CLK, CH1_FF_TXI_CLK, CH0_FF_EBRD_CLK, CH1_FF_EBRD_CLK, input CH0_FF_TX_D_0, CH1_FF_TX_D_0, CH0_FF_TX_D_1, CH1_FF_TX_D_1, CH0_FF_TX_D_2, CH1_FF_TX_D_2, CH0_FF_TX_D_3, CH1_FF_TX_D_3, @@ -701,7 +716,10 @@ endmodule (* blackbox *) module EXTREFB ( - input REFCLKP, REFCLKN, + (* iopad_external_pin *) + input REFCLKP, + (* iopad_external_pin *) + input REFCLKN, output REFCLKO ); parameter REFCK_PWDNB = "0b0"; From ff9f1fb86e41eb59a92590efe03423f15a3d9cc0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 18 Mar 2023 18:11:50 +0100 Subject: [PATCH 047/303] Start unification effort for machxo2 and ecp5 --- techlibs/machxo2/Makefile.inc | 1 + techlibs/machxo2/cells_map.v | 8 ++----- techlibs/machxo2/cells_sim.v | 39 ++++++++++++++----------------- techlibs/machxo2/synth_machxo2.cc | 6 ++--- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc index f6aafbd2bde..acc32659da8 100644 --- a/techlibs/machxo2/Makefile.inc +++ b/techlibs/machxo2/Makefile.inc @@ -1,6 +1,7 @@ OBJS += techlibs/machxo2/synth_machxo2.o +$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/cells_io.vh)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 9c370f246aa..33328df5fe5 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -25,10 +25,6 @@ module \$lut (A, Y); endmodule // DFFs -module \$_DFF_P_ (input D, C, output Q); FACADE_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule +module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule -// IO- "$__" cells for the iopadmap pass. -module \$__FACADE_OUTPAD (input I, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(1'b0)); endmodule -module \$__FACADE_INPAD (input I, output O); FACADE_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.PAD(I), .O(O)); endmodule -module \$__FACADE_TOUTPAD (input I, T, output O); FACADE_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.PAD(O), .I(I), .T(T)); endmodule -module \$__FACADE_TINOUTPAD (input I, T, output O, inout B); FACADE_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.PAD(B), .I(I), .O(O), .T(T)); endmodule +`include "cells_io.vh" diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 82c9d8c4b83..86fc0cd8efd 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -11,7 +11,7 @@ module LUT4 #( assign Z = A ? s1[1] : s1[0]; endmodule -module FACADE_FF #( +module TRELLIS_FF #( parameter GSR = "ENABLED", parameter CEMUX = "1", parameter CLKMUX = "0", @@ -77,7 +77,7 @@ endmodule /* For consistency, input order matches TRELLIS_SLICE even though the BELs in prjtrellis were filled in clockwise order from bottom left. */ -module FACADE_SLICE #( +module TRELLIS_SLICE #( parameter MODE = "LOGIC", parameter GSR = "ENABLED", parameter SRMODE = "LSR_OVER_CE", @@ -139,33 +139,34 @@ module FACADE_SLICE #( endgenerate /* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F - outputs (in other words, feeds back into FACADE_SLICE). */ + outputs (in other words, feeds back into TRELLIS_SLICE). */ wire di0 = (REG0_SD == "1") ? DI0 : M0; wire di1 = (REG1_SD == "1") ? DI1 : M1; - FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), + TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET), .REGMODE(REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0)); - FACADE_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), + TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET), .REGMODE(REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); endmodule -module FACADE_IO #( +module TRELLIS_IO #( parameter DIR = "INPUT" ) ( - inout PAD, + (* iopad_external_pin *) + inout B, input I, T, output O ); generate if (DIR == "INPUT") begin - assign O = PAD; + assign O = B; end else if (DIR == "OUTPUT") begin - assign PAD = T ? 1'bz : I; + assign B = T ? 1'bz : I; end else if (DIR == "BIDIR") begin - assign PAD = T ? 1'bz : I; - assign O = PAD; + assign B = T ? 1'bz : I; + assign O = B; end else begin ERROR_UNKNOWN_IO_MODE error(); end @@ -320,14 +321,8 @@ module DP8KC( parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; endmodule -// IO- "$__" cells for the iopadmap pass. These are temporary cells not meant -// to be instantiated by the end user. They are required in this file for -// attrmvcp to work. -(* blackbox *) -module \$__FACADE_OUTPAD (input I, output O); endmodule -(* blackbox *) -module \$__FACADE_INPAD (input I, output O); endmodule -(* blackbox *) -module \$__FACADE_TOUTPAD (input I, T, output O); endmodule -(* blackbox *) -module \$__FACADE_TINOUTPAD (input I, T, output O, inout B); endmodule +`ifndef NO_INCLUDES + +`include "cells_io.vh" + +`endif diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index dbd01bbfd4d..4ca6351bdfd 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -214,9 +214,9 @@ struct SynthMachXO2Pass : public ScriptPass { if (!noiopad || help_mode) { - run("iopadmap -bits -outpad $__FACADE_OUTPAD I:O -inpad $__FACADE_INPAD O:I -toutpad $__FACADE_TOUTPAD ~T:I:O -tinoutpad $__FACADE_TINOUTPAD ~T:O:I:B A:top"); - run("attrmvcp -attr src -attr LOC t:$__FACADE_OUTPAD %x:+[O] t:$__FACADE_TOUTPAD %x:+[O] t:$__FACADE_TINOUTPAD %x:+[B]"); - run("attrmvcp -attr src -attr LOC -driven t:$__FACADE_INPAD %x:+[I]"); + run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); + run("attrmvcp -attr src -attr LOC t:OB %x:+[O] t:OBZ %x:+[O] t:BB %x:+[B]"); + run("attrmvcp -attr src -attr LOC -driven t:IB %x:+[I]"); } } From 61da330a38812a0a394131f9f434c736cb2239cf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 18 Mar 2023 18:12:02 +0100 Subject: [PATCH 048/303] Update tests --- tests/arch/machxo2/add_sub.ys | 2 +- tests/arch/machxo2/dffs.ys | 8 ++++---- tests/arch/machxo2/fsm.ys | 4 ++-- tests/arch/machxo2/logic.ys | 2 +- tests/arch/machxo2/mux.ys | 8 ++++---- tests/arch/machxo2/shifter.ys | 4 ++-- tests/arch/machxo2/tribuf.ys | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/arch/machxo2/add_sub.ys b/tests/arch/machxo2/add_sub.ys index d9497b8182b..97ee90fbbe2 100644 --- a/tests/arch/machxo2/add_sub.ys +++ b/tests/arch/machxo2/add_sub.ys @@ -5,4 +5,4 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 10 t:LUT4 -select -assert-none t:LUT4 t:FACADE_IO %% t:* %D +select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 83a79a9d6b3..29dcafe2383 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -6,8 +6,8 @@ proc equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module -select -assert-count 1 t:FACADE_FF -select -assert-none t:FACADE_FF t:FACADE_IO %% t:* %D +select -assert-count 1 t:TRELLIS_FF +select -assert-none t:TRELLIS_FF t:TRELLIS_IO %% t:* %D design -load read hierarchy -top dffe @@ -15,5 +15,5 @@ proc equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module -select -assert-count 2 t:FACADE_FF t:LUT4 -select -assert-none t:FACADE_FF t:LUT4 t:FACADE_IO %% t:* %D +select -assert-count 2 t:TRELLIS_FF t:LUT4 +select -assert-none t:TRELLIS_FF t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index 847a61161b0..a61357fcdd2 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -11,5 +11,5 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd fsm # Constrain all select calls below inside the top module select -assert-max 16 t:LUT4 -select -assert-count 6 t:FACADE_FF -select -assert-none t:FACADE_FF t:LUT4 t:FACADE_IO %% t:* %D +select -assert-count 6 t:TRELLIS_FF +select -assert-none t:TRELLIS_FF t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys index bf93ab128ae..0cf57310c81 100644 --- a/tests/arch/machxo2/logic.ys +++ b/tests/arch/machxo2/logic.ys @@ -5,4 +5,4 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 9 t:LUT4 -select -assert-none t:LUT4 t:FACADE_IO %% t:* %D +select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 7b7e62d4caa..27bffbe63aa 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -7,7 +7,7 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT4 -select -assert-none t:LUT4 t:FACADE_IO %% t:* %D +select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 @@ -17,7 +17,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux4 # Constrain all select calls below inside the top module select -assert-count 2 t:LUT4 -select -assert-none t:LUT4 t:FACADE_IO %% t:* %D +select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 @@ -27,7 +27,7 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux8 # Constrain all select calls below inside the top module select -assert-count 5 t:LUT4 -select -assert-none t:LUT4 t:FACADE_IO %% t:* %D +select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 @@ -37,4 +37,4 @@ design -load postopt # load the post-opt design (otherwise equiv_opt loads the p cd mux16 # Constrain all select calls below inside the top module select -assert-max 12 t:LUT4 -select -assert-none t:LUT4 t:FACADE_IO %% t:* %D +select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/shifter.ys b/tests/arch/machxo2/shifter.ys index 87fdab0fa36..bff881fb734 100644 --- a/tests/arch/machxo2/shifter.ys +++ b/tests/arch/machxo2/shifter.ys @@ -6,5 +6,5 @@ equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 8 t:FACADE_FF -select -assert-none t:FACADE_FF t:FACADE_IO %% t:* %D +select -assert-count 8 t:TRELLIS_FF +select -assert-none t:TRELLIS_FF t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys index fce342e183f..840979439f8 100644 --- a/tests/arch/machxo2/tribuf.ys +++ b/tests/arch/machxo2/tribuf.ys @@ -5,6 +5,6 @@ flatten equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module -select -assert-count 3 t:FACADE_IO +select -assert-count 3 t:TRELLIS_IO select -assert-count 1 t:LUT4 -select -assert-none t:FACADE_IO t:LUT4 %% t:* %D +select -assert-none t:TRELLIS_IO t:LUT4 %% t:* %D From fb1c2be76ba065a3da04f279b11e1ed2e59c75c5 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Mon, 20 Mar 2023 12:50:14 +0100 Subject: [PATCH 049/303] verilog: Support void functions The difference between void functions and tasks is that always_comb's implicit sensitivity list behaves as if functions were inlined, but ignores signals read only in tasks. This only matters for event based simulation, and for synthesis we can treat a void function like a task. --- frontends/verilog/verilog_lexer.l | 1 + frontends/verilog/verilog_parser.y | 19 ++++++++++++++- tests/verilog/void_func.ys | 37 ++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/void_func.ys diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 958809319ef..24998666828 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -276,6 +276,7 @@ TIME_SCALE_SUFFIX [munpf]?s "byte" { SV_KEYWORD(TOK_BYTE); } "shortint" { SV_KEYWORD(TOK_SHORTINT); } "longint" { SV_KEYWORD(TOK_LONGINT); } +"void" { SV_KEYWORD(TOK_VOID); } "eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); } "s_eventually" { if (formal_mode) return TOK_EVENTUALLY; SV_KEYWORD(TOK_EVENTUALLY); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 87b50438a5f..96413afb0b6 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -372,7 +372,7 @@ static void rewriteGenForDeclInit(AstNode *loop) %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF %token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY -%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_LONGINT TOK_UNION +%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_LONGINT TOK_VOID TOK_UNION %token TOK_BIT_OR_ASSIGN TOK_BIT_AND_ASSIGN TOK_BIT_XOR_ASSIGN TOK_ADD_ASSIGN %token TOK_SUB_ASSIGN TOK_DIV_ASSIGN TOK_MOD_ASSIGN TOK_MUL_ASSIGN %token TOK_SHL_ASSIGN TOK_SHR_ASSIGN TOK_SSHL_ASSIGN TOK_SSHR_ASSIGN @@ -1020,6 +1020,23 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | + attr TOK_FUNCTION opt_automatic TOK_VOID TOK_ID { + // The difference between void functions and tasks is that + // always_comb's implicit sensitivity list behaves as if functions were + // inlined, but ignores signals read only in tasks. This only matters + // for event based simulation, and for synthesis we can treat a void + // function like a task. + current_function_or_task = new AstNode(AST_TASK); + current_function_or_task->str = *$5; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + ast_stack.push_back(current_function_or_task); + current_function_or_task_port_id = 1; + delete $5; + } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION { + current_function_or_task = NULL; + ast_stack.pop_back(); + } | attr TOK_FUNCTION opt_automatic func_return_type TOK_ID { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$5; diff --git a/tests/verilog/void_func.ys b/tests/verilog/void_func.ys new file mode 100644 index 00000000000..6fb7b4b56e7 --- /dev/null +++ b/tests/verilog/void_func.ys @@ -0,0 +1,37 @@ +read_verilog -sv < Date: Tue, 21 Mar 2023 00:15:46 +0000 Subject: [PATCH 050/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5337d0c8d70..52d02a1fc15 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+12 +YOSYS_VER := 0.27+20 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f35bdaa5278b408e94ac8c97a06c3f7f0fe1773a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 21 Mar 2023 08:53:22 +0100 Subject: [PATCH 051/303] Update Xilinx cell definitions, fixes #3699 --- techlibs/xilinx/cells_sim.v | 11 ++++++++--- techlibs/xilinx/cells_xtra.py | 2 +- techlibs/xilinx/cells_xtra.v | 9 +++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index e6e15b16ead..8b0c913aa6b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -33,8 +33,12 @@ module IBUF( output O, (* iopad_external_pin *) input I); - parameter IOSTANDARD = "default"; - parameter IBUF_LOW_PWR = 0; + parameter CCIO_EN = "TRUE"; + parameter CAPACITANCE = "DONT_CARE"; + parameter IBUF_DELAY_VALUE = "0"; + parameter IBUF_LOW_PWR = "TRUE"; + parameter IFD_DELAY_VALUE = "AUTO"; + parameter IOSTANDARD = "DEFAULT"; assign O = I; specify (I => O) = 0; @@ -56,7 +60,8 @@ module OBUF( (* iopad_external_pin *) output O, input I); - parameter IOSTANDARD = "default"; + parameter CAPACITANCE = "DONT_CARE"; + parameter IOSTANDARD = "DEFAULT"; parameter DRIVE = 12; parameter SLEW = "SLOW"; assign O = I; diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py index 2630c7a0f64..08fe6f35e38 100644 --- a/techlibs/xilinx/cells_xtra.py +++ b/techlibs/xilinx/cells_xtra.py @@ -706,7 +706,7 @@ def xtract_cell_decl(cell, dirs, outf): if __name__ == '__main__': parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from ISE and Vivado.') - parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2018.1') + parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2022.2') parser.add_argument('ise_dir', nargs='?', default='/opt/Xilinx/ISE/14.7') args = parser.parse_args() diff --git a/techlibs/xilinx/cells_xtra.v b/techlibs/xilinx/cells_xtra.v index aae0d3ee5d4..8dc74b16ea2 100644 --- a/techlibs/xilinx/cells_xtra.v +++ b/techlibs/xilinx/cells_xtra.v @@ -7550,10 +7550,12 @@ module IBUF_ANALOG (...); endmodule module IBUFE3 (...); + parameter CCIO_EN = "TRUE"; parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; - parameter USE_IBUFDISABLE = "FALSE"; + parameter SIM_DEVICE = "ULTRASCALE"; parameter integer SIM_INPUT_BUFFER_OFFSET = 0; + parameter USE_IBUFDISABLE = "FALSE"; output O; (* iopad_external_pin *) input I; @@ -7760,8 +7762,9 @@ module IOBUFE3 (...); parameter integer DRIVE = 12; parameter IBUF_LOW_PWR = "TRUE"; parameter IOSTANDARD = "DEFAULT"; - parameter USE_IBUFDISABLE = "FALSE"; + parameter SIM_DEVICE = "ULTRASCALE"; parameter integer SIM_INPUT_BUFFER_OFFSET = 0; + parameter USE_IBUFDISABLE = "FALSE"; output O; (* iopad_external_pin *) inout IO; @@ -19721,6 +19724,7 @@ module HSADC (...); endmodule module RFDAC (...); + parameter integer LD_DEVICE = 0; parameter integer OPT_CLK_DIST = 0; parameter SIM_DEVICE = "ULTRASCALE_PLUS"; parameter integer XPA_ACTIVE_DUTYCYCLE = 100; @@ -19784,6 +19788,7 @@ module RFDAC (...); endmodule module RFADC (...); + parameter integer LD_DEVICE = 0; parameter integer OPT_ANALOG = 0; parameter integer OPT_CLK_DIST = 0; parameter SIM_DEVICE = "ULTRASCALE_PLUS"; From 53c0a6b780199dc56348916acf7c00e30f65e1ec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 00:16:02 +0000 Subject: [PATCH 052/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 52d02a1fc15..c38495fe2dd 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+20 +YOSYS_VER := 0.27+22 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f94f544b502c9de88807dec8205417628fe38202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 5 Apr 2023 12:36:56 +0200 Subject: [PATCH 053/303] Fix the python generator for a bunch of const cases Makes the below show up in the binding. .def("c_str", &IdString::c_str) .def("chunks", &SigSpec::chunks) .def("bits", &SigSpec::bits) .def("at", &SigSpec::at) .def("getPort", &Cell::getPort) .def("connections", &Cell::connections) .def("getParam", &Cell::getParam) .def("connections", &Module::connections) def("log_signal", YOSYS_PYTHON::log_signal); def("log_signal", YOSYS_PYTHON::log_signal); def("log_const", YOSYS_PYTHON::log_const); def("log_const", YOSYS_PYTHON::log_const); def("log_id", YOSYS_PYTHON::log_id); --- misc/py_wrap_generator.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index 4d9a6011326..ecf02e60166 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -178,6 +178,8 @@ def from_string(str_def, containing_file, line_number): t.cont = None t.attr_type = attr_types.default if str_def.find("<") != -1:# and str_def.find("<") < str_def.find(" "): + str_def = str_def.replace("const ", "") + candidate = WContainer.from_string(str_def, containing_file, line_number) if candidate == None: return None @@ -203,8 +205,12 @@ def from_string(str_def, containing_file, line_number): prefix = "" + if str.startswith(str_def, "const "): + if "char_p" in str_def: + prefix = "const " + str_def = str_def[6:] if str.startswith(str_def, "unsigned "): - prefix = "unsigned " + prefix = "unsigned " + prefix str_def = str_def[9:] while str.startswith(str_def, "long "): prefix= "long " + prefix @@ -1285,7 +1291,7 @@ def from_string(str_def, containing_file, class_, line_number, namespace): prefix = "" i = 0 for part in parts: - if part in ["unsigned", "long", "short"]: + if part in ["unsigned", "long", "short", "const"]: prefix += part + " " i += 1 else: From bd063381727a182b5d9f155483d5707fb6ce7e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 5 Apr 2023 13:33:18 +0200 Subject: [PATCH 054/303] py_wrap_generator: Fix handling of method name collisions If two methods have the same signature but for qualifiers the Python binding doesn't care about ('const'), do not generate a mangled name for the method. Fixes .def("wire__YOSYS_NAMESPACE_RTLIL_IdString", &Module::wire__YOSYS_NAMESPACE_RTLIL_IdString) .def("cell__YOSYS_NAMESPACE_RTLIL_IdString", &Module::cell__YOSYS_NAMESPACE_RTLIL_IdString) in the output after the previous change. --- misc/py_wrap_generator.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/misc/py_wrap_generator.py b/misc/py_wrap_generator.py index ecf02e60166..7fe78e03a58 100644 --- a/misc/py_wrap_generator.py +++ b/misc/py_wrap_generator.py @@ -1367,10 +1367,17 @@ def from_string(str_def, containing_file, class_, line_number, namespace): func.args.append(parsed) return func + @property + def mangled_name(self): + mangled_typename = lambda code: code.replace("::", "_").replace("<","_").replace(">","_") \ + .replace(" ","").replace("*","").replace(",","") + + return self.name + "".join( + f"__{mangled_typename(arg.wtype.gen_text_cpp())}" for arg in self.args + ) + def gen_alias(self): - self.alias = self.name - for arg in self.args: - self.alias += "__" + arg.wtype.gen_text_cpp().replace("::", "_").replace("<","_").replace(">","_").replace(" ","").replace("*","").replace(",","") + self.alias = self.mangled_name def gen_decl(self): if self.duplicate: @@ -2196,12 +2203,15 @@ def clean_duplicates(): for fun in class_.found_funs: if fun.gen_decl_hash_py() in known_decls: debug("Multiple declarations of " + fun.gen_decl_hash_py(),3) + other = known_decls[fun.gen_decl_hash_py()] - other.gen_alias() - fun.gen_alias() - if fun.gen_decl_hash_py() == other.gen_decl_hash_py(): + if fun.mangled_name == other.mangled_name: fun.duplicate = True debug("Disabled \"" + fun.gen_decl_hash_py() + "\"", 3) + continue + + other.gen_alias() + fun.gen_alias() else: known_decls[fun.gen_decl_hash_py()] = fun known_decls = [] From 6e12da3956a1960ce62ba389b10f02ef21a43291 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 31 Mar 2023 13:36:36 +0200 Subject: [PATCH 055/303] machxo2: Initial support for carry chains (CCU2D) --- techlibs/machxo2/Makefile.inc | 1 + techlibs/machxo2/arith_map.v | 90 +++++++++++++++++++++++++++++++ techlibs/machxo2/cells_sim.v | 20 +++++++ techlibs/machxo2/synth_machxo2.cc | 21 ++++++-- 4 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 techlibs/machxo2/arith_map.v diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc index acc32659da8..35fb79fc54a 100644 --- a/techlibs/machxo2/Makefile.inc +++ b/techlibs/machxo2/Makefile.inc @@ -9,3 +9,4 @@ $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams.txt)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams_map.v)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams.txt)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams_map.v)) +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/arith_map.v)) diff --git a/techlibs/machxo2/arith_map.v b/techlibs/machxo2/arith_map.v new file mode 100644 index 00000000000..ab4a6b1da6c --- /dev/null +++ b/techlibs/machxo2/arith_map.v @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_ecp5_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; + + (* force_downto *) + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + function integer round_up2; + input integer N; + begin + round_up2 = ((N + 1) / 2) * 2; + end + endfunction + + localparam Y_WIDTH2 = round_up2(Y_WIDTH); + + (* force_downto *) + wire [Y_WIDTH2-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BX = B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] C = {CO, CI}; + (* force_downto *) + wire [Y_WIDTH2-1:0] FCO, Y1; + + genvar i; + generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice + CCU2D #( + .INIT0(16'b0101_1010_1001_0110), + .INIT1(16'b0101_1010_1001_0110), + .INJECT1_0("NO"), + .INJECT1_1("NO") + ) ccu2d_i ( + .CIN(C[i]), + .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b0), + .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b0), + .S0(Y[i]), .S1(Y1[i]), + .COUT(FCO[i]) + ); + + assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); + if (i+1 < Y_WIDTH) begin + assign CO[i+1] = FCO[i]; + assign Y[i+1] = Y1[i]; + end + end endgenerate + + assign X = AA ^ BB; +endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 86fc0cd8efd..f69c6d1e9bd 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -255,6 +255,26 @@ module DPR16X4C ( assign DO = ram[RAD]; endmodule +// --------------------------------------- +(* blackbox *) +module CCU2D ( + CIN, + A0, B0, C0, D0, + A1, B1, C1, D1, + S0, S1, COUT +); + +input CIN; +input A0, B0, C0, D0; +input A1, B1, C1, D1; +output S0, S1, COUT; + +parameter [15:0] INIT0 = 16'h0000; +parameter [15:0] INIT1 = 16'h0000; +parameter INJECT1_0 = "YES"; +parameter INJECT1_1 = "YES"; +endmodule + (* blackbox *) module DP8KC( input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 4ca6351bdfd..3008527e09f 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -69,6 +69,9 @@ struct SynthMachXO2Pass : public ScriptPass log(" -noiopad\n"); log(" do not insert IO buffers\n"); log("\n"); + log(" -ccu2\n"); + log(" use CCU2 cells in output netlist\n"); + log("\n"); log(" -vpr\n"); log(" generate an output netlist (and BLIF file) suitable for VPR\n"); log(" (this feature is experimental and incomplete)\n"); @@ -80,7 +83,7 @@ struct SynthMachXO2Pass : public ScriptPass } string top_opt, blif_file, edif_file, json_file; - bool nobram, nolutram, flatten, vpr, noiopad; + bool ccu2, nobram, nolutram, flatten, vpr, noiopad; void clear_flags() override { @@ -88,6 +91,7 @@ struct SynthMachXO2Pass : public ScriptPass blif_file = ""; edif_file = ""; json_file = ""; + ccu2 = false; nobram = false; nolutram = false; flatten = true; @@ -147,6 +151,10 @@ struct SynthMachXO2Pass : public ScriptPass noiopad = true; continue; } + if (args[argidx] == "-ccu2") { + ccu2 = true; + continue; + } if (args[argidx] == "-vpr") { vpr = true; continue; @@ -204,14 +212,17 @@ struct SynthMachXO2Pass : public ScriptPass if (check_label("fine")) { + run("opt -fast -mux_undef -undriven -fine"); run("memory_map"); - run("opt -full"); - run("techmap -map +/techmap.v"); - run("opt -fast"); + run("opt -undriven -fine"); } - if (check_label("map_ios", "(unless -noiopad)")) + if (check_label("map_gates", "(unless -noiopad)")) { + if (!ccu2) + run("techmap"); + else + run("techmap -map +/techmap.v -map +/machxo2/arith_map.v"); if (!noiopad || help_mode) { run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); From 6e4c1675e725983da8a11be0eda0b2de47a9f522 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 31 Mar 2023 15:46:35 +0200 Subject: [PATCH 056/303] Generate TRELLIS_DPR16X4 for lutram --- techlibs/machxo2/cells_sim.v | 44 ++++++++++++++++++++++++++++++++++ techlibs/machxo2/lutrams.txt | 6 ++--- techlibs/machxo2/lutrams_map.v | 43 +++++++++++++++++++-------------- 3 files changed, 72 insertions(+), 21 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index f69c6d1e9bd..1e920329cb9 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -200,6 +200,50 @@ module DCMA ( ); endmodule +(* abc9_box, lib_whitebox *) +module TRELLIS_DPR16X4 ( + input [3:0] DI, + input [3:0] WAD, + input WRE, + input WCK, + input [3:0] RAD, + output [3:0] DO +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter [63:0] INITVAL = 64'h0000000000000000; + + reg [3:0] mem[15:0]; + + integer i; + initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= INITVAL[4*i +: 4]; + end + + wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; + + reg muxwre; + always @(*) + case (WREMUX) + "1": muxwre = 1'b1; + "0": muxwre = 1'b0; + "INV": muxwre = ~WRE; + default: muxwre = WRE; + endcase + + always @(posedge muxwck) + if (muxwre) + mem[WAD] <= DI; + + assign DO = mem[RAD]; + + specify + // TODO + (RAD *> DO) = 0; + endspecify +endmodule + (* abc9_box, lib_whitebox *) module DPR16X4C ( input [3:0] DI, diff --git a/techlibs/machxo2/lutrams.txt b/techlibs/machxo2/lutrams.txt index c6b0b6c4560..ea42d4fcb5e 100644 --- a/techlibs/machxo2/lutrams.txt +++ b/techlibs/machxo2/lutrams.txt @@ -1,11 +1,11 @@ -ram distributed $__DPR16X4C_ { +ram distributed $__TRELLIS_DPR16X4_ { abits 4; width 4; cost 4; - init no_undef; + init any; prune_rom; port sw "W" { - clock posedge; + clock anyedge; } port ar "R" { } diff --git a/techlibs/machxo2/lutrams_map.v b/techlibs/machxo2/lutrams_map.v index b55253fb868..3cb325f041e 100644 --- a/techlibs/machxo2/lutrams_map.v +++ b/techlibs/machxo2/lutrams_map.v @@ -1,23 +1,30 @@ -module $__DPR16X4C_ (...); - parameter INIT = 64'b0; +module $__TRELLIS_DPR16X4_(...); - input PORT_W_CLK; - input [3:0] PORT_W_ADDR; - input [3:0] PORT_W_WR_DATA; - input PORT_W_WR_EN; +parameter INIT = 64'bx; +parameter PORT_W_CLK_POL = 1; - input [3:0] PORT_R_ADDR; - output [3:0] PORT_R_RD_DATA; +input PORT_W_CLK; +input [3:0] PORT_W_ADDR; +input [3:0] PORT_W_WR_DATA; +input PORT_W_WR_EN; - DPR16X4C #( - .INITVAL($sformatf("0x%08x", INIT)) - ) _TECHMAP_REPLACE_ ( - .RAD(PORT_R_ADDR), - .DO(PORT_R_RD_DATA), +input [3:0] PORT_R_ADDR; +output [3:0] PORT_R_RD_DATA; + +localparam WCKMUX = PORT_W_CLK_POL ? "WCK" : "INV"; + +TRELLIS_DPR16X4 #( + .INITVAL(INIT), + .WCKMUX(WCKMUX), + .WREMUX("WRE") +) _TECHMAP_REPLACE_ ( + .RAD(PORT_R_ADDR), + .DO(PORT_R_RD_DATA), + + .WAD(PORT_W_ADDR), + .DI(PORT_W_WR_DATA), + .WCK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); - .WAD(PORT_W_ADDR), - .DI(PORT_W_WR_DATA), - .WCK(PORT_W_CLK), - .WRE(PORT_W_WR_EN) - ); endmodule From d5a405d3b4c6ab364ec5c9372502a94b84e2fcb1 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 3 Apr 2023 12:58:29 +0200 Subject: [PATCH 057/303] Added proper simulation model for CCU2D --- techlibs/machxo2/cells_sim.v | 50 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 1e920329cb9..2075c05195e 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -1,3 +1,9 @@ +module LUT2(input A, B, output Z); + parameter [3:0] INIT = 4'h0; + wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0]; + assign Z = A ? s1[1] : s1[0]; +endmodule + module LUT4 #( parameter [15:0] INIT = 0 ) ( @@ -300,23 +306,37 @@ module DPR16X4C ( endmodule // --------------------------------------- -(* blackbox *) +(* lib_whitebox *) module CCU2D ( - CIN, - A0, B0, C0, D0, - A1, B1, C1, D1, - S0, S1, COUT + input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + output COUT ); - -input CIN; -input A0, B0, C0, D0; -input A1, B1, C1, D1; -output S0, S1, COUT; - -parameter [15:0] INIT0 = 16'h0000; -parameter [15:0] INIT1 = 16'h0000; -parameter INJECT1_0 = "YES"; -parameter INJECT1_1 = "YES"; + parameter [15:0] INIT0 = 16'h0000; + parameter [15:0] INIT1 = 16'h0000; + parameter INJECT1_0 = "YES"; + parameter INJECT1_1 = "YES"; + + // First half + wire LUT4_0, LUT2_0; + LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); + LUT2 #(.INIT(~INIT0[15:12])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); + wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; + assign S0 = LUT4_0 ^ gated_cin_0; + + wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; + wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); + + // Second half + wire LUT4_1, LUT2_1; + LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); + LUT2 #(.INIT(~INIT1[15:12])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); + wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; + assign S1 = LUT4_1 ^ gated_cin_1; + + wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; + assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); endmodule (* blackbox *) From 9e9fae19662b87c773f435849ea6f2591e9e8900 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 4 Apr 2023 10:56:17 +0200 Subject: [PATCH 058/303] Add more DFF types --- techlibs/machxo2/Makefile.inc | 5 +- techlibs/machxo2/cells_map.v | 93 ++++++++++++++++++++++++++++++- techlibs/machxo2/lutrams.txt | 12 ---- techlibs/machxo2/lutrams_map.v | 30 ---------- techlibs/machxo2/synth_machxo2.cc | 10 +++- 5 files changed, 102 insertions(+), 48 deletions(-) delete mode 100644 techlibs/machxo2/lutrams.txt delete mode 100644 techlibs/machxo2/lutrams_map.v diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc index 35fb79fc54a..774b357a253 100644 --- a/techlibs/machxo2/Makefile.inc +++ b/techlibs/machxo2/Makefile.inc @@ -5,8 +5,9 @@ $(eval $(call add_share_file,share/machxo2,techlibs/ecp5/cells_io.vh)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams.txt)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/lutrams_map.v)) +$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams.txt)) +$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams_map.v)) + $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams.txt)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams_map.v)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/arith_map.v)) diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v index 33328df5fe5..22994a634df 100644 --- a/techlibs/machxo2/cells_map.v +++ b/techlibs/machxo2/cells_map.v @@ -1,3 +1,93 @@ +module \$_DFF_N_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_P_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + module \$lut (A, Y); parameter WIDTH = 0; parameter LUT = 0; @@ -24,7 +114,4 @@ module \$lut (A, Y); LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .Z(Y)); endmodule -// DFFs -module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule - `include "cells_io.vh" diff --git a/techlibs/machxo2/lutrams.txt b/techlibs/machxo2/lutrams.txt deleted file mode 100644 index ea42d4fcb5e..00000000000 --- a/techlibs/machxo2/lutrams.txt +++ /dev/null @@ -1,12 +0,0 @@ -ram distributed $__TRELLIS_DPR16X4_ { - abits 4; - width 4; - cost 4; - init any; - prune_rom; - port sw "W" { - clock anyedge; - } - port ar "R" { - } -} diff --git a/techlibs/machxo2/lutrams_map.v b/techlibs/machxo2/lutrams_map.v deleted file mode 100644 index 3cb325f041e..00000000000 --- a/techlibs/machxo2/lutrams_map.v +++ /dev/null @@ -1,30 +0,0 @@ -module $__TRELLIS_DPR16X4_(...); - -parameter INIT = 64'bx; -parameter PORT_W_CLK_POL = 1; - -input PORT_W_CLK; -input [3:0] PORT_W_ADDR; -input [3:0] PORT_W_WR_DATA; -input PORT_W_WR_EN; - -input [3:0] PORT_R_ADDR; -output [3:0] PORT_R_RD_DATA; - -localparam WCKMUX = PORT_W_CLK_POL ? "WCK" : "INV"; - -TRELLIS_DPR16X4 #( - .INITVAL(INIT), - .WCKMUX(WCKMUX), - .WREMUX("WRE") -) _TECHMAP_REPLACE_ ( - .RAD(PORT_R_ADDR), - .DO(PORT_R_RD_DATA), - - .WAD(PORT_W_ADDR), - .DI(PORT_W_WR_DATA), - .WCK(PORT_W_CLK), - .WRE(PORT_W_WR_EN) -); - -endmodule diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 3008527e09f..fb4d7b9d061 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -233,7 +233,15 @@ struct SynthMachXO2Pass : public ScriptPass if (check_label("map_ffs")) { - run("dfflegalize -cell $_DFF_P_ 0"); + run("opt_clean"); + std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r"; + run("dfflegalize" + dfflegalize_args); + run("techmap -D NO_LUT -map +/machxo2/cells_map.v"); + run("opt_expr -undriven -mux_undef"); + run("simplemap"); + run("ecp5_gsr"); + run("attrmvcp -copy -attr syn_useioff"); + run("opt_clean"); } if (check_label("map_luts")) From 54d313efc3bc6745bea6752830de65107d1d8f2a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 4 Apr 2023 10:56:28 +0200 Subject: [PATCH 059/303] add test for CCU2D --- tests/arch/machxo2/counter.ys | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/arch/machxo2/counter.ys diff --git a/tests/arch/machxo2/counter.ys b/tests/arch/machxo2/counter.ys new file mode 100644 index 00000000000..54ee80066ff --- /dev/null +++ b/tests/arch/machxo2/counter.ys @@ -0,0 +1,10 @@ +read_verilog ../common/counter.v +hierarchy -top top +proc +flatten +equiv_opt -assert -multiclock -map +/machxo2/cells_sim.v synth_machxo2 -ccu2 -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 4 t:CCU2D +select -assert-count 8 t:TRELLIS_FF +select -assert-none t:CCU2D t:TRELLIS_FF %% t:* %D From 0f5e7c244df1bb0d4b41bd54d4d5791e653ed448 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 4 Apr 2023 11:18:24 +0200 Subject: [PATCH 060/303] add additional dff and lutram tests --- tests/arch/machxo2/adffs.ys | 40 ++++++++++++++++++++++++++++++++++++ tests/arch/machxo2/lutram.ys | 17 +++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/arch/machxo2/adffs.ys create mode 100644 tests/arch/machxo2/lutram.ys diff --git a/tests/arch/machxo2/adffs.ys b/tests/arch/machxo2/adffs.ys new file mode 100644 index 00000000000..a9f8980c6e4 --- /dev/null +++ b/tests/arch/machxo2/adffs.ys @@ -0,0 +1,40 @@ +read_verilog ../common/adffs.v +design -save read + +hierarchy -top adff +proc +equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adff # Constrain all select calls below inside the top module +select -assert-count 1 t:TRELLIS_FF +select -assert-none t:TRELLIS_FF %% t:* %D + +design -load read +hierarchy -top adffn +proc +equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd adffn # Constrain all select calls below inside the top module +select -assert-count 1 t:TRELLIS_FF +select -assert-count 1 t:LUT4 +select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D + +design -load read +hierarchy -top dffs +proc +equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd dffs # Constrain all select calls below inside the top module +select -assert-count 1 t:TRELLIS_FF +select -assert-count 1 t:LUT4 +select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D + +design -load read +hierarchy -top ndffnr +proc +equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd ndffnr # Constrain all select calls below inside the top module +select -assert-count 1 t:TRELLIS_FF +select -assert-count 1 t:LUT4 +select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys new file mode 100644 index 00000000000..dc6b86fd349 --- /dev/null +++ b/tests/arch/machxo2/lutram.ys @@ -0,0 +1,17 @@ +read_verilog ../common/lutram.v +hierarchy -top lutram_1w1r +proc +memory -nomap +equiv_opt -run :prove -map +/machxo2/cells_sim.v synth_machxo2 -noiopad +memory +opt -full + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -seq 5 -set-init-zero -show-inputs -show-outputs miter + +design -load postopt +cd lutram_1w1r +select -assert-count 20 t:LUT4 +select -assert-count 8 t:TRELLIS_DPR16X4 +select -assert-count 8 t:TRELLIS_FF +select -assert-none t:LUT4 t:TRELLIS_DPR16X4 t:TRELLIS_FF %% t:* %D From 266f81816bbede3f42fabe59e7d0cd8873e1a467 Mon Sep 17 00:00:00 2001 From: gatecat Date: Thu, 6 Apr 2023 09:29:08 +0200 Subject: [PATCH 061/303] ecp5: Remove TRELLIS_SLICE and add TRELLIS_COMB model Signed-off-by: gatecat --- techlibs/ecp5/cells_sim.v | 190 ++++++-------------------------------- 1 file changed, 30 insertions(+), 160 deletions(-) diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 95f612cfa8b..950d12c9130 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -413,177 +413,47 @@ endmodule // --------------------------------------- -module TRELLIS_SLICE( - input A0, B0, C0, D0, - input A1, B1, C1, D1, - input M0, M1, - input FCI, FXA, FXB, - - input CLK, LSR, CE, - input DI0, DI1, - - input WD0, WD1, +module TRELLIS_COMB( + input A, B, C, D, M, + input FCI, F1, FXA, FXB, + input WD, input WAD0, WAD1, WAD2, WAD3, input WRE, WCK, - - output F0, Q0, - output F1, Q1, - output FCO, OFX0, OFX1, - - output WDO0, WDO1, WDO2, WDO3, - output WADO0, WADO1, WADO2, WADO3 + output F, FCO, OFX ); - parameter MODE = "LOGIC"; - parameter GSR = "ENABLED"; - parameter SRMODE = "LSR_OVER_CE"; - parameter [127:0] CEMUX = "1"; - parameter CLKMUX = "CLK"; - parameter LSRMUX = "LSR"; - parameter LUT0_INITVAL = 16'h0000; - parameter LUT1_INITVAL = 16'h0000; - parameter REG0_SD = "0"; - parameter REG1_SD = "0"; - parameter REG0_REGSET = "RESET"; - parameter REG1_REGSET = "RESET"; - parameter REG0_LSRMODE = "LSR"; - parameter REG1_LSRMODE = "LSR"; - parameter [127:0] CCU2_INJECT1_0 = "NO"; - parameter [127:0] CCU2_INJECT1_1 = "NO"; + parameter INITVAL = 16'h0; + parameter CCU2_INJECT1 = "NO"; parameter WREMUX = "WRE"; - parameter WCKMUX = "WCK"; - - parameter A0MUX = "A0"; - parameter A1MUX = "A1"; - parameter B0MUX = "B0"; - parameter B1MUX = "B1"; - parameter C0MUX = "C0"; - parameter C1MUX = "C1"; - parameter D0MUX = "D0"; - parameter D1MUX = "D1"; - - wire A0m, B0m, C0m, D0m; - wire A1m, B1m, C1m, D1m; + parameter IS_Z1 = 1'b0; generate - if (A0MUX == "1") assign A0m = 1'b1; else assign A0m = A0; - if (B0MUX == "1") assign B0m = 1'b1; else assign B0m = B0; - if (C0MUX == "1") assign C0m = 1'b1; else assign C0m = C0; - if (D0MUX == "1") assign D0m = 1'b1; else assign D0m = D0; - if (A1MUX == "1") assign A1m = 1'b1; else assign A1m = A1; - if (B1MUX == "1") assign B1m = 1'b1; else assign B1m = B1; - if (C1MUX == "1") assign C1m = 1'b1; else assign C1m = C1; - if (D1MUX == "1") assign D1m = 1'b1; else assign D1m = D1; - - endgenerate - - function [15:0] permute_initval; - input [15:0] initval; - integer i; - begin - for (i = 0; i < 16; i = i + 1) begin - permute_initval[{i[0], i[2], i[1], i[3]}] = initval[i]; - end - end - endfunction - - generate - if (MODE == "LOGIC") begin - // LUTs - LUT4 #( - .INIT(LUT0_INITVAL) - ) lut4_0 ( - .A(A0m), .B(B0m), .C(C0m), .D(D0m), - .Z(F0) - ); - LUT4 #( - .INIT(LUT1_INITVAL) - ) lut4_1 ( - .A(A1m), .B(B1m), .C(C1m), .D(D1m), - .Z(F1) - ); - // LUT expansion muxes - PFUMX lut5_mux (.ALUT(F1), .BLUT(F0), .C0(M0), .Z(OFX0)); - L6MUX21 lutx_mux (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1)); - end else if (MODE == "CCU2") begin - CCU2C #( - .INIT0(LUT0_INITVAL), - .INIT1(LUT1_INITVAL), - .INJECT1_0(CCU2_INJECT1_0), - .INJECT1_1(CCU2_INJECT1_1) - ) ccu2c_i ( - .CIN(FCI), - .A0(A0m), .B0(B0m), .C0(C0m), .D0(D0m), - .A1(A1m), .B1(B1m), .C1(C1m), .D1(D1m), - .S0(F0), .S1(F1), - .COUT(FCO) - ); - end else if (MODE == "RAMW") begin - assign WDO0 = C1m; - assign WDO1 = A1m; - assign WDO2 = D1m; - assign WDO3 = B1m; - assign WADO0 = D0m; - assign WADO1 = B0m; - assign WADO2 = C0m; - assign WADO3 = A0m; - end else if (MODE == "DPRAM") begin - TRELLIS_RAM16X2 #( - .INITVAL_0(permute_initval(LUT0_INITVAL)), - .INITVAL_1(permute_initval(LUT1_INITVAL)), - .WREMUX(WREMUX) - ) ram_i ( - .DI0(WD0), .DI1(WD1), - .WAD0(WAD0), .WAD1(WAD1), .WAD2(WAD2), .WAD3(WAD3), - .WRE(WRE), .WCK(WCK), - .RAD0(D0m), .RAD1(B0m), .RAD2(C0m), .RAD3(A0m), - .DO0(F0), .DO1(F1) - ); - // TODO: confirm RAD and INITVAL ordering - // DPRAM mode contract? -`ifdef FORMAL - always @(*) begin - assert(A0m==A1m); - assert(B0m==B1m); - assert(C0m==C1m); - assert(D0m==D1m); - end -`endif + if (MODE == "LOGIC") begin: mode_logic + LUT4 #(.INIT(INITVAL)) lut4 (.A(A), .B(B), .C(C), .D(D), .Z(F)); + end else if (MODE == "CCU2") begin: mode_ccu2 + wire l4o, l2o; + LUT4 #(.INIT(INITVAL)) lut4_0(.A(A), .B(B), .C(C), .D(D), .Z(l4o)); + LUT2 #(.INIT(INITVAL[3:0])) lut2_0(.A(A), .B(B), .Z(l2o)); + wire gated_cin_0 = (CCU2_INJECT1 == "YES") ? 1'b0 : FCI; + assign F = l4o ^ gated_cin_0; + wire gated_lut2_0 = (CCU2_INJECT1 == "YES") ? 1'b0 : l2o; + wire FCO = (~l4o & gated_lut2_0) | (l4o & FCI); + end else if (MODE == "DPRAM") begin: mode_dpram + reg [15:0] ram = INITVAL; + always @(posedge WCK) + if (WRE) + ram[{WAD3, WAD2, WAD1, WAD0}] <= WD; + assign F = ram[{A, C, B, D}]; end else begin - ERROR_UNKNOWN_SLICE_MODE error(); + $error("unsupported COMB mode %s", MODE); end + + if (IS_Z1) + L6MUX21 lutx_mux (.D0(FXA), .D1(FXB), .SD(M), .Z(OFX)); + else + PFUMX lut5_mux (.ALUT(F1), .BLUT(F), .C0(M), .Z(OFX)); endgenerate - // FF input selection muxes - wire muxdi0 = (REG0_SD == "1") ? DI0 : M0; - wire muxdi1 = (REG1_SD == "1") ? DI1 : M1; - // Flipflops - TRELLIS_FF #( - .GSR(GSR), - .CEMUX(CEMUX), - .CLKMUX(CLKMUX), - .LSRMUX(LSRMUX), - .SRMODE(SRMODE), - .REGSET(REG0_REGSET), - .LSRMODE(REG0_LSRMODE) - ) ff_0 ( - .CLK(CLK), .LSR(LSR), .CE(CE), - .DI(muxdi0), .M(M0), - .Q(Q0) - ); - TRELLIS_FF #( - .GSR(GSR), - .CEMUX(CEMUX), - .CLKMUX(CLKMUX), - .LSRMUX(LSRMUX), - .SRMODE(SRMODE), - .REGSET(REG1_REGSET), - .LSRMODE(REG1_LSRMODE) - ) ff_1 ( - .CLK(CLK), .LSR(LSR), .CE(CE), - .DI(muxdi1), .M(M1), - .Q(Q1) - ); endmodule (* blackbox *) From 101075611fc5698739180017bf96b1abf140c8e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 00:14:38 +0000 Subject: [PATCH 062/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c38495fe2dd..7ba0c85793b 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+22 +YOSYS_VER := 0.27+30 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From ee3162c58d744381ae59261c237e977e631b5979 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 10 Apr 2023 12:39:09 +0200 Subject: [PATCH 063/303] Add PLL and EBR related primitives --- techlibs/machxo2/Makefile.inc | 1 + techlibs/machxo2/brams_map.v | 128 ++++++++--------- techlibs/machxo2/cells_bb.v | 227 ++++++++++++++++++++++++++++++ techlibs/machxo2/cells_sim.v | 91 +++++------- techlibs/machxo2/synth_machxo2.cc | 2 +- 5 files changed, 325 insertions(+), 124 deletions(-) create mode 100644 techlibs/machxo2/cells_bb.v diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc index 774b357a253..cd4e27884fc 100644 --- a/techlibs/machxo2/Makefile.inc +++ b/techlibs/machxo2/Makefile.inc @@ -4,6 +4,7 @@ OBJS += techlibs/machxo2/synth_machxo2.o $(eval $(call add_share_file,share/machxo2,techlibs/ecp5/cells_io.vh)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) $(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) +$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_bb.v)) $(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams.txt)) $(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams_map.v)) diff --git a/techlibs/machxo2/brams_map.v b/techlibs/machxo2/brams_map.v index 05a8e8a9b09..6783e5b2902 100644 --- a/techlibs/machxo2/brams_map.v +++ b/techlibs/machxo2/brams_map.v @@ -45,38 +45,38 @@ assign PORT_A_RD_DATA = DOA; assign PORT_B_RD_DATA = DOB; DP8KC #( - .INITVAL_00($sformatf("0x%080x", init_slice('h00))), - .INITVAL_01($sformatf("0x%080x", init_slice('h01))), - .INITVAL_02($sformatf("0x%080x", init_slice('h02))), - .INITVAL_03($sformatf("0x%080x", init_slice('h03))), - .INITVAL_04($sformatf("0x%080x", init_slice('h04))), - .INITVAL_05($sformatf("0x%080x", init_slice('h05))), - .INITVAL_06($sformatf("0x%080x", init_slice('h06))), - .INITVAL_07($sformatf("0x%080x", init_slice('h07))), - .INITVAL_08($sformatf("0x%080x", init_slice('h08))), - .INITVAL_09($sformatf("0x%080x", init_slice('h09))), - .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), - .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), - .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), - .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), - .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), - .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), - .INITVAL_10($sformatf("0x%080x", init_slice('h10))), - .INITVAL_11($sformatf("0x%080x", init_slice('h11))), - .INITVAL_12($sformatf("0x%080x", init_slice('h12))), - .INITVAL_13($sformatf("0x%080x", init_slice('h13))), - .INITVAL_14($sformatf("0x%080x", init_slice('h14))), - .INITVAL_15($sformatf("0x%080x", init_slice('h15))), - .INITVAL_16($sformatf("0x%080x", init_slice('h16))), - .INITVAL_17($sformatf("0x%080x", init_slice('h17))), - .INITVAL_18($sformatf("0x%080x", init_slice('h18))), - .INITVAL_19($sformatf("0x%080x", init_slice('h19))), - .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), - .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), - .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), - .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), - .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), - .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), .DATA_WIDTH_A(PORT_A_WIDTH), .DATA_WIDTH_B(PORT_B_WIDTH), .REGMODE_A("NOREG"), @@ -211,38 +211,38 @@ wire [17:0] DO; assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; DP8KC #( - .INITVAL_00($sformatf("0x%080x", init_slice('h00))), - .INITVAL_01($sformatf("0x%080x", init_slice('h01))), - .INITVAL_02($sformatf("0x%080x", init_slice('h02))), - .INITVAL_03($sformatf("0x%080x", init_slice('h03))), - .INITVAL_04($sformatf("0x%080x", init_slice('h04))), - .INITVAL_05($sformatf("0x%080x", init_slice('h05))), - .INITVAL_06($sformatf("0x%080x", init_slice('h06))), - .INITVAL_07($sformatf("0x%080x", init_slice('h07))), - .INITVAL_08($sformatf("0x%080x", init_slice('h08))), - .INITVAL_09($sformatf("0x%080x", init_slice('h09))), - .INITVAL_0A($sformatf("0x%080x", init_slice('h0a))), - .INITVAL_0B($sformatf("0x%080x", init_slice('h0b))), - .INITVAL_0C($sformatf("0x%080x", init_slice('h0c))), - .INITVAL_0D($sformatf("0x%080x", init_slice('h0d))), - .INITVAL_0E($sformatf("0x%080x", init_slice('h0e))), - .INITVAL_0F($sformatf("0x%080x", init_slice('h0f))), - .INITVAL_10($sformatf("0x%080x", init_slice('h10))), - .INITVAL_11($sformatf("0x%080x", init_slice('h11))), - .INITVAL_12($sformatf("0x%080x", init_slice('h12))), - .INITVAL_13($sformatf("0x%080x", init_slice('h13))), - .INITVAL_14($sformatf("0x%080x", init_slice('h14))), - .INITVAL_15($sformatf("0x%080x", init_slice('h15))), - .INITVAL_16($sformatf("0x%080x", init_slice('h16))), - .INITVAL_17($sformatf("0x%080x", init_slice('h17))), - .INITVAL_18($sformatf("0x%080x", init_slice('h18))), - .INITVAL_19($sformatf("0x%080x", init_slice('h19))), - .INITVAL_1A($sformatf("0x%080x", init_slice('h1a))), - .INITVAL_1B($sformatf("0x%080x", init_slice('h1b))), - .INITVAL_1C($sformatf("0x%080x", init_slice('h1c))), - .INITVAL_1D($sformatf("0x%080x", init_slice('h1d))), - .INITVAL_1E($sformatf("0x%080x", init_slice('h1e))), - .INITVAL_1F($sformatf("0x%080x", init_slice('h1f))), + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), .DATA_WIDTH_A(PORT_W_WIDTH), .DATA_WIDTH_B(PORT_R_WIDTH), .REGMODE_A("NOREG"), diff --git a/techlibs/machxo2/cells_bb.v b/techlibs/machxo2/cells_bb.v new file mode 100644 index 00000000000..3d047b1692a --- /dev/null +++ b/techlibs/machxo2/cells_bb.v @@ -0,0 +1,227 @@ +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v index 2075c05195e..8e0e411791c 100644 --- a/techlibs/machxo2/cells_sim.v +++ b/techlibs/machxo2/cells_sim.v @@ -179,33 +179,6 @@ module TRELLIS_IO #( endgenerate endmodule -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); -endmodule - -(* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); -endmodule - (* abc9_box, lib_whitebox *) module TRELLIS_DPR16X4 ( input [3:0] DI, @@ -371,38 +344,38 @@ module DP8KC( parameter GSR = "ENABLED"; parameter INIT_DATA = "STATIC"; - parameter INITVAL_00 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_01 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_02 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_03 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_04 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_05 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_06 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_07 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_08 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_09 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_0A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_0B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_0C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_0D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_0E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_0F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_10 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_11 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_12 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_13 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_14 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_15 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_16 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_17 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_18 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_19 = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_1A = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_1B = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_1C = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_1D = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_1E = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; - parameter INITVAL_1F = "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; endmodule `ifndef NO_INCLUDES diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index fb4d7b9d061..2b684a7d8fd 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -178,7 +178,7 @@ struct SynthMachXO2Pass : public ScriptPass { if (check_label("begin")) { - run("read_verilog -lib -icells +/machxo2/cells_sim.v"); + run("read_verilog -lib -icells +/machxo2/cells_sim.v +/machxo2/cells_bb.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); } From f9a6c0fcbd29c4a14d81307b6d9f51896dfff9cf Mon Sep 17 00:00:00 2001 From: YRabbit Date: Tue, 4 Apr 2023 09:41:10 +1000 Subject: [PATCH 064/303] gowin: Add serialization/deserialization primitives Primitives are added to convert parallel signals to serial and vice versa. IDES4, IDES8, IDES10, IDES16, IVIDEO, OSER4, OSER8, OSER10, OSER16, OVIDEO. Signed-off-by: YRabbit --- techlibs/gowin/cells_sim.v | 244 +++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 535fd05ed45..86bd677e229 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -598,6 +598,250 @@ module TLVDS_OBUF (I, O, OB); assign OB = ~I; endmodule +module OSER4(D3, D2, D1, D0, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0); + output Q1; + output Q0; + + input D3; + input D2; + input D1; + input D0; + input TX1; + input TX0; + input FCLK; + input PCLK; + input RESET; + + parameter GSREN = "false"; + parameter LSREN = "true"; + parameter TXCLK_POL = 0; + parameter HWL = "false"; +endmodule + +module OSER8(D7, D6, D5, D4, D3, D2, D1, D0, TX3, TX2, TX1, TX0, FCLK, PCLK, RESET, Q1, Q0); + output Q1; + output Q0; + + input D7; + input D6; + input D5; + input D4; + input D3; + input D2; + input D1; + input D0; + input TX3; + input TX2; + input TX1; + input TX0; + input FCLK; + input PCLK; + input RESET; + + parameter GSREN = "false"; + parameter LSREN = "true"; + parameter TXCLK_POL = 0; + parameter HWL = "false"; +endmodule + +module OSER10(D9, D8, D7, D6, D5, D4, D3, D2, D1, D0, FCLK, PCLK, RESET, Q); + output Q; + + input D9; + input D8; + input D7; + input D6; + input D5; + input D4; + input D3; + input D2; + input D1; + input D0; + input FCLK; + input PCLK; + input RESET; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module OVIDEO(D6, D5, D4, D3, D2, D1, D0, FCLK, PCLK, RESET, Q); + output Q; + + input D6; + input D5; + input D4; + input D3; + input D2; + input D1; + input D0; + input FCLK; + input PCLK; + input RESET; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module OSER16(D15, D14, D13, D12, D11, D10, +D9, D8, D7, D6, D5, D4, D3, D2, D1, D0, FCLK, PCLK, +RESET, Q); + output Q; + + input D15; + input D14; + input D13; + input D12; + input D11; + input D10; + input D9; + input D8; + input D7; + input D6; + input D5; + input D4; + input D3; + input D2; + input D1; + input D0; + input FCLK; + input PCLK; + input RESET; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module IDES4(Q3, Q2, Q1, Q0, FCLK, PCLK, +RESET, CALIB, D); + input D; + input FCLK; + input PCLK; + input RESET; + input CALIB; + + output Q3; + output Q2; + output Q1; + output Q0; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module IDES8(Q7, Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK, +RESET, CALIB, D); + input D; + input FCLK; + input PCLK; + input RESET; + input CALIB; + + output Q7; + output Q6; + output Q5; + output Q4; + output Q3; + output Q2; + output Q1; + output Q0; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module IDES10(Q9, Q8, Q7, Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK, +RESET, CALIB, D); + input D; + input FCLK; + input PCLK; + input RESET; + input CALIB; + + output Q9; + output Q8; + output Q7; + output Q6; + output Q5; + output Q4; + output Q3; + output Q2; + output Q1; + output Q0; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module IVIDEO(Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK, +RESET, CALIB, D); + input D; + input FCLK; + input PCLK; + input RESET; + input CALIB; + + output Q6; + output Q5; + output Q4; + output Q3; + output Q2; + output Q1; + output Q0; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module IDES16(Q15, Q14, Q13, Q12, Q11, Q10, +Q9, Q8, Q7, Q6, Q5, Q4, Q3, Q2, Q1, Q0, FCLK, PCLK, +RESET, CALIB, D); + input D; + input FCLK; + input PCLK; + input RESET; + input CALIB; + + output Q15; + output Q14; + output Q13; + output Q12; + output Q11; + output Q10; + output Q9; + output Q8; + output Q7; + output Q6; + output Q5; + output Q4; + output Q3; + output Q2; + output Q1; + output Q0; + + parameter GSREN = "false"; + parameter LSREN = "true"; +endmodule + +module IDDR(D, CLK, Q0, Q1); + input D; + input CLK; + output Q0; + output Q1; + parameter Q0_INIT = 1'b0; + parameter Q1_INIT = 1'b0; +endmodule + +module IDDRC(D, CLK, CLEAR, Q0, Q1); + input D; + input CLK; + input CLEAR; + output Q0; + output Q1; + parameter Q0_INIT = 1'b0; + parameter Q1_INIT = 1'b0; +endmodule + (* blackbox *) module ODDR(D0, D1, TX, CLK, Q0, Q1); input D0; From e56dad56c42c9da03d23ba296ed1582dbb4e8b48 Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 12 Apr 2023 13:53:42 +0200 Subject: [PATCH 065/303] fabulous: Add support for LUT6s Signed-off-by: gatecat --- techlibs/fabulous/cells_map.v | 7 ++++++- techlibs/fabulous/prims.v | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/techlibs/fabulous/cells_map.v b/techlibs/fabulous/cells_map.v index eadd18b6f08..e33e641a8ac 100644 --- a/techlibs/fabulous/cells_map.v +++ b/techlibs/fabulous/cells_map.v @@ -16,10 +16,15 @@ module \$lut (A, Y); end else if (WIDTH == 3) begin LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2])); - end else if (WIDTH == 4) begin LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); + end else + if (WIDTH == 5) begin + LUT5 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]), .I4(A[4])); + end else + if (WIDTH == 6) begin + LUT6 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]), .I4(A[4]), .I5(A[5])); end else begin wire _TECHMAP_FAIL_ = 1; end diff --git a/techlibs/fabulous/prims.v b/techlibs/fabulous/prims.v index fe3e8536aa8..21dc5223d23 100644 --- a/techlibs/fabulous/prims.v +++ b/techlibs/fabulous/prims.v @@ -38,6 +38,38 @@ module LUT4_HA(output O, Co, input I0, I1, I2, I3, Ci); assign Co = (Ci & I1) | (Ci & I2) | (I1 & I2); endmodule +module LUT5(output O, input I0, I1, I2, I3, I4); + parameter [31:0] INIT = 0; + wire [15: 0] s4 = I4 ? INIT[31:16] : INIT[15: 0]; + wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +endmodule + +module LUT6(output O, input I0, I1, I2, I3, I4, I5); + parameter [63:0] INIT = 0; + wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0]; + wire [15: 0] s4 = I4 ? s5[31:16] : s5[15: 0]; + wire [ 7: 0] s3 = I3 ? s4[15: 8] : s4[ 7: 0]; + wire [ 3: 0] s2 = I2 ? s3[ 7: 4] : s3[ 3: 0]; + wire [ 1: 0] s1 = I1 ? s2[ 3: 2] : s2[ 1: 0]; + assign O = I0 ? s1[1] : s1[0]; +endmodule + +module LUT55_FCY (output O, Co, input I0, I1, I2, I3, I4, Ci); + parameter [63:0] INIT = 0; + + wire comb1, comb2; + + LUT5 #(.INIT(INIT[31: 0])) l5_1 (.I0(I0), .I1(I1), .I2(I2), .I3(I3), .I4(I4), .O(comb1)); + LUT5 #(.INIT(INIT[63:32])) l5_2 (.I0(I0), .I1(I1), .I2(I2), .I3(I3), .I4(I4), .O(comb2)); + + assign O = comb1 ^ Ci; + assign Co = comb1 ? Ci : comb2; +endmodule + + module LUTFF(input CLK, D, output reg O); initial O = 1'b0; always @ (posedge CLK) begin From a2655a4b70691aae8be02477f0a236a5a3d45542 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 00:14:37 +0000 Subject: [PATCH 066/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7ba0c85793b..9592a6a5b32 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+30 +YOSYS_VER := 0.27+33 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 0d6f4b068338c25f3de4ddab0747f714602037b5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 14 Apr 2023 09:52:15 +0200 Subject: [PATCH 067/303] Release version 0.28 --- CHANGELOG | 13 ++++++++++++- Makefile | 4 ++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 80672a8cc0d..ee6659f4959 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,19 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.27 .. Yosys 0.27-dev +Yosys 0.27 .. Yosys 0.28 -------------------------- + * Verilog + - Out of bounds checking for struct/union members. + + * Verific support + - Fix enum_values support and signed attribute values. + + * ECP5 support + - Added "synth_ecp5 -iopad" + + * MachXO2 support + - Added "synth_machxo2 -ccu2" Yosys 0.26 .. Yosys 0.27 -------------------------- diff --git a/Makefile b/Makefile index 9592a6a5b32..5cedb71ace8 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.27+33 +YOSYS_VER := 0.28 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 5f88c21.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 5f88c21.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From d0855576aee12f0b8b68c3ad170068f72cade21e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 14 Apr 2023 09:54:46 +0200 Subject: [PATCH 068/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ee6659f4959..1a74acd9d78 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.28 .. Yosys 0.28-dev +-------------------------- + Yosys 0.27 .. Yosys 0.28 -------------------------- * Verilog diff --git a/Makefile b/Makefile index 5cedb71ace8..73fda14646f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28 +YOSYS_VER := 0.28+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 5f88c21.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0d6f4b0.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From a9c792dceef4be21059ff4732d1aff62e67d96bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 15 Apr 2023 00:16:41 +0000 Subject: [PATCH 069/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 73fda14646f..ae8d1222afb 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28+0 +YOSYS_VER := 0.28+1 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a3a8f7be38e8e760c1de87bc71bb6336a486a40d Mon Sep 17 00:00:00 2001 From: Henner Zeller Date: Mon, 17 Apr 2023 10:51:10 -0700 Subject: [PATCH 070/303] Remove a statement without effect. The return value of the min(...) call is never used. Looks like some leftover from some previous implementation. Signed-off-by: Henner Zeller --- kernel/yw.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/yw.cc b/kernel/yw.cc index 73e7710db43..ef043fb0d0f 100644 --- a/kernel/yw.cc +++ b/kernel/yw.cc @@ -190,8 +190,6 @@ RTLIL::Const ReadWitness::get_bits(int t, int bits_offset, int width) const int read_begin = GetSize(bits) - 1 - bits_offset; int read_end = max(-1, read_begin - width); - min(width, GetSize(bits) - bits_offset); - for (int i = read_begin, j = 0; i > read_end; i--, j++) { RTLIL::State bit = State::Sa; switch (bits[i]) { From 7efc50367ed8f582001a5a293a9cd51f788f6a13 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 00:16:35 +0000 Subject: [PATCH 071/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ae8d1222afb..63e5a88d7f2 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28+1 +YOSYS_VER := 0.28+4 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 3861cc31f0dc625ee48e7cc1a62e1f2fd7bd324d Mon Sep 17 00:00:00 2001 From: AdamHillier Date: Wed, 19 Apr 2023 11:00:51 +0000 Subject: [PATCH 072/303] Add outputs before inputs to the sigmap in the AIGER backend. --- backends/aiger/aiger.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 4ef28be9f3b..97acf937cd7 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -119,14 +119,14 @@ struct AigerWriter if (wire->name.isPublic()) sigmap.add(wire); - // promote input wires + // promote output wires for (auto wire : module->wires()) - if (wire->port_input) + if (wire->port_output) sigmap.add(wire); - // promote output wires + // promote input wires for (auto wire : module->wires()) - if (wire->port_output) + if (wire->port_input) sigmap.add(wire); for (auto wire : module->wires()) From 985f4926b77aef98a2639624a44e155b2233c3ad Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 20 Apr 2023 12:12:50 +0200 Subject: [PATCH 073/303] verilog: Fix const eval of unbased unsized constants When the verilog frontend perfomed constant evaluation of unbased unsized constants in a context-determined expression it did not properly extend them by repeating the bit value. This only affected constant evaluation and not constants that made it through unchanged to RTLIL. The latter case was already covered by tests and working before. This fixes the const-eval issue by checking the `is_unsized` flag in bitsAsConst and extending the value accordingly. The newly added test also tests the already working non-const-eval case to highlight that both cases should behave the same. --- frontends/ast/ast.cc | 2 +- tests/verilog/unbased_unsized_shift.sv | 28 ++++++++++++++++++++++++++ tests/verilog/unbased_unsized_shift.ys | 7 +++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/verilog/unbased_unsized_shift.sv create mode 100644 tests/verilog/unbased_unsized_shift.ys diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 5a2ade04a90..91001c70dfd 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -847,7 +847,7 @@ RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed) bits.resize(width); if (width >= 0 && width > int(bits.size())) { RTLIL::State extbit = RTLIL::State::S0; - if (is_signed && !bits.empty()) + if ((is_signed || is_unsized) && !bits.empty()) extbit = bits.back(); while (width > int(bits.size())) bits.push_back(extbit); diff --git a/tests/verilog/unbased_unsized_shift.sv b/tests/verilog/unbased_unsized_shift.sv new file mode 100644 index 00000000000..475e9a75dfe --- /dev/null +++ b/tests/verilog/unbased_unsized_shift.sv @@ -0,0 +1,28 @@ +module pass_through( + input [63:0] inp, + output [63:0] out +); + assign out = inp; +endmodule + +module top; + logic [63:0] s0c, s1c, sxc, s0d, s1d, sxd, d; + + pass_through pt(8, d); + + assign s0c = '0 << 8; + assign s1c = '1 << 8; + assign sxc = 'x << 8; + assign s0d = '0 << d; + assign s1d = '1 << d; + assign sxd = 'x << d; + + always @* begin + assert (s0c === 64'h0000_0000_0000_0000); + assert (s1c === 64'hFFFF_FFFF_FFFF_FF00); + assert (sxc === 64'hxxxx_xxxx_xxxx_xx00); + assert (s0d === 64'h0000_0000_0000_0000); + assert (s1d === 64'hFFFF_FFFF_FFFF_FF00); + assert (sxd === 64'hxxxx_xxxx_xxxx_xx00); + end +endmodule diff --git a/tests/verilog/unbased_unsized_shift.ys b/tests/verilog/unbased_unsized_shift.ys new file mode 100644 index 00000000000..c36049600fd --- /dev/null +++ b/tests/verilog/unbased_unsized_shift.ys @@ -0,0 +1,7 @@ +read_verilog -sv unbased_unsized_shift.sv +hierarchy +proc +flatten +opt -full +select -module top +sat -verify -seq 1 -tempinduct -prove-asserts -show-all From ec47bf174549f4f2430c08e0d24bb9ba7bd5390d Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 21 Apr 2023 16:51:42 +0200 Subject: [PATCH 074/303] verific: Handle conditions when using sva_at_only in VerificClocking This handles conditions on clocked concurrent assertions in unclocked procedural contexts. --- frontends/verific/verific.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 605dcdfb277..bc61c9c82f5 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2011,6 +2011,28 @@ VerificClocking::VerificClocking(VerificImporter *importer, Net *net, bool sva_a Instance *inst = net->Driver(); + // Detect condition expression in sva_at_only mode + if (sva_at_only) + do { + Instance *inst_mux = net->Driver(); + if (inst_mux->Type() != PRIM_MUX) + break; + + bool pwr1 = inst_mux->GetInput1()->IsPwr(); + bool pwr2 = inst_mux->GetInput2()->IsPwr(); + + if (!pwr1 && !pwr2) + break; + + Net *sva_net = pwr1 ? inst_mux->GetInput2() : inst_mux->GetInput1(); + if (!verific_is_sva_net(importer, sva_net)) + break; + + inst = sva_net->Driver(); + cond_net = inst_mux->GetControl(); + cond_pol = pwr1; + } while (0); + if (inst != nullptr && inst->Type() == PRIM_SVA_AT) { net = inst->GetInput1(); From 3cbca5064cfbb418ac69d703034f8bb780a9cc41 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 21 Apr 2023 17:19:42 +0200 Subject: [PATCH 075/303] verific: Handle non-seq properties with VerificClocking conditions --- frontends/verific/verificsva.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/frontends/verific/verificsva.cc b/frontends/verific/verificsva.cc index 986a9864326..222c7d2e917 100644 --- a/frontends/verific/verificsva.cc +++ b/frontends/verific/verificsva.cc @@ -1598,12 +1598,17 @@ struct VerificSvaImporter if (inst == nullptr) { - log_assert(trig == State::S1); - - if (accept_p != nullptr) - *accept_p = importer->net_map_at(net); - if (reject_p != nullptr) - *reject_p = module->Not(NEW_ID, importer->net_map_at(net)); + if (trig != State::S1) { + if (accept_p != nullptr) + *accept_p = module->And(NEW_ID, trig, importer->net_map_at(net)); + if (reject_p != nullptr) + *reject_p = module->And(NEW_ID, trig, module->Not(NEW_ID, importer->net_map_at(net))); + } else { + if (accept_p != nullptr) + *accept_p = importer->net_map_at(net); + if (reject_p != nullptr) + *reject_p = module->Not(NEW_ID, importer->net_map_at(net)); + } } else if (inst->Type() == PRIM_SVA_OVERLAPPED_IMPLICATION || From a1dd794ff883286dcd71c73fc21a701402e1078a Mon Sep 17 00:00:00 2001 From: YRabbit Date: Sat, 22 Apr 2023 17:10:53 +1000 Subject: [PATCH 076/303] gowin: Add all the primitives. Use selected data (names, ports and parameters) from vendor file for GW1N series primitives. Signed-off-by: YRabbit --- techlibs/gowin/Makefile.inc | 1 + techlibs/gowin/cells_xtra.py | 76 ++ techlibs/gowin/cells_xtra.v | 2003 +++++++++++++++++++++++++++++++++ techlibs/gowin/synth_gowin.cc | 1 + 4 files changed, 2081 insertions(+) create mode 100644 techlibs/gowin/cells_xtra.py create mode 100644 techlibs/gowin/cells_xtra.v diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc index 4f3a33f369e..0e24b91e5ff 100644 --- a/techlibs/gowin/Makefile.inc +++ b/techlibs/gowin/Makefile.inc @@ -3,6 +3,7 @@ OBJS += techlibs/gowin/synth_gowin.o $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_sim.v)) +$(eval $(call add_share_file,share/gowin,techlibs/gowin/cells_xtra.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/arith_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_map.v)) $(eval $(call add_share_file,share/gowin,techlibs/gowin/brams.txt)) diff --git a/techlibs/gowin/cells_xtra.py b/techlibs/gowin/cells_xtra.py new file mode 100644 index 00000000000..4d117e428c3 --- /dev/null +++ b/techlibs/gowin/cells_xtra.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +# Base on Nexus cells_xtra.py + +from argparse import ArgumentParser +import os.path +from enum import Enum, auto +import sys +import re + +class State(Enum): + OUTSIDE = auto() + IN_MODULE = auto() + IN_PARAMETER = auto() + +_skip = { 'ALU', 'DFF', 'DFFC', 'DFFCE', 'DFFE', 'DFFN', 'DFFNC', 'DFFNCE', + 'DFFNE', 'DFFNP', 'DFFNPE', 'DFFNR', 'DFFNRE', 'DFFNS', 'DFFNSE', + 'DFFP', 'DFFPE', 'DFFR', 'DFFRE', 'DFFS', 'DFFSE', 'DP', 'DPX9', + 'ELVDS_OBUF', 'GND', 'GSR', 'IBUF', 'IDDR', 'IDDRC', 'IDES10', + 'IDES16', 'IDES4', 'IDES8', 'IOBUF', 'IVIDEO', 'LUT1', 'LUT2', + 'LUT3', 'LUT4', 'MUX2', 'MUX2_LUT5', 'MUX2_LUT6', 'MUX2_LUT7', + 'MUX2_LUT8', 'OBUF', 'ODDR', 'ODDRC', 'OSC', 'OSCF', 'OSCH', + 'OSCO', 'OSCW', 'OSCZ', 'OSER10', 'OSER16', 'OSER10', 'OSER4', + 'OSER8', 'OVIDEO', 'PLLVR', 'RAM16S1', 'RAM16S2', 'RAM16S4', + 'RAM16SDP1', 'RAM16SDP2', 'RAM16SDP4', 'rPLL', 'SDP', + 'SDPX9', 'SP', 'SPX9', 'TBUF', 'TLVDS_OBUF', 'VCC' + } +def xtract_cells_decl(dir, fout): + fname = os.path.join(dir, 'prim_sim.v') + with open(fname) as f: + state = State.OUTSIDE + for l in f: + l, _, comment = l.partition('//') + if l.startswith("module "): + cell_name = l[7:l.find('(')].strip() + if cell_name not in _skip: + state = State.IN_MODULE + fout.write(f'\nmodule {cell_name} (...);\n') + elif l.startswith(('input', 'output', 'inout')) and state == State.IN_MODULE: + fout.write(l) + if l[-1] != '\n': + fout.write('\n') + elif l.startswith('parameter') and state == State.IN_MODULE: + fout.write(l) + if l.rstrip()[-1] == ',': + state = State.IN_PARAMETER + if l[-1] != '\n': + fout.write('\n') + elif state == State.IN_PARAMETER: + fout.write(l) + if l.rstrip()[-1] == ';': + state = State.IN_MODULE + if l[-1] != '\n': + fout.write('\n') + elif l.startswith('endmodule') and state == State.IN_MODULE: + state = State.OUTSIDE + fout.write('endmodule\n') + if l[-1] != '\n': + fout.write('\n') + +if __name__ == '__main__': + parser = ArgumentParser(description='Extract Gowin blackbox cell definitions.') + parser.add_argument('gowin_dir', nargs='?', default='/opt/gowin/') + args = parser.parse_args() + + dirs = [ + os.path.join(args.gowin_dir, 'IDE/simlib/gw1n/'), + ] + + with open('cells_xtra.v', 'w') as fout: + fout.write('// Created by cells_xtra.py\n') + fout.write('\n') + for dir in dirs: + if not os.path.isdir(dir): + print(f'{dir} is not a directory') + xtract_cells_decl(dir, fout) diff --git a/techlibs/gowin/cells_xtra.v b/techlibs/gowin/cells_xtra.v new file mode 100644 index 00000000000..4b89b8098aa --- /dev/null +++ b/techlibs/gowin/cells_xtra.v @@ -0,0 +1,2003 @@ +// Created by cells_xtra.py + + +module MUX2_MUX8 (...); +input I0,I1; +input S0; +output O; +endmodule + + +module MUX2_MUX16 (...); +input I0,I1; +input S0; +output O; +endmodule + + +module MUX2_MUX32 (...); +input I0,I1; +input S0; +output O; +endmodule + + +module MUX4 (...); +input I0, I1, I2, I3; +input S0, S1; +output O; +endmodule + + +module MUX8 (...); +input I0, I1, I2, I3, I4, I5, I6, I7; +input S0, S1, S2; +output O; +endmodule + + +module MUX16 (...); +input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15; +input S0, S1, S2, S3; +output O; +endmodule + +module MUX32 (...); +input I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31; +input S0, S1, S2, S3, S4; +output O; +endmodule + +module LUT5 (...); +parameter INIT = 32'h00000000; +input I0, I1, I2, I3, I4; +output F; +endmodule + + +module LUT6 (...); +parameter INIT = 64'h0000_0000_0000_0000; +input I0, I1, I2, I3, I4, I5; +output F; +endmodule + + +module LUT7 (...); +parameter INIT = 128'h0000_0000_0000_0000_0000_0000_0000_0000; +input I0, I1, I2, I3, I4, I5, I6; +output F; +endmodule + + +module LUT8 (...); +parameter INIT = 256'h0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000; +input I0, I1, I2, I3, I4, I5, I6, I7; +output F; +endmodule + + +module DL (...); +input D, G; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLE (...); +input D, G, CE; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLC (...); +input D, G, CLEAR; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLCE (...); +input D, G, CLEAR, CE; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLP (...); +input D, G, PRESET; +output Q; +parameter INIT = 1'b1; +endmodule + + +module DLPE (...); +input D, G, PRESET, CE; +output Q; +parameter INIT = 1'b1; +endmodule + + +module DLN (...); +input D, G; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLNE (...); +input D, G, CE; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLNC (...); +input D, G, CLEAR; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLNCE (...); +input D, G, CLEAR, CE; +output Q; +parameter INIT = 1'b0; +endmodule + + +module DLNP (...); +input D, G, PRESET; +output Q; +parameter INIT = 1'b1; +endmodule + + +module DLNPE (...); +input D, G, PRESET, CE; +output Q; +parameter INIT = 1'b1; +endmodule + + +module INV (...); +input I; +output O; +endmodule + + +module IODELAY (...); +parameter C_STATIC_DLY = 0; +input DI; +input SDTAP; +input SETN; +input VALUE; +output DF; +output DO; +endmodule + + +module IEM (...); +parameter WINSIZE = "SMALL"; +parameter GSREN = "false"; +parameter LSREN = "true"; +input D, CLK, RESET, MCLK; +output LAG, LEAD; +endmodule + + +module ROM16 (...); +parameter INIT_0 = 16'h0000; +input [3:0] AD; +output DO; +endmodule + + +module ROM (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH = 32; +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +input CLK, CE; +input OCE; +input RESET; +input WRE; +input [13:0] AD; +input [2:0] BLKSEL; +output [31:0] DO; +endmodule + + +module ROMX9 (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH = 36; +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +input CLK, CE; +input OCE; +input RESET; +input WRE; +input [13:0] AD; +input [2:0] BLKSEL; +output [35:0] DO; +endmodule + + +module rSDP (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH_0 = 32; +parameter BIT_WIDTH_1 = 32; +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +input CLKA, CEA, CLKB, CEB; +input OCE; +input RESETA, RESETB; +input [13:0] ADA, ADB; +input [31:0] DI; +input [2:0] BLKSEL; +output [31:0] DO; +endmodule + + +module rSDPX9 (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH_0 = 36; +parameter BIT_WIDTH_1 = 36; +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +input CLKA, CEA, CLKB, CEB; +input OCE; +input RESETA, RESETB; +input [13:0] ADA, ADB; +input [2:0] BLKSEL; +input [35:0] DI; +output [35:0] DO; +endmodule + + +module rROM (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH = 32; +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +input CLK, CE; +input OCE; +input RESET; +input [13:0] AD; +input [2:0] BLKSEL; +output [31:0] DO; +endmodule + + +module rROMX9 (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH = 36; +parameter BLK_SEL = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +input CLK, CE; +input OCE; +input RESET; +input [13:0] AD; +input [2:0] BLKSEL; +output [35:0] DO; +endmodule + + +module pROM (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH = 32; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +input CLK, CE; +input OCE; +input RESET; +input [13:0] AD; +output [31:0] DO; +endmodule + + +module pROMX9 (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH = 36; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +input CLK, CE; +input OCE; +input RESET; +input [13:0] AD; +output [35:0] DO; +endmodule + + +module SDPB (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH_0 = 32; +parameter BIT_WIDTH_1 = 32; +parameter BLK_SEL_0 = 3'b000; +parameter BLK_SEL_1 = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +input CLKA, CEA, CLKB, CEB; +input OCE; +input RESETA, RESETB; +input [13:0] ADA, ADB; +input [31:0] DI; +input [2:0] BLKSELA, BLKSELB; +output [31:0] DO; +endmodule + + +module SDPX9B (...); +parameter READ_MODE = 1'b0; +parameter BIT_WIDTH_0 = 36; +parameter BIT_WIDTH_1 = 36; +parameter BLK_SEL_0 = 3'b000; +parameter BLK_SEL_1 = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +input CLKA, CEA, CLKB, CEB; +input OCE; +input RESETA, RESETB; +input [13:0] ADA, ADB; +input [2:0] BLKSELA, BLKSELB; +input [35:0] DI; +output [35:0] DO; +endmodule + + +module DPB (...); +parameter READ_MODE0 = 1'b0; +parameter READ_MODE1 = 1'b0; +parameter WRITE_MODE0 = 2'b00; +parameter WRITE_MODE1 = 2'b00; +parameter BIT_WIDTH_0 = 16; +parameter BIT_WIDTH_1 = 16; +parameter BLK_SEL_0 = 3'b000; +parameter BLK_SEL_1 = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 256'h0000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 256'h0000000000000000000000000000000000000000000000000000000000000000; +input CLKA, CEA, CLKB, CEB; +input OCEA, OCEB; +input RESETA, RESETB; +input WREA, WREB; +input [13:0] ADA, ADB; +input [2:0] BLKSELA, BLKSELB; +input [15:0] DIA, DIB; +output [15:0] DOA, DOB; +endmodule + + +module DPX9B (...); +parameter READ_MODE0 = 1'b0; +parameter READ_MODE1 = 1'b0; +parameter WRITE_MODE0 = 2'b00; +parameter WRITE_MODE1 = 2'b00; +parameter BIT_WIDTH_0 = 18; +parameter BIT_WIDTH_1 = 18; +parameter BLK_SEL_0 = 3'b000; +parameter BLK_SEL_1 = 3'b000; +parameter RESET_MODE = "SYNC"; +parameter INIT_RAM_00 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_01 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_02 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_03 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_04 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_05 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_06 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_07 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_08 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_09 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_0F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_10 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_11 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_12 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_13 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_14 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_15 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_16 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_17 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_18 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_19 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_1F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_20 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_21 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_22 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_23 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_24 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_25 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_26 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_27 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_28 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_29 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_2F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_30 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_31 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_32 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_33 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_34 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_35 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_36 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_37 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_38 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_39 = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3A = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3B = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3C = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3D = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3E = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +parameter INIT_RAM_3F = 288'h000000000000000000000000000000000000000000000000000000000000000000000000; +input CLKA, CEA, CLKB, CEB; +input OCEA, OCEB; +input RESETA, RESETB; +input WREA, WREB; +input [13:0] ADA, ADB; +input [17:0] DIA, DIB; +input [2:0] BLKSELA, BLKSELB; +output [17:0] DOA, DOB; +endmodule + + +module PADD18 (...); +input [17:0] A; +input [17:0] B; +input ASEL; +input CE,CLK,RESET; +input [17:0] SI,SBI; +output [17:0] SO,SBO; +output [17:0] DOUT; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter ADD_SUB = 1'b0; +parameter PADD_RESET_MODE = "SYNC"; +parameter BSEL_MODE = 1'b1; +parameter SOREG = 1'b0; +endmodule + +module PADD9 (...); +input [8:0] A; +input [8:0] B; +input ASEL; +input CE,CLK,RESET; +input [8:0] SI,SBI; +output [8:0] SO,SBO; +output [8:0] DOUT; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter ADD_SUB = 1'b0; +parameter PADD_RESET_MODE = "SYNC"; +parameter BSEL_MODE = 1'b1; +parameter SOREG = 1'b0; +endmodule + +module MULT9X9 (...); +input [8:0] A,SIA; +input [8:0] B,SIB; +input ASIGN,BSIGN; +input ASEL,BSEL; +input CE; +input CLK; +input RESET; +output [17:0] DOUT; +output [8:0] SOA,SOB; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter OUT_REG = 1'b0; +parameter PIPE_REG = 1'b0; +parameter ASIGN_REG = 1'b0; +parameter BSIGN_REG = 1'b0; +parameter SOA_REG = 1'b0; +parameter MULT_RESET_MODE = "SYNC"; +endmodule + +module MULT18X18 (...); +input [17:0] A,SIA; +input [17:0] B,SIB; +input ASIGN,BSIGN; +input ASEL,BSEL; +input CE; +input CLK; +input RESET; +output [35:0] DOUT; +output [17:0] SOA,SOB; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter OUT_REG = 1'b0; +parameter PIPE_REG = 1'b0; +parameter ASIGN_REG = 1'b0; +parameter BSIGN_REG = 1'b0; +parameter SOA_REG = 1'b0; +parameter MULT_RESET_MODE = "SYNC"; +endmodule + +module MULT36X36 (...); +input [35:0] A; +input [35:0] B; +input ASIGN,BSIGN; +input CE; +input CLK; +input RESET; +output [71:0] DOUT; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter OUT0_REG = 1'b0; +parameter OUT1_REG = 1'b0; +parameter PIPE_REG = 1'b0; +parameter ASIGN_REG = 1'b0; +parameter BSIGN_REG = 1'b0; +parameter MULT_RESET_MODE = "SYNC"; +endmodule + +module MULTALU36X18 (...); +input [17:0] A; +input [35:0] B; +input [53:0] C; +input ASIGN,BSIGN,ACCLOAD; +input CE; +input CLK; +input RESET; +input [54:0] CASI; +output [53:0] DOUT; +output [54:0] CASO; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter CREG = 1'b0; +parameter OUT_REG = 1'b0; +parameter PIPE_REG = 1'b0; +parameter ASIGN_REG = 1'b0; +parameter BSIGN_REG = 1'b0; +parameter ACCLOAD_REG0 = 1'b0; +parameter ACCLOAD_REG1 = 1'b0; +parameter MULT_RESET_MODE = "SYNC"; +parameter MULTALU36X18_MODE = 0; +parameter C_ADD_SUB = 1'b0; +endmodule + +module MULTADDALU18X18 (...); +input [17:0] A0; +input [17:0] B0; +input [17:0] A1; +input [17:0] B1; +input [53:0] C; +input [17:0] SIA, SIB; +input [1:0] ASIGN, BSIGN; +input [1:0] ASEL, BSEL; +input [54:0] CASI; +input CE; +input CLK; +input RESET; +input ACCLOAD; +output [53:0] DOUT; +output [54:0] CASO; +output [17:0] SOA, SOB; +parameter A0REG = 1'b0; +parameter A1REG = 1'b0; +parameter B0REG = 1'b0; +parameter B1REG = 1'b0; +parameter CREG = 1'b0; +parameter PIPE0_REG = 1'b0; +parameter PIPE1_REG = 1'b0; +parameter OUT_REG = 1'b0; +parameter ASIGN0_REG = 1'b0; +parameter ASIGN1_REG = 1'b0; +parameter ACCLOAD_REG0 = 1'b0; +parameter ACCLOAD_REG1 = 1'b0; +parameter BSIGN0_REG = 1'b0; +parameter BSIGN1_REG = 1'b0; +parameter SOA_REG = 1'b0; +parameter B_ADD_SUB = 1'b0; +parameter C_ADD_SUB = 1'b0; +parameter MULTADDALU18X18_MODE = 0; +parameter MULT_RESET_MODE = "SYNC"; +endmodule + +module MULTALU18X18 (...); +input [17:0] A, B; +input CLK,CE,RESET; +input ASIGN, BSIGN; +input ACCLOAD,DSIGN; +input [53:0] C,D; +input [54:0] CASI; +output [53:0] DOUT; +output [54:0] CASO; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter CREG = 1'b0; +parameter DREG = 1'b0; +parameter DSIGN_REG = 1'b0; +parameter ASIGN_REG = 1'b0; +parameter BSIGN_REG = 1'b0; +parameter ACCLOAD_REG0 = 1'b0; +parameter ACCLOAD_REG1 = 1'b0; +parameter MULT_RESET_MODE = "SYNC"; +parameter PIPE_REG = 1'b0; +parameter OUT_REG = 1'b0; +parameter B_ADD_SUB = 1'b0; +parameter C_ADD_SUB = 1'b0; +parameter MULTALU18X18_MODE = 0; +endmodule + +module ALU54D (...); +input [53:0] A, B; +input ASIGN,BSIGN; +input ACCLOAD; +input [54:0] CASI; +input CLK, CE, RESET; +output [53:0] DOUT; +output [54:0] CASO; +parameter AREG = 1'b0; +parameter BREG = 1'b0; +parameter ASIGN_REG = 1'b0; +parameter BSIGN_REG = 1'b0; +parameter ACCLOAD_REG = 1'b0; +parameter OUT_REG = 1'b0; +parameter B_ADD_SUB = 1'b0; +parameter C_ADD_SUB = 1'b0; +parameter ALUD_MODE = 0; +parameter ALU_RESET_MODE = "SYNC"; +endmodule + +module BUFG (...); +output O; +input I; +endmodule + + +module BUFS (...); +output O; +input I; +endmodule + + +module PLL (...); +input CLKIN; +input CLKFB; +input RESET; +input RESET_P; +input RESET_I; +input RESET_S; +input [5:0] FBDSEL; +input [5:0] IDSEL; +input [5:0] ODSEL; +input [3:0] PSDA,FDLY; +input [3:0] DUTYDA; +output CLKOUT; +output LOCK; +output CLKOUTP; +output CLKOUTD; +output CLKOUTD3; +parameter FCLKIN = "100.0"; +parameter DYN_IDIV_SEL= "false"; +parameter IDIV_SEL = 0; +parameter DYN_FBDIV_SEL= "false"; +parameter FBDIV_SEL = 0; +parameter DYN_ODIV_SEL= "false"; +parameter ODIV_SEL = 8; +parameter PSDA_SEL= "0000"; +parameter DYN_DA_EN = "false"; +parameter DUTYDA_SEL= "1000"; +parameter CLKOUT_FT_DIR = 1'b1; +parameter CLKOUTP_FT_DIR = 1'b1; +parameter CLKOUT_DLY_STEP = 0; +parameter CLKOUTP_DLY_STEP = 0; +parameter CLKFB_SEL = "internal"; +parameter CLKOUT_BYPASS = "false"; +parameter CLKOUTP_BYPASS = "false"; +parameter CLKOUTD_BYPASS = "false"; +parameter DYN_SDIV_SEL = 2; +parameter CLKOUTD_SRC = "CLKOUT"; +parameter CLKOUTD3_SRC = "CLKOUT"; +parameter DEVICE = "GW1N-4"; +endmodule + +module TLVDS_IBUF (...); +output O; +input I, IB; +endmodule + +module TLVDS_TBUF (...); +output O, OB; +input I, OEN; +endmodule + +module TLVDS_IOBUF (...); +output O; +inout IO, IOB; +input I, OEN; +endmodule + +module ELVDS_IBUF (...); +output O; +input I, IB; +endmodule + +module ELVDS_TBUF (...); +output O, OB; +input I, OEN; +endmodule + +module ELVDS_IOBUF (...); +output O; +inout IO, IOB; +input I, OEN; +endmodule + +module MIPI_IBUF (...); +output OH, OL, OB; +inout IO, IOB; +input I, IB; +input OEN, OENB; +input HSREN; +endmodule + +module MIPI_IBUF_HS (...); +output OH; +input I, IB; +endmodule + +module MIPI_IBUF_LP (...); +output OL; +output OB; +input I; +input IB; +endmodule + +module MIPI_OBUF (...); +output O, OB; +input I, IB, MODESEL; +endmodule + +module MIPI_OBUF_A (...); +output O, OB; +input I, IB, IL, MODESEL; +endmodule + +module I3C_IOBUF (...); +output O; +inout IO; +input I, MODESEL; +endmodule + +module CLKDIV (...); +input HCLKIN; +input RESETN; +input CALIB; +output CLKOUT; +parameter DIV_MODE = "2"; +parameter GSREN = "false"; +endmodule + +module DHCEN (...); +input CLKIN,CE; +output CLKOUT; +endmodule + +module DLL (...); +input CLKIN; +input STOP; +input UPDNCNTL; +input RESET; +output [7:0]STEP; +output LOCK; +parameter DLL_FORCE = 0; +parameter CODESCAL="000"; +parameter SCAL_EN="true"; +parameter DIV_SEL = 1'b0; +endmodule + +module DLLDLY (...); +input CLKIN; +input [7:0] DLLSTEP; +input DIR,LOADN,MOVE; +output CLKOUT; +output FLAG; +parameter DLL_INSEL = 1'b1; +parameter DLY_SIGN = 1'b0; +parameter DLY_ADJ = 0; +endmodule + +module FLASH96K (...); +input [5:0] RA,CA,PA; +input [3:0] MODE; +input [1:0] SEQ; +input ACLK,PW,RESET,PE,OE; +input [1:0] RMODE,WMODE; +input [1:0] RBYTESEL,WBYTESEL; +input [31:0] DIN; +output [31:0] DOUT; +endmodule + +module FLASH256K (...); +input[6:0]XADR; +input[5:0]YADR; +input XE,YE,SE; +input ERASE,PROG,NVSTR; +input [31:0] DIN; +output reg [31:0] DOUT; +parameter IDLE = 4'd0, + ERA_S1 = 4'd1, + ERA_S2 = 4'd2, + ERA_S3 = 4'd3, + ERA_S4 = 4'd4, + ERA_S5 = 4'd5, + PRO_S1 = 4'd6, + PRO_S2 = 4'd7, + PRO_S3 = 4'd8, + PRO_S4 = 4'd9, + PRO_S5 = 4'd10, + RD_S1 = 4'd11, + RD_S2 = 4'd12; +endmodule + +module FLASH608K (...); +input[8:0]XADR; +input[5:0]YADR; +input XE,YE,SE; +input ERASE,PROG,NVSTR; +input [31:0] DIN; +output reg [31:0] DOUT; +parameter IDLE = 4'd0, + ERA_S1 = 4'd1, + ERA_S2 = 4'd2, + ERA_S3 = 4'd3, + ERA_S4 = 4'd4, + ERA_S5 = 4'd5, + PRO_S1 = 4'd6, + PRO_S2 = 4'd7, + PRO_S3 = 4'd8, + PRO_S4 = 4'd9, + PRO_S5 = 4'd10, + RD_S1 = 4'd11, + RD_S2 = 4'd12; +endmodule + +module DCS (...); +input CLK0, CLK1, CLK2, CLK3, SELFORCE; +input [3:0] CLKSEL; +output CLKOUT; +endmodule + +module DQCE (...); +input CLKIN; +input CE; +output CLKOUT; +endmodule + +module FLASH128K (...); +input [31:0] DIN; +input [14:0] ADDR; +input CS,AE,OE; +input PCLK; +input PROG, SERA, MASE; +input NVSTR; +input IFREN; +input RESETN; +output [31:0] DOUT; +output TBIT; +parameter IDLE = 4'd0, + READ_S1 = 4'd1, + READ_S2 = 4'd2, + PROG_S1 = 4'd3, + PROG_S2 = 4'd4, + PROG_S3 = 4'd5, + PROG_S4 = 4'd6, + SERA_S1 = 4'd7, + SERA_S2 = 4'd8, + SERA_S3 = 4'd9, + SERA_S4 = 4'd10, + MASE_S1 = 4'd11, + MASE_S2 = 4'd12, + MASE_S3 = 4'd13, + MASE_S4 = 4'd14; +endmodule + +module MCU (...); +endmodule + +module USB20_PHY (...); +parameter DATABUS16_8 = 1'b0; +parameter ADP_PRBEN = 1'b0; +parameter TEST_MODE = 5'b00000; +parameter HSDRV1 = 1'b0; +parameter HSDRV0 = 1'b0; +parameter CLK_SEL = 1'b0; +parameter M = 4'b0000; +parameter N = 6'b101000; +parameter C = 2'b01; +parameter FOC_LOCK = 1'b0; +input [15:0] DATAIN; +input TXVLD; +input TXVLDH; +input RESET; +input SUSPENDM; +input [1:0] XCVRSEL; +input TERMSEL; +input [1:0] OPMODE; +output [15:0] DATAOUT; +output TXREADY; +output RXACTIVE; +output RXVLD; +output RXVLDH; +output CLK; +output RXERROR; +inout DP; +inout DM; +output [1:0] LINESTATE; +input IDPULLUP; +input DPPD; +input DMPD; +input CHARGVBUS; +input DISCHARGVBUS; +input TXBITSTUFFEN; +input TXBITSTUFFENH; +input TXENN; +input TXDAT; +input TXSE0; +input FSLSSERIAL; +output HOSTDIS; +output IDDIG; +output ADPPRB; +output ADPSNS; +output SESSVLD; +output VBUSVLD; +output RXDP; +output RXDM; +output RXRCV; +output LBKERR; +output CLKRDY; +input INTCLK; +inout ID; +inout VBUS; +inout REXT; +input XIN; +inout XOUT; +input TEST; +output CLK480PAD; +input SCANCLK; +input SCANEN; +input SCANMODE; +input TRESETN; +input SCANIN1; +output SCANOUT1; +input SCANIN2; +output SCANOUT2; +input SCANIN3; +output SCANOUT3; +input SCANIN4; +output SCANOUT4; +input SCANIN5; +output SCANOUT5; +input SCANIN6; +output SCANOUT6; +endmodule + +module ADC (...); +endmodule + +module BANDGAP (...); +input BGEN; +endmodule + +module CLKDIV2 (...); +parameter GSREN = "false"; +input HCLKIN, RESETN; +output CLKOUT; +endmodule + +module DCC (...); +output CLKOUT; +input CLKIN; +parameter DCC_EN = 1'b1; +parameter FCLKIN = 50.0; +endmodule + +module DHCENC (...); +input CLKIN, CE; +output CLKOUT, CLKOUTN; +endmodule + +module EMCU (...); +endmodule + +module FLASH64K (...); +input[4:0]XADR; +input[5:0]YADR; +input XE,YE,SE; +input ERASE,PROG,NVSTR; +input SLEEP; +input [31:0] DIN; +output reg [31:0] DOUT; +parameter IDLE = 4'd0, + ERA_S1 = 4'd1, + ERA_S2 = 4'd2, + ERA_S3 = 4'd3, + ERA_S4 = 4'd4, + ERA_S5 = 4'd5, + PRO_S1 = 4'd6, + PRO_S2 = 4'd7, + PRO_S3 = 4'd8, + PRO_S4 = 4'd9, + PRO_S5 = 4'd10, + RD_S1 = 4'd11, + RD_S2 = 4'd12; +endmodule + +module FLASH64KZ (...); +input[4:0]XADR; +input[5:0]YADR; +input XE,YE,SE; +input ERASE,PROG,NVSTR; +input [31:0] DIN; +output reg [31:0] DOUT; +parameter IDLE = 4'd0, + ERA_S1 = 4'd1, + ERA_S2 = 4'd2, + ERA_S3 = 4'd3, + ERA_S4 = 4'd4, + ERA_S5 = 4'd5, + PRO_S1 = 4'd6, + PRO_S2 = 4'd7, + PRO_S3 = 4'd8, + PRO_S4 = 4'd9, + PRO_S5 = 4'd10, + RD_S1 = 4'd11, + RD_S2 = 4'd12; +endmodule + +module I3C (...); +parameter ADDRESS = 7'b0000000; +input LGYS, CMS, ACS, AAS, STOPS, STRTS; +output LGYO, CMO, ACO, AAO, SIO, STOPO, STRTO; +input LGYC, CMC, ACC, AAC, SIC, STOPC, STRTC; +input STRTHDS, SENDAHS, SENDALS, ACKHS; +input ACKLS, STOPSUS, STOPHDS, SENDDHS; +input SENDDLS, RECVDHS, RECVDLS, ADDRS; +output PARITYERROR; +input [7:0] DI; +output [7:0] DOBUF; +output [7:0] DO; +output [7:0] STATE; +input SDAI, SCLI; +output SDAO, SCLO; +output SDAOEN, SCLOEN; +output SDAPULLO, SCLPULLO; +output SDAPULLOEN, SCLPULLOEN; +input CE, RESET, CLK; +endmodule + +module IODELAYA (...); +parameter C_STATIC_DLY = 0; +input DI; +input SDTAP; +input SETN; +input VALUE; +output DF; +output DO; +endmodule + +module IODELAYC (...); +parameter C_STATIC_DLY = 0; +parameter DYN_DA_SEL = "false"; +parameter DA_SEL = 2'b00; +input DI; +input SDTAP; +input SETN; +input VALUE; +input [1:0] DASEL; +input [1:0] DAADJ; +output DF; +output DO; +output DAO; +endmodule + + +module SPMI (...); +parameter FUNCTION_CTRL = 7'b0000000; +parameter MSID_CLKSEL = 7'b0000000; +parameter RESPOND_DELAY = 4'b0000; +parameter SCLK_NORMAL_PERIOD = 7'b0000000; +parameter SCLK_LOW_PERIOD = 7'b0000000; +parameter CLK_FREQ = 7'b0000000; +parameter SHUTDOWN_BY_ENABLE = 1'b0; +input CLKEXT, ENEXT; +inout SDATA, SCLK; +input CLK, CE, RESETN, LOCRESET; +input PA, SA, CA; +input [3:0] ADDRI; +input [7:0] DATAI; +output [3:0] ADDRO; +output [7:0] DATAO; +output [15:0] STATE; +output [3:0] CMD; +endmodule + +module IODELAYB (...); +parameter C_STATIC_DLY = 0; +parameter DELAY_MUX = 2'b00; +parameter DA_SEL = 2'b00; +input DI; +input SDTAP; +input SETN; +input VALUE; +input [1:0] DAADJ; +output DF; +output DO; +output DAO; +endmodule + + +module PLLO (...); +input CLKIN; +input CLKFB; +input RESET; +input RESET_P; +input RESET_I; +input RESET_S; +input [5:0] FBDSEL; +input [5:0] IDSEL; +input [6:0] ODSELA; +input [6:0] ODSELB; +input [6:0] ODSELC; +input [6:0] ODSELD; +input [3:0] DTA; +input [3:0] DTB; +input [4:0] ICPSEL; +input [2:0] LPFRES; +input [1:0] PSSEL; +input PSDIR; +input PSPULSE; +input ENCLKA; +input ENCLKB; +input ENCLKC; +input ENCLKD; +output LOCK; +output CLKOUTA; +output CLKOUTB; +output CLKOUTC; +output CLKOUTD; +parameter FCLKIN = "100.0"; +parameter DYN_IDIV_SEL= "FALSE"; +parameter IDIV_SEL = 0; +parameter DYN_FBDIV_SEL= "FALSE"; +parameter FBDIV_SEL = 0; +parameter DYN_ODIVA_SEL= "FALSE"; +parameter ODIVA_SEL = 6; +parameter DYN_ODIVB_SEL= "FALSE"; +parameter ODIVB_SEL = 6; +parameter DYN_ODIVC_SEL= "FALSE"; +parameter ODIVC_SEL = 6; +parameter DYN_ODIVD_SEL= "FALSE"; +parameter ODIVD_SEL = 6; +parameter CLKOUTA_EN = "TRUE"; +parameter CLKOUTB_EN = "TRUE"; +parameter CLKOUTC_EN = "TRUE"; +parameter CLKOUTD_EN = "TRUE"; +parameter DYN_DTA_SEL = "FALSE"; +parameter DYN_DTB_SEL = "FALSE"; +parameter CLKOUTA_DT_DIR = 1'b1; +parameter CLKOUTB_DT_DIR = 1'b1; +parameter CLKOUTA_DT_STEP = 0; +parameter CLKOUTB_DT_STEP = 0; +parameter CLKA_IN_SEL = 2'b00; +parameter CLKA_OUT_SEL = 1'b0; +parameter CLKB_IN_SEL = 2'b00; +parameter CLKB_OUT_SEL = 1'b0; +parameter CLKC_IN_SEL = 2'b00; +parameter CLKC_OUT_SEL = 1'b0; +parameter CLKD_IN_SEL = 2'b00; +parameter CLKD_OUT_SEL = 1'b0; +parameter CLKFB_SEL = "INTERNAL"; +parameter DYN_DPA_EN = "FALSE"; +parameter DYN_PSB_SEL = "FALSE"; +parameter DYN_PSC_SEL = "FALSE"; +parameter DYN_PSD_SEL = "FALSE"; +parameter PSB_COARSE = 1; +parameter PSB_FINE = 0; +parameter PSC_COARSE = 1; +parameter PSC_FINE = 0; +parameter PSD_COARSE = 1; +parameter PSD_FINE = 0; +parameter DTMS_ENB = "FALSE"; +parameter DTMS_ENC = "FALSE"; +parameter DTMS_END = "FALSE"; +parameter RESET_I_EN = "FALSE"; +parameter RESET_S_EN = "FALSE"; +parameter DYN_ICP_SEL= "FALSE"; +parameter ICP_SEL = 5'bXXXXX; +parameter DYN_RES_SEL= "FALSE"; +parameter LPR_REF = 7'bXXXXXXX; +endmodule + +module DCCG (...); +output CLKOUT; +input CLKIN; +parameter DCC_MODE = 2'b00; +parameter FCLKIN = 50.0; +endmodule + +module FLASH96KA (...); +input[5:0]XADR; +input[5:0]YADR; +input XE,YE,SE; +input ERASE,PROG,NVSTR; +input [31:0] DIN; +input SLEEP; +output reg [31:0] DOUT; +parameter IDLE = 4'd0, + ERA_S1 = 4'd1, + ERA_S2 = 4'd2, + ERA_S3 = 4'd3, + ERA_S4 = 4'd4, + ERA_S5 = 4'd5, + PRO_S1 = 4'd6, + PRO_S2 = 4'd7, + PRO_S3 = 4'd8, + PRO_S4 = 4'd9, + PRO_S5 = 4'd10, + RD_S1 = 4'd11, + RD_S2 = 4'd12; +endmodule + +module MIPI_DPHY_RX (...); +output [15:0] D0LN_HSRXD, D1LN_HSRXD, D2LN_HSRXD, D3LN_HSRXD; +output D0LN_HSRXD_VLD,D1LN_HSRXD_VLD,D2LN_HSRXD_VLD,D3LN_HSRXD_VLD; +output DI_LPRX0_N, DI_LPRX0_P, DI_LPRX1_N, DI_LPRX1_P, DI_LPRX2_N, DI_LPRX2_P, DI_LPRX3_N, DI_LPRX3_P; +output DI_LPRXCK_N, DI_LPRXCK_P; +output RX_CLK_O; +output DESKEW_ERROR; +inout CK_N, CK_P, RX0_N, RX0_P, RX1_N, RX1_P, RX2_N, RX2_P, RX3_N, RX3_P; +input LPRX_EN_CK, LPRX_EN_D0, LPRX_EN_D1, LPRX_EN_D2, LPRX_EN_D3; +input HSRX_ODTEN_CK, HSRX_ODTEN_D0, HSRX_ODTEN_D1, HSRX_ODTEN_D2, HSRX_ODTEN_D3; +input D0LN_HSRX_DREN, D1LN_HSRX_DREN, D2LN_HSRX_DREN, D3LN_HSRX_DREN; +input HSRX_EN_CK; +input HS_8BIT_MODE; +input RX_CLK_1X; +input RX_INVERT; +input LALIGN_EN; +input WALIGN_BY; +input DO_LPTX0_N, DO_LPTX0_P, DO_LPTX1_N, DO_LPTX1_P, DO_LPTX2_N, DO_LPTX2_P, DO_LPTX3_N, DO_LPTX3_P; +input DO_LPTXCK_N, DO_LPTXCK_P; +input LPTX_EN_CK, LPTX_EN_D0, LPTX_EN_D1, LPTX_EN_D2, LPTX_EN_D3; +input BYTE_LENDIAN; +input HSRX_STOP; +input LPRX_ULP_LN0, LPRX_ULP_LN1, LPRX_ULP_LN2, LPRX_ULP_LN3, LPRX_ULP_CK; +input PWRON; +input RESET; +input [2:0] DESKEW_LNSEL; +input [7:0] DESKEW_MTH; +input [6:0] DESKEW_OWVAL; +input DESKEW_REQ; +input DRST_N; +input ONE_BYTE0_MATCH; +input WORD_LENDIAN; +input [2:0] FIFO_RD_STD; +parameter ALIGN_BYTE = 8'b10111000; +parameter MIPI_LANE0_EN = 1'b0; +parameter MIPI_LANE1_EN = 1'b0; +parameter MIPI_LANE2_EN = 1'b0; +parameter MIPI_LANE3_EN = 1'b0; +parameter MIPI_CK_EN = 1'b1; +parameter SYNC_CLK_SEL = 1'b1; +endmodule + +module CLKDIVG (...); +input CLKIN; +input RESETN; +input CALIB; +output CLKOUT; +parameter DIV_MODE = "2"; +parameter GSREN = "false"; +endmodule diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index 0dffdf498b3..3b9d7424a7b 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -207,6 +207,7 @@ struct SynthGowinPass : public ScriptPass if (check_label("begin")) { run("read_verilog -specify -lib +/gowin/cells_sim.v"); + run("read_verilog -specify -lib +/gowin/cells_xtra.v"); run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); } From 861142923719aa84afc3bdf3c24a9a36e5d5fbaf Mon Sep 17 00:00:00 2001 From: Benjamin Barzen Date: Sun, 23 Apr 2023 01:24:36 +0200 Subject: [PATCH 077/303] ABC9: Cell Port Bug Patch (#3670) * ABC9: RAMB36E1 Bug Patch * Add simplified testcase * Also fix xaiger writer for under-width output ports * Remove old testcase * Missing top-level input port * Fix tabs --------- Co-authored-by: Eddie Hung --- backends/aiger/xaiger.cc | 6 +++++- passes/techmap/abc9_ops.cc | 6 +++++- tests/arch/xilinx/bug3670.v | 13 +++++++++++++ tests/arch/xilinx/bug3670.ys | 3 +++ 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tests/arch/xilinx/bug3670.v create mode 100644 tests/arch/xilinx/bug3670.ys diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index e223f185e5e..68c2ff52f55 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -274,6 +274,10 @@ struct XAigerWriter continue; auto offset = i.first.offset; + auto rhs = cell->getPort(i.first.name); + if (offset >= rhs.size()) + continue; + #ifndef NDEBUG if (ys_debug(1)) { static pool> seen; @@ -281,7 +285,7 @@ struct XAigerWriter log_id(cell->type), log_id(i.first.name), offset, d); } #endif - arrival_times[cell->getPort(i.first.name)[offset]] = d; + arrival_times[rhs[offset]] = d; } if (abc9_flop) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 9766e81cbf0..ed4d4bdfb04 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -674,8 +674,12 @@ void prep_delays(RTLIL::Design *design, bool dff_mode) continue; auto offset = i.first.offset; - auto O = module->addWire(NEW_ID); + if (!cell->hasPort(i.first.name)) + continue; auto rhs = cell->getPort(i.first.name); + if (offset >= rhs.size()) + continue; + auto O = module->addWire(NEW_ID); #ifndef NDEBUG if (ys_debug(1)) { diff --git a/tests/arch/xilinx/bug3670.v b/tests/arch/xilinx/bug3670.v new file mode 100644 index 00000000000..c7dd1807923 --- /dev/null +++ b/tests/arch/xilinx/bug3670.v @@ -0,0 +1,13 @@ +module bug3670(input we, output [31:0] o1, o2, output o3); + // Completely missing port connections, where first affected port + // (ADDRARDADDR) has a $setup delay + RAMB36E1 ram1(.DOADO(o1)); + + // Under-specified input port connections (WEA is 4 bits) which + // has a $setup delay + RAMB36E1 ram2(.WEA(we), .DOADO(o2)); + + // Under-specified output port connections (DOADO is 32 bits) + // with clk-to-q delay + RAMB36E1 ram3(.DOADO(o3)); +endmodule diff --git a/tests/arch/xilinx/bug3670.ys b/tests/arch/xilinx/bug3670.ys new file mode 100644 index 00000000000..772072c1ee4 --- /dev/null +++ b/tests/arch/xilinx/bug3670.ys @@ -0,0 +1,3 @@ +read_verilog bug3670.v +read_verilog -lib -specify +/xilinx/cells_sim.v +abc9 From 51dd0290241c521f5498f71f4fd4fb0598d83a76 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 23 Apr 2023 00:17:11 +0000 Subject: [PATCH 078/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 63e5a88d7f2..1fcd1914922 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28+4 +YOSYS_VER := 0.28+6 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 7bff8b63b366e1e9c8308a235133600afac757e8 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 25 Apr 2023 12:39:00 +0200 Subject: [PATCH 079/303] rename: Fix renaming cells in -witness mode This was renaming cells while iterating over them which would always cause an assertion failure. Apparently having to rename cells to make all witness signals public is rarely required, so this slipped through. --- passes/cmds/rename.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 45576c91c2b..6bd317ed0e4 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -116,6 +116,8 @@ static bool rename_witness(RTLIL::Design *design, dict &ca } cache.emplace(module, -1); + std::vector> renames; + bool has_witness_signals = false; for (auto cell : module->cells()) { @@ -130,8 +132,9 @@ static bool rename_witness(RTLIL::Design *design, dict &ca c = '_'; auto new_id = module->uniquify("\\_witness_." + name); cell->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 }); - module->rename(cell, new_id); + renames.emplace_back(cell, new_id); } + break; } if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) { @@ -155,6 +158,9 @@ static bool rename_witness(RTLIL::Design *design, dict &ca } } } + for (auto rename : renames) { + module->rename(rename.first, rename.second); + } cache[module] = has_witness_signals; return has_witness_signals; From 30f1d109484141c9fd0b398bef59f6883af35aa8 Mon Sep 17 00:00:00 2001 From: Ralf Fuest Date: Mon, 1 May 2023 17:56:41 +0200 Subject: [PATCH 080/303] gowin: Fix X output of $alu techmap --- techlibs/gowin/arith_map.v | 2 +- tests/arch/gowin/compare.v | 20 ++++++++++++++++++++ tests/arch/gowin/compare.ys | 9 +++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/arch/gowin/compare.v create mode 100644 tests/arch/gowin/compare.ys diff --git a/techlibs/gowin/arith_map.v b/techlibs/gowin/arith_map.v index 2d48fa752a2..828bb35b8d3 100644 --- a/techlibs/gowin/arith_map.v +++ b/techlibs/gowin/arith_map.v @@ -62,6 +62,6 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO); .SUM(Y[i]) ); end endgenerate - assign X = AA ^ BB; + assign X = AA ^ BB ^ {Y_WIDTH{BI}}; endmodule diff --git a/tests/arch/gowin/compare.v b/tests/arch/gowin/compare.v new file mode 100644 index 00000000000..0ed3c2fa4f9 --- /dev/null +++ b/tests/arch/gowin/compare.v @@ -0,0 +1,20 @@ +module top +( + input [4:0] x, + input [4:0] y, + + output lt, + output le, + output gt, + output ge, + output eq, + output ne +); + + assign lt = x < y; + assign le = x <= y; + assign gt = x > y; + assign ge = x >= y; + assign eq = x == y; + assign ne = x != y; +endmodule diff --git a/tests/arch/gowin/compare.ys b/tests/arch/gowin/compare.ys new file mode 100644 index 00000000000..a3aba6dea90 --- /dev/null +++ b/tests/arch/gowin/compare.ys @@ -0,0 +1,9 @@ +read_verilog compare.v +hierarchy -top top +proc +equiv_opt -assert -map +/gowin/cells_sim.v synth_gowin # equivalency check +design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) +cd top # Constrain all select calls below inside the top module +select -assert-count 5 t:ALU + + From 572c8df9a86e3040d13b403976f0c23191c99d78 Mon Sep 17 00:00:00 2001 From: Aki Van Ness Date: Wed, 3 May 2023 02:22:46 -0400 Subject: [PATCH 081/303] plugin: Re-vamped how plugin lookup was done to make it more consistent with the rest of yosys, and prevented a case where you could end up with `.so.so` on the end --- passes/cmds/plugin.cc | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 3a1ae2850b5..85aae239db1 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -21,12 +21,12 @@ #ifdef YOSYS_ENABLE_PLUGINS # include +# include +# include #endif #ifdef WITH_PYTHON -# include # include -# include #endif YOSYS_NAMESPACE_BEGIN @@ -41,20 +41,18 @@ std::map loaded_plugin_aliases; void load_plugin(std::string filename, std::vector aliases) { std::string orig_filename = filename; + rewrite_filename(filename); + boost::filesystem::path full_path(filename); - if (filename.find('/') == std::string::npos) - filename = "./" + filename; #ifdef WITH_PYTHON - if (!loaded_plugins.count(filename) && !loaded_python_plugins.count(filename)) { + if (!loaded_plugins.count(orig_filename) && !loaded_python_plugins.count(orig_filename)) { #else - if (!loaded_plugins.count(filename)) { + if (!loaded_plugins.count(orig_filename)) { #endif #ifdef WITH_PYTHON - boost::filesystem::path full_path(filename); - if(strcmp(full_path.extension().c_str(), ".py") == 0) { std::string path(full_path.parent_path().c_str()); @@ -75,10 +73,23 @@ void load_plugin(std::string filename, std::vector aliases) #endif void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); - if (hdl == NULL && orig_filename.find('/') == std::string::npos) - hdl = dlopen((proc_share_dirname() + "plugins/" + orig_filename + ".so").c_str(), RTLD_LAZY|RTLD_LOCAL); + + // We were unable to open the file, try to do so from the plugin directory + if (hdl == NULL && filename.find('/') == std::string::npos) { + hdl = dlopen([filename]() { + std::string new_path = proc_share_dirname() + "plugins/" + filename; + + // Check if we need to append .so + if (new_path.find(".so") == std::string::npos) + new_path.append(".so"); + + return new_path; + }().c_str(), RTLD_LAZY|RTLD_LOCAL); + } + if (hdl == NULL) log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); + loaded_plugins[orig_filename] = hdl; Pass::init_register(); @@ -182,4 +193,3 @@ struct PluginPass : public Pass { } PluginPass; YOSYS_NAMESPACE_END - From bb240665b7da95687e60379c1a71dfb97c9cc820 Mon Sep 17 00:00:00 2001 From: Aki Van Ness Date: Wed, 3 May 2023 02:50:23 -0400 Subject: [PATCH 082/303] plugin: shuffled the `#ifdef WITH_PYTHON`'s around to un-tangle the code and pulled out the check for the `.py` extension so it will complain if you try to load a python extension without python support --- passes/cmds/plugin.cc | 87 ++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/passes/cmds/plugin.cc b/passes/cmds/plugin.cc index 85aae239db1..08b4aa8c4ee 100644 --- a/passes/cmds/plugin.cc +++ b/passes/cmds/plugin.cc @@ -21,12 +21,12 @@ #ifdef YOSYS_ENABLE_PLUGINS # include -# include -# include #endif #ifdef WITH_PYTHON +# include # include +# include #endif YOSYS_NAMESPACE_BEGIN @@ -42,60 +42,69 @@ void load_plugin(std::string filename, std::vector aliases) { std::string orig_filename = filename; rewrite_filename(filename); - boost::filesystem::path full_path(filename); + + // Would something like this better be put in `rewrite_filename`? + if (filename.find("/") == std::string::npos) + filename = "./" + filename; #ifdef WITH_PYTHON - if (!loaded_plugins.count(orig_filename) && !loaded_python_plugins.count(orig_filename)) { + const bool is_loaded = loaded_plugins.count(orig_filename) && loaded_python_plugins.count(orig_filename); #else - if (!loaded_plugins.count(orig_filename)) { + const bool is_loaded = loaded_plugins.count(orig_filename); #endif - #ifdef WITH_PYTHON - - if(strcmp(full_path.extension().c_str(), ".py") == 0) + if (!is_loaded) { + // Check if we're loading a python script + if(filename.find(".py") != std::string::npos) { - std::string path(full_path.parent_path().c_str()); - filename = full_path.filename().c_str(); - filename = filename.substr(0,filename.size()-3); - PyRun_SimpleString(("sys.path.insert(0,\""+path+"\")").c_str()); - PyErr_Print(); - PyObject *module_p = PyImport_ImportModule(filename.c_str()); - if(module_p == NULL) - { + #ifdef WITH_PYTHON + boost::filesystem::path full_path(filename); + std::string path(full_path.parent_path().c_str()); + filename = full_path.filename().c_str(); + filename = filename.substr(0,filename.size()-3); + PyRun_SimpleString(("sys.path.insert(0,\""+path+"\")").c_str()); PyErr_Print(); - log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str()); - return; - } - loaded_python_plugins[orig_filename] = module_p; - Pass::init_register(); + PyObject *module_p = PyImport_ImportModule(filename.c_str()); + if(module_p == NULL) + { + PyErr_Print(); + log_cmd_error("Can't load python module `%s'\n", full_path.filename().c_str()); + return; + } + loaded_python_plugins[orig_filename] = module_p; + Pass::init_register(); + #else + log_error( + "\n This version of Yosys cannot load python plugins.\n" + " Ensure Yosys is built with Python support to do so.\n" + ); + #endif } else { - #endif + // Otherwise we assume it's a native plugin - void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); + void *hdl = dlopen(filename.c_str(), RTLD_LAZY|RTLD_LOCAL); - // We were unable to open the file, try to do so from the plugin directory - if (hdl == NULL && filename.find('/') == std::string::npos) { - hdl = dlopen([filename]() { - std::string new_path = proc_share_dirname() + "plugins/" + filename; + // We were unable to open the file, try to do so from the plugin directory + if (hdl == NULL && orig_filename.find('/') == std::string::npos) { + hdl = dlopen([orig_filename]() { + std::string new_path = proc_share_dirname() + "plugins/" + orig_filename; - // Check if we need to append .so - if (new_path.find(".so") == std::string::npos) - new_path.append(".so"); + // Check if we need to append .so + if (new_path.find(".so") == std::string::npos) + new_path.append(".so"); - return new_path; - }().c_str(), RTLD_LAZY|RTLD_LOCAL); - } + return new_path; + }().c_str(), RTLD_LAZY|RTLD_LOCAL); + } - if (hdl == NULL) - log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); + if (hdl == NULL) + log_cmd_error("Can't load module `%s': %s\n", filename.c_str(), dlerror()); - loaded_plugins[orig_filename] = hdl; - Pass::init_register(); + loaded_plugins[orig_filename] = hdl; + Pass::init_register(); - #ifdef WITH_PYTHON } - #endif } for (auto &alias : aliases) From ad437c178da6c1842983209a15259b5c6542d90e Mon Sep 17 00:00:00 2001 From: Dag Lem Date: Thu, 2 Mar 2023 19:02:30 +0100 Subject: [PATCH 083/303] Handling of attributes for struct / union variables (* nowrshmsk *) on a struct / union variable now affects dynamic bit slice assignments to members of the struct / union. (* nowrshmsk *) can in some cases yield significant resource savings; the combination of pipeline shifting and indexed writes is an example of this. Constructs similar to the one below can benefit from (* nowrshmsk *), and in addition it is no longer necessary to split out the shift assignments on separate lines in order to avoid the error message "ERROR: incompatible mix of lookahead and non-lookahead IDs in LHS expression." always_ff @(posedge clk) begin if (rotate) begin { v5, v4, v3, v2, v1, v0 } <= { v4, v3, v2, v1, v0, v5 }; if (res) begin v0.bytes <= '0; end else if (w) begin v0.bytes[addr] <= data; end end end --- frontends/ast/simplify.cc | 25 ++++++++++++++++++++----- frontends/verilog/verilog_parser.y | 7 ++++++- tests/svtypes/.gitignore | 1 + tests/svtypes/struct_dynamic_range.sv | 4 ++-- tests/svtypes/struct_dynamic_range.ys | 4 ++++ 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index dfb1b890c7f..1efd1b24dbc 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -557,7 +557,7 @@ static int get_max_offset(AstNode *node) return node->range_left; } -static AstNode *make_packed_struct(AstNode *template_node, std::string &name) +static AstNode *make_packed_struct(AstNode *template_node, std::string &name, decltype(AstNode::attributes) &attributes) { // create a wire for the packed struct auto wnode = new AstNode(AST_WIRE); @@ -565,6 +565,9 @@ static AstNode *make_packed_struct(AstNode *template_node, std::string &name) wnode->is_logic = true; wnode->range_valid = true; wnode->is_signed = template_node->is_signed; + for (auto &pair : attributes) { + wnode->attributes[pair.first] = pair.second->clone(); + } int offset = get_max_offset(template_node); auto range = make_range(offset, 0); wnode->children.push_back(range); @@ -1368,7 +1371,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // instance rather than just a type in a typedef or outer struct? if (!str.empty() && str[0] == '\\') { // instance so add a wire for the packed structure - auto wnode = make_packed_struct(this, str); + auto wnode = make_packed_struct(this, str, attributes); log_assert(current_ast_mod); current_ast_mod->children.push_back(wnode); } @@ -1792,7 +1795,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) { // replace with wire representing the packed structure - newNode = make_packed_struct(template_node, str); + newNode = make_packed_struct(template_node, str, attributes); newNode->attributes[ID::wiretype] = mkconst_str(resolved_type_node->str); // add original input/output attribute to resolved wire newNode->is_input = this->is_input; @@ -1857,7 +1860,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) { // replace with wire representing the packed structure - newNode = make_packed_struct(template_node, str); + newNode = make_packed_struct(template_node, str, attributes); newNode->attributes[ID::wiretype] = mkconst_str(resolved_type_node->str); newNode->type = type; current_scope[str] = this; @@ -2709,11 +2712,23 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int source_width = children[0]->id2ast->range_left - children[0]->id2ast->range_right + 1; int source_offset = children[0]->id2ast->range_right; int result_width = 1; + int stride = 1; AST::AstNode *member_node = get_struct_member(children[0]); if (member_node) { // Clamp chunk to range of member within struct/union. log_assert(!source_offset && !children[0]->id2ast->range_swapped); source_width = member_node->range_left - member_node->range_right + 1; + + // When the (* nowrshmsk *) attribute is set, a CASE block is generated below + // to select the indexed bit slice. When a multirange array is indexed, the + // start of each possible slice is separated by the bit stride of the last + // index dimension, and we can optimize the CASE block accordingly. + // The dimension of the original array expression is saved in the 'integer' field. + int dims = children[0]->integer; + stride = source_width; + for (int dim = 0; dim < dims; dim++) { + stride /= get_struct_range_width(member_node, dim); + } } AstNode *shift_expr = NULL; @@ -2754,7 +2769,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, did_something = true; newNode = new AstNode(AST_CASE, shift_expr); - for (int i = 0; i < source_width; i++) { + for (int i = 0; i < source_width; i += stride) { int start_bit = source_offset + i; int end_bit = std::min(start_bit+result_width,source_width) - 1; AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit, true)); diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 96413afb0b6..4c5bd0b10a9 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1809,7 +1809,12 @@ enum_decl: enum_type enum_var_list ';' { delete $1; } // struct or union ////////////////// -struct_decl: struct_type struct_var_list ';' { delete astbuf2; } +struct_decl: + attr struct_type { + append_attr($2, $1); + } struct_var_list ';' { + delete astbuf2; + } ; struct_type: struct_union { astbuf2 = $1; } struct_body { $$ = astbuf2; } diff --git a/tests/svtypes/.gitignore b/tests/svtypes/.gitignore index b48f808a1e3..75154e735d8 100644 --- a/tests/svtypes/.gitignore +++ b/tests/svtypes/.gitignore @@ -1,3 +1,4 @@ /*.log /*.out /run-test.mk +/temp diff --git a/tests/svtypes/struct_dynamic_range.sv b/tests/svtypes/struct_dynamic_range.sv index ce1f1467005..12c493d1f14 100644 --- a/tests/svtypes/struct_dynamic_range.sv +++ b/tests/svtypes/struct_dynamic_range.sv @@ -4,7 +4,7 @@ module range_shift_mask( input logic [2:0] addr_o, output logic [7:0] data_o ); - // (* nowrshmsk = 0 *) + (* nowrshmsk = 0 *) struct packed { logic [7:0] msb; logic [0:3][7:0] data; @@ -24,7 +24,7 @@ module range_case( input logic [2:0] addr_o, output logic [7:0] data_o ); - // (* nowrshmsk = 1 *) + (* nowrshmsk = 1 *) struct packed { logic [7:0] msb; logic [0:3][7:0] data; diff --git a/tests/svtypes/struct_dynamic_range.ys b/tests/svtypes/struct_dynamic_range.ys index d09e1924dec..943a8c63470 100644 --- a/tests/svtypes/struct_dynamic_range.ys +++ b/tests/svtypes/struct_dynamic_range.ys @@ -1,4 +1,8 @@ +! mkdir -p temp read_verilog -sv struct_dynamic_range.sv +write_rtlil temp/struct_dynamic_range.il +! grep -F -q ' cell $shift ' temp/struct_dynamic_range.il +! grep -F -q ' switch $mul' temp/struct_dynamic_range.il prep -top top flatten sat -enable_undef -verify -prove-asserts From fb7f3bb290c81b4cf2b4faa2ad9e10e0da41fd16 Mon Sep 17 00:00:00 2001 From: Dag Lem Date: Thu, 4 May 2023 13:36:57 +0200 Subject: [PATCH 084/303] Cleaner tests for RTLIL cells in struct_dynamic_range.sv --- tests/svtypes/.gitignore | 1 - tests/svtypes/struct_dynamic_range.ys | 7 +++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/svtypes/.gitignore b/tests/svtypes/.gitignore index 75154e735d8..b48f808a1e3 100644 --- a/tests/svtypes/.gitignore +++ b/tests/svtypes/.gitignore @@ -1,4 +1,3 @@ /*.log /*.out /run-test.mk -/temp diff --git a/tests/svtypes/struct_dynamic_range.ys b/tests/svtypes/struct_dynamic_range.ys index 943a8c63470..9606e73840c 100644 --- a/tests/svtypes/struct_dynamic_range.ys +++ b/tests/svtypes/struct_dynamic_range.ys @@ -1,8 +1,7 @@ -! mkdir -p temp read_verilog -sv struct_dynamic_range.sv -write_rtlil temp/struct_dynamic_range.il -! grep -F -q ' cell $shift ' temp/struct_dynamic_range.il -! grep -F -q ' switch $mul' temp/struct_dynamic_range.il +select -assert-count 4 t:$mul +select -assert-count 2 t:$shift +select -assert-count 2 t:$shiftx prep -top top flatten sat -enable_undef -verify -prove-asserts From f93671eb8567f5548844e7065c808a5b4a32481d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 00:15:06 +0000 Subject: [PATCH 085/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1fcd1914922..4de857621e8 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28+6 +YOSYS_VER := 0.28+12 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 81e089cb609540c5af8932f12b79da695a54eda7 Mon Sep 17 00:00:00 2001 From: Muthu Annamalai Date: Thu, 4 May 2023 22:30:27 -0700 Subject: [PATCH 086/303] [YOSYS-2525] fix read_liberty newline handling #2525 - newlines can be allowed in function parsing --- passes/techmap/libparse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 3d0ebaea366..2dee7bab364 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -314,8 +314,8 @@ LibertyAst *LibertyParser::parse() switch(tok) { case 'n': - error("Unexpected newline."); - break; + //fprintf(stderr,"Unexpected newline at %d\n",line); + continue; case '[': case ']': case '}': From d2f3251528b109bc6583d153a8e277d3f3c8ae17 Mon Sep 17 00:00:00 2001 From: Muthu Annamalai Date: Thu, 4 May 2023 22:43:04 -0700 Subject: [PATCH 087/303] adding unittest --- tests/liberty/XNOR2X1.lib | 337 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 tests/liberty/XNOR2X1.lib diff --git a/tests/liberty/XNOR2X1.lib b/tests/liberty/XNOR2X1.lib new file mode 100644 index 00000000000..0bb285ef7bc --- /dev/null +++ b/tests/liberty/XNOR2X1.lib @@ -0,0 +1,337 @@ +library (ls05_stdcells) { + capacitive_load_unit (1.0, pf); + current_unit: "1uA"; + default_operating_conditions: typical; + delay_model: table_lookup; + in_place_swap_mode: match_footprint; + input_threshold_pct_fall: 50.0; + input_threshold_pct_rise: 50.0; + leakage_power_unit: "1nW"; + nom_process: 1.0; + nom_temperature: 25.0; + nom_voltage: 5.0; + output_threshold_pct_fall: 50.0; + output_threshold_pct_rise: 50.0; + pulling_resistance_unit: "1kohm"; + slew_lower_threshold_pct_fall: 20.0; + slew_lower_threshold_pct_rise: 20.0; + slew_upper_threshold_pct_fall: 80.0; + slew_upper_threshold_pct_rise: 80.0; + time_unit: "1ns"; + voltage_unit: "1V"; + operating_conditions (typical) { + process: 1.0; + temperature: 25.0; + voltage: 5.0; + } + lu_table_template (delay_template_5x1) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + variable_1: input_net_transition; + } + lu_table_template (delay_template_5x5) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + variable_1: total_output_net_capacitance; + variable_2: input_net_transition; + } + lu_table_template (delay_template_5x6) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: total_output_net_capacitance; + variable_2: input_net_transition; + } + lu_table_template (delay_template_6x1) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: input_net_transition; + } + lu_table_template (delay_template_6x6) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: total_output_net_capacitance; + variable_2: input_net_transition; + } + power_lut_template (energy_template_5x5) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + variable_1: total_output_net_capacitance; + variable_2: input_transition_time; + } + power_lut_template (energy_template_5x6) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: total_output_net_capacitance; + variable_2: input_transition_time; + } + power_lut_template (energy_template_6x6) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: total_output_net_capacitance; + variable_2: input_transition_time; + } + lu_table_template (hold_template_3x5) { + index_1 ( + "1000.0, 1001.0, 1002.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + lu_table_template (hold_template_3x6) { + index_1 ( + "1000.0, 1001.0, 1002.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + power_lut_template (passive_energy_template_5x1) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + variable_1: input_transition_time; + } + power_lut_template (passive_energy_template_6x1) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: input_transition_time; + } + lu_table_template (recovery_template_3x6) { + index_1 ( + "1000.0, 1001.0, 1002.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + lu_table_template (recovery_template_6x6) { + index_1 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + lu_table_template (removal_template_3x6) { + index_1 ( + "1000.0, 1001.0, 1002.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + lu_table_template (setup_template_3x5) { + index_1 ( + "1000.0, 1001.0, 1002.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + lu_table_template (setup_template_3x6) { + index_1 ( + "1000.0, 1001.0, 1002.0" + ); + index_2 ( + "1000.0, 1001.0, 1002.0, 1003.0, 1004.0, 1005.0" + ); + variable_1: related_pin_transition; + variable_2: constrained_pin_transition; + } + cell (XNOR2X1) { + area: 206080.0; + cell_leakage_power: 0.1173; + pin (B) { + capacitance: 0.007869572376285055; + direction: input; + fall_capacitance: 0.00787170816777918; + rise_capacitance: 0.007867436584790931; + } + pin (A) { + capacitance: 0.006181892203766934; + direction: input; + fall_capacitance: 0.006286246429833927; + rise_capacitance: 0.006077537977699941; + } + pin (Y) { + direction: output; + function: "!(B&!A|!B&A)"; + timing () { + related_pin: "B"; + timing_sense: non_unate; + cell_rise (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.216615, 0.255249, 0.335937, 0.462500, 0.520313, 0.565625", \ + "0.777736, 0.782028, 0.837500, 1.065625, 1.179688, 1.273438", \ + "1.527774, 1.518945, 1.546875, 1.720781, 1.847266, 1.981250", \ + "2.840291, 2.822515, 2.825000, 2.928125, 3.018750, 3.126562", \ + "3.780926, 3.758589, 3.751563, 3.818750, 3.890625, 3.982812", \ + "5.659064, 5.632141, 5.609375, 5.634375, 5.681250, 5.743750" + ); + } + cell_fall (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.141297, 0.176563, 0.201562, 0.210938, 0.210938, 0.204688", \ + "0.483116, 0.506250, 0.566094, 0.681250, 0.709375, 0.725000", \ + "0.935771, 0.954688, 1.003125, 1.171875, 1.251563, 1.303125", \ + "1.729021, 1.750000, 1.787500, 1.925000, 2.017188, 2.118750", \ + "2.303892, 2.307813, 2.350000, 2.476562, 2.557813, 2.650000", \ + "3.431826, 3.451562, 3.482812, 3.590625, 3.660938, 3.739063" + ); + } + rise_transition (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.301313, 0.323519, 0.432031, 0.843750, 1.059375, 1.275000", \ + "1.118750, 1.120547, 1.139063, 1.348906, 1.528125, 1.746875", \ + "2.212500, 2.209375, 2.210469, 2.298437, 2.406250, 2.534375", \ + "4.121875, 4.121875, 4.121875, 4.126562, 4.164063, 4.234375", \ + "5.487500, 5.487500, 5.487500, 5.489062, 5.495312, 5.528125", \ + "8.218750, 8.218750, 8.218750, 8.218750, 8.218750, 8.219531" + ); + } + fall_transition (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.177720, 0.238125, 0.437500, 0.945313, 1.215625, 1.478125", \ + "0.646864, 0.647852, 0.729688, 1.185938, 1.476563, 1.762500", \ + "1.278125, 1.276953, 1.290625, 1.568750, 1.804687, 2.075000", \ + "2.381250, 2.381250, 2.381094, 2.478125, 2.623437, 2.807812", \ + "3.170313, 3.168750, 3.171875, 3.201562, 3.298438, 3.440625", \ + "4.746875, 4.746875, 4.746875, 4.748281, 4.768750, 4.834375" + ); + } + } + timing () { + related_pin: "A"; + timing_sense: non_unate; + cell_rise (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.198661, 0.238874, 0.325000, 0.464063, 0.525000, 0.578125", \ + "0.751696, 0.739750, 0.796875, 1.043750, 1.162500, 1.262500", \ + "1.500349, 1.465688, 1.475000, 1.656836, 1.798594, 1.940625", \ + "2.813049, 2.758763, 2.725000, 2.800000, 2.895312, 3.010937", \ + "3.752184, 3.693634, 3.639063, 3.659375, 3.725000, 3.818750", \ + "5.630379, 5.564431, 5.484375, 5.431250, 5.453125, 5.504687" + ); + } + cell_fall (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.119260, 0.143750, 0.154687, 0.148438, 0.143750, 0.131250", \ + "0.455345, 0.435938, 0.485937, 0.550000, 0.560938, 0.564063", \ + "0.908764, 0.868750, 0.867188, 1.003125, 1.046875, 1.070313", \ + "1.699465, 1.653125, 1.606250, 1.662656, 1.746875, 1.831250", \ + "2.272986, 2.210938, 2.153125, 2.148437, 2.210469, 2.295117", \ + "3.404215, 3.351562, 3.270312, 3.175000, 3.195313, 3.240625" + ); + } + rise_transition (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.301159, 0.338560, 0.480469, 0.989063, 1.300000, 1.620313", \ + "1.120312, 1.118594, 1.159375, 1.468594, 1.687500, 1.934375", \ + "2.210938, 2.212500, 2.212695, 2.381250, 2.545312, 2.726562", \ + "4.121875, 4.121875, 4.121875, 4.146875, 4.232813, 4.357812", \ + "5.487500, 5.487500, 5.487500, 5.487500, 5.520312, 5.600000", \ + "8.218750, 8.218750, 8.218750, 8.218750, 8.218750, 8.228125" + ); + } + fall_transition (delay_template_6x6) { + index_1 ( + "0.100000, 0.500000, 1.200000, 3.000000, 4.000000, 5.000000" + ); + index_2 ( + "0.060000, 0.240000, 0.480000, 0.900000, 1.200000, 1.800000" + ); + values ( + "0.176166, 0.285586, 0.559375, 1.195313, 1.535938, 1.873438", \ + "0.646209, 0.662500, 0.823438, 1.507813, 1.900000, 2.271875", \ + "1.278125, 1.276250, 1.337500, 1.825000, 2.195469, 2.595313", \ + "2.381250, 2.381250, 2.384961, 2.650000, 2.907812, 3.201562", \ + "3.168750, 3.168750, 3.172031, 3.325000, 3.531250, 3.779687", \ + "4.748437, 4.746875, 4.745312, 4.779687, 4.896875, 5.076562" + ); + } + } + } + } +} \ No newline at end of file From 17cfc969ddfe800525dbeab272b53949846e28b8 Mon Sep 17 00:00:00 2001 From: Muthu Annamalai Date: Sun, 7 May 2023 06:19:02 +0000 Subject: [PATCH 088/303] [YOSYS] Issue #3498 - Fix Synopsys style unquoted Liberty style function body parsing with unittest --- passes/techmap/libparse.cc | 11 +++++++---- tests/liberty/issue3498_bad.lib | 8 ++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100755 tests/liberty/issue3498_bad.lib diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 3d0ebaea366..1a1726f94d2 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -236,10 +236,13 @@ LibertyAst *LibertyParser::parse() if (tok == ':' && ast->value.empty()) { tok = lexer(ast->value); - if (tok != 'v') - error(); - tok = lexer(str); - while (tok == '+' || tok == '-' || tok == '*' || tok == '/') { + if (tok != 'v') { + //Synopsys-style unquoted identifiers issue#3498 + } else { + //Liberty canonical identifier including double quotes + tok = lexer(str); + } + while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') { ast->value += tok; tok = lexer(str); if (tok != 'v') diff --git a/tests/liberty/issue3498_bad.lib b/tests/liberty/issue3498_bad.lib new file mode 100755 index 00000000000..f85c4e19bda --- /dev/null +++ b/tests/liberty/issue3498_bad.lib @@ -0,0 +1,8 @@ +library(fake) { + cell(bugbad) { + bundle(X) { + members(x1, x2); + power_down_function : !a+b ; + } + } +} From 5a4e72f57a2a9f64e7db9328b68a974986ef7da7 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 8 May 2023 13:13:09 +1200 Subject: [PATCH 089/303] Fix sim writeback check for yw_cosim Writeback of simulation state into initial state was only working for `run()` and `run_cosim_fst()`. This change moves the writeback into the `write_output_files()` function so that all simulation modes work with the writeback option. --- passes/sat/sim.cc | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 7c209f51674..fe1635249c9 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1162,6 +1162,11 @@ struct SimWorker : SimShared } for(auto& writer : outputfiles) writer->write(use_signal); + + if (writeback) { + pool wbmods; + top->writeback(wbmods); + } } void update(bool gclk) @@ -1265,11 +1270,6 @@ struct SimWorker : SimShared register_output_step(10*numcycles + 2); write_output_files(); - - if (writeback) { - pool wbmods; - top->writeback(wbmods); - } } void run_cosim_fst(Module *topmod, int numcycles) @@ -1394,11 +1394,6 @@ struct SimWorker : SimShared } write_output_files(); - - if (writeback) { - pool wbmods; - top->writeback(wbmods); - } delete fst; } From 0469405abfe03d5ed31f3bcafb49f708cfa2db45 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 00:15:34 +0000 Subject: [PATCH 090/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4de857621e8..55d6af8f37a 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28+12 +YOSYS_VER := 0.28+24 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 9c5a60eb20104f7c320e263631c1371af9576911 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 9 May 2023 07:57:55 +0200 Subject: [PATCH 091/303] Release version 0.29 --- CHANGELOG | 12 +++++++++++- Makefile | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1a74acd9d78..bbaad12d6d0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,18 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.28 .. Yosys 0.28-dev +Yosys 0.28 .. Yosys 0.29 -------------------------- + * New commands and options + - Added "synthprop" pass for synthesizable properties. + + * Verific support + - Handle conditions on clocked concurrent assertions in unclocked + procedural contexts. + + * Verilog + - Fix const eval of unbased unsized constants. + - Handling of attributes for struct / union variables. Yosys 0.27 .. Yosys 0.28 -------------------------- diff --git a/Makefile b/Makefile index 55d6af8f37a..8d5a90344e9 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.28+24 +YOSYS_VER := 0.29 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0d6f4b0.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0d6f4b0.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From f790e004787706b59bebf1463bdcbb278938d77e Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 9 May 2023 08:00:06 +0200 Subject: [PATCH 092/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bbaad12d6d0..1430f8e2f92 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.29 .. Yosys 0.29-dev +-------------------------- + Yosys 0.28 .. Yosys 0.29 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index 8d5a90344e9..2562a233c1b 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29 +YOSYS_VER := 0.29+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 0d6f4b0.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9c5a60e.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From c855502bd5bf7d006f2758679a0f2491f90b6f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muthiah=20Annamalai=20=28=E0=AE=AE=E0=AF=81=E0=AE=A4?= =?UTF-8?q?=E0=AF=8D=E0=AE=A4=E0=AF=81=20=E0=AE=85=E0=AE=A3=E0=AF=8D?= =?UTF-8?q?=E0=AE=A3=E0=AE=BE=E0=AE=AE=E0=AE=B2=E0=AF=88=29?= Date: Tue, 9 May 2023 06:40:21 -0700 Subject: [PATCH 093/303] Update passes/techmap/libparse.cc Allow Liberty canonical identifier including double quotes in if-body and pass-through for Synopsys-style unquoted identifiers issue#3498 Co-authored-by: Aki <201479+lethalbit@users.noreply.github.com> --- passes/techmap/libparse.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 1a1726f94d2..664e99e2412 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -236,12 +236,9 @@ LibertyAst *LibertyParser::parse() if (tok == ':' && ast->value.empty()) { tok = lexer(ast->value); - if (tok != 'v') { - //Synopsys-style unquoted identifiers issue#3498 - } else { - //Liberty canonical identifier including double quotes - tok = lexer(str); - } + if (tok == 'v') { + tok = lexer(str); + } while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') { ast->value += tok; tok = lexer(str); From d82bae32bee63d4a521e5cb081359aa5a35213f1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 00:15:03 +0000 Subject: [PATCH 094/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2562a233c1b..c622d3bd782 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+0 +YOSYS_VER := 0.29+11 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 6b3e6d96a36e8e52c00e53ebadf3f3706b1e3025 Mon Sep 17 00:00:00 2001 From: Kamil Rakoczy Date: Tue, 28 Mar 2023 10:53:00 +0200 Subject: [PATCH 095/303] Fix missing brackets around else Signed-off-by: Kamil Rakoczy --- frontends/ast/genrtlil.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 8da4b0b0a09..5c0b8802792 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -844,13 +844,14 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM || id_ast->type == AST_ENUM_ITEM) { if (id_ast->children.size() > 1 && id_ast->children[1]->range_valid) { this_width = id_ast->children[1]->range_left - id_ast->children[1]->range_right + 1; - } else - if (id_ast->children[0]->type != AST_CONSTANT) - while (id_ast->simplify(true, false, false, 1, -1, false, true)) { } - if (id_ast->children[0]->type == AST_CONSTANT) - this_width = id_ast->children[0]->bits.size(); - else - log_file_error(filename, location.first_line, "Failed to detect width for parameter %s!\n", str.c_str()); + } else { + if (id_ast->children[0]->type != AST_CONSTANT) + while (id_ast->simplify(true, false, false, 1, -1, false, true)) { } + if (id_ast->children[0]->type == AST_CONSTANT) + this_width = id_ast->children[0]->bits.size(); + else + log_file_error(filename, location.first_line, "Failed to detect width for parameter %s!\n", str.c_str()); + } if (children.size() != 0) range = children[0]; } else if (id_ast->type == AST_WIRE || id_ast->type == AST_AUTOWIRE) { From 665e0f61319ceb5f9fa073498f8c9d5c6c982203 Mon Sep 17 00:00:00 2001 From: Muthu Annamalai Date: Wed, 17 May 2023 04:20:13 +0000 Subject: [PATCH 096/303] remove new line per maintainer request --- passes/techmap/libparse.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/passes/techmap/libparse.cc b/passes/techmap/libparse.cc index 2dee7bab364..471d451de04 100644 --- a/passes/techmap/libparse.cc +++ b/passes/techmap/libparse.cc @@ -314,7 +314,6 @@ LibertyAst *LibertyParser::parse() switch(tok) { case 'n': - //fprintf(stderr,"Unexpected newline at %d\n",line); continue; case '[': case ']': From c2285b3460083afbd8f2dd21d81d7f726e8c93d2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 17 May 2023 13:39:57 +0200 Subject: [PATCH 097/303] fix file rights --- tests/liberty/issue3498_bad.lib | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 tests/liberty/issue3498_bad.lib diff --git a/tests/liberty/issue3498_bad.lib b/tests/liberty/issue3498_bad.lib old mode 100755 new mode 100644 From 52ad7a47f3798f17d9c33209649136418fe1194f Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Thu, 18 May 2023 10:37:55 +1200 Subject: [PATCH 098/303] Assign wires an smtoffset Wires weren't being assigned an smtoffset value so when generating a yosys witness trace it would also use an offset of 0. Not sure if this has any other effects, but it fixes the bug I was having. @jix could you take a look at this? --- backends/smt2/smt2.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 48da3f4be57..bdef8d5695d 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -628,7 +628,7 @@ struct Smt2Worker bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst)); for (auto chunk : cell->getPort(QY).chunks()) if (chunk.is_wire()) - decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire)); + decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire, chunk.offset)); makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(QY)), log_signal(cell->getPort(QY))); if (cell->type == ID($anyseq)) From 147cceb516552f2f9f989508bcdd57ae04621254 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 00:15:34 +0000 Subject: [PATCH 099/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c622d3bd782..c191b8e4d16 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+11 +YOSYS_VER := 0.29+21 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From e6f39148009df28280eacb25c0392c5bfbb39ce0 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 18 May 2023 11:58:09 +0200 Subject: [PATCH 100/303] smt2: Use smt bv offset for `$any*`'s smtoffset While not setting the smtoffset here was clearly a bug, I think using `chunk.offset` only worked incidentally. The `smtoffset` is an offset into the `smtname, smtid` pair (here `"", idcounter`) which corresponds to the smt bitvector `stringf("%s#%d", get_id(module), idcounter)` which contains all the chunks this loop is iterating over. Thus using an incrementing `smtoffset` (like the `$ff`/`$dff` case above already does) should be the correct fix. --- backends/smt2/smt2.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index bdef8d5695d..0ca3fbcac88 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -626,9 +626,12 @@ struct Smt2Worker } bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst)); - for (auto chunk : cell->getPort(QY).chunks()) + int smtoffset = 0; + for (auto chunk : cell->getPort(QY).chunks()) { if (chunk.is_wire()) - decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire, chunk.offset)); + decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire, smtoffset)); + smtoffset += chunk.width; + } makebits(stringf("%s#%d", get_id(module), idcounter), GetSize(cell->getPort(QY)), log_signal(cell->getPort(QY))); if (cell->type == ID($anyseq)) From ad2b04d63a8639a294bfe6148ee262980fc962e1 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 18 May 2023 16:50:11 +0200 Subject: [PATCH 101/303] sim: Fix cosimulation with nested modules having unconnected inputs When assigning values to input ports of nested modules in cosimulation, sim needs to find the actual driver of the signal to perform the assignment. The existing code didn't handle unconnected inputs in that scenario. --- passes/sat/sim.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index fe1635249c9..273e9db8617 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -223,7 +223,8 @@ struct SimInstance if (wire->port_input && instance != nullptr && parent != nullptr) { for (int i = 0; i < GetSize(sig); i++) { - in_parent_drivers.emplace(sig[i], parent->sigmap(instance->getPort(wire->name)[i])); + if (instance->hasPort(wire->name)) + in_parent_drivers.emplace(sig[i], parent->sigmap(instance->getPort(wire->name)[i])); } } } From e7156c644ded014febfa202593d718aa098b54dd Mon Sep 17 00:00:00 2001 From: CORRADI Quentin <12198691+dwRchyngqxs@users.noreply.github.com> Date: Thu, 18 May 2023 14:46:25 +0100 Subject: [PATCH 102/303] Standard compliance for tests/verilog/block_labels.ys genvar declaration cannot take an initial value when declared as a module_or_generate_item_declaration. Correct this test so that it doesn't fail unexpectedly if Yosys aligns with the standard. --- tests/verilog/block_labels.ys | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/verilog/block_labels.ys b/tests/verilog/block_labels.ys index e76bcf771a8..76aad29aeea 100644 --- a/tests/verilog/block_labels.ys +++ b/tests/verilog/block_labels.ys @@ -1,7 +1,7 @@ read_verilog < Date: Mon, 22 May 2023 10:13:17 +1200 Subject: [PATCH 103/303] yosys-witness concat yw trace files Intended for use with SCY to combine sequential cover traces. Arbitrary number of inputs, will load all and attempt to join them. Each trace will be replayed one after the other, in the same order as the files are provided. Mismatch in init_only fields seems to work fine, with values in subsequent traces being assigned in the initial only if they weren't previously defined. Uncertain if a mismatch in non init_only fields will cause problems. Fixes WitnessSig.__eq__(). Adds helper functions to WitnessValues and ReadWitness classes. --- backends/smt2/witness.py | 46 +++++++++++++++++++++++++++++----------- backends/smt2/ywio.py | 29 +++++++++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py index 8d0cc8112d1..8e13cba277b 100644 --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -84,26 +84,48 @@ def stats(input): Transform a Yosys witness trace. Currently no transformations are implemented, so it is only useful for testing. +If two or more inputs are provided they will be concatenated together into the output. """) -@click.argument("input", type=click.File("r")) +@click.argument("inputs", type=click.File("r"), nargs=-1) @click.argument("output", type=click.File("w")) -def yw2yw(input, output): - click.echo(f"Copying yosys witness trace from {input.name!r} to {output.name!r}...") - inyw = ReadWitness(input) +def yw2yw(inputs, output): outyw = WriteWitness(output, "yosys-witness yw2yw") + join_inputs = len(inputs) > 1 + inyws = {} + for input in inputs: + if (join_inputs): + click.echo(f"Loading signals from yosys witness trace {input.name!r}...") + inyw = ReadWitness(input) + inyws[input] = inyw + for clock in inyw.clocks: + if clock not in outyw.clocks: + outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) + + for sig in inyw.signals: + if sig not in outyw.signals: + outyw.add_sig(sig.path, sig.offset, sig.width, sig.init_only) + + init_values = sum([inyw.init_step() for inyw in inyws.values()], start=WitnessValues()) + + first_witness = True + for (input, inyw) in inyws.items(): + click.echo(f"Copying yosys witness trace from {input.name!r} to {output.name!r}...") + + if first_witness: + outyw.step(init_values) + else: + outyw.step(inyw.first_step()) - for clock in inyw.clocks: - outyw.add_clock(clock["path"], clock["offset"], clock["edge"]) - - for sig in inyw.signals: - outyw.add_sig(sig.path, sig.offset, sig.width, sig.init_only) + for t, values in inyw.steps(1): + outyw.step(values) - for t, values in inyw.steps(): - outyw.step(values) + click.echo(f"Copied {t + 1} time steps.") + first_witness = False outyw.end_trace() - click.echo(f"Copied {outyw.t + 1} time steps.") + if join_inputs: + click.echo(f"Copied {outyw.t} total time steps.") class AigerMap: diff --git a/backends/smt2/ywio.py b/backends/smt2/ywio.py index 39cfac41e25..2b897200fa3 100644 --- a/backends/smt2/ywio.py +++ b/backends/smt2/ywio.py @@ -165,8 +165,8 @@ def pretty(self): else: return f"{pretty_path(self.path)}[{self.offset}]" - def __eq__(self): - return self.sort_key + def __eq__(self, other): + return self.sort_key == other.sort_key def __hash__(self): return hash(self.sort_key) @@ -294,6 +294,16 @@ def present_signals(self, sigmap): return sorted(signals), missing_signals + def __add__(self, other: "WitnessValues"): + new = WitnessValues() + new += self + new += other + return new + + def __iadd__(self, other: "WitnessValues"): + for key, value in other.values.items(): + self.values.setdefault(key, value) + return self class WriteWitness: def __init__(self, f, generator): @@ -380,13 +390,24 @@ def __init__(self, f): self.bits = [step["bits"] for step in data["steps"]] + def init_step(self): + return self.step(0) + + def first_step(self): + values = WitnessValues() + if len(self.bits) <= 1: + raise NotImplementedError("ReadWitness.first_step() not supported for less than 2 steps") + non_init_bits = len(self.bits[1]) + values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-non_init_bits:]) + return values + def step(self, t): values = WitnessValues() values.unpack(self.sigmap, self.bits[t]) return values - def steps(self): - for i in range(len(self.bits)): + def steps(self, start=0): + for i in range(start, len(self.bits)): yield i, self.step(i) def __len__(self): From 18b44a1e84da3768056e23dca66ea62f36f044c3 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 22 May 2023 11:44:19 +1200 Subject: [PATCH 104/303] yosys-witness: add append option to yw2yw Can now append a user defined number of steps to input traces when joining. If the number of steps is +ve, inputs are all set to 0. If -ve then steps are skipped. If all of steps are skipped (including init step) then the input trace will not be copied. If more than one input trace is provided, the append option will need to be provided the same number of times as there are input traces. --- backends/smt2/witness.py | 23 ++++++++++++++++++++--- backends/smt2/ywio.py | 20 ++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py index 8e13cba277b..baac3176db9 100644 --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -88,14 +88,31 @@ def stats(input): """) @click.argument("inputs", type=click.File("r"), nargs=-1) @click.argument("output", type=click.File("w")) -def yw2yw(inputs, output): +@click.option("--append", "-p", type=int, multiple=True, + help="Number of steps (+ve or -ve) to append to end of input trace. " + +"Can be defined multiple times, following the same order as input traces. ") +def yw2yw(inputs, output, append): outyw = WriteWitness(output, "yosys-witness yw2yw") join_inputs = len(inputs) > 1 inyws = {} - for input in inputs: + + if not append: + # default to 0 + append = [0] * len(inputs) + if len(append) != len(inputs): + print(f"Mismatch in number of --append values ({len(append)}) and input traces ({len(inputs)}).") + sys.exit(1) + + for (input, p) in zip(inputs, append): if (join_inputs): click.echo(f"Loading signals from yosys witness trace {input.name!r}...") inyw = ReadWitness(input) + if p: + click.echo(f" appending {p} steps") + if (p + len(inyw) <= 0): + click.echo(f" skipping {input.name!r} (only {len(inyw)} steps to skip)") + continue + inyw.append_steps(p) inyws[input] = inyw for clock in inyw.clocks: if clock not in outyw.clocks: @@ -119,7 +136,7 @@ def yw2yw(inputs, output): for t, values in inyw.steps(1): outyw.step(values) - click.echo(f"Copied {t + 1} time steps.") + click.echo(f" copied {t + 1} time steps.") first_witness = False outyw.end_trace() diff --git a/backends/smt2/ywio.py b/backends/smt2/ywio.py index 2b897200fa3..4e95f8c33d2 100644 --- a/backends/smt2/ywio.py +++ b/backends/smt2/ywio.py @@ -393,12 +393,16 @@ def __init__(self, f): def init_step(self): return self.step(0) + def non_init_bits(self): + if len(self) > 1: + return len(self.bits[1]) + else: + return sum([sig.width for sig in self.signals if not sig.init_only]) + def first_step(self): values = WitnessValues() - if len(self.bits) <= 1: - raise NotImplementedError("ReadWitness.first_step() not supported for less than 2 steps") - non_init_bits = len(self.bits[1]) - values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-non_init_bits:]) + # may have issues when non_init_bits is 0 + values.unpack(WitnessSigMap([sig for sig in self.signals if not sig.init_only]), self.bits[0][-self.non_init_bits():]) return values def step(self, t): @@ -410,5 +414,13 @@ def steps(self, start=0): for i in range(start, len(self.bits)): yield i, self.step(i) + def append_steps(self, t): + if not t: + pass + elif t < 0: + self.bits = self.bits[:t] + else: + self.bits.extend(["0"*self.non_init_bits()]*t) + def __len__(self): return len(self.bits) From cdeef5481caf87ae4fe6b5f0effbf0a251a6bbda Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 00:16:53 +0000 Subject: [PATCH 105/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c191b8e4d16..959d55737b2 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+21 +YOSYS_VER := 0.29+23 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From ecd289c10011f06aecb77b8c3961467f274c9d00 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 23 May 2023 08:25:08 +0200 Subject: [PATCH 106/303] Fix importing parametrized VHDL entity --- frontends/verific/verific.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index bc61c9c82f5..5d93954a73a 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2468,6 +2468,7 @@ std::string verific_import(Design *design, const std::mapAddAtt(new Att(" \\top", NULL)); nl_todo.emplace(nl->CellBaseName(), nl); + cell_name = nl->Owner()->Name(); } + if (top.empty()) cell_name = top; delete netlists; @@ -2495,7 +2498,7 @@ std::string verific_import(Design *design, const std::mapfirst) == 0) { VerificImporter importer(false, false, false, false, false, false, false); nl_done[it->first] = it->second; - importer.import_netlist(design, nl, nl_todo, nl->Owner()->Name() == top); + importer.import_netlist(design, nl, nl_todo, nl->Owner()->Name() == cell_name); } nl_todo.erase(it); } From 57c9eb70feb54cff112d095d2153b0d032bdbf18 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 May 2023 00:15:32 +0000 Subject: [PATCH 107/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 959d55737b2..a0b77a837ee 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+23 +YOSYS_VER := 0.29+34 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 52c8c28d2cd05145d5b224c56742c63e79af1e04 Mon Sep 17 00:00:00 2001 From: gatecat Date: Thu, 25 Nov 2021 19:43:58 +0000 Subject: [PATCH 108/303] Add recover_names pass to recover names post-mapping --- kernel/hashlib.h | 6 + passes/sat/Makefile.inc | 1 + passes/sat/recover_names.cc | 730 ++++++++++++++++++++++++++++++++++++ 3 files changed, 737 insertions(+) create mode 100644 passes/sat/recover_names.cc diff --git a/kernel/hashlib.h b/kernel/hashlib.h index af282715356..b3f99bf730f 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -84,6 +84,12 @@ template<> struct hash_ops : hash_int_ops return mkhash((unsigned int)(a), (unsigned int)(a >> 32)); } }; +template<> struct hash_ops : hash_int_ops +{ + static inline unsigned int hash(uint32_t a) { + return a; + } +}; template<> struct hash_ops { static inline bool cmp(const std::string &a, const std::string &b) { diff --git a/passes/sat/Makefile.inc b/passes/sat/Makefile.inc index cc89cc0c8ce..d9bf69dcb90 100644 --- a/passes/sat/Makefile.inc +++ b/passes/sat/Makefile.inc @@ -16,6 +16,7 @@ OBJS += passes/sat/fmcombine.o OBJS += passes/sat/mutate.o OBJS += passes/sat/cutpoint.o OBJS += passes/sat/fminit.o +OBJS += passes/sat/recover_names.o ifeq ($(DISABLE_SPAWN),0) OBJS += passes/sat/qbfsat.o endif diff --git a/passes/sat/recover_names.cc b/passes/sat/recover_names.cc new file mode 100644 index 00000000000..2d7e7f01cfa --- /dev/null +++ b/passes/sat/recover_names.cc @@ -0,0 +1,730 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 gatecat + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/yosys.h" +#include "kernel/sigtools.h" +#include "kernel/consteval.h" +#include "kernel/celltypes.h" +#include "kernel/utils.h" +#include "kernel/satgen.h" + +#include +#include + +USING_YOSYS_NAMESPACE + +template<> struct hashlib::hash_ops : hashlib::hash_int_ops +{ + static inline unsigned int hash(uint64_t a) { + return mkhash((unsigned int)(a), (unsigned int)(a >> 32)); + } +}; + +PRIVATE_NAMESPACE_BEGIN + +// xorshift128 params +#define INIT_X 123456789 +#define INIT_Y 362436069 +#define INIT_Z 521288629 +#define INIT_W 88675123 + + +// Similar to a SigBit; but module-independent +struct IdBit { + IdBit() : name(), bit(0) {}; + IdBit(IdString name, int bit = 0) : name(name), bit(bit) {}; + + bool operator==(const IdBit &other) const { return name == other.name && bit == other.bit; }; + bool operator!=(const IdBit &other) const { return name != other.name || bit != other.bit; }; + unsigned hash() const + { + return mkhash_add(name.hash(), bit); + } + + IdString name; + int bit; +}; + +// As above; but can be inverted +struct InvBit { + InvBit() : bit(), inverted(false) {}; + explicit InvBit(IdBit bit, bool inverted = false) : bit(bit), inverted(inverted) {}; + + bool operator==(const InvBit &other) const { return bit == other.bit && inverted == other.inverted; }; + bool operator!=(const InvBit &other) const { return bit != other.bit || inverted != other.inverted; }; + unsigned hash() const + { + return mkhash(bit.hash(), inverted); + } + + IdBit bit; + bool inverted; +}; + +typedef uint64_t equiv_cls_t; +static const int sim_length = sizeof(equiv_cls_t) * 8; + +struct RecoverModuleWorker { + Design *design = nullptr; + Module *mod, *flat = nullptr; + RecoverModuleWorker(Module *mod) : design(mod->design), mod(mod) {}; + + ConstEval *ce = nullptr; + SigMap *sigmap = nullptr; + + dict flat2orig; + dict bit2primary; + dict bit2driver; + + void prepare() + { + // Create a derivative of the module with whiteboxes flattened so we can + // run eval and sat on it + flat = design->addModule(NEW_ID); + mod->cloneInto(flat); + Pass::call_on_module(design, flat, "flatten -wb"); + ce = new ConstEval(flat); + sigmap = new SigMap(flat); + // Create a mapping from primary name-bit in the box-flattened module to original sigbit + SigMap orig_sigmap(mod); + for (auto wire : mod->wires()) { + Wire *flat_wire = flat->wire(wire->name); + if (!flat_wire) + continue; + for (int i = 0; i < wire->width; i++) { + SigBit orig_sigbit = orig_sigmap(SigBit(wire, i)); + SigBit flat_sigbit = (*sigmap)(SigBit(flat_wire, i)); + if (!orig_sigbit.wire || !flat_sigbit.wire) + continue; + flat2orig[IdBit(flat_sigbit.wire->name, flat_sigbit.offset)] = orig_sigbit; + } + } + find_driven_bits(); + } + + void find_driven_bits() + { + // Add primary inputs + for (auto wire : flat->wires()) { + if (!wire->port_input) + continue; + for (int i = 0; i < wire->width; i++) { + SigBit bit(wire, i); + bit = (*sigmap)(bit); + if (bit.wire) + bit2driver[IdBit(bit.wire->name, bit.offset)] = nullptr; + } + } + // Add cell outputs + for (auto cell : flat->cells()) { + for (auto conn : cell->connections()) { + if (!cell->output(conn.first)) + continue; + for (auto bit : conn.second) { + auto resolved = (*sigmap)(bit); + if (resolved.wire) + bit2driver[IdBit(resolved.wire->name, resolved.offset)] = cell; + } + } + } + // Setup bit2primary + for (auto wire : flat->wires()) { + for (int i = 0; i < wire->width; i++) { + SigBit bit(wire, i); + bit = (*sigmap)(bit); + if (bit.wire) + bit2primary[IdBit(wire->name, i)] = IdBit(bit.wire->name, bit.offset); + } + } + } + + // Mapping from bit to (candidate) equivalence classes + dict bit2cls; + void sim_cycle(int t, const dict &anchors) + { + ce->clear(); + for (auto anchor : anchors) { + SigBit bit = (*sigmap)(SigBit(flat->wire(anchor.first.name), anchor.first.bit)); + // Ignore in the rare case that it's already determined + SigSpec res(bit); + if (ce->eval(res)) + continue; + ce->set(bit, anchor.second); + } + // Only evaluate IdBits that exist in the non-flat design; as they are all we care about + for (auto idbit : flat2orig) { + if (anchors.count(idbit.first)) + continue; + SigBit bit = (*sigmap)(SigBit(flat->wire(idbit.first.name), idbit.first.bit)); + SigSpec res(bit); + if (!ce->eval(res)) + continue; + if (res != State::S0 && res != State::S1) + continue; + // Update equivalence classes + if (res == State::S1) + bit2cls[idbit.first] = bit2cls[idbit.first] | (equiv_cls_t(1) << t); + } + } + + // Update the equivalence class groupings + void group_classes(dict, pool>> &cls2bits, bool is_gate) + { + equiv_cls_t all_ones = 0; + for (int i = 0; i < sim_length; i++) all_ones |= (equiv_cls_t(1) << i); + for (auto pair : bit2cls) { + if (pair.second == 0 || pair.second == all_ones) + continue; // skip stuck-ats + if (is_gate) { + // True doesn't exist in gold; but inverted does + if (!cls2bits.count(pair.second) && cls2bits.count(pair.second ^ all_ones)) + cls2bits[pair.second ^ all_ones].second.emplace(pair.first, true); + else + cls2bits[pair.second].second.emplace(pair.first, false); + } else { + cls2bits[pair.second].first.insert(pair.first); + } + } + } + + // Compute depths of IdBits + dict bit2depth; + void compute_depths(const dict &anchor_bits) + { + dict> bit_drivers, bit_users; + TopoSort toposort; + + for (auto cell : flat->cells()) + for (auto conn : cell->connections()) + { + for (auto bit : (*sigmap)(conn.second)) { + if (!bit.wire) + continue; + IdBit idbit(bit.wire->name, bit.offset); + if (anchor_bits.count(idbit)) + continue; + if (cell->input(conn.first)) + bit_users[bit].insert(cell->name); + + if (cell->output(conn.first)) + bit_drivers[bit].insert(cell->name); + } + + toposort.node(cell->name); + } + + for (auto &it : bit_users) + if (bit_drivers.count(it.first)) + for (auto driver_cell : bit_drivers.at(it.first)) + for (auto user_cell : it.second) + toposort.edge(driver_cell, user_cell); + + toposort.sort(); + for (auto cell_name : toposort.sorted) { + Cell *cell = flat->cell(cell_name); + int cell_depth = 0; + for (auto conn : cell->connections()) { + if (!cell->input(conn.first)) + continue; + for (auto bit : (*sigmap)(conn.second)) { + if (!bit.wire) + continue; + IdBit idbit(bit.wire->name, bit.offset); + if (!bit2depth.count(idbit)) + continue; + cell_depth = std::max(cell_depth, bit2depth.at(idbit)); + } + } + for (auto conn : cell->connections()) { + if (!cell->output(conn.first)) + continue; + for (auto bit : (*sigmap)(conn.second)) { + if (!bit.wire) + continue; + IdBit idbit(bit.wire->name, bit.offset); + bit2depth[idbit] = std::max(bit2depth[idbit], cell_depth + 1); + } + } + } + } + + // SAT thresholds + const int max_sat_cells = 50; + + SigBit id2bit(IdBit bit) { return SigBit(flat->wire(bit.name), bit.bit); } + + // Set up the SAT problem for an IdBit + // the value side of 'anchors' will be populated with the SAT variable for anchor bits + int setup_sat(SatGen *sat, const std::string &prefix, IdBit bit, const dict &anchor_bits, dict &anchor2var) + { + sat->setContext(sigmap, prefix); + pool imported_cells; + int result = sat->importSigBit(id2bit(bit)); + // Recursively import driving cells + std::queue to_import; + to_import.push(bit); + while (!to_import.empty()) { + // Too many cells imported + if (GetSize(imported_cells) > max_sat_cells) + return -1; + IdBit cursor = to_import.front(); + to_import.pop(); + if (anchor_bits.count(cursor)) { + if (!anchor2var.count(cursor)) { + anchor2var[cursor] = sat->importSigBit(id2bit(cursor)); + } + continue; + } + // Import driver if it exists + if (!bit2driver.count(cursor)) + continue; + Cell *driver = bit2driver.at(cursor); + if (!driver || imported_cells.count(driver->name)) + continue; + if (!sat->importCell(driver)) + return -1; // cell can't be imported + imported_cells.insert(driver->name); + // Add cell inputs to queue + for (auto conn : driver->connections()) { + if (!driver->input(conn.first)) + continue; + for (SigBit in_bit : (*sigmap)(conn.second)) { + if (!in_bit.wire) + continue; + IdBit in_idbit(in_bit.wire->name, in_bit.offset); + to_import.push(in_idbit); + } + } + } + return result; + } + + void find_buffers(const pool &buffer_types, dict> &root2buffered) + { + SigMap orig_sigmap(mod); + dict buffer2root; + for (auto cell : mod->cells()) { + if (!buffer_types.count(cell->type)) + continue; + SigBit in, out; + for (auto conn : cell->connections()) { + if (cell->input(conn.first)) { + in = orig_sigmap(conn.second[0]); + } + if (cell->output(conn.first)) { + out = orig_sigmap(conn.second[0]); + } + } + if (!in.wire || !out.wire) + continue; + SigBit root = in; + if (buffer2root.count(root)) + root = buffer2root[root]; + if (root2buffered.count(out)) { + for (auto out_sig : root2buffered.at(out)) + root2buffered[root].insert(out_sig); + root2buffered.erase(out); + } + root2buffered[root].insert(out); + buffer2root[out] = root; + } + } + + void do_rename(Module *gold, const dict &gate2gold, const pool &buffer_types) + { + dict>> bit2port; + pool unused_bits; + SigMap orig_sigmap(mod); + for (auto wire : mod->wires()) { + if (wire->port_input || wire->port_output) + continue; + for (int i = 0; i < wire->width; i++) + unused_bits.insert(orig_sigmap(SigBit(wire, i))); + } + for (auto cell : mod->cells()) { + for (auto conn : cell->connections()) { + for (int i = 0; i < GetSize(conn.second); i++) { + SigBit bit = orig_sigmap(conn.second[i]); + if (!bit.wire) + continue; + bit2port[bit].emplace_back(cell, conn.first, i); + unused_bits.erase(bit); + } + } + } + dict> root2buffered; + find_buffers(buffer_types, root2buffered); + + // An extension of gate2gold that deals with buffers too + // gate sigbit --> (new name, invert, gold wire) + dict> rename_map; + for (auto pair : gate2gold) { + SigBit gate_bit = flat2orig.at(pair.first); + Wire *gold_wire = gold->wire(pair.second.bit.name); + rename_map[gate_bit] = std::make_pair(pair.second, gold_wire); + if (root2buffered.count(gate_bit)) { + int buf_idx = 0; + for (auto buf_bit : root2buffered.at(gate_bit)) { + std::string buf_name_str = stringf("%s_buf_%d", pair.second.bit.name.c_str(), ++buf_idx); + if (buf_name_str[0] == '\\') + buf_name_str[0] = '$'; + rename_map[buf_bit] = std::make_pair( + InvBit(IdBit(IdString(buf_name_str), pair.second.bit.bit), pair.second.inverted), gold_wire); + } + } + } + + for (auto rule : rename_map) { + // Pick a uniq new name + IdBit new_name = rule.second.first.bit; + int dup_idx = 0; + bool must_invert_name = rule.second.first.inverted; + while (must_invert_name || + (mod->wire(new_name.name) && !unused_bits.count(SigBit(mod->wire(new_name.name), new_name.bit)))) { + std::string new_name_str = stringf("%s_%s_%d", rule.second.first.bit.name.c_str(), + rule.second.first.inverted ? "inv" : "dup", ++dup_idx); + if (new_name_str[0] == '\\') + new_name_str[0] = '$'; + new_name.name = IdString(new_name_str); + must_invert_name = false; + } + // Create the wire if needed + Wire *new_wire = mod->wire(new_name.name); + if (!new_wire) { + Wire *gold_wire = rule.second.second; + new_wire = mod->addWire(new_name.name, gold_wire->width); + new_wire->start_offset = gold_wire->start_offset; + new_wire->upto = gold_wire->upto; + for (const auto &attr : gold_wire->attributes) + new_wire->attributes[attr.first] = attr.second; + for (int i = 0; i < new_wire->width; i++) + unused_bits.insert(SigBit(new_wire, i)); + } + // Ensure it's wide enough + if (new_wire->width <= new_name.bit) + new_wire->width = new_name.bit + 1; + SigBit old_bit = rule.first; + SigBit new_bit(new_wire, new_name.bit); + unused_bits.erase(new_bit); + // Replace all users + if (bit2port.count(old_bit)) + for (auto port_ref : bit2port.at(old_bit)) { + Cell *cell = std::get<0>(port_ref); + IdString port_name = std::get<1>(port_ref); + int port_bit = std::get<2>(port_ref); + SigSpec port_sig = cell->getPort(port_name); + port_sig.replace(port_bit, new_bit); + cell->unsetPort(port_name); + cell->setPort(port_name, port_sig); + } + } + } + + ~RecoverModuleWorker() + { + delete ce; + delete sigmap; + if (flat) + design->remove(flat); + } +}; + +struct RecoverNamesWorker { + Design *design, *gold_design = nullptr; + CellTypes ct_all; + RecoverNamesWorker(Design *design) : design(design) {} + + pool comb_whiteboxes, buffer_types; + + // class -> (gold, (gate, inverted)) + dict, dict>> cls2bits; + + void analyse_boxes() + { + for (auto mod : design->modules()) { + if (!mod->get_bool_attribute(ID::whitebox)) + continue; + bool is_comb = true; + for (auto cell : mod->cells()) { + if (ct_all.cell_evaluable(cell->type)) { + is_comb = false; + break; + } + } + if (!is_comb) + continue; + comb_whiteboxes.insert(mod->name); + // Buffers have one input and one output; exactly + SigBit in{}, out{}; + ConstEval eval(mod); + for (auto wire : mod->wires()) { + if (wire->port_input) { + if (wire->width != 1 || in.wire) + goto not_buffer; + in = SigBit(wire, 0); + } + if (wire->port_output) { + if (wire->width != 1 || out.wire) + goto not_buffer; + out = SigBit(wire, 0); + } + } + if (!in.wire || !out.wire) + goto not_buffer; + // Buffer input mirrors output + for (auto bit : {State::S0, State::S1}) { + eval.clear(); + eval.set(in, bit); + SigSpec result(out); + if (!eval.eval(result)) + goto not_buffer; + if (result != bit) + goto not_buffer; + } + buffer_types.insert(mod->name); + if (false) { + not_buffer: + continue; + } + } + log_debug("Found %d combinational cells and %d buffer whiteboxes.\n", GetSize(comb_whiteboxes), GetSize(buffer_types)); + } + + uint32_t x, y, z, w, rng_val; + int rng_bit; + void rng_init() + { + x = INIT_X; + y = INIT_Y; + z = INIT_Z; + w = INIT_W; + rng_bit = 32; + } + uint32_t xorshift128() + { + uint32_t t = x ^ (x << 11); + x = y; y = z; z = w; + w ^= (w >> 19) ^ t ^ (t >> 8); + return w; + } + RTLIL::State next_randbit() + { + if (rng_bit >= 32) { + rng_bit = 0; + rng_val = xorshift128(); + } + return ((rng_val >> (rng_bit++)) & 0x1) ? RTLIL::State::S1 : RTLIL::State::S0; + } + + int popcount(equiv_cls_t cls) { + int result = 0; + for (unsigned i = 0; i < 8*sizeof(equiv_cls_t); i++) + if ((cls >> i) & 0x1) + ++result; + return result; + } + + bool prove_equiv(RecoverModuleWorker &gold_worker, RecoverModuleWorker &gate_worker, + const dict &gold_anchors, const dict &gate_anchors, + IdBit gold_bit, IdBit gate_bit, bool invert) { + ezSatPtr ez; + SatGen satgen(ez.get(), nullptr); + dict anchor2var_gold, anchor2var_gate; + int gold_var = gold_worker.setup_sat(&satgen, "gold", gold_bit, gold_anchors, anchor2var_gold); + if (gold_var == -1) + return false; + int gate_var = gate_worker.setup_sat(&satgen, "gate", gate_bit, gate_anchors, anchor2var_gate); + if (gate_var == -1) + return false; + // Assume anchors are equal + for (auto anchor : anchor2var_gate) { + IdBit gold_anchor = gate_anchors.at(anchor.first); + if (!anchor2var_gold.count(gold_anchor)) + continue; + ez->assume(ez->IFF(anchor.second, anchor2var_gold.at(gold_anchor))); + } + // Prove equivalence + return !ez->solve(ez->NOT(ez->IFF(gold_var, invert ? ez->NOT(gate_var) : gate_var))); + } + + void analyse_mod(Module *gate_mod) + { + Module *gold_mod = gold_design->module(gate_mod->name); + if (!gold_mod) + return; + + RecoverModuleWorker gold_worker(gold_mod); + RecoverModuleWorker gate_worker(gate_mod); + + gold_worker.prepare(); + gate_worker.prepare(); + + // Find anchors (same-name wire-bits driven in both gold and gate) + dict gold_anchors, gate_anchors; + + for (auto gold_bit : gold_worker.bit2driver) { + if (gate_worker.bit2primary.count(gold_bit.first)) { + IdBit gate_bit = gate_worker.bit2primary.at(gold_bit.first); + if (!gate_worker.bit2driver.count(gate_bit)) + continue; + gold_anchors[gold_bit.first] = gate_bit; + gate_anchors[gate_bit] = gold_bit.first; + } + } + // Run a random-value combinational simulation to find candidate equivalence classes + dict gold_anchor_vals, gate_anchor_vals; + rng_init(); + for (int t = 0; t < sim_length; t++) { + for (auto anchor : gold_anchors) { + gold_anchor_vals[anchor.first] = next_randbit(); + gate_anchor_vals[anchor.second] = gold_anchor_vals[anchor.first]; + } + gold_worker.sim_cycle(t, gold_anchor_vals); + gate_worker.sim_cycle(t, gate_anchor_vals); + } + log_debug("%d candidate equiv classes in gold; %d in gate\n", GetSize(gold_worker.bit2cls), GetSize(gate_worker.bit2cls)); + // Group bits by equivalence classes together + dict, pool>> cls2bits; + gold_worker.group_classes(cls2bits, false); + gate_worker.group_classes(cls2bits, true); + gate_worker.compute_depths(gate_anchors); + // Sort equivalence classes by shallowest first (so we have as many anchors as possible when reaching deeper bits) + std::vector> cls_depth; + for (auto &cls : cls2bits) { + if (cls.second.second.empty()) + continue; + int depth = 0; + for (auto gate_bit : cls.second.second) { + if (!gate_worker.bit2depth.count(gate_bit.bit)) + continue; + depth = std::max(depth, gate_worker.bit2depth.at(gate_bit.bit)); + } + cls_depth.emplace_back(cls.first, depth); + } + std::stable_sort(cls_depth.begin(), cls_depth.end(), + [](const std::pair &a, const std::pair &b) { + return a.second < b.second; + }); + // The magic result we've worked hard for.... + dict gate2gold; + // Solve starting from shallowest + for (auto cls : cls_depth) { + int pop = popcount(cls.first); + // Equivalence classes with only one set bit are invariably a waste of SAT time + if (pop == 1 || pop == (8*sizeof(equiv_cls_t) - 1)) + continue; + + log_debug("equivalence class: %016lx\n", cls.first); + const pool &gold_bits = cls2bits.at(cls.first).first; + const pool &gate_bits = cls2bits.at(cls.first).second; + if (gold_bits.empty() || gate_bits.empty()) + continue; + pool solved_gate; + if (GetSize(gold_bits) > 10) + continue; // large equivalence classes are not very interesting; skip + for (IdBit gold_bit : gold_bits) { + for (auto gate_bit : gate_bits) { + if (solved_gate.count(gate_bit.bit)) + continue; + log_debug(" attempting to prove %s[%d] == %s%s[%d]\n", log_id(gold_bit.name), gold_bit.bit, + gate_bit.inverted ? "" : "!", log_id(gate_bit.bit.name), gate_bit.bit.bit); + if (!prove_equiv(gold_worker, gate_worker, gold_anchors, gate_anchors, gold_bit, gate_bit.bit, gate_bit.inverted)) + continue; + log_debug(" success!\n"); + // Success! + gate2gold[gate_bit.bit] = InvBit(gold_bit, gate_bit.inverted); + if (!gate_bit.inverted) { + // Only add as anchor if not inverted + gold_anchors[gold_bit] = gate_bit.bit; + gate_anchors[gate_bit.bit] = gold_bit; + } + solved_gate.insert(gate_bit.bit); + } + // All solved... + if (GetSize(solved_gate) == GetSize(gate_bits)) + break; + } + } + log("Recovered %d net name pairs in module `%s' out.\n", GetSize(gate2gold), log_id(gate_mod)); + gate_worker.do_rename(gold_mod, gate2gold, buffer_types); + } + + void operator()(string command) + { + // Make a backup copy of the pre-mapping design for later + gold_design = new RTLIL::Design; + + for (auto mod : design->modules()) + gold_design->add(mod->clone()); + + run_pass(command, design); + + analyse_boxes(); + + // keeping our own std::vector here avoids modify-while-iterating issues + std::vector to_analyse; + for (auto mod : design->modules()) + if (!mod->get_blackbox_attribute()) + to_analyse.push_back(mod); + for (auto mod : to_analyse) + analyse_mod(mod); + } + ~RecoverNamesWorker() { + delete gold_design; + } +}; + +struct RecoverNamesPass : public Pass { + RecoverNamesPass() : Pass("recover_names", "Execute a lossy mapping command and recover original netnames") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" recover_names [command]\n"); + log("\n"); + log("This pass executes a lossy mapping command and uses a combination of simulation\n"); + log(" to find candidate equivalences and SAT to recover exact original net names.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + log_header(design, "Executing RECOVER_NAMES pass (run mapping and recover original names).\n"); + string command; + + size_t argidx = 1; + for (; argidx < args.size(); argidx++) { + if (command.empty()) { + if (args[argidx].compare(0, 1, "-") == 0) + cmd_error(args, argidx, "Unknown option."); + } else { + command += " "; + } + command += args[argidx]; + } + + if (command.empty()) + log_cmd_error("No mapping pass specified!\n"); + + RecoverNamesWorker worker(design); + worker(command); + + } +} RecoverNamesPass; + +PRIVATE_NAMESPACE_END From 7caeb922a0fc9e5f8fc7b670d2f58d16d6156e50 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 25 May 2023 12:46:16 +0200 Subject: [PATCH 109/303] sim: Run level triggered async updates to fixpoint during initialization --- passes/sat/sim.cc | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 273e9db8617..b970ee568cd 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -589,7 +589,7 @@ struct SimInstance } } - bool update_ph2(bool gclk) + bool update_ph2(bool gclk, bool stable_past_update = false) { bool did_something = false; @@ -600,7 +600,7 @@ struct SimInstance Const current_q = get_state(ff.data.sig_q); - if (ff_data.has_clk) { + if (ff_data.has_clk && !stable_past_update) { // flip-flops State current_clk = get_state(ff_data.sig_clk)[0]; if (ff_data.pol_clk ? (ff.past_clk == State::S0 && current_clk != State::S0) : @@ -621,7 +621,7 @@ struct SimInstance if (ff_data.has_aload) { State current_aload = get_state(ff_data.sig_aload)[0]; if (current_aload == (ff_data.pol_aload ? State::S1 : State::S0)) { - current_q = ff_data.has_clk ? ff.past_ad : get_state(ff.data.sig_ad); + current_q = ff_data.has_clk && !stable_past_update ? ff.past_ad : get_state(ff.data.sig_ad); } } // async reset @@ -672,6 +672,8 @@ struct SimInstance } else { + if (stable_past_update) + continue; if (port.clk_polarity ? (mdb.past_wr_clk[port_idx] == State::S1 || get_state(port.clk) != State::S1) : (mdb.past_wr_clk[port_idx] == State::S0 || get_state(port.clk) != State::S0)) @@ -701,7 +703,7 @@ struct SimInstance } for (auto it : children) - if (it.second->update_ph2(gclk)) { + if (it.second->update_ph2(gclk, stable_past_update)) { dirty_children.insert(it.second); did_something = true; } @@ -1197,9 +1199,21 @@ struct SimWorker : SimShared void initialize_stable_past() { - if (debug) - log("\n-- ph1 (initialize) --\n"); - top->update_ph1(); + + while (1) + { + if (debug) + log("\n-- ph1 (initialize) --\n"); + + top->update_ph1(); + + if (debug) + log("\n-- ph2 (initialize) --\n"); + + if (!top->update_ph2(false, true)) + break; + } + if (debug) log("\n-- ph3 (initialize) --\n"); top->update_ph3(true); From e36c71b5b743e578f3a965cda9926a426cd5c295 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 25 May 2023 12:48:02 +0200 Subject: [PATCH 110/303] Use clk2fflogic attr on cells to track original FF names in witnesses This makes clk2fflogic add an attr to $ff cells that carry the state of the emulated async FF. The $ff output doesn't have any async updates that happened in the current cycle, but the $ff input does, so the $ff input corresponds to the async FF's output in the original design. Hence this patch also makes the following changes to passes besides clk2fflogic (but only for FFs with the clk2fflogic attr set): * opt_clean treats the input as a register name (instead of the output) * rename -witness ensures that the input has a public name * the formal backends (smt2, btor, aiger) will use the input's name for the initial state of the FF in witness files * when sim reads a yw witness that assigns an initial value to the input signal, the state update is redirected to the output This ensures that yosys witness files for clk2fflogic designs have useful and stable public signal names. It also makes it possible to simulate a clk2fflogic witness on the original design (with some limitations when the original design is already using $ff cells). It might seem like setting the output of a clk2fflogic FF to update the input's initial value might not work in general, but it works fine for these reasons: * Witnesses for FFs are only present in the initial cycle, so we do not care about any later cycles. * The logic that clk2fflogic generates loops the output of the genreated FF back to the input, with muxes in between to apply any edge or level sensitive updates. So when there are no active updates in the current gclk cycle, there is a combinational path from the output back to the input. * The logic clk2fflogic generates makes sure that an edge sensitive update cannot be active in the first cycle (i.e. the past initial value is assumed to be whatever it needs to be to avoid an edge). * When a level sensitive update is active in the first gclk cycle, it is actively driving the output for the whole gclk cycle, so ignoring any witness initialization is the correct behavior. --- backends/aiger/aiger.cc | 3 +++ backends/btor/btor.cc | 5 ++++- backends/smt2/smt2.cc | 3 ++- passes/cmds/rename.cc | 12 ++++++++++-- passes/opt/opt_clean.cc | 6 ++++-- passes/sat/clk2fflogic.cc | 20 ++++++++++++++++---- passes/sat/sim.cc | 10 ++++++++++ 7 files changed, 49 insertions(+), 10 deletions(-) diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 97acf937cd7..e39e1771565 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -733,6 +733,9 @@ struct AigerWriter auto sig_qy = cell->getPort(cell->type.in(ID($anyconst), ID($anyseq)) ? ID::Y : ID::Q); SigSpec sig = sigmap(sig_qy); + if (cell->get_bool_attribute(ID(clk2fflogic))) + sig_qy = cell->getPort(ID::D); // For a clk2fflogic $_FF_ the named signal is the D input not the Q output + for (int i = 0; i < GetSize(sig_qy); i++) { if (sig_qy[i].wire == nullptr || sig[i].wire == nullptr) continue; diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 4c43e91e796..9cfd967e581 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -728,7 +728,10 @@ struct BtorWorker else btorf("%d state %d %s\n", nid, sid, log_id(symbol)); - ywmap_state(sig_q); + if (cell->get_bool_attribute(ID(clk2fflogic))) + ywmap_state(cell->getPort(ID::D)); // For a clk2fflogic FF the named signal is the D input not the Q output + else + ywmap_state(sig_q); if (nid_init_val >= 0) { int nid_init = next_nid++; diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 0ca3fbcac88..7b48be29902 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -626,8 +626,9 @@ struct Smt2Worker } bool init_only = cell->type.in(ID($anyconst), ID($anyinit), ID($allconst)); + bool clk2fflogic = cell->type == ID($anyinit) && cell->get_bool_attribute(ID(clk2fflogic)); int smtoffset = 0; - for (auto chunk : cell->getPort(QY).chunks()) { + for (auto chunk : cell->getPort(clk2fflogic ? ID::D : QY).chunks()) { if (chunk.is_wire()) decls.push_back(witness_signal(init_only ? "init" : "seq", chunk.width, chunk.offset, "", idcounter, chunk.wire, smtoffset)); smtoffset += chunk.width; diff --git a/passes/cmds/rename.cc b/passes/cmds/rename.cc index 6bd317ed0e4..da4ba2f17e9 100644 --- a/passes/cmds/rename.cc +++ b/passes/cmds/rename.cc @@ -139,7 +139,12 @@ static bool rename_witness(RTLIL::Design *design, dict &ca if (cell->type.in(ID($anyconst), ID($anyseq), ID($anyinit), ID($allconst), ID($allseq))) { has_witness_signals = true; - auto QY = cell->type == ID($anyinit) ? ID::Q : ID::Y; + IdString QY; + bool clk2fflogic = false; + if (cell->type == ID($anyinit)) + QY = (clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic))) ? ID::D : ID::Q; + else + QY = ID::Y; auto sig_out = cell->getPort(QY); for (auto chunk : sig_out.chunks()) { @@ -151,7 +156,10 @@ static bool rename_witness(RTLIL::Design *design, dict &ca auto new_id = module->uniquify("\\_witness_." + name); auto new_wire = module->addWire(new_id, GetSize(sig_out)); new_wire->set_hdlname_attribute({ "_witness_", strstr(new_id.c_str(), ".") + 1 }); - module->connect({sig_out, new_wire}); + if (clk2fflogic) + module->connect({new_wire, sig_out}); + else + module->connect({sig_out, new_wire}); cell->setPort(QY, new_wire); break; } diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index dde7c5299c6..cb2490dc72e 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -292,10 +292,12 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (!purge_mode) for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; - if (ct_reg.cell_known(cell->type)) + if (ct_reg.cell_known(cell->type)) { + bool clk2fflogic = cell->get_bool_attribute(ID(clk2fflogic)); for (auto &it2 : cell->connections()) - if (ct_reg.cell_output(cell->type, it2.first)) + if (clk2fflogic ? it2.first == ID::D : ct_reg.cell_output(cell->type, it2.first)) register_signals.add(it2.second); + } for (auto &it2 : cell->connections()) connected_signals.add(it2.second); } diff --git a/passes/sat/clk2fflogic.cc b/passes/sat/clk2fflogic.cc index bba2cbbecc7..3dc96ecce2a 100644 --- a/passes/sat/clk2fflogic.cc +++ b/passes/sat/clk2fflogic.cc @@ -80,15 +80,27 @@ struct Clk2fflogicPass : public Pass { return module->Eqx(NEW_ID, {sampled_sig, sig}, polarity ? SigSpec {State::S0, State::S1} : SigSpec {State::S1, State::S0}); } // Sampled and current value of a data signal. - SampledSig sample_data(Module *module, SigSpec sig, RTLIL::Const init, bool is_fine) { + SampledSig sample_data(Module *module, SigSpec sig, RTLIL::Const init, bool is_fine, bool set_attribute = false) { std::string sig_str = log_signal(sig); sig_str.erase(std::remove(sig_str.begin(), sig_str.end(), ' '), sig_str.end()); + + Wire *sampled_sig = module->addWire(NEW_ID_SUFFIX(stringf("%s#sampled", sig_str.c_str())), GetSize(sig)); sampled_sig->attributes[ID::init] = init; + + Cell *cell; if (is_fine) - module->addFfGate(NEW_ID, sig, sampled_sig); + cell = module->addFfGate(NEW_ID, sig, sampled_sig); else - module->addFf(NEW_ID, sig, sampled_sig); + cell = module->addFf(NEW_ID, sig, sampled_sig); + + if (set_attribute) { + for (auto &chunk : sig.chunks()) + if (chunk.wire != nullptr) + chunk.wire->set_bool_attribute(ID::keep); + cell->set_bool_attribute(ID(clk2fflogic)); + } + return {sampled_sig, sig}; } SigSpec mux(Module *module, SigSpec a, SigSpec b, SigSpec s, bool is_fine) { @@ -213,7 +225,7 @@ struct Clk2fflogicPass : public Pass { if (ff.has_clk) ff.unmap_ce_srst(); - auto next_q = sample_data(module, ff.sig_q, ff.val_init, ff.is_fine).sampled; + auto next_q = sample_data(module, ff.sig_q, ff.val_init, ff.is_fine, true).sampled; if (ff.has_clk) { // The init value for the sampled d is never used, so we can set it to fixed zero, reducing uninit'd FFs diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index b970ee568cd..2f353672b24 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -140,6 +140,7 @@ struct SimInstance dict> upd_outports; dict in_parent_drivers; + dict clk2fflogic_drivers; pool dirty_bits; pool dirty_cells; @@ -270,6 +271,11 @@ struct SimInstance ff.past_srst = State::Sx; ff.data = ff_data; ff_database[cell] = ff; + + if (cell->get_bool_attribute(ID(clk2fflogic))) { + for (int i = 0; i < ff_data.width; i++) + clk2fflogic_drivers.emplace(sigmap(ff_data.sig_d[i]), sigmap(ff_data.sig_q[i])); + } } if (cell->is_mem_cell()) @@ -389,6 +395,10 @@ struct SimInstance auto sigbit = sig[i]; auto sigval = value[i]; + auto clk2fflogic_driver = clk2fflogic_drivers.find(sigbit); + if (clk2fflogic_driver != clk2fflogic_drivers.end()) + sigbit = clk2fflogic_driver->second; + auto in_parent_driver = in_parent_drivers.find(sigbit); if (in_parent_driver == in_parent_drivers.end()) set_state(sigbit, sigval); From 00b0e850dbb649a40e7508ae04a10a0816db87fd Mon Sep 17 00:00:00 2001 From: Lofty Date: Thu, 25 May 2023 16:17:09 +0100 Subject: [PATCH 111/303] intel_alm: re-enable carry chains for ABC9 --- techlibs/intel_alm/common/alm_sim.v | 8 +++----- tests/arch/intel_alm/counter.ys | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/techlibs/intel_alm/common/alm_sim.v b/techlibs/intel_alm/common/alm_sim.v index 242f1003f2f..d3bd673903f 100644 --- a/techlibs/intel_alm/common/alm_sim.v +++ b/techlibs/intel_alm/common/alm_sim.v @@ -1,5 +1,5 @@ // The core logic primitive of the Cyclone V/10GX is the Adaptive Logic Module -// (ALM). Each ALM is made up of an 8-input, 2-output look-up table, covered +// (ALM). Each ALM is made up of an 8-input, 2-output look-up table, covered // in this file, connected to combinational outputs, a carry chain, and four // D flip-flops (which are covered as MISTRAL_FF in dff_sim.v). // @@ -283,10 +283,8 @@ assign Q = ~A; endmodule -// Despite the abc9_carry attributes, this doesn't seem to stop ABC9 adding illegal fanout to the carry chain that nextpnr cannot handle. -// So we treat it as a total blackbox from ABC9's perspective for now. -// (* abc9_box, lib_whitebox *) -module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, /* (* abc9_carry *) */ input CI, output SO, /* (* abc9_carry *) */ output CO); +(* abc9_box, lib_whitebox *) +module MISTRAL_ALUT_ARITH(input A, B, C, D0, D1, (* abc9_carry *) input CI, output SO, (* abc9_carry *) output CO); parameter LUT0 = 16'h0000; parameter LUT1 = 16'h0000; diff --git a/tests/arch/intel_alm/counter.ys b/tests/arch/intel_alm/counter.ys index 0a5b9356ab7..2b428fb3e51 100644 --- a/tests/arch/intel_alm/counter.ys +++ b/tests/arch/intel_alm/counter.ys @@ -6,7 +6,7 @@ equiv_opt -assert -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 1 t:MISTRAL_NOT +select -assert-count 2 t:MISTRAL_NOT select -assert-count 8 t:MISTRAL_ALUT_ARITH select -assert-count 8 t:MISTRAL_FF select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D @@ -21,7 +21,7 @@ equiv_opt -assert -async2sync -map +/intel_alm/common/alm_sim.v -map +/intel_alm design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 1 t:MISTRAL_NOT +select -assert-count 2 t:MISTRAL_NOT select -assert-count 8 t:MISTRAL_ALUT_ARITH select -assert-count 8 t:MISTRAL_FF select -assert-none t:MISTRAL_NOT t:MISTRAL_ALUT_ARITH t:MISTRAL_FF %% t:* %D From 862631d657fe04a2b32a7703263a2bf016cf04de Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Sun, 21 May 2023 18:19:51 -0700 Subject: [PATCH 112/303] Add ABC9 DSP cascade test --- tests/arch/xilinx/dsp_abc9.ys | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/arch/xilinx/dsp_abc9.ys b/tests/arch/xilinx/dsp_abc9.ys index 909e54149b9..ae4839d7f1f 100644 --- a/tests/arch/xilinx/dsp_abc9.ys +++ b/tests/arch/xilinx/dsp_abc9.ys @@ -1,3 +1,5 @@ +logger -nowarn "Yosys has only limited support for tri-state logic at the moment\. .*" + read_verilog < Date: Sun, 21 May 2023 18:20:18 -0700 Subject: [PATCH 113/303] abc9_ops -prep_hier to unmap entire module --- passes/techmap/abc9_ops.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index ed4d4bdfb04..4eaed1f75dc 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -233,22 +233,23 @@ void prep_hier(RTLIL::Design *design, bool dff_mode) if (derived_type != cell->type) { auto unmap_module = unmap_design->addModule(derived_type); + auto replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, cell->type); for (auto port : derived_module->ports) { auto w = unmap_module->addWire(port, derived_module->wire(port)); // Do not propagate (* init *) values into the box, // in fact, remove it from outside too if (w->port_output) w->attributes.erase(ID::init); + // Attach (* techmap_autopurge *) to all ports to ensure that + // undriven inputs/unused outputs are propagated through to + // the techmapped cell + w->attributes[ID::techmap_autopurge] = 1; + + replace_cell->setPort(port, w); } unmap_module->ports = derived_module->ports; unmap_module->check(); - auto replace_cell = unmap_module->addCell(ID::_TECHMAP_REPLACE_, cell->type); - for (const auto &conn : cell->connections()) { - auto w = unmap_module->wire(conn.first); - log_assert(w); - replace_cell->setPort(conn.first, w); - } replace_cell->parameters = cell->parameters; } } From cac1bc6fbe4db01060bfd04a51c9e12f82ef6167 Mon Sep 17 00:00:00 2001 From: Lofty Date: Thu, 25 May 2023 17:48:48 +0100 Subject: [PATCH 114/303] intel_alm: enable M10K initialisation --- techlibs/intel_alm/common/bram_m10k.txt | 2 +- techlibs/intel_alm/common/bram_m10k_map.v | 6 ++++-- techlibs/intel_alm/common/mem_sim.v | 8 +++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt index 560711b658e..60ebc5bf126 100644 --- a/techlibs/intel_alm/common/bram_m10k.txt +++ b/techlibs/intel_alm/common/bram_m10k.txt @@ -1,5 +1,5 @@ bram $__MISTRAL_M10K - init 0 # TODO: Re-enable when I figure out how BRAM init works + init 1 abits 13 @D8192x1 dbits 1 @D8192x1 abits 12 @D4096x2 diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v index 8f9d4a3b3ff..3121b9d04c3 100644 --- a/techlibs/intel_alm/common/bram_m10k_map.v +++ b/techlibs/intel_alm/common/bram_m10k_map.v @@ -2,6 +2,8 @@ module \$__MISTRAL_M10K (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); +parameter INIT = 0; + parameter CFG_ABITS = 10; parameter CFG_DBITS = 10; @@ -11,6 +13,6 @@ input [CFG_DBITS-1:0] A1DATA; input A1EN, B1EN; output reg [CFG_DBITS-1:0] B1DATA; -MISTRAL_M10K #(.CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(!A1EN), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN)); +MISTRAL_M10K #(.INIT(INIT), .CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(!A1EN), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN)); -endmodule \ No newline at end of file +endmodule diff --git a/techlibs/intel_alm/common/mem_sim.v b/techlibs/intel_alm/common/mem_sim.v index c9ba8c7f129..563f1d2413e 100644 --- a/techlibs/intel_alm/common/mem_sim.v +++ b/techlibs/intel_alm/common/mem_sim.v @@ -3,7 +3,7 @@ // In addition to Logic Array Blocks (LABs) that contain ten Adaptive Logic // Modules (ALMs, see alm_sim.v), the Cyclone V/10GX also contain // Memory/Logic Array Blocks (MLABs) that can act as either ten ALMs, or utilise -// the memory the ALM uses to store the look-up table data for general usage, +// the memory the ALM uses to store the look-up table data for general usage, // producing a 32 address by 20-bit block of memory. MLABs are spread out // around the chip, so they can be placed near where they are needed, rather than // being comparatively limited in placement for a deep but narrow memory such as @@ -43,7 +43,7 @@ // Quartus will pack external flops into the MLAB, but this is an assumption // that needs testing. -// The vendor sim model outputs 'x for a very short period (a few +// The vendor sim model outputs 'x for a very short period (a few // combinational delta cycles) after each write. This has been omitted from // the following model because it's very difficult to trigger this in practice // as clock cycles will be much longer than any potential blip of 'x, so the @@ -110,6 +110,8 @@ endmodule module MISTRAL_M10K(CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); +parameter INIT = 0; + parameter CFG_ABITS = 10; parameter CFG_DBITS = 10; @@ -119,7 +121,7 @@ input [CFG_DBITS-1:0] A1DATA; input A1EN, B1EN; output reg [CFG_DBITS-1:0] B1DATA; -reg [2**CFG_ABITS * CFG_DBITS - 1 : 0] mem = 0; +reg [2**CFG_ABITS * CFG_DBITS - 1 : 0] mem = INIT; `ifdef cyclonev specify From 3aee765793689f775e4e423be3fd6851e3513620 Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Tue, 4 Apr 2023 21:31:26 +1200 Subject: [PATCH 115/303] Initial version of memory mapping doc --- docs/source/CHAPTER_Memorymap.rst | 652 ++++++++++++++++++++++++++++++ docs/source/index.rst | 1 + 2 files changed, 653 insertions(+) create mode 100644 docs/source/CHAPTER_Memorymap.rst diff --git a/docs/source/CHAPTER_Memorymap.rst b/docs/source/CHAPTER_Memorymap.rst new file mode 100644 index 00000000000..e18ee9bb281 --- /dev/null +++ b/docs/source/CHAPTER_Memorymap.rst @@ -0,0 +1,652 @@ +.. _chapter:memorymap: + +Memory mapping +============== + +Documentation for the Yosys memory_libmap memory mapper. + +See also: `passes/memory/memlib.md `_ + +Supported patterns +------------------ + +Asynchronous-read RAM +~~~~~~~~~~~~~~~~~~~~~ + +- This will result in LUT RAM on supported targets + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + always @(posedge clk) + if (write_enable) + mem[write_addr] <= write_data; + assign read_data = mem[read_addr]; + +Synchronous SDP with clock domain crossing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Will result in block RAM or LUT RAM depending on size +- No behavior guarantees in case of simultaneous read and write to the same address + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge write_clk) begin + if (write_enable) + mem[write_addr] <= write_data; + end + + always @(posedge read_clk) begin + if (read_enable) + read_data <= mem[read_addr]; + end + +Synchronous SDP read first +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- The read and write parts can be in the same or different processes. +- Will result in block RAM or LUT RAM depending on size +- As long as the same clock is used for both, yosys will ensure read-first behavior. This may + require extra circuitry on some targets for block RAM. If this is not necessary, use one of the + patterns below. + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + if (read_enable) + read_data <= mem[read_addr]; + end + +Synchronous SDP with undefined collision behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Like above, but the read value is undefined when read and write ports target the same address in + the same cycle + + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + + if (read_enable) begin + read_data <= mem[read_addr]; + + // 👇 this if block 👇 + if (write_enable && read_addr == write_addr) + read_data <= 'x; + end + end + +- Or below, using the no_rw_check attribute + +.. code:: verilog + + (* no_rw_check *) + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + + if (read_enable) + read_data <= mem[read_addr]; + end + +Synchronous SDP with write-first behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Will result in block RAM or LUT RAM depending on size +- May use additional circuitry for block RAM if write-first is not natively supported. Will always + use additional circuitry for LUT RAM. + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + + if (read_enable) begin + read_data <= mem[read_addr]; + if (write_enable && read_addr == write_addr) + read_data <= write_data; + end + end + +Synchronous SDP with write-first behavior (alternate pattern) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- This pattern is supported for compatibility, but is much less flexible than the above + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + read_addr_reg <= read_addr; + end + + assign read_data = mem[read_addr_reg]; + +Asynchronous-read single-port RAM +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Will result in single-port LUT RAM on supported targets + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + always @(posedge clk) + if (write_enable) + mem[addr] <= write_data; + assign read_data = mem[addr]; + +Synchronous single-port RAM with mutually exclusive read/write +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Will result in single-port block RAM or LUT RAM depending on size +- This is the correct pattern to infer ice40 SPRAM (with manual ram_style selection) +- On targets that don't support read/write block RAM ports (eg. ice40), will result in SDP block RAM instead +- For block RAM, will use "NO_CHANGE" mode if available + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[addr] <= write_data; + else if (read_enable) + read_data <= mem[addr]; + end + +Synchronous single-port RAM with read-first behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Will only result in single-port block RAM when read-first behavior is natively supported; + otherwise, SDP RAM with additional circuitry will be used +- Many targets (Xilinx, ECP5, …) can only natively support read-first/write-first single-port RAM + (or TDP RAM) where the write_enable signal implies the read_enable signal (ie. can never write + without reading). The memory inference code will run a simple SAT solver on the control signals to + determine if this is the case, and insert emulation circuitry if it cannot be easily proven. + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[addr] <= write_data; + if (read_enable) + read_data <= mem[addr]; + end + +Synchronous single-port RAM with write-first behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Will result in single-port block RAM or LUT RAM when supported +- Block RAMs will require extra circuitry if write-first behavior not natively supported + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[addr] <= write_data; + if (read_enable) + if (write_enable) + read_data <= write_data; + else + read_data <= mem[addr]; + end + +Synchronous read port with initial value +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Initial read port values can be combined with any other supported pattern +- If block RAM is used and initial read port values are not natively supported by the target, small + emulation circuit will be inserted + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + reg [DATA_WIDTH - 1 : 0] read_data; + initial read_data = 'h1234; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + if (read_enable) + read_data <= mem[read_addr]; + end + +Synchronous read port with synchronous reset (reset priority over enable) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Synchronous resets can be combined with any other supported pattern (except that synchronous reset + and asynchronous reset cannot be used on a single read port) +- If block RAM is used and synchronous resets are not natively supported by the target, small + emulation circuit will be inserted + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + + if (read_reset) + read_data <= {sval}; + else if (read_enable) + read_data <= mem[read_addr]; + end + +Synchronous read port with synchronous reset (enable priority over reset) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Synchronous resets can be combined with any other supported pattern (except that synchronous reset + and asynchronous reset cannot be used on a single read port) +- If block RAM is used and synchronous resets are not natively supported by the target, small + emulation circuit will be inserted + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + if (read_enable) + if (read_reset) + read_data <= 'h1234; + else + read_data <= mem[read_addr]; + end + +Synchronous read port with asynchronous reset +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Asynchronous resets can be combined with any other supported pattern (except that synchronous + reset and asynchronous reset cannot be used on a single read port) +- If block RAM is used and asynchronous resets are not natively supported by the target, small + emulation circuit will be inserted + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + end + + always @(posedge clk, posedge reset_read) begin + if (reset_read) + read_data <= 'h1234; + else if (read_enable) + read_data <= mem[read_addr]; + end + +Initial data +~~~~~~~~~~~~ + +- Most FPGA targets support initializing all kinds of memory to user-provided values +- If explicit initialization is not used, initial memory value is undefined +- Initial data can be provided by either initial statements writing memory cells one by one or + $readmemh/$readmemb system tasks + +Write port with byte enables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Byte enables can be used with any supported pattern +- To ensure that multiple writes will be merged into one port, they need to have disjoint bit + ranges, have the same address, and the same clock +- Any write enable granularity will be accepted (down to per-bit write enables), but using smaller + granularity than natively supported by the target is very likely to be inefficient (eg. using + 4-bit bytes on ECP5 will result in either padding the bytes with 5 dummy bits to native 9-bit + units or splitting the RAM into two block RAMs) + +.. code:: verilog + + reg [31 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable[0]) + mem[write_addr][7:0] <= write_data[7:0]; + if (write_enable[1]) + mem[write_addr][15:8] <= write_data[15:8]; + if (write_enable[2]) + mem[write_addr][23:16] <= write_data[23:16]; + if (write_enable[3]) + mem[write_addr][31:24] <= write_data[31:24]; + if (read_enable) + read_data <= mem[read_addr]; + end + +Asymmetric memory — general notes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To construct an asymmetric memory (memory with read/write ports of differing widths): + +- Declare the memory with the width of the narrowest intended port +- Split all wide ports into multiple narrow ports +- To ensure the wide ports will be correctly merged: + + - For the address, use a concatenation of actual address in the high bits and a constant in the + low bits + - Ensure the actual address is identical for all ports belonging to the wide port + - Ensure that clock is identical + - For read ports, ensure that enable/reset signals are identical (for write ports, the enable + signal may vary — this will result in using the byte enable functionality) + +- Asymmetric memory is supported on all targets, but may require emulation circuitry where not + natively supported +- Note: when the memory is larger than the underlying block RAM primitive, hardware asymmetric + memory support is likely not to be used even if present, as this is cheaper + +Asymmetric memory with wide synchronous read port +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: verilog + + reg [7:0] mem [0:255]; + wire [7:0] write_addr; + wire [5:0] read_addr; + wire [7:0] write_data; + reg [31:0] read_data; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + if (read_enable) begin + read_data[7:0] <= mem[{read_addr, 2'b00}]; + read_data[15:8] <= mem[{read_addr, 2'b01}]; + read_data[23:16] <= mem[{read_addr, 2'b10}]; + read_data[31:24] <= mem[{read_addr, 2'b11}]; + end + end + +Wide asynchronous read port +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Note: the only target natively supporting this pattern is Xilinx UltraScale + +.. code:: verilog + + reg [7:0] mem [0:511]; + wire [8:0] write_addr; + wire [5:0] read_addr; + wire [7:0] write_data; + wire [63:0] read_data; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + end + + assign read_data[7:0] = mem[{read_addr, 3'b000}]; + assign read_data[15:8] = mem[{read_addr, 3'b001}]; + assign read_data[23:16] = mem[{read_addr, 3'b010}]; + assign read_data[31:24] = mem[{read_addr, 3'b011}]; + assign read_data[39:32] = mem[{read_addr, 3'b100}]; + assign read_data[47:40] = mem[{read_addr, 3'b101}]; + assign read_data[55:48] = mem[{read_addr, 3'b110}]; + assign read_data[63:56] = mem[{read_addr, 3'b111}]; + +Wide write port +~~~~~~~~~~~~~~~ + +.. code:: verilog + + reg [7:0] mem [0:255]; + wire [5:0] write_addr; + wire [7:0] read_addr; + wire [31:0] write_data; + reg [7:0] read_data; + + always @(posedge clk) begin + if (write_enable[0]) + mem[{write_addr, 2'b00}] <= write_data[7:0]; + if (write_enable[1]) + mem[{write_addr, 2'b01}] <= write_data[15:8]; + if (write_enable[2]) + mem[{write_addr, 2'b10}] <= write_data[23:16]; + if (write_enable[3]) + mem[{write_addr, 2'b11}] <= write_data[31:24]; + if (read_enable) + read_data <= mem[read_addr]; + end + +True dual port memory — general notes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Many different variations of true dual port memory can be created by combining two single-port RAM + patterns on the same memory +- When TDP memory is used, memory inference code has much less maneuver room to create requested + semantics compared to individual single-port patterns (which can end up lowered to SDP memory + where necessary) — supported patterns depend strongly on the target +- In particular, when both ports have the same clock, it's likely that "undefined collision" mode + needs to be manually selected to enable TDP memory inference +- The examples below are non-exhaustive — many more combinations of port types are possible +- Note: if two write ports are in the same process, this defines a priority relation between them + (if both ports are active in the same clock, the later one wins). On almost all targets, this will + result in a bit of extra circuitry to ensure the priority semantics. If this is not what you want, + put them in separate processes. + + - Priority is not supported when using the verific front end and any priority semantics are ignored. + +True Dual Port — different clocks, exclusive read/write +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk_a) begin + if (write_enable_a) + mem[addr_a] <= write_data_a; + else if (read_enable_a) + read_data_a <= mem[addr_a]; + end + + always @(posedge clk_b) begin + if (write_enable_b) + mem[addr_b] <= write_data_b; + else if (read_enable_b) + read_data_b <= mem[addr_b]; + end + +True Dual Port — same clock, read-first behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- This requires hardware inter-port read-first behavior, and will only work on some targets (Xilinx, Nexus) + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable_a) + mem[addr_a] <= write_data_a; + if (read_enable_a) + read_data_a <= mem[addr_a]; + end + + always @(posedge clk) begin + if (write_enable_b) + mem[addr_b] <= write_data_b; + if (read_enable_b) + read_data_b <= mem[addr_b]; + end + +Multiple read ports +~~~~~~~~~~~~~~~~~~~ + +- The combination of a single write port with an arbitrary amount of read ports is supported on all + targets — if a multi-read port primitive is available (like Xilinx RAM64M), it'll be used as + appropriate. Otherwise, the memory will be automatically split into multiple primitives. + +.. code:: verilog + + reg [31:0] mem [0:31]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] <= write_data; + end + + assign read_data_a = mem[read_addr_a]; + assign read_data_b = mem[read_addr_b]; + assign read_data_c = mem[read_addr_c]; + +Memory kind selection +~~~~~~~~~~~~~~~~~~~~~ + +- The memory inference code will automatically pick target memory primitive based on memory geometry + and features used. Depending on the target, there can be up to four memory primitive classes + available for selection: + +- FF RAM (aka logic): no hardware primitive used, memory lowered to a bunch of FFs and multiplexers + + - Can handle arbitrary number of write ports, as long as all write ports are in the same clock domain + - Can handle arbitrary number and kind of read ports + +- LUT RAM (aka distributed RAM): uses LUT storage as RAM + + - Supported on most FPGAs (with notable exception of ice40) + - Usually has one synchronous write port, one or more asynchronous read ports + - Small + - Will never be used for ROMs (lowering to plain LUTs is always better) + +- Block RAM: dedicated memory tiles + + - Supported on basically all FPGAs + - Supports only synchronous reads + - Two ports with separate clocks + - Usually supports true dual port (with notable exception of ice40 that only supports SDP) + - Usually supports asymmetric memories and per-byte write enables + - Several kilobits in size + +- Huge RAM: + + - Only supported on several targets: + + - Some Xilinx UltraScale devices (UltraRAM) + + - Two ports, both with mutually exclusive synchronous read and write + - Single clock + - Initial data must be all-0 + + - Some ice40 devices (SPRAM) + + - Single port with mutually exclusive synchronous read and write + - Does not support initial data + + - Nexus (large RAM) + + - Two ports, both with mutually exclusive synchronous read and write + - Single clock + + - Will not be automatically selected by memory inference code, needs explicit opt-in via + ram_style attribute + +In general, you can expect the automatic selection process to work roughly like this: + +- If any read port is asynchronous, only LUT RAM (or FF RAM) can be used. +- If there is more than one write port, only block RAM can be used, and this needs to be a + hardware-supported true dual port pattern + + - … unless all write ports are in the same clock domain, in which case FF RAM can also be used, + but this is generally not what you want for anything but really small memories + +- Otherwise, either FF RAM, LUT RAM, or block RAM will be used, depending on memory size + +This process can be overridden by attaching a ram_style attribute to the memory: + +- `(* ram_style = "logic" *)` selects FF RAM +- `(* ram_style = "distributed" *)` selects LUT RAM +- `(* ram_style = "block" *)` selects block RAM +- `(* ram_style = "huge" *)` selects huge RAM + +It is an error if this override cannot be realized for the given target. + +Many alternate spellings of the attribute are also accepted, for compatibility with other software. + +Not yet supported patterns +-------------------------- + +Synchronous SDP with write-first behavior via blocking assignments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Would require modifications to the Yosys Verilog frontend. +- Use `Synchronous SDP with write-first behavior`_ instead + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr] = write_data; + + if (read_enable) + read_data <= mem[read_addr]; + end + +Asymmetric memories via part selection +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Would require major changes to the Verilog frontend. +- Build wide ports out of narrow ports instead (see `Asymmetric memory with wide synchronous read port`_) + +.. code:: verilog + + reg [31:0] mem [2**ADDR_WIDTH - 1 : 0]; + + wire [1:0] byte_lane; + wire [7:0] write_data; + + always @(posedge clk) begin + if (write_enable) + mem[write_addr][byte_lane * 8 +: 8] <= write_data; + + if (read_enable) + read_data <= mem[read_addr]; + end + + +Undesired patterns +------------------ + +Asynchronous writes +~~~~~~~~~~~~~~~~~~~ + +- Not supported in modern FPGAs +- Not supported in yosys code anyhow + +.. code:: verilog + + reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @* begin + if (write_enable) + mem[write_addr] = write_data; + end + + assign read_data = mem[read_addr]; + diff --git a/docs/source/index.rst b/docs/source/index.rst index fb864307246..111aea873a4 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -42,6 +42,7 @@ Yosys manual CHAPTER_Verilog.rst CHAPTER_Optimize.rst CHAPTER_Techmap.rst + CHAPTER_Memorymap.rst CHAPTER_Eval.rst .. raw:: latex From 8596c5ce4915d1727d93df45fc58047f08886b41 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 00:15:52 +0000 Subject: [PATCH 116/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a0b77a837ee..bcb6a066cce 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+34 +YOSYS_VER := 0.29+40 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 26555a998d0aa8bbeba331ad6eb5a870c719f606 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 24 May 2023 17:52:14 +0200 Subject: [PATCH 117/303] show -colorattr: extend colors to arrows when wires have attribute --- passes/cmds/show.cc | 48 +++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index dd7de827331..46aa16c90d1 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -84,7 +84,7 @@ struct ShowWorker std::string nextColor() { if (currentColor == 0) - return "color=\"black\""; + return "color=\"black\", fontcolor=\"black\""; return stringf("colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", currentColor%8+1, currentColor%8+1); } @@ -97,18 +97,15 @@ struct ShowWorker std::string nextColor(RTLIL::SigSpec sig, std::string defaultColor) { - sig.sort_and_unify(); - for (auto &c : sig.chunks()) { - if (c.wire != nullptr) - for (auto &s : color_selections) - if (s.second.selected_members.count(module->name) > 0 && s.second.selected_members.at(module->name).count(c.wire->name) > 0) - return stringf("color=\"%s\"", s.first.c_str()); - } + std::string color = findColor(sig); + if (!color.empty()) return color; return defaultColor; } std::string nextColor(const RTLIL::SigSig &conn, std::string defaultColor) { + std::string color = findColor(conn); + if (!color.empty()) return color; return nextColor(conn.first, nextColor(conn.second, defaultColor)); } @@ -131,12 +128,28 @@ struct ShowWorker return stringf("style=\"setlinewidth(3)\", label=\"<%d>\"", bits); } - const char *findColor(std::string member_name) + std::string findColor(RTLIL::SigSpec sig) + { + sig.sort_and_unify(); + for (auto &c : sig.chunks()) { + if (c.wire != nullptr) + return findColor(c.wire->name); + } + return ""; + } + + std::string findColor(const RTLIL::SigSig &conn) + { + std::string firstColor = findColor(conn.first); + if (findColor(conn.second) == firstColor) return firstColor; + return ""; + } + + std::string findColor(IdString member_name) { for (auto &s : color_selections) if (s.second.selected_member(module->name, member_name)) { - dot_escape_store.push_back(stringf(", color=\"%s\"", s.first.c_str())); - return dot_escape_store.back().c_str(); + return stringf("color=\"%s\", fontcolor=\"%s\"", s.first.c_str(), s.first.c_str()); } RTLIL::Const colorattr_value; @@ -155,8 +168,7 @@ struct ShowWorker colorattr_cache[colorattr_value] = (next_id % 8) + 1; } - dot_escape_store.push_back(stringf(", colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", colorattr_cache.at(colorattr_value), colorattr_cache.at(colorattr_value))); - return dot_escape_store.back().c_str(); + return stringf("colorscheme=\"dark28\", color=\"%d\", fontcolor=\"%d\"", colorattr_cache.at(colorattr_value), colorattr_cache.at(colorattr_value)); } const char *findLabel(std::string member_name) @@ -414,9 +426,9 @@ struct ShowWorker if (wire->port_input || wire->port_output) shape = "octagon"; if (wire->name.isPublic()) { - fprintf(f, "n%d [ shape=%s, label=\"%s\", %s, fontcolor=\"black\" ];\n", + fprintf(f, "n%d [ shape=%s, label=\"%s\", %s ];\n", id2num(wire->name), shape, findLabel(wire->name.str()), - nextColor(RTLIL::SigSpec(wire), "color=\"black\"").c_str()); + nextColor(RTLIL::SigSpec(wire), "color=\"black\", fontcolor=\"black\"").c_str()); if (wire->port_input) all_sources.insert(stringf("n%d", id2num(wire->name))); else if (wire->port_output) @@ -478,14 +490,16 @@ struct ShowWorker conn.second, ct.cell_output(cell->type, conn.first)); } + std::string color = findColor(cell->name); + if (!color.empty()) color = ", " + color; #ifdef CLUSTER_CELLS_AND_PORTBOXES if (!code.empty()) fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n", - id2num(cell->name), id2num(cell->name), label_string.c_str(), findColor(cell->name), code.c_str()); + id2num(cell->name), id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); else #endif fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s", - id2num(cell->name), label_string.c_str(), findColor(cell->name.str()), code.c_str()); + id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); } for (auto &it : module->processes) From fb7af093a88daf9fa20fb7c45877686f5516808b Mon Sep 17 00:00:00 2001 From: Lofty Date: Mon, 29 May 2023 05:49:53 +0100 Subject: [PATCH 118/303] intel_alm: re-enable 8x40-bit M10K support --- techlibs/intel_alm/common/bram_m10k.txt | 2 ++ techlibs/intel_alm/common/bram_m10k_map.v | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/techlibs/intel_alm/common/bram_m10k.txt b/techlibs/intel_alm/common/bram_m10k.txt index 60ebc5bf126..14688a04c94 100644 --- a/techlibs/intel_alm/common/bram_m10k.txt +++ b/techlibs/intel_alm/common/bram_m10k.txt @@ -10,6 +10,8 @@ bram $__MISTRAL_M10K dbits 10 @D1024x10 abits 9 @D512x20 dbits 20 @D512x20 + abits 8 @D256x40 + dbits 40 @D256x40 groups 2 ports 1 1 wrmode 1 0 diff --git a/techlibs/intel_alm/common/bram_m10k_map.v b/techlibs/intel_alm/common/bram_m10k_map.v index 3121b9d04c3..d48a1999c05 100644 --- a/techlibs/intel_alm/common/bram_m10k_map.v +++ b/techlibs/intel_alm/common/bram_m10k_map.v @@ -13,6 +13,14 @@ input [CFG_DBITS-1:0] A1DATA; input A1EN, B1EN; output reg [CFG_DBITS-1:0] B1DATA; -MISTRAL_M10K #(.INIT(INIT), .CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(!A1EN), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN)); +// Normal M10K configs use WREN[1], which is negative-true. +// However, 8x40-bit mode uses WREN[0], which is positive-true. +wire a1en; +if (CFG_DBITS == 40) + assign a1en = A1EN; +else + assign a1en = !A1EN; + +MISTRAL_M10K #(.INIT(INIT), .CFG_ABITS(CFG_ABITS), .CFG_DBITS(CFG_DBITS)) _TECHMAP_REPLACE_ (.CLK1(CLK1), .A1ADDR(A1ADDR), .A1DATA(A1DATA), .A1EN(a1en), .B1ADDR(B1ADDR), .B1DATA(B1DATA), .B1EN(B1EN)); endmodule From 1cd1e57e3c955a61970480fdc0295d5e3484746c Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Mon, 29 May 2023 16:53:50 +0200 Subject: [PATCH 119/303] Fix use of non-POSIX test expressions in Makefile POSIX test only allows "=" for string comparison. Accepting "==" as an alias is a bashism. Even the bash manpage discourages its use. --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index bcb6a066cce..af66033022b 100644 --- a/Makefile +++ b/Makefile @@ -797,13 +797,13 @@ ifneq ($(ABCREV),default) $(Q) if test -d abc && test -d abc/.git && ! git -C abc diff-index --quiet HEAD; then \ echo 'REEBE: NOP pbagnvaf ybpny zbqvsvpngvbaf! Frg NOPERI=qrsnhyg va Lbflf Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; false; \ fi - $(Q) if test -d abc && ! test -d abc/.git && ! test "`cat abc/.gitcommit | cut -c1-7`" == "$(ABCREV)"; then \ + $(Q) if test -d abc && ! test -d abc/.git && ! test "`cat abc/.gitcommit | cut -c1-7`" = "$(ABCREV)"; then \ echo 'REEBE: Qbjaybnqrq NOP irefvbaf qbrf abg zngpu! Qbjaybnq sebz:' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; echo $(ABCURL)/archive/$(ABCREV).tar.gz; false; \ fi # set a variable so the test fails if git fails to run - when comparing outputs directly, empty string would match empty string - $(Q) if test -d abc && ! test -d abc/.git && test "`cat abc/.gitcommit | cut -c1-7`" == "$(ABCREV)"; then \ + $(Q) if test -d abc && ! test -d abc/.git && test "`cat abc/.gitcommit | cut -c1-7`" = "$(ABCREV)"; then \ echo "Compiling local copy of ABC"; \ - elif ! (cd abc 2> /dev/null && rev="`git rev-parse $(ABCREV)`" && test "`git rev-parse HEAD`" == "$$rev"); then \ + elif ! (cd abc 2> /dev/null && rev="`git rev-parse $(ABCREV)`" && test "`git rev-parse HEAD`" = "$$rev"); then \ test $(ABCPULL) -ne 0 || { echo 'REEBE: NOP abg hc gb qngr naq NOPCHYY frg gb 0 va Znxrsvyr!' | tr 'A-Za-z' 'N-ZA-Mn-za-m'; exit 1; }; \ echo "Pulling ABC from $(ABCURL):"; set -x; \ test -d abc || git clone $(ABCURL) abc; \ From 43b807fe6fc9a124f2c6330e1522f0ceedbd1f4e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 00:17:12 +0000 Subject: [PATCH 120/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bcb6a066cce..3439f20feb4 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+40 +YOSYS_VER := 0.29+42 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From c244a7161b60e74a4db767016b45f4e5dec9920c Mon Sep 17 00:00:00 2001 From: Patrick Urban Date: Tue, 30 May 2023 09:05:43 +0200 Subject: [PATCH 121/303] gatemate: Fix SDP read behavior --- techlibs/gatemate/cells_sim.v | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v index 12e01d2dfe9..dbf2d514aa7 100644 --- a/techlibs/gatemate/cells_sim.v +++ b/techlibs/gatemate/cells_sim.v @@ -733,13 +733,12 @@ module CC_BRAM_20K ( // SDP read port always @(posedge clkb) begin - // "NO_CHANGE" only for (k=0; k < B_RD_WIDTH; k=k+1) begin if (k < 20) begin - if (enb && !wea) A_DO_out[k] <= memory[addrb+k]; + if (enb) A_DO_out[k] <= memory[addrb+k]; end else begin // use both ports - if (enb && !wea) B_DO_out[k-20] <= memory[addrb+k]; + if (enb) B_DO_out[k-20] <= memory[addrb+k]; end end end @@ -1274,13 +1273,12 @@ module CC_BRAM_40K ( // SDP read port always @(posedge clkb) begin - // "NO_CHANGE" only for (k=0; k < B_RD_WIDTH; k=k+1) begin if (k < 40) begin - if (enb && !wea) A_DO_out[k] <= memory[addrb+k]; + if (enb) A_DO_out[k] <= memory[addrb+k]; end else begin // use both ports - if (enb && !wea) B_DO_out[k-40] <= memory[addrb+k]; + if (enb) B_DO_out[k-40] <= memory[addrb+k]; end end end From 2004a9ff4ac008cce94655233def519ca70e2948 Mon Sep 17 00:00:00 2001 From: Patrick Urban Date: Tue, 30 May 2023 09:06:23 +0200 Subject: [PATCH 122/303] gatemate: Add CC_FIFO_40K simulation model --- techlibs/gatemate/cells_bb.v | 67 ------ techlibs/gatemate/cells_sim.v | 387 ++++++++++++++++++++++++++++++++++ 2 files changed, 387 insertions(+), 67 deletions(-) diff --git a/techlibs/gatemate/cells_bb.v b/techlibs/gatemate/cells_bb.v index 87b91764f6a..f928a3d7a1d 100644 --- a/techlibs/gatemate/cells_bb.v +++ b/techlibs/gatemate/cells_bb.v @@ -131,70 +131,3 @@ module CC_USR_RSTN ( output USR_RSTN ); endmodule - -(* blackbox *) -module CC_FIFO_40K ( - output A_ECC_1B_ERR, - output B_ECC_1B_ERR, - output A_ECC_2B_ERR, - output B_ECC_2B_ERR, - // FIFO pop port - output [39:0] A_DO, - output [39:0] B_DO, - (* clkbuf_sink *) - input A_CLK, - input A_EN, - // FIFO push port - input [39:0] A_DI, - input [39:0] B_DI, - input [39:0] A_BM, - input [39:0] B_BM, - (* clkbuf_sink *) - input B_CLK, - input B_EN, - input B_WE, - // FIFO control - input F_RST_N, - input [12:0] F_ALMOST_FULL_OFFSET, - input [12:0] F_ALMOST_EMPTY_OFFSET, - // FIFO status signals - output F_FULL, - output F_EMPTY, - output F_ALMOST_FULL, - output F_ALMOST_EMPTY, - output F_RD_ERROR, - output F_WR_ERROR, - output [15:0] F_RD_PTR, - output [15:0] F_WR_PTR -); - // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED - parameter LOC = "UNPLACED"; - - // Offset configuration - parameter [12:0] ALMOST_FULL_OFFSET = 12'b0; - parameter [12:0] ALMOST_EMPTY_OFFSET = 12'b0; - - // Port Widths - parameter A_WIDTH = 0; - parameter B_WIDTH = 0; - - // RAM and Write Modes - parameter RAM_MODE = "SDP"; // "TPD" or "SDP" - parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC" - - // Inverting Control Pins - parameter A_CLK_INV = 1'b0; - parameter B_CLK_INV = 1'b0; - parameter A_EN_INV = 1'b0; - parameter B_EN_INV = 1'b0; - parameter A_WE_INV = 1'b0; - parameter B_WE_INV = 1'b0; - - // Output Register - parameter A_DO_REG = 1'b0; - parameter B_DO_REG = 1'b0; - - // Error Checking and Correction - parameter A_ECC_EN = 1'b0; - parameter B_ECC_EN = 1'b0; -endmodule diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v index dbf2d514aa7..93f463043c4 100644 --- a/techlibs/gatemate/cells_sim.v +++ b/techlibs/gatemate/cells_sim.v @@ -1410,6 +1410,393 @@ module CC_BRAM_40K ( endgenerate endmodule +module CC_FIFO_40K ( + output A_ECC_1B_ERR, + output B_ECC_1B_ERR, + output A_ECC_2B_ERR, + output B_ECC_2B_ERR, + // FIFO pop port + output [39:0] A_DO, + output [39:0] B_DO, + (* clkbuf_sink *) + input A_CLK, + input A_EN, + // FIFO push port + input [39:0] A_DI, + input [39:0] B_DI, + input [39:0] A_BM, + input [39:0] B_BM, + (* clkbuf_sink *) + input B_CLK, + input B_EN, + input B_WE, + // FIFO control + input F_RST_N, + input [14:0] F_ALMOST_FULL_OFFSET, + input [14:0] F_ALMOST_EMPTY_OFFSET, + // FIFO status signals + output F_FULL, + output F_EMPTY, + output F_ALMOST_FULL, + output F_ALMOST_EMPTY, + output F_RD_ERROR, + output F_WR_ERROR, + output [15:0] F_RD_PTR, + output [15:0] F_WR_PTR +); + // Location format: D(0..N-1)X(0..3)Y(0..7) or UNPLACED + parameter LOC = "UNPLACED"; + + // Offset configuration + parameter DYN_STAT_SELECT = 1'b0; + parameter [14:0] ALMOST_FULL_OFFSET = 15'b0; + parameter [14:0] ALMOST_EMPTY_OFFSET = 15'b0; + + // Port Widths + parameter A_WIDTH = 0; + parameter B_WIDTH = 0; + + // RAM and Write Modes + parameter RAM_MODE = "TDP"; // "TDP" or "SDP" + parameter FIFO_MODE = "SYNC"; // "ASYNC" or "SYNC" + + // Inverting Control Pins + parameter A_CLK_INV = 1'b0; + parameter B_CLK_INV = 1'b0; + parameter A_EN_INV = 1'b0; + parameter B_EN_INV = 1'b0; + parameter A_WE_INV = 1'b0; + parameter B_WE_INV = 1'b0; + + // Output Register + parameter A_DO_REG = 1'b0; + parameter B_DO_REG = 1'b0; + + // Error Checking and Correction + parameter A_ECC_EN = 1'b0; + parameter B_ECC_EN = 1'b0; + + integer i, k; + + // 512 x 80 bit + reg [40959:0] memory = 40960'b0; + + reg [15:0] counter_max; + reg [15:0] sram_depth; + localparam tp = (A_WIDTH == 1) ? 15 : + (A_WIDTH == 2) ? 14 : + (A_WIDTH == 5) ? 13 : + (A_WIDTH == 10) ? 12 : + (A_WIDTH == 20) ? 11 : + (A_WIDTH == 40) ? 10 : 9; + + initial begin + // Check parameters + if ((RAM_MODE != "SDP") && (RAM_MODE != "TDP")) begin + $display("ERROR: Illegal RAM MODE %d.", RAM_MODE); + $finish(); + end + if ((FIFO_MODE != "ASYNC") && (FIFO_MODE != "SYNC")) begin + $display("ERROR: Illegal FIFO MODE %d.", FIFO_MODE); + $finish(); + end + if ((RAM_MODE == "SDP") && (DYN_STAT_SELECT == 1)) begin + $display("ERROR: Dynamic offset configuration is not supported in %s mode.", RAM_MODE); + $finish(); + end + if ((RAM_MODE == "SDP") && ((A_WIDTH != 80) || (B_WIDTH != 80))) begin + $display("ERROR: SDP is ony supported in 80 bit mode."); + $finish(); + end + if ((A_WIDTH == 80) && (RAM_MODE == "TDP")) begin + $display("ERROR: Port A width of 80 bits is only supported in SDP mode."); + $finish(); + end + if ((B_WIDTH == 80) && (RAM_MODE == "TDP")) begin + $display("ERROR: Port B width of 80 bits is only supported in SDP mode."); + $finish(); + end + if ((A_WIDTH != 80) && (A_WIDTH != 40) && (A_WIDTH != 20) && (A_WIDTH != 10) && + (A_WIDTH != 5) && (A_WIDTH != 2) && (A_WIDTH != 1) && (A_WIDTH != 0)) begin + $display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, A_WIDTH); + $finish(); + end + if ((B_WIDTH != 80) && (B_WIDTH != 40) && (B_WIDTH != 20) && (B_WIDTH != 10) && + (B_WIDTH != 5) && (B_WIDTH != 2) && (B_WIDTH != 1) && (B_WIDTH != 0)) begin + $display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, B_WIDTH); + $finish(); + end + if (A_WIDTH != B_WIDTH) begin + $display("ERROR: The values of A_WIDTH and B_WIDTH must be equal."); + end + if ((A_ECC_EN == 1'b1) && (RAM_MODE != "SDP") && (A_WIDTH != 40)) begin + $display("ERROR: Illegal ECC Port A configuration. ECC mode requires TDP >=40 bit or SDP 80 bit, but is %s %d.", RAM_MODE, A_WIDTH); + $finish(); + end + // Set local parameters + if (A_WIDTH == 1) begin // A_WIDTH=B_WIDTH + counter_max = 2 * 32*1024 - 1; + sram_depth = 32*1024; + end + else if (A_WIDTH == 2) begin + counter_max = 2 * 16*1024 - 1; + sram_depth = 16*1024; + end + else if (A_WIDTH == 5) begin + counter_max = 2 * 8*1024 - 1; + sram_depth = 8*1024; + end + else if (A_WIDTH == 10) begin + counter_max = 2 * 4*1024 - 1; + sram_depth = 4*1024; + end + else if (A_WIDTH == 20) begin + counter_max = 2 * 2*1024 - 1; + sram_depth = 2*1024; + end + else if (A_WIDTH == 40) begin + counter_max = 2 * 1*1024 - 1; + sram_depth = 1*1024; + end + else begin // 80 bit SDP + counter_max = 2 * 512 - 1; + sram_depth = 512; + end + end + + // Internal signals + wire fifo_rdclk = A_CLK ^ A_CLK_INV; + wire fifo_wrclk = (FIFO_MODE == "ASYNC") ? (B_CLK ^ B_CLK_INV) : (A_CLK ^ A_CLK_INV); + wire [15:0] almost_full_offset = DYN_STAT_SELECT ? F_ALMOST_FULL_OFFSET : ALMOST_FULL_OFFSET; + wire [15:0] almost_empty_offset = DYN_STAT_SELECT ? F_ALMOST_EMPTY_OFFSET : ALMOST_EMPTY_OFFSET; + reg [39:0] A_DO_out = 0, A_DO_reg = 0; + reg [39:0] B_DO_out = 0, B_DO_reg = 0; + + // Status signals + reg fifo_full; + reg fifo_empty; + reg fifo_almost_full; + reg fifo_almost_empty; + assign F_FULL = fifo_full; + assign F_EMPTY = fifo_empty; + assign F_ALMOST_FULL = fifo_almost_full; + assign F_ALMOST_EMPTY = fifo_almost_empty; + assign F_WR_ERROR = (F_FULL && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); + assign F_RD_ERROR = (F_EMPTY && (A_EN ^ A_EN_INV)); + assign ram_we = (~F_FULL && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); + assign ram_en = (~F_EMPTY && (A_EN ^ A_EN_INV)); + + // Reset synchronizers + reg [1:0] aclk_reset_q, bclk_reset_q; + wire fifo_sync_rstn = aclk_reset_q; + wire fifo_async_wrrstn = bclk_reset_q; + wire fifo_async_rdrstn = aclk_reset_q; + + always @(posedge fifo_rdclk or negedge F_RST_N) + begin + if (F_RST_N == 1'b0) begin + aclk_reset_q <= 2'b0; + end + else begin + aclk_reset_q[1] <= aclk_reset_q[0]; + aclk_reset_q[0] <= 1'b1; + end + end + + always @(posedge fifo_wrclk or negedge F_RST_N) + begin + if (F_RST_N == 1'b0) begin + bclk_reset_q <= 2'b0; + end + else begin + bclk_reset_q[1] <= bclk_reset_q[0]; + bclk_reset_q[0] <= 1'b1; + end + end + + // Push/pop pointers + reg [15:0] rd_pointer, rd_pointer_int; + reg [15:0] wr_pointer, wr_pointer_int; + reg [15:0] rd_pointer_cmp, wr_pointer_cmp; + wire [15:0] rd_pointer_nxt; + wire [15:0] wr_pointer_nxt; + reg [15:0] fifo_rdaddr, rdaddr; + reg [15:0] fifo_wraddr, wraddr; + assign F_RD_PTR = fifo_rdaddr; + assign F_WR_PTR = fifo_wraddr; + + always @(posedge fifo_rdclk or negedge F_RST_N) + begin + if (F_RST_N == 1'b0) begin + rd_pointer <= 0; + rd_pointer_int <= 0; + end + else if (ram_en) begin + rd_pointer <= rd_pointer_nxt; + rd_pointer_int <= rd_pointer_nxt[15:1] ^ rd_pointer_nxt[14:0]; + end + end + + assign rd_pointer_nxt = (rd_pointer == counter_max) ? (0) : (rd_pointer + 1'b1); + + always @(posedge fifo_wrclk or negedge F_RST_N) + begin + if (F_RST_N == 1'b0) begin + wr_pointer <= 0; + wr_pointer_int <= 0; + end + else if (ram_we) begin + wr_pointer <= wr_pointer_nxt; + wr_pointer_int <= wr_pointer_nxt[15:1] ^ wr_pointer_nxt[14:0]; + end + end + + assign wr_pointer_nxt = (wr_pointer == counter_max) ? (0) : (wr_pointer + 1'b1); + + // Address synchronizers + reg [15:0] rd_pointer_sync, wr_pointer_sync; + reg [15:0] rd_pointer_sync_0, rd_pointer_sync_1; + reg [15:0] wr_pointer_sync_0, wr_pointer_sync_1; + + always @(posedge fifo_rdclk or negedge F_RST_N) + begin + if (F_RST_N == 1'b0) begin + wr_pointer_sync_0 <= 0; + wr_pointer_sync_1 <= 0; + end + else begin + wr_pointer_sync_0 <= wraddr; + wr_pointer_sync_1 <= wr_pointer_sync_0; + end + end + + always @(posedge fifo_wrclk or negedge F_RST_N) + begin + if (F_RST_N == 1'b0) begin + rd_pointer_sync_0 <= 0; + rd_pointer_sync_1 <= 0; + end + else begin + rd_pointer_sync_0 <= rdaddr; + rd_pointer_sync_1 <= rd_pointer_sync_0; + end + end + + always @(*) begin + fifo_wraddr = {wr_pointer[tp-1:0], {(15-tp){1'b0}}}; + fifo_rdaddr = {rd_pointer[tp-1:0], {(15-tp){1'b0}}}; + + rdaddr = {rd_pointer[tp], rd_pointer_int[tp-1:0]}; + wraddr = {{(15-tp){1'b0}}, wr_pointer[tp], wr_pointer_int[tp:0]}; + + if (FIFO_MODE == "ASYNC") + fifo_full = (wraddr[tp-2:0] == rd_pointer_sync_1[tp-2:0] ) && (wraddr[tp] != rd_pointer_sync_1[tp] ) && ( wraddr[tp-1] != rd_pointer_sync_1[tp-1] ); + else + fifo_full = (wr_pointer[tp-1:0] == rd_pointer[tp-1:0]) && (wr_pointer[tp] ^ rd_pointer[tp]); + + if (FIFO_MODE == "ASYNC") + fifo_empty = (wr_pointer_sync_1[tp:0] == rdaddr[tp:0]); + else + fifo_empty = (wr_pointer[tp:0] == rd_pointer[tp:0]); + + rd_pointer_cmp = (FIFO_MODE == "ASYNC") ? rd_pointer_sync : rd_pointer; + if (wr_pointer[tp] == rd_pointer_cmp[tp]) + fifo_almost_full = ((wr_pointer[tp-1:0] - rd_pointer_cmp[tp-1:0]) >= (sram_depth - almost_full_offset)); + else + fifo_almost_full = ((rd_pointer_cmp[tp-1:0] - wr_pointer[tp-1:0]) <= almost_full_offset); + + wr_pointer_cmp = (FIFO_MODE == "ASYNC") ? wr_pointer_sync : wr_pointer; + if (wr_pointer_cmp[tp] == rd_pointer[tp]) + fifo_almost_empty = ((wr_pointer_cmp[tp-1:0] - rd_pointer[tp-1:0]) <= almost_empty_offset); + else + fifo_almost_empty = ((rd_pointer[tp-1:0] - wr_pointer_cmp[tp-1:0]) >= (sram_depth - almost_empty_offset)); + end + + generate + always @(*) begin + wr_pointer_sync = 0; + rd_pointer_sync = 0; + for (i=tp; i >= 0; i=i-1) begin + if (i == tp) begin + wr_pointer_sync[i] = wr_pointer_sync_1[i]; + rd_pointer_sync[i] = rd_pointer_sync_1[i]; + end + else begin + wr_pointer_sync[i] = wr_pointer_sync_1[i] ^ wr_pointer_sync[i+1]; + rd_pointer_sync[i] = rd_pointer_sync_1[i] ^ rd_pointer_sync[i+1]; + end + end + end + if (RAM_MODE == "SDP") begin + // SDP push ports A+B + always @(posedge fifo_wrclk) + begin + for (k=0; k < A_WIDTH; k=k+1) begin + if (k < 40) begin + if (ram_we && A_BM[k]) memory[fifo_wraddr+k] <= A_DI[k]; + end + else begin // use both ports + if (ram_we && B_BM[k-40]) memory[fifo_wraddr+k] <= B_DI[k-40]; + end + end + end + // SDP pop ports A+B + always @(posedge fifo_rdclk) + begin + for (k=0; k < B_WIDTH; k=k+1) begin + if (k < 40) begin + if (ram_en) A_DO_out[k] <= memory[fifo_rdaddr+k]; + end + else begin // use both ports + if (ram_en) B_DO_out[k-40] <= memory[fifo_rdaddr+k]; + end + end + end + end + else if (RAM_MODE == "TDP") begin + // TDP pop port A + always @(posedge fifo_rdclk) + begin + for (i=0; i < A_WIDTH; i=i+1) begin + if (ram_en) begin + A_DO_out[i] <= memory[fifo_rdaddr+i]; + end + end + end + // TDP push port B + always @(posedge fifo_wrclk) + begin + for (i=0; i < B_WIDTH; i=i+1) begin + if (ram_we && B_BM[i]) + memory[fifo_wraddr+i] <= B_DI[i]; + end + end + end + endgenerate + + // Optional output register + generate + if (A_DO_REG) begin + always @(posedge fifo_rdclk) begin + A_DO_reg <= A_DO_out; + end + assign A_DO = A_DO_reg; + end + else begin + assign A_DO = A_DO_out; + end + if (B_DO_REG) begin + always @(posedge fifo_rdclk) begin + B_DO_reg <= B_DO_out; + end + assign B_DO = B_DO_reg; + end + else begin + assign B_DO = B_DO_out; + end + endgenerate +endmodule + // Models of the LUT2 tree primitives module CC_L2T4( output O, From 4b986c9c65a9ceb297f0843eb0a9f34d97baadb0 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 31 May 2023 17:38:46 +0200 Subject: [PATCH 123/303] fix wire color after BUF --- passes/cmds/show.cc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 46aa16c90d1..09fd3d4b657 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -106,7 +106,7 @@ struct ShowWorker { std::string color = findColor(conn); if (!color.empty()) return color; - return nextColor(conn.first, nextColor(conn.second, defaultColor)); + return defaultColor; } std::string nextColor(const RTLIL::SigSpec &sig) @@ -490,16 +490,14 @@ struct ShowWorker conn.second, ct.cell_output(cell->type, conn.first)); } - std::string color = findColor(cell->name); - if (!color.empty()) color = ", " + color; #ifdef CLUSTER_CELLS_AND_PORTBOXES if (!code.empty()) fprintf(f, "subgraph cluster_c%d {\nc%d [ shape=record, label=\"%s\"%s ];\n%s}\n", id2num(cell->name), id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); else #endif - fprintf(f, "c%d [ shape=record, label=\"%s\"%s ];\n%s", - id2num(cell->name), label_string.c_str(), color.c_str(), code.c_str()); + fprintf(f, "c%d [ shape=record, label=\"%s\", %s ];\n%s", + id2num(cell->name), label_string.c_str(), findColor(cell->name).c_str(), code.c_str()); } for (auto &it : module->processes) @@ -569,9 +567,9 @@ struct ShowWorker } else if (right_node[0] == 'x') { net_conn_map[left_node].out.insert({right_node, GetSize(conn.first)}); } else { - net_conn_map[right_node].in.insert({stringf("x%d:e", single_idx_count), GetSize(conn.first)}); - net_conn_map[left_node].out.insert({stringf("x%d:w", single_idx_count), GetSize(conn.first)}); - fprintf(f, "x%d [shape=box, style=rounded, label=\"BUF\"];\n", single_idx_count++); + net_conn_map[right_node].in.insert({stringf("x%d", single_idx_count), GetSize(conn.first)}); + net_conn_map[left_node].out.insert({stringf("x%d", single_idx_count), GetSize(conn.first)}); + fprintf(f, "x%d [shape=box, style=rounded, label=\"BUF\", %s];\n", single_idx_count++, findColor(conn).c_str()); } } } From 0707b911c7352398388a0331cf1660a78cc571c8 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Thu, 1 Jun 2023 10:02:30 +0200 Subject: [PATCH 124/303] show: add -viewer none option --- passes/cmds/show.cc | 49 ++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 09fd3d4b657..525c81d5b85 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -329,7 +329,7 @@ struct ShowWorker } code += stringf("x%d [ shape=record, style=rounded, label=\"", dot_idx) \ - + join_label_pieces(label_pieces) + "\" ];\n"; + + join_label_pieces(label_pieces) + stringf("\", %s ];\n", nextColor(sig).c_str()); if (!port.empty()) { currentColor = xorshift32(currentColor); @@ -655,6 +655,7 @@ struct ShowPass : public Pass { log(" -viewer \n"); log(" Run the specified command with the graphics file as parameter.\n"); log(" On Windows, this pauses yosys until the viewer exits.\n"); + log(" Use \"-viewer none\" to not run any command.\n"); log("\n"); log(" -format \n"); log(" Generate a graphics file in the specified format. Use 'dot' to just\n"); @@ -915,28 +916,30 @@ struct ShowPass : public Pass { #if defined(YOSYS_DISABLE_SPAWN) log_assert(viewer_exe.empty() && !format.empty()); #else - if (!viewer_exe.empty()) { - #ifdef _WIN32 - // system()/cmd.exe does not understand single quotes nor - // background tasks on Windows. So we have to pause yosys - // until the viewer exits. - std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str()); - #else - std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str()); - #endif - log("Exec: %s\n", cmd.c_str()); - if (run_command(cmd) != 0) - log_cmd_error("Shell command failed!\n"); - } else - if (format.empty()) { - #ifdef __APPLE__ - std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str()); - #else - std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str()); - #endif - log("Exec: %s\n", cmd.c_str()); - if (run_command(cmd) != 0) - log_cmd_error("Shell command failed!\n"); + if (viewer_exe != "none") { + if (!viewer_exe.empty()) { + #ifdef _WIN32 + // system()/cmd.exe does not understand single quotes nor + // background tasks on Windows. So we have to pause yosys + // until the viewer exits. + std::string cmd = stringf("%s \"%s\"", viewer_exe.c_str(), out_file.c_str()); + #else + std::string cmd = stringf("%s '%s' %s", viewer_exe.c_str(), out_file.c_str(), background.c_str()); + #endif + log("Exec: %s\n", cmd.c_str()); + if (run_command(cmd) != 0) + log_cmd_error("Shell command failed!\n"); + } else + if (format.empty()) { + #ifdef __APPLE__ + std::string cmd = stringf("ps -fu %d | grep -q '[ ]%s' || xdot '%s' %s", getuid(), dot_file.c_str(), dot_file.c_str(), background.c_str()); + #else + std::string cmd = stringf("{ test -f '%s.pid' && fuser -s '%s.pid' 2> /dev/null; } || ( echo $$ >&3; exec xdot '%s'; ) 3> '%s.pid' %s", dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), dot_file.c_str(), background.c_str()); + #endif + log("Exec: %s\n", cmd.c_str()); + if (run_command(cmd) != 0) + log_cmd_error("Shell command failed!\n"); + } } #endif From d7f25165a53b97b10aafce4c70732f1adc3c5156 Mon Sep 17 00:00:00 2001 From: Claire Xenia Wolf Date: Sat, 3 Jun 2023 14:38:22 +0200 Subject: [PATCH 125/303] Add ninitff line to aiger .aim files Signed-off-by: Claire Xenia Wolf --- backends/aiger/aiger.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 97acf937cd7..689864153db 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -706,6 +706,9 @@ struct AigerWriter for (auto &it : latch_lines) f << it.second; + if (initstate_ff) + f << stringf("ninitff %d\n", ((initstate_ff >> 1)-1-aig_i)); + wire_lines.sort(); for (auto &it : wire_lines) f << it.second; From 88c849d112f4f8cf20617bbc98eac055956269c2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 4 Jun 2023 00:19:27 +0000 Subject: [PATCH 126/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3439f20feb4..99ee10c43c0 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+42 +YOSYS_VER := 0.29+44 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 61387d78b7243c10fee247f8a6c4e1fc1a6a5659 Mon Sep 17 00:00:00 2001 From: Patrick Urban Date: Mon, 5 Jun 2023 19:08:44 +0200 Subject: [PATCH 127/303] gatemate: Prevent implicit declaration of `ram_{we,en}` --- techlibs/gatemate/cells_sim.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v index 93f463043c4..e05ce811c9e 100644 --- a/techlibs/gatemate/cells_sim.v +++ b/techlibs/gatemate/cells_sim.v @@ -1583,8 +1583,8 @@ module CC_FIFO_40K ( assign F_ALMOST_EMPTY = fifo_almost_empty; assign F_WR_ERROR = (F_FULL && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); assign F_RD_ERROR = (F_EMPTY && (A_EN ^ A_EN_INV)); - assign ram_we = (~F_FULL && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); - assign ram_en = (~F_EMPTY && (A_EN ^ A_EN_INV)); + wire ram_we = (~F_FULL && (B_EN ^ B_EN_INV) && (B_WE ^ B_WE_INV)); + wire ram_en = (~F_EMPTY && (A_EN ^ A_EN_INV)); // Reset synchronizers reg [1:0] aclk_reset_q, bclk_reset_q; From 73badeccefc5dedd2681ae5bcbc2893d92be2354 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 00:17:35 +0000 Subject: [PATCH 128/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5fc6ac29c80..430dd5b7dfa 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+44 +YOSYS_VER := 0.29+58 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f7a8284c7b095bca4bc2c65032144c4e3264ee4d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 6 Jun 2023 09:38:46 +0200 Subject: [PATCH 129/303] Release version 0.30 --- CHANGELOG | 12 +++++++++++- Makefile | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1430f8e2f92..a461564081e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,18 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.29 .. Yosys 0.29-dev +Yosys 0.29 .. Yosys 0.30 -------------------------- + * New commands and options + - Added "recover_names" pass to recover names post-mapping. + + * Gowin support + - Added remaining primitives blackboxes. + + * Various + - "show -colorattr" will now color the cells, wires, and + connection arrows. + - "show -viewer none" will not execute viewer. Yosys 0.28 .. Yosys 0.29 -------------------------- diff --git a/Makefile b/Makefile index 430dd5b7dfa..3ff983198a8 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.29+58 +YOSYS_VER := 0.30 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9c5a60e.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9c5a60e.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From c5e4eec3ba932268a81bb352b3734e8868d874bf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 6 Jun 2023 09:41:26 +0200 Subject: [PATCH 130/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a461564081e..0d433d4a33d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.30 .. Yosys 0.31-dev +-------------------------- + Yosys 0.29 .. Yosys 0.30 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index 3ff983198a8..6732998affa 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30 +YOSYS_VER := 0.30+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 9c5a60e.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f7a8284.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From b623888f6aa3b9d519cdb55bc7508021ae43dad2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 6 Jun 2023 11:57:20 +0200 Subject: [PATCH 131/303] Update ABC to latest --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6732998affa..f957c773018 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 2c1c83f +ABCREV = 0b36135 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From 0d4a67026732749931463c7f455f72c8e21d110c Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 6 Jun 2023 14:37:14 +0200 Subject: [PATCH 132/303] Update ABC --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f957c773018..a5049bfa443 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 0b36135 +ABCREV = 1de4eaf ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From 5813809ad9afbe1c38f65c6aae7c3441d7614d0b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 00:17:31 +0000 Subject: [PATCH 133/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6732998affa..7afa6c47264 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+0 +YOSYS_VER := 0.30+1 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From e6f7cf3b29adcfef592055158308c6ab2bc69288 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 9 Jun 2023 14:41:45 +0200 Subject: [PATCH 134/303] Update tests --- tests/arch/anlogic/mux.ys | 8 +++++--- tests/arch/ecp5/mux.ys | 4 ++-- tests/arch/gatemate/fsm.ys | 2 +- tests/arch/ice40/rom.ys | 2 +- tests/arch/intel_alm/mux.ys | 8 ++++---- tests/arch/nexus/mux.ys | 3 +-- tests/arch/xilinx/mux_lut4.ys | 9 +++++---- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tests/arch/anlogic/mux.ys b/tests/arch/anlogic/mux.ys index 3d5fe7c9a61..89014b5e057 100644 --- a/tests/arch/anlogic/mux.ys +++ b/tests/arch/anlogic/mux.ys @@ -26,10 +26,12 @@ proc equiv_opt -assert -map +/anlogic/cells_sim.v synth_anlogic # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module -select -assert-count 3 t:AL_MAP_LUT4 -select -assert-count 1 t:AL_MAP_LUT6 +select -assert-max 3 t:AL_MAP_LUT3 +select -assert-max 3 t:AL_MAP_LUT4 +select -assert-max 1 t:AL_MAP_LUT5 +select -assert-max 1 t:AL_MAP_LUT6 -select -assert-none t:AL_MAP_LUT4 t:AL_MAP_LUT6 %% t:* %D +select -assert-none t:AL_MAP_LUT3 t:AL_MAP_LUT4 t:AL_MAP_LUT5 t:AL_MAP_LUT6 %% t:* %D design -load read hierarchy -top mux16 diff --git a/tests/arch/ecp5/mux.ys b/tests/arch/ecp5/mux.ys index db63dda5f94..daa9e86f269 100644 --- a/tests/arch/ecp5/mux.ys +++ b/tests/arch/ecp5/mux.ys @@ -28,8 +28,8 @@ equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-max 1 t:L6MUX21 -select -assert-max 7 t:LUT4 -select -assert-max 2 t:PFUMX +select -assert-max 8 t:LUT4 +select -assert-max 3 t:PFUMX select -assert-none t:LUT4 t:L6MUX21 t:PFUMX %% t:* %D diff --git a/tests/arch/gatemate/fsm.ys b/tests/arch/gatemate/fsm.ys index 6b43ead7ac7..506862c908e 100644 --- a/tests/arch/gatemate/fsm.ys +++ b/tests/arch/gatemate/fsm.ys @@ -15,6 +15,6 @@ cd fsm # Constrain all select calls below inside the top module select -assert-count 1 t:CC_BUFG select -assert-count 6 t:CC_DFF select -assert-max 5 t:CC_LUT2 -select -assert-max 4 t:CC_LUT3 +select -assert-max 6 t:CC_LUT3 select -assert-max 9 t:CC_LUT4 select -assert-none t:CC_BUFG t:CC_DFF t:CC_LUT2 t:CC_LUT3 t:CC_LUT4 %% t:* %D diff --git a/tests/arch/ice40/rom.ys b/tests/arch/ice40/rom.ys index 41d214e2a91..d795e206b4a 100644 --- a/tests/arch/ice40/rom.ys +++ b/tests/arch/ice40/rom.ys @@ -4,5 +4,5 @@ flatten equiv_opt -assert -map +/ice40/cells_sim.v synth_ice40 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module -select -assert-count 5 t:SB_LUT4 +select -assert-max 6 t:SB_LUT4 select -assert-none t:SB_LUT4 %% t:* %D diff --git a/tests/arch/intel_alm/mux.ys b/tests/arch/intel_alm/mux.ys index 6fb6ae80a42..20969ead35f 100644 --- a/tests/arch/intel_alm/mux.ys +++ b/tests/arch/intel_alm/mux.ys @@ -69,7 +69,7 @@ proc equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclonev -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module -select -assert-count 1 t:MISTRAL_ALUT3 +select -assert-max 1 t:MISTRAL_ALUT3 select -assert-max 2 t:MISTRAL_ALUT5 select -assert-max 5 t:MISTRAL_ALUT6 select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D @@ -81,8 +81,8 @@ proc equiv_opt -assert -map +/intel_alm/common/alm_sim.v synth_intel_alm -family cyclone10gx -noiopad -noclkbuf # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module -select -assert-count 1 t:MISTRAL_ALUT3 -select -assert-count 2 t:MISTRAL_ALUT5 -select -assert-count 4 t:MISTRAL_ALUT6 +select -assert-max 1 t:MISTRAL_ALUT3 +select -assert-max 2 t:MISTRAL_ALUT5 +select -assert-max 5 t:MISTRAL_ALUT6 select -assert-none t:MISTRAL_ALUT3 t:MISTRAL_ALUT5 t:MISTRAL_ALUT6 %% t:* %D diff --git a/tests/arch/nexus/mux.ys b/tests/arch/nexus/mux.ys index 0e12d674a7c..280d3e48f95 100644 --- a/tests/arch/nexus/mux.ys +++ b/tests/arch/nexus/mux.ys @@ -36,8 +36,7 @@ proc equiv_opt -assert -map +/nexus/cells_sim.v synth_nexus # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module -select -assert-min 11 t:LUT4 select -assert-max 12 t:LUT4 -select -assert-count 1 t:WIDEFN9 +select -assert-max 2 t:WIDEFN9 select -assert-none t:IB t:OB t:VLO t:VHI t:LUT4 t:WIDEFN9 %% t:* %D diff --git a/tests/arch/xilinx/mux_lut4.ys b/tests/arch/xilinx/mux_lut4.ys index 3e3256993bc..147601dce01 100644 --- a/tests/arch/xilinx/mux_lut4.ys +++ b/tests/arch/xilinx/mux_lut4.ys @@ -30,12 +30,13 @@ proc equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -family xc3se -noiopad # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module -select -assert-count 4 t:LUT1 -select -assert-count 3 t:LUT4 -select -assert-count 2 t:MUXF5 +select -assert-max 5 t:LUT1 +select -assert-max 3 t:LUT3 +select -assert-max 3 t:LUT4 +select -assert-max 3 t:MUXF5 select -assert-count 1 t:MUXF6 -select -assert-none t:LUT1 t:LUT4 t:MUXF5 t:MUXF6 %% t:* %D +select -assert-none t:LUT1 t:LUT3 t:LUT4 t:MUXF5 t:MUXF6 %% t:* %D design -load read From dcc4d6e90be3ad349eb6497adf6dbe2781e8bd57 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 9 Jun 2023 15:21:22 +0200 Subject: [PATCH 135/303] yosys-witness: Don't treat aiw x-bits as don't change While treating initialization only bits as don't change during later cycles is correct, actual x-bits should be kept as x-bits. --- backends/smt2/witness.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/smt2/witness.py b/backends/smt2/witness.py index 8d0cc8112d1..7d5a2469eb5 100644 --- a/backends/smt2/witness.py +++ b/backends/smt2/witness.py @@ -194,7 +194,7 @@ def aiw2yw(input, mapfile, output): values = WitnessValues() for i, v in enumerate(inline): - if v == "x" or outyw.t > 0 and i in aiger_map.init_inputs: + if outyw.t > 0 and i in aiger_map.init_inputs: continue try: From 75cf79588e6b877fdbb45836abf6d177130ee27d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 12 Jun 2023 10:01:01 +0200 Subject: [PATCH 136/303] Add ability for user plugin to add new verific log callback --- frontends/verific/verific.cc | 21 ++++++++++++++++----- kernel/log.cc | 1 + kernel/log.h | 3 +++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 5d93954a73a..52008ddc6d7 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -112,15 +112,26 @@ void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefil string message = linefile ? stringf("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)) : ""; message += vstringf(msg, args); - if (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_WARNING || msg_type == VERIFIC_PROGRAM_ERROR) - log_warning_noprefix("%s%s\n", message_prefix.c_str(), message.c_str()); - else - log("%s%s\n", message_prefix.c_str(), message.c_str()); - + if (log_verific_callback) { + string full_message = stringf("%s%s\n", message_prefix.c_str(), message.c_str()); + log_verific_callback(int(msg_type), message_id, LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile), full_message.c_str()); + } else { + if (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_WARNING || msg_type == VERIFIC_PROGRAM_ERROR) + log_warning_noprefix("%s%s\n", message_prefix.c_str(), message.c_str()); + else + log("%s%s\n", message_prefix.c_str(), message.c_str()); + } if (verific_error_msg.empty() && (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_PROGRAM_ERROR)) verific_error_msg = message; } +void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int line_no, const char *msg)) +{ + Message::SetConsoleOutput(0); + Message::RegisterCallBackMsg(msg_func); + log_verific_callback = cb; +} + string get_full_netlist_name(Netlist *nl) { if (nl->NumOfRefs() == 1) { diff --git a/kernel/log.cc b/kernel/log.cc index 75a1ffb4559..985165a97f0 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -59,6 +59,7 @@ bool log_quiet_warnings = false; int log_verbose_level; string log_last_error; void (*log_error_atexit)() = NULL; +void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int line_no, const char *msg) = NULL; int log_make_debug = 0; int log_force_debug = 0; diff --git a/kernel/log.h b/kernel/log.h index 3a6ec87587a..3e4c2edfddd 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -130,6 +130,9 @@ void log_header(RTLIL::Design *design, const char *format, ...) YS_ATTRIBUTE(for void log_warning(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); void log_experimental(const char *format, ...) YS_ATTRIBUTE(format(printf, 1, 2)); +void set_verific_logging(void (*cb)(int msg_type, const char *message_id, const char* file_path, unsigned int line_no, const char *msg)); +extern void (*log_verific_callback)(int msg_type, const char *message_id, const char* file_path, unsigned int line_no, const char *msg); + // 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)); From 34a6bef768934413a3c7064b2406b490d8e63252 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 12 Jun 2023 10:01:35 +0200 Subject: [PATCH 137/303] link verific where appropriate and link full archives --- Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 7afa6c47264..1ecf672f9be 100644 --- a/Makefile +++ b/Makefile @@ -523,6 +523,7 @@ CXXFLAGS += -I$(GHDL_INCLUDE_DIR) -DYOSYS_ENABLE_GHDL LDLIBS += $(GHDL_LIB_DIR)/libghdl.a $(file <$(GHDL_LIB_DIR)/libghdl.link) endif +LDLIBS_VERIFIC = ifeq ($(ENABLE_VERIFIC),1) VERIFIC_DIR ?= /usr/local/src/verific_lib VERIFIC_COMPONENTS ?= verilog database util containers hier_tree @@ -548,9 +549,9 @@ CXXFLAGS += -DYOSYSHQ_VERIFIC_EXTENSIONS endif CXXFLAGS += $(patsubst %,-I$(VERIFIC_DIR)/%,$(VERIFIC_COMPONENTS)) -DYOSYS_ENABLE_VERIFIC ifeq ($(OS), Darwin) -LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)) -lz +LDLIBS_VERIFIC += $(foreach comp,$(patsubst %,$(VERIFIC_DIR)/%/*-mac.a,$(VERIFIC_COMPONENTS)),-Wl,-force_load $(comp)) -lz else -LDLIBS += $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) -lz +LDLIBS_VERIFIC += -Wl,--whole-archive $(patsubst %,$(VERIFIC_DIR)/%/*-linux.a,$(VERIFIC_COMPONENTS)) -Wl,--no-whole-archive -lz endif endif @@ -740,13 +741,13 @@ yosys.js: $(filter-out yosysjs-$(YOSYS_VER).zip,$(EXTRA_TARGETS)) endif $(PROGRAM_PREFIX)yosys$(EXE): $(OBJS) - $(P) $(LD) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) + $(P) $(LD) -o $(PROGRAM_PREFIX)yosys$(EXE) $(EXE_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) $(LDLIBS_VERIFIC) libyosys.so: $(filter-out kernel/driver.o,$(OBJS)) ifeq ($(OS), Darwin) - $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) + $(P) $(LD) -o libyosys.so -shared -Wl,-install_name,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) else - $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) + $(P) $(LD) -o libyosys.so -shared -Wl,-soname,$(LIBDIR)/libyosys.so $(LDFLAGS) $^ $(LDLIBS) $(LDLIBS_VERIFIC) endif %.o: %.cc From 8b2a0010216f9a15c09bd2f4dc63691949b126df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 00:17:19 +0000 Subject: [PATCH 138/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 808bf6bc8a7..c068c1f6d29 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+1 +YOSYS_VER := 0.30+16 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From c9d31c3c876c1b95accede88cbe8687eab815e7f Mon Sep 17 00:00:00 2001 From: Charlotte Connor Date: Tue, 13 Jun 2023 14:59:18 +1000 Subject: [PATCH 139/303] smt2: abits needs to be at least 1 for BitVec BitVecs need a minimum length of 1; we zero-fill any extra bits in the extend_u0() calls which works perfectly. --- backends/smt2/smt2.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/smt2/smt2.cc b/backends/smt2/smt2.cc index 7b48be29902..5e63e62370d 100644 --- a/backends/smt2/smt2.cc +++ b/backends/smt2/smt2.cc @@ -773,7 +773,7 @@ struct Smt2Worker int arrayid = idcounter++; memarrays[mem] = arrayid; - int abits = ceil_log2(mem->size); + int abits = max(1, ceil_log2(mem->size)); bool has_sync_wr = false; bool has_async_wr = false; @@ -1220,7 +1220,7 @@ struct Smt2Worker { int arrayid = memarrays.at(mem); - int abits = ceil_log2(mem->size);; + int abits = max(1, ceil_log2(mem->size)); bool has_sync_wr = false; bool has_async_wr = false; From d1b86d2fcf2fe92eb6b58dd05ea1284084af188b Mon Sep 17 00:00:00 2001 From: Krystine Sherwin <93062060+KrystalDelusion@users.noreply.github.com> Date: Mon, 19 Jun 2023 12:05:51 +1200 Subject: [PATCH 140/303] docs: reflow memory map Move additional notes up to the top and give it its own section. Also reformat some paragraphs, and turn some bullet points into paragraphs. Split supported patterns section into some kind of grouping. Currently: - SDP - single-port RAM - reset patterns - asymmetric - TDP --- docs/source/CHAPTER_Memorymap.rst | 300 +++++++++++++++--------------- 1 file changed, 151 insertions(+), 149 deletions(-) diff --git a/docs/source/CHAPTER_Memorymap.rst b/docs/source/CHAPTER_Memorymap.rst index e18ee9bb281..cdc381eed81 100644 --- a/docs/source/CHAPTER_Memorymap.rst +++ b/docs/source/CHAPTER_Memorymap.rst @@ -3,14 +3,131 @@ Memory mapping ============== -Documentation for the Yosys memory_libmap memory mapper. +Documentation for the Yosys ``memory_libmap`` memory mapper. Note that not all supported patterns +are included in this document, of particular note is that combinations of multiple patterns should +generally work. For example, `Write port with byte enables`_ could be used in conjunction with any +of the simple dual port (SDP) models. In general if a hardware memory definition does not support a +given configuration, additional logic will be instantiated to guarantee behaviour is consistent with +simulation. See also: `passes/memory/memlib.md `_ -Supported patterns ------------------- +Additional notes +---------------- + +Memory kind selection +~~~~~~~~~~~~~~~~~~~~~ + +The memory inference code will automatically pick target memory primitive based on memory geometry +and features used. Depending on the target, there can be up to four memory primitive classes +available for selection: + +- FF RAM (aka logic): no hardware primitive used, memory lowered to a bunch of FFs and multiplexers + + - Can handle arbitrary number of write ports, as long as all write ports are in the same clock domain + - Can handle arbitrary number and kind of read ports + +- LUT RAM (aka distributed RAM): uses LUT storage as RAM + + - Supported on most FPGAs (with notable exception of ice40) + - Usually has one synchronous write port, one or more asynchronous read ports + - Small + - Will never be used for ROMs (lowering to plain LUTs is always better) + +- Block RAM: dedicated memory tiles + + - Supported on basically all FPGAs + - Supports only synchronous reads + - Two ports with separate clocks + - Usually supports true dual port (with notable exception of ice40 that only supports SDP) + - Usually supports asymmetric memories and per-byte write enables + - Several kilobits in size + +- Huge RAM: + + - Only supported on several targets: + + - Some Xilinx UltraScale devices (UltraRAM) + + - Two ports, both with mutually exclusive synchronous read and write + - Single clock + - Initial data must be all-0 + + - Some ice40 devices (SPRAM) + + - Single port with mutually exclusive synchronous read and write + - Does not support initial data + + - Nexus (large RAM) + + - Two ports, both with mutually exclusive synchronous read and write + - Single clock + + - Will not be automatically selected by memory inference code, needs explicit opt-in via + ram_style attribute + +In general, you can expect the automatic selection process to work roughly like this: + +- If any read port is asynchronous, only LUT RAM (or FF RAM) can be used. +- If there is more than one write port, only block RAM can be used, and this needs to be a + hardware-supported true dual port pattern + + - … unless all write ports are in the same clock domain, in which case FF RAM can also be used, + but this is generally not what you want for anything but really small memories + +- Otherwise, either FF RAM, LUT RAM, or block RAM will be used, depending on memory size + +This process can be overridden by attaching a ram_style attribute to the memory: + +- `(* ram_style = "logic" *)` selects FF RAM +- `(* ram_style = "distributed" *)` selects LUT RAM +- `(* ram_style = "block" *)` selects block RAM +- `(* ram_style = "huge" *)` selects huge RAM + +It is an error if this override cannot be realized for the given target. + +Many alternate spellings of the attribute are also accepted, for compatibility with other software. + +Initial data +~~~~~~~~~~~~ + +Most FPGA targets support initializing all kinds of memory to user-provided values. If explicit +initialization is not used the initial memory value is undefined. Initial data can be provided by +either initial statements writing memory cells one by one of ``$readmemh`` or ``$readmemb`` system +tasks. For an example pattern, see `Synchronous read port with initial value`_. + +Write port with byte enables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Byte enables can be used with any supported pattern +- To ensure that multiple writes will be merged into one port, they need to have disjoint bit + ranges, have the same address, and the same clock +- Any write enable granularity will be accepted (down to per-bit write enables), but using smaller + granularity than natively supported by the target is very likely to be inefficient (eg. using + 4-bit bytes on ECP5 will result in either padding the bytes with 5 dummy bits to native 9-bit + units or splitting the RAM into two block RAMs) + +.. code:: verilog + + reg [31 : 0] mem [2**ADDR_WIDTH - 1 : 0]; + + always @(posedge clk) begin + if (write_enable[0]) + mem[write_addr][7:0] <= write_data[7:0]; + if (write_enable[1]) + mem[write_addr][15:8] <= write_data[15:8]; + if (write_enable[2]) + mem[write_addr][23:16] <= write_data[23:16]; + if (write_enable[3]) + mem[write_addr][31:24] <= write_data[31:24]; + if (read_enable) + read_data <= mem[read_addr]; + end + +Simple dual port (SDP) memory patterns +-------------------------------------- -Asynchronous-read RAM +Asynchronous-read SDP ~~~~~~~~~~~~~~~~~~~~~ - This will result in LUT RAM on supported targets @@ -69,7 +186,6 @@ Synchronous SDP with undefined collision behavior - Like above, but the read value is undefined when read and write ports target the same address in the same cycle - .. code:: verilog reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; @@ -141,6 +257,9 @@ Synchronous SDP with write-first behavior (alternate pattern) assign read_data = mem[read_addr_reg]; +Single-port RAM memory patterns +------------------------------- + Asynchronous-read single-port RAM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -234,13 +353,16 @@ Synchronous read port with initial value read_data <= mem[read_addr]; end -Synchronous read port with synchronous reset (reset priority over enable) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Read register reset patterns +---------------------------- -- Synchronous resets can be combined with any other supported pattern (except that synchronous reset - and asynchronous reset cannot be used on a single read port) -- If block RAM is used and synchronous resets are not natively supported by the target, small - emulation circuit will be inserted +Resets can be combined with any other supported pattern (except that synchronous reset and +asynchronous reset cannot both be used on a single read port). If block RAM is used and the +selected reset (synchronous or asynchronous) is used but not natively supported by the target, small +emulation circuitry will be inserted. + +Synchronous reset, reset priority over enable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: verilog @@ -256,13 +378,8 @@ Synchronous read port with synchronous reset (reset priority over enable) read_data <= mem[read_addr]; end -Synchronous read port with synchronous reset (enable priority over reset) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Synchronous resets can be combined with any other supported pattern (except that synchronous reset - and asynchronous reset cannot be used on a single read port) -- If block RAM is used and synchronous resets are not natively supported by the target, small - emulation circuit will be inserted +Synchronous reset, enable priority over reset +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: verilog @@ -281,11 +398,6 @@ Synchronous read port with synchronous reset (enable priority over reset) Synchronous read port with asynchronous reset ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Asynchronous resets can be combined with any other supported pattern (except that synchronous - reset and asynchronous reset cannot be used on a single read port) -- If block RAM is used and asynchronous resets are not natively supported by the target, small - emulation circuit will be inserted - .. code:: verilog reg [DATA_WIDTH - 1 : 0] mem [2**ADDR_WIDTH - 1 : 0]; @@ -302,44 +414,8 @@ Synchronous read port with asynchronous reset read_data <= mem[read_addr]; end -Initial data -~~~~~~~~~~~~ - -- Most FPGA targets support initializing all kinds of memory to user-provided values -- If explicit initialization is not used, initial memory value is undefined -- Initial data can be provided by either initial statements writing memory cells one by one or - $readmemh/$readmemb system tasks - -Write port with byte enables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Byte enables can be used with any supported pattern -- To ensure that multiple writes will be merged into one port, they need to have disjoint bit - ranges, have the same address, and the same clock -- Any write enable granularity will be accepted (down to per-bit write enables), but using smaller - granularity than natively supported by the target is very likely to be inefficient (eg. using - 4-bit bytes on ECP5 will result in either padding the bytes with 5 dummy bits to native 9-bit - units or splitting the RAM into two block RAMs) - -.. code:: verilog - - reg [31 : 0] mem [2**ADDR_WIDTH - 1 : 0]; - - always @(posedge clk) begin - if (write_enable[0]) - mem[write_addr][7:0] <= write_data[7:0]; - if (write_enable[1]) - mem[write_addr][15:8] <= write_data[15:8]; - if (write_enable[2]) - mem[write_addr][23:16] <= write_data[23:16]; - if (write_enable[3]) - mem[write_addr][31:24] <= write_data[31:24]; - if (read_enable) - read_data <= mem[read_addr]; - end - -Asymmetric memory — general notes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Asymmetric memory patterns +-------------------------- To construct an asymmetric memory (memory with read/write ports of differing widths): @@ -354,13 +430,12 @@ To construct an asymmetric memory (memory with read/write ports of differing wid - For read ports, ensure that enable/reset signals are identical (for write ports, the enable signal may vary — this will result in using the byte enable functionality) -- Asymmetric memory is supported on all targets, but may require emulation circuitry where not - natively supported -- Note: when the memory is larger than the underlying block RAM primitive, hardware asymmetric - memory support is likely not to be used even if present, as this is cheaper +Asymmetric memory is supported on all targets, but may require emulation circuitry where not +natively supported. Note that when the memory is larger than the underlying block RAM primitive, +hardware asymmetric memory support is likely not to be used even if present as it is more expensive. -Asymmetric memory with wide synchronous read port -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Wide synchronous read port +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: verilog @@ -432,8 +507,8 @@ Wide write port read_data <= mem[read_addr]; end -True dual port memory — general notes -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +True dual port (TDP) patterns +----------------------------- - Many different variations of true dual port memory can be created by combining two single-port RAM patterns on the same memory @@ -450,8 +525,8 @@ True dual port memory — general notes - Priority is not supported when using the verific front end and any priority semantics are ignored. -True Dual Port — different clocks, exclusive read/write -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +TDP with different clocks, exclusive read/write +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code:: verilog @@ -471,8 +546,8 @@ True Dual Port — different clocks, exclusive read/write read_data_b <= mem[addr_b]; end -True Dual Port — same clock, read-first behavior -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +TDP with same clock, read-first behavior +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - This requires hardware inter-port read-first behavior, and will only work on some targets (Xilinx, Nexus) @@ -494,8 +569,8 @@ True Dual Port — same clock, read-first behavior read_data_b <= mem[addr_b]; end -Multiple read ports -~~~~~~~~~~~~~~~~~~~ +TDP with multiple read ports +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - The combination of a single write port with an arbitrary amount of read ports is supported on all targets — if a multi-read port primitive is available (like Xilinx RAM64M), it'll be used as @@ -514,79 +589,6 @@ Multiple read ports assign read_data_b = mem[read_addr_b]; assign read_data_c = mem[read_addr_c]; -Memory kind selection -~~~~~~~~~~~~~~~~~~~~~ - -- The memory inference code will automatically pick target memory primitive based on memory geometry - and features used. Depending on the target, there can be up to four memory primitive classes - available for selection: - -- FF RAM (aka logic): no hardware primitive used, memory lowered to a bunch of FFs and multiplexers - - - Can handle arbitrary number of write ports, as long as all write ports are in the same clock domain - - Can handle arbitrary number and kind of read ports - -- LUT RAM (aka distributed RAM): uses LUT storage as RAM - - - Supported on most FPGAs (with notable exception of ice40) - - Usually has one synchronous write port, one or more asynchronous read ports - - Small - - Will never be used for ROMs (lowering to plain LUTs is always better) - -- Block RAM: dedicated memory tiles - - - Supported on basically all FPGAs - - Supports only synchronous reads - - Two ports with separate clocks - - Usually supports true dual port (with notable exception of ice40 that only supports SDP) - - Usually supports asymmetric memories and per-byte write enables - - Several kilobits in size - -- Huge RAM: - - - Only supported on several targets: - - - Some Xilinx UltraScale devices (UltraRAM) - - - Two ports, both with mutually exclusive synchronous read and write - - Single clock - - Initial data must be all-0 - - - Some ice40 devices (SPRAM) - - - Single port with mutually exclusive synchronous read and write - - Does not support initial data - - - Nexus (large RAM) - - - Two ports, both with mutually exclusive synchronous read and write - - Single clock - - - Will not be automatically selected by memory inference code, needs explicit opt-in via - ram_style attribute - -In general, you can expect the automatic selection process to work roughly like this: - -- If any read port is asynchronous, only LUT RAM (or FF RAM) can be used. -- If there is more than one write port, only block RAM can be used, and this needs to be a - hardware-supported true dual port pattern - - - … unless all write ports are in the same clock domain, in which case FF RAM can also be used, - but this is generally not what you want for anything but really small memories - -- Otherwise, either FF RAM, LUT RAM, or block RAM will be used, depending on memory size - -This process can be overridden by attaching a ram_style attribute to the memory: - -- `(* ram_style = "logic" *)` selects FF RAM -- `(* ram_style = "distributed" *)` selects LUT RAM -- `(* ram_style = "block" *)` selects block RAM -- `(* ram_style = "huge" *)` selects huge RAM - -It is an error if this override cannot be realized for the given target. - -Many alternate spellings of the attribute are also accepted, for compatibility with other software. - Not yet supported patterns -------------------------- @@ -612,7 +614,7 @@ Asymmetric memories via part selection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Would require major changes to the Verilog frontend. -- Build wide ports out of narrow ports instead (see `Asymmetric memory with wide synchronous read port`_) +- Build wide ports out of narrow ports instead (see `Wide synchronous read port`_) .. code:: verilog From 25954715f0a8a2fc65d5961c3f09f9ee95774760 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 00:16:06 +0000 Subject: [PATCH 141/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c068c1f6d29..befbc58d776 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+16 +YOSYS_VER := 0.30+21 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From fb9e12761bd9ea0e81316f69190c96b4ec872a82 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 12 Nov 2019 17:38:00 +0100 Subject: [PATCH 142/303] Add "write_edif -lsbidx" --- backends/edif/edif.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 7722d0c3394..04037edcd59 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -120,6 +120,9 @@ struct EdifBackend : public Backend { log(" sets the delimiting character for module port rename clauses to\n"); log(" parentheses, square brackets, or angle brackets.\n"); log("\n"); + log(" -lsbidx\n"); + log(" use index 0 for the LSB bit of a net or port instead of MSB.\n"); + log("\n"); log("Unfortunately there are different \"flavors\" of the EDIF file format. This\n"); log("command generates EDIF files for the Xilinx place&route tools. It might be\n"); log("necessary to make small modifications to this command when a different tool\n"); @@ -132,6 +135,7 @@ struct EdifBackend : public Backend { std::string top_module_name; bool port_rename = false; bool attr_properties = false; + bool lsbidx = false; std::map> lib_cell_ports; bool nogndvcc = false, gndvccy = false, keepmode = false; CellTypes ct(design); @@ -173,6 +177,10 @@ struct EdifBackend : public Backend { } continue; } + if (args[argidx] == "-lsbidx") { + lsbidx = true; + continue; + } break; } extra_args(f, filename, args, argidx); @@ -437,7 +445,7 @@ struct EdifBackend : public Backend { *f << ")\n"; for (int i = 0; i < wire->width; i++) { RTLIL::SigSpec sig = sigmap(RTLIL::SigSpec(wire, i)); - net_join_db[sig].insert(make_pair(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), GetSize(wire)-i-1), wire->port_input)); + net_join_db[sig].insert(make_pair(stringf("(portRef (member %s %d))", EDIF_REF(wire->name), lsbidx ? i : GetSize(wire)-i-1), wire->port_input)); } } } @@ -468,13 +476,13 @@ struct EdifBackend : public Backend { 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 { - int member_idx = GetSize(sig)-i-1; + int member_idx = lsbidx ? i : GetSize(sig)-i-1; auto m = design->module(cell->type); int width = sig.size(); if (m) { auto w = m->wire(p.first); if (w) { - member_idx = GetSize(w)-i-1; + member_idx = lsbidx ? i : GetSize(w)-i-1; width = GetSize(w); } } From cff3195caa8297f39dd77c1b7842f0a70e938eca Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Nov 2019 15:55:21 +0100 Subject: [PATCH 143/303] Improve EDIF lib_cell_ports scan --- backends/edif/edif.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backends/edif/edif.cc b/backends/edif/edif.cc index 04037edcd59..00fd7f54e39 100644 --- a/backends/edif/edif.cc +++ b/backends/edif/edif.cc @@ -192,6 +192,14 @@ struct EdifBackend : public Backend { for (auto module : design->modules()) { + lib_cell_ports[module->name]; + + for (auto port : module->ports) + { + Wire *wire = module->wire(port); + lib_cell_ports[module->name][port] = std::max(lib_cell_ports[module->name][port], GetSize(wire)); + } + if (module->get_blackbox_attribute()) continue; @@ -208,7 +216,7 @@ struct EdifBackend : public Backend { if (design->module(cell->type) == nullptr || design->module(cell->type)->get_blackbox_attribute()) { lib_cell_ports[cell->type]; for (auto p : cell->connections()) - lib_cell_ports[cell->type][p.first] = GetSize(p.second); + lib_cell_ports[cell->type][p.first] = std::max(lib_cell_ports[cell->type][p.first], GetSize(p.second)); } } } From 22c9237716028ccfd1876a31eef813f7720b0a42 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Tue, 20 Jun 2023 11:17:12 +0200 Subject: [PATCH 144/303] show: escape angle brackets --- passes/cmds/show.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index 525c81d5b85..f1854058cab 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -208,7 +208,7 @@ struct ShowWorker str += "╲"; continue; } - if (ch == '"') + if (ch == '"' || ch == '<' || ch == '>') str += "\\"; str += ch; } From 9c7f0e76709aa7f4f77c404562a7468acbb116bc Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Tue, 20 Jun 2023 12:53:56 +0200 Subject: [PATCH 145/303] show: truncate very long module names --- passes/cmds/show.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/passes/cmds/show.cc b/passes/cmds/show.cc index f1854058cab..0dc5c452c09 100644 --- a/passes/cmds/show.cc +++ b/passes/cmds/show.cc @@ -201,6 +201,12 @@ struct ShowWorker if (id[0] == '\\') id = id.substr(1); + // TODO: optionally include autoname + print correspondence in case of ambiguity + size_t max_label_len = abbreviateIds ? 256 : 16384; + if (id.size() > max_label_len) { + id = id.substr(0,max_label_len-3) + "..."; + } + std::string str; for (char ch : id) { if (ch == '\\') { From 104edb458784fdbf2bb782f095c2afada9b0299c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 00:17:27 +0000 Subject: [PATCH 146/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index befbc58d776..2bf079ee82e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+21 +YOSYS_VER := 0.30+25 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 0c0171bd6040e44b7013ffca830cfc891db536e6 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 21 Jun 2023 17:21:04 +1000 Subject: [PATCH 147/303] docs: RD_DATA is an output, not input --- docs/source/CHAPTER_CellLib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index c5db434a64f..c8904086879 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -571,7 +571,7 @@ The ``$mem_v2`` cell has the following ports: signals for the read ports. ``\RD_DATA`` - This input is ``\RD_PORTS*\WIDTH`` bits wide, containing all data + This output is ``\RD_PORTS*\WIDTH`` bits wide, containing all data signals for the read ports. ``\RD_ARST`` From 63e4114233d2610ae69e95baca835b7ff946e804 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 21 Jun 2023 19:05:02 +1000 Subject: [PATCH 148/303] proc_prune: avoid using invalidated iterator An `std::vector::reverse_iterator` stores the `std::vector::iterator` which points to the (forwards-ordered) *following* item. Thus while `vec.rbegin()` dereferences to the final item of `vec`, the iterator it wraps (`vec.rbegin().base()`) is equal to `vec.end()`. In the remove case here, we advance `it` (backwards), erasing the item we just advanced past by grabbing its (pre-increment) base forward-iterator and subtracting 1. The iterator maths here is obviously all OK, but the forward-iterator that `it` wraps post-increment actually points to the item we just removed. That iterator was invalidated by the `erase()` call. That this works anyway is (AFAICT) some combination of luck and/or promises that aren't part of the C++ spec, but MSVC's debug iterator support picks this up. `erase()` returns the new iterator that follows the item just erased, which happens to be the exact one we want our reverse-iterator to wrap for the next loop; we get a fresh iterator to the same base, now without the preceding item. --- passes/proc/proc_prune.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/proc/proc_prune.cc b/passes/proc/proc_prune.cc index 9f1080ef635..3433557eea1 100644 --- a/passes/proc/proc_prune.cc +++ b/passes/proc/proc_prune.cc @@ -91,7 +91,7 @@ struct PruneWorker if (GetSize(new_lhs) == 0) { if (GetSize(conn_lhs) == 0) removed_count++; - cs->actions.erase((it++).base() - 1); + it = decltype(cs->actions)::reverse_iterator(cs->actions.erase(it.base() - 1)); } else { it->first = new_lhs; it->second = new_rhs; From aff0065646f1f526c199bdbb8de74f22391a345d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 21 Jun 2023 13:21:34 +0200 Subject: [PATCH 149/303] Use defaultvalue for init values of input ports --- frontends/verific/verific.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 52008ddc6d7..989e2173b8d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2005,7 +2005,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma initval[i] = State::Sx; } - if (initval.is_fully_undef()) + if (wire->port_input) { + wire->attributes[ID::defaultvalue] = Const(initval); + wire->attributes.erase(ID::init); + } else if (initval.is_fully_undef()) wire->attributes.erase(ID::init); } } From 8f7a9a0b667031d661cd91a66c5dcab39eb470d6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 22 Jun 2023 00:17:44 +0000 Subject: [PATCH 150/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2bf079ee82e..e676c7cef7a 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+25 +YOSYS_VER := 0.30+33 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 3f29bdbbc56885fe1f6db9c9b49a5323d1d30ad6 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Fri, 23 Jun 2023 14:38:15 +1000 Subject: [PATCH 151/303] smt2: py3.12+: avoid SyntaxWarning. Python 3.12 emits a SyntaxWarning when encountering invalid escape sequences. They still parse as expected. Marking these raw produces the same result without the warnings. --- backends/smt2/smtio.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index a7374589690..8094747bc14 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -768,7 +768,7 @@ def check_sat(self, expected=["sat", "unsat", "unknown", "timeout", "interrupted if self.timeinfo: i = 0 - s = "/-\|" + s = r"/-\|" count = 0 num_bs = 0 @@ -1171,7 +1171,7 @@ def set_net(self, path, bits): def escape_name(self, name): name = re.sub(r"\[([0-9a-zA-Z_]*[a-zA-Z_][0-9a-zA-Z_]*)\]", r"<\1>", name) - if re.match("[\[\]]", name) and name[0] != "\\": + if re.match(r"[\[\]]", name) and name[0] != "\\": name = "\\" + name return name From f9744fdfcd8106107e2bef750c36c04ae2406973 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 23 Jun 2023 10:27:38 +0200 Subject: [PATCH 152/303] smtbmc: Make cover mode respect --keep-going As cover mode by default stops looking for further traces when an assertion fails, it should respect --keep-going. --- backends/smt2/smtbmc.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backends/smt2/smtbmc.py b/backends/smt2/smtbmc.py index 6b81740a272..02e15a1b502 100644 --- a/backends/smt2/smtbmc.py +++ b/backends/smt2/smtbmc.py @@ -174,6 +174,8 @@ def help(): further failed assertions. To output multiple traces covering all found failed assertions, the character '%' is replaced in all dump filenames with an increasing number. + In cover mode, don't stop when a cover trace contains a failed + assertion. --check-witness check that the used witness file contains sufficient @@ -1739,7 +1741,7 @@ def smt_check_sat(expected=["sat", "unsat"]): smt_pop() smt.write("(define-fun covers_%d ((state |%s_s|)) (_ BitVec %d) (bvand (covers_%d state) #b%s))" % (coveridx, topmod, len(cover_desc), coveridx-1, cover_mask)) - if found_failed_assert: + if found_failed_assert and not keep_going: break if "1" not in cover_mask: From a07f8ac38ab9e4c2160673f601755d5044c15de2 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Fri, 23 Jun 2023 18:07:28 +0200 Subject: [PATCH 153/303] check: Also check for conflicts with constant drivers --- passes/cmds/check.cc | 31 +++++++++----- tests/various/constant_drive_conflict.ys | 51 ++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 tests/various/constant_drive_conflict.ys diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index ee0f0a58fae..d1c83f04d88 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -112,11 +112,10 @@ struct CheckPass : public Pass { for (size_t i = 0; i < all_cases.size(); i++) { for (auto action : all_cases[i]->actions) { for (auto bit : sigmap(action.first)) - if (bit.wire) { - wire_drivers[bit].push_back( - stringf("action %s <= %s (case rule) in process %s", - log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); - } + wire_drivers[bit].push_back( + stringf("action %s <= %s (case rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + for (auto bit : sigmap(action.second)) if (bit.wire) used_wires.insert(bit); } @@ -134,10 +133,9 @@ struct CheckPass : public Pass { if (bit.wire) used_wires.insert(bit); for (auto action : sync->actions) { for (auto bit : sigmap(action.first)) - if (bit.wire) - wire_drivers[bit].push_back( - stringf("action %s <= %s (sync rule) in process %s", - log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); + wire_drivers[bit].push_back( + stringf("action %s <= %s (sync rule) in process %s", + log_signal(action.first), log_signal(action.second), log_id(proc_it.first))); for (auto bit : sigmap(action.second)) if (bit.wire) used_wires.insert(bit); } @@ -176,7 +174,8 @@ struct CheckPass : public Pass { if (logic_cell) topo.edge(stringf("cell %s (%s)", log_id(cell), log_id(cell->type)), stringf("wire %s", log_signal(sig[i]))); - if (sig[i].wire) + + if (sig[i].wire || !cell->input(conn.first)) wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)", log_id(conn.first), i, log_id(cell), log_id(cell->type))); } @@ -192,7 +191,8 @@ struct CheckPass : public Pass { if (wire->port_input) { SigSpec sig = sigmap(wire); for (int i = 0; i < GetSize(sig); i++) - wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", log_id(wire), i)); + if (sig[i].wire || !wire->port_output) + wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", log_id(wire), i)); } if (wire->port_output) for (auto bit : sigmap(wire)) @@ -212,6 +212,15 @@ struct CheckPass : public Pass { } } + for (auto state : {State::S0, State::S1, State::Sx}) + if (wire_drivers.count(state)) { + string message = stringf("Drivers conflicting with a constant %s driver:\n", log_signal(state)); + for (auto str : wire_drivers[state]) + message += stringf(" %s\n", str.c_str()); + log_warning("%s", message.c_str()); + counter++; + } + for (auto it : wire_drivers) if (wire_drivers_count[it.first] > 1) { string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first)); diff --git a/tests/various/constant_drive_conflict.ys b/tests/various/constant_drive_conflict.ys new file mode 100644 index 00000000000..1246cbcae01 --- /dev/null +++ b/tests/various/constant_drive_conflict.ys @@ -0,0 +1,51 @@ +read_verilog < Date: Fri, 23 Jun 2023 19:40:29 +0200 Subject: [PATCH 154/303] verific: import src attribute on $memrd/$memwr cells --- frontends/verific/verific.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 989e2173b8d..0dd785ec3ab 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1649,6 +1649,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma cell->parameters[ID::TRANSPARENT] = false; cell->parameters[ID::ABITS] = GetSize(addr); cell->parameters[ID::WIDTH] = GetSize(data); + import_attributes(cell->attributes, inst); cell->setPort(ID::CLK, RTLIL::State::Sx); cell->setPort(ID::EN, RTLIL::State::Sx); cell->setPort(ID::ADDR, addr); @@ -1678,6 +1679,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma cell->parameters[ID::PRIORITY] = 0; cell->parameters[ID::ABITS] = GetSize(addr); cell->parameters[ID::WIDTH] = GetSize(data); + import_attributes(cell->attributes, inst); cell->setPort(ID::EN, RTLIL::SigSpec(net_map_at(inst->GetControl())).repeat(GetSize(data))); cell->setPort(ID::CLK, RTLIL::State::S0); cell->setPort(ID::ADDR, addr); From 2310a0ea9a61ed14d2769f01283a5a7590cbe558 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 25 Jun 2023 00:21:16 +0000 Subject: [PATCH 155/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e676c7cef7a..fae752952f3 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+33 +YOSYS_VER := 0.30+38 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a7bccdfe8d2a3ef7faa8b1cf1d311b36e698d6f5 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Wed, 28 Jun 2023 11:20:44 +0200 Subject: [PATCH 156/303] Update ABC version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fae752952f3..fb2d164257e 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 1de4eaf +ABCREV = bb64142 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From eb397592f0d84c54e8923af9512582b7efcd6622 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:47:30 +1000 Subject: [PATCH 157/303] cxxrtl: add `$divfloor`. --- backends/cxxrtl/cxxrtl.h | 19 +++++++++++++++++++ backends/cxxrtl/cxxrtl_backend.cc | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 073921cc49e..5d0596f0d61 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -1595,6 +1595,25 @@ value modfloor_ss(const value &a, const value &b) { return r; } +template +CXXRTL_ALWAYS_INLINE +value divfloor_uu(const value &a, const value &b) { + return divmod_uu(a, b).first; +} + +// Divfloor. Similar to above: returns q=a//b, where q has the sign of a*b and a=b*q+N. +// In other words, returns (truncating) a/b, except if a and b have different signs +// and there's non-zero remainder, subtract one more towards floor. +template +CXXRTL_ALWAYS_INLINE +value divfloor_ss(const value &a, const value &b) { + value q, r; + std::tie(q, r) = divmod_ss(a, b); + if ((b.is_neg() != a.is_neg()) && !r.is_zero()) + return sub_uu(q, value<1> { 1u }); + return q; + +} // Memory helper struct memory_index { diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 62768bd3395..1b13985ab4e 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -185,7 +185,7 @@ bool is_binary_cell(RTLIL::IdString type) ID($and), ID($or), ID($xor), ID($xnor), ID($logic_and), ID($logic_or), ID($shl), ID($sshl), ID($shr), ID($sshr), ID($shift), ID($shiftx), ID($eq), ID($ne), ID($eqx), ID($nex), ID($gt), ID($ge), ID($lt), ID($le), - ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor)); + ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($modfloor), ID($divfloor)); } bool is_extending_cell(RTLIL::IdString type) From 7542146fc52b8ac09b1319a0bae97ed048905aa3 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Wed, 28 Jun 2023 17:48:20 +0200 Subject: [PATCH 158/303] memory_libmap: print message about attributes forcing ram kind --- passes/memory/memory_libmap.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index 9e147b0bf06..aee07c6070d 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -431,6 +431,7 @@ void MemMapping::determine_style() { style = ""; if (mem.get_bool_attribute(ID::lram)) { kind = RamKind::Huge; + log("found attribute 'lram' on memory %s.%s, forced mapping to huge RAM\n", log_id(mem.module->name), log_id(mem.memid)); return; } for (auto attr: {ID::ram_block, ID::rom_block, ID::ram_style, ID::rom_style, ID::ramstyle, ID::romstyle, ID::syn_ramstyle, ID::syn_romstyle}) { @@ -438,6 +439,7 @@ void MemMapping::determine_style() { Const val = mem.attributes.at(attr); if (val == 1) { kind = RamKind::NotLogic; + log("found attribute '%s = 1' on memory %s.%s, disabled mapping to FF\n", log_id(attr), log_id(mem.module->name), log_id(mem.memid)); return; } std::string val_s = val.decode_string(); @@ -450,15 +452,20 @@ void MemMapping::determine_style() { // Nothing. } else if (val_s == "logic" || val_s == "registers") { kind = RamKind::Logic; + log("found attribute '%s = %s' on memory %s.%s, forced mapping to FF\n", log_id(attr), val_s.c_str(), log_id(mem.module->name), log_id(mem.memid)); } else if (val_s == "distributed") { kind = RamKind::Distributed; + log("found attribute '%s = %s' on memory %s.%s, forced mapping to distributed RAM\n", log_id(attr), val_s.c_str(), log_id(mem.module->name), log_id(mem.memid)); } else if (val_s == "block" || val_s == "block_ram" || val_s == "ebr") { kind = RamKind::Block; + log("found attribute '%s = %s' on memory %s.%s, forced mapping to block RAM\n", log_id(attr), val_s.c_str(), log_id(mem.module->name), log_id(mem.memid)); } else if (val_s == "huge" || val_s == "ultra") { kind = RamKind::Huge; + log("found attribute '%s = %s' on memory %s.%s, forced mapping to huge RAM\n", log_id(attr), val_s.c_str(), log_id(mem.module->name), log_id(mem.memid)); } else { kind = RamKind::NotLogic; style = val_s; + log("found attribute '%s = %s' on memory %s.%s, forced mapping to %s RAM\n", log_id(attr), val_s.c_str(), log_id(mem.module->name), log_id(mem.memid), val_s.c_str()); } return; } From b5b0b7e839c562f23623108e9cfc6015756045b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Jun 2023 00:18:55 +0000 Subject: [PATCH 159/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fb2d164257e..cf2d8f200bf 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+38 +YOSYS_VER := 0.30+48 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a6be7b475192f285e23b7ee94465b004513aa150 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Thu, 29 Jun 2023 14:02:08 +0200 Subject: [PATCH 160/303] memory_libmap: add debug messages for some reasons for rejecting mappings --- passes/memory/memory_libmap.cc | 37 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index aee07c6070d..0496a402967 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -201,8 +201,10 @@ struct MemMapping { continue; if (!check_init(rdef)) continue; - if (rdef.prune_rom && mem.wr_ports.empty()) + if (rdef.prune_rom && mem.wr_ports.empty()) { + log_debug("memory %s.%s: rejecting mapping to %s: ROM not allowed\n", log_id(mem.module->name), log_id(mem.memid), log_id(rdef.id)); continue; + } MemConfig cfg; cfg.def = &rdef; for (auto &cdef: rdef.shared_clocks) { @@ -476,18 +478,26 @@ void MemMapping::determine_style() { // Determine whether the memory can be mapped entirely to soft logic. bool MemMapping::determine_logic_ok() { - if (kind != RamKind::Auto && kind != RamKind::Logic) + if (kind != RamKind::Auto && kind != RamKind::Logic) { + log_debug("memory %s.%s: rejecting mapping to logic: RAM kind conflicts with attribute\n", log_id(mem.module->name), log_id(mem.memid)); return false; + } // Memory is mappable entirely to soft logic iff all its write ports are in the same clock domain. if (mem.wr_ports.empty()) return true; for (auto &port: mem.wr_ports) { - if (!port.clk_enable) + if (!port.clk_enable){ + log_debug("memory %s.%s: rejecting mapping to logic: unclocked port\n", log_id(mem.module->name), log_id(mem.memid)); return false; - if (port.clk != mem.wr_ports[0].clk) + } + if (port.clk != mem.wr_ports[0].clk) { + log_debug("memory %s.%s: rejecting mapping to logic: ports have different write clock domains\n", log_id(mem.module->name), log_id(mem.memid)); return false; - if (port.clk_polarity != mem.wr_ports[0].clk_polarity) + } + if (port.clk_polarity != mem.wr_ports[0].clk_polarity) { + log_debug("memory %s.%s: rejecting mapping to logic: ports have different write clock polarity\n", log_id(mem.module->name), log_id(mem.memid)); return false; + } } return true; } @@ -499,14 +509,21 @@ bool MemMapping::check_ram_kind(const Ram &ram) { if (ram.kind == kind) return true; if (kind == RamKind::Auto || kind == RamKind::NotLogic) { - if (ram.kind == RamKind::Distributed && opts.no_auto_distributed) + if (ram.kind == RamKind::Distributed && opts.no_auto_distributed) { + log_debug("memory %s.%s: rejecting mapping to %s: option -no-auto-distributed given\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return false; - if (ram.kind == RamKind::Block && opts.no_auto_block) + } + if (ram.kind == RamKind::Block && opts.no_auto_block) { + log_debug("memory %s.%s: rejecting mapping to %s: option -no-auto-block given\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return false; - if (ram.kind == RamKind::Huge && opts.no_auto_huge) + } + if (ram.kind == RamKind::Huge && opts.no_auto_huge) { + log_debug("memory %s.%s: rejecting mapping to %s: option -no-auto-huge given\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return false; + } return true; } + log_debug("memory %s.%s: rejecting mapping to %s: RAM kind conflicts with attribute\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return false; } @@ -517,6 +534,7 @@ bool MemMapping::check_ram_style(const Ram &ram) { for (auto &s: ram.style) if (s == style) return true; + log_debug("memory %s.%s: rejecting mapping to %s: RAM style conflicts with attribute\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return false; } @@ -536,8 +554,10 @@ bool MemMapping::check_init(const Ram &ram) { switch (ram.init) { case MemoryInitKind::None: + if(has_nonx) log_debug("memory %s.%s: rejecting mapping to %s: does not support initialization\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return !has_nonx; case MemoryInitKind::Zero: + if(has_one) log_debug("memory %s.%s: rejecting mapping to %s: does not support non-zero initialization\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); return !has_one; default: return true; @@ -577,6 +597,7 @@ void MemMapping::assign_wr_ports() { if (!port.clk_enable) { // Async write ports not supported. cfgs.clear(); + log_debug("memory %s.%s: rejecting mapping: async write port\n", log_id(mem.module->name), log_id(mem.memid)); return; } MemConfigs new_cfgs; From 991bff00f186182f11c472ceede8bf1ec75eedaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 4 Jul 2023 00:50:38 +0200 Subject: [PATCH 161/303] Makefile: install cellaigs.h header --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index cf2d8f200bf..7cbda3343ab 100644 --- a/Makefile +++ b/Makefile @@ -612,6 +612,7 @@ $(eval $(call add_include_file,kernel/log.h)) $(eval $(call add_include_file,kernel/rtlil.h)) $(eval $(call add_include_file,kernel/binding.h)) $(eval $(call add_include_file,kernel/register.h)) +$(eval $(call add_include_file,kernel/cellaigs.h)) $(eval $(call add_include_file,kernel/celltypes.h)) $(eval $(call add_include_file,kernel/celledges.h)) $(eval $(call add_include_file,kernel/consteval.h)) From 57de249881fbad885195b9e99d2bd0547895a5b9 Mon Sep 17 00:00:00 2001 From: "N. Engelhardt" Date: Thu, 6 Jul 2023 18:54:32 +0200 Subject: [PATCH 162/303] memory_libmap: print additional debug messages when no valid mapping is found --- passes/memory/memory_libmap.cc | 160 ++++++++++++++++++++++++++------- 1 file changed, 128 insertions(+), 32 deletions(-) diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index 0496a402967..6e5a806fd0e 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -183,6 +183,7 @@ struct MemMapping { dict, bool> wr_implies_rd_cache; dict, bool> wr_excludes_rd_cache; dict, bool> wr_excludes_srst_cache; + std::string rejected_cfg_debug_msgs; MemMapping(MapWorker &worker, Mem &mem, const Library &lib, const PassOptions &opts) : worker(worker), qcsat(worker.modwalker), mem(mem), lib(lib), opts(opts) { determine_style(); @@ -202,7 +203,7 @@ struct MemMapping { if (!check_init(rdef)) continue; if (rdef.prune_rom && mem.wr_ports.empty()) { - log_debug("memory %s.%s: rejecting mapping to %s: ROM not allowed\n", log_id(mem.module->name), log_id(mem.memid), log_id(rdef.id)); + log_debug("memory %s.%s: rejecting mapping to %s: ROM mapping disabled (prune_rom set)\n", log_id(mem.module->name), log_id(mem.memid), log_id(rdef.id)); continue; } MemConfig cfg; @@ -311,6 +312,59 @@ struct MemMapping { void prune_post_geom(); void emit_port(const MemConfig &cfg, std::vector &cells, const PortVariant &pdef, const char *name, int wpidx, int rpidx, const std::vector &hw_addr_swizzle); void emit(const MemConfig &cfg); + + void log_reject(std::string message){ + if(ys_debug(1)) { + rejected_cfg_debug_msgs += message; + rejected_cfg_debug_msgs += "\n"; + } + } + + void log_reject(const Ram &ram, std::string message) { + if(ys_debug(1)) { + rejected_cfg_debug_msgs += stringf("can't map to to %s: ", log_id(ram.id)); + rejected_cfg_debug_msgs += message; + rejected_cfg_debug_msgs += "\n"; + } + } + + void log_reject(const Ram &ram, const PortGroup &pg, std::string message) { + if(ys_debug(1)) { + rejected_cfg_debug_msgs += stringf("can't map to port group ["); + bool first = true; + for (std::string portname : pg.names){ + if (!first) rejected_cfg_debug_msgs += ", "; + rejected_cfg_debug_msgs += portname; + first = false; + } + rejected_cfg_debug_msgs += stringf("] of %s: ", log_id(ram.id)); + rejected_cfg_debug_msgs += message; + rejected_cfg_debug_msgs += "\n"; + } + } + + void log_reject(const Ram &ram, const PortGroup &pg, int pvi, std::string message) { + if(ys_debug(1)) { + rejected_cfg_debug_msgs += stringf("can't map to option selection ["); + bool first = true; + for(auto opt : pg.variants[pvi].options){ + if (!first) rejected_cfg_debug_msgs += ", "; + rejected_cfg_debug_msgs += opt.first; + rejected_cfg_debug_msgs += stringf(" = %s", log_const(opt.second)); + first = false; + } + rejected_cfg_debug_msgs += "] of port group ["; + first = true; + for (std::string portname : pg.names){ + if (!first) rejected_cfg_debug_msgs += ", "; + rejected_cfg_debug_msgs += portname; + first = false; + } + rejected_cfg_debug_msgs += stringf("] of %s: ", log_id(ram.id)); + rejected_cfg_debug_msgs += message; + rejected_cfg_debug_msgs += "\n"; + } + } }; void MemMapping::dump_configs(int stage) { @@ -479,7 +533,7 @@ void MemMapping::determine_style() { // Determine whether the memory can be mapped entirely to soft logic. bool MemMapping::determine_logic_ok() { if (kind != RamKind::Auto && kind != RamKind::Logic) { - log_debug("memory %s.%s: rejecting mapping to logic: RAM kind conflicts with attribute\n", log_id(mem.module->name), log_id(mem.memid)); + log_reject("can't map to logic: RAM kind conflicts with attribute"); return false; } // Memory is mappable entirely to soft logic iff all its write ports are in the same clock domain. @@ -487,15 +541,15 @@ bool MemMapping::determine_logic_ok() { return true; for (auto &port: mem.wr_ports) { if (!port.clk_enable){ - log_debug("memory %s.%s: rejecting mapping to logic: unclocked port\n", log_id(mem.module->name), log_id(mem.memid)); + log_reject("can't map to logic: unclocked port"); return false; } if (port.clk != mem.wr_ports[0].clk) { - log_debug("memory %s.%s: rejecting mapping to logic: ports have different write clock domains\n", log_id(mem.module->name), log_id(mem.memid)); + log_reject("can't map to logic: ports have different write clock domains"); return false; } if (port.clk_polarity != mem.wr_ports[0].clk_polarity) { - log_debug("memory %s.%s: rejecting mapping to logic: ports have different write clock polarity\n", log_id(mem.module->name), log_id(mem.memid)); + log_reject("can't map to logic: ports have different write clock polarity"); return false; } } @@ -510,20 +564,20 @@ bool MemMapping::check_ram_kind(const Ram &ram) { return true; if (kind == RamKind::Auto || kind == RamKind::NotLogic) { if (ram.kind == RamKind::Distributed && opts.no_auto_distributed) { - log_debug("memory %s.%s: rejecting mapping to %s: option -no-auto-distributed given\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + log_reject(ram, "option -no-auto-distributed given"); return false; } if (ram.kind == RamKind::Block && opts.no_auto_block) { - log_debug("memory %s.%s: rejecting mapping to %s: option -no-auto-block given\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + log_reject(ram, "option -no-auto-block given"); return false; } if (ram.kind == RamKind::Huge && opts.no_auto_huge) { - log_debug("memory %s.%s: rejecting mapping to %s: option -no-auto-huge given\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + log_reject(ram, "option -no-auto-huge given"); return false; } return true; } - log_debug("memory %s.%s: rejecting mapping to %s: RAM kind conflicts with attribute\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + log_reject(ram, "RAM kind conflicts with attribute"); return false; } @@ -534,7 +588,7 @@ bool MemMapping::check_ram_style(const Ram &ram) { for (auto &s: ram.style) if (s == style) return true; - log_debug("memory %s.%s: rejecting mapping to %s: RAM style conflicts with attribute\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + log_reject(ram, "RAM style conflicts with attribute"); return false; } @@ -554,10 +608,10 @@ bool MemMapping::check_init(const Ram &ram) { switch (ram.init) { case MemoryInitKind::None: - if(has_nonx) log_debug("memory %s.%s: rejecting mapping to %s: does not support initialization\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + if(has_nonx) log_reject(ram, "does not support initialization"); return !has_nonx; case MemoryInitKind::Zero: - if(has_one) log_debug("memory %s.%s: rejecting mapping to %s: does not support non-zero initialization\n", log_id(mem.module->name), log_id(mem.memid), log_id(ram.id)); + if(has_one) log_reject(ram, "does not support non-zero initialization"); return !has_one; default: return true; @@ -593,11 +647,12 @@ bool apply_clock(MemConfig &cfg, const PortVariant &def, SigBit clk, bool clk_po // Perform write port assignment, validating clock options as we go. void MemMapping::assign_wr_ports() { + log_reject(stringf("Assigning write ports... (candidate configs: %lu)", cfgs.size())); for (auto &port: mem.wr_ports) { if (!port.clk_enable) { // Async write ports not supported. cfgs.clear(); - log_debug("memory %s.%s: rejecting mapping: async write port\n", log_id(mem.module->name), log_id(mem.memid)); + log_reject("can't map at all: async write port"); return; } MemConfigs new_cfgs; @@ -609,21 +664,27 @@ void MemMapping::assign_wr_ports() { for (auto &oport: cfg.wr_ports) if (oport.port_group == pgi) used++; - if (used >= GetSize(pg.names)) + if (used >= GetSize(pg.names)) { + log_reject(*cfg.def, pg, "not enough unassigned ports remaining"); continue; + } for (int pvi = 0; pvi < GetSize(pg.variants); pvi++) { auto &def = pg.variants[pvi]; // Make sure the target is a write port. - if (def.kind == PortKind::Ar || def.kind == PortKind::Sr) + if (def.kind == PortKind::Ar || def.kind == PortKind::Sr) { + log_reject(*cfg.def, pg, pvi, "not a write port"); continue; + } MemConfig new_cfg = cfg; WrPortConfig pcfg; pcfg.rd_port = -1; pcfg.port_group = pgi; pcfg.port_variant = pvi; pcfg.def = &def; - if (!apply_clock(new_cfg, def, port.clk, port.clk_polarity)) + if (!apply_clock(new_cfg, def, port.clk, port.clk_polarity)) { + log_reject(*cfg.def, pg, pvi, "incompatible clock polarity"); continue; + } new_cfg.wr_ports.push_back(pcfg); new_cfgs.push_back(new_cfg); } @@ -635,6 +696,7 @@ void MemMapping::assign_wr_ports() { // Perform read port assignment, validating clock and rden options as we go. void MemMapping::assign_rd_ports() { + log_reject(stringf("Assigning read ports... (candidate configs: %lu)", cfgs.size())); for (int pidx = 0; pidx < GetSize(mem.rd_ports); pidx++) { auto &port = mem.rd_ports[pidx]; MemConfigs new_cfgs; @@ -649,17 +711,23 @@ void MemMapping::assign_rd_ports() { for (auto &oport: cfg.wr_ports) if (oport.port_group == pgi) used++; - if (used >= GetSize(pg.names)) + if (used >= GetSize(pg.names)) { + log_reject(*cfg.def, pg, "not enough unassigned ports remaining"); continue; + } for (int pvi = 0; pvi < GetSize(pg.variants); pvi++) { auto &def = pg.variants[pvi]; // Make sure the target is a read port. - if (def.kind == PortKind::Sw) + if (def.kind == PortKind::Sw) { + log_reject(*cfg.def, pg, pvi, "not a read port"); continue; + } // If mapping an async port, accept only async defs. if (!port.clk_enable) { - if (def.kind == PortKind::Sr || def.kind == PortKind::Srsw) + if (def.kind == PortKind::Sr || def.kind == PortKind::Srsw) { + log_reject(*cfg.def, pg, pvi, "not an asynchronous read port"); continue; + } } MemConfig new_cfg = cfg; RdPortConfig pcfg; @@ -669,8 +737,10 @@ void MemMapping::assign_rd_ports() { pcfg.def = &def; if (def.kind == PortKind::Sr || def.kind == PortKind::Srsw) { pcfg.emu_sync = false; - if (!apply_clock(new_cfg, def, port.clk, port.clk_polarity)) + if (!apply_clock(new_cfg, def, port.clk, port.clk_polarity)) { + log_reject(*cfg.def, pg, pvi, "incompatible clock polarity"); continue; + } // Decide if rden is usable. if (port.en != State::S1) { if (def.clk_en) { @@ -692,22 +762,34 @@ void MemMapping::assign_rd_ports() { auto &wpcfg = cfg.wr_ports[wpidx]; auto &def = *wpcfg.def; // Make sure the write port is not yet shared. - if (wpcfg.rd_port != -1) + if (wpcfg.rd_port != -1) { + log_reject(stringf("can't share write port %d: already shared by a different read port", wpidx)); continue; + } // Make sure the target is a read port. - if (def.kind == PortKind::Sw) + if (def.kind == PortKind::Sw) { + log_reject(stringf("can't share write port %d: not a read-write port", wpidx)); continue; + } // Validate address compatibility. - if (!addr_compatible(wpidx, pidx)) + if (!addr_compatible(wpidx, pidx)) { + log_reject(stringf("can't share write port %d: addresses are not compatible", wpidx)); continue; + } // Validate clock compatibility, if needed. if (def.kind == PortKind::Srsw) { - if (!port.clk_enable) + if (!port.clk_enable) { + log_reject(stringf("can't share write port %d: incompatible enable", wpidx)); continue; - if (port.clk != wport.clk) + } + if (port.clk != wport.clk) { + log_reject(stringf("can't share write port %d: different clock signal", wpidx)); continue; - if (port.clk_polarity != wport.clk_polarity) + } + if (port.clk_polarity != wport.clk_polarity) { + log_reject(stringf("can't share write port %d: incompatible clock polarity", wpidx)); continue; + } } // Okay, let's fill it in. MemConfig new_cfg = cfg; @@ -724,8 +806,10 @@ void MemMapping::assign_rd_ports() { bool col_x = port.collision_x_mask[wpidx]; if (def.rdwr == RdWrKind::NoChange) { if (!get_wr_excludes_rd(wpidx, pidx)) { - if (!trans && !col_x) + if (!trans && !col_x) { + log_reject(stringf("can't share write port %d: conflict in simultaneous read and write operations", wpidx)); continue; + } if (trans) pcfg.emu_trans.push_back(wpidx); new_cfg.wr_ports[wpidx].force_uniform = true; @@ -738,8 +822,10 @@ void MemMapping::assign_rd_ports() { } } } else { - if (!col_x && !trans && def.rdwr != RdWrKind::Old) + if (!col_x && !trans && def.rdwr != RdWrKind::Old) { + log_reject(stringf("can't share write port %d: simultaneous read and write operations should result in new value but port reads old", wpidx)); continue; + } if (trans) { if (def.rdwr != RdWrKind::New && def.rdwr != RdWrKind::NewOnly) pcfg.emu_trans.push_back(wpidx); @@ -771,6 +857,7 @@ void MemMapping::assign_rd_ports() { // Validate transparency restrictions, determine where to add soft transparency logic. void MemMapping::handle_trans() { + log_reject(stringf("Handling transparency... (candidate configs: %lu)", cfgs.size())); if (mem.emulate_read_first_ok()) { MemConfigs new_cfgs; for (auto &cfg: cfgs) { @@ -829,15 +916,21 @@ void MemMapping::handle_trans() { bool found = false; for (auto &tdef: wpcfg.def->wrtrans) { // Check if the target matches. - if (tdef.target_kind == WrTransTargetKind::Group && rpcfg.port_group != tdef.target_group) + if (tdef.target_kind == WrTransTargetKind::Group && rpcfg.port_group != tdef.target_group) { + log_reject(*cfg.def, stringf("transparency with target port group %d not supported", tdef.target_group)); continue; + } // Check if the transparency kind is acceptable. if (transparent) { - if (tdef.kind == WrTransKind::Old) + if (tdef.kind == WrTransKind::Old) { + log_reject(*cfg.def, stringf("target %d has wrong transparency kind: new value required", tdef.target_group)); continue; + } } else { - if (tdef.kind != WrTransKind::Old) + if (tdef.kind != WrTransKind::Old) { + log_reject(*cfg.def, stringf("target %d has wrong transparency kind: old value required", tdef.target_group)); continue; + } } // Okay, we can use this cap. new_cfgs.push_back(cfg); @@ -2101,8 +2194,11 @@ struct MemoryLibMapPass : public Pass { int idx = -1; int best = map.logic_cost; if (!map.logic_ok) { - if (map.cfgs.empty()) + if (map.cfgs.empty()) { + log_debug("Rejected candidates for mapping memory %s.%s:\n", log_id(module->name), log_id(mem.memid)); + log_debug("%s", map.rejected_cfg_debug_msgs.c_str()); log_error("no valid mapping found for memory %s.%s\n", log_id(module->name), log_id(mem.memid)); + } idx = 0; best = map.cfgs[0].cost; } From 06256c0c000e393a90f8447b32695d2296de09aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:20:19 +0200 Subject: [PATCH 163/303] Slightly adjust the wording of "write_blif" help --- backends/blif/blif.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/blif/blif.cc b/backends/blif/blif.cc index 23d1d58fc20..8e2c088c484 100644 --- a/backends/blif/blif.cc +++ b/backends/blif/blif.cc @@ -512,8 +512,8 @@ struct BlifBackend : public Backend { log(" suppresses the generation of this nets without fanout.\n"); log("\n"); log("The following options can be useful when the generated file is not going to be\n"); - log("read by a BLIF parser but a custom tool. It is recommended to not name the\n"); - log("output file *.blif when any of this options is used.\n"); + log("read by a BLIF parser but a custom tool. It is recommended not to name the\n"); + log("output file *.blif when any of these options are used.\n"); log("\n"); log(" -icells\n"); log(" do not translate Yosys's internal gates to generic BLIF logic\n"); From 7c6cc4c40ba1ab59652da1201271ca8936523274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:20:48 +0200 Subject: [PATCH 164/303] tests: Fix invocation of 'help -cells' There's no such thing as 'help -celltypes' and there probably never was. --- tests/various/help.ys | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/various/help.ys b/tests/various/help.ys index 9283ce8f1b5..04793274bdb 100644 --- a/tests/various/help.ys +++ b/tests/various/help.ys @@ -1,2 +1,2 @@ help -all -help -celltypes +help -cells From c0b1a7daa4f6f0f3430367096fb2cf41f7e3dbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:21:49 +0200 Subject: [PATCH 165/303] Drop stray 'cellaigs.h' include from backend passes This include seems to have been copied over from the JSON backend where AIG models are sometimes inserted into the JSON output, but these other backends don't do anything with AIG. --- backends/firrtl/firrtl.cc | 1 - backends/jny/jny.cc | 1 - 2 files changed, 2 deletions(-) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index eb30ab4b948..531b2f01ff9 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -21,7 +21,6 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" -#include "kernel/cellaigs.h" #include "kernel/log.h" #include "kernel/mem.h" #include diff --git a/backends/jny/jny.cc b/backends/jny/jny.cc index 0be11a52cca..9989feed599 100644 --- a/backends/jny/jny.cc +++ b/backends/jny/jny.cc @@ -21,7 +21,6 @@ #include "kernel/register.h" #include "kernel/sigtools.h" #include "kernel/celltypes.h" -#include "kernel/cellaigs.h" #include "kernel/log.h" #include #include From 78d13d195693df897b9d427c91e17b9f0dc6f2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:22:58 +0200 Subject: [PATCH 166/303] Mention 'bwmuxmap' in 'write_firrtl' help The FIRRTL backend does call into the 'bwmuxmap' pass but omits it in the help message. --- backends/firrtl/firrtl.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index 531b2f01ff9..fc1d628915c 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -1195,6 +1195,7 @@ struct FirrtlBackend : public Backend { log(" pmuxtree\n"); log(" bmuxmap\n"); log(" demuxmap\n"); + log(" bwmuxmap\n"); log("\n"); } void execute(std::ostream *&f, std::string filename, std::vector args, RTLIL::Design *design) override From 8839d7fa5a60214e1ff54fc2fdec8a33b27731cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:27:50 +0200 Subject: [PATCH 167/303] cellaigs: Fix the case of $_NMUX_ cells Later on there's a if (cell->type == ID($_NMUX_)) but that code was unreachable until now. --- kernel/cellaigs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 292af3f51b0..c0d413fadbe 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -318,7 +318,7 @@ Aig::Aig(Cell *cell) goto optimize; } - if (cell->type.in(ID($mux), ID($_MUX_))) + if (cell->type.in(ID($mux), ID($_MUX_), ID($_NMUX_))) { int S = mk.inport(ID::S); for (int i = 0; i < GetSize(cell->getPort(ID::Y)); i++) { From eb083c5d4b464378180d6e4ba2a890eeba656c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:34:04 +0200 Subject: [PATCH 168/303] extract_counter: Update help and comments after UP/DOWN support Commit fec7dc5c should have added support for up counters so update the help and comments accordingly. --- passes/techmap/extract_counter.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/passes/techmap/extract_counter.cc b/passes/techmap/extract_counter.cc index 9c814af231b..b780f7df06c 100644 --- a/passes/techmap/extract_counter.cc +++ b/passes/techmap/extract_counter.cc @@ -120,8 +120,6 @@ struct CounterExtractionSettings }; //attempt to extract a counter centered on the given adder cell -//For now we only support DOWN counters. -//TODO: up/down support int counter_tryextract( ModIndex& index, Cell *cell, @@ -766,9 +764,9 @@ struct ExtractCounterPass : public Pass { log("\n"); log(" extract_counter [options] [selection]\n"); log("\n"); - log("This pass converts non-resettable or async resettable down counters to\n"); - log("counter cells. Use a target-specific 'techmap' map file to convert those cells\n"); - log("to the actual target cells.\n"); + log("This pass converts non-resettable or async resettable counters to counter cells.\n"); + log("Use a target-specific 'techmap' map file to convert those cells to the actual\n"); + log("target cells.\n"); log("\n"); log(" -maxwidth N\n"); log(" Only extract counters up to N bits wide (default 64)\n"); From 0d5e9acd34b622be867db9fcc4c42934622a6130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:54:02 +0200 Subject: [PATCH 169/303] README.md: s/write_ilang/write_rtlil/ It's my understanding write_ilang is deprecated so best no to mention it in the README. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f3a63cbec39..5e5a8ec3e12 100644 --- a/README.md +++ b/README.md @@ -156,9 +156,10 @@ reading and elaborating the design using the Verilog frontend: yosys> read -sv tests/simple/fiedler-cooley.v yosys> hierarchy -top up3down5 -writing the design to the console in Yosys's internal format: +writing the design to the console in the RTLIL format used by Yosys +internally: - yosys> write_ilang + yosys> write_rtlil convert processes (``always`` blocks) to netlist elements and perform some simple optimizations: From 5584ce95db40743acec582a59c4efccd3c33d59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:40:18 +0200 Subject: [PATCH 170/303] log: Detect newlines in Python log output So that Python messages are annotated with timestamps too (if -t was passed). --- kernel/log.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/log.cc b/kernel/log.cc index 985165a97f0..12d7596a1c5 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -147,6 +147,12 @@ void logv(const char *format, va_list ap) if (format[0] && format[strlen(format)-1] == '\n') next_print_log = true; + // Special case to detect newlines in Python log output, since + // the binding always calls `log("%s", payload)` and the newline + // is then in the first formatted argument + if (!strcmp(format, "%s") && str.back() == '\n') + next_print_log = true; + for (auto f : log_files) fputs(time_str.c_str(), f); From 25d4b3a5dc32ac3865d5907b5aba45f67f2dabb0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 00:26:17 +0000 Subject: [PATCH 171/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cf2d8f200bf..30e144f83ee 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+48 +YOSYS_VER := 0.30+55 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f3c6b41050f388634a1e781e0734675dfc5fa505 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 18 Jul 2023 08:45:00 +0200 Subject: [PATCH 172/303] Release version 0.31 --- CHANGELOG | 8 +++++++- Makefile | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0d433d4a33d..8ca3a45c272 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,14 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.30 .. Yosys 0.31-dev +Yosys 0.30 .. Yosys 0.31 -------------------------- + * New commands and options + - Added option "-lsbidx" to "write_edif" pass. + + * Various + - Added support for $divfloor operator to cxxrtl backend. + - dfflegalize: allow setting mince and minsrst args from scratchpad. Yosys 0.29 .. Yosys 0.30 -------------------------- diff --git a/Makefile b/Makefile index 30e144f83ee..00ae0d0760a 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.30+55 +YOSYS_VER := 0.31 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f7a8284.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f7a8284.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 4fff228b0cfd8c8b3810399dc8191253f79244fa Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 18 Jul 2023 08:47:52 +0200 Subject: [PATCH 173/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8ca3a45c272..0b211771f0f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.31 .. Yosys 0.32-dev +-------------------------- + Yosys 0.30 .. Yosys 0.31 -------------------------- * New commands and options diff --git a/Makefile b/Makefile index 00ae0d0760a..a8d51ef8bfe 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31 +YOSYS_VER := 0.31+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f7a8284.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 83c9261d6ca47e7974258ae4e7f1c86f0dfa8961 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 00:31:56 +0000 Subject: [PATCH 174/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a8d51ef8bfe..4707379ab9e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+0 +YOSYS_VER := 0.31+1 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 6a553568c56146f3084e361a7194c8a0762b58da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 19 Jul 2023 16:48:15 +0200 Subject: [PATCH 175/303] kernel/mem: Assert ABITS is not below wide_log2 Later in the check() code we check the bottom wide_log2 bits on the address port are zeroed out. If the address port is too narrow, we crash due to out of bounds access. Explicitly assert the address port is wide enough, so we don't crash on input such as read_rtlil <= port.wide_log2); log_assert(GetSize(port.data) == (width << port.wide_log2)); log_assert(GetSize(port.init_value) == (width << port.wide_log2)); log_assert(GetSize(port.arst_value) == (width << port.wide_log2)); @@ -484,6 +485,7 @@ void Mem::check() { log_assert(GetSize(port.clk) == 1); log_assert(GetSize(port.en) == (width << port.wide_log2)); log_assert(GetSize(port.data) == (width << port.wide_log2)); + log_assert(GetSize(port.addr) >= port.wide_log2); for (int j = 0; j < port.wide_log2; j++) { log_assert(port.addr[j] == State::S0); } From f0ae046c5a712af91d8a10e2a8724f934989d848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 19 Jul 2023 20:08:22 +0200 Subject: [PATCH 176/303] opt_share: Fix input confusion with ANDNOT, ORNOT gates Distinguish between the A, B input ports of `$_ANDNOT_`, `$_ORNOT_` gates when considering those for sharing. Unlike the input ports of the other supported single-bit gates, those are not interchangeable. Fixes #3848. --- passes/opt/opt_share.cc | 3 +++ tests/opt/bug3848.ys | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/opt/bug3848.ys diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index ba85df975f9..bf9569d9905 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -131,6 +131,9 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na if (cell->type.in(ID($lt), ID($le), ID($ge), ID($gt), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($concat), SHIFT_OPS) && port_name == ID::B) return port_name; + if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) + return port_name; + return ""; } diff --git a/tests/opt/bug3848.ys b/tests/opt/bug3848.ys new file mode 100644 index 00000000000..32f5403467d --- /dev/null +++ b/tests/opt/bug3848.ys @@ -0,0 +1,28 @@ +read_verilog -icells < Date: Wed, 19 Jul 2023 16:55:30 +0200 Subject: [PATCH 177/303] verilog_backend: Make the keywords pool static Do not recreate the keywords pool on every lookup of an identifier. --- backends/verilog/verilog_backend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 3da168960f4..7b6a4c93e30 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -129,7 +129,7 @@ std::string id(RTLIL::IdString internal_id, bool may_rename = true) break; } - const pool keywords = { + static const pool keywords = { // IEEE 1800-2017 Annex B "accept_on", "alias", "always", "always_comb", "always_ff", "always_latch", "and", "assert", "assign", "assume", "automatic", "before", "begin", "bind", "bins", "binsof", "bit", "break", "buf", "bufif0", "bufif1", "byte", "case", "casex", "casez", "cell", "chandle", From 51ef942547860584522c570f7ae68600da7ca9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 19 Jul 2023 16:56:58 +0200 Subject: [PATCH 178/303] verilog_backend: Use hashlib dict for `auto_name_map` This is most likely faster. --- backends/verilog/verilog_backend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 7b6a4c93e30..5ff191a9c16 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -37,7 +37,7 @@ PRIVATE_NAMESPACE_BEGIN bool verbose, norename, noattr, attr2comment, noexpr, nodec, nohex, nostr, extmem, defparam, decimal, siminit, systemverilog, simple_lhs, noparallelcase; int auto_name_counter, auto_name_offset, auto_name_digits, extmem_counter; -std::map auto_name_map; +dict auto_name_map; std::set reg_wires; std::string auto_prefix, extmem_prefix; From f5485b59a97fd3c833f696b229a820abd16767b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 19 Jul 2023 16:57:49 +0200 Subject: [PATCH 179/303] sim: Bail if there are blackboxes in simulation --- passes/sat/sim.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 2f353672b24..325e123201c 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -188,6 +188,10 @@ struct SimInstance { log_assert(module); + if (module->get_blackbox_attribute(true)) + log_error("Cannot simulate blackbox module %s (instanced at %s).\n", + log_id(module->name), hiername().c_str()); + if (parent) { log_assert(parent->children.count(instance) == 0); parent->children[instance] = this; From 0b8f72859058f691cfc52fd9f29974d8d9637fd0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 21 Jul 2023 00:17:07 +0000 Subject: [PATCH 180/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4707379ab9e..a28713c69d4 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+1 +YOSYS_VER := 0.31+6 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From cff53d6d873493c2560a8ed1997a01f71c3571e6 Mon Sep 17 00:00:00 2001 From: Dag Lem Date: Sun, 29 Jan 2023 20:22:00 +0100 Subject: [PATCH 181/303] Corrected handling of nested typedefs of struct/union This also corrects shadowing of constants in struct/union types. --- frontends/ast/simplify.cc | 58 ++++++++++++++++++++++++++++-- frontends/verilog/verilog_parser.y | 51 ++------------------------ tests/svtypes/typedef_scopes.sv | 20 +++++++++++ tests/svtypes/typedef_struct.sv | 4 ++- 4 files changed, 81 insertions(+), 52 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 1efd1b24dbc..28f316d26a1 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1380,6 +1380,60 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, break; case AST_STRUCT_ITEM: + if (is_custom_type) { + log_assert(children.size() == 1); + log_assert(children[0]->type == AST_WIRETYPE); + auto type_name = children[0]->str; + if (!current_scope.count(type_name)) { + log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str()); + } + AstNode *resolved_type_node = current_scope.at(type_name); + if (resolved_type_node->type != AST_TYPEDEF) + log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str()); + log_assert(resolved_type_node->children.size() == 1); + AstNode *template_node = resolved_type_node->children[0]; + + // Ensure typedef itself is fully simplified + while (template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; + + // Remove type reference + delete children[0]; + children.pop_back(); + + switch (template_node->type) { + case AST_WIRE: + type = AST_STRUCT_ITEM; + break; + case AST_STRUCT: + case AST_UNION: + type = template_node->type; + break; + default: + log_file_error(filename, location.first_line, "Invalid type for struct member: %s", type2str(template_node->type).c_str()); + } + + is_reg = template_node->is_reg; + is_logic = template_node->is_logic; + is_signed = template_node->is_signed; + is_string = template_node->is_string; + is_custom_type = template_node->is_custom_type; + + range_valid = template_node->range_valid; + range_swapped = template_node->range_swapped; + range_left = template_node->range_left; + range_right = template_node->range_right; + + attributes[ID::wiretype] = mkconst_str(resolved_type_node->str); + + // Copy clones of children from template + for (auto template_child : template_node->children) { + children.push_back(template_child->clone()); + } + + did_something = true; + + } + log_assert(!is_custom_type); break; case AST_ENUM: @@ -1793,8 +1847,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // Ensure typedef itself is fully simplified while (template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; - if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) { - // replace with wire representing the packed structure + if (!str.empty() && str[0] == '\\' && (template_node->type == AST_STRUCT || template_node->type == AST_UNION)) { + // replace instance with wire representing the packed structure newNode = make_packed_struct(template_node, str, attributes); newNode->attributes[ID::wiretype] = mkconst_str(resolved_type_node->str); // add original input/output attribute to resolved wire diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 4c5bd0b10a9..98bdbf9e5c5 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -171,36 +171,6 @@ static bool isInLocalScope(const std::string *name) return (user_types.count(*name) > 0); } -static AstNode *getTypeDefinitionNode(std::string type_name) -{ - // check package types - if (type_name.find("::") != std::string::npos && pkg_user_types.count(type_name) > 0) { - auto typedef_node = pkg_user_types[type_name]; - log_assert(typedef_node->type == AST_TYPEDEF); - return typedef_node->children[0]; - } - - // check current scope then outer scopes for a name - for (auto it = user_type_stack.rbegin(); it != user_type_stack.rend(); ++it) { - if (it->count(type_name) > 0) { - // return the definition nodes from the typedef statement - auto typedef_node = (*it)[type_name]; - log_assert(typedef_node->type == AST_TYPEDEF); - return typedef_node->children[0]; - } - } - - // The lexer recognized the name as a TOK_USER_TYPE, but now we can't find it anymore? - log_error("typedef for user type `%s' not found", type_name.c_str()); -} - -static AstNode *copyTypeDefinition(std::string type_name) -{ - // return a copy of the template from a typedef definition - auto typedef_node = getTypeDefinitionNode(type_name); - return typedef_node->clone(); -} - static AstNode *makeRange(int msb = 31, int lsb = 0, bool isSigned = true) { auto range = new AstNode(AST_RANGE); @@ -1633,10 +1603,7 @@ param_implicit_type: param_signed param_range; param_type: param_integer_type | param_real | param_range_type | param_implicit_type | hierarchical_type_id { - astbuf1->is_custom_type = true; - astbuf1->children.push_back(new AstNode(AST_WIRETYPE)); - astbuf1->children.back()->str = *$1; - delete $1; + addWiretypeNode($1, astbuf1); }; param_decl: @@ -1865,21 +1832,7 @@ struct_member_type: { astbuf1 = new AstNode(AST_STRUCT_ITEM); } member_type_toke member_type_token: member_type | hierarchical_type_id { - // use a clone of the typedef definition nodes - auto template_node = copyTypeDefinition(*$1); - delete $1; - switch (template_node->type) { - case AST_WIRE: - template_node->type = AST_STRUCT_ITEM; - break; - case AST_STRUCT: - case AST_UNION: - break; - default: - frontend_verilog_yyerror("Invalid type for struct member: %s", type2str(template_node->type).c_str()); - } - delete astbuf1; - astbuf1 = template_node; + addWiretypeNode($1, astbuf1); } | { delete astbuf1; diff --git a/tests/svtypes/typedef_scopes.sv b/tests/svtypes/typedef_scopes.sv index 9a898fac8a4..5ac9a4664c4 100644 --- a/tests/svtypes/typedef_scopes.sv +++ b/tests/svtypes/typedef_scopes.sv @@ -17,6 +17,12 @@ module top; always @(*) assert(inner_i1 == 4'hA); always @(*) assert(inner_enum1 == 3'h3); + // adapted from tests/verilog/typedef_const_shadow.sv + localparam W = 5; + typedef logic [W-1:0] T; + T x; // width 5 + always @(*) assert($bits(x) == 5); + if (1) begin: genblock // type declarations in child scopes shadow their parents typedef logic [7:0] inner_type; @@ -34,6 +40,20 @@ module top; } mystruct_t; mystruct_t mystruct; always @(*) assert($bits(mystruct) == 4); + + // adapted from tests/verilog/typedef_const_shadow.sv + localparam W = 10; + typedef T U; + typedef logic [W-1:0] V; + struct packed { + logic [W-1:0] x; // width 10 + U y; // width 5 + V z; // width 10 + } shadow; + // This currently only works as long as long as shadow is not typedef'ed + always @(*) assert($bits(shadow.x) == 10); + always @(*) assert($bits(shadow.y) == 5); + always @(*) assert($bits(shadow.z) == 10); end inner_type inner_i2 = 8'h42; diff --git a/tests/svtypes/typedef_struct.sv b/tests/svtypes/typedef_struct.sv index 8df8e32b0bd..136bb5c1bbc 100644 --- a/tests/svtypes/typedef_struct.sv +++ b/tests/svtypes/typedef_struct.sv @@ -19,8 +19,10 @@ module top; p::p_t ps; } s_t; + typedef s_t s1_t; + s_t s; - s_t s1; + s1_t s1; p::p_t ps; From 1ac1b2eed5299b1fe4da893e1c475015a520f018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 4 Apr 2023 11:34:17 +0200 Subject: [PATCH 182/303] ast/simplify: Factor out helper to determine range width --- frontends/ast/simplify.cc | 68 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 28f316d26a1..4b6f6606966 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -775,6 +775,33 @@ static IdentUsage always_asgn_before_use(const AstNode *node, const std::string return IdentUsage::NotReferenced; } +static bool try_determine_range_width(AstNode *range, int &result_width) +{ + log_assert(range->type == AST_RANGE); + + if (range->children.size() == 1) { + result_width = 1; + return true; + } + + AstNode *left_at_zero_ast = range->children[0]->clone(); + AstNode *right_at_zero_ast = range->children[1]->clone(); + + while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) {} + while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) {} + + bool ok = false; + if (left_at_zero_ast->type == AST_CONSTANT + && right_at_zero_ast->type == AST_CONSTANT) { + ok = true; + result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; + } + + delete left_at_zero_ast; + delete right_at_zero_ast; + return ok; +} + static const std::string auto_nosync_prefix = "\\AutoNosync"; // mark a local variable in an always_comb block for automatic nosync @@ -2788,20 +2815,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *shift_expr = NULL; AstNode *range = children[0]->children[0]; - if (range->children.size() == 1) { - shift_expr = range->children[0]->clone(); - } else { + if (!try_determine_range_width(range, result_width)) + log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + + if (range->children.size() >= 2) shift_expr = range->children[1]->clone(); - AstNode *left_at_zero_ast = range->children[0]->clone(); - AstNode *right_at_zero_ast = range->children[1]->clone(); - while (left_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } - while (right_at_zero_ast->simplify(true, true, false, stage, -1, false, false)) { } - if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); - result_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; - delete left_at_zero_ast; - delete right_at_zero_ast; - } + else + shift_expr = range->children[0]->clone(); bool use_case_method = false; @@ -3205,19 +3225,20 @@ skip_dynamic_range_lvalue_expansion:; else { AstNode *the_range = children[0]->children[1]; - AstNode *left_at_zero_ast = the_range->children[0]->clone(); - AstNode *right_at_zero_ast = the_range->children.size() >= 2 ? the_range->children[1]->clone() : left_at_zero_ast->clone(); - AstNode *offset_ast = right_at_zero_ast->clone(); + AstNode *offset_ast; + int width; + + if (!try_determine_range_width(the_range, width)) + log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + + if (the_range->children.size() >= 2) + offset_ast = the_range->children[1]->clone(); + else + offset_ast = the_range->children[0]->clone(); if (mem_data_range_offset) offset_ast = new AstNode(AST_SUB, offset_ast, mkconst_int(mem_data_range_offset, true)); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } - if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); - int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; - assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), new AstNode(AST_SHIFT_LEFT, children[1]->clone(), offset_ast->clone())); assign_data->children[0]->str = id_data; @@ -3229,9 +3250,6 @@ skip_dynamic_range_lvalue_expansion:; new AstNode(AST_SHIFT_LEFT, mkconst_bits(set_bits_en, false), offset_ast->clone())); assign_en->children[0]->str = id_en; assign_en->children[0]->was_checked = true; - - delete left_at_zero_ast; - delete right_at_zero_ast; delete offset_ast; } } From 77d4b5230ed2e02cf0979837fb85146d42ac0833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 4 Apr 2023 11:53:50 +0200 Subject: [PATCH 183/303] ast: Move to a new helper method to print input errors It's a repeating pattern to print an error message tied to an AST node. Start using an 'input_error' helper for that. Among other things this is beneficial in shortening the print lines, which tend to be long. --- frontends/ast/ast.cc | 19 ++- frontends/ast/ast.h | 3 + frontends/ast/genrtlil.cc | 129 ++++++++++----------- frontends/ast/simplify.cc | 235 +++++++++++++++++++------------------- kernel/log.cc | 12 +- kernel/log.h | 1 + 6 files changed, 204 insertions(+), 195 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 91001c70dfd..a900731a4b2 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -192,7 +192,7 @@ bool AstNode::get_bool_attribute(RTLIL::IdString id) AstNode *attr = attributes.at(id); if (attr->type != AST_CONSTANT) - log_file_error(attr->filename, attr->location.first_line, "Attribute `%s' with non-constant value!\n", id.c_str()); + attr->input_error("Attribute `%s' with non-constant value!\n", id.c_str()); return attr->integer != 0; } @@ -1039,7 +1039,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d { for (const AstNode *node : ast->children) if (node->type == AST_PARAMETER && param_has_no_default(node)) - log_file_error(node->filename, node->location.first_line, "Parameter `%s' has no default value and has not been overridden!\n", node->str.c_str()); + node->input_error("Parameter `%s' has no default value and has not been overridden!\n", node->str.c_str()); bool blackbox_module = flag_lib; @@ -1099,14 +1099,14 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d if (!blackbox_module && ast->attributes.count(ID::blackbox)) { AstNode *n = ast->attributes.at(ID::blackbox); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->location.first_line, "Got blackbox attribute with non-constant value!\n"); + ast->input_error("Got blackbox attribute with non-constant value!\n"); blackbox_module = n->asBool(); } if (blackbox_module && ast->attributes.count(ID::whitebox)) { AstNode *n = ast->attributes.at(ID::whitebox); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->location.first_line, "Got whitebox attribute with non-constant value!\n"); + ast->input_error("Got whitebox attribute with non-constant value!\n"); blackbox_module = !n->asBool(); } @@ -1114,7 +1114,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d if (blackbox_module) { AstNode *n = ast->attributes.at(ID::noblackbox); if (n->type != AST_CONSTANT) - log_file_error(ast->filename, ast->location.first_line, "Got noblackbox attribute with non-constant value!\n"); + ast->input_error("Got noblackbox attribute with non-constant value!\n"); blackbox_module = !n->asBool(); } delete ast->attributes.at(ID::noblackbox); @@ -1158,7 +1158,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + ast->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); module->attributes[attr.first] = attr.second->asAttrConst(); } for (size_t i = 0; i < ast->children.size(); i++) { @@ -1841,4 +1841,11 @@ void AstModule::loadconfig() const flag_autowire = autowire; } +void AstNode::input_error(const char *format, ...) const +{ + va_list ap; + va_start(ap, format); + logv_file_error(filename, location.first_line, format, ap); +} + YOSYS_NAMESPACE_END diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 25a600f00b8..0c0e8a3bc3b 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -335,6 +335,9 @@ namespace AST // Helper for looking up identifiers which are prefixed with the current module name std::string try_pop_module_prefix() const; + + // helper to print errors from simplify/genrtlil code + [[noreturn]] void input_error(const char *format, ...) const YS_ATTRIBUTE(format(printf, 2, 3)); }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 5c0b8802792..65251431240 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -56,7 +56,7 @@ static RTLIL::SigSpec uniop2rtlil(AstNode *that, IdString type, int result_width if (gen_attributes) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -88,7 +88,7 @@ static void widthExtend(AstNode *that, RTLIL::SigSpec &sig, int width, bool is_s if (that != NULL) for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -114,7 +114,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -149,7 +149,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const for (auto &attr : that->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(that->filename, that->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + that->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -325,8 +325,7 @@ struct AST_INTERNAL::ProcessGenerator set_src_attr(proc, always); for (auto &attr : always->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(always->filename, always->location.first_line, "Attribute `%s' with non-constant value!\n", - attr.first.c_str()); + always->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); proc->attributes[attr.first] = attr.second->asAttrConst(); } current_case = &proc->root_case; @@ -355,7 +354,7 @@ struct AST_INTERNAL::ProcessGenerator if (found_anyedge_syncs) { if (found_global_syncs) - log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n"); + always->input_error("Found non-synthesizable event list!\n"); log("Note: Assuming pure combinatorial block at %s in\n", always->loc_string().c_str()); log("compliance with IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002. Recommending\n"); log("use of @* instead of @(...) for better match of synthesis and simulation.\n"); @@ -370,12 +369,12 @@ struct AST_INTERNAL::ProcessGenerator continue; found_clocked_sync = true; if (found_global_syncs || found_anyedge_syncs) - log_file_error(always->filename, always->location.first_line, "Found non-synthesizable event list!\n"); + always->input_error("Found non-synthesizable event list!\n"); RTLIL::SyncRule *syncrule = new RTLIL::SyncRule; syncrule->type = child->type == AST_POSEDGE ? RTLIL::STp : RTLIL::STn; syncrule->signal = child->children[0]->genRTLIL(); if (GetSize(syncrule->signal) != 1) - log_file_error(always->filename, always->location.first_line, "Found posedge/negedge event on a signal that is not 1 bit wide!\n"); + always->input_error("Found posedge/negedge event on a signal that is not 1 bit wide!\n"); addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true); proc->syncs.push_back(syncrule); } @@ -604,7 +603,7 @@ struct AST_INTERNAL::ProcessGenerator for (auto &attr : ast->attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(ast->filename, ast->location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + ast->input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); sw->attributes[attr.first] = attr.second->asAttrConst(); } @@ -682,16 +681,16 @@ struct AST_INTERNAL::ProcessGenerator break; case AST_WIRE: - log_file_error(ast->filename, ast->location.first_line, "Found reg declaration in block without label!\n"); + ast->input_error("Found reg declaration in block without label!\n"); break; case AST_ASSIGN: - log_file_error(ast->filename, ast->location.first_line, "Found continous assignment in always/initial block!\n"); + ast->input_error("Found continous assignment in always/initial block!\n"); break; case AST_PARAMETER: case AST_LOCALPARAM: - log_file_error(ast->filename, ast->location.first_line, "Found parameter declaration in block without label!\n"); + ast->input_error("Found parameter declaration in block without label!\n"); break; case AST_NONE: @@ -840,7 +839,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun } } if (!id_ast) - log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", str.c_str()); + input_error("Failed to resolve identifier %s for width detection!\n", str.c_str()); if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM || id_ast->type == AST_ENUM_ITEM) { if (id_ast->children.size() > 1 && id_ast->children[1]->range_valid) { this_width = id_ast->children[1]->range_left - id_ast->children[1]->range_right + 1; @@ -850,7 +849,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun if (id_ast->children[0]->type == AST_CONSTANT) this_width = id_ast->children[0]->bits.size(); else - log_file_error(filename, location.first_line, "Failed to detect width for parameter %s!\n", str.c_str()); + input_error("Failed to detect width for parameter %s!\n", str.c_str()); } if (children.size() != 0) range = children[0]; @@ -863,7 +862,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun // log("---\n"); // id_ast->dumpAst(NULL, "decl> "); // dumpAst(NULL, "ref> "); - log_file_error(filename, location.first_line, "Failed to detect width of signal access `%s'!\n", str.c_str()); + input_error("Failed to detect width of signal access `%s'!\n", str.c_str()); } } else { this_width = id_ast->range_left - id_ast->range_right + 1; @@ -874,7 +873,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun this_width = 32; } else if (id_ast->type == AST_MEMORY) { if (!id_ast->children[0]->range_valid) - log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", str.c_str()); + input_error("Failed to detect width of memory access `%s'!\n", str.c_str()); this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1; if (children.size() > 1) range = children[1]; @@ -883,7 +882,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun this_width = tmp_range->range_left - tmp_range->range_right + 1; delete tmp_range; } else - log_file_error(filename, location.first_line, "Failed to detect width for identifier %s!\n", str.c_str()); + input_error("Failed to detect width for identifier %s!\n", str.c_str()); if (range) { if (range->children.size() == 1) this_width = 1; @@ -893,7 +892,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; delete left_at_zero_ast; delete right_at_zero_ast; @@ -909,7 +908,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_TO_BITS: while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } if (children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Left operand of tobits expression is not constant!\n"); + input_error("Left operand of tobits expression is not constant!\n"); children[1]->detectSignWidthWorker(sub_width_hint, sign_hint); width_hint = max(width_hint, children[0]->bitsAsConst().as_int()); break; @@ -931,12 +930,12 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_CAST_SIZE: while (children.at(0)->simplify(true, false, false, 1, -1, false, false)) { } if (children.at(0)->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Static cast with non constant expression!\n"); + input_error("Static cast with non constant expression!\n"); children.at(1)->detectSignWidthWorker(width_hint, sign_hint); this_width = children.at(0)->bitsAsConst().as_int(); width_hint = max(width_hint, this_width); if (width_hint <= 0) - log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n"); + input_error("Static cast with zero or negative size!\n"); break; case AST_CONCAT: @@ -953,7 +952,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_REPLICATE: while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { } if (children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n"); + input_error("Left operand of replicate expression is not constant!\n"); children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint); width_hint = max(width_hint, children[0]->bitsAsConst().as_int() * sub_width_hint); sign_hint = false; @@ -1029,7 +1028,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun if (!id2ast->is_signed) sign_hint = false; if (!id2ast->children[0]->range_valid) - log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", str.c_str()); + input_error("Failed to detect width of memory access `%s'!\n", str.c_str()); this_width = id2ast->children[0]->range_left - id2ast->children[0]->range_right + 1; width_hint = max(width_hint, this_width); break; @@ -1073,7 +1072,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun if (GetSize(children) == 1) { while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { } if (children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n", + input_error("System function %s called with non-const argument!\n", RTLIL::unescape_id(str).c_str()); width_hint = max(width_hint, int(children[0]->asInt(true))); } @@ -1101,7 +1100,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun // item expressions. const AstNode *func = current_scope.at(str); if (func->type != AST_FUNCTION) - log_file_error(filename, location.first_line, "Function call to %s resolved to something that isn't a function!\n", RTLIL::unescape_id(str).c_str()); + input_error("Function call to %s resolved to something that isn't a function!\n", RTLIL::unescape_id(str).c_str()); const AstNode *wire = nullptr; for (const AstNode *child : func->children) if (child->str == func->str) { @@ -1121,7 +1120,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun while (left->simplify(true, false, false, 1, -1, false, true)) { } while (right->simplify(true, false, false, 1, -1, false, true)) { } if (left->type != AST_CONSTANT || right->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Function %s has non-constant width!", + input_error("Function %s has non-constant width!", RTLIL::unescape_id(str).c_str()); result_width = abs(int(left->asInt(true) - right->asInt(true))); delete left; @@ -1137,7 +1136,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun AstNode *current_scope_ast = current_ast_mod == nullptr ? current_ast : current_ast_mod; for (auto f : log_files) current_scope_ast->dumpAst(f, "verilog-ast> "); - log_file_error(filename, location.first_line, "Don't know how to detect sign and width for %s node!\n", type2str(type).c_str()); + input_error("Don't know how to detect sign and width for %s node!\n", type2str(type).c_str()); } if (*found_real) @@ -1155,9 +1154,8 @@ void AstNode::detectSignWidth(int &width_hint, bool &sign_hint, bool *found_real constexpr int kWidthLimit = 1 << 24; if (width_hint >= kWidthLimit) - log_file_error(filename, location.first_line, - "Expression width %d exceeds implementation limit of %d!\n", - width_hint, kWidthLimit); + input_error("Expression width %d exceeds implementation limit of %d!\n", + width_hint, kWidthLimit); } static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id, @@ -1168,9 +1166,8 @@ static void check_unique_id(RTLIL::Module *module, RTLIL::IdString id, std::string location_str = "earlier"; if (!src.empty()) location_str = "at " + src; - log_file_error(node->filename, node->location.first_line, - "Cannot add %s `%s' because a %s with the same name was already created %s!\n", - to_add_kind, id.c_str(), existing_kind, location_str.c_str()); + node->input_error("Cannot add %s `%s' because a %s with the same name was already created %s!\n", + to_add_kind, id.c_str(), existing_kind, location_str.c_str()); }; if (const RTLIL::Wire *wire = module->wire(id)) @@ -1265,7 +1262,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (flag_pwires) { if (GetSize(children) < 1 || children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Parameter `%s' with non-constant value!\n", str.c_str()); + input_error("Parameter `%s' with non-constant value!\n", str.c_str()); RTLIL::Const val = children[0]->bitsAsConst(); RTLIL::IdString id = str; @@ -1279,7 +1276,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); wire->attributes[attr.first] = attr.second->asAttrConst(); } } @@ -1288,10 +1285,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) // create an RTLIL::Wire for an AST_WIRE node case AST_WIRE: { if (!range_valid) - log_file_error(filename, location.first_line, "Signal `%s' with non-constant width!\n", str.c_str()); + input_error("Signal `%s' with non-constant width!\n", str.c_str()); if (!(range_left + 1 >= range_right)) - log_file_error(filename, location.first_line, "Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); + input_error("Signal `%s' with invalid width range %d!\n", str.c_str(), range_left - range_right + 1); RTLIL::IdString id = str; check_unique_id(current_module, id, this, "signal"); @@ -1306,7 +1303,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); wire->attributes[attr.first] = attr.second->asAttrConst(); } @@ -1322,7 +1319,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(children[1]->type == AST_RANGE); if (!children[0]->range_valid || !children[1]->range_valid) - log_file_error(filename, location.first_line, "Memory `%s' with non-constant width or size!\n", str.c_str()); + input_error("Memory `%s' with non-constant width or size!\n", str.c_str()); RTLIL::Memory *memory = new RTLIL::Memory; set_src_attr(memory, this); @@ -1340,7 +1337,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); memory->attributes[attr.first] = attr.second->asAttrConst(); } } @@ -1397,11 +1394,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } else if (flag_autowire) log_file_warning(filename, location.first_line, "Identifier `%s' is implicitly declared.\n", str.c_str()); else - log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); + input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); } else if (id2ast->type == AST_PARAMETER || id2ast->type == AST_LOCALPARAM || id2ast->type == AST_ENUM_ITEM) { if (id2ast->children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Parameter %s does not evaluate to constant value!\n", str.c_str()); + input_error("Parameter %s does not evaluate to constant value!\n", str.c_str()); chunk = RTLIL::Const(id2ast->children[0]->bits); goto use_const_chunk; } @@ -1416,11 +1413,11 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) is_interface = true; } else { - log_file_error(filename, location.first_line, "Identifier `%s' doesn't map to any signal!\n", str.c_str()); + input_error("Identifier `%s' doesn't map to any signal!\n", str.c_str()); } if (id2ast->type == AST_MEMORY) - log_file_error(filename, location.first_line, "Identifier `%s' does map to an unexpanded memory!\n", str.c_str()); + input_error("Identifier `%s' does map to an unexpanded memory!\n", str.c_str()); // If identifier is an interface, create a RTLIL::SigSpec with a dummy wire with a attribute called 'is_interface' // This makes it possible for the hierarchy pass to see what are interface connections and then replace them @@ -1449,7 +1446,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) use_const_chunk: if (children.size() != 0) { if (children[0]->type != AST_RANGE) - log_file_error(filename, location.first_line, "Single range expected.\n"); + input_error("Single range expected.\n"); int source_width = id2ast->range_left - id2ast->range_right + 1; int source_offset = id2ast->range_right; int chunk_left = source_width - 1; @@ -1468,7 +1465,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; AstNode *fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : children[0]->children[0]->clone()); @@ -1553,10 +1550,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) case AST_CAST_SIZE: { RTLIL::SigSpec size = children[0]->genRTLIL(); if (!size.is_fully_const()) - log_file_error(filename, location.first_line, "Static cast with non constant expression!\n"); + input_error("Static cast with non constant expression!\n"); int width = size.as_int(); if (width <= 0) - log_file_error(filename, location.first_line, "Static cast with zero or negative size!\n"); + input_error("Static cast with zero or negative size!\n"); // determine the *signedness* of the expression int sub_width_hint = -1; bool sub_sign_hint = true; @@ -1585,7 +1582,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) RTLIL::SigSpec left = children[0]->genRTLIL(); RTLIL::SigSpec right = children[1]->genRTLIL(); if (!left.is_fully_const()) - log_file_error(filename, location.first_line, "Left operand of replicate expression is not constant!\n"); + input_error("Left operand of replicate expression is not constant!\n"); int count = left.as_int(); RTLIL::SigSpec sig; for (int i = 0; i < count; i++) @@ -1845,7 +1842,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) id2ast->meminfo(mem_width, mem_size, addr_bits); if (children[3]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Memory init with non-constant word count!\n"); + input_error("Memory init with non-constant word count!\n"); int num_words = int(children[3]->asInt(false)); cell->parameters[ID::WORDS] = RTLIL::Const(num_words); @@ -1899,7 +1896,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value!\n", attr.first.c_str()); + input_error("Attribute `%s' with non-constant value!\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } @@ -1958,7 +1955,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_warning(filename, location.first_line, "Replacing floating point parameter %s.%s = %f with string.\n", log_id(cell), log_id(paraname), value->realvalue); else if (value->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Parameter %s.%s with non-constant value!\n", + input_error("Parameter %s.%s with non-constant value!\n", log_id(cell), log_id(paraname)); cell->parameters[paraname] = value->asParaConst(); continue; @@ -2006,7 +2003,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } for (auto &attr : attributes) { if (attr.second->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `%s' with non-constant value.\n", attr.first.c_str()); + input_error("Attribute `%s' with non-constant value.\n", attr.first.c_str()); cell->attributes[attr.first] = attr.second->asAttrConst(); } if (cell->type == ID($specify2)) { @@ -2014,7 +2011,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int dst_width = GetSize(cell->getPort(ID::DST)); bool full = cell->getParam(ID::FULL).as_bool(); if (!full && src_width != dst_width) - log_file_error(filename, location.first_line, "Parallel specify SRC width does not match DST width.\n"); + input_error("Parallel specify SRC width does not match DST width.\n"); cell->setParam(ID::SRC_WIDTH, Const(src_width)); cell->setParam(ID::DST_WIDTH, Const(dst_width)); } @@ -2022,7 +2019,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int dat_width = GetSize(cell->getPort(ID::DAT)); int dst_width = GetSize(cell->getPort(ID::DST)); if (dat_width != dst_width) - log_file_error(filename, location.first_line, "Specify DAT width does not match DST width.\n"); + input_error("Specify DAT width does not match DST width.\n"); int src_width = GetSize(cell->getPort(ID::SRC)); cell->setParam(ID::SRC_WIDTH, Const(src_width)); cell->setParam(ID::DST_WIDTH, Const(dst_width)); @@ -2064,20 +2061,20 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_file_warning(filename, location.first_line, "\n"); } else if (str == "$error") { if (sz > 0) - log_file_error(filename, location.first_line, "%s.\n", children[0]->str.c_str()); + input_error("%s.\n", children[0]->str.c_str()); else - log_file_error(filename, location.first_line, "\n"); + input_error("\n"); } else if (str == "$fatal") { // TODO: 1st parameter, if exists, is 0,1 or 2, and passed to $finish() // if no parameter is given, default value is 1 // dollar_finish(sz ? children[0] : 1); // perhaps create & use log_file_fatal() if (sz > 0) - log_file_error(filename, location.first_line, "FATAL: %s.\n", children[0]->str.c_str()); + input_error("FATAL: %s.\n", children[0]->str.c_str()); else - log_file_error(filename, location.first_line, "FATAL.\n"); + input_error("FATAL.\n"); } else { - log_file_error(filename, location.first_line, "Unknown elabortoon system task '%s'.\n", str.c_str()); + input_error("Unknown elabortoon system task '%s'.\n", str.c_str()); } } break; @@ -2095,18 +2092,18 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) int width = width_hint; if (GetSize(children) > 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 0.\n", + input_error("System function %s got %d arguments, expected 1 or 0.\n", RTLIL::unescape_id(str).c_str(), GetSize(children)); if (GetSize(children) == 1) { if (children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "System function %s called with non-const argument!\n", + input_error("System function %s called with non-const argument!\n", RTLIL::unescape_id(str).c_str()); width = children[0]->asInt(true); } if (width <= 0) - log_file_error(filename, location.first_line, "Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str()); + input_error("Failed to detect width of %s!\n", RTLIL::unescape_id(str).c_str()); Cell *cell = current_module->addCell(myid, str.substr(1)); set_src_attr(cell, this); @@ -2115,7 +2112,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (attributes.count(ID::reg)) { auto &attr = attributes.at(ID::reg); if (attr->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `reg' with non-constant value!\n"); + input_error("Attribute `reg' with non-constant value!\n"); cell->attributes[ID::reg] = attr->asAttrConst(); } @@ -2133,7 +2130,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) default: for (auto f : log_files) current_ast_mod->dumpAst(f, "verilog-ast> "); - log_file_error(filename, location.first_line, "Don't know how to generate RTLIL code for %s node!\n", type2str(type).c_str()); + input_error("Don't know how to generate RTLIL code for %s node!\n", type2str(type).c_str()); } return RTLIL::SigSpec(); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 4b6f6606966..6a2c190e09a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -53,7 +53,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg { // If there's no next character, that's a problem if (i+1 >= sformat.length()) - log_file_error(filename, location.first_line, "System task `%s' called with `%%' at end of string.\n", str.c_str()); + input_error("System task `%s' called with `%%' at end of string.\n", str.c_str()); char cformat = sformat[++i]; @@ -95,13 +95,13 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'x': case 'X': if (next_arg >= GetSize(children)) - log_file_error(filename, location.first_line, "Missing argument for %%%c format specifier in system task `%s'.\n", + input_error("Missing argument for %%%c format specifier in system task `%s'.\n", cformat, str.c_str()); node_arg = children[next_arg++]; while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_arg->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); + input_error("Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); break; case 'm': @@ -118,7 +118,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg default: unsupported_format: - log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); + input_error("System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); break; } @@ -266,7 +266,7 @@ static int range_width(AstNode *node, AstNode *rnode) { log_assert(rnode->type==AST_RANGE); if (!rnode->range_valid) { - log_file_error(node->filename, node->location.first_line, "Size must be constant in packed struct/union member %s\n", node->str.c_str()); + node->input_error("Size must be constant in packed struct/union member %s\n", node->str.c_str()); } // note: range swapping has already been checked for @@ -275,7 +275,7 @@ static int range_width(AstNode *node, AstNode *rnode) [[noreturn]] static void struct_array_packing_error(AstNode *node) { - log_file_error(node->filename, node->location.first_line, "Unpacked array in packed struct/union member %s\n", node->str.c_str()); + node->input_error("Unpacked array in packed struct/union member %s\n", node->str.c_str()); } static void save_struct_range_dimensions(AstNode *node, AstNode *rnode) @@ -394,10 +394,8 @@ static int size_packed_struct(AstNode *snode, int base_offset) packed_width = width; } else { - if (packed_width != width) { - - log_file_error(node->filename, node->location.first_line, "member %s of a packed union has %d bits, expecting %d\n", node->str.c_str(), width, packed_width); - } + if (packed_width != width) + node->input_error("member %s of a packed union has %d bits, expecting %d\n", node->str.c_str(), width, packed_width); } } else { @@ -409,7 +407,7 @@ static int size_packed_struct(AstNode *snode, int base_offset) [[noreturn]] static void struct_op_error(AstNode *node) { - log_file_error(node->filename, node->location.first_line, "Unsupported operation for struct/union member %s\n", node->str.c_str()+1); + node->input_error("Unsupported operation for struct/union member %s\n", node->str.c_str()+1); } static AstNode *node_int(int ival) @@ -1034,14 +1032,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, { int nargs = GetSize(children); if (nargs < 1) - log_file_error(filename, location.first_line, "System task `%s' got %d arguments, expected >= 1.\n", + input_error("System task `%s' got %d arguments, expected >= 1.\n", str.c_str(), int(children.size())); // First argument is the format string AstNode *node_string = children[0]; while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_string->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); + input_error("Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); std::string sformat = node_string->bitsAsConst().decode_string(); std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); // Finally, print the message (only include a \n for $display, not for $write) @@ -1138,7 +1136,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; wires_are_incompatible: if (stage > 1) - log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", node->str.c_str()); + input_error("Incompatible re-declaration of wire %s.\n", node->str.c_str()); continue; } this_wire_scope[node->str] = node; @@ -1157,7 +1155,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_scope.count(enode->str) == 0) current_scope[enode->str] = enode; else - log_file_error(filename, location.first_line, "enum item %s already exists\n", enode->str.c_str()); + input_error("enum item %s already exists\n", enode->str.c_str()); } } } @@ -1197,7 +1195,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_scope.count(enode->str) == 0) current_scope[enode->str] = enode; else - log_file_error(filename, location.first_line, "enum item %s already exists in package\n", enode->str.c_str()); + input_error("enum item %s already exists in package\n", enode->str.c_str()); } } } @@ -1213,7 +1211,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_ALWAYS || type == AST_INITIAL) { if (current_always != nullptr) - log_file_error(filename, location.first_line, "Invalid nesting of always blocks and/or initializations.\n"); + input_error("Invalid nesting of always blocks and/or initializations.\n"); current_always = this; current_always_clocked = false; @@ -1279,16 +1277,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, port_name = child->str; else { if (port_counter >= module->ports.size()) - log_file_error(filename, location.first_line, - "Cell instance has more ports than the module!\n"); + input_error("Cell instance has more ports than the module!\n"); port_name = module->ports[port_counter++]; } // find the port's wire in the underlying module const RTLIL::Wire *ref = module->wire(port_name); if (ref == nullptr) - log_file_error(filename, location.first_line, - "Cell instance refers to port %s which does not exist in module %s!.\n", + input_error("Cell instance refers to port %s which does not exist in module %s!.\n", log_id(port_name), log_id(module->name)); // select the argument, if present @@ -1494,7 +1490,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) did_something = true; if (!children[1]->range_valid) - log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n"); + input_error("Non-constant width range on parameter decl.\n"); width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1); } break; @@ -1506,7 +1502,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param)) did_something = true; if (!children[1]->range_valid) - log_file_error(filename, location.first_line, "Non-constant width range on enum item decl.\n"); + input_error("Non-constant width range on enum item decl.\n"); width_hint = max(width_hint, children[1]->range_left - children[1]->range_right + 1); } break; @@ -1812,7 +1808,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_DEFPARAM && !children.empty()) { if (children[0]->type != AST_IDENTIFIER) - log_file_error(filename, location.first_line, "Module name in defparam contains non-constant expressions!\n"); + input_error("Module name in defparam contains non-constant expressions!\n"); string modname, paramname = children[0]->str; @@ -1829,12 +1825,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (pos == std::string::npos) - log_file_error(filename, location.first_line, "Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str()); + input_error("Can't find object for defparam `%s`!\n", RTLIL::unescape_id(paramname).c_str()); paramname = "\\" + paramname.substr(pos+1); if (current_scope.at(modname)->type != AST_CELL) - log_file_error(filename, location.first_line, "Defparam argument `%s . %s` does not match a cell!\n", + input_error("Defparam argument `%s . %s` does not match a cell!\n", RTLIL::unescape_id(modname).c_str(), RTLIL::unescape_id(paramname).c_str()); AstNode *paraset = new AstNode(AST_PARASET, children[1]->clone(), GetSize(children) > 2 ? children[2]->clone() : NULL); @@ -1863,11 +1859,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_assert(children[0]->type == AST_WIRETYPE); auto type_name = children[0]->str; if (!current_scope.count(type_name)) { - log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str()); + input_error("Unknown identifier `%s' used as type name\n", type_name.c_str()); } AstNode *resolved_type_node = current_scope.at(type_name); if (resolved_type_node->type != AST_TYPEDEF) - log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str()); + input_error("`%s' does not name a type\n", type_name.c_str()); log_assert(resolved_type_node->children.size() == 1); AstNode *template_node = resolved_type_node->children[0]; @@ -1928,11 +1924,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_assert(children[1]->type == AST_WIRETYPE); auto type_name = children[1]->str; if (!current_scope.count(type_name)) { - log_file_error(filename, location.first_line, "Unknown identifier `%s' used as type name\n", type_name.c_str()); + input_error("Unknown identifier `%s' used as type name\n", type_name.c_str()); } AstNode *resolved_type_node = current_scope.at(type_name); if (resolved_type_node->type != AST_TYPEDEF) - log_file_error(filename, location.first_line, "`%s' does not name a type\n", type_name.c_str()); + input_error("`%s' does not name a type\n", type_name.c_str()); log_assert(resolved_type_node->children.size() == 1); AstNode *template_node = resolved_type_node->children[0]; @@ -1955,7 +1951,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, children.pop_back(); if (template_node->type == AST_MEMORY) - log_file_error(filename, location.first_line, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); + input_error("unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); is_signed = template_node->is_signed; is_string = template_node->is_string; is_custom_type = template_node->is_custom_type; @@ -1976,7 +1972,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_PREFIX) { if (children[0]->type != AST_CONSTANT) { // dumpAst(NULL, "> "); - log_file_error(filename, location.first_line, "Index in generate block prefix syntax is not constant!\n"); + input_error("Index in generate block prefix syntax is not constant!\n"); } if (children[1]->type == AST_PREFIX) children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param); @@ -1992,9 +1988,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // evaluate TO_BITS nodes if (type == AST_TO_BITS) { if (children[0]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Left operand of to_bits expression is not constant!\n"); + input_error("Left operand of to_bits expression is not constant!\n"); if (children[1]->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Right operand of to_bits expression is not constant!\n"); + input_error("Right operand of to_bits expression is not constant!\n"); RTLIL::Const new_value = children[1]->bitsAsConst(children[0]->bitsAsConst().as_int(), children[1]->is_signed); newNode = mkconst_bits(new_value.bits, children[1]->is_signed); goto apply_newNode; @@ -2044,17 +2040,17 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (attributes.count(ID::force_upto)) { AstNode *val = attributes[ID::force_upto]; if (val->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `force_upto' with non-constant value!\n"); + input_error("Attribute `force_upto' with non-constant value!\n"); force_upto = val->asAttrConst().as_bool(); } if (attributes.count(ID::force_downto)) { AstNode *val = attributes[ID::force_downto]; if (val->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Attribute `force_downto' with non-constant value!\n"); + input_error("Attribute `force_downto' with non-constant value!\n"); force_downto = val->asAttrConst().as_bool(); } if (force_upto && force_downto) - log_file_error(filename, location.first_line, "Attributes `force_downto' and `force_upto' cannot be both set!\n"); + input_error("Attributes `force_downto' and `force_upto' cannot be both set!\n"); if ((force_upto && !range_swapped) || (force_downto && range_swapped)) { std::swap(range_left, range_right); range_swapped = force_upto; @@ -2078,7 +2074,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, multirange_swapped.clear(); for (auto range : children[1]->children) { if (!range->range_valid) - log_file_error(filename, location.first_line, "Non-constant range on memory decl.\n"); + input_error("Non-constant range on memory decl.\n"); multirange_dimensions.push_back(min(range->range_left, range->range_right)); multirange_dimensions.push_back(max(range->range_left, range->range_right) - min(range->range_left, range->range_right) + 1); multirange_swapped.push_back(range->range_swapped); @@ -2098,7 +2094,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (int i = 0; 2*i < GetSize(id2ast->multirange_dimensions); i++) { if (GetSize(children[0]->children) <= i) - log_file_error(filename, location.first_line, "Insufficient number of array indices for %s.\n", log_id(str)); + input_error("Insufficient number of array indices for %s.\n", log_id(str)); AstNode *new_index_expr = children[0]->children[i]->children.at(0)->clone(); @@ -2127,7 +2123,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_ENUM_ITEM) { if (children.size() > 1 && children[1]->type == AST_RANGE) { if (!children[1]->range_valid) - log_file_error(filename, location.first_line, "Non-constant width range on parameter decl.\n"); + input_error("Non-constant width range on parameter decl.\n"); int width = std::abs(children[1]->range_left - children[1]->range_right) + 1; if (children[0]->type == AST_REALVALUE) { RTLIL::Const constvalue = children[0]->realAsConst(width); @@ -2228,7 +2224,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (current_scope.count(str) == 0) { if (current_ast_mod == nullptr) { - log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared outside of a module.\n", str.c_str()); + input_error("Identifier `%s' is implicitly declared outside of a module.\n", str.c_str()); } else if (flag_autowire || str == "\\$global_clock") { AstNode *auto_wire = new AstNode(AST_AUTOWIRE); auto_wire->str = str; @@ -2236,7 +2232,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, current_scope[str] = auto_wire; did_something = true; } else { - log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); + input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", str.c_str()); } } if (id2ast != current_scope[str]) { @@ -2249,7 +2245,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_IDENTIFIER && children.size() == 2 && children[0]->type == AST_RANGE && children[1]->type == AST_RANGE && !in_lvalue && stage == 2) { if (id2ast == NULL || id2ast->type != AST_MEMORY || children[0]->children.size() != 1) - log_file_error(filename, location.first_line, "Invalid bit-select on memory access!\n"); + input_error("Invalid bit-select on memory access!\n"); int mem_width, mem_size, addr_bits; id2ast->meminfo(mem_width, mem_size, addr_bits); @@ -2303,7 +2299,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (type == AST_WHILE) - log_file_error(filename, location.first_line, "While loops are only allowed in constant functions!\n"); + input_error("While loops are only allowed in constant functions!\n"); if (type == AST_REPEAT) { @@ -2314,7 +2310,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (count->simplify(true, false, false, stage, 32, true, false)) { } if (count->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Repeat loops outside must have constant repeat counts!\n"); + input_error("Repeat loops outside must have constant repeat counts!\n"); // convert to a block with the body repeated n times type = AST_BLOCK; @@ -2349,17 +2345,17 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (init_ast->type != AST_ASSIGN_EQ) - log_file_error(filename, location.first_line, "Unsupported 1st expression of %s for-loop!\n", loop_type_str); + input_error("Unsupported 1st expression of %s for-loop!\n", loop_type_str); if (next_ast->type != AST_ASSIGN_EQ) - log_file_error(filename, location.first_line, "Unsupported 3rd expression of %s for-loop!\n", loop_type_str); + input_error("Unsupported 3rd expression of %s for-loop!\n", loop_type_str); if (init_ast->children[0]->id2ast == NULL || init_ast->children[0]->id2ast->type != var_type) - log_file_error(filename, location.first_line, "Left hand side of 1st expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str); + input_error("Left hand side of 1st expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str); if (next_ast->children[0]->id2ast == NULL || next_ast->children[0]->id2ast->type != var_type) - log_file_error(filename, location.first_line, "Left hand side of 3rd expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str); + input_error("Left hand side of 3rd expression of %s for-loop is not a %s!\n", loop_type_str, var_type_str); if (init_ast->children[0]->id2ast != next_ast->children[0]->id2ast) - log_file_error(filename, location.first_line, "Incompatible left-hand sides in 1st and 3rd expression of %s for-loop!\n", loop_type_str); + input_error("Incompatible left-hand sides in 1st and 3rd expression of %s for-loop!\n", loop_type_str); // eval 1st expression AstNode *varbuf = init_ast->children[1]->clone(); @@ -2371,7 +2367,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (varbuf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str); + input_error("Right hand side of 1st expression of %s for-loop is not constant!\n", loop_type_str); auto resolved = current_scope.at(init_ast->children[0]->str); if (resolved->range_valid) { @@ -2412,7 +2408,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (buf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "2nd expression of %s for-loop is not constant!\n", loop_type_str); + input_error("2nd expression of %s for-loop is not constant!\n", loop_type_str); if (buf->integer == 0) { delete buf; @@ -2463,7 +2459,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } if (buf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type).c_str()); + input_error("Right hand side of 3rd expression of %s for-loop is not constant (%s)!\n", loop_type_str, type2str(buf->type).c_str()); delete varbuf->children[0]; varbuf->children[0] = buf; @@ -2489,7 +2485,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) { log_assert(!VERILOG_FRONTEND::sv_mode); - log_file_error(children[i]->filename, children[i]->location.first_line, "Local declaration in unnamed block is only supported in SystemVerilog mode!\n"); + children[i]->input_error("Local declaration in unnamed block is only supported in SystemVerilog mode!\n"); } } @@ -2546,7 +2542,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); - log_file_error(filename, location.first_line, "Condition for generate if is not constant!\n"); + input_error("Condition for generate if is not constant!\n"); } if (buf->asBool() != 0) { delete buf; @@ -2586,7 +2582,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); - log_file_error(filename, location.first_line, "Condition for generate case is not constant!\n"); + input_error("Condition for generate case is not constant!\n"); } bool ref_signed = buf->is_signed; @@ -2620,7 +2616,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); - log_file_error(filename, location.first_line, "Expression in generate case is not constant!\n"); + input_error("Expression in generate case is not constant!\n"); } bool is_selected = RTLIL::const_eq(ref_value, buf->bitsAsConst(), ref_signed && buf->is_signed, ref_signed && buf->is_signed, 1).as_bool(); @@ -2660,7 +2656,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_CELLARRAY) { if (!children.at(0)->range_valid) - log_file_error(filename, location.first_line, "Non-constant array range on cell array.\n"); + input_error("Non-constant array range on cell array.\n"); newNode = new AstNode(AST_GENBLOCK); int num = max(children.at(0)->range_left, children.at(0)->range_right) - min(children.at(0)->range_left, children.at(0)->range_right) + 1; @@ -2671,7 +2667,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, newNode->children.push_back(new_cell); new_cell->str += stringf("[%d]", idx); if (new_cell->type == AST_PRIMITIVE) { - log_file_error(filename, location.first_line, "Cell arrays of primitives are currently not supported.\n"); + input_error("Cell arrays of primitives are currently not supported.\n"); } else { log_assert(new_cell->children.at(0)->type == AST_CELLTYPE); new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str()); @@ -2685,7 +2681,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_PRIMITIVE) { if (children.size() < 2) - log_file_error(filename, location.first_line, "Insufficient number of arguments for primitive `%s'!\n", str.c_str()); + input_error("Insufficient number of arguments for primitive `%s'!\n", str.c_str()); std::vector children_list; for (auto child : children) { @@ -2700,7 +2696,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (str == "bufif0" || str == "bufif1" || str == "notif0" || str == "notif1") { if (children_list.size() != 3) - log_file_error(filename, location.first_line, "Invalid number of arguments for primitive `%s'!\n", str.c_str()); + input_error("Invalid number of arguments for primitive `%s'!\n", str.c_str()); std::vector z_const(1, RTLIL::State::Sz); @@ -2816,7 +2812,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *range = children[0]->children[0]; if (!try_determine_range_width(range, result_width)) - log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); if (range->children.size() >= 2) shift_expr = range->children[1]->clone(); @@ -2829,7 +2825,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *node = children[0]->id2ast->attributes.at(ID::nowrshmsk); while (node->simplify(true, false, false, stage, -1, false, false)) { } if (node->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str()); + input_error("Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str()); if (node->asAttrConst().as_bool()) use_case_method = true; } @@ -3229,7 +3225,7 @@ skip_dynamic_range_lvalue_expansion:; int width; if (!try_determine_range_width(the_range, width)) - log_file_error(filename, location.first_line, "Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); + input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); if (the_range->children.size() >= 2) offset_ast = the_range->children[1]->clone(); @@ -3337,11 +3333,11 @@ skip_dynamic_range_lvalue_expansion:; int num_steps = 1; if (GetSize(children) != 1 && GetSize(children) != 2) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", + input_error("System function %s got %d arguments, expected 1 or 2.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); if (!current_always_clocked) - log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n", + input_error("System function %s is only allowed in clocked blocks.\n", RTLIL::unescape_id(str).c_str()); if (GetSize(children) == 2) @@ -3349,7 +3345,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *buf = children[1]->clone(); while (buf->simplify(true, false, false, stage, -1, false, false)) { } if (buf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); num_steps = buf->asInt(true); delete buf; @@ -3412,11 +3408,11 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$stable" || str == "\\$rose" || str == "\\$fell" || str == "\\$changed") { if (GetSize(children) != 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + input_error("System function %s got %d arguments, expected 1.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); if (!current_always_clocked) - log_file_error(filename, location.first_line, "System function %s is only allowed in clocked blocks.\n", + input_error("System function %s is only allowed in clocked blocks.\n", RTLIL::unescape_id(str).c_str()); AstNode *present = children.at(0)->clone(); @@ -3454,13 +3450,13 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$clog2") { if (children.size() != 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + input_error("System function %s got %d arguments, expected 1.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); AstNode *buf = children[0]->clone(); while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); RTLIL::Const arg_value = buf->bitsAsConst(); if (arg_value.as_bool()) @@ -3481,11 +3477,11 @@ skip_dynamic_range_lvalue_expansion:; int dim = 1; if (str == "\\$bits") { if (children.size() != 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + input_error("System function %s got %d arguments, expected 1.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); } else { if (children.size() != 1 && children.size() != 2) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1 or 2.\n", + input_error("System function %s got %d arguments, expected 1 or 2.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); if (children.size() == 2) { AstNode *buf = children[1]->clone(); @@ -3509,7 +3505,7 @@ skip_dynamic_range_lvalue_expansion:; if (id_ast == NULL && current_scope.count(buf->str)) id_ast = current_scope.at(buf->str); if (!id_ast) - log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); + input_error("Failed to resolve identifier %s for width detection!\n", buf->str.c_str()); // Check for item in packed struct / union AST::AstNode *item_node = get_struct_member(buf); @@ -3518,13 +3514,13 @@ skip_dynamic_range_lvalue_expansion:; dim += buf->integer; if (item_node->multirange_dimensions.empty()) { if (dim != 1) - log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has one dimension!\n", dim, item_node->str.c_str()); + input_error("Dimension %d out of range in `%s', as it only has one dimension!\n", dim, item_node->str.c_str()); left = high = item_node->range_left; right = low = item_node->range_right; } else { int dims = GetSize(item_node->multirange_dimensions)/2; if (dim < 1 || dim > dims) - log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, item_node->str.c_str(), dims); + input_error("Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, item_node->str.c_str(), dims); right = low = get_struct_range_offset(item_node, dim - 1); left = high = low + get_struct_range_width(item_node, dim - 1) - 1; if (item_node->multirange_swapped[dim - 1]) { @@ -3568,17 +3564,17 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$bits") { if (mem_range->type == AST_RANGE) { if (!mem_range->range_valid) - log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); + input_error("Failed to detect width of memory access `%s'!\n", buf->str.c_str()); mem_depth = mem_range->range_left - mem_range->range_right + 1; } else - log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); + input_error("Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); } else { // $size(), $left(), $right(), $high(), $low() int dims = 1; if (mem_range->type == AST_RANGE) { if (id_ast->multirange_dimensions.empty()) { if (!mem_range->range_valid) - log_file_error(filename, location.first_line, "Failed to detect width of memory access `%s'!\n", buf->str.c_str()); + input_error("Failed to detect width of memory access `%s'!\n", buf->str.c_str()); if (dim == 1) { left = mem_range->range_right; right = mem_range->range_left; @@ -3599,10 +3595,10 @@ skip_dynamic_range_lvalue_expansion:; left = high; } } else if ((dim > dims+1) || (dim < 0)) - log_file_error(filename, location.first_line, "Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); + input_error("Dimension %d out of range in `%s', as it only has dimensions 1..%d!\n", dim, buf->str.c_str(), dims+1); } } else { - log_file_error(filename, location.first_line, "Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); + input_error("Unknown memory depth AST type in `%s'!\n", buf->str.c_str()); } } } @@ -3639,18 +3635,18 @@ skip_dynamic_range_lvalue_expansion:; if (func_with_two_arguments) { if (children.size() != 2) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2.\n", + input_error("System function %s got %d arguments, expected 2.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); } else { if (children.size() != 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + input_error("System function %s got %d arguments, expected 1.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); } if (children.size() >= 1) { while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (!children[0]->isConst()) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n", + input_error("Failed to evaluate system function `%s' with non-constant argument.\n", RTLIL::unescape_id(str).c_str()); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; @@ -3661,7 +3657,7 @@ skip_dynamic_range_lvalue_expansion:; if (children.size() >= 2) { while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (!children[1]->isConst()) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant argument.\n", + input_error("Failed to evaluate system function `%s' with non-constant argument.\n", RTLIL::unescape_id(str).c_str()); int child_width_hint = width_hint; bool child_sign_hint = sign_hint; @@ -3704,7 +3700,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *node_string = children[0]; while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_string->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); std::string sformat = node_string->bitsAsConst().decode_string(); std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); newNode = AstNode::mkconst_str(sout); @@ -3713,7 +3709,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$countbits") { if (children.size() < 2) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected at least 2.\n", + input_error("System function %s got %d arguments, expected at least 2.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); std::vector control_bits; @@ -3723,9 +3719,9 @@ skip_dynamic_range_lvalue_expansion:; AstNode *node = children[i]; while (node->simplify(true, false, false, stage, -1, false, false)) { } if (node->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str()); if (node->bits.size() != 1) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with control bit width != 1.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with control bit width != 1.\n", str.c_str()); control_bits.push_back(node->bits[0]); } @@ -3772,7 +3768,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$countones" || str == "\\$isunknown" || str == "\\$onehot" || str == "\\$onehot0") { if (children.size() != 1) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 1.\n", + input_error("System function %s got %d arguments, expected 1.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); AstNode *countbits = clone(); @@ -3812,14 +3808,14 @@ skip_dynamic_range_lvalue_expansion:; for (int i = 2; i < GetSize(dpi_decl->children); i++) { if (i-2 >= GetSize(children)) - log_file_error(filename, location.first_line, "Insufficient number of arguments in DPI function call.\n"); + input_error("Insufficient number of arguments in DPI function call.\n"); argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); args.push_back(children.at(i-2)->clone()); while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) - log_file_error(filename, location.first_line, "Failed to evaluate DPI function with non-constant argument.\n"); + input_error("Failed to evaluate DPI function with non-constant argument.\n"); } newNode = dpi_call(rtype, fname, argtypes, args); @@ -3833,7 +3829,7 @@ skip_dynamic_range_lvalue_expansion:; if (current_scope.count(str) == 0) str = try_pop_module_prefix(); if (current_scope.count(str) == 0 || current_scope[str]->type != AST_FUNCTION) - log_file_error(filename, location.first_line, "Can't resolve function name `%s'.\n", str.c_str()); + input_error("Can't resolve function name `%s'.\n", str.c_str()); } if (type == AST_TCALL) @@ -3841,26 +3837,26 @@ skip_dynamic_range_lvalue_expansion:; if (str == "$finish" || str == "$stop") { if (!current_always || current_always->type != AST_INITIAL) - log_file_error(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); + input_error("System task `%s' outside initial block is unsupported.\n", str.c_str()); - log_file_error(filename, location.first_line, "System task `%s' executed.\n", str.c_str()); + input_error("System task `%s' executed.\n", str.c_str()); } if (str == "\\$readmemh" || str == "\\$readmemb") { if (GetSize(children) < 2 || GetSize(children) > 4) - log_file_error(filename, location.first_line, "System function %s got %d arguments, expected 2-4.\n", + input_error("System function %s got %d arguments, expected 2-4.\n", RTLIL::unescape_id(str).c_str(), int(children.size())); AstNode *node_filename = children[0]->clone(); while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_filename->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); AstNode *node_memory = children[1]->clone(); while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); int start_addr = -1, finish_addr = -1; @@ -3868,7 +3864,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *node_addr = children[2]->clone(); while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_addr->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); start_addr = int(node_addr->asInt(false)); } @@ -3876,7 +3872,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *node_addr = children[3]->clone(); while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } if (node_addr->type != AST_CONSTANT) - log_file_error(filename, location.first_line, "Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); + input_error("Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); finish_addr = int(node_addr->asInt(false)); } @@ -3906,7 +3902,7 @@ skip_dynamic_range_lvalue_expansion:; if (current_scope.count(str) == 0) str = try_pop_module_prefix(); if (current_scope.count(str) == 0 || current_scope[str]->type != AST_TASK) - log_file_error(filename, location.first_line, "Can't resolve task name `%s'.\n", str.c_str()); + input_error("Can't resolve task name `%s'.\n", str.c_str()); } @@ -3943,9 +3939,9 @@ skip_dynamic_range_lvalue_expansion:; } if (in_param) - log_file_error(filename, location.first_line, "Non-constant function call in constant expression.\n"); + input_error("Non-constant function call in constant expression.\n"); if (require_const_eval) - log_file_error(filename, location.first_line, "Function %s can only be called with constant arguments.\n", str.c_str()); + input_error("Function %s can only be called with constant arguments.\n", str.c_str()); } size_t arg_count = 0; @@ -4066,7 +4062,7 @@ skip_dynamic_range_lvalue_expansion:; goto tcall_incompatible_wires; } else { tcall_incompatible_wires: - log_file_error(filename, location.first_line, "Incompatible re-declaration of wire %s.\n", child->str.c_str()); + input_error("Incompatible re-declaration of wire %s.\n", child->str.c_str()); } } } @@ -4498,7 +4494,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m yosys_input_files.insert(mem_filename); } if (f.fail() || GetSize(mem_filename) == 0) - log_file_error(filename, location.first_line, "Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str()); + input_error("Can not open file `%s` for %s.\n", mem_filename.c_str(), str.c_str()); log_assert(GetSize(memory->children) == 2 && memory->children[1]->type == AST_RANGE && memory->children[1]->range_valid); int range_left = memory->children[1]->range_left, range_right = memory->children[1]->range_right; @@ -4544,7 +4540,7 @@ AstNode *AstNode::readmem(bool is_readmemh, std::string mem_filename, AstNode *m char *endptr; cursor = strtol(nptr, &endptr, 16); if (!*nptr || *endptr) - log_file_error(filename, location.first_line, "Can not parse address `%s` for %s.\n", nptr, str.c_str()); + input_error("Can not parse address `%s` for %s.\n", nptr, str.c_str()); continue; } @@ -4905,7 +4901,7 @@ bool AstNode::mem2reg_check(pool &mem2reg_set) return false; if (children.empty() || children[0]->type != AST_RANGE || GetSize(children[0]->children) != 1) - log_file_error(filename, location.first_line, "Invalid array access.\n"); + input_error("Invalid array access.\n"); return true; } @@ -5339,7 +5335,7 @@ bool AstNode::replace_variables(std::map &varia if (children.size() != 1 || children.at(0)->type != AST_RANGE) { if (!must_succeed) return false; - log_file_error(filename, location.first_line, "Memory access in constant function is not supported\n%s: ...called from here.\n", + input_error("Memory access in constant function is not supported\n%s: ...called from here.\n", fcall->loc_string().c_str()); } if (!children.at(0)->replace_variables(variables, fcall, must_succeed)) @@ -5348,7 +5344,7 @@ bool AstNode::replace_variables(std::map &varia if (!children.at(0)->range_valid) { if (!must_succeed) return false; - log_file_error(filename, location.first_line, "Non-constant range\n%s: ... called from here.\n", + input_error("Non-constant range\n%s: ... called from here.\n", fcall->loc_string().c_str()); } offset = min(children.at(0)->range_left, children.at(0)->range_right); @@ -5403,7 +5399,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (!stmt->range_valid) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Can't determine size of variable %s\n%s: ... called from here.\n", + stmt->input_error("Can't determine size of variable %s\n%s: ... called from here.\n", stmt->str.c_str(), fcall->loc_string().c_str()); } AstNode::varinfo_t &variable = variables[stmt->str]; @@ -5411,7 +5407,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) // if this variable has already been declared as an input, check the // sizes match if it already had an explicit size if (variable.arg && variable.explicitly_sized && variable.val.size() != width) { - log_file_error(filename, location.first_line, "Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str()); + input_error("Incompatible re-declaration of constant function wire %s.\n", stmt->str.c_str()); } variable.val = RTLIL::Const(RTLIL::State::Sx, width); variable.offset = stmt->range_swapped ? stmt->range_left : stmt->range_right; @@ -5468,21 +5464,21 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (stmt->children.at(1)->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here. X\n", + stmt->input_error("Non-constant expression in constant function\n%s: ... called from here. X\n", fcall->loc_string().c_str()); } if (stmt->children.at(0)->type != AST_IDENTIFIER) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Unsupported composite left hand side in constant function\n%s: ... called from here.\n", + stmt->input_error("Unsupported composite left hand side in constant function\n%s: ... called from here.\n", fcall->loc_string().c_str()); } if (!variables.count(stmt->children.at(0)->str)) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Assignment to non-local variable in constant function\n%s: ... called from here.\n", + stmt->input_error("Assignment to non-local variable in constant function\n%s: ... called from here.\n", fcall->loc_string().c_str()); } @@ -5493,8 +5489,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (!range->range_valid) { if (!must_succeed) goto finished; - log_file_error(range->filename, range->location.first_line, "Non-constant range\n%s: ... called from here.\n", - fcall->loc_string().c_str()); + range->input_error("Non-constant range\n%s: ... called from here.\n", fcall->loc_string().c_str()); } int offset = min(range->range_left, range->range_right); int width = std::abs(range->range_left - range->range_right) + 1; @@ -5533,7 +5528,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (cond->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n", + stmt->input_error("Non-constant expression in constant function\n%s: ... called from here.\n", fcall->loc_string().c_str()); } @@ -5558,7 +5553,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (num->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n", + stmt->input_error("Non-constant expression in constant function\n%s: ... called from here.\n", fcall->loc_string().c_str()); } @@ -5601,7 +5596,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (cond->type != AST_CONSTANT) { if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Non-constant expression in constant function\n%s: ... called from here.\n", + stmt->input_error("Non-constant expression in constant function\n%s: ... called from here.\n", fcall->loc_string().c_str()); } @@ -5637,7 +5632,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (!must_succeed) goto finished; - log_file_error(stmt->filename, stmt->location.first_line, "Unsupported language construct in constant function\n%s: ... called from here.\n", + stmt->input_error("Unsupported language construct in constant function\n%s: ... called from here.\n", fcall->loc_string().c_str()); log_abort(); } diff --git a/kernel/log.cc b/kernel/log.cc index 985165a97f0..d38d0c71731 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -378,14 +378,20 @@ void logv_error(const char *format, va_list ap) logv_error_with_prefix("ERROR: ", format, ap); } +void logv_file_error(const string &filename, int lineno, + const char *format, va_list ap) +{ + std::string prefix = stringf("%s:%d: ERROR: ", + filename.c_str(), lineno); + logv_error_with_prefix(prefix.c_str(), 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); + logv_file_error(filename, lineno, format, ap); } void log(const char *format, ...) diff --git a/kernel/log.h b/kernel/log.h index 3e4c2edfddd..78a2e434c7a 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -124,6 +124,7 @@ void logv_header(RTLIL::Design *design, const char *format, va_list ap); void logv_warning(const char *format, va_list ap); void logv_warning_noprefix(const char *format, va_list ap); [[noreturn]] void logv_error(const char *format, va_list ap); +[[noreturn]] void logv_file_error(const string &filename, int lineno, const char *format, va_list ap); 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)); From 4fceeb3b321d4976cffddc29360da3783dd61c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 21 Jun 2023 13:45:42 +0200 Subject: [PATCH 184/303] ast/simplify: Use clone_at_zero() for "at_zero" evaluations The correct way of using the 'at_zero' regime of simplify is to perform the simplification on a cloned AST subtree, otherwise the "at_zero" evaluation seeps into the main tree. Move the effect of the 'at_zero' flag to the cloning itself, so that the simplify flag can be retired. We assume we can rely on id2ast in the new clone method. --- frontends/ast/ast.h | 4 +++ frontends/ast/genrtlil.cc | 16 +++++------ frontends/ast/simplify.cc | 58 +++++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 0c0e8a3bc3b..f42a8c16cf5 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -336,6 +336,10 @@ namespace AST // Helper for looking up identifiers which are prefixed with the current module name std::string try_pop_module_prefix() const; + // helper to clone the node with some of its subexpressions replaced with zero (this is used + // to evaluate widths of dynamic ranges) + AstNode *clone_at_zero(); + // helper to print errors from simplify/genrtlil code [[noreturn]] void input_error(const char *format, ...) const YS_ATTRIBUTE(format(printf, 2, 3)); }; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 65251431240..ba75ee97f1a 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -887,10 +887,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun if (range->children.size() == 1) this_width = 1; else if (!range->range_valid) { - AstNode *left_at_zero_ast = children[0]->children[0]->clone(); - AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + AstNode *left_at_zero_ast = children[0]->children[0]->clone_at_zero(); + AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone(); + while (left_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; @@ -1460,10 +1460,10 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } if (!children[0]->range_valid) { - AstNode *left_at_zero_ast = children[0]->children[0]->clone(); - AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) { } + AstNode *left_at_zero_ast = children[0]->children[0]->clone_at_zero(); + AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone(); + while (left_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 6a2c190e09a..882dde296ec 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -773,6 +773,44 @@ static IdentUsage always_asgn_before_use(const AstNode *node, const std::string return IdentUsage::NotReferenced; } +AstNode *AstNode::clone_at_zero() +{ + int width_hint; + bool sign_hint; + AstNode *pointee; + + switch (type) { + case AST_IDENTIFIER: + if (id2ast) + pointee = id2ast; + else if (current_scope.count(str)) + pointee = current_scope[str]; + else + break; + + if (pointee->type != AST_WIRE && + pointee->type != AST_AUTOWIRE && + pointee->type != AST_MEMORY) + break; + + YS_FALLTHROUGH; + case AST_MEMRD: + detectSignWidth(width_hint, sign_hint); + return mkconst_int(0, sign_hint, width_hint); + + default: + break; + } + + AstNode *that = new AstNode; + *that = *this; + for (auto &it : that->children) + it = it->clone_at_zero(); + for (auto &it : that->attributes) + it.second = it.second->clone(); + return that; +} + static bool try_determine_range_width(AstNode *range, int &result_width) { log_assert(range->type == AST_RANGE); @@ -782,11 +820,11 @@ static bool try_determine_range_width(AstNode *range, int &result_width) return true; } - AstNode *left_at_zero_ast = range->children[0]->clone(); - AstNode *right_at_zero_ast = range->children[1]->clone(); + AstNode *left_at_zero_ast = range->children[0]->clone_at_zero(); + AstNode *right_at_zero_ast = range->children[1]->clone_at_zero(); - while (left_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) {} - while (right_at_zero_ast->simplify(true, true, false, 1, -1, false, false)) {} + while (left_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) {} + while (right_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) {} bool ok = false; if (left_at_zero_ast->type == AST_CONSTANT @@ -873,6 +911,8 @@ static void check_auto_nosync(AstNode *node) // nodes that link to a different node using names and lexical scoping. bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param) { + log_assert(!at_zero); + static int recursion_counter = 0; static bool deep_recursion_warning = false; @@ -4202,16 +4242,6 @@ replace_fcall_later:; if (current_scope[str]->children[0]->isConst()) newNode = current_scope[str]->children[0]->clone(); } - else if (at_zero && current_scope.count(str) > 0) { - AstNode *node = current_scope[str]; - if (node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY) - newNode = mkconst_int(0, sign_hint, width_hint); - } - break; - case AST_MEMRD: - if (at_zero) { - newNode = mkconst_int(0, sign_hint, width_hint); - } break; case AST_BIT_NOT: if (children[0]->type == AST_CONSTANT) { From 72a4022a1056febb9c2abd2605731a8cdc44f764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 4 Apr 2023 22:53:01 +0200 Subject: [PATCH 185/303] ast/simplify: Retire 'at_zero' flag Now that all the callsites pass in 'false' for the flag (or propagate the flag on recursion), we can retire it. --- frontends/ast/ast.cc | 4 +- frontends/ast/ast.h | 2 +- frontends/ast/genrtlil.cc | 26 +++--- frontends/ast/simplify.cc | 188 +++++++++++++++++++------------------- 4 files changed, 109 insertions(+), 111 deletions(-) diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index a900731a4b2..a027295e979 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1061,7 +1061,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d // simplify this module or interface using the current design as context // for lookup up ports and wires within cells set_simplify_design_context(design); - while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { } + while (ast->simplify(!flag_noopt, false, 0, -1, false, false)) { } set_simplify_design_context(nullptr); if (flag_dump_ast2) { @@ -1361,7 +1361,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } else if (child->type == AST_PACKAGE) { // process enum/other declarations - child->simplify(true, false, false, 1, -1, false, false); + child->simplify(true, false, 1, -1, false, false); rename_in_package_stmts(child); design->verilog_packages.push_back(child->clone()); current_scope.clear(); diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index f42a8c16cf5..8893d5e010c 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -250,7 +250,7 @@ namespace AST // simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc. // it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL() - bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); + bool simplify(bool const_fold, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param); void replace_result_wire_name_in_function(const std::string &from, const std::string &to); AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init); void expand_genblock(const std::string &prefix); diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index ba75ee97f1a..3aa19b70687 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -179,7 +179,7 @@ struct AST_INTERNAL::LookaheadRewriter wire->str = stringf("$lookahead%s$%d", node->str.c_str(), autoidx++); wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false); wire->is_logic = true; - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } current_ast_mod->children.push_back(wire); lookaheadids[node->str] = make_pair(node->id2ast, wire); wire->genRTLIL(); @@ -845,7 +845,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun this_width = id_ast->children[1]->range_left - id_ast->children[1]->range_right + 1; } else { if (id_ast->children[0]->type != AST_CONSTANT) - while (id_ast->simplify(true, false, false, 1, -1, false, true)) { } + while (id_ast->simplify(true, false, 1, -1, false, true)) { } if (id_ast->children[0]->type == AST_CONSTANT) this_width = id_ast->children[0]->bits.size(); else @@ -889,8 +889,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun else if (!range->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone_at_zero(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } - while (right_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } + while (left_at_zero_ast->simplify(true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); this_width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; @@ -906,7 +906,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_TO_BITS: - while (children[0]->simplify(true, false, false, 1, -1, false, false) == true) { } + while (children[0]->simplify(true, false, 1, -1, false, false) == true) { } if (children[0]->type != AST_CONSTANT) input_error("Left operand of tobits expression is not constant!\n"); children[1]->detectSignWidthWorker(sub_width_hint, sign_hint); @@ -928,7 +928,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_CAST_SIZE: - while (children.at(0)->simplify(true, false, false, 1, -1, false, false)) { } + while (children.at(0)->simplify(true, false, 1, -1, false, false)) { } if (children.at(0)->type != AST_CONSTANT) input_error("Static cast with non constant expression!\n"); children.at(1)->detectSignWidthWorker(width_hint, sign_hint); @@ -950,7 +950,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun break; case AST_REPLICATE: - while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { } + while (children[0]->simplify(true, false, 1, -1, false, true) == true) { } if (children[0]->type != AST_CONSTANT) input_error("Left operand of replicate expression is not constant!\n"); children[1]->detectSignWidthWorker(sub_width_hint, sub_sign_hint); @@ -1062,7 +1062,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_PREFIX: // Prefix nodes always resolve to identifiers in generate loops, so we // can simply perform the resolution to determine the sign and width. - simplify(true, false, false, 1, -1, false, false); + simplify(true, false, 1, -1, false, false); log_assert(type == AST_IDENTIFIER); detectSignWidthWorker(width_hint, sign_hint, found_real); break; @@ -1070,7 +1070,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_FCALL: if (str == "\\$anyconst" || str == "\\$anyseq" || str == "\\$allconst" || str == "\\$allseq") { if (GetSize(children) == 1) { - while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { } + while (children[0]->simplify(true, false, 1, -1, false, true) == true) { } if (children[0]->type != AST_CONSTANT) input_error("System function %s called with non-const argument!\n", RTLIL::unescape_id(str).c_str()); @@ -1117,8 +1117,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun log_assert(range->type == AST_RANGE && range->children.size() == 2); AstNode *left = range->children.at(0)->clone(); AstNode *right = range->children.at(1)->clone(); - while (left->simplify(true, false, false, 1, -1, false, true)) { } - while (right->simplify(true, false, false, 1, -1, false, true)) { } + while (left->simplify(true, false, 1, -1, false, true)) { } + while (right->simplify(true, false, 1, -1, false, true)) { } if (left->type != AST_CONSTANT || right->type != AST_CONSTANT) input_error("Function %s has non-constant width!", RTLIL::unescape_id(str).c_str()); @@ -1462,8 +1462,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (!children[0]->range_valid) { AstNode *left_at_zero_ast = children[0]->children[0]->clone_at_zero(); AstNode *right_at_zero_ast = children[0]->children.size() >= 2 ? children[0]->children[1]->clone_at_zero() : left_at_zero_ast->clone(); - while (left_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } - while (right_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) { } + while (left_at_zero_ast->simplify(true, false, 1, -1, false, false)) { } + while (right_at_zero_ast->simplify(true, false, 1, -1, false, false)) { } if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 882dde296ec..3a2955de27a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -99,7 +99,7 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg cformat, str.c_str()); node_arg = children[next_arg++]; - while (node_arg->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_arg->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_arg->type != AST_CONSTANT) input_error("Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); break; @@ -192,7 +192,7 @@ void AstNode::annotateTypedEnums(AstNode *template_node) log_assert(current_scope.count(enum_type) == 1); AstNode *enum_node = current_scope.at(enum_type); log_assert(enum_node->type == AST_ENUM); - while (enum_node->simplify(true, false, false, 1, -1, false, true)) { } + while (enum_node->simplify(true, false, 1, -1, false, true)) { } //get width from 1st enum item: log_assert(enum_node->children.size() >= 1); AstNode *enum_item0 = enum_node->children[0]; @@ -823,8 +823,8 @@ static bool try_determine_range_width(AstNode *range, int &result_width) AstNode *left_at_zero_ast = range->children[0]->clone_at_zero(); AstNode *right_at_zero_ast = range->children[1]->clone_at_zero(); - while (left_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) {} - while (right_at_zero_ast->simplify(true, false, false, 1, -1, false, false)) {} + while (left_at_zero_ast->simplify(true, false, 1, -1, false, false)) {} + while (right_at_zero_ast->simplify(true, false, 1, -1, false, false)) {} bool ok = false; if (left_at_zero_ast->type == AST_CONSTANT @@ -909,10 +909,8 @@ static void check_auto_nosync(AstNode *node) // // this function also does all name resolving and sets the id2ast member of all // nodes that link to a different node using names and lexical scoping. -bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param) +bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param) { - log_assert(!at_zero); - static int recursion_counter = 0; static bool deep_recursion_warning = false; @@ -929,8 +927,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, #if 0 log("-------------\n"); log("AST simplify[%d] depth %d at %s:%d on %s %p:\n", stage, recursion_counter, filename.c_str(), location.first_line, type2str(type).c_str(), this); - log("const_fold=%d, at_zero=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n", - int(const_fold), int(at_zero), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param)); + log("const_fold=%d, in_lvalue=%d, stage=%d, width_hint=%d, sign_hint=%d, in_param=%d\n", + int(const_fold), int(in_lvalue), int(stage), int(width_hint), int(sign_hint), int(in_param)); // dumpAst(NULL, "> "); #endif @@ -939,7 +937,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_assert(type == AST_MODULE || type == AST_INTERFACE); deep_recursion_warning = true; - while (simplify(const_fold, at_zero, in_lvalue, 1, width_hint, sign_hint, in_param)) { } + while (simplify(const_fold, in_lvalue, 1, width_hint, sign_hint, in_param)) { } if (!flag_nomem2reg && !get_bool_attribute(ID::nomem2reg)) { @@ -1022,7 +1020,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->filename = node->filename; reg->location = node->location; children.push_back(reg); - while (reg->simplify(true, false, false, 1, -1, false, false)) { } + while (reg->simplify(true, false, 1, -1, false, false)) { } } } @@ -1036,7 +1034,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, delete node; } - while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { } + while (simplify(const_fold, in_lvalue, 2, width_hint, sign_hint, in_param)) { } recursion_counter--; return false; } @@ -1077,7 +1075,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // First argument is the format string AstNode *node_string = children[0]; - while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_string->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_string->type != AST_CONSTANT) input_error("Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); std::string sformat = node_string->bitsAsConst().decode_string(); @@ -1202,12 +1200,12 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (size_t i = 0; i < children.size(); i++) { AstNode *node = children[i]; if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF) - while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) + while (node->simplify(true, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM)) did_something = true; if (node->type == AST_ENUM) { for (auto enode : node->children){ log_assert(enode->type==AST_ENUM_ITEM); - while (node->simplify(true, false, false, 1, -1, false, in_param)) + while (node->simplify(true, false, 1, -1, false, in_param)) did_something = true; } } @@ -1272,7 +1270,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, for (AstNode *child : children) { // simplify any parameters to constants if (child->type == AST_PARASET) - while (child->simplify(true, false, false, 1, -1, false, true)) { } + while (child->simplify(true, false, 1, -1, false, true)) { } // look for patterns which _may_ indicate ambiguity requiring // resolution of the underlying module @@ -1386,9 +1384,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, case AST_ASSIGN_EQ: case AST_ASSIGN_LE: case AST_ASSIGN: - while (!children[0]->basic_prep && children[0]->simplify(false, false, true, stage, -1, false, in_param) == true) + while (!children[0]->basic_prep && children[0]->simplify(false, true, stage, -1, false, in_param) == true) did_something = true; - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param) == true) + while (!children[1]->basic_prep && children[1]->simplify(false, false, stage, -1, false, in_param) == true) did_something = true; children[0]->detectSignWidth(backup_width_hint, backup_sign_hint); children[1]->detectSignWidth(width_hint, sign_hint); @@ -1424,7 +1422,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (!basic_prep) { for (auto *node : children) { // resolve any ranges - while (!node->basic_prep && node->simplify(true, false, false, stage, -1, false, false)) { + while (!node->basic_prep && node->simplify(true, false, stage, -1, false, false)) { did_something = true; } } @@ -1503,7 +1501,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, //log("\nENUM %s: %d child %d\n", str.c_str(), basic_prep, children[0]->basic_prep); if (!basic_prep) { for (auto item_node : children) { - while (!item_node->basic_prep && item_node->simplify(false, false, false, stage, -1, false, in_param)) + while (!item_node->basic_prep && item_node->simplify(false, false, stage, -1, false, in_param)) did_something = true; } // allocate values (called more than once) @@ -1523,11 +1521,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, add_members_to_scope(attributes[ID::wiretype], str); } } - while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) + while (!children[0]->basic_prep && children[0]->simplify(false, false, stage, -1, false, true) == true) did_something = true; children[0]->detectSignWidth(width_hint, sign_hint); if (children.size() > 1 && children[1]->type == AST_RANGE) { - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, true) == true) + while (!children[1]->basic_prep && children[1]->simplify(false, false, stage, -1, false, true) == true) did_something = true; if (!children[1]->range_valid) input_error("Non-constant width range on parameter decl.\n"); @@ -1535,11 +1533,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } break; case AST_ENUM_ITEM: - while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, in_param)) + while (!children[0]->basic_prep && children[0]->simplify(false, false, stage, -1, false, in_param)) did_something = true; children[0]->detectSignWidth(width_hint, sign_hint); if (children.size() > 1 && children[1]->type == AST_RANGE) { - while (!children[1]->basic_prep && children[1]->simplify(false, false, false, stage, -1, false, in_param)) + while (!children[1]->basic_prep && children[1]->simplify(false, false, stage, -1, false, in_param)) did_something = true; if (!children[1]->range_valid) input_error("Non-constant width range on enum item decl.\n"); @@ -1598,7 +1596,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint = -1; sign_hint = true; for (auto child : children) { - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) + while (!child->basic_prep && child->simplify(false, in_lvalue, stage, -1, false, in_param) == true) did_something = true; child->detectSignWidthWorker(width_hint, sign_hint); } @@ -1633,10 +1631,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (detect_width_simple && width_hint < 0) { if (type == AST_REPLICATE) - while (children[0]->simplify(true, false, in_lvalue, stage, -1, false, true) == true) + while (children[0]->simplify(true, in_lvalue, stage, -1, false, true) == true) did_something = true; for (auto child : children) - while (!child->basic_prep && child->simplify(false, false, in_lvalue, stage, -1, false, in_param) == true) + while (!child->basic_prep && child->simplify(false, in_lvalue, stage, -1, false, in_param) == true) did_something = true; detectSignWidth(width_hint, sign_hint); } @@ -1646,18 +1644,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_TERNARY) { if (width_hint < 0) { - while (!children[0]->basic_prep && children[0]->simplify(true, false, in_lvalue, stage, -1, false, in_param)) + while (!children[0]->basic_prep && children[0]->simplify(true, in_lvalue, stage, -1, false, in_param)) did_something = true; bool backup_unevaluated_tern_branch = unevaluated_tern_branch; AstNode *chosen = get_tern_choice().first; unevaluated_tern_branch = backup_unevaluated_tern_branch || chosen == children[2]; - while (!children[1]->basic_prep && children[1]->simplify(false, false, in_lvalue, stage, -1, false, in_param)) + while (!children[1]->basic_prep && children[1]->simplify(false, in_lvalue, stage, -1, false, in_param)) did_something = true; unevaluated_tern_branch = backup_unevaluated_tern_branch || chosen == children[1]; - while (!children[2]->basic_prep && children[2]->simplify(false, false, in_lvalue, stage, -1, false, in_param)) + while (!children[2]->basic_prep && children[2]->simplify(false, in_lvalue, stage, -1, false, in_param)) did_something = true; unevaluated_tern_branch = backup_unevaluated_tern_branch; @@ -1689,7 +1687,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (const_fold && type == AST_CASE) { detectSignWidth(width_hint, sign_hint); - while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { } + while (children[0]->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param)) { } if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) { children[0]->is_signed = sign_hint; RTLIL::Const case_expr = children[0]->bitsAsConst(width_hint, sign_hint); @@ -1703,7 +1701,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, goto keep_const_cond; if (v->type == AST_BLOCK) continue; - while (v->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { } + while (v->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param)) { } if (v->type == AST_CONSTANT && v->bits_only_01()) { RTLIL::Const case_item_expr = v->bitsAsConst(width_hint, sign_hint); RTLIL::Const match = const_eq(case_expr, case_item_expr, sign_hint, sign_hint, 1); @@ -1788,7 +1786,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, width_hint_here = -1, sign_hint_here = false; if (children_are_self_determined) width_hint_here = -1, sign_hint_here = false; - did_something_here = children[i]->simplify(const_fold_here, at_zero, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here); + did_something_here = children[i]->simplify(const_fold_here, in_lvalue_here, stage, width_hint_here, sign_hint_here, in_param_here); if (did_something_here) did_something = true; } @@ -1808,7 +1806,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } for (auto &attr : attributes) { - while (attr.second->simplify(true, false, false, stage, -1, false, true)) + while (attr.second->simplify(true, false, stage, -1, false, true)) did_something = true; } if (type == AST_CASE && stage == 2) { @@ -1886,7 +1884,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, log_assert(children.size() == 1); auto type_node = children[0]; log_assert(type_node->type == AST_WIRE || type_node->type == AST_MEMORY || type_node->type == AST_STRUCT || type_node->type == AST_UNION); - while (type_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { + while (type_node->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param)) { did_something = true; } log_assert(!type_node->is_custom_type); @@ -1908,7 +1906,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *template_node = resolved_type_node->children[0]; // Ensure typedef itself is fully simplified - while (template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; + while (template_node->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; if (!str.empty() && str[0] == '\\' && (template_node->type == AST_STRUCT || template_node->type == AST_UNION)) { // replace instance with wire representing the packed structure @@ -1973,7 +1971,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *template_node = resolved_type_node->children[0]; // Ensure typedef itself is fully simplified - while (template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; + while (template_node->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) { // replace with wire representing the packed structure @@ -2015,7 +2013,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, input_error("Index in generate block prefix syntax is not constant!\n"); } if (children[1]->type == AST_PREFIX) - children[1]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param); + children[1]->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param); log_assert(children[1]->type == AST_IDENTIFIER); newNode = children[1]->clone(); const char *second_part = children[1]->str.c_str(); @@ -2305,7 +2303,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (current_block) wire->attributes[ID::nosync] = AstNode::mkconst_int(1, false); current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } AstNode *data = clone(); delete data->children[1]; @@ -2347,7 +2345,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, AstNode *body = children[1]; // eval count expression - while (count->simplify(true, false, false, stage, 32, true, false)) { } + while (count->simplify(true, false, stage, 32, true, false)) { } if (count->type != AST_CONSTANT) input_error("Repeat loops outside must have constant repeat counts!\n"); @@ -2403,7 +2401,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int expr_width_hint = -1; bool expr_sign_hint = true; varbuf->detectSignWidth(expr_width_hint, expr_sign_hint); - while (varbuf->simplify(true, false, false, stage, 32, true, false)) { } + while (varbuf->simplify(true, false, stage, 32, true, false)) { } } if (varbuf->type != AST_CONSTANT) @@ -2444,7 +2442,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int expr_width_hint = -1; bool expr_sign_hint = true; buf->detectSignWidth(expr_width_hint, expr_sign_hint); - while (buf->simplify(true, false, false, stage, expr_width_hint, expr_sign_hint, false)) { } + while (buf->simplify(true, false, stage, expr_width_hint, expr_sign_hint, false)) { } } if (buf->type != AST_CONSTANT) @@ -2479,7 +2477,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENFOR) { for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false); + buf->children[i]->simplify(const_fold, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } } else { @@ -2495,7 +2493,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int expr_width_hint = -1; bool expr_sign_hint = true; buf->detectSignWidth(expr_width_hint, expr_sign_hint); - while (buf->simplify(true, false, false, stage, expr_width_hint, expr_sign_hint, true)) { } + while (buf->simplify(true, false, stage, expr_width_hint, expr_sign_hint, true)) { } } if (buf->type != AST_CONSTANT) @@ -2547,7 +2545,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, std::vector new_children; for (size_t i = 0; i < children.size(); i++) if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) { - children[i]->simplify(false, false, false, stage, -1, false, false); + children[i]->simplify(false, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); current_scope[children[i]->str] = children[i]; } else @@ -2566,7 +2564,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < children.size(); i++) { - children[i]->simplify(const_fold, false, false, stage, -1, false, false); + children[i]->simplify(const_fold, false, stage, -1, false, false); current_ast_mod->children.push_back(children[i]); } @@ -2578,7 +2576,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENIF && children.size() != 0) { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (buf->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -2602,7 +2600,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false); + buf->children[i]->simplify(const_fold, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -2618,7 +2616,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_GENCASE && children.size() != 0) { AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (buf->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -2652,7 +2650,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, continue; buf = child->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, true)) { } + while (buf->simplify(true, false, stage, width_hint, sign_hint, true)) { } if (buf->type != AST_CONSTANT) { // for (auto f : log_files) // dumpAst(f, "verilog-ast> "); @@ -2680,7 +2678,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } for (size_t i = 0; i < buf->children.size(); i++) { - buf->children[i]->simplify(const_fold, false, false, stage, -1, false, false); + buf->children[i]->simplify(const_fold, false, stage, -1, false, false); current_ast_mod->children.push_back(buf->children[i]); } @@ -2863,7 +2861,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (children[0]->id2ast->attributes.count(ID::nowrshmsk)) { AstNode *node = children[0]->id2ast->attributes.at(ID::nowrshmsk); - while (node->simplify(true, false, false, stage, -1, false, false)) { } + while (node->simplify(true, false, stage, -1, false, false)) { } if (node->type != AST_CONSTANT) input_error("Non-constant value for `nowrshmsk' attribute on `%s'!\n", children[0]->id2ast->str.c_str()); if (node->asAttrConst().as_bool()) @@ -2901,14 +2899,14 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, wire_mask->str = stringf("$bitselwrite$mask$%s:%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, autoidx++); wire_mask->attributes[ID::nosync] = AstNode::mkconst_int(1, false); wire_mask->is_logic = true; - while (wire_mask->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_mask->simplify(true, false, 1, -1, false, false)) { } current_ast_mod->children.push_back(wire_mask); AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(source_width-1, true), mkconst_int(0, true))); wire_data->str = stringf("$bitselwrite$data$%s:%d$%d", RTLIL::encode_filename(filename).c_str(), location.first_line, autoidx++); wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false); wire_data->is_logic = true; - while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_data->simplify(true, false, 1, -1, false, false)) { } current_ast_mod->children.push_back(wire_data); int shamt_width_hint = -1; @@ -2920,7 +2918,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, wire_sel->attributes[ID::nosync] = AstNode::mkconst_int(1, false); wire_sel->is_logic = true; wire_sel->is_signed = shamt_sign_hint; - while (wire_sel->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_sel->simplify(true, false, 1, -1, false, false)) { } current_ast_mod->children.push_back(wire_sel); did_something = true; @@ -3003,7 +3001,7 @@ skip_dynamic_range_lvalue_expansion:; wire_check->was_checked = true; current_ast_mod->children.push_back(wire_check); current_scope[wire_check->str] = wire_check; - while (wire_check->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_check->simplify(true, false, 1, -1, false, false)) { } AstNode *wire_en = new AstNode(AST_WIRE); wire_en->str = id_en; @@ -3015,7 +3013,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.back()->children[0]->children[0]->children[0]->was_checked = true; } current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_en->simplify(true, false, 1, -1, false, false)) { } AstNode *check_defval; if (type == AST_LIVE || type == AST_FAIR) { @@ -3108,7 +3106,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(wire_tmp); current_scope[wire_tmp->str] = wire_tmp; wire_tmp->attributes[ID::nosync] = AstNode::mkconst_int(1, false); - while (wire_tmp->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_tmp->simplify(true, false, 1, -1, false, false)) { } wire_tmp->is_logic = true; AstNode *wire_tmp_id = new AstNode(AST_IDENTIFIER); @@ -3178,7 +3176,7 @@ skip_dynamic_range_lvalue_expansion:; wire_addr->was_checked = true; current_ast_mod->children.push_back(wire_addr); current_scope[wire_addr->str] = wire_addr; - while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_addr->simplify(true, false, 1, -1, false, false)) { } AstNode *assign_addr = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_addr, false)); assign_addr->children[0]->str = id_addr; @@ -3204,7 +3202,7 @@ skip_dynamic_range_lvalue_expansion:; wire_data->is_signed = mem_signed; current_ast_mod->children.push_back(wire_data); current_scope[wire_data->str] = wire_data; - while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_data->simplify(true, false, 1, -1, false, false)) { } AstNode *assign_data = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_bits(x_bits_data, false)); assign_data->children[0]->str = id_data; @@ -3220,7 +3218,7 @@ skip_dynamic_range_lvalue_expansion:; wire_en->was_checked = true; current_ast_mod->children.push_back(wire_en); current_scope[wire_en->str] = wire_en; - while (wire_en->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_en->simplify(true, false, 1, -1, false, false)) { } AstNode *assign_en_first = new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER), mkconst_int(0, false, mem_width)); assign_en_first->children[0]->str = id_en; @@ -3348,7 +3346,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *wire = new AstNode(AST_WIRE); wire->str = stringf("$initstate$%d_wire", myidx); current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } AstNode *cell = new AstNode(AST_CELL, new AstNode(AST_CELLTYPE), new AstNode(AST_ARGUMENT, new AstNode(AST_IDENTIFIER))); cell->str = stringf("$initstate$%d", myidx); @@ -3357,7 +3355,7 @@ skip_dynamic_range_lvalue_expansion:; cell->children[1]->children[0]->str = wire->str; cell->children[1]->children[0]->id2ast = wire; current_ast_mod->children.push_back(cell); - while (cell->simplify(true, false, false, 1, -1, false, false)) { } + while (cell->simplify(true, false, 1, -1, false, false)) { } newNode = new AstNode(AST_IDENTIFIER); newNode->str = wire->str; @@ -3383,7 +3381,7 @@ skip_dynamic_range_lvalue_expansion:; if (GetSize(children) == 2) { AstNode *buf = children[1]->clone(); - while (buf->simplify(true, false, false, stage, -1, false, false)) { } + while (buf->simplify(true, false, stage, -1, false, false)) { } if (buf->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); @@ -3418,7 +3416,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(reg); - while (reg->simplify(true, false, false, 1, -1, false, false)) { } + while (reg->simplify(true, false, 1, -1, false, false)) { } AstNode *regid = new AstNode(AST_IDENTIFIER); regid->str = reg->str; @@ -3494,7 +3492,7 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::unescape_id(str).c_str(), int(children.size())); AstNode *buf = children[0]->clone(); - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (buf->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (buf->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant value.\n", str.c_str()); @@ -3526,7 +3524,7 @@ skip_dynamic_range_lvalue_expansion:; if (children.size() == 2) { AstNode *buf = children[1]->clone(); // Evaluate constant expression - while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (buf->simplify(true, false, stage, width_hint, sign_hint, false)) { } dim = buf->asInt(false); delete buf; } @@ -3537,7 +3535,7 @@ skip_dynamic_range_lvalue_expansion:; AstNode *id_ast = NULL; // Is this needed? - //while (buf->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + //while (buf->simplify(true, false, stage, width_hint, sign_hint, false)) { } buf->detectSignWidth(width_hint, sign_hint); if (buf->type == AST_IDENTIFIER) { @@ -3684,7 +3682,7 @@ skip_dynamic_range_lvalue_expansion:; } if (children.size() >= 1) { - while (children[0]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (children[0]->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (!children[0]->isConst()) input_error("Failed to evaluate system function `%s' with non-constant argument.\n", RTLIL::unescape_id(str).c_str()); @@ -3695,7 +3693,7 @@ skip_dynamic_range_lvalue_expansion:; } if (children.size() >= 2) { - while (children[1]->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (children[1]->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (!children[1]->isConst()) input_error("Failed to evaluate system function `%s' with non-constant argument.\n", RTLIL::unescape_id(str).c_str()); @@ -3738,7 +3736,7 @@ skip_dynamic_range_lvalue_expansion:; if (str == "\\$sformatf") { AstNode *node_string = children[0]; - while (node_string->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_string->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_string->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); std::string sformat = node_string->bitsAsConst().decode_string(); @@ -3757,7 +3755,7 @@ skip_dynamic_range_lvalue_expansion:; // Determine which bits to count for (size_t i = 1; i < children.size(); i++) { AstNode *node = children[i]; - while (node->simplify(true, false, false, stage, -1, false, false)) { } + while (node->simplify(true, false, stage, -1, false, false)) { } if (node->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant control bit argument.\n", str.c_str()); if (node->bits.size() != 1) @@ -3852,7 +3850,7 @@ skip_dynamic_range_lvalue_expansion:; argtypes.push_back(RTLIL::unescape_id(dpi_decl->children.at(i)->str)); args.push_back(children.at(i-2)->clone()); - while (args.back()->simplify(true, false, false, stage, -1, false, true)) { } + while (args.back()->simplify(true, false, stage, -1, false, true)) { } if (args.back()->type != AST_CONSTANT && args.back()->type != AST_REALVALUE) input_error("Failed to evaluate DPI function with non-constant argument.\n"); @@ -3889,12 +3887,12 @@ skip_dynamic_range_lvalue_expansion:; RTLIL::unescape_id(str).c_str(), int(children.size())); AstNode *node_filename = children[0]->clone(); - while (node_filename->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_filename->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_filename->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); AstNode *node_memory = children[1]->clone(); - while (node_memory->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_memory->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_memory->type != AST_IDENTIFIER || node_memory->id2ast == nullptr || node_memory->id2ast->type != AST_MEMORY) input_error("Failed to evaluate system function `%s' with non-memory 2nd argument.\n", str.c_str()); @@ -3902,7 +3900,7 @@ skip_dynamic_range_lvalue_expansion:; if (GetSize(children) > 2) { AstNode *node_addr = children[2]->clone(); - while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_addr->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_addr->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant 3rd argument.\n", str.c_str()); start_addr = int(node_addr->asInt(false)); @@ -3910,7 +3908,7 @@ skip_dynamic_range_lvalue_expansion:; if (GetSize(children) > 3) { AstNode *node_addr = children[3]->clone(); - while (node_addr->simplify(true, false, false, stage, width_hint, sign_hint, false)) { } + while (node_addr->simplify(true, false, stage, width_hint, sign_hint, false)) { } if (node_addr->type != AST_CONSTANT) input_error("Failed to evaluate system function `%s' with non-constant 4th argument.\n", str.c_str()); finish_addr = int(node_addr->asInt(false)); @@ -3962,7 +3960,7 @@ skip_dynamic_range_lvalue_expansion:; bool require_const_eval = decl->has_const_only_constructs(); bool all_args_const = true; for (auto child : children) { - while (child->simplify(true, false, false, 1, -1, false, true)) { } + while (child->simplify(true, false, 1, -1, false, true)) { } if (child->type != AST_CONSTANT && child->type != AST_REALVALUE) all_args_const = false; } @@ -4006,7 +4004,7 @@ skip_dynamic_range_lvalue_expansion:; current_scope[wire->str] = wire; current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } AstNode *lvalue = new AstNode(AST_IDENTIFIER); lvalue->str = wire->str; @@ -4052,7 +4050,7 @@ skip_dynamic_range_lvalue_expansion:; wire->is_input = false; wire->is_output = false; current_ast_mod->children.push_back(wire); - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } AstNode *wire_id = new AstNode(AST_IDENTIFIER); wire_id->str = wire->str; @@ -4095,7 +4093,7 @@ skip_dynamic_range_lvalue_expansion:; for (auto c : child->children) wire->children.push_back(c->clone()); } else if (!child->children.empty()) { - while (child->simplify(true, false, false, stage, -1, false, false)) { } + while (child->simplify(true, false, stage, -1, false, false)) { } if (GetSize(child->children) == GetSize(wire->children) - contains_value) { for (int i = 0; i < GetSize(child->children); i++) if (*child->children.at(i) != *wire->children.at(i + contains_value)) @@ -4123,7 +4121,7 @@ skip_dynamic_range_lvalue_expansion:; current_ast_mod->children.push_back(wire); } - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } if ((child->is_input || child->is_output) && arg_count < children.size()) { @@ -4155,7 +4153,7 @@ skip_dynamic_range_lvalue_expansion:; } } // updates the sizing - while (wire->simplify(true, false, false, 1, -1, false, false)) { } + while (wire->simplify(true, false, 1, -1, false, false)) { } delete arg; continue; } @@ -5065,7 +5063,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, wire_addr->was_checked = true; wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_addr); - while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_addr->simplify(true, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; @@ -5074,7 +5072,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, wire_data->is_signed = mem_signed; wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_data); - while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_data->simplify(true, false, 1, -1, false, false)) { } log_assert(block != NULL); size_t assign_idx = 0; @@ -5182,7 +5180,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, if (block) wire_addr->attributes[ID::nosync] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_addr); - while (wire_addr->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_addr->simplify(true, false, 1, -1, false, false)) { } AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true))); wire_data->str = id_data; @@ -5192,7 +5190,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, if (block) wire_data->attributes[ID::nosync] = AstNode::mkconst_int(1, false); mod->children.push_back(wire_data); - while (wire_data->simplify(true, false, false, 1, -1, false, false)) { } + while (wire_data->simplify(true, false, 1, -1, false, false)) { } AstNode *assign_addr = new AstNode(block ? AST_ASSIGN_EQ : AST_ASSIGN, new AstNode(AST_IDENTIFIER), children[0]->children[0]->clone()); assign_addr->children[0]->str = id_addr; @@ -5370,7 +5368,7 @@ bool AstNode::replace_variables(std::map &varia } if (!children.at(0)->replace_variables(variables, fcall, must_succeed)) return false; - while (simplify(true, false, false, 1, -1, false, true)) { } + while (simplify(true, false, 1, -1, false, true)) { } if (!children.at(0)->range_valid) { if (!must_succeed) return false; @@ -5425,7 +5423,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (stmt->type == AST_WIRE) { - while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + while (stmt->simplify(true, false, 1, -1, false, true)) { } if (!stmt->range_valid) { if (!must_succeed) goto finished; @@ -5469,7 +5467,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) if (stmt->type == AST_LOCALPARAM) { - while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + while (stmt->simplify(true, false, 1, -1, false, true)) { } current_scope[stmt->str] = stmt; @@ -5486,7 +5484,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) goto finished; if (!stmt->children.at(1)->replace_variables(variables, fcall, must_succeed)) goto finished; - while (stmt->simplify(true, false, false, 1, -1, false, true)) { } + while (stmt->simplify(true, false, 1, -1, false, true)) { } if (stmt->type != AST_ASSIGN_EQ) continue; @@ -5553,7 +5551,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) AstNode *cond = stmt->children.at(0)->clone(); if (!cond->replace_variables(variables, fcall, must_succeed)) goto finished; - while (cond->simplify(true, false, false, 1, -1, false, true)) { } + while (cond->simplify(true, false, 1, -1, false, true)) { } if (cond->type != AST_CONSTANT) { if (!must_succeed) @@ -5578,7 +5576,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) AstNode *num = stmt->children.at(0)->clone(); if (!num->replace_variables(variables, fcall, must_succeed)) goto finished; - while (num->simplify(true, false, false, 1, -1, false, true)) { } + while (num->simplify(true, false, 1, -1, false, true)) { } if (num->type != AST_CONSTANT) { if (!must_succeed) @@ -5601,7 +5599,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) AstNode *expr = stmt->children.at(0)->clone(); if (!expr->replace_variables(variables, fcall, must_succeed)) goto finished; - while (expr->simplify(true, false, false, 1, -1, false, true)) { } + while (expr->simplify(true, false, 1, -1, false, true)) { } AstNode *sel_case = NULL; for (size_t i = 1; i < stmt->children.size(); i++) @@ -5621,7 +5619,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall, bool must_succeed) goto finished; cond = new AstNode(AST_EQ, expr->clone(), cond); - while (cond->simplify(true, false, false, 1, -1, false, true)) { } + while (cond->simplify(true, false, 1, -1, false, true)) { } if (cond->type != AST_CONSTANT) { if (!must_succeed) From d5d2bf815ae73cd9e003196e0b880e98b42caa1a Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 21 Jul 2023 00:08:10 -0400 Subject: [PATCH 186/303] Fix semantic merge conflict in previous two merged PRs --- frontends/ast/simplify.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 3a2955de27a..64191cd7ebf 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1455,7 +1455,7 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin AstNode *template_node = resolved_type_node->children[0]; // Ensure typedef itself is fully simplified - while (template_node->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; + while (template_node->simplify(const_fold, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; // Remove type reference delete children[0]; From c023b9485a5a6ba336fa6d96a3412840955892bb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 22 Jul 2023 00:17:24 +0000 Subject: [PATCH 187/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a28713c69d4..8f6430bee7a 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+6 +YOSYS_VER := 0.31+13 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 411b6e98cd05ef98611b5c696470330a93fa3b21 Mon Sep 17 00:00:00 2001 From: Catherine Date: Sat, 22 Jul 2023 21:47:03 +0000 Subject: [PATCH 188/303] abc, abc9_exe: respect `-q` when built with linked ABC. This is mostly important for YoWASP builds, since those do not have a way to build with external ABC (I prototyped it but for some reason ABC always segfaults when built as an independent Wasm binary...) --- passes/techmap/abc.cc | 16 +++++++++++++++- passes/techmap/abc9_exe.cc | 16 +++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index da601a85606..182e26c2f83 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1091,10 +1091,17 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); -#ifndef YOSYS_LINK_ABC abc_output_filter filt(tempdir_name, show_tempdir); +#ifndef YOSYS_LINK_ABC int ret = run_command(buffer, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1)); #else + string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name.c_str()); + FILE *temp_stdouterr_w = fopen(temp_stdouterr_name.c_str(), "w"); + if (temp_stdouterr_w == NULL) + log_error("ABC: cannot open a temporary file for output redirection"); + FILE *old_stdout = stdout; + FILE *old_stderr = stderr; + stdout = stderr = temp_stdouterr_w; // These needs to be mutable, supposedly due to getopt char *abc_argv[5]; string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); @@ -1108,6 +1115,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin free(abc_argv[1]); free(abc_argv[2]); free(abc_argv[3]); + stdout = old_stdout; + stderr = old_stderr; + fclose(temp_stdouterr_w); + std::ifstream temp_stdouterr_r(temp_stdouterr_name); + for (std::string line; std::getline(temp_stdouterr_r, line); ) + filt.next_line(line + "\n"); + temp_stdouterr_r.close(); #endif if (ret != 0) log_error("ABC: execution of command \"%s\" failed: return code %d.\n", buffer.c_str(), ret); diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index 1d9bb433211..449b5b129af 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -267,10 +267,17 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); -#ifndef YOSYS_LINK_ABC abc9_output_filter filt(tempdir_name, show_tempdir); +#ifndef YOSYS_LINK_ABC int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); #else + string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name.c_str()); + FILE *temp_stdouterr_w = fopen(temp_stdouterr_name.c_str(), "w"); + if (temp_stdouterr_w == NULL) + log_error("ABC: cannot open a temporary file for output redirection"); + FILE *old_stdout = stdout; + FILE *old_stderr = stderr; + stdout = stderr = temp_stdouterr_w; // These needs to be mutable, supposedly due to getopt char *abc9_argv[5]; string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); @@ -284,6 +291,13 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe free(abc9_argv[1]); free(abc9_argv[2]); free(abc9_argv[3]); + stdout = old_stdout; + stderr = old_stderr; + fclose(temp_stdouterr_w); + std::ifstream temp_stdouterr_r(temp_stdouterr_name); + for (std::string line; std::getline(temp_stdouterr_r, line); ) + filt.next_line(line + "\n"); + temp_stdouterr_r.close(); #endif if (ret != 0) { if (check_file_exists(stringf("%s/output.aig", tempdir_name.c_str()))) From 6965abeefa29869541e1c071733bff213b9d65b4 Mon Sep 17 00:00:00 2001 From: Catherine Date: Sun, 23 Jul 2023 01:36:37 +0000 Subject: [PATCH 189/303] abc, abc9_exe: fix build on WASI (and others with `const* stdout`). C does not guarantee that stdout/stderr can be reassigned. Most platforms do make them assignable, however musl and WASI that is based on musl do not. WASI does not have `dup2()`; instead it has its own non-portable version of it that can only assign to previously allocated fds. Update the stream redirection code so that it does the right thing on WASI and other platforms. --- passes/techmap/abc.cc | 29 ++++++++++++++++++++++------- passes/techmap/abc9_exe.cc | 29 ++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 182e26c2f83..364a8e54458 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1091,17 +1091,28 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); - abc_output_filter filt(tempdir_name, show_tempdir); #ifndef YOSYS_LINK_ABC + abc_output_filter filt(tempdir_name, show_tempdir); int ret = run_command(buffer, std::bind(&abc_output_filter::next_line, filt, std::placeholders::_1)); #else string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name.c_str()); FILE *temp_stdouterr_w = fopen(temp_stdouterr_name.c_str(), "w"); if (temp_stdouterr_w == NULL) log_error("ABC: cannot open a temporary file for output redirection"); - FILE *old_stdout = stdout; - FILE *old_stderr = stderr; - stdout = stderr = temp_stdouterr_w; + fflush(stdout); + fflush(stderr); + FILE *old_stdout = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering + FILE *old_stderr = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering +#if defined(__wasm) +#define fd_renumber(from, to) (void)__wasi_fd_renumber(from, to) +#else +#define fd_renumber(from, to) dup2(from, to) +#endif + fd_renumber(fileno(stdout), fileno(old_stdout)); + fd_renumber(fileno(stderr), fileno(old_stderr)); + fd_renumber(fileno(temp_stdouterr_w), fileno(stdout)); + fd_renumber(fileno(temp_stdouterr_w), fileno(stderr)); + fclose(temp_stdouterr_w); // These needs to be mutable, supposedly due to getopt char *abc_argv[5]; string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); @@ -1115,10 +1126,14 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin free(abc_argv[1]); free(abc_argv[2]); free(abc_argv[3]); - stdout = old_stdout; - stderr = old_stderr; - fclose(temp_stdouterr_w); + fflush(stdout); + fflush(stderr); + fd_renumber(fileno(old_stdout), fileno(stdout)); + fd_renumber(fileno(old_stderr), fileno(stderr)); + fclose(old_stdout); + fclose(old_stderr); std::ifstream temp_stdouterr_r(temp_stdouterr_name); + abc_output_filter filt(tempdir_name, show_tempdir); for (std::string line; std::getline(temp_stdouterr_r, line); ) filt.next_line(line + "\n"); temp_stdouterr_r.close(); diff --git a/passes/techmap/abc9_exe.cc b/passes/techmap/abc9_exe.cc index 449b5b129af..8e02e25a4bf 100644 --- a/passes/techmap/abc9_exe.cc +++ b/passes/techmap/abc9_exe.cc @@ -267,17 +267,28 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe buffer = stringf("\"%s\" -s -f %s/abc.script 2>&1", exe_file.c_str(), tempdir_name.c_str()); log("Running ABC command: %s\n", replace_tempdir(buffer, tempdir_name, show_tempdir).c_str()); - abc9_output_filter filt(tempdir_name, show_tempdir); #ifndef YOSYS_LINK_ABC + abc9_output_filter filt(tempdir_name, show_tempdir); int ret = run_command(buffer, std::bind(&abc9_output_filter::next_line, filt, std::placeholders::_1)); #else string temp_stdouterr_name = stringf("%s/stdouterr.txt", tempdir_name.c_str()); FILE *temp_stdouterr_w = fopen(temp_stdouterr_name.c_str(), "w"); if (temp_stdouterr_w == NULL) log_error("ABC: cannot open a temporary file for output redirection"); - FILE *old_stdout = stdout; - FILE *old_stderr = stderr; - stdout = stderr = temp_stdouterr_w; + fflush(stdout); + fflush(stderr); + FILE *old_stdout = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering + FILE *old_stderr = fopen(temp_stdouterr_name.c_str(), "r"); // need any fd for renumbering +#if defined(__wasm) +#define fd_renumber(from, to) (void)__wasi_fd_renumber(from, to) +#else +#define fd_renumber(from, to) dup2(from, to) +#endif + fd_renumber(fileno(stdout), fileno(old_stdout)); + fd_renumber(fileno(stderr), fileno(old_stderr)); + fd_renumber(fileno(temp_stdouterr_w), fileno(stdout)); + fd_renumber(fileno(temp_stdouterr_w), fileno(stderr)); + fclose(temp_stdouterr_w); // These needs to be mutable, supposedly due to getopt char *abc9_argv[5]; string tmp_script_name = stringf("%s/abc.script", tempdir_name.c_str()); @@ -291,10 +302,14 @@ void abc9_module(RTLIL::Design *design, std::string script_file, std::string exe free(abc9_argv[1]); free(abc9_argv[2]); free(abc9_argv[3]); - stdout = old_stdout; - stderr = old_stderr; - fclose(temp_stdouterr_w); + fflush(stdout); + fflush(stderr); + fd_renumber(fileno(old_stdout), fileno(stdout)); + fd_renumber(fileno(old_stderr), fileno(stderr)); + fclose(old_stdout); + fclose(old_stderr); std::ifstream temp_stdouterr_r(temp_stdouterr_name); + abc9_output_filter filt(tempdir_name, show_tempdir); for (std::string line; std::getline(temp_stdouterr_r, line); ) filt.next_line(line + "\n"); temp_stdouterr_r.close(); From c7670b36d4b4bc7bcffeeddb4f43f8f02cf9e86f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 00:17:45 +0000 Subject: [PATCH 190/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8f6430bee7a..4aac6312db6 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+13 +YOSYS_VER := 0.31+16 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 3989181cd618f98eb4a0a663e7dca8295d946cf0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 24 Jul 2023 12:41:57 +0200 Subject: [PATCH 191/303] Add ability to blackbox modules/units from file while reading with verific --- frontends/verific/verific.cc | 151 ++++++++++++++++++++++++++++++++--- 1 file changed, 138 insertions(+), 13 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 0dd785ec3ab..fd64af925ba 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1197,13 +1197,13 @@ static std::string sha1_if_contain_spaces(std::string str) void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::map &nl_todo, bool norename) { - std::string netlist_name = nl->GetAtt(" \\top") ? nl->CellBaseName() : nl->Owner()->Name(); + std::string netlist_name = nl->GetAtt(" \\top") || is_blackbox(nl) ? nl->CellBaseName() : nl->Owner()->Name(); std::string module_name = netlist_name; if (nl->IsOperator() || nl->IsPrimitive()) { module_name = "$verific$" + module_name; } else { - if (!norename && *nl->Name()) { + if (!norename && *nl->Name() && !is_blackbox(nl)) { module_name += "("; module_name += nl->Name(); module_name += ")"; @@ -1893,14 +1893,14 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma } import_verific_cells: - std::string inst_type = inst->View()->Owner()->Name(); + std::string inst_type = is_blackbox(inst->View()) ? inst->View()->CellBaseName() : inst->View()->Owner()->Name(); nl_todo[inst_type] = inst->View(); if (inst->View()->IsOperator() || inst->View()->IsPrimitive()) { inst_type = "$verific$" + inst_type; } else { - if (*inst->View()->Name()) { + if (*inst->View()->Name() && !is_blackbox(inst->View())) { inst_type += "("; inst_type += inst->View()->Name(); inst_type += ")"; @@ -1918,6 +1918,14 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (verific_verbose) log(" ports in verific db:\n"); + const char *param_name ; + const char *param_value ; + if (is_blackbox(inst->View())) { + FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { + cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value)); + } + } + FOREACH_PORTREF_OF_INST(inst, mi2, pr) { if (verific_verbose) log(" .%s(%s)\n", pr->GetPort()->Name(), pr->GetNet()->Name()); @@ -2834,6 +2842,67 @@ struct VerificPass : public Pass { return filename; } +#ifdef VERIFIC_VHDL_SUPPORT + void add_units_to_map(Map &map, std::string work, bool flag_lib) + { + MapIter mi ; + VhdlPrimaryUnit *unit ; + if (flag_lib) { + VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); + if (vhdl_lib) { + FOREACH_VHDL_PRIMARY_UNIT(vhdl_lib, mi, unit) { + if (!unit) continue; + map.Insert(unit,unit); + } + } + } + } + + void set_units_to_blackbox(Map &map, std::string work, bool flag_lib) + { + MapIter mi ; + VhdlPrimaryUnit *unit ; + if (!flag_lib) return; + VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); + FOREACH_VHDL_PRIMARY_UNIT(vhdl_lib, mi, unit) { + if (!unit) continue; + if (!map.GetValue(unit)) { + unit->SetCompileAsBlackbox(); + } + } + } +#endif + + void add_modules_to_map(Map &map, std::string work, bool flag_lib) + { + MapIter mi ; + VeriModule *veri_module ; + if (flag_lib) { + + VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); + if (veri_lib) { + FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, veri_module) { + if (!veri_module) continue; + map.Insert(veri_module,veri_module); + } + } + } + } + + void set_modules_to_blackbox(Map &map, std::string work, bool flag_lib) + { + MapIter mi ; + VeriModule *veri_module ; + if (!flag_lib) return; + VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); + FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, veri_module) { + if (!veri_module) continue; + if (!map.GetValue(veri_module)) { + veri_module->SetCompileAsBlackbox(); + } + } + } + void execute(std::vector args, RTLIL::Design *design) override { static bool set_verific_global_flags = true; @@ -3130,15 +3199,27 @@ struct VerificPass : public Pass { for (auto &ext : verific_libexts) veri_file::AddLibExt(ext.c_str()); + bool flag_lib = false; while (argidx < GetSize(args)) { + if (args[argidx] == "-lib") { + flag_lib = true; + argidx++; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } std::string filename = frontent_rewrite(args, argidx, tmp_files); file_names.Insert(strdup(filename.c_str())); } + Map map(POINTER_HASH); + add_modules_to_map(map, work, flag_lib); if (!veri_file::AnalyzeMultipleFiles(&file_names, verilog_mode, work.c_str(), veri_file::MFCU)) { verific_error_msg.clear(); log_cmd_error("Reading Verilog/SystemVerilog sources failed.\n"); } - + set_modules_to_blackbox(map, work, flag_lib); verific_import_pending = true; goto check_error; } @@ -3146,11 +3227,22 @@ struct VerificPass : public Pass { #ifdef VERIFIC_VHDL_SUPPORT if (GetSize(args) > argidx && args[argidx] == "-vhdl87") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1987").c_str()); - argidx++; - while (argidx < GetSize(args)) { + bool flag_lib = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-lib") { + flag_lib = true; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + Map map(POINTER_HASH); + add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_87)) log_cmd_error("Reading `%s' in VHDL_87 mode failed.\n", filename.c_str()); + set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; goto check_error; @@ -3158,11 +3250,22 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && args[argidx] == "-vhdl93") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); - argidx++; - while (argidx < GetSize(args)) { + bool flag_lib = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-lib") { + flag_lib = true; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + Map map(POINTER_HASH); + add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_93)) log_cmd_error("Reading `%s' in VHDL_93 mode failed.\n", filename.c_str()); + set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; goto check_error; @@ -3170,11 +3273,22 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && args[argidx] == "-vhdl2k") { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_1993").c_str()); - argidx++; - while (argidx < GetSize(args)) { + bool flag_lib = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-lib") { + flag_lib = true; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + Map map(POINTER_HASH); + add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2K)) log_cmd_error("Reading `%s' in VHDL_2K mode failed.\n", filename.c_str()); + set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; goto check_error; @@ -3182,11 +3296,22 @@ struct VerificPass : public Pass { if (GetSize(args) > argidx && (args[argidx] == "-vhdl2008" || args[argidx] == "-vhdl")) { vhdl_file::SetDefaultLibraryPath((proc_share_dirname() + "verific/vhdl_vdbs_2008").c_str()); - argidx++; - while (argidx < GetSize(args)) { + bool flag_lib = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-lib") { + flag_lib = true; + continue; + } + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + Map map(POINTER_HASH); + add_units_to_map(map, work, flag_lib); std::string filename = frontent_rewrite(args, argidx, tmp_files); if (!vhdl_file::Analyze(filename.c_str(), work.c_str(), vhdl_file::VHDL_2008)) log_cmd_error("Reading `%s' in VHDL_2008 mode failed.\n", filename.c_str()); + set_units_to_blackbox(map, work, flag_lib); } verific_import_pending = true; goto check_error; From 372760af57bb4206b2098b57a2bc145eeb930526 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 24 Jul 2023 16:18:21 +0200 Subject: [PATCH 192/303] spaces to tabs --- frontends/verific/verific.cc | 58 ++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index fd64af925ba..05ae853c19d 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -145,29 +145,29 @@ string get_full_netlist_name(Netlist *nl) class YosysStreamCallBackHandler : public VerificStreamCallBackHandler { public: - YosysStreamCallBackHandler() : VerificStreamCallBackHandler() { } - virtual ~YosysStreamCallBackHandler() { } - - virtual verific_stream *GetSysCallStream(const char *file_path) - { - if (!file_path) return nullptr; - - linefile_type src_loc = GetFromLocation(); - - char *this_file_name = nullptr; - if (src_loc && !FileSystem::IsAbsolutePath(file_path)) { - const char *src_file_name = LineFile::GetFileName(src_loc); - char *dir_name = FileSystem::DirectoryPath(src_file_name); - if (dir_name) { - this_file_name = Strings::save(dir_name, "/", file_path); - Strings::free(dir_name); - file_path = this_file_name; - } - } - verific_stream *strm = new verific_ifstream(file_path); - Strings::free(this_file_name); - return strm; - } + YosysStreamCallBackHandler() : VerificStreamCallBackHandler() { } + virtual ~YosysStreamCallBackHandler() { } + + virtual verific_stream *GetSysCallStream(const char *file_path) + { + if (!file_path) return nullptr; + + linefile_type src_loc = GetFromLocation(); + + char *this_file_name = nullptr; + if (src_loc && !FileSystem::IsAbsolutePath(file_path)) { + const char *src_file_name = LineFile::GetFileName(src_loc); + char *dir_name = FileSystem::DirectoryPath(src_file_name); + if (dir_name) { + this_file_name = Strings::save(dir_name, "/", file_path); + Strings::free(dir_name); + file_path = this_file_name; + } + } + verific_stream *strm = new verific_ifstream(file_path); + Strings::free(this_file_name); + return strm; + } }; YosysStreamCallBackHandler verific_read_cb; @@ -1918,10 +1918,10 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::ma if (verific_verbose) log(" ports in verific db:\n"); - const char *param_name ; - const char *param_value ; + const char *param_name ; + const char *param_value ; if (is_blackbox(inst->View())) { - FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { + FOREACH_PARAMETER_OF_INST(inst, mi2, param_name, param_value) { cell->setParam(RTLIL::escape_id(param_name), verific_const(param_value)); } } @@ -2510,7 +2510,7 @@ std::string verific_import(Design *design, const std::mapChangePortBusStructures(1 /* hierarchical */); + nl.second->ChangePortBusStructures(1 /* hierarchical */); VerificExtNets worker; for (auto nl : nl_todo) @@ -3473,7 +3473,7 @@ struct VerificPass : public Pass { const std::string &key = args[++argidx]; const std::string &value = args[++argidx]; unsigned new_insertion = parameters.Insert(key.c_str(), value.c_str(), - 1 /* force_overwrite */); + 1 /* force_overwrite */); if (!new_insertion) log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str()); continue; @@ -3754,7 +3754,7 @@ struct VerificPass : public Pass { } #ifdef YOSYSHQ_VERIFIC_EXTENSIONS if (VerificExtensions::Execute(args, argidx, work, - [this](const std::vector &args, size_t argidx, std::string msg) + [this](const std::vector &args, size_t argidx, std::string msg) { cmd_error(args, argidx, msg); } )) { goto check_error; } From 3ec00cceaa62ad7e06bdaa0fa48eaaffeae8982c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:28:22 +0200 Subject: [PATCH 193/303] cellaigs: Generate models for integer comparison cells Add the case of $lt, $le, $gt, $ge to the code generating AIGs. --- kernel/cellaigs.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 292af3f51b0..6246e59c7c1 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -385,6 +385,26 @@ Aig::Aig(Cell *cell) goto optimize; } + if (cell->type.in({ID($lt), ID($gt), ID($le), ID($ge)})) + { + int width = std::max(GetSize(cell->getPort(ID::A)), + GetSize(cell->getPort(ID::B))) + 1; + vector A = mk.inport_vec(ID::A, width); + vector B = mk.inport_vec(ID::B, width); + + if (cell->type.in({ID($gt), ID($ge)})) + std::swap(A, B); + + int carry = mk.bool_node(!cell->type.in({ID($le), ID($ge)})); + for (auto &n : B) + n = mk.not_gate(n); + vector Y = mk.adder(A, B, carry); + mk.outport(Y.back(), ID::Y); + 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 == ID($alu)) { int width = GetSize(cell->getPort(ID::Y)); From b59c7172454f118f935f5d0696662a0427d29673 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Wed, 26 Jul 2023 20:46:56 +0100 Subject: [PATCH 194/303] kernel/rtlil: Fixed the destruction guard for IdString The guard is optimised out on some compilers under certain conditions (eg: LTO on GCC) as constant under C++ lifetime rules. This is because the guard type's member is invalid to access (UB) after the type has been destroyed, resulting in `destruct_guard.ok` being unable to be `false` according to the optimiser, based on the lifetime rules. This patch still invokes UB (all accesses to the destroyed IdString instance are), but at least the optimiser can't reason that destruct_guard_ok cannot be false and therefore it's safe to optimise out from its guard role. --- kernel/rtlil.cc | 1 + kernel/rtlil.h | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7f3508b2f49..7011429ff5a 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -30,6 +30,7 @@ YOSYS_NAMESPACE_BEGIN +bool RTLIL::IdString::destruct_guard_ok = false; RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; std::vector RTLIL::IdString::global_id_storage_; dict RTLIL::IdString::global_id_index_; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7c7669caa88..71ee7f98919 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -85,10 +85,10 @@ namespace RTLIL // the global id string cache + static bool destruct_guard_ok; // POD, will be initialized to zero static struct destruct_guard_t { - bool ok; // POD, will be initialized to zero - destruct_guard_t() { ok = true; } - ~destruct_guard_t() { ok = false; } + destruct_guard_t() { destruct_guard_ok = true; } + ~destruct_guard_t() { destruct_guard_ok = false; } } destruct_guard; static std::vector global_id_storage_; @@ -147,7 +147,7 @@ namespace RTLIL static int get_reference(const char *p) { - log_assert(destruct_guard.ok); + log_assert(destruct_guard_ok); if (!p[0]) return 0; @@ -225,7 +225,7 @@ namespace RTLIL { // 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 || !idx) + if (!destruct_guard_ok || !idx) return; #ifdef YOSYS_XTRACE_GET_PUT From ef7e35857668a552c6ff783d5db29fa12708e1a2 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Wed, 26 Jul 2023 20:50:55 +0100 Subject: [PATCH 195/303] kernel/rtlil: Trailing whitespace cleanup --- kernel/rtlil.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 71ee7f98919..a69ce480baf 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -443,13 +443,13 @@ namespace RTLIL static inline std::string encode_filename(const std::string &filename) { std::stringstream val; - if (!std::any_of(filename.begin(), filename.end(), [](char c) { - return static_cast(c) < 33 || static_cast(c) > 126; + if (!std::any_of(filename.begin(), filename.end(), [](char c) { + return static_cast(c) < 33 || static_cast(c) > 126; })) return filename; for (unsigned char const c : filename) { if (c < 33 || c > 126) val << stringf("$%02x", c); - else + else val << c; } return val.str(); From 19d5293657658a32f74d5b355cb263334756850f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 31 Jul 2023 09:18:54 +0200 Subject: [PATCH 196/303] when blackboxing no need to know missing modules --- frontends/verific/verific.cc | 50 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 05ae853c19d..b0d789d8fa3 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2843,19 +2843,26 @@ struct VerificPass : public Pass { } #ifdef VERIFIC_VHDL_SUPPORT + msg_type_t prev_1240 ; + msg_type_t prev_1241 ; + void add_units_to_map(Map &map, std::string work, bool flag_lib) { MapIter mi ; VhdlPrimaryUnit *unit ; - if (flag_lib) { - VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); - if (vhdl_lib) { - FOREACH_VHDL_PRIMARY_UNIT(vhdl_lib, mi, unit) { - if (!unit) continue; - map.Insert(unit,unit); - } + if (!flag_lib) return; + VhdlLibrary *vhdl_lib = vhdl_file::GetLibrary(work.c_str(), 1); + if (vhdl_lib) { + FOREACH_VHDL_PRIMARY_UNIT(vhdl_lib, mi, unit) { + if (!unit) continue; + map.Insert(unit,unit); } } + + prev_1240 = Message::GetMessageType("VHDL-1240") ; + prev_1241 = Message::GetMessageType("VHDL-1241") ; + Message::SetMessageType("VHDL-1240", VERIFIC_INFO); + Message::SetMessageType("VHDL-1241", VERIFIC_INFO); } void set_units_to_blackbox(Map &map, std::string work, bool flag_lib) @@ -2870,23 +2877,33 @@ struct VerificPass : public Pass { unit->SetCompileAsBlackbox(); } } + Message::ClearMessageType("VHDL-1240") ; + Message::ClearMessageType("VHDL-1241") ; + if (Message::GetMessageType("VHDL-1240")!=prev_1240) + Message::SetMessageType("VHDL-1240", prev_1240); + if (Message::GetMessageType("VHDL-1241")!=prev_1241) + Message::SetMessageType("VHDL-1241", prev_1241); + } #endif + msg_type_t prev_1063; + void add_modules_to_map(Map &map, std::string work, bool flag_lib) { MapIter mi ; VeriModule *veri_module ; - if (flag_lib) { - - VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); - if (veri_lib) { - FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, veri_module) { - if (!veri_module) continue; - map.Insert(veri_module,veri_module); - } + if (!flag_lib) return; + VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); + if (veri_lib) { + FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, veri_module) { + if (!veri_module) continue; + map.Insert(veri_module,veri_module); } } + + prev_1063 = Message::GetMessageType("VERI-1063") ; + Message::SetMessageType("VERI-1063", VERIFIC_INFO); } void set_modules_to_blackbox(Map &map, std::string work, bool flag_lib) @@ -2901,6 +2918,9 @@ struct VerificPass : public Pass { veri_module->SetCompileAsBlackbox(); } } + Message::ClearMessageType("VERI-1063") ; + if (Message::GetMessageType("VERI-1063")!=prev_1063) + Message::SetMessageType("VERI-1063", prev_1063); } void execute(std::vector args, RTLIL::Design *design) override From 93988ef5df8a477b0e880c3fe4c7c4e450816761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 10 Jul 2023 12:40:50 +0200 Subject: [PATCH 197/303] tests: Extend aigmap.ys with SAT comparison Extend the aigmap.ys test with SAT-based comparison of the original cells and their AIG implementations. This tests both the usual cells and the single-bit Yosys gates. --- tests/techmap/aigmap.ys | 115 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/tests/techmap/aigmap.ys b/tests/techmap/aigmap.ys index a40aa39f14b..6f6cdd1f21a 100644 --- a/tests/techmap/aigmap.ys +++ b/tests/techmap/aigmap.ys @@ -1,3 +1,118 @@ +read_verilog -icells <, 3, 3, 1) +`BIOP(logic_ge, >=, 3, 3, 1) +`UNOP(pos, +, 3) +`UNOP(neg, ~, 3) +`UNOP_REDUCE(logic_not, !, 3) +`UNOP_REDUCE(reduce_and, &, 3) +`UNOP_REDUCE(reduce_or, |, 3) +`UNOP_REDUCE(reduce_xor, ^, 3) +`UNOP_REDUCE(reduce_xnor, ~^, 3) + +wire [3:0] mux_a, mux_b, mux_s, mux_y; +assign mux_y = mux_s ? mux_b : mux_a; +endmodule +EOF + +expose -input c:* %ci* w:* %i +expose c:* %co* w:* %i +copy test gold +aigmap test +select -assert-none test/t:$_AND_ test/t:$_NOT_ %% test/c:* %D +miter -equiv -flatten gold test miter +sat -verify -prove trigger 0 miter + + +design -reset read_verilog < Date: Tue, 1 Aug 2023 00:19:43 +0000 Subject: [PATCH 198/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5fa288a44b0..512fe2f3d9b 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+16 +YOSYS_VER := 0.31+40 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f8325f66b7ae31111f2fe5b084bd8d96789c3747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 1 Aug 2023 11:10:27 +0200 Subject: [PATCH 199/303] opt_expr: Fix 'signed X>=0' replacement for wide output ports If the `$ge` cell we are replacing has wide output port, the upper bits on the port should be driven to zero. That's not what a `$not` cell with a single-bit input does. Instead opt for a `$logic_not` cell, which does zero-pad its output. Fixes #3867. --- passes/opt/opt_expr.cc | 2 +- tests/opt/bug3867.ys | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/opt/bug3867.ys diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 9d5ca4ef9a1..46773a344b1 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -2165,7 +2165,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons { condition = "signed X>=0"; replacement = stringf("X[%d]", var_width - 1); - module->addNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID::Y)); + module->addLogicNot(NEW_ID, var_sig[var_width - 1], cell->getPort(ID::Y)); remove = true; } } diff --git a/tests/opt/bug3867.ys b/tests/opt/bug3867.ys new file mode 100644 index 00000000000..9c4359a7838 --- /dev/null +++ b/tests/opt/bug3867.ys @@ -0,0 +1,7 @@ +read_verilog <= 0); +endmodule +EOF + +equiv_opt -assert opt_expr -fine From b9751ef0b0b89799c649d20653b685045f14cd36 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Mon, 24 Jul 2023 16:40:43 +0200 Subject: [PATCH 200/303] Install yw.h and json.h --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 512fe2f3d9b..a2803058b06 100644 --- a/Makefile +++ b/Makefile @@ -629,6 +629,8 @@ ifeq ($(ENABLE_ZLIB),1) $(eval $(call add_include_file,kernel/fstdata.h)) endif $(eval $(call add_include_file,kernel/mem.h)) +$(eval $(call add_include_file,kernel/yw.h)) +$(eval $(call add_include_file,kernel/json.h)) $(eval $(call add_include_file,libs/ezsat/ezsat.h)) $(eval $(call add_include_file,libs/ezsat/ezminisat.h)) ifeq ($(ENABLE_ZLIB),1) From 77c7355d537f620a18ca6cf39243850bdc885807 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 1 Aug 2023 17:19:29 +0200 Subject: [PATCH 201/303] smtbmc: Avoid quadratic behavior when scanning s-exprs The previous implementation for finding the end of a top-level s-expr exhibited quadratic behavior as it would re-scan the complete input for the current expression for every new line. For large designs with trivial properties this could easily take seconds and dominate the runtime over the actual solving. This change remembers the current nesting level between lines, avoiding the re-scanning. --- backends/smt2/smtio.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/backends/smt2/smtio.py b/backends/smt2/smtio.py index 8094747bc14..0ec7f08f4dc 100644 --- a/backends/smt2/smtio.py +++ b/backends/smt2/smtio.py @@ -245,6 +245,7 @@ def setup(self): self.logic_uf = False self.unroll_idcnt = 0 self.unroll_buffer = "" + self.unroll_level = 0 self.unroll_sorts = set() self.unroll_objs = set() self.unroll_decls = dict() @@ -420,13 +421,15 @@ def write(self, stmt, unroll=True): self.p_close() if unroll and self.unroll: - stmt = self.unroll_buffer + stmt - self.unroll_buffer = "" - s = re.sub(r"\|[^|]*\|", "", stmt) - if s.count("(") != s.count(")"): - self.unroll_buffer = stmt + " " + self.unroll_level += s.count("(") - s.count(")") + if self.unroll_level > 0: + self.unroll_buffer += stmt + self.unroll_buffer += " " return + else: + stmt = self.unroll_buffer + stmt + self.unroll_buffer = "" s = self.parse(stmt) From f37ce5c839c5a5e21fb74046375e5928ad91d22e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 00:16:17 +0000 Subject: [PATCH 202/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a2803058b06..44a420a3dc3 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+40 +YOSYS_VER := 0.31+45 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From ff3c7873f5af5bf701fd331f16df2fe7cb3455b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 2 Aug 2023 20:10:18 +0200 Subject: [PATCH 203/303] wreduce: Group reconnections Group the reconnections, so that instead of producing connect $auto$wreduce.cc:455:run$24 [0] 1'0 connect $auto$wreduce.cc:455:run$23 [31] 1'0 connect $auto$wreduce.cc:455:run$23 [30] 1'0 ... (40 more lines) we produce connect $auto$wreduce.cc:461:run$23 [31:11] 21'000000000000000000000 connect $auto$wreduce.cc:461:run$24 [31:10] 22'0000000000000000000000 . --- passes/opt/wreduce.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/passes/opt/wreduce.cc b/passes/opt/wreduce.cc index 8fd4c788c92..87a5cb56d86 100644 --- a/passes/opt/wreduce.cc +++ b/passes/opt/wreduce.cc @@ -364,10 +364,16 @@ struct WreduceWorker if (cell->type == ID($mul)) max_y_size = a_size + b_size; - while (GetSize(sig) > 1 && GetSize(sig) > max_y_size) { - module->connect(sig[GetSize(sig)-1], is_signed ? sig[GetSize(sig)-2] : State::S0); - sig.remove(GetSize(sig)-1); - bits_removed++; + max_y_size = std::max(max_y_size, 1); + + if (GetSize(sig) > max_y_size) { + SigSpec extra_bits = sig.extract(max_y_size, GetSize(sig) - max_y_size); + + bits_removed += GetSize(extra_bits); + sig.remove(max_y_size, GetSize(extra_bits)); + + SigBit padbit = is_signed ? sig[GetSize(sig)-1] : State::S0; + module->connect(extra_bits, SigSpec(padbit, GetSize(extra_bits))); } } From e0ba07aed3118502e623139048a24a0cd433d85f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 5 Aug 2023 00:16:43 +0000 Subject: [PATCH 204/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 44a420a3dc3..41fecf2c172 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+45 +YOSYS_VER := 0.31+49 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From fbab08acf14cc5e1fda6c33ba03094e348ea8953 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Aug 2023 08:22:52 +0200 Subject: [PATCH 205/303] Release version 0.32 --- CHANGELOG | 9 ++++++++- Makefile | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0b211771f0f..585605abcdd 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,15 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.31 .. Yosys 0.32-dev +Yosys 0.31 .. Yosys 0.32 -------------------------- + * Verific support + - Added sub option "-lib" to reading commands for VHDL and + SystemVerilog, that will later import all units/modules from + marked files as blackboxes. + + * Various + - Added support for $lt, $le, $gt, $ge to the code generating AIGs. Yosys 0.30 .. Yosys 0.31 -------------------------- diff --git a/Makefile b/Makefile index 41fecf2c172..6d831e5665f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.31+49 +YOSYS_VER := 0.32 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 105c447010cff8c408c719454901b32b51dac421 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 7 Aug 2023 08:25:37 +0200 Subject: [PATCH 206/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 585605abcdd..027187b6d9f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.32 .. Yosys 0.33-dev +-------------------------- + Yosys 0.31 .. Yosys 0.32 -------------------------- * Verific support diff --git a/Makefile b/Makefile index 6d831e5665f..8ff1e43867d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32 +YOSYS_VER := 0.32+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline f3c6b41.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 389b8d0f94a24c30e5b9352866f0999b14312b23 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 00:16:52 +0000 Subject: [PATCH 207/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8ff1e43867d..c56cb0a3f6e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+0 +YOSYS_VER := 0.32+1 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From f8e2c955fc9fe052c15d1215c5f7a7aab9fe77cc Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 02:40:36 +0000 Subject: [PATCH 208/303] read_verilog: set location of AST_TCALL. Useful for error reporting of $display() arguments, etc. --- frontends/verilog/verilog_parser.y | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 98bdbf9e5c5..1e82940bbbd 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1830,7 +1830,7 @@ struct_member_type: { astbuf1 = new AstNode(AST_STRUCT_ITEM); } member_type_toke ; member_type_token: - member_type + member_type | hierarchical_type_id { addWiretypeNode($1, astbuf1); } @@ -2721,6 +2721,7 @@ behavioral_stmt: ast_stack.push_back(node); append_attr(node, $1); } opt_arg_list ';'{ + SET_AST_NODE_LOC(ast_stack.back(), @2, @5); ast_stack.pop_back(); } | attr TOK_MSG_TASKS { @@ -2731,6 +2732,7 @@ behavioral_stmt: ast_stack.push_back(node); append_attr(node, $1); } opt_arg_list ';'{ + SET_AST_NODE_LOC(ast_stack.back(), @2, @5); ast_stack.pop_back(); } | attr TOK_BEGIN { From 9ea241711e15536bc1ee0c8bc156d39bfacb9768 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 08:16:43 +0000 Subject: [PATCH 209/303] kernel: add format string helpers, `fmt`. --- Makefile | 12 +- kernel/fmt.cc | 577 ++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/fmt.h | 90 ++++++++ 3 files changed, 673 insertions(+), 6 deletions(-) create mode 100644 kernel/fmt.cc create mode 100644 kernel/fmt.h diff --git a/Makefile b/Makefile index c56cb0a3f6e..dab83bcbe56 100644 --- a/Makefile +++ b/Makefile @@ -652,12 +652,7 @@ $(eval $(call add_include_file,backends/cxxrtl/cxxrtl_vcd_capi.h)) OBJS += kernel/driver.o kernel/register.o kernel/rtlil.o kernel/log.o kernel/calc.o kernel/yosys.o OBJS += kernel/binding.o -ifeq ($(ENABLE_ABC),1) -ifneq ($(ABCEXTERNAL),) -kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' -endif -endif -OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o +OBJS += kernel/cellaigs.o kernel/celledges.o kernel/satgen.o kernel/qcsat.o kernel/mem.o kernel/ffmerge.o kernel/ff.o kernel/yw.o kernel/json.o kernel/fmt.o ifeq ($(ENABLE_ZLIB),1) OBJS += kernel/fstdata.o endif @@ -669,6 +664,11 @@ endif kernel/log.o: CXXFLAGS += -DYOSYS_SRC='"$(YOSYS_SRC)"' kernel/yosys.o: CXXFLAGS += -DYOSYS_DATDIR='"$(DATDIR)"' -DYOSYS_PROGRAM_PREFIX='"$(PROGRAM_PREFIX)"' +ifeq ($(ENABLE_ABC),1) +ifneq ($(ABCEXTERNAL),) +kernel/yosys.o: CXXFLAGS += -DABCEXTERNAL='"$(ABCEXTERNAL)"' +endif +endif OBJS += libs/bigint/BigIntegerAlgorithms.o libs/bigint/BigInteger.o libs/bigint/BigIntegerUtils.o OBJS += libs/bigint/BigUnsigned.o libs/bigint/BigUnsignedInABase.o diff --git a/kernel/fmt.cc b/kernel/fmt.cc new file mode 100644 index 00000000000..924a23a0c1e --- /dev/null +++ b/kernel/fmt.cc @@ -0,0 +1,577 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 whitequark + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "libs/bigint/BigUnsigned.hh" +#include "kernel/fmt.h" + +USING_YOSYS_NAMESPACE + +void Fmt::append_string(const std::string &str) { + FmtPart part = {}; + part.type = FmtPart::STRING; + part.str = str; + parts.push_back(part); +} + +void Fmt::parse_rtlil(RTLIL::Cell *cell) { + std::string fmt = cell->getParam(ID(FORMAT)).decode_string(); + RTLIL::SigSpec args = cell->getPort(ID(ARGS)); + parts.clear(); + + FmtPart part; + for (size_t i = 0; i < fmt.size(); i++) { + if (fmt.substr(i, 2) == "}}") + part.str += '}'; + else if (fmt.substr(i, 2) == "{{") + part.str += '{'; + else if (fmt[i] == '}') + log_assert(false && "Unexpected '}' in format string"); + else if (fmt[i] == '{') { + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + part = {}; + } + + size_t arg_size = 0; + for (++i; i < fmt.size(); i++) { + if (fmt[i] >= '0' && fmt[i] <= '9') { + arg_size *= 10; + arg_size += fmt[i] - '0'; + } else if (fmt[i] == ':') { + break; + } else { + log_assert(false && "Unexpected character in format substitution"); + } + } + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + if ((size_t)args.size() < arg_size) + log_assert(false && "Format part overruns arguments"); + part.sig = args.extract(0, arg_size); + args.remove(0, arg_size); + + if (fmt[i] == '>') + part.justify = FmtPart::RIGHT; + else if (fmt[i] == '<') + part.justify = FmtPart::LEFT; + else + log_assert(false && "Unexpected justification in format substitution"); + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + if (fmt[i] == '0' || fmt[i] == ' ') + part.padding = fmt[i]; + else + log_assert(false && "Unexpected padding in format substitution"); + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + for (; i < fmt.size(); i++) { + if (fmt[i] >= '0' && fmt[i] <= '9') { + part.width *= 10; + part.width += fmt[i] - '0'; + continue; + } else if (fmt[i] == 'b') { + part.type = FmtPart::INTEGER; + part.base = 2; + } else if (fmt[i] == 'o') { + part.type = FmtPart::INTEGER; + part.base = 8; + } else if (fmt[i] == 'd') { + part.type = FmtPart::INTEGER; + part.base = 10; + } else if (fmt[i] == 'h') { + part.type = FmtPart::INTEGER; + part.base = 16; + } else if (fmt[i] == 'c') { + part.type = FmtPart::CHARACTER; + } else { + log_assert(false && "Unexpected character in format substitution"); + } + break; + } + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + + if (part.type == FmtPart::INTEGER) { + if (fmt[i] == '+') { + part.plus = true; + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } + + if (fmt[i] == '0') { + part.lzero = true; + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } + + if (fmt[i] == 'u') + part.signed_ = false; + else if (fmt[i] == 's') + part.signed_ = true; + else + log_assert(false && "Unexpected character in format substitution"); + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + } + + if (fmt[i] != '}') + log_assert(false && "Expected '}' after format substitution"); + + parts.push_back(part); + part = {}; + } else { + part.str += fmt[i]; + } + } + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + } +} + +void Fmt::emit_rtlil(RTLIL::Cell *cell) const { + std::string fmt; + RTLIL::SigSpec args; + + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + for (char c : part.str) { + if (c == '{') + fmt += "{{"; + else if (c == '}') + fmt += "}}"; + else + fmt += c; + } + break; + + case FmtPart::CHARACTER: + log_assert(part.sig.size() % 8 == 0); + YS_FALLTHROUGH + case FmtPart::INTEGER: + args.append(part.sig); + fmt += '{'; + fmt += std::to_string(part.sig.size()); + fmt += ':'; + if (part.justify == FmtPart::RIGHT) + fmt += '>'; + else if (part.justify == FmtPart::LEFT) + fmt += '<'; + else log_abort(); + log_assert(part.padding == '0' || part.padding == ' '); + fmt += part.padding; + fmt += std::to_string(part.width); + if (part.type == FmtPart::INTEGER) { + switch (part.base) { + case 2: fmt += 'b'; break; + case 8: fmt += 'o'; break; + case 10: fmt += 'd'; break; + case 16: fmt += 'h'; break; + default: log_abort(); + } + if (part.plus) + fmt += '+'; + if (part.lzero) + fmt += '0'; + fmt += part.signed_ ? 's' : 'u'; + } else if (part.type == FmtPart::CHARACTER) { + fmt += 'c'; + } else log_abort(); + fmt += '}'; + break; + + default: log_abort(); + } + } + + cell->setParam(ID(FORMAT), fmt); + cell->setParam(ID(ARGS_WIDTH), args.size()); + cell->setPort(ID(ARGS), args); +} + +static size_t compute_requried_decimal_places(size_t size, bool signed_) +{ + BigUnsigned max; + if (!signed_) + max.setBit(size, true); + else + max.setBit(size - 1, true); + size_t places = 0; + while (!max.isZero()) { + places++; + max /= 10; + } + if (signed_) + places++; + return places; +} + +static void apply_verilog_automatic_sizing(FmtPart &part) +{ + if (part.base == 10) { + size_t places = compute_requried_decimal_places(part.sig.size(), part.signed_); + part.padding = ' '; + part.width = std::max(part.width, places); + } else { + part.lzero = true; + } +} + +void Fmt::parse_verilog(const std::vector &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name) +{ + parts.clear(); + + auto arg = args.begin(); + for (; arg != args.end(); ++arg) { + switch (arg->type) { + case VerilogFmtArg::INTEGER: { + FmtPart part = {}; + part.type = FmtPart::INTEGER; + part.sig = arg->sig; + part.base = default_base; + part.signed_ = arg->signed_; + apply_verilog_automatic_sizing(part); + parts.push_back(part); + break; + } + + case VerilogFmtArg::STRING: { + if (arg == args.begin() || !sformat_like) { + const auto fmtarg = arg; + const std::string &fmt = fmtarg->str; + FmtPart part = {}; + for (size_t i = 0; i < fmt.size(); i++) { + if (fmt[i] != '%') { + part.str += fmt[i]; + } else if (fmt.substr(i, 2) == "%%") { + i++; + part.str += '%'; + } else if (fmt.substr(i, 2) == "%l" || fmt.substr(i, 2) == "%L") { + i++; + part.str += module_name.str(); + } else { + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + part = {}; + } + if (++i == fmt.size()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + + if (++arg == args.end()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with fewer arguments than the format specifiers in argument %zu require.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + part.sig = arg->sig; + part.signed_ = arg->signed_; + + for (; i < fmt.size(); i++) { + if (fmt[i] == '-') { + // left justify; not in IEEE 1800-2017 or verilator but iverilog has it + part.justify = FmtPart::LEFT; + } else if (fmt[i] == '+') { + // always show sign; not in IEEE 1800-2017 or verilator but iverilog has it + part.plus = true; + } else break; + } + if (i == fmt.size()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + + bool has_leading_zero = false, has_width = false; + for (; i < fmt.size(); i++) { + if (fmt[i] >= '0' && fmt[i] <= '9') { + if (fmt[i] == '0' && !has_width) { + has_leading_zero = true; + } else { + has_width = true; + part.width *= 10; + part.width += fmt[i] - '0'; + } + continue; + } else if (fmt[i] == 'b' || fmt[i] == 'B') { + part.type = FmtPart::INTEGER; + part.base = 2; + } else if (fmt[i] == 'o' || fmt[i] == 'O') { + part.type = FmtPart::INTEGER; + part.base = 8; + } else if (fmt[i] == 'd' || fmt[i] == 'D') { + part.type = FmtPart::INTEGER; + part.base = 10; + } else if (fmt[i] == 'h' || fmt[i] == 'H' || + fmt[i] == 'x' || fmt[i] == 'X') { + // hex digits always printed in lowercase for %h%x as well as %H%X + part.type = FmtPart::INTEGER; + part.base = 16; + } else if (fmt[i] == 'c' || fmt[i] == 'C') { + part.type = FmtPart::CHARACTER; + part.sig.extend_u0(8); + // %10c and %010c not fully defined in IEEE 1800-2017 and do different things in iverilog + } else if (fmt[i] == 's' || fmt[i] == 'S') { + part.type = FmtPart::CHARACTER; + if ((part.sig.size() % 8) != 0) + part.sig.extend_u0((part.sig.size() + 7) / 8 * 8); + // %10s and %010s not fully defined in IEEE 1800-2017 and do the same thing in iverilog + part.padding = ' '; + } else { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); + } + break; + } + if (i == fmt.size()) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with incomplete format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + + if (part.padding == '\0') + part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' '; + + if (part.type == FmtPart::INTEGER) { + if (part.base != 10 && part.plus) { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); + } + if (!has_leading_zero) + apply_verilog_automatic_sizing(part); + } + + parts.push_back(part); + part = {}; + } + } + if (!part.str.empty()) { + part.type = FmtPart::STRING; + parts.push_back(part); + } + } else { + FmtPart part = {}; + part.type = FmtPart::STRING; + part.str = arg->str; + parts.push_back(part); + } + break; + } + + default: log_abort(); + } + } +} + +std::vector Fmt::emit_verilog() const +{ + std::vector args; + VerilogFmtArg fmt = {}; + fmt.type = VerilogFmtArg::STRING; + + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + for (char c : part.str) { + if (c == '%') + fmt.str += "%%"; + else + fmt.str += c; + } + break; + + case FmtPart::INTEGER: { + VerilogFmtArg arg = {}; + arg.type = VerilogFmtArg::INTEGER; + arg.sig = part.sig; + arg.signed_ = part.signed_; + args.push_back(arg); + + fmt.str += '%'; + if (part.plus) + fmt.str += '+'; + if (part.justify == FmtPart::LEFT) + fmt.str += '-'; + if (part.width == 0) { + if (!part.lzero) + fmt.str += '0'; + } else if (part.width > 0) { + log_assert(part.padding == ' ' || part.padding == '0'); + if (!part.lzero && part.base != 10) + fmt.str += '0'; + else if (part.padding == '0') + fmt.str += '0'; + fmt.str += std::to_string(part.width); + } + switch (part.base) { + case 2: fmt.str += 'b'; break; + case 8: fmt.str += 'o'; break; + case 10: fmt.str += 'd'; break; + case 16: fmt.str += 'h'; break; + default: log_abort(); + } + break; + } + + case FmtPart::CHARACTER: { + VerilogFmtArg arg; + arg.type = VerilogFmtArg::INTEGER; + arg.sig = part.sig; + args.push_back(arg); + + fmt.str += '%'; + if (part.justify == FmtPart::LEFT) + fmt.str += '-'; + if (part.sig.size() == 8) { + if (part.width > 0) { + log_assert(part.padding == '0' || part.padding == ' '); + if (part.padding == '0') + fmt.str += part.padding; + fmt.str += std::to_string(part.width); + } + fmt.str += 'c'; + } else { + log_assert(part.sig.size() % 8 == 0); + if (part.width > 0) { + log_assert(part.padding == ' '); // no zero padding + fmt.str += std::to_string(part.width); + } + fmt.str += 's'; + } + break; + } + } + } + + args.insert(args.begin(), fmt); + return args; +} + +std::string Fmt::render() const +{ + std::string str; + + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + str += part.str; + break; + + case FmtPart::INTEGER: + case FmtPart::CHARACTER: { + std::string buf; + if (part.type == FmtPart::INTEGER) { + RTLIL::Const value = part.sig.as_const(); + + if (!part.lzero && part.base != 10) { + size_t minimum_size = 0; + for (size_t index = 0; index < (size_t)value.size(); index++) + if (value[index] != State::S0) + minimum_size = index + 1; + value = value.extract(0, minimum_size); + } + + if (part.base == 2) { + buf = value.as_string(); + } else if (part.base == 8 || part.base == 16) { + size_t step = (part.base == 16) ? 4 : 3; + for (size_t index = 0; index < (size_t)value.size(); index += step) { + RTLIL::Const subvalue = value.extract(index, min(step, value.size() - index)); + bool has_x = false, all_x = true, has_z = false, all_z = true; + for (State bit : subvalue) { + if (bit == State::Sx) + has_x = true; + else + all_x = false; + if (bit == State::Sz) + has_z = true; + else + all_z = false; + } + if (all_x) + buf += 'x'; + else if (all_z) + buf += 'z'; + else if (has_x) + buf += 'X'; + else if (has_z) + buf += 'Z'; + else + buf += "0123456789abcdef"[subvalue.as_int()]; + } + std::reverse(buf.begin(), buf.end()); + } else if (part.base == 10) { + bool has_x = false, all_x = true, has_z = false, all_z = true; + for (State bit : value) { + if (bit == State::Sx) + has_x = true; + else + all_x = false; + if (bit == State::Sz) + has_z = true; + else + all_z = false; + } + if (all_x) + buf += 'x'; + else if (all_z) + buf += 'z'; + else if (has_x) + buf += 'X'; + else if (has_z) + buf += 'Z'; + else { + bool negative = part.signed_ && value[value.size() - 1]; + RTLIL::Const absvalue; + if (negative) + absvalue = RTLIL::const_neg(value, {}, part.signed_, {}, value.size() + 1); + else + absvalue = value; + log_assert(absvalue.is_fully_def()); + if (absvalue.is_fully_zero()) + buf += '0'; + while (!absvalue.is_fully_zero()) { + buf += '0' + RTLIL::const_mod(absvalue, 10, part.signed_, false, 4).as_int(); + absvalue = RTLIL::const_div(absvalue, 10, part.signed_, false, absvalue.size()); + } + if (negative || part.plus) + buf += negative ? '-' : '+'; + std::reverse(buf.begin(), buf.end()); + } + } else log_abort(); + } else if (part.type == FmtPart::CHARACTER) { + buf = part.sig.as_const().decode_string(); + } + + log_assert(part.width == 0 || part.padding != '\0'); + if (part.justify == FmtPart::RIGHT && buf.size() < part.width) { + size_t pad_width = part.width - buf.size(); + if (part.padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + str += buf.front(); + buf.erase(0, 1); + } + str += std::string(pad_width, part.padding); + } + str += buf; + if (part.justify == FmtPart::LEFT && buf.size() < part.width) + str += std::string(part.width - buf.size(), part.padding); + break; + } + } + } + + return str; +} diff --git a/kernel/fmt.h b/kernel/fmt.h new file mode 100644 index 00000000000..c85da19c01b --- /dev/null +++ b/kernel/fmt.h @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2020 whitequark + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef FMT_H +#define FMT_H + +#include "kernel/yosys.h" + +YOSYS_NAMESPACE_BEGIN + +// Verilog format argument, such as the arguments in: +// $display("foo %d bar %01x", 4'b0, $signed(2'b11)) +struct VerilogFmtArg { + enum { + STRING = 0, + INTEGER = 1, + } type; + + // All types + std::string filename; + unsigned first_line; + + // STRING type + std::string str; + + // INTEGER type + RTLIL::SigSpec sig; + bool signed_ = false; +}; + +// RTLIL format part, such as the substitutions in: +// "foo {4: 4du} bar {2:01xs}" +struct FmtPart { + enum { + STRING = 0, + INTEGER = 1, + CHARACTER = 2, + } type; + + // STRING type + std::string str; + + // INTEGER/CHARACTER type + RTLIL::SigSpec sig; + enum { + RIGHT = 0, + LEFT = 1, + } justify = RIGHT; + char padding = '\0'; + size_t width = 0; + // INTEGER type + unsigned base = 10; + bool signed_ = false; + bool lzero = false; + bool plus = false; +}; + +struct Fmt { + std::vector parts; + + void append_string(const std::string &str); + + void parse_rtlil(RTLIL::Cell *cell); + void emit_rtlil(RTLIL::Cell *cell) const; + + void parse_verilog(const std::vector &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name); + std::vector emit_verilog() const; + + std::string render() const; +}; + +YOSYS_NAMESPACE_END + +#endif From 9f8e039a4b10e936457fd75d589eb7ec51f0292b Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 08:57:07 +0000 Subject: [PATCH 210/303] ast: use new format string helpers. --- frontends/ast/ast.h | 3 +- frontends/ast/simplify.cc | 206 +++++++----------------------- frontends/verilog/verilog_lexer.l | 2 +- tests/various/sformatf.ys | 2 +- 4 files changed, 50 insertions(+), 163 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 8893d5e010c..55e05709dd5 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -30,6 +30,7 @@ #define AST_H #include "kernel/rtlil.h" +#include "kernel/fmt.h" #include #include @@ -277,7 +278,7 @@ namespace AST bool replace_variables(std::map &variables, AstNode *fcall, bool must_succeed); AstNode *eval_const_function(AstNode *fcall, bool must_succeed); bool is_simple_const_expr(); - std::string process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint); + Fmt processFormat(int stage, bool sformat_like, int default_base = 10, size_t first_arg_at = 0); bool is_recursive_function() const; std::pair get_tern_choice(); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 64191cd7ebf..489ce255a0c 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -43,141 +43,35 @@ using namespace AST_INTERNAL; // Process a format string and arguments for $display, $write, $sprintf, etc -std::string AstNode::process_format_str(const std::string &sformat, int next_arg, int stage, int width_hint, bool sign_hint) { - // Other arguments are placeholders. Process the string as we go through it - std::string sout; - for (size_t i = 0; i < sformat.length(); i++) - { - // format specifier - if (sformat[i] == '%') - { - // If there's no next character, that's a problem - if (i+1 >= sformat.length()) - input_error("System task `%s' called with `%%' at end of string.\n", str.c_str()); - - char cformat = sformat[++i]; - - // %% is special, does not need a matching argument - if (cformat == '%') - { - sout += '%'; - continue; - } - - bool got_len = false; - bool got_zlen = false; - int len_value = 0; - - while ('0' <= cformat && cformat <= '9') - { - if (!got_len && cformat == '0') - got_zlen = true; - - got_len = true; - len_value = 10*len_value + (cformat - '0'); - - cformat = sformat[++i]; - } - - // Simplify the argument - AstNode *node_arg = nullptr; - - // Everything from here on depends on the format specifier - switch (cformat) - { - case 's': - case 'S': - case 'd': - case 'D': - if (got_len && len_value != 0) - goto unsupported_format; - YS_FALLTHROUGH - case 'x': - case 'X': - if (next_arg >= GetSize(children)) - input_error("Missing argument for %%%c format specifier in system task `%s'.\n", - cformat, str.c_str()); - - node_arg = children[next_arg++]; - while (node_arg->simplify(true, false, stage, width_hint, sign_hint, false)) { } - if (node_arg->type != AST_CONSTANT) - input_error("Failed to evaluate system task `%s' with non-constant argument.\n", str.c_str()); - break; - - case 'm': - case 'M': - if (got_len) - goto unsupported_format; - break; - - case 'l': - case 'L': - if (got_len) - goto unsupported_format; - break; - - default: - unsupported_format: - input_error("System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); - break; - } - - switch (cformat) - { - case 's': - case 'S': - sout += node_arg->bitsAsConst().decode_string(); - break; - - case 'd': - case 'D': - sout += stringf("%d", node_arg->bitsAsConst().as_int()); - break; - - case 'x': - case 'X': - { - Const val = node_arg->bitsAsConst(); - - while (GetSize(val) % 4 != 0) - val.bits.push_back(State::S0); - - int len = GetSize(val) / 4; - for (int i = len; i < len_value; i++) - sout += got_zlen ? '0' : ' '; - - for (int i = len-1; i >= 0; i--) { - Const digit = val.extract(4*i, 4); - if (digit.is_fully_def()) - sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int()); - else - sout += cformat == 'x' ? "x" : "X"; - } - } - break; - - case 'm': - case 'M': - sout += log_id(current_module->name); - break; - - case 'l': - case 'L': - sout += log_id(current_module->name); - break; - - default: - log_abort(); - } +Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_t first_arg_at) { + std::vector args; + for (size_t index = first_arg_at; index < children.size(); index++) { + AstNode *node_arg = children[index]; + while (node_arg->simplify(true, false, stage, -1, false, false)) { } + if (node_arg->type != AST_CONSTANT) + input_error("Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); + + VerilogFmtArg arg = {}; + arg.filename = filename; + arg.first_line = location.first_line; + if (node_arg->is_string) { + arg.type = VerilogFmtArg::STRING; + arg.str = node_arg->bitsAsConst().decode_string(); + // and in case this will be used as an argument... + arg.sig = node_arg->bitsAsConst(); + arg.signed_ = false; + } else { + arg.type = VerilogFmtArg::INTEGER; + arg.sig = node_arg->bitsAsConst(); + arg.signed_ = node_arg->is_signed; } - - // not a format specifier - else - sout += sformat[i]; + args.push_back(arg); } - return sout; -} + Fmt fmt = {}; + fmt.parse_verilog(args, sformat_like, default_base, /*task_name=*/str, current_module->name); + return fmt; +} void AstNode::annotateTypedEnums(AstNode *template_node) { @@ -1057,33 +951,30 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin str = std::string(); } - if ((type == AST_TCALL) && (str == "$display" || str == "$write") && (!current_always || current_always->type != AST_INITIAL)) { + if ((type == AST_TCALL) && (str.substr(0, 8) == "$display" || str.substr(0, 6) == "$write") && (!current_always || current_always->type != AST_INITIAL)) { log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); delete_children(); str = std::string(); } - // print messages if this a call to $display() or $write() - // This code implements only a small subset of Verilog-2005 $display() format specifiers, - // but should be good enough for most uses - if ((type == AST_TCALL) && ((str == "$display") || (str == "$write"))) + // print messages if this a call to $display() or $write() family of functions + if ((type == AST_TCALL) && + (str == "$display" || str == "$displayb" || str == "$displayh" || str == "$displayo" || + str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo")) { - int nargs = GetSize(children); - if (nargs < 1) - input_error("System task `%s' got %d arguments, expected >= 1.\n", - str.c_str(), int(children.size())); - - // First argument is the format string - AstNode *node_string = children[0]; - while (node_string->simplify(true, false, stage, width_hint, sign_hint, false)) { } - if (node_string->type != AST_CONSTANT) - input_error("Failed to evaluate system task `%s' with non-constant 1st argument.\n", str.c_str()); - std::string sformat = node_string->bitsAsConst().decode_string(); - std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); - // Finally, print the message (only include a \n for $display, not for $write) - log("%s", sout.c_str()); - if (str == "$display") - log("\n"); + int default_base = 10; + if (str.back() == 'b') + default_base = 2; + else if (str.back() == 'o') + default_base = 8; + else if (str.back() == 'h') + default_base = 16; + + Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base); + if (str.substr(0, 8) == "$display") + fmt.append_string("\n"); + log("%s", fmt.render().c_str()); + delete_children(); str = std::string(); } @@ -3735,13 +3626,8 @@ skip_dynamic_range_lvalue_expansion:; } if (str == "\\$sformatf") { - AstNode *node_string = children[0]; - while (node_string->simplify(true, false, stage, width_hint, sign_hint, false)) { } - if (node_string->type != AST_CONSTANT) - input_error("Failed to evaluate system function `%s' with non-constant 1st argument.\n", str.c_str()); - std::string sformat = node_string->bitsAsConst().decode_string(); - std::string sout = process_format_str(sformat, 1, stage, width_hint, sign_hint); - newNode = AstNode::mkconst_str(sout); + Fmt fmt = processFormat(stage, /*sformat_like=*/true); + newNode = AstNode::mkconst_str(fmt.render()); goto apply_newNode; } diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 24998666828..89ccee788c9 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -386,7 +386,7 @@ and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 { supply0 { return TOK_SUPPLY0; } supply1 { return TOK_SUPPLY1; } -"$"(display|write|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { +"$"(display[bho]?|write[bho]?|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { yylval->string = new std::string(yytext); return TOK_ID; } diff --git a/tests/various/sformatf.ys b/tests/various/sformatf.ys index 66d6b0dbe9e..f281a9cd530 100644 --- a/tests/various/sformatf.ys +++ b/tests/various/sformatf.ys @@ -5,7 +5,7 @@ module top; localparam b = $sformatf("%d", 4'b011); generate if (a != "0x5a") $error("a incorrect!"); - if (b != "3") $error("b incorrect!"); + if (b != " 3") $error("b incorrect!"); endgenerate endmodule From d5c9953c09f5430ccc299d214c77f48e98cdc908 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 14:34:17 +0000 Subject: [PATCH 211/303] ast: translate $display/$write tasks in always blocks to new $print cell. --- frontends/ast/ast.h | 2 ++ frontends/ast/genrtlil.cc | 74 ++++++++++++++++++++++++++++++++++++++- frontends/ast/simplify.cc | 42 ++++++++++++---------- kernel/constids.inc | 7 ++++ kernel/rtlil.cc | 11 ++++++ 5 files changed, 116 insertions(+), 20 deletions(-) diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 55e05709dd5..e357579add2 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -278,6 +278,8 @@ namespace AST bool replace_variables(std::map &variables, AstNode *fcall, bool must_succeed); AstNode *eval_const_function(AstNode *fcall, bool must_succeed); bool is_simple_const_expr(); + + // helper for parsing format strings Fmt processFormat(int stage, bool sformat_like, int default_base = 10, size_t first_arg_at = 0); bool is_recursive_function() const; diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 3aa19b70687..40e71e8bd20 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -693,8 +693,80 @@ struct AST_INTERNAL::ProcessGenerator ast->input_error("Found parameter declaration in block without label!\n"); break; - case AST_NONE: case AST_TCALL: + if (ast->str == "$display" || ast->str == "$displayb" || ast->str == "$displayh" || ast->str == "$displayo" || + ast->str == "$write" || ast->str == "$writeb" || ast->str == "$writeh" || ast->str == "$writeo") { + std::stringstream sstr; + sstr << ast->str << "$" << ast->filename << ":" << ast->location.first_line << "$" << (autoidx++); + + RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print)); + cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column); + + RTLIL::SigSpec triggers; + RTLIL::Const polarity; + for (auto sync : proc->syncs) { + if (sync->type == RTLIL::STp) { + triggers.append(sync->signal); + polarity.bits.push_back(RTLIL::S1); + } else if (sync->type == RTLIL::STn) { + triggers.append(sync->signal); + polarity.bits.push_back(RTLIL::S0); + } + } + cell->parameters[ID::TRG_WIDTH] = triggers.size(); + cell->parameters[ID::TRG_ENABLE] = !triggers.empty(); + cell->parameters[ID::TRG_POLARITY] = polarity; + cell->setPort(ID::TRG, triggers); + + Wire *wire = current_module->addWire(sstr.str() + "_EN", 1); + wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column); + cell->setPort(ID::EN, wire); + + proc->root_case.actions.push_back(SigSig(wire, false)); + current_case->actions.push_back(SigSig(wire, true)); + + int default_base = 10; + if (ast->str.back() == 'b') + default_base = 2; + else if (ast->str.back() == 'o') + default_base = 8; + else if (ast->str.back() == 'h') + default_base = 16; + + std::vector args; + for (auto node : ast->children) { + int width; + bool is_signed; + node->detectSignWidth(width, is_signed, nullptr); + + VerilogFmtArg arg = {}; + arg.filename = node->filename; + arg.first_line = node->location.first_line; + if (node->type == AST_CONSTANT && node->is_string) { + arg.type = VerilogFmtArg::STRING; + arg.str = node->bitsAsConst().decode_string(); + // and in case this will be used as an argument... + arg.sig = node->bitsAsConst(); + arg.signed_ = false; + } else { + arg.type = VerilogFmtArg::INTEGER; + arg.sig = node->genRTLIL(); + arg.signed_ = is_signed; + } + args.push_back(arg); + } + + Fmt fmt = {}; + fmt.parse_verilog(args, /*sformat_like=*/false, default_base, /*task_name=*/ast->str, current_module->name); + if (ast->str.substr(0, 8) == "$display") + fmt.append_string("\n"); + fmt.emit_rtlil(cell); + } else if (!ast->str.empty()) { + log_file_error(ast->filename, ast->location.first_line, "Found unsupported invocation of system task `%s'!\n", ast->str.c_str()); + } + break; + + case AST_NONE: case AST_FOR: break; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 489ce255a0c..19e62668b9e 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -951,29 +951,33 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin str = std::string(); } - if ((type == AST_TCALL) && (str.substr(0, 8) == "$display" || str.substr(0, 6) == "$write") && (!current_always || current_always->type != AST_INITIAL)) { - log_file_warning(filename, location.first_line, "System task `%s' outside initial block is unsupported.\n", str.c_str()); - delete_children(); - str = std::string(); - } - - // print messages if this a call to $display() or $write() family of functions if ((type == AST_TCALL) && (str == "$display" || str == "$displayb" || str == "$displayh" || str == "$displayo" || str == "$write" || str == "$writeb" || str == "$writeh" || str == "$writeo")) { - int default_base = 10; - if (str.back() == 'b') - default_base = 2; - else if (str.back() == 'o') - default_base = 8; - else if (str.back() == 'h') - default_base = 16; - - Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base); - if (str.substr(0, 8) == "$display") - fmt.append_string("\n"); - log("%s", fmt.render().c_str()); + if (!current_always) { + log_file_warning(filename, location.first_line, "System task `%s' outside initial or always block is unsupported.\n", str.c_str()); + } else if (current_always->type == AST_INITIAL) { + int default_base = 10; + if (str.back() == 'b') + default_base = 2; + else if (str.back() == 'o') + default_base = 8; + else if (str.back() == 'h') + default_base = 16; + + // when $display()/$write() functions are used in an initial block, print them during synthesis + Fmt fmt = processFormat(stage, /*sformat_like=*/false, default_base); + if (str.substr(0, 8) == "$display") + fmt.append_string("\n"); + log("%s", fmt.render().c_str()); + } else { + // when $display()/$write() functions are used in an always block, simplify the expressions and + // convert them to a special cell later in genrtlil + for (auto node : children) + while (node->simplify(true, false, stage, -1, false, false)) {} + return false; + } delete_children(); str = std::string(); diff --git a/kernel/constids.inc b/kernel/constids.inc index 39211d0c753..08b0ecdc2b4 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -22,6 +22,8 @@ X(always_ff) X(always_latch) X(anyconst) X(anyseq) +X(ARGS) +X(ARGS_WIDTH) X(ARST) X(ARST_POLARITY) X(ARST_VALUE) @@ -86,6 +88,7 @@ X(equiv_merged) X(equiv_region) X(extract_order) X(F) +X(FORMAT) X(force_downto) X(force_upto) X(fsm_encoding) @@ -233,6 +236,10 @@ X(TRANS_NUM) X(TRANSPARENCY_MASK) X(TRANSPARENT) X(TRANS_TABLE) +X(TRG) +X(TRG_ENABLE) +X(TRG_POLARITY) +X(TRG_WIDTH) X(T_RISE_MAX) X(T_RISE_MIN) X(T_RISE_TYP) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7011429ff5a..09fe0800078 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1720,6 +1720,17 @@ namespace { return; } + if (cell->type == ID($print)) { + param(ID(FORMAT)); + param_bool(ID::TRG_ENABLE); + param(ID::TRG_POLARITY); + port(ID::EN, 1); + port(ID::TRG, param(ID::TRG_WIDTH)); + port(ID::ARGS, param(ID::ARGS_WIDTH)); + check_expected(); + return; + } + if (cell->type == ID($_BUF_)) { port(ID::A,1); port(ID::Y,1); check_expected(); return; } if (cell->type == ID($_NOT_)) { port(ID::A,1); port(ID::Y,1); check_expected(); return; } if (cell->type == ID($_AND_)) { port(ID::A,1); port(ID::B,1); port(ID::Y,1); check_expected(); return; } From d51ecde8c2e488fc299d6033bbc18202ee5058de Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 16:33:45 +0000 Subject: [PATCH 212/303] clean: keep $print cells, since they have unmodelled side effects. --- passes/opt/opt_clean.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index cb2490dc72e..4da67cf630f 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -79,6 +79,9 @@ struct keep_cache_t if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule))) return true; + if (cell->type == ID($print)) + return true; + if (cell->has_keep_attr()) return true; From 3f8eab15bb7677e32aac1980e361a566be8d68de Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 29 Nov 2020 17:31:04 +0000 Subject: [PATCH 213/303] write_verilog: translate $print cells to $write tasks in always blocks. --- backends/verilog/verilog_backend.cc | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 5ff191a9c16..a6fd859a396 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -27,6 +27,7 @@ #include "kernel/sigtools.h" #include "kernel/ff.h" #include "kernel/mem.h" +#include "kernel/fmt.h" #include #include #include @@ -1753,6 +1754,57 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) return true; } + if (cell->type == ID($print)) + { + Fmt fmt = {}; + fmt.parse_rtlil(cell); + std::vector args = fmt.emit_verilog(); + + if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + f << stringf("%s" "always @(", indent.c_str()); + for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { + if (i != 0) + f << " or "; + if (cell->getParam(ID::TRG_POLARITY)[i]) + f << "posedge "; + else + f << "negedge "; + dump_sigspec(f, cell->getPort(ID::TRG)[i]); + } + f << ")\n"; + } else { + f << stringf("%s" "always @*\n", indent.c_str()); + } + + f << stringf("%s" " if (", indent.c_str()); + dump_sigspec(f, cell->getPort(ID::EN)); + f << stringf(")\n"); + + f << stringf("%s" " $write(", indent.c_str()); + bool first = true; + for (auto &arg : args) { + if (first) { + first = false; + } else { + f << ", "; + } + switch (arg.type) { + case VerilogFmtArg::STRING: + dump_const(f, RTLIL::Const(arg.str)); + break; + case VerilogFmtArg::INTEGER: + f << (arg.signed_ ? "$signed(" : "$unsigned("); + dump_sigspec(f, arg.sig); + f << ")"; + break; + default: log_abort(); + } + } + f << stringf(");\n"); + + return true; + } + // FIXME: $fsm return false; From 67052f62ec888fef2055ecca3da1c88123c6a1ed Mon Sep 17 00:00:00 2001 From: whitequark Date: Sat, 5 Dec 2020 22:26:25 +0000 Subject: [PATCH 214/303] fmt: add tests for Yosys evaluation of format expressions. --- Makefile | 1 + tests/fmt/.gitignore | 2 + tests/fmt/initial_display.v | 245 ++++++++++++++++++++++++++++++++++++ tests/fmt/run-test.sh | 6 + 4 files changed, 254 insertions(+) create mode 100644 tests/fmt/.gitignore create mode 100644 tests/fmt/initial_display.v create mode 100644 tests/fmt/run-test.sh diff --git a/Makefile b/Makefile index dab83bcbe56..7883cf2b9b8 100644 --- a/Makefile +++ b/Makefile @@ -882,6 +882,7 @@ endif +cd tests/memfile && bash run-test.sh +cd tests/verilog && bash run-test.sh +cd tests/xprop && bash run-test.sh $(SEEDOPT) + +cd tests/fmt && bash run-test.sh @echo "" @echo " Passed \"make test\"." @echo "" diff --git a/tests/fmt/.gitignore b/tests/fmt/.gitignore new file mode 100644 index 00000000000..07043e54799 --- /dev/null +++ b/tests/fmt/.gitignore @@ -0,0 +1,2 @@ +*.log +iverilog-initial_display* diff --git a/tests/fmt/initial_display.v b/tests/fmt/initial_display.v new file mode 100644 index 00000000000..26a39d0ec88 --- /dev/null +++ b/tests/fmt/initial_display.v @@ -0,0 +1,245 @@ +module m; + initial $display("<<>>"); + + initial $display("==> small unsigned %%d"); + initial $display(":%d:", 16'haa); + initial $display(":%-d:", 16'haa); + initial $display(":%+d:", 16'haa); + initial $display(":%+-d:", 16'haa); + initial $display(":%0d:", 16'haa); + initial $display(":%-0d:", 16'haa); + initial $display(":%+0d:", 16'haa); + initial $display(":%+-0d:", 16'haa); + initial $display(":%20d:", 16'haa); + initial $display(":%-20d:", 16'haa); + initial $display(":%+20d:", 16'haa); + initial $display(":%+-20d:", 16'haa); + initial $display(":%020d:", 16'haa); + initial $display(":%-020d:", 16'haa); + initial $display(":%+020d:", 16'haa); + initial $display(":%+-020d:", 16'haa); + + initial $display("==> big unsigned %%d"); + initial $display(":%d:", 16'haaaa); + initial $display(":%-d:", 16'haaaa); + initial $display(":%+d:", 16'haaaa); + initial $display(":%+-d:", 16'haaaa); + initial $display(":%0d:", 16'haaaa); + initial $display(":%-0d:", 16'haaaa); + initial $display(":%+0d:", 16'haaaa); + initial $display(":%+-0d:", 16'haaaa); + initial $display(":%20d:", 16'haaaa); + initial $display(":%-20d:", 16'haaaa); + initial $display(":%+20d:", 16'haaaa); + initial $display(":%+-20d:", 16'haaaa); + initial $display(":%020d:", 16'haaaa); + initial $display(":%-020d:", 16'haaaa); + initial $display(":%+020d:", 16'haaaa); + initial $display(":%+-020d:", 16'haaaa); + + initial $display("==> small signed %%d"); + initial $display(":%d:", 16'shaa); + initial $display(":%-d:", 16'shaa); + initial $display(":%+d:", 16'shaa); + initial $display(":%+-d:", 16'shaa); + initial $display(":%0d:", 16'shaa); + initial $display(":%-0d:", 16'shaa); + initial $display(":%+0d:", 16'shaa); + initial $display(":%+-0d:", 16'shaa); + initial $display(":%20d:", 16'shaa); + initial $display(":%-20d:", 16'shaa); + initial $display(":%+20d:", 16'shaa); + initial $display(":%+-20d:", 16'shaa); + initial $display(":%020d:", 16'shaa); + initial $display(":%-020d:", 16'shaa); + initial $display(":%+020d:", 16'shaa); + initial $display(":%+-020d:", 16'shaa); + + initial $display("==> big signed %%d"); + initial $display(":%d:", 16'shaaaa); + initial $display(":%-d:", 16'shaaaa); + initial $display(":%+d:", 16'shaaaa); + initial $display(":%+-d:", 16'shaaaa); + initial $display(":%0d:", 16'shaaaa); + initial $display(":%-0d:", 16'shaaaa); + initial $display(":%+0d:", 16'shaaaa); + initial $display(":%+-0d:", 16'shaaaa); + initial $display(":%20d:", 16'shaaaa); + initial $display(":%-20d:", 16'shaaaa); + initial $display(":%+20d:", 16'shaaaa); + initial $display(":%+-20d:", 16'shaaaa); + initial $display(":%020d:", 16'shaaaa); + initial $display(":%-020d:", 16'shaaaa); + initial $display(":%+020d:", 16'shaaaa); + initial $display(":%+-020d:", 16'shaaaa); + + initial $display("==> small unsigned %%h"); + initial $display(":%h:", 16'haa); + initial $display(":%-h:", 16'haa); + initial $display(":%0h:", 16'haa); + initial $display(":%-0h:", 16'haa); + initial $display(":%20h:", 16'haa); + initial $display(":%-20h:", 16'haa); + initial $display(":%020h:", 16'haa); + initial $display(":%-020h:", 16'haa); + + initial $display("==> big unsigned %%h"); + initial $display(":%h:", 16'haaaa); + initial $display(":%-h:", 16'haaaa); + initial $display(":%0h:", 16'haaaa); + initial $display(":%-0h:", 16'haaaa); + initial $display(":%20h:", 16'haaaa); + initial $display(":%-20h:", 16'haaaa); + initial $display(":%020h:", 16'haaaa); + initial $display(":%-020h:", 16'haaaa); + + initial $display("==> small signed %%h"); + initial $display(":%h:", 16'shaa); + initial $display(":%-h:", 16'shaa); + initial $display(":%0h:", 16'shaa); + initial $display(":%-0h:", 16'shaa); + initial $display(":%20h:", 16'shaa); + initial $display(":%-20h:", 16'shaa); + initial $display(":%020h:", 16'shaa); + initial $display(":%-020h:", 16'shaa); + + initial $display("==> big signed %%h"); + initial $display(":%h:", 16'shaaaa); + initial $display(":%-h:", 16'shaaaa); + initial $display(":%0h:", 16'shaaaa); + initial $display(":%-0h:", 16'shaaaa); + initial $display(":%20h:", 16'shaaaa); + initial $display(":%-20h:", 16'shaaaa); + initial $display(":%020h:", 16'shaaaa); + initial $display(":%-020h:", 16'shaaaa); + + initial $display("==> small unsigned %%o"); + initial $display(":%o:", 16'haa); + initial $display(":%-o:", 16'haa); + initial $display(":%0o:", 16'haa); + initial $display(":%-0o:", 16'haa); + initial $display(":%20o:", 16'haa); + initial $display(":%-20o:", 16'haa); + initial $display(":%020o:", 16'haa); + initial $display(":%-020o:", 16'haa); + + initial $display("==> big unsigned %%o"); + initial $display(":%o:", 16'haaaa); + initial $display(":%-o:", 16'haaaa); + initial $display(":%0o:", 16'haaaa); + initial $display(":%-0o:", 16'haaaa); + initial $display(":%20o:", 16'haaaa); + initial $display(":%-20o:", 16'haaaa); + initial $display(":%020o:", 16'haaaa); + initial $display(":%-020o:", 16'haaaa); + + initial $display("==> small signed %%o"); + initial $display(":%o:", 16'shaa); + initial $display(":%-o:", 16'shaa); + initial $display(":%0o:", 16'shaa); + initial $display(":%-0o:", 16'shaa); + initial $display(":%20o:", 16'shaa); + initial $display(":%-20o:", 16'shaa); + initial $display(":%020o:", 16'shaa); + initial $display(":%-020o:", 16'shaa); + + initial $display("==> big signed %%o"); + initial $display(":%o:", 16'shaaaa); + initial $display(":%-o:", 16'shaaaa); + initial $display(":%0o:", 16'shaaaa); + initial $display(":%-0o:", 16'shaaaa); + initial $display(":%20o:", 16'shaaaa); + initial $display(":%-20o:", 16'shaaaa); + initial $display(":%020o:", 16'shaaaa); + initial $display(":%-020o:", 16'shaaaa); + + initial $display("==> small unsigned %%b"); + initial $display(":%b:", 16'haa); + initial $display(":%-b:", 16'haa); + initial $display(":%0b:", 16'haa); + initial $display(":%-0b:", 16'haa); + initial $display(":%20b:", 16'haa); + initial $display(":%-20b:", 16'haa); + initial $display(":%020b:", 16'haa); + initial $display(":%-020b:", 16'haa); + + initial $display("==> big unsigned %%b"); + initial $display(":%b:", 16'haaaa); + initial $display(":%-b:", 16'haaaa); + initial $display(":%0b:", 16'haaaa); + initial $display(":%-0b:", 16'haaaa); + initial $display(":%20b:", 16'haaaa); + initial $display(":%-20b:", 16'haaaa); + initial $display(":%020b:", 16'haaaa); + initial $display(":%-020b:", 16'haaaa); + + initial $display("==> small signed %%b"); + initial $display(":%b:", 16'shaa); + initial $display(":%-b:", 16'shaa); + initial $display(":%0b:", 16'shaa); + initial $display(":%-0b:", 16'shaa); + initial $display(":%20b:", 16'shaa); + initial $display(":%-20b:", 16'shaa); + initial $display(":%020b:", 16'shaa); + initial $display(":%-020b:", 16'shaa); + + initial $display("==> big signed %%b"); + initial $display(":%b:", 16'shaaaa); + initial $display(":%-b:", 16'shaaaa); + initial $display(":%0b:", 16'shaaaa); + initial $display(":%-0b:", 16'shaaaa); + initial $display(":%20b:", 16'shaaaa); + initial $display(":%-20b:", 16'shaaaa); + initial $display(":%020b:", 16'shaaaa); + initial $display(":%-020b:", 16'shaaaa); + + initial $display("===> %%s"); + initial $display(":%10s:", "foo"); + initial $display(":%010s:", "foo"); + initial $display(":%-10s:", "foo"); + initial $display(":%-010s:", "foo"); + + initial $display("===> %%c"); + initial $display(":%10c:", "foo"); + initial $display(":%010c:", "foo"); + initial $display(":%-10c:", "foo"); + initial $display(":%-010c:", "foo"); + + initial $display("==> aliases"); + initial $display(":%x:", 16'shaa); + initial $display(":%X:", 16'shaa); + initial $display(":%H:", 16'shaa); + initial $display(":%O:", 16'shaa); + initial $display(":%B:", 16'shaa); + + initial $display("==> x/z"); + initial $display(":%d:", 16'b1010101010101010); + initial $display(":%d:", 16'b101010101010101x); + initial $display(":%d:", 16'b101010101010101z); + initial $display(":%x:", 16'b1010101010101010); + initial $display(":%x:", 16'b101010101010101x); + initial $display(":%x:", 16'b101010101010101z); + initial $display(":%x:", 16'b101010101010xxxx); + initial $display(":%x:", 16'b101010101010zzzz); + initial $display(":%o:", 16'b1010101010101010); + initial $display(":%o:", 16'b101010101010101x); + initial $display(":%o:", 16'b101010101010101z); + initial $display(":%o:", 16'b1010101010101xxx); + initial $display(":%o:", 16'b1010101010101zzz); + initial $display(":%b:", 16'b1010101010101010); + initial $display(":%b:", 16'b101010101010101x); + initial $display(":%b:", 16'b101010101010101z); + + initial $display("==> default base"); + initial $displayh(16'haa); + initial $displayo(16'haa); + initial $displayb(16'haa); + + initial $display("==> write/format"); + initial $display("%d", 1, "%d", 1); + // this one hits a bug in iverilog: + // initial $display("%s", $sformatf("%d", 1, "%d", 1)); + + initial $display("<<>>"); + +endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh new file mode 100644 index 00000000000..c6bd111b2e2 --- /dev/null +++ b/tests/fmt/run-test.sh @@ -0,0 +1,6 @@ +#!/bin/bash -eu + +../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log +iverilog -o iverilog-initial_display initial_display.v +./iverilog-initial_display >iverilog-initial_display.log +diff yosys-initial_display.log iverilog-initial_display.log From c28588068407b4e5eec33c6fd5c6f5c97b7ae9d4 Mon Sep 17 00:00:00 2001 From: whitequark Date: Sun, 6 Dec 2020 04:08:44 +0000 Subject: [PATCH 215/303] fmt: add tests for Verilog round trip of format expressions. --- tests/fmt/.gitignore | 3 ++- tests/fmt/always_display.v | 17 +++++++++++++++ tests/fmt/roundtrip.v | 22 ++++++++++++++++++++ tests/fmt/roundtrip_tb.v | 13 ++++++++++++ tests/fmt/run-test.sh | 42 +++++++++++++++++++++++++++++++++++++- 5 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/fmt/always_display.v create mode 100644 tests/fmt/roundtrip.v create mode 100644 tests/fmt/roundtrip_tb.v diff --git a/tests/fmt/.gitignore b/tests/fmt/.gitignore index 07043e54799..a36a15ec464 100644 --- a/tests/fmt/.gitignore +++ b/tests/fmt/.gitignore @@ -1,2 +1,3 @@ *.log -iverilog-initial_display* +iverilog-* +yosys-* diff --git a/tests/fmt/always_display.v b/tests/fmt/always_display.v new file mode 100644 index 00000000000..593c5afc08c --- /dev/null +++ b/tests/fmt/always_display.v @@ -0,0 +1,17 @@ +module m(input clk, rst, en, input [31:0] data); + +`ifdef EVENT_CLK + always @(posedge clk) +`endif +`ifdef EVENT_CLK_RST + always @(posedge clk or negedge rst) +`endif +`ifdef EVENT_STAR + always @(*) +`endif +`ifdef COND_EN + if (en) +`endif + $display("data=%d", data); + +endmodule diff --git a/tests/fmt/roundtrip.v b/tests/fmt/roundtrip.v new file mode 100644 index 00000000000..7b50039cd26 --- /dev/null +++ b/tests/fmt/roundtrip.v @@ -0,0 +1,22 @@ +module m(input clk, input `SIGN [31:0] data); + + always @(posedge clk) + // All on a single line to avoid order effects. +`ifdef BASE_DEC + $display(":%d:%-d:%+d:%+-d:%0d:%-0d:%+0d:%+-0d:%20d:%-20d:%+20d:%+-20d:%020d:%-020d:%+020d:%+-020d:", + data, data, data, data, data, data, data, data, data, data, data, data, data, data, data, data); +`endif +`ifdef BASE_HEX + $display(":%h:%-h:%0h:%-0h:%20h:%-20h:%020h:%-020h:", + data, data, data, data, data, data, data, data); +`endif +`ifdef BASE_OCT + $display(":%o:%-o:%0o:%-0o:%20o:%-20o:%020o:%-020o:", + data, data, data, data, data, data, data, data); +`endif +`ifdef BASE_BIN + $display(":%b:%-b:%0b:%-0b:%20b:%-20b:%020b:%-020b:", + data, data, data, data, data, data, data, data); +`endif + +endmodule diff --git a/tests/fmt/roundtrip_tb.v b/tests/fmt/roundtrip_tb.v new file mode 100644 index 00000000000..988b8d8c2c0 --- /dev/null +++ b/tests/fmt/roundtrip_tb.v @@ -0,0 +1,13 @@ +module tb; + reg clk = 1'b0; + reg [31:0] data; + + m dut(.clk(clk), .data(data)); + + initial begin + data = 32'haa; + #10; clk = 1; #10; clk = 0; + data = 32'haaaa; + #10; clk = 1; #10; clk = 0; + end +endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index c6bd111b2e2..850dbd53eed 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -1,6 +1,46 @@ -#!/bin/bash -eu +#!/bin/bash -ex ../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log iverilog -o iverilog-initial_display initial_display.v ./iverilog-initial_display >iverilog-initial_display.log diff yosys-initial_display.log iverilog-initial_display.log + +test_always_display () { + local subtest=$1; shift + ../../yosys $* always_display.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-1.v + ../../yosys yosys-always_display-${subtest}-1.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-2.v + diff yosys-always_display-${subtest}-1.v yosys-always_display-${subtest}-2.v +} + +test_always_display clk -DEVENT_CLK +test_always_display clk_rst -DEVENT_CLK_RST +test_always_display star -DEVENT_STAR + +test_always_display clk_en -DEVENT_CLK -DCOND_EN +test_always_display clk_rst_en -DEVENT_CLK_RST -DCOND_EN +test_always_display star_en -DEVENT_STAR -DCOND_EN + +test_roundtrip () { + local subtest=$1; shift + ../../yosys $* roundtrip.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-1.v + ../../yosys yosys-roundtrip-${subtest}-1.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-2.v + diff yosys-roundtrip-${subtest}-1.v yosys-roundtrip-${subtest}-2.v + + iverilog $* -o iverilog-roundtrip-${subtest} roundtrip.v roundtrip_tb.v + ./iverilog-roundtrip-${subtest} >iverilog-roundtrip-${subtest}.log + iverilog $* -o iverilog-roundtrip-${subtest}-1 yosys-roundtrip-${subtest}-1.v roundtrip_tb.v + ./iverilog-roundtrip-${subtest}-1 >iverilog-roundtrip-${subtest}-1.log + iverilog $* -o iverilog-roundtrip-${subtest}-2 yosys-roundtrip-${subtest}-2.v roundtrip_tb.v + ./iverilog-roundtrip-${subtest}-1 >iverilog-roundtrip-${subtest}-2.log + diff iverilog-roundtrip-${subtest}.log iverilog-roundtrip-${subtest}-1.log + diff iverilog-roundtrip-${subtest}-1.log iverilog-roundtrip-${subtest}-2.log +} + +test_roundtrip dec_unsigned -DBASE_DEC -DSIGN="" +test_roundtrip dec_signed -DBASE_DEC -DSIGN="signed" +test_roundtrip hex_unsigned -DBASE_HEX -DSIGN="" +test_roundtrip hex_signed -DBASE_HEX -DSIGN="signed" +test_roundtrip oct_unsigned -DBASE_HEX -DSIGN="" +test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" +test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" +test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" From 1eff84cb926c7916b6127badf2b7cec37a7a7e7f Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:50:45 +1000 Subject: [PATCH 216/303] fmt: ensure test exits on fail shebang not honoured when directly called with "bash run-test.sh". --- tests/fmt/run-test.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 850dbd53eed..e3e9972b1a6 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -1,4 +1,6 @@ -#!/bin/bash -ex +#!/bin/bash + +set -ex ../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log iverilog -o iverilog-initial_display initial_display.v From 9db73aa87282bacc710be05c8455fd09308bbdf7 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:09 +1000 Subject: [PATCH 217/303] celltypes: add `$print` Otherwise, the \TRG connection is pruned by CleanZeroWidthPass. --- kernel/celltypes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 63e7408c142..4a0621a7386 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -101,6 +101,7 @@ struct CellTypes setup_type(ID($specify2), {ID::EN, ID::SRC, ID::DST}, pool(), true); setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool(), true); setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool(), true); + setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool()); } void setup_internals_eval() From 51d9b73107254dccc5b8efd3924f5a2372deaa74 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:11 +1000 Subject: [PATCH 218/303] fmt: tests completing again We need to invoke "read_verilog" manually, since the default action on input files is to defer processing. Under such conditions, we never simplify the AST, and initial $prints never execute. --- tests/fmt/run-test.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index e3e9972b1a6..0757d7f2ae5 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -2,15 +2,15 @@ set -ex -../../yosys initial_display.v | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log +../../yosys -p 'read_verilog initial_display.v' | awk '/<<>>/,/<<>>/ {print $0}' >yosys-initial_display.log iverilog -o iverilog-initial_display initial_display.v ./iverilog-initial_display >iverilog-initial_display.log diff yosys-initial_display.log iverilog-initial_display.log test_always_display () { local subtest=$1; shift - ../../yosys $* always_display.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-1.v - ../../yosys yosys-always_display-${subtest}-1.v -p 'proc; opt_expr -mux_bool; clean' -o yosys-always_display-${subtest}-2.v + ../../yosys -p "read_verilog $* always_display.v; proc; opt_expr -mux_bool; clean" -o yosys-always_display-${subtest}-1.v + ../../yosys -p "read_verilog yosys-always_display-${subtest}-1.v; proc; opt_expr -mux_bool; clean" -o yosys-always_display-${subtest}-2.v diff yosys-always_display-${subtest}-1.v yosys-always_display-${subtest}-2.v } @@ -24,8 +24,8 @@ test_always_display star_en -DEVENT_STAR -DCOND_EN test_roundtrip () { local subtest=$1; shift - ../../yosys $* roundtrip.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-1.v - ../../yosys yosys-roundtrip-${subtest}-1.v -p 'proc; clean' -o yosys-roundtrip-${subtest}-2.v + ../../yosys -p "read_verilog $* roundtrip.v; proc; clean" -o yosys-roundtrip-${subtest}-1.v + ../../yosys -p "read_verilog yosys-roundtrip-${subtest}-1.v; proc; clean" -o yosys-roundtrip-${subtest}-2.v diff yosys-roundtrip-${subtest}-1.v yosys-roundtrip-${subtest}-2.v iverilog $* -o iverilog-roundtrip-${subtest} roundtrip.v roundtrip_tb.v From 28bd3a4b5d24742567049875ef7456cf0633f64c Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:12 +1000 Subject: [PATCH 219/303] fmt: don't overrun fmt string buffer For input like "{", "{1", etc., we would exit the loop due to `i < fmt.size()` no longer being the case, and then check if `++i == fmt.size()`. That would increment i to `fmt.size() + 1`, and so execution continues. The intention is to move i beyond the ':', so we do it only in that case instead. --- kernel/fmt.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 924a23a0c1e..b24fe59b277 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -55,12 +55,13 @@ void Fmt::parse_rtlil(RTLIL::Cell *cell) { arg_size *= 10; arg_size += fmt[i] - '0'; } else if (fmt[i] == ':') { + ++i; break; } else { log_assert(false && "Unexpected character in format substitution"); } } - if (++i == fmt.size()) + if (i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); if ((size_t)args.size() < arg_size) From 3c8f84b70bc94fe64ce3ca014031a16e68ced773 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:13 +1000 Subject: [PATCH 220/303] fmt: fix another overrun --- kernel/fmt.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index b24fe59b277..0f5ebd94e83 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -107,9 +107,10 @@ void Fmt::parse_rtlil(RTLIL::Cell *cell) { } else { log_assert(false && "Unexpected character in format substitution"); } + ++i; break; } - if (++i == fmt.size()) + if (i == fmt.size()) log_assert(false && "Unexpected end in format substitution"); if (part.type == FmtPart::INTEGER) { From 289f8d42cb7d8a0e5948c1bec73ea7a47ad2c370 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:13 +1000 Subject: [PATCH 221/303] fmt: correct parsing of {{ and }} for brace literals --- kernel/fmt.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 0f5ebd94e83..952511eeb15 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -36,11 +36,13 @@ void Fmt::parse_rtlil(RTLIL::Cell *cell) { FmtPart part; for (size_t i = 0; i < fmt.size(); i++) { - if (fmt.substr(i, 2) == "}}") + if (fmt.substr(i, 2) == "}}") { part.str += '}'; - else if (fmt.substr(i, 2) == "{{") + ++i; + } else if (fmt.substr(i, 2) == "{{") { part.str += '{'; - else if (fmt[i] == '}') + ++i; + } else if (fmt[i] == '}') log_assert(false && "Unexpected '}' in format string"); else if (fmt[i] == '{') { if (!part.str.empty()) { From 2d7b8f71ccdb651cb1e12db2700ae7ece4cdb1a3 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:14 +1000 Subject: [PATCH 222/303] docs: first pass $print documentation --- docs/source/CHAPTER_CellLib.rst | 68 +++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index c8904086879..31d114854eb 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -627,6 +627,74 @@ Add information about ``$assert``, ``$assume``, ``$live``, ``$fair``, Add information about ``$ff`` and ``$_FF_`` cells. +Debugging cells +~~~~~~~~~~~~~~~ + +The ``$print`` cell is used to log the values of signals, akin to (and +translatable to) the ``$display`` and ``$write`` tasks in Verilog. It +has parameters: + +``\FORMAT`` + The internal format string. + +``\ARGS_WIDTH`` + The number of args referenced by the format string/in ``\ARGS`` port. + XXX is this actually bitwidth? + +``\TRG_ENABLE`` + True if only triggered on ``\TRG``; false if always. + +If ``\TRG_ENABLE`` is true: + +``\TRG_WIDTH`` + The number of bits in the ``\TRG`` port. + +``\TRG_POLARITY`` + A bitfield for each signal in ``\TRG``, 1 if STp (posedge), 0 if + STn (negedge). + +Ports: + +``\TRG`` + The signals defining when to print. + +``\EN`` + Enable signal for the whole cell. + +``\ARGS`` + The values to be displayed, in format string order. + +The format string has format specifiers as following: + +``{`` size ``:`` justify padding width? base options ``}`` + +size + Signal size in bits. + +justify + ``>`` for right-justified, ``<`` for left-justified. + +width + The number of characters wide to pad to. + +base + ``b`` for base-2 integers (binary), ``o`` for base-8 integers + (octal), ``d`` for base-10 integers (decimal), ``h`` for base-16 + integers (hexadecimal), or ``c`` for ASCII characters/strings. + +options + Only valid for integers, and is an optional ``+`` if a + leading plus should be included for non-negatives (decimals only), + an optional ``0`` if the number should be zero-padded to its signal + size before any padding/justification (non-decimals only), and then + either ``u`` or ``s`` to specify if the value should be treated as + unsigned or signed respectively. This distinction is only respected + when rendering decimals. + +Literal ``{`` and ``}`` are written as ``{{`` and ``}}``. + +Everything else is passed through unchanged. + .. _sec:celllib_gates: Gates From 1a222cb163ac88f95848cc8fd843011207e6b4ff Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:15 +1000 Subject: [PATCH 223/303] fmt: function name typo --- kernel/fmt.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 952511eeb15..68725c136f5 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -214,7 +214,7 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { cell->setPort(ID(ARGS), args); } -static size_t compute_requried_decimal_places(size_t size, bool signed_) +static size_t compute_required_decimal_places(size_t size, bool signed_) { BigUnsigned max; if (!signed_) @@ -234,7 +234,7 @@ static size_t compute_requried_decimal_places(size_t size, bool signed_) static void apply_verilog_automatic_sizing(FmtPart &part) { if (part.base == 10) { - size_t places = compute_requried_decimal_places(part.sig.size(), part.signed_); + size_t places = compute_required_decimal_places(part.sig.size(), part.signed_); part.padding = ' '; part.width = std::max(part.width, places); } else { From d9e4582558b84f0cacb64b3e4a1e5d67854ddbd2 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:15 +1000 Subject: [PATCH 224/303] fmt: handle part with unspecified padding in `emit_rtlil` e.g. `$displayh(8'ha)` won't have a padding set, because it just gets `lzero` set instead by `compute_required_decimal_places`. It also doesn't have a width. In this case, we can just fill in a dummy (unused) padding. Either space or zero would work, but space is a bit more distinct given the width field follows. Also omit writing the width if it's zero. This makes the emitted ilang a little cleaner in places; `{8:> h0u}` is the output for this example, now. The other possible extreme would be `{8:>00h0u}`. --- kernel/fmt.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 68725c136f5..41de4939230 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -183,9 +183,10 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { else if (part.justify == FmtPart::LEFT) fmt += '<'; else log_abort(); - log_assert(part.padding == '0' || part.padding == ' '); - fmt += part.padding; - fmt += std::to_string(part.width); + log_assert(part.width == 0 || part.padding != '\0'); + fmt += part.padding != '\0' ? part.padding : ' '; + if (part.width > 0) + fmt += std::to_string(part.width); if (part.type == FmtPart::INTEGER) { switch (part.base) { case 2: fmt += 'b'; break; From 202c3776e240557e7e283cd7c14502ab0caab53b Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:16 +1000 Subject: [PATCH 225/303] docs: elaborate $print documentation --- docs/source/CHAPTER_CellLib.rst | 109 ++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index 31d114854eb..0fae4f44b6f 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -631,32 +631,32 @@ Debugging cells ~~~~~~~~~~~~~~~ The ``$print`` cell is used to log the values of signals, akin to (and -translatable to) the ``$display`` and ``$write`` tasks in Verilog. It -has parameters: +translatable to) the ``$display`` and ``$write`` family of tasks in Verilog. It +has the following parameters: ``\FORMAT`` - The internal format string. + The internal format string. The syntax is described below. ``\ARGS_WIDTH`` - The number of args referenced by the format string/in ``\ARGS`` port. - XXX is this actually bitwidth? + The width (in bits) of the signal on the ``\ARGS`` port. ``\TRG_ENABLE`` - True if only triggered on ``\TRG``; false if always. + True if only triggered on specific signals defined in ``\TRG``; false if + executed on every step. -If ``\TRG_ENABLE`` is true: +If ``\TRG_ENABLE`` is true, the following parameters are also set: ``\TRG_WIDTH`` The number of bits in the ``\TRG`` port. ``\TRG_POLARITY`` - A bitfield for each signal in ``\TRG``, 1 if STp (posedge), 0 if - STn (negedge). + For each bit in ``\TRG``, 1 if that signal is positive-edge triggered, 0 if + negative-edge triggered. Ports: ``\TRG`` - The signals defining when to print. + The signals that control when this ``$print`` cell is triggered. ``\EN`` Enable signal for the whole cell. @@ -664,36 +664,89 @@ Ports: ``\ARGS`` The values to be displayed, in format string order. -The format string has format specifiers as following: +Format string syntax +^^^^^^^^^^^^^^^^^^^^ -``{`` size ``:`` justify padding width? base options ``}`` +The format string syntax resembles Python f-strings. Regular text is passed +through unchanged until a format specifier is reached, starting with a ``{``. + +Format specifiers have the following syntax. Unless noted, all items are +required: + +``{`` + Denotes the start of the format specifier. size - Signal size in bits. + Signal size in bits; this many bits are consumed from the ``\ARGS`` port by + this specifier. + +``:`` + Separates the size from the remaining items. justify ``>`` for right-justified, ``<`` for left-justified. -width - The number of characters wide to pad to. +padding + ``0`` for zero-padding, or a space for space-padding. + +width\ *?* + (optional) The number of characters wide to pad to. base - ``b`` for base-2 integers (binary), ``o`` for base-8 integers - (octal), ``d`` for base-10 integers (decimal), ``h`` for base-16 - integers (hexadecimal), or ``c`` for ASCII characters/strings. - -options - Only valid for integers, and is an optional ``+`` if a - leading plus should be included for non-negatives (decimals only), - an optional ``0`` if the number should be zero-padded to its signal - size before any padding/justification (non-decimals only), and then - either ``u`` or ``s`` to specify if the value should be treated as - unsigned or signed respectively. This distinction is only respected + * ``b`` for base-2 integers (binary) + * ``o`` for base-8 integers (octal) + * ``d`` for base-10 integers (decimal) + * ``h`` for base-16 integers (hexadecimal) + * ``c`` for ASCII characters/strings + +For integers, these items follow: + +``+``\ *?* + (optional, decimals only) Include a leading plus for non-negative numbers. + This can assist with symmetry with negatives in tabulated output. + +``0``\ *?* + (optional, non-decimals only) Zero-pad the number to fit the signal's + largest value before any further padding/justification. + +signedness + ``u`` for unsigned, ``s`` for signed. This distinction is only respected when rendering decimals. -Literal ``{`` and ``}`` are written as ``{{`` and ``}}``. +ASCII characters/strings have no special options, but the signal size must be +divisible by 8. + +Finally: + +``}`` + Denotes the end of the format specifier. + +Some example format specifiers: + ++ ``{8:>02hu}`` - 8-bit unsigned integer rendered as hexadecimal, + right-justified, zero-padded to 2 characters wide. ++ ``{32:< 15d+s}`` - 32-bit signed integer rendered as decimal, left-justified, + space-padded to 15 characters wide, positive values prefixed with ``+``. ++ ``{16:< 10h0u}`` - 16-bit unsigned integer rendered as hexadecimal, + zero-padded to fit the largest signal value (4 characters for hex), + left-justified, space-padded to 10 characters wide. + +To include literal ``{`` and ``}`` characters in your format string, use ``{{`` +and ``}}`` respectively. + +It is an error for a format string to consume more or less bits from ``\ARGS`` +than the port width. + +Note that further restrictions on allowable combinations of options may apply +depending on the backend used. + +For example, Verilog does not have a format specifier that allows zero-padding a +string (i.e. more than 1 ASCII character), though zero-padding a single +character is permitted. -Everything else is passed through unchanged. +Thus, while the RTLIL format specifier ``{8:>02c}`` translates to ``%02c``, +``{16:>02c}`` cannot be represented in Verilog and will fail to emit. In this +case, ``{16:> 02c}`` must be used, which translates to ``%2s``. .. _sec:celllib_gates: From 095b093f4a58794becba06939a10a530c6758f70 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:17 +1000 Subject: [PATCH 226/303] cxxrtl: first pass of $print impl --- backends/cxxrtl/cxxrtl.h | 237 ++++++++++++++++++++++++++++++ backends/cxxrtl/cxxrtl_backend.cc | 52 ++++++- kernel/fmt.cc | 63 +++++++- kernel/fmt.h | 4 +- 4 files changed, 353 insertions(+), 3 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 5d0596f0d61..6d955fe9bfb 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -518,6 +518,14 @@ struct value : public expr_base> { return count; } + size_t chunks_used() const { + for (size_t n = chunks; n > 0; n--) { + if (data[n - 1] != 0) + return n; + } + return 0; + } + template std::pair, bool /*CarryOut*/> alu(const value &other) const { value result; @@ -575,6 +583,140 @@ struct value : public expr_base> { result.data[result.chunks - 1] &= result.msb_mask; return result; } + + // parallel to BigUnsigned::divideWithRemainder; quotient is stored in q, + // *this is left with the remainder. See that function for commentary describing + // how/why this works. + void divideWithRemainder(const value &b, value &q) { + assert(this != &q); + + if (this == &b || &q == &b) { + value tmpB(b); + divideWithRemainder(tmpB, q); + return; + } + + q = value {0u}; + + size_t blen = b.chunks_used(); + if (blen == 0) { + return; + } + + size_t len = chunks_used(); + if (len < blen) { + return; + } + + size_t i, j, k; + size_t i2; + chunk_t temp; + bool borrowIn, borrowOut; + + size_t origLen = len; + len++; + chunk::type blk[len]; + std::copy(data, data + origLen, blk); + blk[origLen] = 0; + chunk::type subtractBuf[len]; + std::fill(subtractBuf, subtractBuf + len, 0); + + size_t qlen = origLen - blen + 1; + + i = qlen; + while (i > 0) { + i--; + i2 = chunk::bits; + while (i2 > 0) { + i2--; + for (j = 0, k = i, borrowIn = false; j <= blen; j++, k++) { + temp = blk[k] - getShiftedBlock(b, j, i2); + borrowOut = (temp > blk[k]); + if (borrowIn) { + borrowOut |= (temp == 0); + temp--; + } + subtractBuf[k] = temp; + borrowIn = borrowOut; + } + for (; k < origLen && borrowIn; k++) { + borrowIn = (blk[k] == 0); + subtractBuf[k] = blk[k] - 1; + } + if (!borrowIn) { + q.data[i] |= (chunk::type(1) << i2); + while (k > i) { + k--; + blk[k] = subtractBuf[k]; + } + } + } + } + + std::copy(blk, blk + origLen, data); + std::fill(blk + origLen, blk + chunks, 0); + } + + static chunk::type getShiftedBlock(const value &num, size_t x, size_t y) { + chunk::type part1 = (x == 0 || y == 0) ? 0 : (num.data[x - 1] >> (chunk::bits - y)); + chunk::type part2 = (x == num.chunks) ? 0 : (num.data[x] << y); + return part1 | part2; + } + + // parallel to BigInteger::divideWithRemainder; quotient is stored in q, + // *this is left with the remainder. See that function for commentary describing + // how/why this works. + void signedDivideWithRemainder(const value &b, value &q) { + assert(this != &q); + + if (this == &b || &q == &b) { + value tmpB(b); + signedDivideWithRemainder(tmpB, q); + return; + } + + if (b.is_zero()) { + q = value{0u}; + return; + } + + if (is_zero()) { + q = value{0u}; + return; + } + + // BigInteger has a separate 'mag' to its sign. We don't, so the lazy + // approach is to improvise said. + auto mag = *this; + bool neg = mag.is_neg(); + if (neg) + mag = mag.neg(); + + auto bmag = b; + bool bneg = bmag.is_neg(); + if (bneg) + bmag = bmag.neg(); + + bool qneg = false; + if (neg != b.is_neg()) { + qneg = true; + mag = mag.sub(value{1u}); + } + + mag.divideWithRemainder(bmag, q); + + if (neg != bneg) { + q = q.add(value{1u}); + mag = bmag.sub(mag); + mag = mag.sub(value{1u}); + } + + neg = bneg; + + *this = neg ? mag.neg() : mag; + if (qneg) + q = q.neg(); + } }; // Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here. @@ -707,6 +849,101 @@ std::ostream &operator<<(std::ostream &os, const value &val) { return os; } +template +struct value_formatted { + const value &val; + bool character; + bool justify_left; + char padding; + int width; + int base; + bool signed_; + bool lzero; + bool plus; + + value_formatted(const value &val, bool character, bool justify_left, char padding, int width, int base, bool signed_, bool lzero, bool plus) : + val(val), character(character), justify_left(justify_left), padding(padding), width(width), base(base), signed_(signed_), lzero(lzero), plus(plus) {} + value_formatted(const value_formatted &) = delete; + value_formatted &operator=(const value_formatted &rhs) = delete; +}; + +template +std::ostream &operator<<(std::ostream &os, const value_formatted &vf) +{ + value val = vf.val; + + std::string buf; + + // We might want to replace some of these bit() calls with direct + // chunk access if it turns out to be slow enough to matter. + + if (!vf.character) { + size_t width = Bits; + if (!vf.lzero && vf.base != 10) { + width = 0; + for (size_t index = 0; index < Bits; index++) + if (val.bit(index)) + width = index + 1; + } + + if (vf.base == 2) { + for (size_t i = width; i > 0; i--) + buf += (val.bit(i - 1) ? '1' : '0'); + } else if (vf.base == 8 || vf.base == 16) { + size_t step = (vf.base == 16) ? 4 : 3; + for (size_t index = 0; index < width; index += step) { + uint8_t value = val.bit(index) | (val.bit(index + 1) << 1) | (val.bit(index + 2) << 2); + if (step == 4) + value |= val.bit(index + 3) << 3; + buf += "0123456789abcdef"[value]; + } + std::reverse(buf.begin(), buf.end()); + } else if (vf.base == 10) { + bool negative = vf.signed_ && val.is_neg(); + if (negative) + val = val.neg(); + if (val.is_zero()) + buf += '0'; + // TODO: rigorously check our signed behaviour here + while (!val.is_zero()) { + value quotient; + val.signedDivideWithRemainder(value{10u}, quotient); + buf += '0' + val.template slice<3, 0>().val().template get(); + val = quotient; + } + if (negative || vf.plus) + buf += negative ? '-' : '+'; + std::reverse(buf.begin(), buf.end()); + } else assert(false); + } else { + buf.reserve(Bits/8); + for (int i = 0; i < Bits; i += 8) { + char ch = 0; + for (int j = 0; j < 8 && i + j < int(Bits); j++) + if (val.bit(i + j)) + ch |= 1 << j; + if (ch != 0) + buf.append({ch}); + } + std::reverse(buf.begin(), buf.end()); + } + + assert(vf.width == 0 || vf.padding != '\0'); + if (!vf.justify_left && buf.size() < vf.width) { + size_t pad_width = vf.width - buf.size(); + if (vf.padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + os << buf.front(); + buf.erase(0, 1); + } + os << std::string(pad_width, vf.padding); + } + os << buf; + if (vf.justify_left && buf.size() < vf.width) + os << std::string(vf.width - buf.size(), vf.padding); + + return os; +} + template struct wire { static constexpr size_t bits = Bits; diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 1b13985ab4e..4986836b9f8 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -24,6 +24,7 @@ #include "kernel/celltypes.h" #include "kernel/mem.h" #include "kernel/log.h" +#include "kernel/fmt.h" USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN @@ -217,7 +218,7 @@ bool is_internal_cell(RTLIL::IdString type) bool is_effectful_cell(RTLIL::IdString type) { - return type.isPublic(); + return type.isPublic() || type == ID($print); } bool is_cxxrtl_blackbox_cell(const RTLIL::Cell *cell) @@ -1036,6 +1037,17 @@ struct CxxrtlWorker { f << ".val()"; } + void dump_print(const RTLIL::Cell *cell) + { + Fmt fmt = {}; + fmt.parse_rtlil(cell); + + // TODO: we may want to configure the output stream + f << indent << "std::cout"; + fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); + f << ";\n"; + } + void dump_inlined_cells(const std::vector &cells) { if (cells.empty()) { @@ -1202,6 +1214,34 @@ struct CxxrtlWorker { f << " = "; dump_cell_expr(cell, for_debug); f << ";\n"; + // $print cell + } else if (cell->type == ID($print)) { + log_assert(!for_debug); + f << indent << "if ("; + if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + f << '('; + for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { + RTLIL::SigBit trg_bit = cell->getPort(ID::TRG)[i]; + trg_bit = sigmaps[trg_bit.wire->module](trg_bit); + log_assert(trg_bit.wire); + + if (i != 0) + f << " || "; + + if (cell->getParam(ID::TRG_POLARITY)[i] == State::S1) + f << "posedge_"; + else + f << "negedge_"; + f << mangle(trg_bit); + } + f << ") && "; + } + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << " == value<1>{1u}) {\n"; + inc_indent(); + dump_print(cell); + dec_indent(); + f << indent << "}\n"; // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); @@ -2601,6 +2641,16 @@ struct CxxrtlWorker { register_edge_signal(sigmap, cell->getPort(ID::CLK), cell->parameters[ID::CLK_POLARITY].as_bool() ? RTLIL::STp : RTLIL::STn); } + + // $print cells may be triggered on posedge/negedge events. + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) { + for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { + RTLIL::SigBit trg = cell->getPort(ID::TRG).extract(i, 1); + if (is_valid_clock(trg)) + register_edge_signal(sigmap, trg, + cell->parameters[ID::TRG_POLARITY][i] == RTLIL::S1 ? RTLIL::STp : RTLIL::STn); + } + } } for (auto &mem : memories) { diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 41de4939230..074ec08ca09 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -29,7 +29,7 @@ void Fmt::append_string(const std::string &str) { parts.push_back(part); } -void Fmt::parse_rtlil(RTLIL::Cell *cell) { +void Fmt::parse_rtlil(const RTLIL::Cell *cell) { std::string fmt = cell->getParam(ID(FORMAT)).decode_string(); RTLIL::SigSpec args = cell->getPort(ID(ARGS)); parts.clear(); @@ -465,6 +465,67 @@ std::vector Fmt::emit_verilog() const return args; } +void Fmt::emit_cxxrtl(std::ostream &f, std::function emit_sig) const +{ + for (auto &part : parts) { + switch (part.type) { + case FmtPart::STRING: + f << " << \""; + for (char c : part.str) { + switch (c) { + case '\\': + YS_FALLTHROUGH + case '"': + f << '\\' << c; + break; + case '\a': + f << "\\a"; + break; + case '\b': + f << "\\b"; + break; + case '\f': + f << "\\f"; + break; + case '\n': + f << "\\n"; + break; + case '\r': + f << "\\r"; + break; + case '\t': + f << "\\t"; + break; + case '\v': + f << "\\v"; + break; + default: + f << c; + break; + } + } + f << '"'; + break; + + case FmtPart::INTEGER: + case FmtPart::CHARACTER: { + f << " << value_formatted<" << part.sig.size() << ">("; + emit_sig(part.sig); + f << ", " << (part.type == FmtPart::CHARACTER); + f << ", " << (part.justify == FmtPart::LEFT); + f << ", (char)" << (int)part.padding; + f << ", " << part.width; + f << ", " << part.base; + f << ", " << part.signed_; + f << ", " << part.lzero; + f << ", " << part.plus; + f << ')'; + break; + } + } + } +} + std::string Fmt::render() const { std::string str; diff --git a/kernel/fmt.h b/kernel/fmt.h index c85da19c01b..00b8d9b594e 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -76,12 +76,14 @@ struct Fmt { void append_string(const std::string &str); - void parse_rtlil(RTLIL::Cell *cell); + void parse_rtlil(const RTLIL::Cell *cell); void emit_rtlil(RTLIL::Cell *cell) const; void parse_verilog(const std::vector &args, bool sformat_like, int default_base, RTLIL::IdString task_name, RTLIL::IdString module_name); std::vector emit_verilog() const; + void emit_cxxrtl(std::ostream &f, std::function emit_sig) const; + std::string render() const; }; From b0f69f2cd5fa37c8b6eaf7b30a3c9297af87bf58 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:18 +1000 Subject: [PATCH 227/303] tests: test cxxrtl against iverilog (and uncover bug!) --- kernel/fmt.h | 2 +- tests/fmt/always_full.v | 239 ++++++++++++++++++++++++++++++++++++ tests/fmt/always_full_tb.cc | 15 +++ tests/fmt/always_full_tb.v | 14 +++ tests/fmt/run-test.sh | 7 ++ 5 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 tests/fmt/always_full.v create mode 100644 tests/fmt/always_full_tb.cc create mode 100644 tests/fmt/always_full_tb.v diff --git a/kernel/fmt.h b/kernel/fmt.h index 00b8d9b594e..647fe3a8119 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -45,7 +45,7 @@ struct VerilogFmtArg { }; // RTLIL format part, such as the substitutions in: -// "foo {4: 4du} bar {2:01xs}" +// "foo {4:> 4du} bar {2:<01hs}" struct FmtPart { enum { STRING = 0, diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v new file mode 100644 index 00000000000..5e3b17e9c43 --- /dev/null +++ b/tests/fmt/always_full.v @@ -0,0 +1,239 @@ +module always_full(input clk, output reg fin); + + reg [7:0] counter = 0; + + always @(posedge clk) begin + + counter <= counter + 1; + + if (counter == 0) fin <= 0; + + if (counter == 1) $display("<<>>"); + + if (counter == 2) $display("==> small unsigned %%d"); + if (counter == 3) $display(":%d:", 16'haa); + if (counter == 4) $display(":%-d:", 16'haa); + if (counter == 5) $display(":%+d:", 16'haa); + if (counter == 6) $display(":%+-d:", 16'haa); + if (counter == 7) $display(":%0d:", 16'haa); + if (counter == 8) $display(":%-0d:", 16'haa); + if (counter == 9) $display(":%+0d:", 16'haa); + if (counter == 10) $display(":%+-0d:", 16'haa); + if (counter == 11) $display(":%20d:", 16'haa); + if (counter == 12) $display(":%-20d:", 16'haa); + if (counter == 13) $display(":%+20d:", 16'haa); + if (counter == 14) $display(":%+-20d:", 16'haa); + if (counter == 15) $display(":%020d:", 16'haa); + if (counter == 16) $display(":%-020d:", 16'haa); + if (counter == 17) $display(":%+020d:", 16'haa); + if (counter == 18) $display(":%+-020d:", 16'haa); + + if (counter == 19) $display("==> big unsigned %%d"); + if (counter == 20) $display(":%d:", 16'haaaa); + if (counter == 21) $display(":%-d:", 16'haaaa); + if (counter == 22) $display(":%+d:", 16'haaaa); + if (counter == 23) $display(":%+-d:", 16'haaaa); + if (counter == 24) $display(":%0d:", 16'haaaa); + if (counter == 25) $display(":%-0d:", 16'haaaa); + if (counter == 26) $display(":%+0d:", 16'haaaa); + if (counter == 27) $display(":%+-0d:", 16'haaaa); + if (counter == 28) $display(":%20d:", 16'haaaa); + if (counter == 29) $display(":%-20d:", 16'haaaa); + if (counter == 30) $display(":%+20d:", 16'haaaa); + if (counter == 31) $display(":%+-20d:", 16'haaaa); + if (counter == 32) $display(":%020d:", 16'haaaa); + if (counter == 33) $display(":%-020d:", 16'haaaa); + if (counter == 34) $display(":%+020d:", 16'haaaa); + if (counter == 35) $display(":%+-020d:", 16'haaaa); + + if (counter == 36) $display("==> small signed %%d"); + if (counter == 37) $display(":%d:", 16'shaa); + if (counter == 38) $display(":%-d:", 16'shaa); + if (counter == 39) $display(":%+d:", 16'shaa); + if (counter == 40) $display(":%+-d:", 16'shaa); + if (counter == 41) $display(":%0d:", 16'shaa); + if (counter == 42) $display(":%-0d:", 16'shaa); + if (counter == 43) $display(":%+0d:", 16'shaa); + if (counter == 44) $display(":%+-0d:", 16'shaa); + if (counter == 45) $display(":%20d:", 16'shaa); + if (counter == 46) $display(":%-20d:", 16'shaa); + if (counter == 47) $display(":%+20d:", 16'shaa); + if (counter == 48) $display(":%+-20d:", 16'shaa); + if (counter == 49) $display(":%020d:", 16'shaa); + if (counter == 50) $display(":%-020d:", 16'shaa); + if (counter == 51) $display(":%+020d:", 16'shaa); + if (counter == 52) $display(":%+-020d:", 16'shaa); + + if (counter == 53) $display("==> big signed %%d"); + if (counter == 54) $display(":%d:", 16'shaaaa); + if (counter == 55) $display(":%-d:", 16'shaaaa); + if (counter == 56) $display(":%+d:", 16'shaaaa); + if (counter == 57) $display(":%+-d:", 16'shaaaa); + if (counter == 58) $display(":%0d:", 16'shaaaa); + if (counter == 59) $display(":%-0d:", 16'shaaaa); + if (counter == 60) $display(":%+0d:", 16'shaaaa); + if (counter == 61) $display(":%+-0d:", 16'shaaaa); + if (counter == 62) $display(":%20d:", 16'shaaaa); + if (counter == 63) $display(":%-20d:", 16'shaaaa); + if (counter == 64) $display(":%+20d:", 16'shaaaa); + if (counter == 65) $display(":%+-20d:", 16'shaaaa); + if (counter == 66) $display(":%020d:", 16'shaaaa); + if (counter == 67) $display(":%-020d:", 16'shaaaa); + if (counter == 68) $display(":%+020d:", 16'shaaaa); + if (counter == 69) $display(":%+-020d:", 16'shaaaa); + + if (counter == 70) $display("==> small unsigned %%h"); + if (counter == 71) $display(":%h:", 16'haa); + if (counter == 72) $display(":%-h:", 16'haa); + if (counter == 73) $display(":%0h:", 16'haa); + if (counter == 74) $display(":%-0h:", 16'haa); + if (counter == 75) $display(":%20h:", 16'haa); + if (counter == 76) $display(":%-20h:", 16'haa); + if (counter == 77) $display(":%020h:", 16'haa); + if (counter == 78) $display(":%-020h:", 16'haa); + + if (counter == 79) $display("==> big unsigned %%h"); + if (counter == 80) $display(":%h:", 16'haaaa); + if (counter == 81) $display(":%-h:", 16'haaaa); + if (counter == 82) $display(":%0h:", 16'haaaa); + if (counter == 83) $display(":%-0h:", 16'haaaa); + if (counter == 84) $display(":%20h:", 16'haaaa); + if (counter == 85) $display(":%-20h:", 16'haaaa); + if (counter == 86) $display(":%020h:", 16'haaaa); + if (counter == 87) $display(":%-020h:", 16'haaaa); + + if (counter == 88) $display("==> small signed %%h"); + if (counter == 89) $display(":%h:", 16'shaa); + if (counter == 90) $display(":%-h:", 16'shaa); + if (counter == 91) $display(":%0h:", 16'shaa); + if (counter == 92) $display(":%-0h:", 16'shaa); + if (counter == 93) $display(":%20h:", 16'shaa); + if (counter == 94) $display(":%-20h:", 16'shaa); + if (counter == 95) $display(":%020h:", 16'shaa); + if (counter == 96) $display(":%-020h:", 16'shaa); + + if (counter == 97) $display("==> big signed %%h"); + if (counter == 98) $display(":%h:", 16'shaaaa); + if (counter == 99) $display(":%-h:", 16'shaaaa); + if (counter == 100) $display(":%0h:", 16'shaaaa); + if (counter == 101) $display(":%-0h:", 16'shaaaa); + if (counter == 102) $display(":%20h:", 16'shaaaa); + if (counter == 103) $display(":%-20h:", 16'shaaaa); + if (counter == 104) $display(":%020h:", 16'shaaaa); + if (counter == 105) $display(":%-020h:", 16'shaaaa); + + if (counter == 106) $display("==> small unsigned %%o"); + if (counter == 107) $display(":%o:", 16'haa); + if (counter == 108) $display(":%-o:", 16'haa); + if (counter == 109) $display(":%0o:", 16'haa); + if (counter == 110) $display(":%-0o:", 16'haa); + if (counter == 111) $display(":%20o:", 16'haa); + if (counter == 112) $display(":%-20o:", 16'haa); + if (counter == 113) $display(":%020o:", 16'haa); + if (counter == 114) $display(":%-020o:", 16'haa); + + if (counter == 115) $display("==> big unsigned %%o"); + if (counter == 116) $display(":%o:", 16'haaaa); + if (counter == 117) $display(":%-o:", 16'haaaa); + if (counter == 118) $display(":%0o:", 16'haaaa); + if (counter == 119) $display(":%-0o:", 16'haaaa); + if (counter == 120) $display(":%20o:", 16'haaaa); + if (counter == 121) $display(":%-20o:", 16'haaaa); + if (counter == 122) $display(":%020o:", 16'haaaa); + if (counter == 123) $display(":%-020o:", 16'haaaa); + + if (counter == 124) $display("==> small signed %%o"); + if (counter == 125) $display(":%o:", 16'shaa); + if (counter == 126) $display(":%-o:", 16'shaa); + if (counter == 127) $display(":%0o:", 16'shaa); + if (counter == 128) $display(":%-0o:", 16'shaa); + if (counter == 129) $display(":%20o:", 16'shaa); + if (counter == 130) $display(":%-20o:", 16'shaa); + if (counter == 131) $display(":%020o:", 16'shaa); + if (counter == 132) $display(":%-020o:", 16'shaa); + + if (counter == 133) $display("==> big signed %%o"); + if (counter == 134) $display(":%o:", 16'shaaaa); + if (counter == 135) $display(":%-o:", 16'shaaaa); + if (counter == 136) $display(":%0o:", 16'shaaaa); + if (counter == 137) $display(":%-0o:", 16'shaaaa); + if (counter == 138) $display(":%20o:", 16'shaaaa); + if (counter == 139) $display(":%-20o:", 16'shaaaa); + if (counter == 140) $display(":%020o:", 16'shaaaa); + if (counter == 141) $display(":%-020o:", 16'shaaaa); + + if (counter == 142) $display("==> small unsigned %%b"); + if (counter == 143) $display(":%b:", 16'haa); + if (counter == 144) $display(":%-b:", 16'haa); + if (counter == 145) $display(":%0b:", 16'haa); + if (counter == 146) $display(":%-0b:", 16'haa); + if (counter == 147) $display(":%20b:", 16'haa); + if (counter == 148) $display(":%-20b:", 16'haa); + if (counter == 149) $display(":%020b:", 16'haa); + if (counter == 150) $display(":%-020b:", 16'haa); + + if (counter == 151) $display("==> big unsigned %%b"); + if (counter == 152) $display(":%b:", 16'haaaa); + if (counter == 153) $display(":%-b:", 16'haaaa); + if (counter == 154) $display(":%0b:", 16'haaaa); + if (counter == 155) $display(":%-0b:", 16'haaaa); + if (counter == 156) $display(":%20b:", 16'haaaa); + if (counter == 157) $display(":%-20b:", 16'haaaa); + if (counter == 158) $display(":%020b:", 16'haaaa); + if (counter == 159) $display(":%-020b:", 16'haaaa); + + if (counter == 160) $display("==> small signed %%b"); + if (counter == 161) $display(":%b:", 16'shaa); + if (counter == 162) $display(":%-b:", 16'shaa); + if (counter == 163) $display(":%0b:", 16'shaa); + if (counter == 164) $display(":%-0b:", 16'shaa); + if (counter == 165) $display(":%20b:", 16'shaa); + if (counter == 166) $display(":%-20b:", 16'shaa); + if (counter == 167) $display(":%020b:", 16'shaa); + if (counter == 168) $display(":%-020b:", 16'shaa); + + if (counter == 169) $display("==> big signed %%b"); + if (counter == 170) $display(":%b:", 16'shaaaa); + if (counter == 171) $display(":%-b:", 16'shaaaa); + if (counter == 172) $display(":%0b:", 16'shaaaa); + if (counter == 173) $display(":%-0b:", 16'shaaaa); + if (counter == 174) $display(":%20b:", 16'shaaaa); + if (counter == 175) $display(":%-20b:", 16'shaaaa); + if (counter == 176) $display(":%020b:", 16'shaaaa); + if (counter == 177) $display(":%-020b:", 16'shaaaa); + + if (counter == 178) $display("===> %%s"); + if (counter == 179) $display(":%10s:", "foo"); + if (counter == 180) $display(":%010s:", "foo"); + if (counter == 181) $display(":%-10s:", "foo"); + if (counter == 182) $display(":%-010s:", "foo"); + + if (counter == 183) $display("===> %%c"); + if (counter == 184) $display(":%10c:", "foo"); + if (counter == 185) $display(":%010c:", "foo"); + if (counter == 186) $display(":%-10c:", "foo"); + if (counter == 187) $display(":%-010c:", "foo"); + + if (counter == 188) $display("==> aliases"); + if (counter == 189) $display(":%x:", 16'shaa); + if (counter == 190) $display(":%X:", 16'shaa); + if (counter == 191) $display(":%H:", 16'shaa); + if (counter == 192) $display(":%O:", 16'shaa); + if (counter == 193) $display(":%B:", 16'shaa); + + if (counter == 194) $display("==> default base"); + if (counter == 195) $displayh(16'haa); + if (counter == 196) $displayo(16'haa); + if (counter == 197) $displayb(16'haa); + + if (counter == 198) $display("==> write/format"); + if (counter == 199) $display("%d", 1, "%d", 1); + + if (counter == 200) begin + $display("<<>>"); + fin <= 1; + end + + end + +endmodule diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc new file mode 100644 index 00000000000..8bf1022d330 --- /dev/null +++ b/tests/fmt/always_full_tb.cc @@ -0,0 +1,15 @@ +#include +#include "yosys-always_full.cc" + +int main() +{ + cxxrtl_design::p_always__full uut; + + while (true) { + uut.p_clk.set(!uut.p_clk); + uut.step(); + + if (uut.p_fin.get()) + return 0; + } +} diff --git a/tests/fmt/always_full_tb.v b/tests/fmt/always_full_tb.v new file mode 100644 index 00000000000..1edd35b67d9 --- /dev/null +++ b/tests/fmt/always_full_tb.v @@ -0,0 +1,14 @@ +module always_full_tb; + + reg clk = 0; + wire fin; + + always_full uut (.clk(clk), .fin(fin)); + + always begin + #1 clk <= ~clk; + + if (fin) $finish; + end + +endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 0757d7f2ae5..aa9c8fe7b8c 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -46,3 +46,10 @@ test_roundtrip oct_unsigned -DBASE_HEX -DSIGN="" test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" + +../../yosys -p "read_verilog always_full.v; write_cxxrtl yosys-always_full.cc" +${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc +./yosys-always_full >yosys-always_full.log +iverilog -o iverilog-always_full always_full.v always_full_tb.v +./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log +diff iverilog-always_full.log yosys-always_full.log From 52dc397a5085c360b6ac2e9538f96ba3e7956113 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:19 +1000 Subject: [PATCH 228/303] cxxrtl: don't use signed divide with unsigned/pos values Incorrect for unsigned, wasted effort for positive signed. --- backends/cxxrtl/cxxrtl.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 6d955fe9bfb..c7a6321056c 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -904,10 +904,12 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) val = val.neg(); if (val.is_zero()) buf += '0'; - // TODO: rigorously check our signed behaviour here while (!val.is_zero()) { value quotient; - val.signedDivideWithRemainder(value{10u}, quotient); + if (negative) + val.signedDivideWithRemainder(value{10u}, quotient); + else + val.divideWithRemainder(value{10u}, quotient); buf += '0' + val.template slice<3, 0>().val().template get(); val = quotient; } From c382d7d3ac2b713c5b3f55e81430e121520a1787 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:20 +1000 Subject: [PATCH 229/303] fmt: %t/$time support --- backends/cxxrtl/cxxrtl.h | 3 ++ backends/verilog/verilog_backend.cc | 6 +++ frontends/ast/genrtlil.cc | 5 ++ frontends/verilog/verilog_lexer.l | 2 +- kernel/fmt.cc | 74 ++++++++++++++++++++++++++++- kernel/fmt.h | 13 ++++- tests/fmt/always_full.v | 66 ++++++++++++++----------- 7 files changed, 138 insertions(+), 31 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index c7a6321056c..8ea800ed93f 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -1330,7 +1330,10 @@ struct module { virtual bool eval() = 0; virtual bool commit() = 0; + unsigned int steps = 0; + size_t step() { + ++steps; size_t deltas = 0; bool converged = false; do { diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index a6fd859a396..573fa6d5b84 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1797,6 +1797,12 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) dump_sigspec(f, arg.sig); f << ")"; break; + case VerilogFmtArg::TIME: + if (arg.realtime) + f << "$realtime"; + else + f << "$time"; + break; default: log_abort(); } } diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 40e71e8bd20..2e2d0de74bf 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -748,6 +748,11 @@ struct AST_INTERNAL::ProcessGenerator // and in case this will be used as an argument... arg.sig = node->bitsAsConst(); arg.signed_ = false; + } else if (node->type == AST_IDENTIFIER && node->str == "$time") { + arg.type = VerilogFmtArg::TIME; + } else if (node->type == AST_IDENTIFIER && node->str == "$realtime") { + arg.type = VerilogFmtArg::TIME; + arg.realtime = true; } else { arg.type = VerilogFmtArg::INTEGER; arg.sig = node->genRTLIL(); diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 89ccee788c9..8a37343022f 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -386,7 +386,7 @@ and|nand|or|nor|xor|xnor|not|buf|bufif0|bufif1|notif0|notif1 { supply0 { return TOK_SUPPLY0; } supply1 { return TOK_SUPPLY1; } -"$"(display[bho]?|write[bho]?|strobe|monitor|time|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { +"$"(display[bho]?|write[bho]?|strobe|monitor|time|realtime|stop|finish|dumpfile|dumpvars|dumpon|dumpoff|dumpall) { yylval->string = new std::string(yytext); return TOK_ID; } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 074ec08ca09..d72d60ba8b2 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -51,8 +51,11 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part = {}; } + if (++i == fmt.size()) + log_assert(false && "Unexpected end in format substitution"); + size_t arg_size = 0; - for (++i; i < fmt.size(); i++) { + for (; i < fmt.size(); i++) { if (fmt[i] >= '0' && fmt[i] <= '9') { arg_size *= 10; arg_size += fmt[i] - '0'; @@ -106,6 +109,11 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { part.base = 16; } else if (fmt[i] == 'c') { part.type = FmtPart::CHARACTER; + } else if (fmt[i] == 't') { + part.type = FmtPart::TIME; + } else if (fmt[i] == 'r') { + part.type = FmtPart::TIME; + part.realtime = true; } else { log_assert(false && "Unexpected character in format substitution"); } @@ -170,6 +178,9 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { } break; + case FmtPart::TIME: + log_assert(part.sig.size() == 0); + YS_FALLTHROUGH case FmtPart::CHARACTER: log_assert(part.sig.size() % 8 == 0); YS_FALLTHROUGH @@ -202,6 +213,11 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::CHARACTER) { fmt += 'c'; + } else if (part.type == FmtPart::TIME) { + if (part.realtime) + fmt += 'r'; + else + fmt += 't'; } else log_abort(); fmt += '}'; break; @@ -339,6 +355,15 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.sig.extend_u0((part.sig.size() + 7) / 8 * 8); // %10s and %010s not fully defined in IEEE 1800-2017 and do the same thing in iverilog part.padding = ' '; + } else if (fmt[i] == 't' || fmt[i] == 'T') { + if (arg->type == VerilogFmtArg::TIME) { + part.type = FmtPart::TIME; + part.realtime = arg->realtime; + if (!has_width && !has_leading_zero) + part.width = 20; + } else { + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with format character `%c' in argument %zu, but the argument is not $time or $realtime.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); + } } else { log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with unrecognized format character `%c' in argument %zu.\n", task_name.c_str(), fmt[i], fmtarg - args.begin() + 1); } @@ -458,6 +483,28 @@ std::vector Fmt::emit_verilog() const } break; } + + case FmtPart::TIME: { + VerilogFmtArg arg; + arg.type = VerilogFmtArg::TIME; + if (part.realtime) + arg.realtime = true; + args.push_back(arg); + + fmt.str += '%'; + if (part.plus) + fmt.str += '+'; + if (part.justify == FmtPart::LEFT) + fmt.str += '-'; + log_assert(part.padding == ' ' || part.padding == '0'); + if (part.padding == '0' && part.width > 0) + fmt.str += '0'; + fmt.str += std::to_string(part.width); + fmt.str += 't'; + break; + } + + default: log_abort(); } } @@ -522,6 +569,25 @@ void Fmt::emit_cxxrtl(std::ostream &f, std::function("; + f << "value<64>{steps}"; + f << ", " << (part.type == FmtPart::CHARACTER); + f << ", " << (part.justify == FmtPart::LEFT); + f << ", (char)" << (int)part.padding; + f << ", " << part.width; + f << ", " << part.base; + f << ", " << part.signed_; + f << ", " << part.lzero; + f << ", " << part.plus; + f << ')'; + break; + } + + default: log_abort(); } } } @@ -636,6 +702,12 @@ std::string Fmt::render() const str += std::string(part.width - buf.size(), part.padding); break; } + + case FmtPart::TIME: { + // We only render() during initial, so time is always zero. + str += "0"; + break; + } } } diff --git a/kernel/fmt.h b/kernel/fmt.h index 647fe3a8119..0d730074399 100644 --- a/kernel/fmt.h +++ b/kernel/fmt.h @@ -30,6 +30,7 @@ struct VerilogFmtArg { enum { STRING = 0, INTEGER = 1, + TIME = 2, } type; // All types @@ -42,6 +43,9 @@ struct VerilogFmtArg { // INTEGER type RTLIL::SigSpec sig; bool signed_ = false; + + // TIME type + bool realtime = false; }; // RTLIL format part, such as the substitutions in: @@ -51,24 +55,31 @@ struct FmtPart { STRING = 0, INTEGER = 1, CHARACTER = 2, + TIME = 3, } type; // STRING type std::string str; - // INTEGER/CHARACTER type + // INTEGER/CHARACTER types RTLIL::SigSpec sig; + + // INTEGER/CHARACTER/TIME types enum { RIGHT = 0, LEFT = 1, } justify = RIGHT; char padding = '\0'; size_t width = 0; + // INTEGER type unsigned base = 10; bool signed_ = false; bool lzero = false; bool plus = false; + + // TIME type + bool realtime = false; }; struct Fmt { diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index 5e3b17e9c43..3727813543c 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -202,34 +202,44 @@ module always_full(input clk, output reg fin); if (counter == 176) $display(":%020b:", 16'shaaaa); if (counter == 177) $display(":%-020b:", 16'shaaaa); - if (counter == 178) $display("===> %%s"); - if (counter == 179) $display(":%10s:", "foo"); - if (counter == 180) $display(":%010s:", "foo"); - if (counter == 181) $display(":%-10s:", "foo"); - if (counter == 182) $display(":%-010s:", "foo"); - - if (counter == 183) $display("===> %%c"); - if (counter == 184) $display(":%10c:", "foo"); - if (counter == 185) $display(":%010c:", "foo"); - if (counter == 186) $display(":%-10c:", "foo"); - if (counter == 187) $display(":%-010c:", "foo"); - - if (counter == 188) $display("==> aliases"); - if (counter == 189) $display(":%x:", 16'shaa); - if (counter == 190) $display(":%X:", 16'shaa); - if (counter == 191) $display(":%H:", 16'shaa); - if (counter == 192) $display(":%O:", 16'shaa); - if (counter == 193) $display(":%B:", 16'shaa); - - if (counter == 194) $display("==> default base"); - if (counter == 195) $displayh(16'haa); - if (counter == 196) $displayo(16'haa); - if (counter == 197) $displayb(16'haa); - - if (counter == 198) $display("==> write/format"); - if (counter == 199) $display("%d", 1, "%d", 1); - - if (counter == 200) begin + if (counter == 178) $display("==> time %%t"); + if (counter == 179) $display(":%t:", $time); + if (counter == 180) $display(":%-t:", $time); + if (counter == 181) $display(":%0t:", $time); + if (counter == 182) $display(":%-0t:", $time); + if (counter == 183) $display(":%10t:", $time); + if (counter == 184) $display(":%-10t:", $time); + if (counter == 185) $display(":%015t:", $time); + if (counter == 186) $display(":%-015t:", $time); + + if (counter == 187) $display("===> %%s"); + if (counter == 188) $display(":%10s:", "foo"); + if (counter == 189) $display(":%010s:", "foo"); + if (counter == 190) $display(":%-10s:", "foo"); + if (counter == 191) $display(":%-010s:", "foo"); + + if (counter == 192) $display("===> %%c"); + if (counter == 193) $display(":%10c:", "foo"); + if (counter == 194) $display(":%010c:", "foo"); + if (counter == 195) $display(":%-10c:", "foo"); + if (counter == 196) $display(":%-010c:", "foo"); + + if (counter == 197) $display("==> aliases"); + if (counter == 198) $display(":%x:", 16'shaa); + if (counter == 199) $display(":%X:", 16'shaa); + if (counter == 200) $display(":%H:", 16'shaa); + if (counter == 201) $display(":%O:", 16'shaa); + if (counter == 202) $display(":%B:", 16'shaa); + + if (counter == 203) $display("==> default base"); + if (counter == 204) $displayh(16'haa); + if (counter == 205) $displayo(16'haa); + if (counter == 206) $displayb(16'haa); + + if (counter == 207) $display("==> write/format"); + if (counter == 208) $display("%d", 1, "%d", 1); + + if (counter == 209) begin $display("<<>>"); fin <= 1; end From 75b44f21d1ff0c79f64e4ec3d2c10d4bb93fdefe Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:21 +1000 Subject: [PATCH 230/303] fmt: rudimentary %m support (= %l) --- kernel/fmt.cc | 3 +++ tests/fmt/display_lm.v | 12 ++++++++++++ tests/fmt/display_lm_tb.cc | 10 ++++++++++ tests/fmt/run-test.sh | 9 +++++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/fmt/display_lm.v create mode 100644 tests/fmt/display_lm_tb.cc diff --git a/kernel/fmt.cc b/kernel/fmt.cc index d72d60ba8b2..9d9e95ac392 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -291,6 +291,9 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik } else if (fmt.substr(i, 2) == "%l" || fmt.substr(i, 2) == "%L") { i++; part.str += module_name.str(); + } else if (fmt.substr(i, 2) == "%m" || fmt.substr(i, 2) == "%M") { + i++; + part.str += module_name.str(); } else { if (!part.str.empty()) { part.type = FmtPart::STRING; diff --git a/tests/fmt/display_lm.v b/tests/fmt/display_lm.v new file mode 100644 index 00000000000..d96f233f064 --- /dev/null +++ b/tests/fmt/display_lm.v @@ -0,0 +1,12 @@ +module top; + mid mid_uut (); +endmodule + +module mid (); + bot bot_uut (); +endmodule + +module bot (); + initial $display("%%l: %l\n%%m: %m"); + always $display("%%l: %l\n%%m: %m"); +endmodule diff --git a/tests/fmt/display_lm_tb.cc b/tests/fmt/display_lm_tb.cc new file mode 100644 index 00000000000..ebc62f80fad --- /dev/null +++ b/tests/fmt/display_lm_tb.cc @@ -0,0 +1,10 @@ +#include +#include "yosys-display_lm.cc" + +int main() +{ + cxxrtl_design::p_top uut; + + uut.step(); + return 0; +} diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index aa9c8fe7b8c..2568e27764d 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -53,3 +53,12 @@ ${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log diff iverilog-always_full.log yosys-always_full.log + +../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log +../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" +${CXX:-g++} -o yosys-display_lm_cc -I../.. display_lm_tb.cc +./yosys-display_lm_cc >yosys-display_lm_cc.log +for log in yosys-display_lm.log yosys-display_lm_cc.log; do + grep "^%l: \\\\bot\$" "$log" + grep "^%m: \\\\bot\$" "$log" +done From c391ee7a0d5be7d1fba0da1cd02da14138afdb35 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:22 +1000 Subject: [PATCH 231/303] docs: document simulation time format specifiers --- docs/source/CHAPTER_CellLib.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index 0fae4f44b6f..a4f986f7590 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -698,6 +698,7 @@ base * ``d`` for base-10 integers (decimal) * ``h`` for base-16 integers (hexadecimal) * ``c`` for ASCII characters/strings + * ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and :verilog:`$realtime`) For integers, these items follow: @@ -716,6 +717,8 @@ signedness ASCII characters/strings have no special options, but the signal size must be divisible by 8. +For simulation time, the signal size must be zero. + Finally: ``}`` @@ -730,6 +733,8 @@ Some example format specifiers: + ``{16:< 10h0u}`` - 16-bit unsigned integer rendered as hexadecimal, zero-padded to fit the largest signal value (4 characters for hex), left-justified, space-padded to 10 characters wide. ++ ``{0:>010t}`` - simulation time, right-justified, zero-padded to 10 characters + wide. To include literal ``{`` and ``}`` characters in your format string, use ``{{`` and ``}}`` respectively. From 9f9561379b10776d2e4ad6fcc7ec821ec208ae4c Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:22 +1000 Subject: [PATCH 232/303] fmt: format %t consistently at initial --- frontends/ast/simplify.cc | 13 +++++++++---- kernel/fmt.cc | 10 ++++------ tests/fmt/initial_display.v | 10 ++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 19e62668b9e..ee1be3781c8 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -48,22 +48,27 @@ Fmt AstNode::processFormat(int stage, bool sformat_like, int default_base, size_ for (size_t index = first_arg_at; index < children.size(); index++) { AstNode *node_arg = children[index]; while (node_arg->simplify(true, false, stage, -1, false, false)) { } - if (node_arg->type != AST_CONSTANT) - input_error("Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); VerilogFmtArg arg = {}; arg.filename = filename; arg.first_line = location.first_line; - if (node_arg->is_string) { + if (node_arg->type == AST_CONSTANT && node_arg->is_string) { arg.type = VerilogFmtArg::STRING; arg.str = node_arg->bitsAsConst().decode_string(); // and in case this will be used as an argument... arg.sig = node_arg->bitsAsConst(); arg.signed_ = false; - } else { + } else if (node_arg->type == AST_IDENTIFIER && node_arg->str == "$time") { + arg.type = VerilogFmtArg::TIME; + } else if (node_arg->type == AST_IDENTIFIER && node_arg->str == "$realtime") { + arg.type = VerilogFmtArg::TIME; + arg.realtime = true; + } else if (node_arg->type == AST_CONSTANT) { arg.type = VerilogFmtArg::INTEGER; arg.sig = node_arg->bitsAsConst(); arg.signed_ = node_arg->is_signed; + } else { + log_file_error(filename, location.first_line, "Failed to evaluate system task `%s' with non-constant argument at position %zu.\n", str.c_str(), index + 1); } args.push_back(arg); } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 9d9e95ac392..0fac6417560 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -606,6 +606,7 @@ std::string Fmt::render() const break; case FmtPart::INTEGER: + case FmtPart::TIME: case FmtPart::CHARACTER: { std::string buf; if (part.type == FmtPart::INTEGER) { @@ -689,6 +690,9 @@ std::string Fmt::render() const } else log_abort(); } else if (part.type == FmtPart::CHARACTER) { buf = part.sig.as_const().decode_string(); + } else if (part.type == FmtPart::TIME) { + // We only render() during initial, so time is always zero. + buf = "0"; } log_assert(part.width == 0 || part.padding != '\0'); @@ -705,12 +709,6 @@ std::string Fmt::render() const str += std::string(part.width - buf.size(), part.padding); break; } - - case FmtPart::TIME: { - // We only render() during initial, so time is always zero. - str += "0"; - break; - } } } diff --git a/tests/fmt/initial_display.v b/tests/fmt/initial_display.v index 26a39d0ec88..d3ef9ed7691 100644 --- a/tests/fmt/initial_display.v +++ b/tests/fmt/initial_display.v @@ -193,6 +193,16 @@ module m; initial $display(":%020b:", 16'shaaaa); initial $display(":%-020b:", 16'shaaaa); + initial $display("==> time %%t"); + initial $display(":%t:", $time); + initial $display(":%-t:", $time); + initial $display(":%0t:", $time); + initial $display(":%-0t:", $time); + initial $display(":%10t:", $time); + initial $display(":%-10t:", $time); + initial $display(":%015t:", $time); + initial $display(":%-015t:", $time); + initial $display("===> %%s"); initial $display(":%10s:", "foo"); initial $display(":%010s:", "foo"); From 2ae551c0af26dd81e7e28bac4618ca3fc84019dc Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:23 +1000 Subject: [PATCH 233/303] fmt: fuzz, fix (remove extraneous + incorrect fill) "blk + chunks" is often an overrun, plus the fill is unnecessary; we throw blk away immediately. --- backends/cxxrtl/cxxrtl.h | 1 - tests/fmt/fuzz/.gitignore | 2 ++ tests/fmt/fuzz/CMakeLists.txt | 23 +++++++++++++++++++ tests/fmt/fuzz/x_test.cc | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/fmt/fuzz/.gitignore create mode 100644 tests/fmt/fuzz/CMakeLists.txt create mode 100644 tests/fmt/fuzz/x_test.cc diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 8ea800ed93f..d2f06d6bf30 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -654,7 +654,6 @@ struct value : public expr_base> { } std::copy(blk, blk + origLen, data); - std::fill(blk + origLen, blk + chunks, 0); } static chunk::type getShiftedBlock(const value &num, size_t x, size_t y) { diff --git a/tests/fmt/fuzz/.gitignore b/tests/fmt/fuzz/.gitignore new file mode 100644 index 00000000000..88ea7e2ef91 --- /dev/null +++ b/tests/fmt/fuzz/.gitignore @@ -0,0 +1,2 @@ +fuzztest +build diff --git a/tests/fmt/fuzz/CMakeLists.txt b/tests/fmt/fuzz/CMakeLists.txt new file mode 100644 index 00000000000..6f7c43da888 --- /dev/null +++ b/tests/fmt/fuzz/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.14) +project(cxxrtl_division_fuzz) + +set(CMAKE_CXX_STANDARD 17) + +add_subdirectory(fuzztest) + +enable_testing() + +include(GoogleTest) + +fuzztest_setup_fuzzing_flags() + +include_directories(../../..) + +add_executable( + x_test + x_test.cc + ../../../libs/bigint/BigUnsigned.cc +) + +link_fuzztest(x_test) +gtest_discover_tests(x_test) diff --git a/tests/fmt/fuzz/x_test.cc b/tests/fmt/fuzz/x_test.cc new file mode 100644 index 00000000000..ce4af54135b --- /dev/null +++ b/tests/fmt/fuzz/x_test.cc @@ -0,0 +1,42 @@ +#include "fuzztest/fuzztest.h" +#include "gtest/gtest.h" + +#include +#include "backends/cxxrtl/cxxrtl.h" +#include "libs/bigint/BigUnsigned.hh" + +using namespace cxxrtl_yosys; + +void Formats128BitUnsignedIntegers(uint64_t x, uint64_t y) { + // Compare output to actual BigUnsigned. + value<64> vs; + value<128> v; + vs.set(x); + v = v.blit<127, 64>(vs); + vs.set(y); + v = v.blit<63, 0>(vs); + + std::ostringstream oss; + oss << value_formatted<128>(v, false, false, ' ', 0, 10, false, false, false); + auto actual = oss.str(); + + BigUnsigned b(x); + b.bitShiftLeft(b, 64); + b.bitOr(b, y); + + std::string expected; + + if (b.isZero()) { + expected = "0"; + } else { + while (!b.isZero()) { + expected += '0' + (b % 10).toInt(); + b /= 10; + } + std::reverse(expected.begin(), expected.end()); + } + + EXPECT_EQ(actual, expected); +} +FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitUnsignedIntegers); + From 3571bf2c2d4b84940533500cfae6471dbf6b7258 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:24 +1000 Subject: [PATCH 234/303] fmt: fuzz, remove some unnecessary busywork Removing some signed checks and logic where we've already guaranteed the values to be positive. Indeed, in these cases, if a negative value got through (per my realisation in the signed fuzz harness), it would cause an infinite loop due to flooring division. --- backends/cxxrtl/cxxrtl.h | 5 +-- kernel/fmt.cc | 4 +-- tests/fmt/fuzz/CMakeLists.txt | 1 + tests/fmt/fuzz/x_test.cc | 65 +++++++++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index d2f06d6bf30..d4e2fa7fc86 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -905,10 +905,7 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) buf += '0'; while (!val.is_zero()) { value quotient; - if (negative) - val.signedDivideWithRemainder(value{10u}, quotient); - else - val.divideWithRemainder(value{10u}, quotient); + val.divideWithRemainder(value{10u}, quotient); buf += '0' + val.template slice<3, 0>().val().template get(); val = quotient; } diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 0fac6417560..0fdd996fb8a 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -680,8 +680,8 @@ std::string Fmt::render() const if (absvalue.is_fully_zero()) buf += '0'; while (!absvalue.is_fully_zero()) { - buf += '0' + RTLIL::const_mod(absvalue, 10, part.signed_, false, 4).as_int(); - absvalue = RTLIL::const_div(absvalue, 10, part.signed_, false, absvalue.size()); + buf += '0' + RTLIL::const_mod(absvalue, 10, false, false, 4).as_int(); + absvalue = RTLIL::const_div(absvalue, 10, false, false, absvalue.size()); } if (negative || part.plus) buf += negative ? '-' : '+'; diff --git a/tests/fmt/fuzz/CMakeLists.txt b/tests/fmt/fuzz/CMakeLists.txt index 6f7c43da888..e436067725d 100644 --- a/tests/fmt/fuzz/CMakeLists.txt +++ b/tests/fmt/fuzz/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable( x_test x_test.cc ../../../libs/bigint/BigUnsigned.cc + ../../../libs/bigint/BigInteger.cc ) link_fuzztest(x_test) diff --git a/tests/fmt/fuzz/x_test.cc b/tests/fmt/fuzz/x_test.cc index ce4af54135b..07ff7885dae 100644 --- a/tests/fmt/fuzz/x_test.cc +++ b/tests/fmt/fuzz/x_test.cc @@ -4,34 +4,33 @@ #include #include "backends/cxxrtl/cxxrtl.h" #include "libs/bigint/BigUnsigned.hh" +#include "libs/bigint/BigInteger.hh" using namespace cxxrtl_yosys; -void Formats128BitUnsignedIntegers(uint64_t x, uint64_t y) { - // Compare output to actual BigUnsigned. - value<64> vs; +void Formats128BitUnsignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) +{ + // Compare output to BigUnsigned. value<128> v; - vs.set(x); - v = v.blit<127, 64>(vs); - vs.set(y); - v = v.blit<63, 0>(vs); + v = v.blit<127, 64>(value<64>{x1, x0}); + v = v.blit<63, 0>(value<64>{x3, x2}); std::ostringstream oss; oss << value_formatted<128>(v, false, false, ' ', 0, 10, false, false, false); auto actual = oss.str(); - BigUnsigned b(x); - b.bitShiftLeft(b, 64); - b.bitOr(b, y); + BigUnsigned u; + u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); + u.bitOr(u, v.slice<63, 0>().val().get()); std::string expected; - if (b.isZero()) { + if (u.isZero()) { expected = "0"; } else { - while (!b.isZero()) { - expected += '0' + (b % 10).toInt(); - b /= 10; + while (!u.isZero()) { + expected += '0' + (u % 10).toInt(); + u /= 10; } std::reverse(expected.begin(), expected.end()); } @@ -40,3 +39,41 @@ void Formats128BitUnsignedIntegers(uint64_t x, uint64_t y) { } FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitUnsignedIntegers); + +void Formats128BitSignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) { + // Compare output to BigInteger. + value<128> v; + v = v.blit<127, 64>(value<64>{x1, x0}); + v = v.blit<63, 0>(value<64>{x3, x2}); + + std::ostringstream oss; + oss << value_formatted<128>(v, false, false, ' ', 0, 10, true, false, false); + auto actual = oss.str(); + + BigUnsigned u; + bool negative = v.is_neg(); + if (negative) + v = v.neg(); + u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); + u.bitOr(u, v.slice<63, 0>().val().get()); + + std::string expected; + if (u.isZero()) { + expected = "0"; + } else { + // Note that we never actually do division of negative numbers: our division + // routines are flooring, not truncating, so dividing by 10 repeatedly won't + // necessarily ever get to zero. + while (!u.isZero()) { + expected += '0' + (u % 10).toInt(); + u /= 10; + } + if (negative) { + expected += '-'; + } + std::reverse(expected.begin(), expected.end()); + } + + EXPECT_EQ(actual, expected); +} +FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitSignedIntegers); From a1de898fcc96ef1546fc7c656685403ef1242378 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:24 +1000 Subject: [PATCH 235/303] fmt: merge fuzzers since we don't rely on BigInteger logic This is per fmt's (effective) use, as it turns out, so we're not losing any fidelity in the comparison. --- tests/fmt/fuzz/CMakeLists.txt | 1 - tests/fmt/fuzz/x_test.cc | 47 +++++------------------------------ 2 files changed, 6 insertions(+), 42 deletions(-) diff --git a/tests/fmt/fuzz/CMakeLists.txt b/tests/fmt/fuzz/CMakeLists.txt index e436067725d..6f7c43da888 100644 --- a/tests/fmt/fuzz/CMakeLists.txt +++ b/tests/fmt/fuzz/CMakeLists.txt @@ -17,7 +17,6 @@ add_executable( x_test x_test.cc ../../../libs/bigint/BigUnsigned.cc - ../../../libs/bigint/BigInteger.cc ) link_fuzztest(x_test) diff --git a/tests/fmt/fuzz/x_test.cc b/tests/fmt/fuzz/x_test.cc index 07ff7885dae..ee061861f90 100644 --- a/tests/fmt/fuzz/x_test.cc +++ b/tests/fmt/fuzz/x_test.cc @@ -4,11 +4,10 @@ #include #include "backends/cxxrtl/cxxrtl.h" #include "libs/bigint/BigUnsigned.hh" -#include "libs/bigint/BigInteger.hh" using namespace cxxrtl_yosys; -void Formats128BitUnsignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) +void Formats128BitIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3, bool signed_) { // Compare output to BigUnsigned. value<128> v; @@ -16,64 +15,30 @@ void Formats128BitUnsignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x v = v.blit<63, 0>(value<64>{x3, x2}); std::ostringstream oss; - oss << value_formatted<128>(v, false, false, ' ', 0, 10, false, false, false); + oss << value_formatted<128>(v, false, false, ' ', 0, 10, signed_, false, false); auto actual = oss.str(); BigUnsigned u; - u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); - u.bitOr(u, v.slice<63, 0>().val().get()); - - std::string expected; - - if (u.isZero()) { - expected = "0"; - } else { - while (!u.isZero()) { - expected += '0' + (u % 10).toInt(); - u /= 10; - } - std::reverse(expected.begin(), expected.end()); - } - - EXPECT_EQ(actual, expected); -} -FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitUnsignedIntegers); - - -void Formats128BitSignedIntegers(chunk_t x0, chunk_t x1, chunk_t x2, chunk_t x3) { - // Compare output to BigInteger. - value<128> v; - v = v.blit<127, 64>(value<64>{x1, x0}); - v = v.blit<63, 0>(value<64>{x3, x2}); - - std::ostringstream oss; - oss << value_formatted<128>(v, false, false, ' ', 0, 10, true, false, false); - auto actual = oss.str(); - - BigUnsigned u; - bool negative = v.is_neg(); + bool negative = signed_ && v.is_neg(); if (negative) v = v.neg(); u.bitShiftLeft(v.slice<127, 64>().val().get(), 64); u.bitOr(u, v.slice<63, 0>().val().get()); std::string expected; + if (u.isZero()) { expected = "0"; } else { - // Note that we never actually do division of negative numbers: our division - // routines are flooring, not truncating, so dividing by 10 repeatedly won't - // necessarily ever get to zero. while (!u.isZero()) { expected += '0' + (u % 10).toInt(); u /= 10; } - if (negative) { + if (negative) expected += '-'; - } std::reverse(expected.begin(), expected.end()); } EXPECT_EQ(actual, expected); } -FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitSignedIntegers); +FUZZ_TEST(CxxrtlDivisionFuzz, Formats128BitIntegers); From bfa8b631bf59da3f41f594ba9e9d4ac3588d2af4 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:25 +1000 Subject: [PATCH 236/303] cxxrtl: remove unused signedDivideWithRemainder --- backends/cxxrtl/cxxrtl.h | 55 ---------------------------------------- 1 file changed, 55 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index d4e2fa7fc86..4abb27be5dc 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -661,61 +661,6 @@ struct value : public expr_base> { chunk::type part2 = (x == num.chunks) ? 0 : (num.data[x] << y); return part1 | part2; } - - // parallel to BigInteger::divideWithRemainder; quotient is stored in q, - // *this is left with the remainder. See that function for commentary describing - // how/why this works. - void signedDivideWithRemainder(const value &b, value &q) { - assert(this != &q); - - if (this == &b || &q == &b) { - value tmpB(b); - signedDivideWithRemainder(tmpB, q); - return; - } - - if (b.is_zero()) { - q = value{0u}; - return; - } - - if (is_zero()) { - q = value{0u}; - return; - } - - // BigInteger has a separate 'mag' to its sign. We don't, so the lazy - // approach is to improvise said. - auto mag = *this; - bool neg = mag.is_neg(); - if (neg) - mag = mag.neg(); - - auto bmag = b; - bool bneg = bmag.is_neg(); - if (bneg) - bmag = bmag.neg(); - - bool qneg = false; - if (neg != b.is_neg()) { - qneg = true; - mag = mag.sub(value{1u}); - } - - mag.divideWithRemainder(bmag, q); - - if (neg != bneg) { - q = q.add(value{1u}); - mag = bmag.sub(mag); - mag = mag.sub(value{1u}); - } - - neg = bneg; - - *this = neg ? mag.neg() : mag; - if (qneg) - q = q.neg(); - } }; // Expression template for a slice, usable as lvalue or rvalue, and composable with other expression templates here. From f9b149fa7b6fe5b51c548e564dafd99a3cd87d0b Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:26 +1000 Subject: [PATCH 237/303] cxxrtl: add "-print-output" option, test in fmt --- backends/cxxrtl/cxxrtl_backend.cc | 12 ++++++++++-- tests/fmt/run-test.sh | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 4986836b9f8..2c9dc412178 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -682,6 +682,7 @@ struct CxxrtlWorker { bool split_intf = false; std::string intf_filename; std::string design_ns = "cxxrtl_design"; + std::string print_output = "std::cout"; std::ostream *impl_f = nullptr; std::ostream *intf_f = nullptr; @@ -1042,8 +1043,7 @@ struct CxxrtlWorker { Fmt fmt = {}; fmt.parse_rtlil(cell); - // TODO: we may want to configure the output stream - f << indent << "std::cout"; + f << indent << print_output; fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); f << ";\n"; } @@ -3263,6 +3263,10 @@ struct CxxrtlBackend : public Backend { log(" place the generated code into namespace . if not specified,\n"); log(" \"cxxrtl_design\" is used.\n"); log("\n"); + log(" -print-output \n"); + log(" $print cells in the generated code direct their output to .\n"); + log(" if not specified, \"std::cout\" is used.\n"); + log("\n"); log(" -nohierarchy\n"); log(" use design hierarchy as-is. in most designs, a top module should be\n"); log(" present as it is exposed through the C API and has unbuffered outputs\n"); @@ -3401,6 +3405,10 @@ struct CxxrtlBackend : public Backend { worker.design_ns = args[++argidx]; continue; } + if (args[argidx] == "-print-output" && argidx+1 < args.size()) { + worker.print_output = args[++argidx]; + continue; + } break; } extra_args(f, filename, args, argidx); diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 2568e27764d..a5a0c0c7e59 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -47,9 +47,9 @@ test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" -../../yosys -p "read_verilog always_full.v; write_cxxrtl yosys-always_full.cc" +../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" ${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc -./yosys-always_full >yosys-always_full.log +./yosys-always_full 2>yosys-always_full.log iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log diff iverilog-always_full.log yosys-always_full.log From fc0acd0ad119de5a606355cd8d9da2548338e579 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:26 +1000 Subject: [PATCH 238/303] cxxrtl: restrict -print-output to cout, cerr --- backends/cxxrtl/cxxrtl_backend.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 2c9dc412178..8f06dda66a9 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -3265,7 +3265,8 @@ struct CxxrtlBackend : public Backend { log("\n"); log(" -print-output \n"); log(" $print cells in the generated code direct their output to .\n"); - log(" if not specified, \"std::cout\" is used.\n"); + log(" must be one of \"std::cout\", \"std::cerr\". if not specified,\n"); + log(" \"std::cout\" is used.\n"); log("\n"); log(" -nohierarchy\n"); log(" use design hierarchy as-is. in most designs, a top module should be\n"); @@ -3407,6 +3408,10 @@ struct CxxrtlBackend : public Backend { } if (args[argidx] == "-print-output" && argidx+1 < args.size()) { worker.print_output = args[++argidx]; + if (!(worker.print_output == "std::cout" || worker.print_output == "std::cerr")) { + log_cmd_error("Invalid output stream \"%s\".\n", worker.print_output.c_str()); + worker.print_output = "std::cout"; + } continue; } break; From 4e94f62116cf4b9180a7a0ddb6ca4ad61a97bd53 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:27 +1000 Subject: [PATCH 239/303] simlib: blackbox `$print` cell It's possible to `generate` the appropriate always blocks per the triggers, but unlikely to be worth parsing the RTLIL \FORMAT parameter. --- techlibs/common/simlib.v | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 9cb68e7252f..32f2b693740 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1799,6 +1799,23 @@ end endmodule +// -------------------------------------------------------- + +module \$print (EN, TRG, ARGS); + +parameter FORMAT = ""; +parameter ARGS_WIDTH = 0; +parameter TRG_ENABLE = 1; + +parameter TRG_WIDTH = 0; +parameter TRG_POLARITY = 0; + +input EN; +input [TRG_WIDTH-1:0] TRG; +input [ARGS_WIDTH-1:0] ARGS; + +endmodule + // -------------------------------------------------------- `ifndef SIMLIB_NOSR From 992a728ec7ad5b7a19d58e544fd0901065bb2f71 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:28 +1000 Subject: [PATCH 240/303] tests: CXX may be e.g. gcc, so use CC and link stdc++ explicitly --- frontends/ast/genrtlil.cc | 4 ++-- tests/fmt/run-test.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 2e2d0de74bf..849b5ebad46 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -700,7 +700,7 @@ struct AST_INTERNAL::ProcessGenerator sstr << ast->str << "$" << ast->filename << ":" << ast->location.first_line << "$" << (autoidx++); RTLIL::Cell *cell = current_module->addCell(sstr.str(), ID($print)); - cell->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column); + set_src_attr(cell, ast); RTLIL::SigSpec triggers; RTLIL::Const polarity; @@ -719,7 +719,7 @@ struct AST_INTERNAL::ProcessGenerator cell->setPort(ID::TRG, triggers); Wire *wire = current_module->addWire(sstr.str() + "_EN", 1); - wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", ast->filename.c_str(), ast->location.first_line, ast->location.first_column, ast->location.last_line, ast->location.last_column); + set_src_attr(wire, ast); cell->setPort(ID::EN, wire); proc->root_case.actions.push_back(SigSig(wire, false)); diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index a5a0c0c7e59..0e073a707fa 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -48,7 +48,7 @@ test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" ../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" -${CXX:-g++} -o yosys-always_full -I../.. always_full_tb.cc +${CC:-gcc} -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ ./yosys-always_full 2>yosys-always_full.log iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log @@ -56,7 +56,7 @@ diff iverilog-always_full.log yosys-always_full.log ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" -${CXX:-g++} -o yosys-display_lm_cc -I../.. display_lm_tb.cc +${CC:-gcc} -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ ./yosys-display_lm_cc >yosys-display_lm_cc.log for log in yosys-display_lm.log yosys-display_lm_cc.log; do grep "^%l: \\\\bot\$" "$log" From eb0fb4d6629876de5027263f8e47cc48b7643d8a Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:29 +1000 Subject: [PATCH 241/303] tests: -std=c++11 not optional --- tests/fmt/run-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 0e073a707fa..d793c37dd08 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -48,7 +48,7 @@ test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" ../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" -${CC:-gcc} -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ +${CC:-gcc} -std=c++11 -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ ./yosys-always_full 2>yosys-always_full.log iverilog -o iverilog-always_full always_full.v always_full_tb.v ./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log @@ -56,7 +56,7 @@ diff iverilog-always_full.log yosys-always_full.log ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" -${CC:-gcc} -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ +${CC:-gcc} -std=c++11 -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ ./yosys-display_lm_cc >yosys-display_lm_cc.log for log in yosys-display_lm.log yosys-display_lm_cc.log; do grep "^%l: \\\\bot\$" "$log" From 7f7c61c9f018cd7ed24d8c7e570a80e565ca7c7b Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:29 +1000 Subject: [PATCH 242/303] fmt: remove lzero by lowering during Verilog parse See https://github.com/YosysHQ/yosys/pull/3721#issuecomment-1502037466 -- this reduces logic within the cell, and makes the rules that apply much more clear. --- backends/cxxrtl/cxxrtl.h | 7 +-- docs/source/CHAPTER_CellLib.rst | 11 ++-- kernel/fmt.cc | 100 +++++++++++++++++++++++--------- kernel/fmt.h | 5 +- 4 files changed, 82 insertions(+), 41 deletions(-) diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 4abb27be5dc..45ec256af3c 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -802,11 +802,10 @@ struct value_formatted { int width; int base; bool signed_; - bool lzero; bool plus; - value_formatted(const value &val, bool character, bool justify_left, char padding, int width, int base, bool signed_, bool lzero, bool plus) : - val(val), character(character), justify_left(justify_left), padding(padding), width(width), base(base), signed_(signed_), lzero(lzero), plus(plus) {} + value_formatted(const value &val, bool character, bool justify_left, char padding, int width, int base, bool signed_, bool plus) : + val(val), character(character), justify_left(justify_left), padding(padding), width(width), base(base), signed_(signed_), plus(plus) {} value_formatted(const value_formatted &) = delete; value_formatted &operator=(const value_formatted &rhs) = delete; }; @@ -823,7 +822,7 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) if (!vf.character) { size_t width = Bits; - if (!vf.lzero && vf.base != 10) { + if (vf.base != 10) { width = 0; for (size_t index = 0; index < Bits; index++) if (val.bit(index)) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index a4f986f7590..dc2ad3e578a 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -700,16 +700,12 @@ base * ``c`` for ASCII characters/strings * ``t`` and ``r`` for simulation time (corresponding to :verilog:`$time` and :verilog:`$realtime`) -For integers, these items follow: +For integers, this item may follow: ``+``\ *?* (optional, decimals only) Include a leading plus for non-negative numbers. This can assist with symmetry with negatives in tabulated output. -``0``\ *?* - (optional, non-decimals only) Zero-pad the number to fit the signal's - largest value before any further padding/justification. - signedness ``u`` for unsigned, ``s`` for signed. This distinction is only respected when rendering decimals. @@ -730,8 +726,7 @@ Some example format specifiers: right-justified, zero-padded to 2 characters wide. + ``{32:< 15d+s}`` - 32-bit signed integer rendered as decimal, left-justified, space-padded to 15 characters wide, positive values prefixed with ``+``. -+ ``{16:< 10h0u}`` - 16-bit unsigned integer rendered as hexadecimal, - zero-padded to fit the largest signal value (4 characters for hex), ++ ``{16:< 10hu}`` - 16-bit unsigned integer rendered as hexadecimal, left-justified, space-padded to 10 characters wide. + ``{0:>010t}`` - simulation time, right-justified, zero-padded to 10 characters wide. @@ -742,6 +737,8 @@ and ``}}`` respectively. It is an error for a format string to consume more or less bits from ``\ARGS`` than the port width. +Values are never truncated, regardless of the specified width. + Note that further restrictions on allowable combinations of options may apply depending on the backend used. diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 0fdd996fb8a..69bdbb013b0 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -130,12 +130,6 @@ void Fmt::parse_rtlil(const RTLIL::Cell *cell) { log_assert(false && "Unexpected end in format substitution"); } - if (fmt[i] == '0') { - part.lzero = true; - if (++i == fmt.size()) - log_assert(false && "Unexpected end in format substitution"); - } - if (fmt[i] == 'u') part.signed_ = false; else if (fmt[i] == 's') @@ -208,8 +202,6 @@ void Fmt::emit_rtlil(RTLIL::Cell *cell) const { } if (part.plus) fmt += '+'; - if (part.lzero) - fmt += '0'; fmt += part.signed_ ? 's' : 'u'; } else if (part.type == FmtPart::CHARACTER) { fmt += 'c'; @@ -248,14 +240,72 @@ static size_t compute_required_decimal_places(size_t size, bool signed_) return places; } -static void apply_verilog_automatic_sizing(FmtPart &part) +static size_t compute_required_nondecimal_places(size_t size, unsigned base) +{ + log_assert(base != 10); + BigUnsigned max; + max.setBit(size - 1, true); + size_t places = 0; + while (!max.isZero()) { + places++; + max /= base; + } + return places; +} + +// Only called for integers, either when: +// +// (a) passed without a format string (e.g. "$display(a);"), or +// +// (b) the corresponding format specifier has no leading zero, e.g. "%b", +// "%20h", "%-10d". +// +// In these cases, for binary/octal/hex, we always zero-pad to the size of the +// signal; i.e. whether "%h" or "%10h" or "%-20h" is used, if the corresponding +// signal is 32'h1234, "00001234" will always be a substring of the output. +// +// For case (a), we have no specified width, so there is nothing more to do. +// +// For case (b), because we are only called with no leading zero on the +// specifier, any specified width beyond the signal size is therefore space +// padding, whatever the justification. +// +// For decimal, we do no zero-padding, instead space-padding to the size +// required for the signal's largest value. This is per other Verilog +// implementations, and intuitively makes sense as decimal representations lack +// a discrete mapping of digits to bit groups. Decimals may also show sign and +// must accommodate this, whereas other representations do not. +void Fmt::apply_verilog_automatic_sizing_and_add(FmtPart &part) { if (part.base == 10) { size_t places = compute_required_decimal_places(part.sig.size(), part.signed_); part.padding = ' '; part.width = std::max(part.width, places); - } else { - part.lzero = true; + parts.push_back(part); + return; + } + + part.padding = '0'; + + size_t places = compute_required_nondecimal_places(part.sig.size(), part.base); + if (part.width < places) { + part.justify = FmtPart::RIGHT; + part.width = places; + parts.push_back(part); + } else if (part.width == places) { + parts.push_back(part); + } else if (part.width > places) { + auto gap = std::string(part.width - places, ' '); + part.width = places; + + if (part.justify == FmtPart::RIGHT) { + append_string(gap); + parts.push_back(part); + } else { + part.justify = FmtPart::RIGHT; + parts.push_back(part); + append_string(gap); + } } } @@ -272,8 +322,7 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik part.sig = arg->sig; part.base = default_base; part.signed_ = arg->signed_; - apply_verilog_automatic_sizing(part); - parts.push_back(part); + apply_verilog_automatic_sizing_and_add(part); break; } @@ -379,15 +428,13 @@ void Fmt::parse_verilog(const std::vector &args, bool sformat_lik if (part.padding == '\0') part.padding = (has_leading_zero && part.justify == FmtPart::RIGHT) ? '0' : ' '; - if (part.type == FmtPart::INTEGER) { - if (part.base != 10 && part.plus) { - log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); - } - if (!has_leading_zero) - apply_verilog_automatic_sizing(part); - } + if (part.type == FmtPart::INTEGER && part.base != 10 && part.plus) + log_file_error(fmtarg->filename, fmtarg->first_line, "System task `%s' called with invalid format specifier in argument %zu.\n", task_name.c_str(), fmtarg - args.begin() + 1); - parts.push_back(part); + if (part.type == FmtPart::INTEGER && !has_leading_zero) + apply_verilog_automatic_sizing_and_add(part); + else + parts.push_back(part); part = {}; } } @@ -439,13 +486,10 @@ std::vector Fmt::emit_verilog() const if (part.justify == FmtPart::LEFT) fmt.str += '-'; if (part.width == 0) { - if (!part.lzero) - fmt.str += '0'; + fmt.str += '0'; } else if (part.width > 0) { log_assert(part.padding == ' ' || part.padding == '0'); - if (!part.lzero && part.base != 10) - fmt.str += '0'; - else if (part.padding == '0') + if (part.base != 10 || part.padding == '0') fmt.str += '0'; fmt.str += std::to_string(part.width); } @@ -567,7 +611,6 @@ void Fmt::emit_cxxrtl(std::ostream &f, std::function parts; void append_string(const std::string &str); @@ -96,6 +96,9 @@ struct Fmt { void emit_cxxrtl(std::ostream &f, std::function emit_sig) const; std::string render() const; + +private: + void apply_verilog_automatic_sizing_and_add(FmtPart &part); }; YOSYS_NAMESPACE_END From 843ad9331b6eaefc772d59b52ac0a3e2c04930d7 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:30 +1000 Subject: [PATCH 243/303] cxxrtl: WIP: adjust comb display cells to only fire on change Naming and use of statics to be possibly revised. --- backends/cxxrtl/cxxrtl.h | 2 +- backends/cxxrtl/cxxrtl_backend.cc | 33 ++++++++++++++++++++++++++++++- docs/source/CHAPTER_CellLib.rst | 4 ++-- tests/fmt/always_comb.v | 24 ++++++++++++++++++++++ tests/fmt/always_comb_tb.cc | 14 +++++++++++++ tests/fmt/always_comb_tb.v | 8 ++++++++ tests/fmt/always_full.v | 7 +------ tests/fmt/run-test.sh | 19 ++++++++++++------ 8 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 tests/fmt/always_comb.v create mode 100644 tests/fmt/always_comb_tb.cc create mode 100644 tests/fmt/always_comb_tb.v diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 45ec256af3c..8f5e4035a34 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -850,7 +850,7 @@ std::ostream &operator<<(std::ostream &os, const value_formatted &vf) while (!val.is_zero()) { value quotient; val.divideWithRemainder(value{10u}, quotient); - buf += '0' + val.template slice<3, 0>().val().template get(); + buf += '0' + val.template trunc<(Bits > 4 ? 4 : Bits)>().val().template get(); val = quotient; } if (negative || vf.plus) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 8f06dda66a9..82babe72b4f 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1217,8 +1217,18 @@ struct CxxrtlWorker { // $print cell } else if (cell->type == ID($print)) { log_assert(!for_debug); + + auto trg_enable = cell->getParam(ID::TRG_ENABLE).as_bool(); + static int cell_counter = 0; + if (!trg_enable) { + ++cell_counter; + f << indent << "static bool last_print_" << cell_counter << "_known = false;\n"; + f << indent << "static value<1> last_print_" << cell_counter << "_en;\n"; + f << indent << "static value<" << cell->getPort(ID::ARGS).size() << "> last_print_" << cell_counter << "_args;\n"; + } + f << indent << "if ("; - if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + if (trg_enable) { f << '('; for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { RTLIL::SigBit trg_bit = cell->getPort(ID::TRG)[i]; @@ -1235,6 +1245,17 @@ struct CxxrtlWorker { f << mangle(trg_bit); } f << ") && "; + } else { + f << '('; + f << "!last_print_" << cell_counter << "_known || "; + f << '('; + f << "last_print_" << cell_counter << "_en != "; + dump_sigspec_rhs(cell->getPort(ID::EN)); + + f << " || last_print_" << cell_counter << "_args != "; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ')'; + f << ") && "; } dump_sigspec_rhs(cell->getPort(ID::EN)); f << " == value<1>{1u}) {\n"; @@ -1242,6 +1263,16 @@ struct CxxrtlWorker { dump_print(cell); dec_indent(); f << indent << "}\n"; + + if (!trg_enable) { + f << indent << "last_print_" << cell_counter << "_known = true;\n"; + f << indent << "last_print_" << cell_counter << "_en = "; + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << ";\n"; + f << indent << "last_print_" << cell_counter << "_args = "; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ";\n"; + } // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index dc2ad3e578a..4bbbe0ea85b 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -641,8 +641,8 @@ has the following parameters: The width (in bits) of the signal on the ``\ARGS`` port. ``\TRG_ENABLE`` - True if only triggered on specific signals defined in ``\TRG``; false if - executed on every step. + True if triggered on specific signals defined in ``\TRG``; false if + triggered whenever ``\ARGS`` or ``\EN`` change and ``\EN`` is 1. If ``\TRG_ENABLE`` is true, the following parameters are also set: diff --git a/tests/fmt/always_comb.v b/tests/fmt/always_comb.v new file mode 100644 index 00000000000..7147786bebf --- /dev/null +++ b/tests/fmt/always_comb.v @@ -0,0 +1,24 @@ +module top(input clk); + reg a = 0; + reg b = 0; + wire y; + + sub s (.a(a), .b(b), .y(y)); + + always @(posedge clk) begin + a <= (!a && !b) || (a && !b); + b <= (a && !b) || (a && b); + end +endmodule + +module sub(input a, input b, output wire y); + assign y = a & b; + + // Not fit for our purposes: always @* if (a) $display(a, b, y); + // + // We compare output against iverilog, but async iverilog $display fires + // even before values have propagated -- i.e. combinations of a/b/y will be + // shown where a & b are both 1, but y has not yet taken the value 1. We + // don't, so we specify it in the conditional. + always @* if (y & (y == (a & b))) $display(a, b, y); +endmodule diff --git a/tests/fmt/always_comb_tb.cc b/tests/fmt/always_comb_tb.cc new file mode 100644 index 00000000000..c949af4e330 --- /dev/null +++ b/tests/fmt/always_comb_tb.cc @@ -0,0 +1,14 @@ +#include +#include "yosys-always_comb.cc" + +int main() +{ + cxxrtl_design::p_top uut; + + for (int i = 0; i < 20; ++i) { + uut.p_clk.set(!uut.p_clk); + uut.step(); + } + + return 0; +} diff --git a/tests/fmt/always_comb_tb.v b/tests/fmt/always_comb_tb.v new file mode 100644 index 00000000000..44789743317 --- /dev/null +++ b/tests/fmt/always_comb_tb.v @@ -0,0 +1,8 @@ +module tb; + reg clk = 0; + + top uut (.clk(clk)); + + always #1 clk <= ~clk; + initial #20 $finish; +endmodule diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index 3727813543c..d573bed317d 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -8,8 +8,6 @@ module always_full(input clk, output reg fin); if (counter == 0) fin <= 0; - if (counter == 1) $display("<<>>"); - if (counter == 2) $display("==> small unsigned %%d"); if (counter == 3) $display(":%d:", 16'haa); if (counter == 4) $display(":%-d:", 16'haa); @@ -239,10 +237,7 @@ module always_full(input clk, output reg fin); if (counter == 207) $display("==> write/format"); if (counter == 208) $display("%d", 1, "%d", 1); - if (counter == 209) begin - $display("<<>>"); - fin <= 1; - end + if (counter == 209) fin <= 1; end diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index d793c37dd08..44759dbc140 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -47,12 +47,19 @@ test_roundtrip oct_signed -DBASE_HEX -DSIGN="signed" test_roundtrip bin_unsigned -DBASE_HEX -DSIGN="" test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" -../../yosys -p "read_verilog always_full.v; write_cxxrtl -print-output std::cerr yosys-always_full.cc" -${CC:-gcc} -std=c++11 -o yosys-always_full -I../.. always_full_tb.cc -lstdc++ -./yosys-always_full 2>yosys-always_full.log -iverilog -o iverilog-always_full always_full.v always_full_tb.v -./iverilog-always_full | awk '/<<>>/,/<<>>/ {print $0}' >iverilog-always_full.log -diff iverilog-always_full.log yosys-always_full.log +test_cxxrtl () { + local subtest=$1; shift + + ../../yosys -p "read_verilog ${subtest}.v; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" + ${CC:-gcc} -std=c++11 -o yosys-${subtest} -I../.. ${subtest}_tb.cc -lstdc++ + ./yosys-${subtest} 2>yosys-${subtest}.log + iverilog -o iverilog-${subtest} ${subtest}.v ${subtest}_tb.v + ./iverilog-${subtest} |grep -v '\$finish called' >iverilog-${subtest}.log + diff iverilog-${subtest}.log yosys-${subtest}.log +} + +test_cxxrtl always_full +test_cxxrtl always_comb ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" From 4ffdee65e034493cf1eafd9f94d770c88d2f35e0 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:31 +1000 Subject: [PATCH 244/303] cxxrtl: store comb $print cell last EN/ARGS in module statics were obviously wrong -- may be multiple instantiations of any given module. Extend test to cover this. --- backends/cxxrtl/cxxrtl_backend.cc | 35 ++++++++++++------------------- tests/fmt/always_comb_tb.cc | 9 +++++--- tests/fmt/always_comb_tb.v | 3 ++- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 82babe72b4f..17080ef2ec6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -1219,12 +1219,13 @@ struct CxxrtlWorker { log_assert(!for_debug); auto trg_enable = cell->getParam(ID::TRG_ENABLE).as_bool(); - static int cell_counter = 0; + if (!trg_enable) { - ++cell_counter; - f << indent << "static bool last_print_" << cell_counter << "_known = false;\n"; - f << indent << "static value<1> last_print_" << cell_counter << "_en;\n"; - f << indent << "static value<" << cell->getPort(ID::ARGS).size() << "> last_print_" << cell_counter << "_args;\n"; + f << indent << "auto " << mangle(cell) << "_curr = "; + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << ".concat("; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ").val();\n"; } f << indent << "if ("; @@ -1246,16 +1247,7 @@ struct CxxrtlWorker { } f << ") && "; } else { - f << '('; - f << "!last_print_" << cell_counter << "_known || "; - f << '('; - f << "last_print_" << cell_counter << "_en != "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - - f << " || last_print_" << cell_counter << "_args != "; - dump_sigspec_rhs(cell->getPort(ID::ARGS)); - f << ')'; - f << ") && "; + f << mangle(cell) << " != " << mangle(cell) << "_curr && "; } dump_sigspec_rhs(cell->getPort(ID::EN)); f << " == value<1>{1u}) {\n"; @@ -1265,13 +1257,7 @@ struct CxxrtlWorker { f << indent << "}\n"; if (!trg_enable) { - f << indent << "last_print_" << cell_counter << "_known = true;\n"; - f << indent << "last_print_" << cell_counter << "_en = "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - f << ";\n"; - f << indent << "last_print_" << cell_counter << "_args = "; - dump_sigspec_rhs(cell->getPort(ID::ARGS)); - f << ";\n"; + f << indent << mangle(cell) << " = " << mangle(cell) << "_curr;\n"; } // Flip-flops } else if (is_ff_cell(cell->type)) { @@ -2362,6 +2348,11 @@ struct CxxrtlWorker { f << "\n"; bool has_cells = false; for (auto cell : module->cells()) { + if (cell->type == ID($print) && !cell->getParam(ID::TRG_ENABLE).as_bool()) { + // comb $print cell -- store the last EN/ARGS values to know when they change. + dump_attrs(cell); + f << indent << "value<" << (1 + cell->getParam(ID::ARGS_WIDTH).as_int()) << "> " << mangle(cell) << ";\n"; + } if (is_internal_cell(cell->type)) continue; dump_attrs(cell); diff --git a/tests/fmt/always_comb_tb.cc b/tests/fmt/always_comb_tb.cc index c949af4e330..f2a8c6b2695 100644 --- a/tests/fmt/always_comb_tb.cc +++ b/tests/fmt/always_comb_tb.cc @@ -3,11 +3,14 @@ int main() { - cxxrtl_design::p_top uut; + cxxrtl_design::p_top uut1, uut2; for (int i = 0; i < 20; ++i) { - uut.p_clk.set(!uut.p_clk); - uut.step(); + uut1.p_clk.set(!uut1.p_clk); + uut1.step(); + + uut2.p_clk.set(!uut2.p_clk); + uut2.step(); } return 0; diff --git a/tests/fmt/always_comb_tb.v b/tests/fmt/always_comb_tb.v index 44789743317..3cc4496a04f 100644 --- a/tests/fmt/always_comb_tb.v +++ b/tests/fmt/always_comb_tb.v @@ -1,7 +1,8 @@ module tb; reg clk = 0; - top uut (.clk(clk)); + top uut1 (.clk(clk)); + top uut2 (.clk(clk)); always #1 clk <= ~clk; initial #20 $finish; From f9d38253c56cddf941e7969bb391dd57e78b8a5d Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:31 +1000 Subject: [PATCH 245/303] ast: add `PRIORITY` to `$print` cells --- docs/source/CHAPTER_CellLib.rst | 6 +++++- frontends/ast/genrtlil.cc | 6 +++++- kernel/rtlil.cc | 1 + techlibs/common/simlib.v | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/source/CHAPTER_CellLib.rst b/docs/source/CHAPTER_CellLib.rst index 4bbbe0ea85b..494c0651c6a 100644 --- a/docs/source/CHAPTER_CellLib.rst +++ b/docs/source/CHAPTER_CellLib.rst @@ -644,7 +644,7 @@ has the following parameters: True if triggered on specific signals defined in ``\TRG``; false if triggered whenever ``\ARGS`` or ``\EN`` change and ``\EN`` is 1. -If ``\TRG_ENABLE`` is true, the following parameters are also set: +If ``\TRG_ENABLE`` is true, the following parameters also apply: ``\TRG_WIDTH`` The number of bits in the ``\TRG`` port. @@ -653,6 +653,10 @@ If ``\TRG_ENABLE`` is true, the following parameters are also set: For each bit in ``\TRG``, 1 if that signal is positive-edge triggered, 0 if negative-edge triggered. +``\PRIORITY`` + When multiple ``$print`` cells fire on the same trigger, they execute in + descending priority order. + Ports: ``\TRG`` diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 849b5ebad46..81fb3189d94 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -315,7 +315,10 @@ struct AST_INTERNAL::ProcessGenerator // Buffer for generating the init action RTLIL::SigSpec init_lvalue, init_rvalue; - ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg) + // The most recently assigned $print cell \PRIORITY. + int last_print_priority; + + ProcessGenerator(AstNode *always, RTLIL::SigSpec initSyncSignalsArg = RTLIL::SigSpec()) : always(always), initSyncSignals(initSyncSignalsArg), last_print_priority(0) { // rewrite lookahead references LookaheadRewriter la_rewriter(always); @@ -716,6 +719,7 @@ struct AST_INTERNAL::ProcessGenerator cell->parameters[ID::TRG_WIDTH] = triggers.size(); cell->parameters[ID::TRG_ENABLE] = !triggers.empty(); cell->parameters[ID::TRG_POLARITY] = polarity; + cell->parameters[ID::PRIORITY] = --last_print_priority; cell->setPort(ID::TRG, triggers); Wire *wire = current_module->addWire(sstr.str() + "_EN", 1); diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 09fe0800078..7a59c526275 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1724,6 +1724,7 @@ namespace { param(ID(FORMAT)); param_bool(ID::TRG_ENABLE); param(ID::TRG_POLARITY); + param(ID::PRIORITY); port(ID::EN, 1); port(ID::TRG, param(ID::TRG_WIDTH)); port(ID::ARGS, param(ID::ARGS_WIDTH)); diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 32f2b693740..cdb6e02e762 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1805,6 +1805,7 @@ module \$print (EN, TRG, ARGS); parameter FORMAT = ""; parameter ARGS_WIDTH = 0; +parameter PRIORITY = 0; parameter TRG_ENABLE = 1; parameter TRG_WIDTH = 0; From 04582f2fb79e08a4a8264add98b2080d329379db Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:32 +1000 Subject: [PATCH 246/303] verilog_backend: emit sync `$print` cells with same triggers together Sort by PRIORITY, ensuring output order. --- backends/verilog/verilog_backend.cc | 126 +++++--- tests/fmt/always_full.v | 466 ++++++++++++++-------------- tests/fmt/always_full_tb.cc | 11 +- tests/fmt/always_full_tb.v | 6 +- tests/fmt/run-test.sh | 6 + 5 files changed, 319 insertions(+), 296 deletions(-) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index 573fa6d5b84..ca119427f6d 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1006,6 +1006,41 @@ void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell f << stringf(";\n"); } +void dump_cell_expr_print(std::ostream &f, std::string indent, RTLIL::Cell *cell) +{ + Fmt fmt = {}; + fmt.parse_rtlil(cell); + std::vector args = fmt.emit_verilog(); + + f << stringf("%s" "$write(", indent.c_str()); + bool first = true; + for (auto &arg : args) { + if (first) { + first = false; + } else { + f << ", "; + } + switch (arg.type) { + case VerilogFmtArg::STRING: + dump_const(f, RTLIL::Const(arg.str)); + break; + case VerilogFmtArg::INTEGER: + f << (arg.signed_ ? "$signed(" : "$unsigned("); + dump_sigspec(f, arg.sig); + f << ")"; + break; + case VerilogFmtArg::TIME: + if (arg.realtime) + f << "$realtime"; + else + f << "$time"; + break; + default: log_abort(); + } + } + f << stringf(");\n"); +} + bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) { if (cell->type == ID($_NOT_)) { @@ -1756,58 +1791,17 @@ bool dump_cell_expr(std::ostream &f, std::string indent, RTLIL::Cell *cell) if (cell->type == ID($print)) { - Fmt fmt = {}; - fmt.parse_rtlil(cell); - std::vector args = fmt.emit_verilog(); - - if (cell->getParam(ID::TRG_ENABLE).as_bool()) { - f << stringf("%s" "always @(", indent.c_str()); - for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { - if (i != 0) - f << " or "; - if (cell->getParam(ID::TRG_POLARITY)[i]) - f << "posedge "; - else - f << "negedge "; - dump_sigspec(f, cell->getPort(ID::TRG)[i]); - } - f << ")\n"; - } else { - f << stringf("%s" "always @*\n", indent.c_str()); - } + // Sync $print cells are accumulated and handled in dump_module. + if (cell->getParam(ID::TRG_ENABLE).as_bool()) + return true; + + f << stringf("%s" "always @*\n", indent.c_str()); f << stringf("%s" " if (", indent.c_str()); dump_sigspec(f, cell->getPort(ID::EN)); f << stringf(")\n"); - f << stringf("%s" " $write(", indent.c_str()); - bool first = true; - for (auto &arg : args) { - if (first) { - first = false; - } else { - f << ", "; - } - switch (arg.type) { - case VerilogFmtArg::STRING: - dump_const(f, RTLIL::Const(arg.str)); - break; - case VerilogFmtArg::INTEGER: - f << (arg.signed_ ? "$signed(" : "$unsigned("); - dump_sigspec(f, arg.sig); - f << ")"; - break; - case VerilogFmtArg::TIME: - if (arg.realtime) - f << "$realtime"; - else - f << "$time"; - break; - default: log_abort(); - } - } - f << stringf(");\n"); - + dump_cell_expr_print(f, indent + " ", cell); return true; } @@ -1899,6 +1893,34 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } +void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) +{ + f << stringf("%s" "always @(", indent.c_str()); + for (int i = 0; i < trg.size(); i++) { + if (i != 0) + f << " or "; + if (polarity[i]) + f << "posedge "; + else + f << "negedge "; + dump_sigspec(f, trg[i]); + } + f << ") begin\n"; + + std::sort(cells.begin(), cells.end(), [](const RTLIL::Cell *a, const RTLIL::Cell *b) { + return a->getParam(ID::PRIORITY).as_int() > b->getParam(ID::PRIORITY).as_int(); + }); + for (auto cell : cells) { + f << stringf("%s" " if (", indent.c_str()); + dump_sigspec(f, cell->getPort(ID::EN)); + f << stringf(")\n"); + + dump_cell_expr_print(f, indent + " ", cell); + } + + f << stringf("%s" "end\n", indent.c_str()); +} + void dump_conn(std::ostream &f, std::string indent, const RTLIL::SigSpec &left, const RTLIL::SigSpec &right) { if (simple_lhs) { @@ -2080,6 +2102,8 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) { + std::map, std::vector> sync_print_cells; + reg_wires.clear(); reset_auto_counter(module); active_module = module; @@ -2110,6 +2134,11 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) std::set> reg_bits; for (auto cell : module->cells()) { + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) { + sync_print_cells[make_pair(cell->getPort(ID::TRG), cell->getParam(ID::TRG_POLARITY))].push_back(cell); + continue; + } + if (!RTLIL::builtin_ff_cell_types().count(cell->type) || !cell->hasPort(ID::Q) || cell->type.in(ID($ff), ID($_FF_))) continue; @@ -2165,6 +2194,9 @@ void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) for (auto cell : module->cells()) dump_cell(f, indent + " ", cell); + for (auto &it : sync_print_cells) + dump_sync_print(f, indent + " ", it.first.first, it.first.second, it.second); + for (auto it = module->processes.begin(); it != module->processes.end(); ++it) dump_process(f, indent + " ", it->second); diff --git a/tests/fmt/always_full.v b/tests/fmt/always_full.v index d573bed317d..4d3df7a615c 100644 --- a/tests/fmt/always_full.v +++ b/tests/fmt/always_full.v @@ -1,243 +1,235 @@ -module always_full(input clk, output reg fin); - - reg [7:0] counter = 0; +module always_full(input clk); always @(posedge clk) begin - counter <= counter + 1; - - if (counter == 0) fin <= 0; - - if (counter == 2) $display("==> small unsigned %%d"); - if (counter == 3) $display(":%d:", 16'haa); - if (counter == 4) $display(":%-d:", 16'haa); - if (counter == 5) $display(":%+d:", 16'haa); - if (counter == 6) $display(":%+-d:", 16'haa); - if (counter == 7) $display(":%0d:", 16'haa); - if (counter == 8) $display(":%-0d:", 16'haa); - if (counter == 9) $display(":%+0d:", 16'haa); - if (counter == 10) $display(":%+-0d:", 16'haa); - if (counter == 11) $display(":%20d:", 16'haa); - if (counter == 12) $display(":%-20d:", 16'haa); - if (counter == 13) $display(":%+20d:", 16'haa); - if (counter == 14) $display(":%+-20d:", 16'haa); - if (counter == 15) $display(":%020d:", 16'haa); - if (counter == 16) $display(":%-020d:", 16'haa); - if (counter == 17) $display(":%+020d:", 16'haa); - if (counter == 18) $display(":%+-020d:", 16'haa); - - if (counter == 19) $display("==> big unsigned %%d"); - if (counter == 20) $display(":%d:", 16'haaaa); - if (counter == 21) $display(":%-d:", 16'haaaa); - if (counter == 22) $display(":%+d:", 16'haaaa); - if (counter == 23) $display(":%+-d:", 16'haaaa); - if (counter == 24) $display(":%0d:", 16'haaaa); - if (counter == 25) $display(":%-0d:", 16'haaaa); - if (counter == 26) $display(":%+0d:", 16'haaaa); - if (counter == 27) $display(":%+-0d:", 16'haaaa); - if (counter == 28) $display(":%20d:", 16'haaaa); - if (counter == 29) $display(":%-20d:", 16'haaaa); - if (counter == 30) $display(":%+20d:", 16'haaaa); - if (counter == 31) $display(":%+-20d:", 16'haaaa); - if (counter == 32) $display(":%020d:", 16'haaaa); - if (counter == 33) $display(":%-020d:", 16'haaaa); - if (counter == 34) $display(":%+020d:", 16'haaaa); - if (counter == 35) $display(":%+-020d:", 16'haaaa); - - if (counter == 36) $display("==> small signed %%d"); - if (counter == 37) $display(":%d:", 16'shaa); - if (counter == 38) $display(":%-d:", 16'shaa); - if (counter == 39) $display(":%+d:", 16'shaa); - if (counter == 40) $display(":%+-d:", 16'shaa); - if (counter == 41) $display(":%0d:", 16'shaa); - if (counter == 42) $display(":%-0d:", 16'shaa); - if (counter == 43) $display(":%+0d:", 16'shaa); - if (counter == 44) $display(":%+-0d:", 16'shaa); - if (counter == 45) $display(":%20d:", 16'shaa); - if (counter == 46) $display(":%-20d:", 16'shaa); - if (counter == 47) $display(":%+20d:", 16'shaa); - if (counter == 48) $display(":%+-20d:", 16'shaa); - if (counter == 49) $display(":%020d:", 16'shaa); - if (counter == 50) $display(":%-020d:", 16'shaa); - if (counter == 51) $display(":%+020d:", 16'shaa); - if (counter == 52) $display(":%+-020d:", 16'shaa); - - if (counter == 53) $display("==> big signed %%d"); - if (counter == 54) $display(":%d:", 16'shaaaa); - if (counter == 55) $display(":%-d:", 16'shaaaa); - if (counter == 56) $display(":%+d:", 16'shaaaa); - if (counter == 57) $display(":%+-d:", 16'shaaaa); - if (counter == 58) $display(":%0d:", 16'shaaaa); - if (counter == 59) $display(":%-0d:", 16'shaaaa); - if (counter == 60) $display(":%+0d:", 16'shaaaa); - if (counter == 61) $display(":%+-0d:", 16'shaaaa); - if (counter == 62) $display(":%20d:", 16'shaaaa); - if (counter == 63) $display(":%-20d:", 16'shaaaa); - if (counter == 64) $display(":%+20d:", 16'shaaaa); - if (counter == 65) $display(":%+-20d:", 16'shaaaa); - if (counter == 66) $display(":%020d:", 16'shaaaa); - if (counter == 67) $display(":%-020d:", 16'shaaaa); - if (counter == 68) $display(":%+020d:", 16'shaaaa); - if (counter == 69) $display(":%+-020d:", 16'shaaaa); - - if (counter == 70) $display("==> small unsigned %%h"); - if (counter == 71) $display(":%h:", 16'haa); - if (counter == 72) $display(":%-h:", 16'haa); - if (counter == 73) $display(":%0h:", 16'haa); - if (counter == 74) $display(":%-0h:", 16'haa); - if (counter == 75) $display(":%20h:", 16'haa); - if (counter == 76) $display(":%-20h:", 16'haa); - if (counter == 77) $display(":%020h:", 16'haa); - if (counter == 78) $display(":%-020h:", 16'haa); - - if (counter == 79) $display("==> big unsigned %%h"); - if (counter == 80) $display(":%h:", 16'haaaa); - if (counter == 81) $display(":%-h:", 16'haaaa); - if (counter == 82) $display(":%0h:", 16'haaaa); - if (counter == 83) $display(":%-0h:", 16'haaaa); - if (counter == 84) $display(":%20h:", 16'haaaa); - if (counter == 85) $display(":%-20h:", 16'haaaa); - if (counter == 86) $display(":%020h:", 16'haaaa); - if (counter == 87) $display(":%-020h:", 16'haaaa); - - if (counter == 88) $display("==> small signed %%h"); - if (counter == 89) $display(":%h:", 16'shaa); - if (counter == 90) $display(":%-h:", 16'shaa); - if (counter == 91) $display(":%0h:", 16'shaa); - if (counter == 92) $display(":%-0h:", 16'shaa); - if (counter == 93) $display(":%20h:", 16'shaa); - if (counter == 94) $display(":%-20h:", 16'shaa); - if (counter == 95) $display(":%020h:", 16'shaa); - if (counter == 96) $display(":%-020h:", 16'shaa); - - if (counter == 97) $display("==> big signed %%h"); - if (counter == 98) $display(":%h:", 16'shaaaa); - if (counter == 99) $display(":%-h:", 16'shaaaa); - if (counter == 100) $display(":%0h:", 16'shaaaa); - if (counter == 101) $display(":%-0h:", 16'shaaaa); - if (counter == 102) $display(":%20h:", 16'shaaaa); - if (counter == 103) $display(":%-20h:", 16'shaaaa); - if (counter == 104) $display(":%020h:", 16'shaaaa); - if (counter == 105) $display(":%-020h:", 16'shaaaa); - - if (counter == 106) $display("==> small unsigned %%o"); - if (counter == 107) $display(":%o:", 16'haa); - if (counter == 108) $display(":%-o:", 16'haa); - if (counter == 109) $display(":%0o:", 16'haa); - if (counter == 110) $display(":%-0o:", 16'haa); - if (counter == 111) $display(":%20o:", 16'haa); - if (counter == 112) $display(":%-20o:", 16'haa); - if (counter == 113) $display(":%020o:", 16'haa); - if (counter == 114) $display(":%-020o:", 16'haa); - - if (counter == 115) $display("==> big unsigned %%o"); - if (counter == 116) $display(":%o:", 16'haaaa); - if (counter == 117) $display(":%-o:", 16'haaaa); - if (counter == 118) $display(":%0o:", 16'haaaa); - if (counter == 119) $display(":%-0o:", 16'haaaa); - if (counter == 120) $display(":%20o:", 16'haaaa); - if (counter == 121) $display(":%-20o:", 16'haaaa); - if (counter == 122) $display(":%020o:", 16'haaaa); - if (counter == 123) $display(":%-020o:", 16'haaaa); - - if (counter == 124) $display("==> small signed %%o"); - if (counter == 125) $display(":%o:", 16'shaa); - if (counter == 126) $display(":%-o:", 16'shaa); - if (counter == 127) $display(":%0o:", 16'shaa); - if (counter == 128) $display(":%-0o:", 16'shaa); - if (counter == 129) $display(":%20o:", 16'shaa); - if (counter == 130) $display(":%-20o:", 16'shaa); - if (counter == 131) $display(":%020o:", 16'shaa); - if (counter == 132) $display(":%-020o:", 16'shaa); - - if (counter == 133) $display("==> big signed %%o"); - if (counter == 134) $display(":%o:", 16'shaaaa); - if (counter == 135) $display(":%-o:", 16'shaaaa); - if (counter == 136) $display(":%0o:", 16'shaaaa); - if (counter == 137) $display(":%-0o:", 16'shaaaa); - if (counter == 138) $display(":%20o:", 16'shaaaa); - if (counter == 139) $display(":%-20o:", 16'shaaaa); - if (counter == 140) $display(":%020o:", 16'shaaaa); - if (counter == 141) $display(":%-020o:", 16'shaaaa); - - if (counter == 142) $display("==> small unsigned %%b"); - if (counter == 143) $display(":%b:", 16'haa); - if (counter == 144) $display(":%-b:", 16'haa); - if (counter == 145) $display(":%0b:", 16'haa); - if (counter == 146) $display(":%-0b:", 16'haa); - if (counter == 147) $display(":%20b:", 16'haa); - if (counter == 148) $display(":%-20b:", 16'haa); - if (counter == 149) $display(":%020b:", 16'haa); - if (counter == 150) $display(":%-020b:", 16'haa); - - if (counter == 151) $display("==> big unsigned %%b"); - if (counter == 152) $display(":%b:", 16'haaaa); - if (counter == 153) $display(":%-b:", 16'haaaa); - if (counter == 154) $display(":%0b:", 16'haaaa); - if (counter == 155) $display(":%-0b:", 16'haaaa); - if (counter == 156) $display(":%20b:", 16'haaaa); - if (counter == 157) $display(":%-20b:", 16'haaaa); - if (counter == 158) $display(":%020b:", 16'haaaa); - if (counter == 159) $display(":%-020b:", 16'haaaa); - - if (counter == 160) $display("==> small signed %%b"); - if (counter == 161) $display(":%b:", 16'shaa); - if (counter == 162) $display(":%-b:", 16'shaa); - if (counter == 163) $display(":%0b:", 16'shaa); - if (counter == 164) $display(":%-0b:", 16'shaa); - if (counter == 165) $display(":%20b:", 16'shaa); - if (counter == 166) $display(":%-20b:", 16'shaa); - if (counter == 167) $display(":%020b:", 16'shaa); - if (counter == 168) $display(":%-020b:", 16'shaa); - - if (counter == 169) $display("==> big signed %%b"); - if (counter == 170) $display(":%b:", 16'shaaaa); - if (counter == 171) $display(":%-b:", 16'shaaaa); - if (counter == 172) $display(":%0b:", 16'shaaaa); - if (counter == 173) $display(":%-0b:", 16'shaaaa); - if (counter == 174) $display(":%20b:", 16'shaaaa); - if (counter == 175) $display(":%-20b:", 16'shaaaa); - if (counter == 176) $display(":%020b:", 16'shaaaa); - if (counter == 177) $display(":%-020b:", 16'shaaaa); - - if (counter == 178) $display("==> time %%t"); - if (counter == 179) $display(":%t:", $time); - if (counter == 180) $display(":%-t:", $time); - if (counter == 181) $display(":%0t:", $time); - if (counter == 182) $display(":%-0t:", $time); - if (counter == 183) $display(":%10t:", $time); - if (counter == 184) $display(":%-10t:", $time); - if (counter == 185) $display(":%015t:", $time); - if (counter == 186) $display(":%-015t:", $time); - - if (counter == 187) $display("===> %%s"); - if (counter == 188) $display(":%10s:", "foo"); - if (counter == 189) $display(":%010s:", "foo"); - if (counter == 190) $display(":%-10s:", "foo"); - if (counter == 191) $display(":%-010s:", "foo"); - - if (counter == 192) $display("===> %%c"); - if (counter == 193) $display(":%10c:", "foo"); - if (counter == 194) $display(":%010c:", "foo"); - if (counter == 195) $display(":%-10c:", "foo"); - if (counter == 196) $display(":%-010c:", "foo"); - - if (counter == 197) $display("==> aliases"); - if (counter == 198) $display(":%x:", 16'shaa); - if (counter == 199) $display(":%X:", 16'shaa); - if (counter == 200) $display(":%H:", 16'shaa); - if (counter == 201) $display(":%O:", 16'shaa); - if (counter == 202) $display(":%B:", 16'shaa); - - if (counter == 203) $display("==> default base"); - if (counter == 204) $displayh(16'haa); - if (counter == 205) $displayo(16'haa); - if (counter == 206) $displayb(16'haa); - - if (counter == 207) $display("==> write/format"); - if (counter == 208) $display("%d", 1, "%d", 1); - - if (counter == 209) fin <= 1; + $display("==> small unsigned %%d"); + $display(":%d:", 16'haa); + $display(":%-d:", 16'haa); + $display(":%+d:", 16'haa); + $display(":%+-d:", 16'haa); + $display(":%0d:", 16'haa); + $display(":%-0d:", 16'haa); + $display(":%+0d:", 16'haa); + $display(":%+-0d:", 16'haa); + $display(":%20d:", 16'haa); + $display(":%-20d:", 16'haa); + $display(":%+20d:", 16'haa); + $display(":%+-20d:", 16'haa); + $display(":%020d:", 16'haa); + $display(":%-020d:", 16'haa); + $display(":%+020d:", 16'haa); + $display(":%+-020d:", 16'haa); + + $display("==> big unsigned %%d"); + $display(":%d:", 16'haaaa); + $display(":%-d:", 16'haaaa); + $display(":%+d:", 16'haaaa); + $display(":%+-d:", 16'haaaa); + $display(":%0d:", 16'haaaa); + $display(":%-0d:", 16'haaaa); + $display(":%+0d:", 16'haaaa); + $display(":%+-0d:", 16'haaaa); + $display(":%20d:", 16'haaaa); + $display(":%-20d:", 16'haaaa); + $display(":%+20d:", 16'haaaa); + $display(":%+-20d:", 16'haaaa); + $display(":%020d:", 16'haaaa); + $display(":%-020d:", 16'haaaa); + $display(":%+020d:", 16'haaaa); + $display(":%+-020d:", 16'haaaa); + + $display("==> small signed %%d"); + $display(":%d:", 16'shaa); + $display(":%-d:", 16'shaa); + $display(":%+d:", 16'shaa); + $display(":%+-d:", 16'shaa); + $display(":%0d:", 16'shaa); + $display(":%-0d:", 16'shaa); + $display(":%+0d:", 16'shaa); + $display(":%+-0d:", 16'shaa); + $display(":%20d:", 16'shaa); + $display(":%-20d:", 16'shaa); + $display(":%+20d:", 16'shaa); + $display(":%+-20d:", 16'shaa); + $display(":%020d:", 16'shaa); + $display(":%-020d:", 16'shaa); + $display(":%+020d:", 16'shaa); + $display(":%+-020d:", 16'shaa); + + $display("==> big signed %%d"); + $display(":%d:", 16'shaaaa); + $display(":%-d:", 16'shaaaa); + $display(":%+d:", 16'shaaaa); + $display(":%+-d:", 16'shaaaa); + $display(":%0d:", 16'shaaaa); + $display(":%-0d:", 16'shaaaa); + $display(":%+0d:", 16'shaaaa); + $display(":%+-0d:", 16'shaaaa); + $display(":%20d:", 16'shaaaa); + $display(":%-20d:", 16'shaaaa); + $display(":%+20d:", 16'shaaaa); + $display(":%+-20d:", 16'shaaaa); + $display(":%020d:", 16'shaaaa); + $display(":%-020d:", 16'shaaaa); + $display(":%+020d:", 16'shaaaa); + $display(":%+-020d:", 16'shaaaa); + + $display("==> small unsigned %%h"); + $display(":%h:", 16'haa); + $display(":%-h:", 16'haa); + $display(":%0h:", 16'haa); + $display(":%-0h:", 16'haa); + $display(":%20h:", 16'haa); + $display(":%-20h:", 16'haa); + $display(":%020h:", 16'haa); + $display(":%-020h:", 16'haa); + + $display("==> big unsigned %%h"); + $display(":%h:", 16'haaaa); + $display(":%-h:", 16'haaaa); + $display(":%0h:", 16'haaaa); + $display(":%-0h:", 16'haaaa); + $display(":%20h:", 16'haaaa); + $display(":%-20h:", 16'haaaa); + $display(":%020h:", 16'haaaa); + $display(":%-020h:", 16'haaaa); + + $display("==> small signed %%h"); + $display(":%h:", 16'shaa); + $display(":%-h:", 16'shaa); + $display(":%0h:", 16'shaa); + $display(":%-0h:", 16'shaa); + $display(":%20h:", 16'shaa); + $display(":%-20h:", 16'shaa); + $display(":%020h:", 16'shaa); + $display(":%-020h:", 16'shaa); + + $display("==> big signed %%h"); + $display(":%h:", 16'shaaaa); + $display(":%-h:", 16'shaaaa); + $display(":%0h:", 16'shaaaa); + $display(":%-0h:", 16'shaaaa); + $display(":%20h:", 16'shaaaa); + $display(":%-20h:", 16'shaaaa); + $display(":%020h:", 16'shaaaa); + $display(":%-020h:", 16'shaaaa); + + $display("==> small unsigned %%o"); + $display(":%o:", 16'haa); + $display(":%-o:", 16'haa); + $display(":%0o:", 16'haa); + $display(":%-0o:", 16'haa); + $display(":%20o:", 16'haa); + $display(":%-20o:", 16'haa); + $display(":%020o:", 16'haa); + $display(":%-020o:", 16'haa); + + $display("==> big unsigned %%o"); + $display(":%o:", 16'haaaa); + $display(":%-o:", 16'haaaa); + $display(":%0o:", 16'haaaa); + $display(":%-0o:", 16'haaaa); + $display(":%20o:", 16'haaaa); + $display(":%-20o:", 16'haaaa); + $display(":%020o:", 16'haaaa); + $display(":%-020o:", 16'haaaa); + + $display("==> small signed %%o"); + $display(":%o:", 16'shaa); + $display(":%-o:", 16'shaa); + $display(":%0o:", 16'shaa); + $display(":%-0o:", 16'shaa); + $display(":%20o:", 16'shaa); + $display(":%-20o:", 16'shaa); + $display(":%020o:", 16'shaa); + $display(":%-020o:", 16'shaa); + + $display("==> big signed %%o"); + $display(":%o:", 16'shaaaa); + $display(":%-o:", 16'shaaaa); + $display(":%0o:", 16'shaaaa); + $display(":%-0o:", 16'shaaaa); + $display(":%20o:", 16'shaaaa); + $display(":%-20o:", 16'shaaaa); + $display(":%020o:", 16'shaaaa); + $display(":%-020o:", 16'shaaaa); + + $display("==> small unsigned %%b"); + $display(":%b:", 16'haa); + $display(":%-b:", 16'haa); + $display(":%0b:", 16'haa); + $display(":%-0b:", 16'haa); + $display(":%20b:", 16'haa); + $display(":%-20b:", 16'haa); + $display(":%020b:", 16'haa); + $display(":%-020b:", 16'haa); + + $display("==> big unsigned %%b"); + $display(":%b:", 16'haaaa); + $display(":%-b:", 16'haaaa); + $display(":%0b:", 16'haaaa); + $display(":%-0b:", 16'haaaa); + $display(":%20b:", 16'haaaa); + $display(":%-20b:", 16'haaaa); + $display(":%020b:", 16'haaaa); + $display(":%-020b:", 16'haaaa); + + $display("==> small signed %%b"); + $display(":%b:", 16'shaa); + $display(":%-b:", 16'shaa); + $display(":%0b:", 16'shaa); + $display(":%-0b:", 16'shaa); + $display(":%20b:", 16'shaa); + $display(":%-20b:", 16'shaa); + $display(":%020b:", 16'shaa); + $display(":%-020b:", 16'shaa); + + $display("==> big signed %%b"); + $display(":%b:", 16'shaaaa); + $display(":%-b:", 16'shaaaa); + $display(":%0b:", 16'shaaaa); + $display(":%-0b:", 16'shaaaa); + $display(":%20b:", 16'shaaaa); + $display(":%-20b:", 16'shaaaa); + $display(":%020b:", 16'shaaaa); + $display(":%-020b:", 16'shaaaa); + + $display("==> time %%t"); + $display(":%t:", $time); + $display(":%-t:", $time); + $display(":%0t:", $time); + $display(":%-0t:", $time); + $display(":%10t:", $time); + $display(":%-10t:", $time); + $display(":%015t:", $time); + $display(":%-015t:", $time); + + $display("===> %%s"); + $display(":%10s:", "foo"); + $display(":%010s:", "foo"); + $display(":%-10s:", "foo"); + $display(":%-010s:", "foo"); + + $display("===> %%c"); + $display(":%10c:", "foo"); + $display(":%010c:", "foo"); + $display(":%-10c:", "foo"); + $display(":%-010c:", "foo"); + + $display("==> aliases"); + $display(":%x:", 16'shaa); + $display(":%X:", 16'shaa); + $display(":%H:", 16'shaa); + $display(":%O:", 16'shaa); + $display(":%B:", 16'shaa); + + $display("==> default base"); + $displayh(16'haa); + $displayo(16'haa); + $displayb(16'haa); + + $display("==> write/format"); + $display("%d", 1, "%d", 1); end diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc index 8bf1022d330..bd98020dec1 100644 --- a/tests/fmt/always_full_tb.cc +++ b/tests/fmt/always_full_tb.cc @@ -4,12 +4,7 @@ int main() { cxxrtl_design::p_always__full uut; - - while (true) { - uut.p_clk.set(!uut.p_clk); - uut.step(); - - if (uut.p_fin.get()) - return 0; - } + uut.p_clk.set(!uut.p_clk); + uut.step(); + return 0; } diff --git a/tests/fmt/always_full_tb.v b/tests/fmt/always_full_tb.v index 1edd35b67d9..0c2599cc263 100644 --- a/tests/fmt/always_full_tb.v +++ b/tests/fmt/always_full_tb.v @@ -1,14 +1,12 @@ module always_full_tb; reg clk = 0; - wire fin; - always_full uut (.clk(clk), .fin(fin)); + always_full uut (.clk(clk)); always begin #1 clk <= ~clk; - - if (fin) $finish; + #1 $finish; end endmodule diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index 44759dbc140..ba5aea9f627 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -61,6 +61,12 @@ test_cxxrtl () { test_cxxrtl always_full test_cxxrtl always_comb +# Ensure Verilog backend preserves behaviour of always block with multiple $displays. +../../yosys -p "read_verilog always_full.v; prep; clean" -o yosys-always_full-1.v +iverilog -o iverilog-always_full-1 yosys-always_full-1.v always_full_tb.v +./iverilog-always_full-1 |grep -v '\$finish called' >iverilog-always_full-1.log +diff iverilog-always_full.log iverilog-always_full-1.log + ../../yosys -p "read_verilog display_lm.v" >yosys-display_lm.log ../../yosys -p "read_verilog display_lm.v; write_cxxrtl yosys-display_lm.cc" ${CC:-gcc} -std=c++11 -o yosys-display_lm_cc -I../.. display_lm_tb.cc -lstdc++ From ce245b51054a316d3f4c3476335a4b42221af21f Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:33 +1000 Subject: [PATCH 247/303] cxxrtl_backend: respect sync `$print` priority We add a new flow graph node type, PRINT_SYNC, as they don't get handled with regular CELL_EVALs. We could probably move this grouping out of the dump method. --- backends/cxxrtl/cxxrtl_backend.cc | 102 +++++++++++++++++----------- backends/verilog/verilog_backend.cc | 6 +- tests/fmt/run-test.sh | 2 +- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 17080ef2ec6..8f9cd941ecb 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -282,6 +282,7 @@ struct FlowGraph { CONNECT, CELL_SYNC, CELL_EVAL, + PRINT_SYNC, PROCESS_SYNC, PROCESS_CASE, MEM_RDPORT, @@ -472,6 +473,8 @@ struct FlowGraph { Node *node = new Node; node->type = Node::Type::CELL_EVAL; + if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) + node->type = Node::Type::PRINT_SYNC; node->cell = cell; nodes.push_back(node); add_cell_eval_defs_uses(node, cell); @@ -1043,9 +1046,49 @@ struct CxxrtlWorker { Fmt fmt = {}; fmt.parse_rtlil(cell); - f << indent << print_output; - fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); - f << ";\n"; + f << indent << "if ("; + dump_sigspec_rhs(cell->getPort(ID::EN)); + f << " == value<1>{1u}) {\n"; + inc_indent(); + f << indent << print_output; + fmt.emit_cxxrtl(f, [this](const RTLIL::SigSpec &sig) { dump_sigspec_rhs(sig); }); + f << ";\n"; + dec_indent(); + f << indent << "}\n"; + } + + void dump_sync_print(const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) + { + f << indent << "if ("; + for (int i = 0; i < trg.size(); i++) { + RTLIL::SigBit trg_bit = trg[i]; + trg_bit = sigmaps[trg_bit.wire->module](trg_bit); + log_assert(trg_bit.wire); + + if (i != 0) + f << " || "; + + if (polarity[i] == State::S1) + f << "posedge_"; + else + f << "negedge_"; + f << mangle(trg_bit); + } + f << ") {\n"; + inc_indent(); + std::sort(cells.begin(), cells.end(), [](const RTLIL::Cell *a, const RTLIL::Cell *b) { + return a->getParam(ID::PRIORITY).as_int() > b->getParam(ID::PRIORITY).as_int(); + }); + for (auto cell : cells) { + log_assert(cell->getParam(ID::TRG_ENABLE).as_bool()); + std::vector inlined_cells; + collect_cell_eval(cell, /*for_debug=*/false, inlined_cells); + dump_inlined_cells(inlined_cells); + dump_print(cell); + } + dec_indent(); + + f << indent << "}\n"; } void dump_inlined_cells(const std::vector &cells) @@ -1218,47 +1261,21 @@ struct CxxrtlWorker { } else if (cell->type == ID($print)) { log_assert(!for_debug); - auto trg_enable = cell->getParam(ID::TRG_ENABLE).as_bool(); + // Sync $print cells become PRINT_SYNC in the FlowGraph, not CELL_EVAL. + log_assert(!cell->getParam(ID::TRG_ENABLE).as_bool()); - if (!trg_enable) { - f << indent << "auto " << mangle(cell) << "_curr = "; - dump_sigspec_rhs(cell->getPort(ID::EN)); - f << ".concat("; - dump_sigspec_rhs(cell->getPort(ID::ARGS)); - f << ").val();\n"; - } - - f << indent << "if ("; - if (trg_enable) { - f << '('; - for (size_t i = 0; i < (size_t)cell->getParam(ID::TRG_WIDTH).as_int(); i++) { - RTLIL::SigBit trg_bit = cell->getPort(ID::TRG)[i]; - trg_bit = sigmaps[trg_bit.wire->module](trg_bit); - log_assert(trg_bit.wire); - - if (i != 0) - f << " || "; - - if (cell->getParam(ID::TRG_POLARITY)[i] == State::S1) - f << "posedge_"; - else - f << "negedge_"; - f << mangle(trg_bit); - } - f << ") && "; - } else { - f << mangle(cell) << " != " << mangle(cell) << "_curr && "; - } + f << indent << "auto " << mangle(cell) << "_curr = "; dump_sigspec_rhs(cell->getPort(ID::EN)); - f << " == value<1>{1u}) {\n"; + f << ".concat("; + dump_sigspec_rhs(cell->getPort(ID::ARGS)); + f << ").val();\n"; + + f << indent << "if (" << mangle(cell) << " != " << mangle(cell) << "_curr) {\n"; inc_indent(); dump_print(cell); + f << indent << mangle(cell) << " = " << mangle(cell) << "_curr;\n"; dec_indent(); f << indent << "}\n"; - - if (!trg_enable) { - f << indent << mangle(cell) << " = " << mangle(cell) << "_curr;\n"; - } // Flip-flops } else if (is_ff_cell(cell->type)) { log_assert(!for_debug); @@ -1971,6 +1988,8 @@ struct CxxrtlWorker { void dump_eval_method(RTLIL::Module *module) { + std::map, std::vector> sync_print_cells; + inc_indent(); f << indent << "bool converged = " << (eval_converges.at(module) ? "true" : "false") << ";\n"; if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { @@ -2003,6 +2022,9 @@ struct CxxrtlWorker { case FlowGraph::Node::Type::CELL_EVAL: dump_cell_eval(node.cell); break; + case FlowGraph::Node::Type::PRINT_SYNC: + sync_print_cells[make_pair(node.cell->getPort(ID::TRG), node.cell->getParam(ID::TRG_POLARITY))].push_back(node.cell); + break; case FlowGraph::Node::Type::PROCESS_CASE: dump_process_case(node.process); break; @@ -2017,6 +2039,8 @@ struct CxxrtlWorker { break; } } + for (auto &it : sync_print_cells) + dump_sync_print(it.first.first, it.first.second, it.second); } f << indent << "return converged;\n"; dec_indent(); @@ -2808,6 +2832,8 @@ struct CxxrtlWorker { for (auto node : flow.nodes) { if (node->type == FlowGraph::Node::Type::CELL_EVAL && is_effectful_cell(node->cell->type)) worklist.insert(node); // node has effects + else if (node->type == FlowGraph::Node::Type::PRINT_SYNC) + worklist.insert(node); // node is sync $print else if (node->type == FlowGraph::Node::Type::MEM_WRPORTS) worklist.insert(node); // node is memory write else if (node->type == FlowGraph::Node::Type::PROCESS_SYNC && is_memwr_process(node->process)) diff --git a/backends/verilog/verilog_backend.cc b/backends/verilog/verilog_backend.cc index ca119427f6d..7099c18c349 100644 --- a/backends/verilog/verilog_backend.cc +++ b/backends/verilog/verilog_backend.cc @@ -1006,7 +1006,7 @@ void dump_cell_expr_binop(std::ostream &f, std::string indent, RTLIL::Cell *cell f << stringf(";\n"); } -void dump_cell_expr_print(std::ostream &f, std::string indent, RTLIL::Cell *cell) +void dump_cell_expr_print(std::ostream &f, std::string indent, const RTLIL::Cell *cell) { Fmt fmt = {}; fmt.parse_rtlil(cell); @@ -1893,7 +1893,7 @@ void dump_cell(std::ostream &f, std::string indent, RTLIL::Cell *cell) } } -void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) +void dump_sync_print(std::ostream &f, std::string indent, const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) { f << stringf("%s" "always @(", indent.c_str()); for (int i = 0; i < trg.size(); i++) { @@ -2102,7 +2102,7 @@ void dump_process(std::ostream &f, std::string indent, RTLIL::Process *proc, boo void dump_module(std::ostream &f, std::string indent, RTLIL::Module *module) { - std::map, std::vector> sync_print_cells; + std::map, std::vector> sync_print_cells; reg_wires.clear(); reset_auto_counter(module); diff --git a/tests/fmt/run-test.sh b/tests/fmt/run-test.sh index ba5aea9f627..914a7234747 100644 --- a/tests/fmt/run-test.sh +++ b/tests/fmt/run-test.sh @@ -50,7 +50,7 @@ test_roundtrip bin_signed -DBASE_HEX -DSIGN="signed" test_cxxrtl () { local subtest=$1; shift - ../../yosys -p "read_verilog ${subtest}.v; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" + ../../yosys -p "read_verilog ${subtest}.v; proc; clean; write_cxxrtl -print-output std::cerr yosys-${subtest}.cc" ${CC:-gcc} -std=c++11 -o yosys-${subtest} -I../.. ${subtest}_tb.cc -lstdc++ ./yosys-${subtest} 2>yosys-${subtest}.log iverilog -o iverilog-${subtest} ${subtest}.v ${subtest}_tb.v From 2829cd9caa5729b3b7e2393d3428e265cd038ea6 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Wed, 28 Jun 2023 11:51:34 +1000 Subject: [PATCH 248/303] cxxrtl_backend: move sync $print grouping out of dump into analyze --- backends/cxxrtl/cxxrtl_backend.cc | 48 +++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 8f9cd941ecb..3a3bc39bcd6 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -292,6 +292,7 @@ struct FlowGraph { Type type; RTLIL::SigSig connect = {}; const RTLIL::Cell *cell = nullptr; + std::vector print_sync_cells; const RTLIL::Process *process = nullptr; const Mem *mem = nullptr; int portidx; @@ -473,14 +474,21 @@ struct FlowGraph { Node *node = new Node; node->type = Node::Type::CELL_EVAL; - if (cell->type == ID($print) && cell->getParam(ID::TRG_ENABLE).as_bool()) - node->type = Node::Type::PRINT_SYNC; node->cell = cell; nodes.push_back(node); add_cell_eval_defs_uses(node, cell); return node; } + Node *add_print_sync_node(std::vector cells) + { + Node *node = new Node; + node->type = Node::Type::PRINT_SYNC; + node->print_sync_cells = cells; + nodes.push_back(node); + return node; + } + // Processes void add_case_rule_defs_uses(Node *node, const RTLIL::CaseRule *case_) { @@ -1057,8 +1065,12 @@ struct CxxrtlWorker { f << indent << "}\n"; } - void dump_sync_print(const RTLIL::SigSpec &trg, const RTLIL::Const &polarity, std::vector &cells) + void dump_sync_print(std::vector &cells) { + log_assert(!cells.empty()); + const auto &trg = cells[0]->getPort(ID::TRG); + const auto &trg_polarity = cells[0]->getParam(ID::TRG_POLARITY); + f << indent << "if ("; for (int i = 0; i < trg.size(); i++) { RTLIL::SigBit trg_bit = trg[i]; @@ -1068,7 +1080,7 @@ struct CxxrtlWorker { if (i != 0) f << " || "; - if (polarity[i] == State::S1) + if (trg_polarity[i] == State::S1) f << "posedge_"; else f << "negedge_"; @@ -1081,6 +1093,9 @@ struct CxxrtlWorker { }); for (auto cell : cells) { log_assert(cell->getParam(ID::TRG_ENABLE).as_bool()); + log_assert(cell->getPort(ID::TRG) == trg); + log_assert(cell->getParam(ID::TRG_POLARITY) == trg_polarity); + std::vector inlined_cells; collect_cell_eval(cell, /*for_debug=*/false, inlined_cells); dump_inlined_cells(inlined_cells); @@ -1261,7 +1276,7 @@ struct CxxrtlWorker { } else if (cell->type == ID($print)) { log_assert(!for_debug); - // Sync $print cells become PRINT_SYNC in the FlowGraph, not CELL_EVAL. + // Sync $print cells are grouped into PRINT_SYNC nodes in the FlowGraph. log_assert(!cell->getParam(ID::TRG_ENABLE).as_bool()); f << indent << "auto " << mangle(cell) << "_curr = "; @@ -1988,8 +2003,6 @@ struct CxxrtlWorker { void dump_eval_method(RTLIL::Module *module) { - std::map, std::vector> sync_print_cells; - inc_indent(); f << indent << "bool converged = " << (eval_converges.at(module) ? "true" : "false") << ";\n"; if (!module->get_bool_attribute(ID(cxxrtl_blackbox))) { @@ -2023,7 +2036,7 @@ struct CxxrtlWorker { dump_cell_eval(node.cell); break; case FlowGraph::Node::Type::PRINT_SYNC: - sync_print_cells[make_pair(node.cell->getPort(ID::TRG), node.cell->getParam(ID::TRG_POLARITY))].push_back(node.cell); + dump_sync_print(node.print_sync_cells); break; case FlowGraph::Node::Type::PROCESS_CASE: dump_process_case(node.process); @@ -2039,8 +2052,6 @@ struct CxxrtlWorker { break; } } - for (auto &it : sync_print_cells) - dump_sync_print(it.first.first, it.first.second, it.second); } f << indent << "return converged;\n"; dec_indent(); @@ -2890,9 +2901,22 @@ struct CxxrtlWorker { } // Emit reachable nodes in eval(). + // Accumulate sync $print cells per trigger condition. + dict, std::vector> sync_print_cells; for (auto node : node_order) - if (live_nodes[node]) - schedule[module].push_back(*node); + if (live_nodes[node]) { + if (node->type == FlowGraph::Node::Type::CELL_EVAL && + node->cell->type == ID($print) && + node->cell->getParam(ID::TRG_ENABLE).as_bool()) + sync_print_cells[make_pair(node->cell->getPort(ID::TRG), node->cell->getParam(ID::TRG_POLARITY))].push_back(node->cell); + else + schedule[module].push_back(*node); + } + + for (auto &it : sync_print_cells) { + auto node = flow.add_print_sync_node(it.second); + schedule[module].push_back(*node); + } // For maximum performance, the state of the simulation (which is the same as the set of its double buffered // wires, since using a singly buffered wire for any kind of state introduces a race condition) should contain From 40978971f4fe8ad4d089b70526313bf0c6d1ec65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Aug 2023 00:13:32 +0000 Subject: [PATCH 249/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7883cf2b9b8..8beae8a355e 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+1 +YOSYS_VER := 0.32+43 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From bf84861fc2abeb877b770b33206ff2ee61d11552 Mon Sep 17 00:00:00 2001 From: Charlotte Date: Fri, 11 Aug 2023 15:52:05 +1000 Subject: [PATCH 250/303] proc_clean: only consider fully-defined case operands. --- passes/proc/proc_clean.cc | 2 +- tests/proc/clean_undef_case.ys | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/proc/clean_undef_case.ys diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 45872907bd8..6ce2f8cb031 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -41,7 +41,7 @@ void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did break; for (int j = 0; j < int(cs->compare.size()); j++) { RTLIL::SigSpec &val = cs->compare[j]; - if (!val.is_fully_const()) + if (!val.is_fully_def()) continue; if (val == sw->signal) { cs->compare.clear(); diff --git a/tests/proc/clean_undef_case.ys b/tests/proc/clean_undef_case.ys new file mode 100644 index 00000000000..3c29c93bcab --- /dev/null +++ b/tests/proc/clean_undef_case.ys @@ -0,0 +1,22 @@ +read_rtlil < Date: Fri, 11 Aug 2023 16:34:00 +1000 Subject: [PATCH 251/303] proc_clean: only consider fully-defined switch operands too. --- passes/proc/proc_clean.cc | 2 +- tests/proc/clean_undef_case.ys | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index 6ce2f8cb031..95cb0e88ca9 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -31,7 +31,7 @@ PRIVATE_NAMESPACE_BEGIN void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth) { - if (sw->signal.size() > 0 && sw->signal.is_fully_const()) + if (sw->signal.size() > 0 && sw->signal.is_fully_def()) { int found_matching_case_idx = -1; for (int i = 0; i < int(sw->cases.size()) && found_matching_case_idx < 0; i++) diff --git a/tests/proc/clean_undef_case.ys b/tests/proc/clean_undef_case.ys index 3c29c93bcab..c874b08c017 100644 --- a/tests/proc/clean_undef_case.ys +++ b/tests/proc/clean_undef_case.ys @@ -1,6 +1,6 @@ read_rtlil < Date: Sun, 13 Aug 2023 00:15:02 +0000 Subject: [PATCH 252/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8beae8a355e..657b2c245df 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+43 +YOSYS_VER := 0.32+46 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 6d9cd16fadfab64201a07ae9e84e4596a4497fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 14 Aug 2023 11:42:19 +0200 Subject: [PATCH 253/303] cellaigs: Drop initializer list in call to `IdString::in` Remove superfluous curly braces in call to IdString::in to address a compilation error (reproduced below) under GCC 9 and earlier. kernel/cellaigs.cc:395:18: error: call to member function 'in' is ambiguous if (cell->type.in({ID($gt), ID($ge)})) ~~~~~~~~~~~^~ ./kernel/rtlil.h:383:8: note: candidate function bool in(const std::string &rhs) const { return *this == rhs; } ^ ./kernel/rtlil.h:384:8: note: candidate function bool in(const pool &rhs) const { return rhs.co... ^ --- kernel/cellaigs.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/cellaigs.cc b/kernel/cellaigs.cc index 332f821b76c..5dda4503fdd 100644 --- a/kernel/cellaigs.cc +++ b/kernel/cellaigs.cc @@ -385,17 +385,17 @@ Aig::Aig(Cell *cell) goto optimize; } - if (cell->type.in({ID($lt), ID($gt), ID($le), ID($ge)})) + if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge))) { int width = std::max(GetSize(cell->getPort(ID::A)), GetSize(cell->getPort(ID::B))) + 1; vector A = mk.inport_vec(ID::A, width); vector B = mk.inport_vec(ID::B, width); - if (cell->type.in({ID($gt), ID($ge)})) + if (cell->type.in(ID($gt), ID($ge))) std::swap(A, B); - int carry = mk.bool_node(!cell->type.in({ID($le), ID($ge)})); + int carry = mk.bool_node(!cell->type.in(ID($le), ID($ge))); for (auto &n : B) n = mk.not_gate(n); vector Y = mk.adder(A, B, carry); From cbd3ff2d3a8d29fda2d796e4db5feb384990812c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 00:14:23 +0000 Subject: [PATCH 254/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 657b2c245df..33fe11c5207 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+46 +YOSYS_VER := 0.32+49 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From d525a414978236682e067180a8a5d94189f67335 Mon Sep 17 00:00:00 2001 From: Ethan Mahintorabi Date: Tue, 15 Aug 2023 20:03:46 +0000 Subject: [PATCH 255/303] abc: Exposes dont_use flag in ABC ABC's read_lib command has a dont_use cell list that is configurable by the user. This PR exposes that option to Yosys. See https://github.com/berkeley-abc/abc/blob/5405d4787a86615de76afccf1356676fb5c56c1c/src/map/scl/scl.c#L285 for documentation on this option. Signed-off-by: Ethan Mahintorabi --- passes/techmap/abc.cc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 364a8e54458..f36cadc8882 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -702,7 +702,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::vector &liberty_files, std::vector &genlib_files, std::string constr_file, bool cleanup, vector lut_costs, bool dff_mode, std::string clk_str, bool keepff, std::string delay_target, std::string sop_inputs, std::string sop_products, std::string lutin_shared, bool fast_mode, - const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress) + const std::vector &cells, bool show_tempdir, bool sop_mode, bool abc_dress, std::vector &dont_use_cells) { module = current_module; map_autoidx = autoidx++; @@ -795,8 +795,13 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin std::string abc_script = stringf("read_blif \"%s/input.blif\"; ", tempdir_name.c_str()); if (!liberty_files.empty() || !genlib_files.empty()) { - for (std::string liberty_file : liberty_files) - abc_script += stringf("read_lib -w \"%s\"; ", liberty_file.c_str()); + std::string dont_use_args; + for (std::string dont_use_cell : dont_use_cells) { + dont_use_args += stringf("-X \"%s\" ", dont_use_cell.c_str()); + } + for (std::string liberty_file : liberty_files) { + abc_script += stringf("read_lib %s -w \"%s\" ; ", dont_use_args.c_str(), liberty_file.c_str()); + } for (std::string liberty_file : genlib_files) abc_script += stringf("read_library \"%s\"; ", liberty_file.c_str()); if (!constr_file.empty()) @@ -1503,6 +1508,10 @@ struct AbcPass : public Pass { log(" generate netlists for the specified cell library (using the liberty\n"); log(" file format).\n"); log("\n"); + log(" -dont_use \n"); + log(" generate netlists for the specified cell library (using the liberty\n"); + log(" file format).\n"); + log("\n"); log(" -genlib \n"); log(" generate netlists for the specified cell library (using the SIS Genlib\n"); log(" file format).\n"); @@ -1639,7 +1648,7 @@ struct AbcPass : public Pass { std::string exe_file = yosys_abc_executable; std::string script_file, default_liberty_file, constr_file, clk_str; - std::vector liberty_files, genlib_files; + std::vector liberty_files, genlib_files, dont_use_cells; std::string delay_target, sop_inputs, sop_products, lutin_shared = "-S 1"; bool fast_mode = false, dff_mode = false, keepff = false, cleanup = true; bool show_tempdir = false, sop_mode = false; @@ -1722,6 +1731,10 @@ struct AbcPass : public Pass { liberty_files.push_back(args[++argidx]); continue; } + if (arg == "-dont_use" && argidx+1 < args.size()) { + dont_use_cells.push_back(args[++argidx]); + continue; + } if (arg == "-genlib" && argidx+1 < args.size()) { genlib_files.push_back(args[++argidx]); continue; @@ -2028,7 +2041,7 @@ struct AbcPass : public Pass { if (!dff_mode || !clk_str.empty()) { abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, dff_mode, clk_str, keepff, - delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress); + delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, mod->selected_cells(), show_tempdir, sop_mode, abc_dress, dont_use_cells); continue; } @@ -2190,7 +2203,7 @@ struct AbcPass : public Pass { srst_polarity = std::get<6>(it.first); srst_sig = assign_map(std::get<7>(it.first)); abc_module(design, mod, script_file, exe_file, liberty_files, genlib_files, constr_file, cleanup, lut_costs, !clk_sig.empty(), "$", - keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress); + keepff, delay_target, sop_inputs, sop_products, lutin_shared, fast_mode, it.second, show_tempdir, sop_mode, abc_dress, dont_use_cells); assign_map.set(mod); } } From 4a475fa7a2788679b4c575dc3c1231a065d35271 Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Wed, 19 Apr 2023 19:54:09 +1000 Subject: [PATCH 256/303] cxxrtl: include iostream when prints are used --- backends/cxxrtl/cxxrtl_backend.cc | 5 +++++ tests/fmt/always_comb_tb.cc | 1 - tests/fmt/always_full_tb.cc | 1 - tests/fmt/display_lm_tb.cc | 5 ++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index 3a3bc39bcd6..7696ae5747c 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -2474,6 +2474,7 @@ struct CxxrtlWorker { RTLIL::Module *top_module = nullptr; std::vector modules; TopoSort topo_design; + bool has_prints = false; for (auto module : design->modules()) { if (!design->selected_module(module)) continue; @@ -2486,6 +2487,8 @@ struct CxxrtlWorker { topo_design.node(module); for (auto cell : module->cells()) { + if (cell->type == ID($print)) + has_prints = true; if (is_internal_cell(cell->type) || is_cxxrtl_blackbox_cell(cell)) continue; RTLIL::Module *cell_module = design->module(cell->type); @@ -2544,6 +2547,8 @@ struct CxxrtlWorker { f << "#include \"" << intf_filename << "\"\n"; else f << "#include \n"; + if (has_prints) + f << "#include \n"; f << "\n"; f << "#if defined(CXXRTL_INCLUDE_CAPI_IMPL) || \\\n"; f << " defined(CXXRTL_INCLUDE_VCD_CAPI_IMPL)\n"; diff --git a/tests/fmt/always_comb_tb.cc b/tests/fmt/always_comb_tb.cc index f2a8c6b2695..5812500535a 100644 --- a/tests/fmt/always_comb_tb.cc +++ b/tests/fmt/always_comb_tb.cc @@ -1,4 +1,3 @@ -#include #include "yosys-always_comb.cc" int main() diff --git a/tests/fmt/always_full_tb.cc b/tests/fmt/always_full_tb.cc index bd98020dec1..229f78aebe1 100644 --- a/tests/fmt/always_full_tb.cc +++ b/tests/fmt/always_full_tb.cc @@ -1,4 +1,3 @@ -#include #include "yosys-always_full.cc" int main() diff --git a/tests/fmt/display_lm_tb.cc b/tests/fmt/display_lm_tb.cc index ebc62f80fad..7a593d72919 100644 --- a/tests/fmt/display_lm_tb.cc +++ b/tests/fmt/display_lm_tb.cc @@ -1,10 +1,9 @@ -#include #include "yosys-display_lm.cc" int main() { cxxrtl_design::p_top uut; - uut.step(); - return 0; + uut.step(); + return 0; } From 6405bbab1e8afc587febf41339aaf8b514c8f202 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 18 Aug 2023 00:14:07 +0000 Subject: [PATCH 257/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 33fe11c5207..09cf4992dab 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+49 +YOSYS_VER := 0.32+51 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From a8809989c4f31e284a2bed593d71e9a11deec771 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 22 Aug 2023 10:50:11 +0200 Subject: [PATCH 258/303] ecp5_gsr -> lattice_gsr, change opt_lut_ins to accept lattice as tech --- passes/opt/opt_lut_ins.cc | 14 +++++++------- techlibs/ecp5/Makefile.inc | 2 +- techlibs/ecp5/synth_ecp5.cc | 4 ++-- techlibs/lattice/Makefile.inc | 1 + .../{ecp5/ecp5_gsr.cc => lattice/lattice_gsr.cc} | 10 +++++----- techlibs/machxo2/synth_machxo2.cc | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 techlibs/lattice/Makefile.inc rename techlibs/{ecp5/ecp5_gsr.cc => lattice/lattice_gsr.cc} (93%) diff --git a/passes/opt/opt_lut_ins.cc b/passes/opt/opt_lut_ins.cc index 2f7c392b29a..652fce1e2d5 100644 --- a/passes/opt/opt_lut_ins.cc +++ b/passes/opt/opt_lut_ins.cc @@ -39,7 +39,7 @@ struct OptLutInsPass : public Pass { log("\n"); log(" -tech \n"); log(" Instead of generic $lut cells, operate on LUT cells specific\n"); - log(" to the given technology. Valid values are: xilinx, ecp5, gowin.\n"); + log(" to the given technology. Valid values are: xilinx, lattice, gowin.\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) override @@ -58,7 +58,7 @@ struct OptLutInsPass : public Pass { } extra_args(args, argidx, design); - if (techname != "" && techname != "xilinx" && techname != "ecp5" && techname != "gowin") + if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "ecp5" && techname != "gowin") log_cmd_error("Unsupported technology: '%s'\n", techname.c_str()); for (auto module : design->selected_modules()) @@ -130,7 +130,7 @@ struct OptLutInsPass : public Pass { output = cell->getPort(ID::O); else output = cell->getPort(ID::F); - } else if (techname == "ecp5") { + } else if (techname == "lattice" || techname == "ecp5") { if (cell->type == ID(LUT4)) { inputs = { cell->getPort(ID::A), @@ -181,7 +181,7 @@ struct OptLutInsPass : public Pass { if (!doit) continue; log(" Optimizing lut %s (%d -> %d)\n", log_id(cell), GetSize(inputs), GetSize(new_inputs)); - if (techname == "ecp5") { + if (techname == "lattice" || techname == "ecp5") { // Pad the LUT to 4 inputs, adding consts from the front. int extra = 4 - GetSize(new_inputs); log_assert(extra >= 0); @@ -215,9 +215,9 @@ struct OptLutInsPass : public Pass { } new_lut[i] = lut[lidx]; } - // For ecp5, and gowin do not replace with a const driver — the nextpnr + // For lattice, and gowin do not replace with a const driver — the nextpnr // packer requires a complete set of LUTs for wide LUT muxes. - if (new_inputs.empty() && techname != "ecp5" && techname != "gowin") { + if (new_inputs.empty() && techname != "lattice" && techname != "ecp5" && techname != "gowin") { // const driver. remove_cells.push_back(cell); module->connect(output, new_lut[0]); @@ -226,7 +226,7 @@ struct OptLutInsPass : public Pass { cell->setParam(ID::LUT, new_lut); cell->setParam(ID::WIDTH, GetSize(new_inputs)); cell->setPort(ID::A, new_inputs); - } else if (techname == "ecp5") { + } else if (techname == "lattice" || techname == "ecp5") { log_assert(GetSize(new_inputs) == 4); cell->setParam(ID::INIT, new_lut); cell->setPort(ID::A, new_inputs[0]); diff --git a/techlibs/ecp5/Makefile.inc b/techlibs/ecp5/Makefile.inc index f9fa79ab9ad..a1c9bfc5233 100644 --- a/techlibs/ecp5/Makefile.inc +++ b/techlibs/ecp5/Makefile.inc @@ -1,5 +1,5 @@ -OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_gsr.o +OBJS += techlibs/ecp5/synth_ecp5.o $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_ff.vh)) $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_io.vh)) diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc index 82e23486844..fdc36e55267 100644 --- a/techlibs/ecp5/synth_ecp5.cc +++ b/techlibs/ecp5/synth_ecp5.cc @@ -359,7 +359,7 @@ struct SynthEcp5Pass : public ScriptPass run("techmap -D NO_LUT -map +/ecp5/cells_map.v"); run("opt_expr -undriven -mux_undef"); run("simplemap"); - run("ecp5_gsr"); + run("lattice_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); } @@ -404,7 +404,7 @@ struct SynthEcp5Pass : public ScriptPass run("techmap -map +/ecp5/cells_map.v", "(skip if -vpr)"); else if (!vpr) run("techmap -map +/ecp5/cells_map.v"); - run("opt_lut_ins -tech ecp5"); + run("opt_lut_ins -tech lattice"); run("clean"); } diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc new file mode 100644 index 00000000000..b198de0cc11 --- /dev/null +++ b/techlibs/lattice/Makefile.inc @@ -0,0 +1 @@ +OBJS += techlibs/lattice/lattice_gsr.o diff --git a/techlibs/ecp5/ecp5_gsr.cc b/techlibs/lattice/lattice_gsr.cc similarity index 93% rename from techlibs/ecp5/ecp5_gsr.cc rename to techlibs/lattice/lattice_gsr.cc index 62b231aab3b..d7d41eca519 100644 --- a/techlibs/ecp5/ecp5_gsr.cc +++ b/techlibs/lattice/lattice_gsr.cc @@ -24,13 +24,13 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN -struct Ecp5GsrPass : public Pass { - Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { } +struct LatticeGsrPass : public Pass { + LatticeGsrPass() : Pass("lattice_gsr", "Lattice: handle GSR") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" ecp5_gsr [options] [selection]\n"); + log(" lattice_gsr [options] [selection]\n"); log("\n"); log("Trim active low async resets connected to GSR and resolve GSR parameter,\n"); log("if a GSR or SGSR primitive is used in the design.\n"); @@ -42,7 +42,7 @@ struct Ecp5GsrPass : public Pass { } void execute(std::vector args, RTLIL::Design *design) override { - log_header(design, "Executing ECP5_GSR pass (implement FF init values).\n"); + log_header(design, "Executing LATTICE_GSR pass (implement FF init values).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) @@ -130,6 +130,6 @@ struct Ecp5GsrPass : public Pass { } } -} Ecp5GsrPass; +} LatticeGsrPass; PRIVATE_NAMESPACE_END diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc index 2b684a7d8fd..907c6659ed8 100644 --- a/techlibs/machxo2/synth_machxo2.cc +++ b/techlibs/machxo2/synth_machxo2.cc @@ -239,7 +239,7 @@ struct SynthMachXO2Pass : public ScriptPass run("techmap -D NO_LUT -map +/machxo2/cells_map.v"); run("opt_expr -undriven -mux_undef"); run("simplemap"); - run("ecp5_gsr"); + run("lattice_gsr"); run("attrmvcp -copy -attr syn_useioff"); run("opt_clean"); } From e3c15f003e1d976c4d27c2ffc08196b50576bd26 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 10:53:21 +0200 Subject: [PATCH 259/303] Create synth_lattice --- techlibs/lattice/Makefile.inc | 26 + techlibs/lattice/arith_map_ccu2c.v | 90 +++ techlibs/lattice/arith_map_ccu2d.v | 90 +++ techlibs/lattice/brams_16kd.txt | 52 ++ techlibs/lattice/brams_8kc.txt | 50 ++ techlibs/lattice/brams_map_16kd.v | 489 +++++++++++++ techlibs/lattice/brams_map_8kc.v | 337 +++++++++ techlibs/lattice/ccu2c_sim.vh | 61 ++ techlibs/lattice/ccu2d_sim.vh | 33 + techlibs/lattice/cells_bb_ecp5.v | 1067 ++++++++++++++++++++++++++++ techlibs/lattice/cells_bb_xo2.v | 293 ++++++++ techlibs/lattice/cells_bb_xo3.v | 293 ++++++++ techlibs/lattice/cells_bb_xo3d.v | 293 ++++++++ techlibs/lattice/cells_ff.vh | 40 ++ techlibs/lattice/cells_io.vh | 14 + techlibs/lattice/cells_map.v | 191 +++++ techlibs/lattice/cells_sim_ecp5.v | 9 + techlibs/lattice/cells_sim_xo2.v | 9 + techlibs/lattice/cells_sim_xo3.v | 9 + techlibs/lattice/cells_sim_xo3d.v | 9 + techlibs/lattice/common_sim.vh | 402 +++++++++++ techlibs/lattice/dsp_map_18x18.v | 17 + techlibs/lattice/latches_map.v | 11 + techlibs/lattice/lutrams.txt | 12 + techlibs/lattice/lutrams_map.v | 30 + techlibs/lattice/synth_lattice.cc | 574 +++++++++++++++ 26 files changed, 4501 insertions(+) create mode 100644 techlibs/lattice/arith_map_ccu2c.v create mode 100644 techlibs/lattice/arith_map_ccu2d.v create mode 100644 techlibs/lattice/brams_16kd.txt create mode 100644 techlibs/lattice/brams_8kc.txt create mode 100644 techlibs/lattice/brams_map_16kd.v create mode 100644 techlibs/lattice/brams_map_8kc.v create mode 100644 techlibs/lattice/ccu2c_sim.vh create mode 100644 techlibs/lattice/ccu2d_sim.vh create mode 100644 techlibs/lattice/cells_bb_ecp5.v create mode 100644 techlibs/lattice/cells_bb_xo2.v create mode 100644 techlibs/lattice/cells_bb_xo3.v create mode 100644 techlibs/lattice/cells_bb_xo3d.v create mode 100644 techlibs/lattice/cells_ff.vh create mode 100644 techlibs/lattice/cells_io.vh create mode 100644 techlibs/lattice/cells_map.v create mode 100644 techlibs/lattice/cells_sim_ecp5.v create mode 100644 techlibs/lattice/cells_sim_xo2.v create mode 100644 techlibs/lattice/cells_sim_xo3.v create mode 100644 techlibs/lattice/cells_sim_xo3d.v create mode 100644 techlibs/lattice/common_sim.vh create mode 100644 techlibs/lattice/dsp_map_18x18.v create mode 100644 techlibs/lattice/latches_map.v create mode 100644 techlibs/lattice/lutrams.txt create mode 100644 techlibs/lattice/lutrams_map.v create mode 100644 techlibs/lattice/synth_lattice.cc diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc index b198de0cc11..4a908fa3ead 100644 --- a/techlibs/lattice/Makefile.inc +++ b/techlibs/lattice/Makefile.inc @@ -1 +1,27 @@ + +OBJS += techlibs/lattice/synth_lattice.o OBJS += techlibs/lattice/lattice_gsr.o + +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_ff.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_io.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_map.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/common_sim.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/ccu2d_sim.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/ccu2c_sim.vh)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_ecp5.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo2.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3d.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_ecp5.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo2.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams.txt)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_16kd.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_16kd.txt)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_8kc.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_8kc.txt)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_ccu2c.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_ccu2d.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/latches_map.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/dsp_map_18x18.v)) diff --git a/techlibs/lattice/arith_map_ccu2c.v b/techlibs/lattice/arith_map_ccu2c.v new file mode 100644 index 00000000000..a5efc35613a --- /dev/null +++ b/techlibs/lattice/arith_map_ccu2c.v @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_ccu2c_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; + + (* force_downto *) + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + function integer round_up2; + input integer N; + begin + round_up2 = ((N + 1) / 2) * 2; + end + endfunction + + localparam Y_WIDTH2 = round_up2(Y_WIDTH); + + (* force_downto *) + wire [Y_WIDTH2-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BX = B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] C = {CO, CI}; + (* force_downto *) + wire [Y_WIDTH2-1:0] FCO, Y1; + + genvar i; + generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice + CCU2C #( + .INIT0(16'b1001011010101010), + .INIT1(16'b1001011010101010), + .INJECT1_0("NO"), + .INJECT1_1("NO") + ) ccu2c_i ( + .CIN(C[i]), + .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b1), + .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b1), + .S0(Y[i]), .S1(Y1[i]), + .COUT(FCO[i]) + ); + + assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); + if (i+1 < Y_WIDTH) begin + assign CO[i+1] = FCO[i]; + assign Y[i+1] = Y1[i]; + end + end endgenerate + + assign X = AA ^ BB; +endmodule diff --git a/techlibs/lattice/arith_map_ccu2d.v b/techlibs/lattice/arith_map_ccu2d.v new file mode 100644 index 00000000000..31e4afe09a1 --- /dev/null +++ b/techlibs/lattice/arith_map_ccu2d.v @@ -0,0 +1,90 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +(* techmap_celltype = "$alu" *) +module _80_ccu2d_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; + + (* force_downto *) + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + function integer round_up2; + input integer N; + begin + round_up2 = ((N + 1) / 2) * 2; + end + endfunction + + localparam Y_WIDTH2 = round_up2(Y_WIDTH); + + (* force_downto *) + wire [Y_WIDTH2-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] BX = B_buf; + (* force_downto *) + wire [Y_WIDTH2-1:0] C = {CO, CI}; + (* force_downto *) + wire [Y_WIDTH2-1:0] FCO, Y1; + + genvar i; + generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice + CCU2D #( + .INIT0(16'b0101_1010_1001_0110), + .INIT1(16'b0101_1010_1001_0110), + .INJECT1_0("NO"), + .INJECT1_1("NO") + ) ccu2d_i ( + .CIN(C[i]), + .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b0), + .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b0), + .S0(Y[i]), .S1(Y1[i]), + .COUT(FCO[i]) + ); + + assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); + if (i+1 < Y_WIDTH) begin + assign CO[i+1] = FCO[i]; + assign Y[i+1] = Y1[i]; + end + end endgenerate + + assign X = AA ^ BB; +endmodule diff --git a/techlibs/lattice/brams_16kd.txt b/techlibs/lattice/brams_16kd.txt new file mode 100644 index 00000000000..ccdf490501f --- /dev/null +++ b/techlibs/lattice/brams_16kd.txt @@ -0,0 +1,52 @@ +ram block $__DP16KD_ { + abits 14; + widths 1 2 4 9 18 per_port; + byte 9; + cost 128; + init no_undef; + port srsw "A" "B" { + clock anyedge; + clken; + wrbe_separate; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__PDPW16KD_ { + abits 14; + widths 1 2 4 9 18 36 per_port; + byte 9; + cost 128; + init no_undef; + port sr "R" { + clock anyedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + width 36; + clock anyedge; + clken; + } +} diff --git a/techlibs/lattice/brams_8kc.txt b/techlibs/lattice/brams_8kc.txt new file mode 100644 index 00000000000..3afbeda07e6 --- /dev/null +++ b/techlibs/lattice/brams_8kc.txt @@ -0,0 +1,50 @@ +ram block $__DP8KC_ { + abits 13; + widths 1 2 4 9 per_port; + cost 64; + init no_undef; + port srsw "A" "B" { + clock posedge; + clken; + portoption "WRITEMODE" "NORMAL" { + rdwr no_change; + } + portoption "WRITEMODE" "WRITETHROUGH" { + rdwr new; + } + portoption "WRITEMODE" "READBEFOREWRITE" { + rdwr old; + } + option "RESETMODE" "SYNC" { + rdsrst zero ungated block_wr; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } +} + +ram block $__PDPW8KC_ { + abits 13; + widths 1 2 4 9 18 per_port; + byte 9; + cost 64; + init no_undef; + port sr "R" { + clock posedge; + clken; + option "RESETMODE" "SYNC" { + rdsrst zero ungated; + } + option "RESETMODE" "ASYNC" { + rdarst zero; + } + rdinit zero; + } + port sw "W" { + width 18; + clock posedge; + clken; + } +} diff --git a/techlibs/lattice/brams_map_16kd.v b/techlibs/lattice/brams_map_16kd.v new file mode 100644 index 00000000000..da4d8041770 --- /dev/null +++ b/techlibs/lattice/brams_map_16kd.v @@ -0,0 +1,489 @@ +module $__DP16KD_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_WR_BE_WIDTH = 2; +parameter PORT_A_CLK_POL = 1; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [13:0] PORT_A_ADDR; +input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_WR_BE_WIDTH = 2; +parameter PORT_B_CLK_POL = 1; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [13:0] PORT_B_ADDR; +input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DOA; +wire [17:0] DOB; +wire [17:0] DIA = PORT_A_WR_DATA; +wire [17:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP16KD #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .INITVAL_20(init_slice('h20)), + .INITVAL_21(init_slice('h21)), + .INITVAL_22(init_slice('h22)), + .INITVAL_23(init_slice('h23)), + .INITVAL_24(init_slice('h24)), + .INITVAL_25(init_slice('h25)), + .INITVAL_26(init_slice('h26)), + .INITVAL_27(init_slice('h27)), + .INITVAL_28(init_slice('h28)), + .INITVAL_29(init_slice('h29)), + .INITVAL_2A(init_slice('h2a)), + .INITVAL_2B(init_slice('h2b)), + .INITVAL_2C(init_slice('h2c)), + .INITVAL_2D(init_slice('h2d)), + .INITVAL_2E(init_slice('h2e)), + .INITVAL_2F(init_slice('h2f)), + .INITVAL_30(init_slice('h30)), + .INITVAL_31(init_slice('h31)), + .INITVAL_32(init_slice('h32)), + .INITVAL_33(init_slice('h33)), + .INITVAL_34(init_slice('h34)), + .INITVAL_35(init_slice('h35)), + .INITVAL_36(init_slice('h36)), + .INITVAL_37(init_slice('h37)), + .INITVAL_38(init_slice('h38)), + .INITVAL_39(init_slice('h39)), + .INITVAL_3A(init_slice('h3a)), + .INITVAL_3B(init_slice('h3b)), + .INITVAL_3C(init_slice('h3c)), + .INITVAL_3D(init_slice('h3d)), + .INITVAL_3E(init_slice('h3e)), + .INITVAL_3F(init_slice('h3f)), + .DATA_WIDTH_A(PORT_A_WIDTH), + .DATA_WIDTH_B(PORT_B_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .CLKAMUX(PORT_A_CLK_POL ? "CLKA" : "INV"), + .CLKBMUX(PORT_B_CLK_POL ? "CLKB" : "INV"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])), + .CEA(PORT_A_CLK_EN), + .OCEA(1'b1), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[0] : PORT_A_ADDR[0]), + .ADA1(PORT_A_WIDTH == 18 ? PORT_A_WR_BE[1] : PORT_A_ADDR[1]), + .ADA2(PORT_A_ADDR[2]), + .ADA3(PORT_A_ADDR[3]), + .ADA4(PORT_A_ADDR[4]), + .ADA5(PORT_A_ADDR[5]), + .ADA6(PORT_A_ADDR[6]), + .ADA7(PORT_A_ADDR[7]), + .ADA8(PORT_A_ADDR[8]), + .ADA9(PORT_A_ADDR[9]), + .ADA10(PORT_A_ADDR[10]), + .ADA11(PORT_A_ADDR[11]), + .ADA12(PORT_A_ADDR[12]), + .ADA13(PORT_A_ADDR[13]), + .DIA0(DIA[0]), + .DIA1(DIA[1]), + .DIA2(DIA[2]), + .DIA3(DIA[3]), + .DIA4(DIA[4]), + .DIA5(DIA[5]), + .DIA6(DIA[6]), + .DIA7(DIA[7]), + .DIA8(DIA[8]), + .DIA9(DIA[9]), + .DIA10(DIA[10]), + .DIA11(DIA[11]), + .DIA12(DIA[12]), + .DIA13(DIA[13]), + .DIA14(DIA[14]), + .DIA15(DIA[15]), + .DIA16(DIA[16]), + .DIA17(DIA[17]), + .DOA0(DOA[0]), + .DOA1(DOA[1]), + .DOA2(DOA[2]), + .DOA3(DOA[3]), + .DOA4(DOA[4]), + .DOA5(DOA[5]), + .DOA6(DOA[6]), + .DOA7(DOA[7]), + .DOA8(DOA[8]), + .DOA9(DOA[9]), + .DOA10(DOA[10]), + .DOA11(DOA[11]), + .DOA12(DOA[12]), + .DOA13(DOA[13]), + .DOA14(DOA[14]), + .DOA15(DOA[15]), + .DOA16(DOA[16]), + .DOA17(DOA[17]), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])), + .CEB(PORT_B_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[0] : PORT_B_ADDR[0]), + .ADB1(PORT_B_WIDTH == 18 ? PORT_B_WR_BE[1] : PORT_B_ADDR[1]), + .ADB2(PORT_B_ADDR[2]), + .ADB3(PORT_B_ADDR[3]), + .ADB4(PORT_B_ADDR[4]), + .ADB5(PORT_B_ADDR[5]), + .ADB6(PORT_B_ADDR[6]), + .ADB7(PORT_B_ADDR[7]), + .ADB8(PORT_B_ADDR[8]), + .ADB9(PORT_B_ADDR[9]), + .ADB10(PORT_B_ADDR[10]), + .ADB11(PORT_B_ADDR[11]), + .ADB12(PORT_B_ADDR[12]), + .ADB13(PORT_B_ADDR[13]), + .DIB0(DIB[0]), + .DIB1(DIB[1]), + .DIB2(DIB[2]), + .DIB3(DIB[3]), + .DIB4(DIB[4]), + .DIB5(DIB[5]), + .DIB6(DIB[6]), + .DIB7(DIB[7]), + .DIB8(DIB[8]), + .DIB9(DIB[9]), + .DIB10(DIB[10]), + .DIB11(DIB[11]), + .DIB12(DIB[12]), + .DIB13(DIB[13]), + .DIB14(DIB[14]), + .DIB15(DIB[15]), + .DIB16(DIB[16]), + .DIB17(DIB[17]), + .DOB0(DOB[0]), + .DOB1(DOB[1]), + .DOB2(DOB[2]), + .DOB3(DOB[3]), + .DOB4(DOB[4]), + .DOB5(DOB[5]), + .DOB6(DOB[6]), + .DOB7(DOB[7]), + .DOB8(DOB[8]), + .DOB9(DOB[9]), + .DOB10(DOB[10]), + .DOB11(DOB[11]), + .DOB12(DOB[12]), + .DOB13(DOB[13]), + .DOB14(DOB[14]), + .DOB15(DOB[15]), + .DOB16(DOB[16]), + .DOB17(DOB[17]), +); + +endmodule + + +module $__PDPW16KD_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 36; +parameter PORT_R_CLK_POL = 1; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [13:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 36; +parameter PORT_W_WR_EN_WIDTH = 4; +parameter PORT_W_CLK_POL = 1; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [13:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [35:0] DI = PORT_W_WR_DATA; +wire [35:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 36 ? DO : DO[35:18]; + +DP16KD #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .INITVAL_20(init_slice('h20)), + .INITVAL_21(init_slice('h21)), + .INITVAL_22(init_slice('h22)), + .INITVAL_23(init_slice('h23)), + .INITVAL_24(init_slice('h24)), + .INITVAL_25(init_slice('h25)), + .INITVAL_26(init_slice('h26)), + .INITVAL_27(init_slice('h27)), + .INITVAL_28(init_slice('h28)), + .INITVAL_29(init_slice('h29)), + .INITVAL_2A(init_slice('h2a)), + .INITVAL_2B(init_slice('h2b)), + .INITVAL_2C(init_slice('h2c)), + .INITVAL_2D(init_slice('h2d)), + .INITVAL_2E(init_slice('h2e)), + .INITVAL_2F(init_slice('h2f)), + .INITVAL_30(init_slice('h30)), + .INITVAL_31(init_slice('h31)), + .INITVAL_32(init_slice('h32)), + .INITVAL_33(init_slice('h33)), + .INITVAL_34(init_slice('h34)), + .INITVAL_35(init_slice('h35)), + .INITVAL_36(init_slice('h36)), + .INITVAL_37(init_slice('h37)), + .INITVAL_38(init_slice('h38)), + .INITVAL_39(init_slice('h39)), + .INITVAL_3A(init_slice('h3a)), + .INITVAL_3B(init_slice('h3b)), + .INITVAL_3C(init_slice('h3c)), + .INITVAL_3D(init_slice('h3d)), + .INITVAL_3E(init_slice('h3e)), + .INITVAL_3F(init_slice('h3f)), + .DATA_WIDTH_A(PORT_W_WIDTH), + .DATA_WIDTH_B(PORT_R_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .CLKAMUX(PORT_W_CLK_POL ? "CLKA" : "INV"), + .CLKBMUX(PORT_R_CLK_POL ? "CLKB" : "INV"), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_W_CLK), + .WEA(PORT_W_WIDTH >= 18 ? 1'b1 : PORT_W_WR_EN[0]), + .CEA(PORT_W_CLK_EN), + .OCEA(1'b0), + .RSTA(1'b0), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), + .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), + .ADA2(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[2] : PORT_W_ADDR[2]), + .ADA3(PORT_W_WIDTH >= 36 ? PORT_W_WR_EN[3] : PORT_W_ADDR[3]), + .ADA4(PORT_W_ADDR[4]), + .ADA5(PORT_W_ADDR[5]), + .ADA6(PORT_W_ADDR[6]), + .ADA7(PORT_W_ADDR[7]), + .ADA8(PORT_W_ADDR[8]), + .ADA9(PORT_W_ADDR[9]), + .ADA10(PORT_W_ADDR[10]), + .ADA11(PORT_W_ADDR[11]), + .ADA12(PORT_W_ADDR[12]), + .ADA13(PORT_W_ADDR[13]), + .DIA0(DI[0]), + .DIA1(DI[1]), + .DIA2(DI[2]), + .DIA3(DI[3]), + .DIA4(DI[4]), + .DIA5(DI[5]), + .DIA6(DI[6]), + .DIA7(DI[7]), + .DIA8(DI[8]), + .DIA9(DI[9]), + .DIA10(DI[10]), + .DIA11(DI[11]), + .DIA12(DI[12]), + .DIA13(DI[13]), + .DIA14(DI[14]), + .DIA15(DI[15]), + .DIA16(DI[16]), + .DIA17(DI[17]), + .DIB0(DI[18]), + .DIB1(DI[19]), + .DIB2(DI[20]), + .DIB3(DI[21]), + .DIB4(DI[22]), + .DIB5(DI[23]), + .DIB6(DI[24]), + .DIB7(DI[25]), + .DIB8(DI[26]), + .DIB9(DI[27]), + .DIB10(DI[28]), + .DIB11(DI[29]), + .DIB12(DI[30]), + .DIB13(DI[31]), + .DIB14(DI[32]), + .DIB15(DI[33]), + .DIB16(DI[34]), + .DIB17(DI[35]), + + .CLKB(PORT_R_CLK), + .WEB(1'b0), + .CEB(PORT_R_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_R_ADDR[0]), + .ADB1(PORT_R_ADDR[1]), + .ADB2(PORT_R_ADDR[2]), + .ADB3(PORT_R_ADDR[3]), + .ADB4(PORT_R_ADDR[4]), + .ADB5(PORT_R_ADDR[5]), + .ADB6(PORT_R_ADDR[6]), + .ADB7(PORT_R_ADDR[7]), + .ADB8(PORT_R_ADDR[8]), + .ADB9(PORT_R_ADDR[9]), + .ADB10(PORT_R_ADDR[10]), + .ADB11(PORT_R_ADDR[11]), + .ADB12(PORT_R_ADDR[12]), + .ADB13(PORT_R_ADDR[13]), + .DOA0(DO[0]), + .DOA1(DO[1]), + .DOA2(DO[2]), + .DOA3(DO[3]), + .DOA4(DO[4]), + .DOA5(DO[5]), + .DOA6(DO[6]), + .DOA7(DO[7]), + .DOA8(DO[8]), + .DOA9(DO[9]), + .DOA10(DO[10]), + .DOA11(DO[11]), + .DOA12(DO[12]), + .DOA13(DO[13]), + .DOA14(DO[14]), + .DOA15(DO[15]), + .DOA16(DO[16]), + .DOA17(DO[17]), + .DOB0(DO[18]), + .DOB1(DO[19]), + .DOB2(DO[20]), + .DOB3(DO[21]), + .DOB4(DO[22]), + .DOB5(DO[23]), + .DOB6(DO[24]), + .DOB7(DO[25]), + .DOB8(DO[26]), + .DOB9(DO[27]), + .DOB10(DO[28]), + .DOB11(DO[29]), + .DOB12(DO[30]), + .DOB13(DO[31]), + .DOB14(DO[32]), + .DOB15(DO[33]), + .DOB16(DO[34]), + .DOB17(DO[35]), +); + +endmodule diff --git a/techlibs/lattice/brams_map_8kc.v b/techlibs/lattice/brams_map_8kc.v new file mode 100644 index 00000000000..6783e5b2902 --- /dev/null +++ b/techlibs/lattice/brams_map_8kc.v @@ -0,0 +1,337 @@ +module $__DP8KC_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_A_WIDTH = 18; +parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; + +input PORT_A_CLK; +input PORT_A_CLK_EN; +input PORT_A_WR_EN; +input PORT_A_RD_SRST; +input PORT_A_RD_ARST; +input [12:0] PORT_A_ADDR; +input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; +output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; + +parameter PORT_B_WIDTH = 18; +parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; + +input PORT_B_CLK; +input PORT_B_CLK_EN; +input PORT_B_WR_EN; +input PORT_B_RD_SRST; +input PORT_B_RD_ARST; +input [12:0] PORT_B_ADDR; +input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; +output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [8:0] DOA; +wire [8:0] DOB; +wire [8:0] DIA = PORT_A_WR_DATA; +wire [8:0] DIB = PORT_B_WR_DATA; + +assign PORT_A_RD_DATA = DOA; +assign PORT_B_RD_DATA = DOB; + +DP8KC #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .DATA_WIDTH_A(PORT_A_WIDTH), + .DATA_WIDTH_B(PORT_B_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), + .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_A_CLK), + .WEA(PORT_A_WR_EN), + .CEA(PORT_A_CLK_EN), + .OCEA(1'b1), + .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_A_WIDTH == 9 ? 1'b1 : PORT_A_ADDR[0]), + .ADA1(PORT_A_ADDR[1]), + .ADA2(PORT_A_ADDR[2]), + .ADA3(PORT_A_ADDR[3]), + .ADA4(PORT_A_ADDR[4]), + .ADA5(PORT_A_ADDR[5]), + .ADA6(PORT_A_ADDR[6]), + .ADA7(PORT_A_ADDR[7]), + .ADA8(PORT_A_ADDR[8]), + .ADA9(PORT_A_ADDR[9]), + .ADA10(PORT_A_ADDR[10]), + .ADA11(PORT_A_ADDR[11]), + .ADA12(PORT_A_ADDR[12]), + .DIA0(DIA[0]), + .DIA1(DIA[1]), + .DIA2(DIA[2]), + .DIA3(DIA[3]), + .DIA4(DIA[4]), + .DIA5(DIA[5]), + .DIA6(DIA[6]), + .DIA7(DIA[7]), + .DIA8(DIA[8]), + .DOA0(DOA[0]), + .DOA1(DOA[1]), + .DOA2(DOA[2]), + .DOA3(DOA[3]), + .DOA4(DOA[4]), + .DOA5(DOA[5]), + .DOA6(DOA[6]), + .DOA7(DOA[7]), + .DOA8(DOA[8]), + + .CLKB(PORT_B_CLK), + .WEB(PORT_B_WR_EN), + .CEB(PORT_B_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_B_WIDTH == 9 ? 1'b1 : PORT_B_ADDR[0]), + .ADB1(PORT_B_ADDR[1]), + .ADB2(PORT_B_ADDR[2]), + .ADB3(PORT_B_ADDR[3]), + .ADB4(PORT_B_ADDR[4]), + .ADB5(PORT_B_ADDR[5]), + .ADB6(PORT_B_ADDR[6]), + .ADB7(PORT_B_ADDR[7]), + .ADB8(PORT_B_ADDR[8]), + .ADB9(PORT_B_ADDR[9]), + .ADB10(PORT_B_ADDR[10]), + .ADB11(PORT_B_ADDR[11]), + .ADB12(PORT_B_ADDR[12]), + .DIB0(DIB[0]), + .DIB1(DIB[1]), + .DIB2(DIB[2]), + .DIB3(DIB[3]), + .DIB4(DIB[4]), + .DIB5(DIB[5]), + .DIB6(DIB[6]), + .DIB7(DIB[7]), + .DIB8(DIB[8]), + .DOB0(DOB[0]), + .DOB1(DOB[1]), + .DOB2(DOB[2]), + .DOB3(DOB[3]), + .DOB4(DOB[4]), + .DOB5(DOB[5]), + .DOB6(DOB[6]), + .DOB7(DOB[7]), + .DOB8(DOB[8]), +); + +endmodule + + +module $__PDPW8KC_ (...); + +parameter INIT = 0; +parameter OPTION_RESETMODE = "SYNC"; + +parameter PORT_R_WIDTH = 18; + +input PORT_R_CLK; +input PORT_R_CLK_EN; +input PORT_R_RD_SRST; +input PORT_R_RD_ARST; +input [12:0] PORT_R_ADDR; +output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; + +parameter PORT_W_WIDTH = 18; +parameter PORT_W_WR_EN_WIDTH = 2; + +input PORT_W_CLK; +input PORT_W_CLK_EN; +input [12:0] PORT_W_ADDR; +input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; +input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; + +function [319:0] init_slice; + input integer idx; + integer i, j; + init_slice = 0; + for (i = 0; i < 16; i = i + 1) begin + init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; + end +endfunction + +wire [17:0] DI = PORT_W_WR_DATA; +wire [17:0] DO; + +assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; + +DP8KC #( + .INITVAL_00(init_slice('h00)), + .INITVAL_01(init_slice('h01)), + .INITVAL_02(init_slice('h02)), + .INITVAL_03(init_slice('h03)), + .INITVAL_04(init_slice('h04)), + .INITVAL_05(init_slice('h05)), + .INITVAL_06(init_slice('h06)), + .INITVAL_07(init_slice('h07)), + .INITVAL_08(init_slice('h08)), + .INITVAL_09(init_slice('h09)), + .INITVAL_0A(init_slice('h0a)), + .INITVAL_0B(init_slice('h0b)), + .INITVAL_0C(init_slice('h0c)), + .INITVAL_0D(init_slice('h0d)), + .INITVAL_0E(init_slice('h0e)), + .INITVAL_0F(init_slice('h0f)), + .INITVAL_10(init_slice('h10)), + .INITVAL_11(init_slice('h11)), + .INITVAL_12(init_slice('h12)), + .INITVAL_13(init_slice('h13)), + .INITVAL_14(init_slice('h14)), + .INITVAL_15(init_slice('h15)), + .INITVAL_16(init_slice('h16)), + .INITVAL_17(init_slice('h17)), + .INITVAL_18(init_slice('h18)), + .INITVAL_19(init_slice('h19)), + .INITVAL_1A(init_slice('h1a)), + .INITVAL_1B(init_slice('h1b)), + .INITVAL_1C(init_slice('h1c)), + .INITVAL_1D(init_slice('h1d)), + .INITVAL_1E(init_slice('h1e)), + .INITVAL_1F(init_slice('h1f)), + .DATA_WIDTH_A(PORT_W_WIDTH), + .DATA_WIDTH_B(PORT_R_WIDTH), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .RESETMODE(OPTION_RESETMODE), + .ASYNC_RESET_RELEASE(OPTION_RESETMODE), + .CSDECODE_A("0b000"), + .CSDECODE_B("0b000"), + .GSR("AUTO") +) _TECHMAP_REPLACE_ ( + .CLKA(PORT_W_CLK), + .WEA(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]), + .CEA(PORT_W_CLK_EN), + .OCEA(1'b0), + .RSTA(1'b0), + .CSA0(1'b0), + .CSA1(1'b0), + .CSA2(1'b0), + .ADA0(PORT_W_WIDTH >= 9 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), + .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), + .ADA2(PORT_W_ADDR[2]), + .ADA3(PORT_W_ADDR[3]), + .ADA4(PORT_W_ADDR[4]), + .ADA5(PORT_W_ADDR[5]), + .ADA6(PORT_W_ADDR[6]), + .ADA7(PORT_W_ADDR[7]), + .ADA8(PORT_W_ADDR[8]), + .ADA9(PORT_W_ADDR[9]), + .ADA10(PORT_W_ADDR[10]), + .ADA11(PORT_W_ADDR[11]), + .ADA12(PORT_W_ADDR[12]), + .DIA0(DI[0]), + .DIA1(DI[1]), + .DIA2(DI[2]), + .DIA3(DI[3]), + .DIA4(DI[4]), + .DIA5(DI[5]), + .DIA6(DI[6]), + .DIA7(DI[7]), + .DIA8(DI[8]), + .DIB0(DI[9]), + .DIB1(DI[10]), + .DIB2(DI[11]), + .DIB3(DI[12]), + .DIB4(DI[13]), + .DIB5(DI[14]), + .DIB6(DI[15]), + .DIB7(DI[16]), + .DIB8(DI[17]), + + .CLKB(PORT_R_CLK), + .WEB(1'b0), + .CEB(PORT_R_CLK_EN), + .OCEB(1'b1), + .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), + .CSB0(1'b0), + .CSB1(1'b0), + .CSB2(1'b0), + .ADB0(PORT_R_ADDR[0]), + .ADB1(PORT_R_ADDR[1]), + .ADB2(PORT_R_ADDR[2]), + .ADB3(PORT_R_ADDR[3]), + .ADB4(PORT_R_ADDR[4]), + .ADB5(PORT_R_ADDR[5]), + .ADB6(PORT_R_ADDR[6]), + .ADB7(PORT_R_ADDR[7]), + .ADB8(PORT_R_ADDR[8]), + .ADB9(PORT_R_ADDR[9]), + .ADB10(PORT_R_ADDR[10]), + .ADB11(PORT_R_ADDR[11]), + .ADB12(PORT_R_ADDR[12]), + .DOA0(DO[0]), + .DOA1(DO[1]), + .DOA2(DO[2]), + .DOA3(DO[3]), + .DOA4(DO[4]), + .DOA5(DO[5]), + .DOA6(DO[6]), + .DOA7(DO[7]), + .DOA8(DO[8]), + .DOB0(DO[9]), + .DOB1(DO[10]), + .DOB2(DO[11]), + .DOB3(DO[12]), + .DOB4(DO[13]), + .DOB5(DO[14]), + .DOB6(DO[15]), + .DOB7(DO[16]), + .DOB8(DO[17]), +); + +endmodule diff --git a/techlibs/lattice/ccu2c_sim.vh b/techlibs/lattice/ccu2c_sim.vh new file mode 100644 index 00000000000..d9eb69ab455 --- /dev/null +++ b/techlibs/lattice/ccu2c_sim.vh @@ -0,0 +1,61 @@ +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module CCU2C( + (* abc9_carry *) + input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + (* abc9_carry *) + output COUT +); + parameter [15:0] INIT0 = 16'h0000; + parameter [15:0] INIT1 = 16'h0000; + parameter INJECT1_0 = "YES"; + parameter INJECT1_1 = "YES"; + + // First half + wire LUT4_0, LUT2_0; + LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); + LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); + wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; + assign S0 = LUT4_0 ^ gated_cin_0; + + wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; + wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); + + // Second half + wire LUT4_1, LUT2_1; + LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); + LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); + wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; + assign S1 = LUT4_1 ^ gated_cin_1; + + wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; + assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); + + specify + (A0 => S0) = 379; + (B0 => S0) = 379; + (C0 => S0) = 275; + (D0 => S0) = 141; + (CIN => S0) = 257; + (A0 => S1) = 630; + (B0 => S1) = 630; + (C0 => S1) = 526; + (D0 => S1) = 392; + (A1 => S1) = 379; + (B1 => S1) = 379; + (C1 => S1) = 275; + (D1 => S1) = 141; + (CIN => S1) = 273; + (A0 => COUT) = 516; + (B0 => COUT) = 516; + (C0 => COUT) = 412; + (D0 => COUT) = 278; + (A1 => COUT) = 516; + (B1 => COUT) = 516; + (C1 => COUT) = 412; + (D1 => COUT) = 278; + (CIN => COUT) = 43; + endspecify +endmodule diff --git a/techlibs/lattice/ccu2d_sim.vh b/techlibs/lattice/ccu2d_sim.vh new file mode 100644 index 00000000000..5b9c95cc9ef --- /dev/null +++ b/techlibs/lattice/ccu2d_sim.vh @@ -0,0 +1,33 @@ +// --------------------------------------- +(* lib_whitebox *) +module CCU2D ( + input CIN, + input A0, B0, C0, D0, A1, B1, C1, D1, + output S0, S1, + output COUT +); + parameter [15:0] INIT0 = 16'h0000; + parameter [15:0] INIT1 = 16'h0000; + parameter INJECT1_0 = "YES"; + parameter INJECT1_1 = "YES"; + + // First half + wire LUT4_0, LUT2_0; + LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); + LUT2 #(.INIT(~INIT0[15:12])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); + wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; + assign S0 = LUT4_0 ^ gated_cin_0; + + wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; + wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); + + // Second half + wire LUT4_1, LUT2_1; + LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); + LUT2 #(.INIT(~INIT1[15:12])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); + wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; + assign S1 = LUT4_1 ^ gated_cin_1; + + wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; + assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); +endmodule diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v new file mode 100644 index 00000000000..5cb90b97efc --- /dev/null +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -0,0 +1,1067 @@ +// ECP5 Blackbox cells +// FIXME: Create sim models + +(* blackbox *) +module DP16KD( + input DIA17, DIA16, DIA15, DIA14, DIA13, DIA12, DIA11, DIA10, DIA9, DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA13, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB17, DIB16, DIB15, DIB14, DIB13, DIB12, DIB11, DIB10, DIB9, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB13, ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 18; + parameter DATA_WIDTH_B = 18; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter DIA17MUX = "DIA17"; + parameter DIA16MUX = "DIA16"; + parameter DIA15MUX = "DIA15"; + parameter DIA14MUX = "DIA14"; + parameter DIA13MUX = "DIA13"; + parameter DIA12MUX = "DIA12"; + parameter DIA11MUX = "DIA11"; + parameter DIA10MUX = "DIA10"; + parameter DIA9MUX = "DIA9"; + parameter DIA8MUX = "DIA8"; + parameter DIA7MUX = "DIA7"; + parameter DIA6MUX = "DIA6"; + parameter DIA5MUX = "DIA5"; + parameter DIA4MUX = "DIA4"; + parameter DIA3MUX = "DIA3"; + parameter DIA2MUX = "DIA2"; + parameter DIA1MUX = "DIA1"; + parameter DIA0MUX = "DIA0"; + parameter ADA13MUX = "ADA13"; + parameter ADA12MUX = "ADA12"; + parameter ADA11MUX = "ADA11"; + parameter ADA10MUX = "ADA10"; + parameter ADA9MUX = "ADA9"; + parameter ADA8MUX = "ADA8"; + parameter ADA7MUX = "ADA7"; + parameter ADA6MUX = "ADA6"; + parameter ADA5MUX = "ADA5"; + parameter ADA4MUX = "ADA4"; + parameter ADA3MUX = "ADA3"; + parameter ADA2MUX = "ADA2"; + parameter ADA1MUX = "ADA1"; + parameter ADA0MUX = "ADA0"; + parameter CEAMUX = "CEA"; + parameter OCEAMUX = "OCEA"; + parameter CLKAMUX = "CLKA"; + parameter WEAMUX = "WEA"; + parameter RSTAMUX = "RSTA"; + parameter CSA2MUX = "CSA2"; + parameter CSA1MUX = "CSA1"; + parameter CSA0MUX = "CSA0"; + parameter DOA17MUX = "DOA17"; + parameter DOA16MUX = "DOA16"; + parameter DOA15MUX = "DOA15"; + parameter DOA14MUX = "DOA14"; + parameter DOA13MUX = "DOA13"; + parameter DOA12MUX = "DOA12"; + parameter DOA11MUX = "DOA11"; + parameter DOA10MUX = "DOA10"; + parameter DOA9MUX = "DOA9"; + parameter DOA8MUX = "DOA8"; + parameter DOA7MUX = "DOA7"; + parameter DOA6MUX = "DOA6"; + parameter DOA5MUX = "DOA5"; + parameter DOA4MUX = "DOA4"; + parameter DOA3MUX = "DOA3"; + parameter DOA2MUX = "DOA2"; + parameter DOA1MUX = "DOA1"; + parameter DOA0MUX = "DOA0"; + parameter DIB17MUX = "DIB17"; + parameter DIB16MUX = "DIB16"; + parameter DIB15MUX = "DIB15"; + parameter DIB14MUX = "DIB14"; + parameter DIB13MUX = "DIB13"; + parameter DIB12MUX = "DIB12"; + parameter DIB11MUX = "DIB11"; + parameter DIB10MUX = "DIB10"; + parameter DIB9MUX = "DIB9"; + parameter DIB8MUX = "DIB8"; + parameter DIB7MUX = "DIB7"; + parameter DIB6MUX = "DIB6"; + parameter DIB5MUX = "DIB5"; + parameter DIB4MUX = "DIB4"; + parameter DIB3MUX = "DIB3"; + parameter DIB2MUX = "DIB2"; + parameter DIB1MUX = "DIB1"; + parameter DIB0MUX = "DIB0"; + parameter ADB13MUX = "ADB13"; + parameter ADB12MUX = "ADB12"; + parameter ADB11MUX = "ADB11"; + parameter ADB10MUX = "ADB10"; + parameter ADB9MUX = "ADB9"; + parameter ADB8MUX = "ADB8"; + parameter ADB7MUX = "ADB7"; + parameter ADB6MUX = "ADB6"; + parameter ADB5MUX = "ADB5"; + parameter ADB4MUX = "ADB4"; + parameter ADB3MUX = "ADB3"; + parameter ADB2MUX = "ADB2"; + parameter ADB1MUX = "ADB1"; + parameter ADB0MUX = "ADB0"; + parameter CEBMUX = "CEB"; + parameter OCEBMUX = "OCEB"; + parameter CLKBMUX = "CLKB"; + parameter WEBMUX = "WEB"; + parameter RSTBMUX = "RSTB"; + parameter CSB2MUX = "CSB2"; + parameter CSB1MUX = "CSB1"; + parameter CSB0MUX = "CSB0"; + parameter DOB17MUX = "DOB17"; + parameter DOB16MUX = "DOB16"; + parameter DOB15MUX = "DOB15"; + parameter DOB14MUX = "DOB14"; + parameter DOB13MUX = "DOB13"; + parameter DOB12MUX = "DOB12"; + parameter DOB11MUX = "DOB11"; + parameter DOB10MUX = "DOB10"; + parameter DOB9MUX = "DOB9"; + parameter DOB8MUX = "DOB8"; + parameter DOB7MUX = "DOB7"; + parameter DOB6MUX = "DOB6"; + parameter DOB5MUX = "DOB5"; + parameter DOB4MUX = "DOB4"; + parameter DOB3MUX = "DOB3"; + parameter DOB2MUX = "DOB2"; + parameter DOB1MUX = "DOB1"; + parameter DOB0MUX = "DOB0"; + + parameter WID = 0; + + parameter GSR = "ENABLED"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module MULT18X18D( + input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, + input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, + input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, + input SIGNEDA, SIGNEDB, SOURCEA, SOURCEB, + input CLK0, CLK1, CLK2, CLK3, + input CE0, CE1, CE2, CE3, + input RST0, RST1, RST2, RST3, + input SRIA0, SRIA1, SRIA2, SRIA3, SRIA4, SRIA5, SRIA6, SRIA7, SRIA8, SRIA9, SRIA10, SRIA11, SRIA12, SRIA13, SRIA14, SRIA15, SRIA16, SRIA17, + input SRIB0, SRIB1, SRIB2, SRIB3, SRIB4, SRIB5, SRIB6, SRIB7, SRIB8, SRIB9, SRIB10, SRIB11, SRIB12, SRIB13, SRIB14, SRIB15, SRIB16, SRIB17, + output SROA0, SROA1, SROA2, SROA3, SROA4, SROA5, SROA6, SROA7, SROA8, SROA9, SROA10, SROA11, SROA12, SROA13, SROA14, SROA15, SROA16, SROA17, + output SROB0, SROB1, SROB2, SROB3, SROB4, SROB5, SROB6, SROB7, SROB8, SROB9, SROB10, SROB11, SROB12, SROB13, SROB14, SROB15, SROB16, SROB17, + output ROA0, ROA1, ROA2, ROA3, ROA4, ROA5, ROA6, ROA7, ROA8, ROA9, ROA10, ROA11, ROA12, ROA13, ROA14, ROA15, ROA16, ROA17, + output ROB0, ROB1, ROB2, ROB3, ROB4, ROB5, ROB6, ROB7, ROB8, ROB9, ROB10, ROB11, ROB12, ROB13, ROB14, ROB15, ROB16, ROB17, + output ROC0, ROC1, ROC2, ROC3, ROC4, ROC5, ROC6, ROC7, ROC8, ROC9, ROC10, ROC11, ROC12, ROC13, ROC14, ROC15, ROC16, ROC17, + output P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, + output SIGNEDP +); + parameter REG_INPUTA_CLK = "NONE"; + parameter REG_INPUTA_CE = "CE0"; + parameter REG_INPUTA_RST = "RST0"; + parameter REG_INPUTB_CLK = "NONE"; + parameter REG_INPUTB_CE = "CE0"; + parameter REG_INPUTB_RST = "RST0"; + parameter REG_INPUTC_CLK = "NONE"; + parameter REG_INPUTC_CE = "CE0"; + parameter REG_INPUTC_RST = "RST0"; + parameter REG_PIPELINE_CLK = "NONE"; + parameter REG_PIPELINE_CE = "CE0"; + parameter REG_PIPELINE_RST = "RST0"; + parameter REG_OUTPUT_CLK = "NONE"; + parameter REG_OUTPUT_CE = "CE0"; + parameter REG_OUTPUT_RST = "RST0"; + parameter [127:0] CLK0_DIV = "ENABLED"; + parameter [127:0] CLK1_DIV = "ENABLED"; + parameter [127:0] CLK2_DIV = "ENABLED"; + parameter [127:0] CLK3_DIV = "ENABLED"; + parameter HIGHSPEED_CLK = "NONE"; + parameter [127:0] GSR = "ENABLED"; + parameter CAS_MATCH_REG = "FALSE"; + parameter [127:0] SOURCEB_MODE = "B_SHIFT"; + parameter [127:0] MULT_BYPASS = "DISABLED"; + parameter [127:0] RESETMODE = "SYNC"; +endmodule + +(* blackbox *) +module ALU54B( + input CLK0, CLK1, CLK2, CLK3, + input CE0, CE1, CE2, CE3, + input RST0, RST1, RST2, RST3, + input SIGNEDIA, SIGNEDIB, SIGNEDCIN, + input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, + input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, B27, B28, B29, B30, B31, B32, B33, B34, B35, + input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26, C27, C28, C29, C30, C31, C32, C33, C34, C35, C36, C37, C38, C39, C40, C41, C42, C43, C44, C45, C46, C47, C48, C49, C50, C51, C52, C53, + input CFB0, CFB1, CFB2, CFB3, CFB4, CFB5, CFB6, CFB7, CFB8, CFB9, CFB10, CFB11, CFB12, CFB13, CFB14, CFB15, CFB16, CFB17, CFB18, CFB19, CFB20, CFB21, CFB22, CFB23, CFB24, CFB25, CFB26, CFB27, CFB28, CFB29, CFB30, CFB31, CFB32, CFB33, CFB34, CFB35, CFB36, CFB37, CFB38, CFB39, CFB40, CFB41, CFB42, CFB43, CFB44, CFB45, CFB46, CFB47, CFB48, CFB49, CFB50, CFB51, CFB52, CFB53, + input MA0, MA1, MA2, MA3, MA4, MA5, MA6, MA7, MA8, MA9, MA10, MA11, MA12, MA13, MA14, MA15, MA16, MA17, MA18, MA19, MA20, MA21, MA22, MA23, MA24, MA25, MA26, MA27, MA28, MA29, MA30, MA31, MA32, MA33, MA34, MA35, + input MB0, MB1, MB2, MB3, MB4, MB5, MB6, MB7, MB8, MB9, MB10, MB11, MB12, MB13, MB14, MB15, MB16, MB17, MB18, MB19, MB20, MB21, MB22, MB23, MB24, MB25, MB26, MB27, MB28, MB29, MB30, MB31, MB32, MB33, MB34, MB35, + input CIN0, CIN1, CIN2, CIN3, CIN4, CIN5, CIN6, CIN7, CIN8, CIN9, CIN10, CIN11, CIN12, CIN13, CIN14, CIN15, CIN16, CIN17, CIN18, CIN19, CIN20, CIN21, CIN22, CIN23, CIN24, CIN25, CIN26, CIN27, CIN28, CIN29, CIN30, CIN31, CIN32, CIN33, CIN34, CIN35, CIN36, CIN37, CIN38, CIN39, CIN40, CIN41, CIN42, CIN43, CIN44, CIN45, CIN46, CIN47, CIN48, CIN49, CIN50, CIN51, CIN52, CIN53, + input OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, OP8, OP9, OP10, + output R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, R47, R48, R49, R50, R51, R52, R53, + output CO0, CO1, CO2, CO3, CO4, CO5, CO6, CO7, CO8, CO9, CO10, CO11, CO12, CO13, CO14, CO15, CO16, CO17, CO18, CO19, CO20, CO21, CO22, CO23, CO24, CO25, CO26, CO27, CO28, CO29, CO30, CO31, CO32, CO33, CO34, CO35, CO36, CO37, CO38, CO39, CO40, CO41, CO42, CO43, CO44, CO45, CO46, CO47, CO48, CO49, CO50, CO51, CO52, CO53, + output EQZ, EQZM, EQOM, EQPAT, EQPATB, + output OVER, UNDER, OVERUNDER, + output SIGNEDR +); + parameter REG_INPUTC0_CLK = "NONE"; + parameter REG_INPUTC0_CE = "CE0"; + parameter REG_INPUTC0_RST = "RST0"; + parameter REG_INPUTC1_CLK = "NONE"; + parameter REG_INPUTC1_CE = "CE0"; + parameter REG_INPUTC1_RST = "RST0"; + parameter REG_OPCODEOP0_0_CLK = "NONE"; + parameter REG_OPCODEOP0_0_CE = "CE0"; + parameter REG_OPCODEOP0_0_RST = "RST0"; + parameter REG_OPCODEOP1_0_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CE = "CE0"; + parameter REG_OPCODEOP0_1_RST = "RST0"; + parameter REG_OPCODEOP1_1_CLK = "NONE"; + parameter REG_OPCODEIN_0_CLK = "NONE"; + parameter REG_OPCODEIN_0_CE = "CE0"; + parameter REG_OPCODEIN_0_RST = "RST0"; + parameter REG_OPCODEIN_1_CLK = "NONE"; + parameter REG_OPCODEIN_1_CE = "CE0"; + parameter REG_OPCODEIN_1_RST = "RST0"; + parameter REG_OUTPUT0_CLK = "NONE"; + parameter REG_OUTPUT0_CE = "CE0"; + parameter REG_OUTPUT0_RST = "RST0"; + parameter REG_OUTPUT1_CLK = "NONE"; + parameter REG_OUTPUT1_CE = "CE0"; + parameter REG_OUTPUT1_RST = "RST0"; + parameter REG_FLAG_CLK = "NONE"; + parameter REG_FLAG_CE = "CE0"; + parameter REG_FLAG_RST = "RST0"; + parameter REG_INPUTCFB_CLK = "NONE"; + parameter REG_INPUTCFB_CE = "CE0"; + parameter REG_INPUTCFB_RST = "RST0"; + parameter [127:0] MCPAT_SOURCE = "STATIC"; + parameter [127:0] MASKPAT_SOURCE = "STATIC"; + parameter MASK01 = "0x00000000000000"; + parameter [127:0] CLK0_DIV = "ENABLED"; + parameter [127:0] CLK1_DIV = "ENABLED"; + parameter [127:0] CLK2_DIV = "ENABLED"; + parameter [127:0] CLK3_DIV = "ENABLED"; + parameter MCPAT = "0x00000000000000"; + parameter MASKPAT = "0x00000000000000"; + parameter RNDPAT = "0x00000000000000"; + parameter [127:0] GSR = "ENABLED"; + parameter [127:0] RESETMODE = "SYNC"; + parameter MULT9_MODE = "DISABLED"; + parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; + parameter LEGACY = "DISABLED"; +endmodule + +(* blackbox *) +module EHXPLLL ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, PHASELOADREG, + input STDBY, PLLWAKESYNC, + input RST, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, + output CLKOP, CLKOS, CLKOS2, CLKOS3, + output LOCK, INTLOCK, + output REFCLK, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "DISABLED"; + parameter CLKOS2_ENABLE = "DISABLED"; + parameter CLKOS3_ENABLE = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter OUTDIVIDER_MUXA = "DIVA"; + parameter OUTDIVIDER_MUXB = "DIVB"; + parameter OUTDIVIDER_MUXC = "DIVC"; + parameter OUTDIVIDER_MUXD = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter PLL_LOCK_DELAY = 200; + parameter STDBY_ENABLE = "DISABLED"; + parameter REFIN_RESET = "DISABLED"; + parameter SYNC_ENABLE = "DISABLED"; + parameter INT_LOCK_STICKY = "ENABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module DTR( + input STARTPULSE, + output DTROUT7, DTROUT6, DTROUT5, DTROUT4, DTROUT3, DTROUT2, DTROUT1, DTROUT0 +); +endmodule + +(* blackbox *) +module OSCG( + output OSC +); +parameter DIV = 128; +endmodule + +(* blackbox *) (* keep *) +module USRMCLK( + input USRMCLKI, USRMCLKTS, + output USRMCLKO +); +endmodule + +(* blackbox *) (* keep *) +module JTAGG( + (* iopad_external_pin *) + input TCK, + (* iopad_external_pin *) + input TMS, + (* iopad_external_pin *) + input TDI, + input JTDO2, JTDO1, + (* iopad_external_pin *) + output TDO, + output JTDI, JTCK, JRTI2, JRTI1, + output JSHIFT, JUPDATE, JRSTN, JCE2, JCE1 +); +parameter ER1 = "ENABLED"; +parameter ER2 = "ENABLED"; +endmodule + +(* blackbox *) +module DELAYF( + input A, LOADN, MOVE, DIRECTION, + output Z, CFLAG +); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; +endmodule + +(* blackbox *) +module DELAYG( + input A, + output Z +); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; +endmodule + +(* blackbox *) +module IDDRX1F( + input D, SCLK, RST, + output Q0, Q1 +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module IDDRX2F( + input D, SCLK, ECLK, RST, ALIGNWD, + output Q0, Q1, Q2, Q3 +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module IDDR71B( + input D, SCLK, ECLK, RST, ALIGNWD, + output Q0, Q1, Q2, Q3, Q4, Q5, Q6 +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module IDDRX2DQA( + input D, DQSR90, ECLK, SCLK, RST, + input RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, + output Q0, Q1, Q2, Q3, QWL +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX1F( + input SCLK, RST, D0, D1, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX2F( + input SCLK, ECLK, RST, D0, D1, D2, D3, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDR71B( + input SCLK, ECLK, RST, D0, D1, D2, D3, D4, D5, D6, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module OSHX2A( + input D0, D1, RST, ECLK, SCLK, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX2DQA( + input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW270, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module ODDRX2DQSB( + input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW, + output Q +); + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module TSHX2DQA( + input T0, T1, SCLK, ECLK, DQSW270, RST, + output Q +); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; +endmodule + +(* blackbox *) +module TSHX2DQSA( + input T0, T1, SCLK, ECLK, DQSW, RST, + output Q +); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; +endmodule + +(* blackbox *) +module DQSBUFM( + input DQSI, READ1, READ0, READCLKSEL2, READCLKSEL1, READCLKSEL0, DDRDEL, + input ECLK, SCLK, + input DYNDELAY7, DYNDELAY6, DYNDELAY5, DYNDELAY4, + input DYNDELAY3, DYNDELAY2, DYNDELAY1, DYNDELAY0, + input RST, RDLOADN, RDMOVE, RDDIRECTION, WRLOADN, WRMOVE, WRDIRECTION, PAUSE, + output DQSR90, DQSW, DQSW270, + output RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, + output DATAVALID, BURSTDET, RDCFLAG, WRCFLAG +); + parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; + parameter DQS_LI_DEL_VAL = 0; + parameter DQS_LO_DEL_ADJ = "FACTORYONLY"; + parameter DQS_LO_DEL_VAL = 0; + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module DDRDLLA( + input CLK, RST, UDDCNTLN, FREEZE, + output LOCK, DDRDEL, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0 +); + parameter FORCE_MAX_DELAY = "NO"; + parameter GSR = "ENABLED"; +endmodule + +(* blackbox *) +module DLLDELD( + input A, DDRDEL, LOADN, MOVE, DIRECTION, + output Z, CFLAG +); + parameter DEL_ADJ = "PLUS"; + parameter DEL_VAL = 0; +endmodule + +(* blackbox *) +module CLKDIVF( + input CLKI, RST, ALIGNWD, + output CDIVX +); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; +endmodule + +(* blackbox *) +module ECLKSYNCB( + input ECLKI, STOP, + output ECLKO +); +endmodule + +(* blackbox *) +module ECLKBRIDGECS( + input CLK0, CLK1, SEL, + output ECSOUT +); +endmodule + +(* blackbox *) +module DCCA( + input CLKI, CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCSC( + input CLK1, CLK0, + input SEL1, SEL0, + input MODESEL, + output DCSOUT +); + parameter DCSMODE = "POS"; +endmodule + +(* blackbox *) (* keep *) +module DCUA( + (* iopad_external_pin *) + input CH0_HDINP, + (* iopad_external_pin *) + input CH1_HDINP, + (* iopad_external_pin *) + input CH0_HDINN, + (* iopad_external_pin *) + input CH1_HDINN, + input D_TXBIT_CLKP_FROM_ND, D_TXBIT_CLKN_FROM_ND, D_SYNC_ND, D_TXPLL_LOL_FROM_ND, + input CH0_RX_REFCLK, CH1_RX_REFCLK, CH0_FF_RXI_CLK, CH1_FF_RXI_CLK, CH0_FF_TXI_CLK, CH1_FF_TXI_CLK, CH0_FF_EBRD_CLK, CH1_FF_EBRD_CLK, + input CH0_FF_TX_D_0, CH1_FF_TX_D_0, CH0_FF_TX_D_1, CH1_FF_TX_D_1, CH0_FF_TX_D_2, CH1_FF_TX_D_2, CH0_FF_TX_D_3, CH1_FF_TX_D_3, + input CH0_FF_TX_D_4, CH1_FF_TX_D_4, CH0_FF_TX_D_5, CH1_FF_TX_D_5, CH0_FF_TX_D_6, CH1_FF_TX_D_6, CH0_FF_TX_D_7, CH1_FF_TX_D_7, + input CH0_FF_TX_D_8, CH1_FF_TX_D_8, CH0_FF_TX_D_9, CH1_FF_TX_D_9, CH0_FF_TX_D_10, CH1_FF_TX_D_10, CH0_FF_TX_D_11, CH1_FF_TX_D_11, + input CH0_FF_TX_D_12, CH1_FF_TX_D_12, CH0_FF_TX_D_13, CH1_FF_TX_D_13, CH0_FF_TX_D_14, CH1_FF_TX_D_14, CH0_FF_TX_D_15, CH1_FF_TX_D_15, + input CH0_FF_TX_D_16, CH1_FF_TX_D_16, CH0_FF_TX_D_17, CH1_FF_TX_D_17, CH0_FF_TX_D_18, CH1_FF_TX_D_18, CH0_FF_TX_D_19, CH1_FF_TX_D_19, + input CH0_FF_TX_D_20, CH1_FF_TX_D_20, CH0_FF_TX_D_21, CH1_FF_TX_D_21, CH0_FF_TX_D_22, CH1_FF_TX_D_22, CH0_FF_TX_D_23, CH1_FF_TX_D_23, + input CH0_FFC_EI_EN, CH1_FFC_EI_EN, CH0_FFC_PCIE_DET_EN, CH1_FFC_PCIE_DET_EN, CH0_FFC_PCIE_CT, CH1_FFC_PCIE_CT, CH0_FFC_SB_INV_RX, CH1_FFC_SB_INV_RX, + input CH0_FFC_ENABLE_CGALIGN, CH1_FFC_ENABLE_CGALIGN, CH0_FFC_SIGNAL_DETECT, CH1_FFC_SIGNAL_DETECT, CH0_FFC_FB_LOOPBACK, CH1_FFC_FB_LOOPBACK, CH0_FFC_SB_PFIFO_LP, CH1_FFC_SB_PFIFO_LP, + input CH0_FFC_PFIFO_CLR, CH1_FFC_PFIFO_CLR, CH0_FFC_RATE_MODE_RX, CH1_FFC_RATE_MODE_RX, CH0_FFC_RATE_MODE_TX, CH1_FFC_RATE_MODE_TX, CH0_FFC_DIV11_MODE_RX, CH1_FFC_DIV11_MODE_RX, CH0_FFC_RX_GEAR_MODE, CH1_FFC_RX_GEAR_MODE, CH0_FFC_TX_GEAR_MODE, CH1_FFC_TX_GEAR_MODE, + input CH0_FFC_DIV11_MODE_TX, CH1_FFC_DIV11_MODE_TX, CH0_FFC_LDR_CORE2TX_EN, CH1_FFC_LDR_CORE2TX_EN, CH0_FFC_LANE_TX_RST, CH1_FFC_LANE_TX_RST, CH0_FFC_LANE_RX_RST, CH1_FFC_LANE_RX_RST, + input CH0_FFC_RRST, CH1_FFC_RRST, CH0_FFC_TXPWDNB, CH1_FFC_TXPWDNB, CH0_FFC_RXPWDNB, CH1_FFC_RXPWDNB, CH0_LDR_CORE2TX, CH1_LDR_CORE2TX, + input D_SCIWDATA0, D_SCIWDATA1, D_SCIWDATA2, D_SCIWDATA3, D_SCIWDATA4, D_SCIWDATA5, D_SCIWDATA6, D_SCIWDATA7, + input D_SCIADDR0, D_SCIADDR1, D_SCIADDR2, D_SCIADDR3, D_SCIADDR4, D_SCIADDR5, D_SCIENAUX, D_SCISELAUX, + input CH0_SCIEN, CH1_SCIEN, CH0_SCISEL, CH1_SCISEL, D_SCIRD, D_SCIWSTN, D_CYAWSTN, D_FFC_SYNC_TOGGLE, + input D_FFC_DUAL_RST, D_FFC_MACRO_RST, D_FFC_MACROPDB, D_FFC_TRST, CH0_FFC_CDR_EN_BITSLIP, CH1_FFC_CDR_EN_BITSLIP, D_SCAN_ENABLE, D_SCAN_IN_0, + input D_SCAN_IN_1, D_SCAN_IN_2, D_SCAN_IN_3, D_SCAN_IN_4, D_SCAN_IN_5, D_SCAN_IN_6, D_SCAN_IN_7, D_SCAN_MODE, + input D_SCAN_RESET, D_CIN0, D_CIN1, D_CIN2, D_CIN3, D_CIN4, D_CIN5, D_CIN6,D_CIN7, D_CIN8, D_CIN9, D_CIN10, D_CIN11, + output CH0_HDOUTP, CH1_HDOUTP, CH0_HDOUTN, CH1_HDOUTN, D_TXBIT_CLKP_TO_ND, D_TXBIT_CLKN_TO_ND, D_SYNC_PULSE2ND, D_TXPLL_LOL_TO_ND, + output CH0_FF_RX_F_CLK, CH1_FF_RX_F_CLK, CH0_FF_RX_H_CLK, CH1_FF_RX_H_CLK, CH0_FF_TX_F_CLK, CH1_FF_TX_F_CLK, CH0_FF_TX_H_CLK, CH1_FF_TX_H_CLK, + output CH0_FF_RX_PCLK, CH1_FF_RX_PCLK, CH0_FF_TX_PCLK, CH1_FF_TX_PCLK, CH0_FF_RX_D_0, CH1_FF_RX_D_0, CH0_FF_RX_D_1, CH1_FF_RX_D_1, + output CH0_FF_RX_D_2, CH1_FF_RX_D_2, CH0_FF_RX_D_3, CH1_FF_RX_D_3, CH0_FF_RX_D_4, CH1_FF_RX_D_4, CH0_FF_RX_D_5, CH1_FF_RX_D_5, + output CH0_FF_RX_D_6, CH1_FF_RX_D_6, CH0_FF_RX_D_7, CH1_FF_RX_D_7, CH0_FF_RX_D_8, CH1_FF_RX_D_8, CH0_FF_RX_D_9, CH1_FF_RX_D_9, + output CH0_FF_RX_D_10, CH1_FF_RX_D_10, CH0_FF_RX_D_11, CH1_FF_RX_D_11, CH0_FF_RX_D_12, CH1_FF_RX_D_12, CH0_FF_RX_D_13, CH1_FF_RX_D_13, + output CH0_FF_RX_D_14, CH1_FF_RX_D_14, CH0_FF_RX_D_15, CH1_FF_RX_D_15, CH0_FF_RX_D_16, CH1_FF_RX_D_16, CH0_FF_RX_D_17, CH1_FF_RX_D_17, + output CH0_FF_RX_D_18, CH1_FF_RX_D_18, CH0_FF_RX_D_19, CH1_FF_RX_D_19, CH0_FF_RX_D_20, CH1_FF_RX_D_20, CH0_FF_RX_D_21, CH1_FF_RX_D_21, + output CH0_FF_RX_D_22, CH1_FF_RX_D_22, CH0_FF_RX_D_23, CH1_FF_RX_D_23, CH0_FFS_PCIE_DONE, CH1_FFS_PCIE_DONE, CH0_FFS_PCIE_CON, CH1_FFS_PCIE_CON, + output CH0_FFS_RLOS, CH1_FFS_RLOS, CH0_FFS_LS_SYNC_STATUS, CH1_FFS_LS_SYNC_STATUS, CH0_FFS_CC_UNDERRUN, CH1_FFS_CC_UNDERRUN, CH0_FFS_CC_OVERRUN, CH1_FFS_CC_OVERRUN, + output CH0_FFS_RXFBFIFO_ERROR, CH1_FFS_RXFBFIFO_ERROR, CH0_FFS_TXFBFIFO_ERROR, CH1_FFS_TXFBFIFO_ERROR, CH0_FFS_RLOL, CH1_FFS_RLOL, CH0_FFS_SKP_ADDED, CH1_FFS_SKP_ADDED, + output CH0_FFS_SKP_DELETED, CH1_FFS_SKP_DELETED, CH0_LDR_RX2CORE, CH1_LDR_RX2CORE, D_SCIRDATA0, D_SCIRDATA1, D_SCIRDATA2, D_SCIRDATA3, + output D_SCIRDATA4, D_SCIRDATA5, D_SCIRDATA6, D_SCIRDATA7, D_SCIINT, D_SCAN_OUT_0, D_SCAN_OUT_1, D_SCAN_OUT_2, D_SCAN_OUT_3, D_SCAN_OUT_4, D_SCAN_OUT_5, D_SCAN_OUT_6, D_SCAN_OUT_7, + output D_COUT0, D_COUT1, D_COUT2, D_COUT3, D_COUT4, D_COUT5, D_COUT6, D_COUT7, D_COUT8, D_COUT9, D_COUT10, D_COUT11, D_COUT12, D_COUT13, D_COUT14, D_COUT15, D_COUT16, D_COUT17, D_COUT18, D_COUT19, + + input D_REFCLKI, + output D_FFS_PLOL +); + parameter CH0_AUTO_CALIB_EN = "0b0"; + parameter CH0_AUTO_FACQ_EN = "0b0"; + parameter CH0_BAND_THRESHOLD = "0b000000"; + parameter CH0_CALIB_CK_MODE = "0b0"; + parameter CH0_CC_MATCH_1 = "0b0000000000"; + parameter CH0_CC_MATCH_2 = "0b0000000000"; + parameter CH0_CC_MATCH_3 = "0b0000000000"; + parameter CH0_CC_MATCH_4 = "0b0000000000"; + parameter CH0_CDR_CNT4SEL = "0b00"; + parameter CH0_CDR_CNT8SEL = "0b00"; + parameter CH0_CTC_BYPASS = "0b0"; + parameter CH0_DCOATDCFG = "0b00"; + parameter CH0_DCOATDDLY = "0b00"; + parameter CH0_DCOBYPSATD = "0b0"; + parameter CH0_DCOCALDIV = "0b000"; + parameter CH0_DCOCTLGI = "0b000"; + parameter CH0_DCODISBDAVOID = "0b0"; + parameter CH0_DCOFLTDAC = "0b00"; + parameter CH0_DCOFTNRG = "0b000"; + parameter CH0_DCOIOSTUNE = "0b000"; + parameter CH0_DCOITUNE = "0b00"; + parameter CH0_DCOITUNE4LSB = "0b000"; + parameter CH0_DCOIUPDNX2 = "0b0"; + parameter CH0_DCONUOFLSB = "0b000"; + parameter CH0_DCOSCALEI = "0b00"; + parameter CH0_DCOSTARTVAL = "0b000"; + parameter CH0_DCOSTEP = "0b00"; + parameter CH0_DEC_BYPASS = "0b0"; + parameter CH0_ENABLE_CG_ALIGN = "0b0"; + parameter CH0_ENC_BYPASS = "0b0"; + parameter CH0_FF_RX_F_CLK_DIS = "0b0"; + parameter CH0_FF_RX_H_CLK_EN = "0b0"; + parameter CH0_FF_TX_F_CLK_DIS = "0b0"; + parameter CH0_FF_TX_H_CLK_EN = "0b0"; + parameter CH0_GE_AN_ENABLE = "0b0"; + parameter CH0_INVERT_RX = "0b0"; + parameter CH0_INVERT_TX = "0b0"; + parameter CH0_LDR_CORE2TX_SEL = "0b0"; + parameter CH0_LDR_RX2CORE_SEL = "0b0"; + parameter CH0_LEQ_OFFSET_SEL = "0b0"; + parameter CH0_LEQ_OFFSET_TRIM = "0b000"; + parameter CH0_LSM_DISABLE = "0b0"; + parameter CH0_MATCH_2_ENABLE = "0b0"; + parameter CH0_MATCH_4_ENABLE = "0b0"; + parameter CH0_MIN_IPG_CNT = "0b00"; + parameter CH0_PCIE_EI_EN = "0b0"; + parameter CH0_PCIE_MODE = "0b0"; + parameter CH0_PCS_DET_TIME_SEL = "0b00"; + parameter CH0_PDEN_SEL = "0b0"; + parameter CH0_PRBS_ENABLE = "0b0"; + parameter CH0_PRBS_LOCK = "0b0"; + parameter CH0_PRBS_SELECTION = "0b0"; + parameter CH0_RATE_MODE_RX = "0b0"; + parameter CH0_RATE_MODE_TX = "0b0"; + parameter CH0_RCV_DCC_EN = "0b0"; + parameter CH0_REG_BAND_OFFSET = "0b0000"; + parameter CH0_REG_BAND_SEL = "0b000000"; + parameter CH0_REG_IDAC_EN = "0b0"; + parameter CH0_REG_IDAC_SEL = "0b0000000000"; + parameter CH0_REQ_EN = "0b0"; + parameter CH0_REQ_LVL_SET = "0b00"; + parameter CH0_RIO_MODE = "0b0"; + parameter CH0_RLOS_SEL = "0b0"; + parameter CH0_RPWDNB = "0b0"; + parameter CH0_RTERM_RX = "0b00000"; + parameter CH0_RTERM_TX = "0b00000"; + parameter CH0_RXIN_CM = "0b00"; + parameter CH0_RXTERM_CM = "0b00"; + parameter CH0_RX_DCO_CK_DIV = "0b000"; + parameter CH0_RX_DIV11_SEL = "0b0"; + parameter CH0_RX_GEAR_BYPASS = "0b0"; + parameter CH0_RX_GEAR_MODE = "0b0"; + parameter CH0_RX_LOS_CEQ = "0b00"; + parameter CH0_RX_LOS_EN = "0b0"; + parameter CH0_RX_LOS_HYST_EN = "0b0"; + parameter CH0_RX_LOS_LVL = "0b000"; + parameter CH0_RX_RATE_SEL = "0b0000"; + parameter CH0_RX_SB_BYPASS = "0b0"; + parameter CH0_SB_BYPASS = "0b0"; + parameter CH0_SEL_SD_RX_CLK = "0b0"; + parameter CH0_TDRV_DAT_SEL = "0b00"; + parameter CH0_TDRV_POST_EN = "0b0"; + parameter CH0_TDRV_PRE_EN = "0b0"; + parameter CH0_TDRV_SLICE0_CUR = "0b000"; + parameter CH0_TDRV_SLICE0_SEL = "0b00"; + parameter CH0_TDRV_SLICE1_CUR = "0b000"; + parameter CH0_TDRV_SLICE1_SEL = "0b00"; + parameter CH0_TDRV_SLICE2_CUR = "0b00"; + parameter CH0_TDRV_SLICE2_SEL = "0b00"; + parameter CH0_TDRV_SLICE3_CUR = "0b00"; + parameter CH0_TDRV_SLICE3_SEL = "0b00"; + parameter CH0_TDRV_SLICE4_CUR = "0b00"; + parameter CH0_TDRV_SLICE4_SEL = "0b00"; + parameter CH0_TDRV_SLICE5_CUR = "0b00"; + parameter CH0_TDRV_SLICE5_SEL = "0b00"; + parameter CH0_TPWDNB = "0b0"; + parameter CH0_TX_CM_SEL = "0b00"; + parameter CH0_TX_DIV11_SEL = "0b0"; + parameter CH0_TX_GEAR_BYPASS = "0b0"; + parameter CH0_TX_GEAR_MODE = "0b0"; + parameter CH0_TX_POST_SIGN = "0b0"; + parameter CH0_TX_PRE_SIGN = "0b0"; + parameter CH0_UC_MODE = "0b0"; + parameter CH0_UDF_COMMA_A = "0b0000000000"; + parameter CH0_UDF_COMMA_B = "0b0000000000"; + parameter CH0_UDF_COMMA_MASK = "0b0000000000"; + parameter CH0_WA_BYPASS = "0b0"; + parameter CH0_WA_MODE = "0b0"; + parameter CH1_AUTO_CALIB_EN = "0b0"; + parameter CH1_AUTO_FACQ_EN = "0b0"; + parameter CH1_BAND_THRESHOLD = "0b000000"; + parameter CH1_CALIB_CK_MODE = "0b0"; + parameter CH1_CC_MATCH_1 = "0b0000000000"; + parameter CH1_CC_MATCH_2 = "0b0000000000"; + parameter CH1_CC_MATCH_3 = "0b0000000000"; + parameter CH1_CC_MATCH_4 = "0b0000000000"; + parameter CH1_CDR_CNT4SEL = "0b00"; + parameter CH1_CDR_CNT8SEL = "0b00"; + parameter CH1_CTC_BYPASS = "0b0"; + parameter CH1_DCOATDCFG = "0b00"; + parameter CH1_DCOATDDLY = "0b00"; + parameter CH1_DCOBYPSATD = "0b0"; + parameter CH1_DCOCALDIV = "0b000"; + parameter CH1_DCOCTLGI = "0b000"; + parameter CH1_DCODISBDAVOID = "0b0"; + parameter CH1_DCOFLTDAC = "0b00"; + parameter CH1_DCOFTNRG = "0b000"; + parameter CH1_DCOIOSTUNE = "0b000"; + parameter CH1_DCOITUNE = "0b00"; + parameter CH1_DCOITUNE4LSB = "0b000"; + parameter CH1_DCOIUPDNX2 = "0b0"; + parameter CH1_DCONUOFLSB = "0b000"; + parameter CH1_DCOSCALEI = "0b00"; + parameter CH1_DCOSTARTVAL = "0b000"; + parameter CH1_DCOSTEP = "0b00"; + parameter CH1_DEC_BYPASS = "0b0"; + parameter CH1_ENABLE_CG_ALIGN = "0b0"; + parameter CH1_ENC_BYPASS = "0b0"; + parameter CH1_FF_RX_F_CLK_DIS = "0b0"; + parameter CH1_FF_RX_H_CLK_EN = "0b0"; + parameter CH1_FF_TX_F_CLK_DIS = "0b0"; + parameter CH1_FF_TX_H_CLK_EN = "0b0"; + parameter CH1_GE_AN_ENABLE = "0b0"; + parameter CH1_INVERT_RX = "0b0"; + parameter CH1_INVERT_TX = "0b0"; + parameter CH1_LDR_CORE2TX_SEL = "0b0"; + parameter CH1_LDR_RX2CORE_SEL = "0b0"; + parameter CH1_LEQ_OFFSET_SEL = "0b0"; + parameter CH1_LEQ_OFFSET_TRIM = "0b000"; + parameter CH1_LSM_DISABLE = "0b0"; + parameter CH1_MATCH_2_ENABLE = "0b0"; + parameter CH1_MATCH_4_ENABLE = "0b0"; + parameter CH1_MIN_IPG_CNT = "0b00"; + parameter CH1_PCIE_EI_EN = "0b0"; + parameter CH1_PCIE_MODE = "0b0"; + parameter CH1_PCS_DET_TIME_SEL = "0b00"; + parameter CH1_PDEN_SEL = "0b0"; + parameter CH1_PRBS_ENABLE = "0b0"; + parameter CH1_PRBS_LOCK = "0b0"; + parameter CH1_PRBS_SELECTION = "0b0"; + parameter CH1_RATE_MODE_RX = "0b0"; + parameter CH1_RATE_MODE_TX = "0b0"; + parameter CH1_RCV_DCC_EN = "0b0"; + parameter CH1_REG_BAND_OFFSET = "0b0000"; + parameter CH1_REG_BAND_SEL = "0b000000"; + parameter CH1_REG_IDAC_EN = "0b0"; + parameter CH1_REG_IDAC_SEL = "0b0000000000"; + parameter CH1_REQ_EN = "0b0"; + parameter CH1_REQ_LVL_SET = "0b00"; + parameter CH1_RIO_MODE = "0b0"; + parameter CH1_RLOS_SEL = "0b0"; + parameter CH1_RPWDNB = "0b0"; + parameter CH1_RTERM_RX = "0b00000"; + parameter CH1_RTERM_TX = "0b00000"; + parameter CH1_RXIN_CM = "0b00"; + parameter CH1_RXTERM_CM = "0b00"; + parameter CH1_RX_DCO_CK_DIV = "0b000"; + parameter CH1_RX_DIV11_SEL = "0b0"; + parameter CH1_RX_GEAR_BYPASS = "0b0"; + parameter CH1_RX_GEAR_MODE = "0b0"; + parameter CH1_RX_LOS_CEQ = "0b00"; + parameter CH1_RX_LOS_EN = "0b0"; + parameter CH1_RX_LOS_HYST_EN = "0b0"; + parameter CH1_RX_LOS_LVL = "0b000"; + parameter CH1_RX_RATE_SEL = "0b0000"; + parameter CH1_RX_SB_BYPASS = "0b0"; + parameter CH1_SB_BYPASS = "0b0"; + parameter CH1_SEL_SD_RX_CLK = "0b0"; + parameter CH1_TDRV_DAT_SEL = "0b00"; + parameter CH1_TDRV_POST_EN = "0b0"; + parameter CH1_TDRV_PRE_EN = "0b0"; + parameter CH1_TDRV_SLICE0_CUR = "0b000"; + parameter CH1_TDRV_SLICE0_SEL = "0b00"; + parameter CH1_TDRV_SLICE1_CUR = "0b000"; + parameter CH1_TDRV_SLICE1_SEL = "0b00"; + parameter CH1_TDRV_SLICE2_CUR = "0b00"; + parameter CH1_TDRV_SLICE2_SEL = "0b00"; + parameter CH1_TDRV_SLICE3_CUR = "0b00"; + parameter CH1_TDRV_SLICE3_SEL = "0b00"; + parameter CH1_TDRV_SLICE4_CUR = "0b00"; + parameter CH1_TDRV_SLICE4_SEL = "0b00"; + parameter CH1_TDRV_SLICE5_CUR = "0b00"; + parameter CH1_TDRV_SLICE5_SEL = "0b00"; + parameter CH1_TPWDNB = "0b0"; + parameter CH1_TX_CM_SEL = "0b00"; + parameter CH1_TX_DIV11_SEL = "0b0"; + parameter CH1_TX_GEAR_BYPASS = "0b0"; + parameter CH1_TX_GEAR_MODE = "0b0"; + parameter CH1_TX_POST_SIGN = "0b0"; + parameter CH1_TX_PRE_SIGN = "0b0"; + parameter CH1_UC_MODE = "0b0"; + parameter CH1_UDF_COMMA_A = "0b0000000000"; + parameter CH1_UDF_COMMA_B = "0b0000000000"; + parameter CH1_UDF_COMMA_MASK = "0b0000000000"; + parameter CH1_WA_BYPASS = "0b0"; + parameter CH1_WA_MODE = "0b0"; + parameter D_BITCLK_FROM_ND_EN = "0b0"; + parameter D_BITCLK_LOCAL_EN = "0b0"; + parameter D_BITCLK_ND_EN = "0b0"; + parameter D_BUS8BIT_SEL = "0b0"; + parameter D_CDR_LOL_SET = "0b00"; + parameter D_CMUSETBIASI = "0b00"; + parameter D_CMUSETI4CPP = "0b0000"; + parameter D_CMUSETI4CPZ = "0b0000"; + parameter D_CMUSETI4VCO = "0b00"; + parameter D_CMUSETICP4P = "0b00"; + parameter D_CMUSETICP4Z = "0b000"; + parameter D_CMUSETINITVCT = "0b00"; + parameter D_CMUSETISCL4VCO = "0b000"; + parameter D_CMUSETP1GM = "0b000"; + parameter D_CMUSETP2AGM = "0b000"; + parameter D_CMUSETZGM = "0b000"; + parameter D_DCO_CALIB_TIME_SEL = "0b00"; + parameter D_HIGH_MARK = "0b0000"; + parameter D_IB_PWDNB = "0b0"; + parameter D_ISETLOS = "0b00000000"; + parameter D_LOW_MARK = "0b0000"; + parameter D_MACROPDB = "0b0"; + parameter D_PD_ISET = "0b00"; + parameter D_PLL_LOL_SET = "0b00"; + parameter D_REFCK_MODE = "0b000"; + parameter D_REQ_ISET = "0b000"; + parameter D_RG_EN = "0b0"; + parameter D_RG_SET = "0b00"; + parameter D_SETICONST_AUX = "0b00"; + parameter D_SETICONST_CH = "0b00"; + parameter D_SETIRPOLY_AUX = "0b00"; + parameter D_SETIRPOLY_CH = "0b00"; + parameter D_SETPLLRC = "0b000000"; + parameter D_SYNC_LOCAL_EN = "0b0"; + parameter D_SYNC_ND_EN = "0b0"; + parameter D_TXPLL_PWDNB = "0b0"; + parameter D_TX_VCO_CK_DIV = "0b000"; + parameter D_XGE_MODE = "0b0"; + +// These parameters don't do anything but are +// needed for compatibility with Diamond + parameter D_TX_MAX_RATE = "2.5"; + parameter D_RX_MAX_RATE = "2.5"; + parameter CH0_TXAMPLITUDE = "0d1300"; + parameter CH1_TXAMPLITUDE = "0d1300"; + parameter CH0_PROTOCOL = "8B10B"; + parameter CH1_PROTOCOL = "8B10B"; + parameter CH0_CDR_MAX_RATE = "2.5"; + parameter CH1_CDR_MAX_RATE = "2.5"; + parameter CH0_TXDEPRE = "DISABLED"; + parameter CH1_TXDEPRE = "DISABLED"; + parameter CH0_TXDEPOST = "DISABLED"; + parameter CH1_TXDEPOST = "DISABLED"; +endmodule + +(* blackbox *) +module EXTREFB ( + (* iopad_external_pin *) + input REFCLKP, + (* iopad_external_pin *) + input REFCLKN, + output REFCLKO +); + parameter REFCK_PWDNB = "0b0"; + parameter REFCK_RTERM = "0b0"; + parameter REFCK_DCBIAS_EN = "0b0"; +endmodule + +(* blackbox *) +module PCSCLKDIV ( + input CLKI, RST, SEL2, SEL1, SEL0, + output CDIV1, CDIVX +); + parameter GSR = "DISABLED"; +endmodule + +// Note: this module is not marked keep as we want it swept away in synth (sim use only) +(* blackbox *) +module PUR ( + input PUR +); + parameter RST_PULSE = 1; +endmodule + +(* blackbox, keep *) +module GSR ( + input GSR +); +endmodule + +(* blackbox, keep *) +module SGSR ( + input GSR, CLK +); +endmodule + + +(* blackbox *) +module PDPW16KD ( + input DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18, + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, + input ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 36; + parameter DATA_WIDTH_R = 36; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + parameter CLKWMUX = "CLKW"; + parameter CLKRMUX = "CLKR"; + +endmodule diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v new file mode 100644 index 00000000000..3363ed5710d --- /dev/null +++ b/techlibs/lattice/cells_bb_xo2.v @@ -0,0 +1,293 @@ +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +endmodule + +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v new file mode 100644 index 00000000000..3363ed5710d --- /dev/null +++ b/techlibs/lattice/cells_bb_xo3.v @@ -0,0 +1,293 @@ +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +endmodule + +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v new file mode 100644 index 00000000000..3363ed5710d --- /dev/null +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -0,0 +1,293 @@ +(* blackbox *) +module DP8KC( + input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, + input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, + input CEA, OCEA, CLKA, WEA, RSTA, + input CSA2, CSA1, CSA0, + output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, + + input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, + input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, + input CEB, OCEB, CLKB, WEB, RSTB, + input CSB2, CSB1, CSB0, + output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 +); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + + parameter GSR = "ENABLED"; + parameter INIT_DATA = "STATIC"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +endmodule + +(* blackbox *) +module EHXPLLJ ( + input CLKI, CLKFB, + input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, + input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, + input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, + input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, + input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, + output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, + output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, + output DPHSRC, CLKINTFB +); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; +endmodule + +(* blackbox *) +module OSCH #( + parameter NOM_FREQ = "2.08" +) ( + input STDBY, + output OSC, + output SEDSTDBY +); +endmodule + +(* blackbox *) +module DCCA ( + input CLKI, + input CE, + output CLKO +); +endmodule + +(* blackbox *) +module DCMA ( + input CLK0, + input CLK1, + input SEL, + output DCMOUT +); +endmodule + +(* blackbox *) +module PDPW8KC ( + input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, + input BE1, BE0, + input CEW, CLKW, CSW2, CSW1, CSW0, + input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, + input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, + output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 9; + + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + +endmodule + +(* blackbox *) +module SP8KC ( + input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, + input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, + input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, + output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 +); + parameter DATA_WIDTH = 9; + parameter GSR = "ENABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE = "0b000"; + + parameter WRITEMODE = "NORMAL"; + + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; +endmodule + +(* blackbox *) +module FIFO8KB ( + input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, + input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, + output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, + input EF, AEF, AFF, FF +); + parameter DATA_WIDTH_W = 18; + parameter DATA_WIDTH_R = 18; + + parameter GSR = "DISABLED"; + + parameter REGMODE = "NOREG"; + + parameter RESETMODE = "ASYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + + parameter CSDECODE_W = "0b00"; + parameter CSDECODE_R = "0b00"; + + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; + parameter FULLPOINTER1 = "0b00000000000000"; +endmodule diff --git a/techlibs/lattice/cells_ff.vh b/techlibs/lattice/cells_ff.vh new file mode 100644 index 00000000000..6b745f391ee --- /dev/null +++ b/techlibs/lattice/cells_ff.vh @@ -0,0 +1,40 @@ +// Diamond flip-flops +module FD1P3AX(input D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3AY(input D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3BX(input PD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3DX(input CD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3IX(input CD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1P3JX(input PD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module FD1S3AX(input D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .DI(D), .Q(Q)); endmodule +module FD1S3AY(input D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(|0), .DI(D), .Q(Q)); endmodule +module FD1S3BX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule +module FD1S3DX(input CD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule +module FD1S3IX(input CD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule +module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule + +// TODO: Diamond latches +// module FL1P3AY(); endmodule +// module FL1P3AZ(); endmodule +// module FL1P3BX(); endmodule +// module FL1P3DX(); endmodule +// module FL1P3IY(); endmodule +// module FL1P3JY(); endmodule +// module FL1S3AX(); endmodule +// module FL1S3AY(); endmodule + +// Diamond I/O registers +module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule + +module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule +module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule +module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule + +// TODO: Diamond I/O latches +// module IFS1S1B(input PD, D, SCLK, output Q); endmodule +// module IFS1S1D(input CD, D, SCLK, output Q); endmodule +// module IFS1S1I(input PD, D, SCLK, output Q); endmodule +// module IFS1S1J(input CD, D, SCLK, output Q); endmodule diff --git a/techlibs/lattice/cells_io.vh b/techlibs/lattice/cells_io.vh new file mode 100644 index 00000000000..220460c4467 --- /dev/null +++ b/techlibs/lattice/cells_io.vh @@ -0,0 +1,14 @@ +// Diamond I/O buffers +module IB ((* iopad_external_pin *) input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPU ((* iopad_external_pin *) input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module IBPD ((* iopad_external_pin *) input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule +module OB (input I, (* iopad_external_pin *) output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I)); endmodule +module OBZ (input I, T, (* iopad_external_pin *) output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPU(input I, T, (* iopad_external_pin *) output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule +module OBZPD(input I, T, (* iopad_external_pin *) 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 olvds (.A(I), .Z(OT), .ZN(OC)); endmodule +module BB (input I, T, output O, (* iopad_external_pin *) 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, (* iopad_external_pin *) 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, (* iopad_external_pin *) inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule +module ILVDS(input A, AN, (* iopad_external_pin *) output Z ); TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(A), .O(Z)); endmodule +module OLVDS(input A, (* iopad_external_pin *) output Z, output ZN); TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(Z), .I(A)); endmodule diff --git a/techlibs/lattice/cells_map.v b/techlibs/lattice/cells_map.v new file mode 100644 index 00000000000..4944ece4569 --- /dev/null +++ b/techlibs/lattice/cells_map.v @@ -0,0 +1,191 @@ +module \$_DFF_N_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_P_ (input D, C, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PN_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_NP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFFE_PP_ (input D, C, E, output Q); + parameter _TECHMAP_WIREINIT_Q_ = 1'bx; + generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + else + TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); + endgenerate + wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; +endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule +module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule + +module \$_ALDFF_NP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFF_PP_ (input C, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule + +module \$_ALDFFE_NPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_NPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPN_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule +module \$_ALDFFE_PPP_ (input C, E, L, AD, D, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMODE("PRLD"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(L), .DI(D), .M(AD), .Q(Q)); endmodule + +`include "cells_ff.vh" +`include "cells_io.vh" + +`ifndef NO_LUT +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + (* force_downto *) + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(1'b0), .D(A[0])); + end else + if (WIDTH == 2) begin + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(1'b0), .C(A[0]), .D(A[1])); + end else + if (WIDTH == 3) begin + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; + LUT4 #(.INIT(INIT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(1'b0), .B(A[0]), .C(A[1]), .D(A[2])); + end else + if (WIDTH == 4) begin + LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Z(Y), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + `ifndef NO_PFUMUX + end else + if (WIDTH == 5) begin + wire f0, f1; + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + PFUMX mux5(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(Y)); + end else + if (WIDTH == 6) begin + wire f0, f1, f2, f3, g0, g1; + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); + L6MUX21 mux6 (.D0(g0), .D1(g1), .SD(A[5]), .Z(Y)); + end else + if (WIDTH == 7) begin + wire f0, f1, f2, f3, f4, f5, f6, f7, g0, g1, g2, g3, h0, h1; + LUT4 #(.INIT(LUT[15: 0])) lut0 (.Z(f0), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[31:16])) lut1 (.Z(f1), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[47:32])) lut2 (.Z(f2), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[63:48])) lut3 (.Z(f3), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[79:64])) lut4 (.Z(f4), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[95:80])) lut5 (.Z(f5), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + LUT4 #(.INIT(LUT[111: 96])) lut6 (.Z(f6), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + LUT4 #(.INIT(LUT[127:112])) lut7 (.Z(f7), + .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + + PFUMX mux50(.ALUT(f1), .BLUT(f0), .C0(A[4]), .Z(g0)); + PFUMX mux51(.ALUT(f3), .BLUT(f2), .C0(A[4]), .Z(g1)); + PFUMX mux52(.ALUT(f5), .BLUT(f4), .C0(A[4]), .Z(g2)); + PFUMX mux53(.ALUT(f7), .BLUT(f6), .C0(A[4]), .Z(g3)); + L6MUX21 mux60 (.D0(g0), .D1(g1), .SD(A[5]), .Z(h0)); + L6MUX21 mux61 (.D0(g2), .D1(g3), .SD(A[5]), .Z(h1)); + L6MUX21 mux7 (.D0(h0), .D1(h1), .SD(A[6]), .Z(Y)); + `endif + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule +`endif diff --git a/techlibs/lattice/cells_sim_ecp5.v b/techlibs/lattice/cells_sim_ecp5.v new file mode 100644 index 00000000000..9439e3a5b31 --- /dev/null +++ b/techlibs/lattice/cells_sim_ecp5.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2c_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/cells_sim_xo2.v b/techlibs/lattice/cells_sim_xo2.v new file mode 100644 index 00000000000..54414287572 --- /dev/null +++ b/techlibs/lattice/cells_sim_xo2.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2d_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/cells_sim_xo3.v b/techlibs/lattice/cells_sim_xo3.v new file mode 100644 index 00000000000..54414287572 --- /dev/null +++ b/techlibs/lattice/cells_sim_xo3.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2d_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/cells_sim_xo3d.v b/techlibs/lattice/cells_sim_xo3d.v new file mode 100644 index 00000000000..54414287572 --- /dev/null +++ b/techlibs/lattice/cells_sim_xo3d.v @@ -0,0 +1,9 @@ +`include "common_sim.vh" +`include "ccu2d_sim.vh" + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/common_sim.vh b/techlibs/lattice/common_sim.vh new file mode 100644 index 00000000000..e6c2e57b507 --- /dev/null +++ b/techlibs/lattice/common_sim.vh @@ -0,0 +1,402 @@ +// --------------------------------------- + +(* abc9_lut=1, lib_whitebox *) +module LUT4(input A, B, C, D, output Z); + parameter [15:0] INIT = 16'h0000; + wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0]; + wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; + wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; + assign Z = A ? s1[1] : s1[0]; + specify + (A => Z) = 141; + (B => Z) = 275; + (C => Z) = 379; + (D => Z) = 379; + endspecify +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// cost of 5-input LUTs and is not intended to be instantiated +// LUT5 = 2x LUT4 + PFUMX +(* abc9_lut=2 *) +module \$__ABC9_LUT5 (input M0, D, C, B, A, output Z); + specify + (M0 => Z) = 151; + (D => Z) = 239; + (C => Z) = 373; + (B => Z) = 477; + (A => Z) = 477; + endspecify +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// of 6-input LUTs and is not intended to be instantiated +// LUT6 = 2x LUT5 + MUX2 +(* abc9_lut=4 *) +module \$__ABC9_LUT6 (input M1, M0, D, C, B, A, output Z); + specify + (M1 => Z) = 148; + (M0 => Z) = 292; + (D => Z) = 380; + (C => Z) = 514; + (B => Z) = 618; + (A => Z) = 618; + endspecify +endmodule + +// This is a placeholder for ABC9 to extract the area/delay +// of 7-input LUTs and is not intended to be instantiated +// LUT7 = 2x LUT6 + MUX2 +(* abc9_lut=8 *) +module \$__ABC9_LUT7 (input M2, M1, M0, D, C, B, A, output Z); + specify + (M2 => Z) = 148; + (M1 => Z) = 289; + (M0 => Z) = 433; + (D => Z) = 521; + (C => Z) = 655; + (B => Z) = 759; + (A => Z) = 759; + endspecify +endmodule + +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module L6MUX21 (input D0, D1, SD, output Z); + assign Z = SD ? D1 : D0; + specify + (D0 => Z) = 140; + (D1 => Z) = 141; + (SD => Z) = 148; + endspecify +endmodule + +// --------------------------------------- + +module TRELLIS_RAM16X2 ( + input DI0, DI1, + input WAD0, WAD1, WAD2, WAD3, + input WRE, WCK, + input RAD0, RAD1, RAD2, RAD3, + output DO0, DO1 +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter INITVAL_0 = 16'h0000; + parameter INITVAL_1 = 16'h0000; + + reg [1:0] mem[15:0]; + + integer i; + initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= {INITVAL_1[i], INITVAL_0[i]}; + end + + wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; + + reg muxwre; + always @(*) + case (WREMUX) + "1": muxwre = 1'b1; + "0": muxwre = 1'b0; + "INV": muxwre = ~WRE; + default: muxwre = WRE; + endcase + + + always @(posedge muxwck) + if (muxwre) + mem[{WAD3, WAD2, WAD1, WAD0}] <= {DI1, DI0}; + + assign {DO1, DO0} = mem[{RAD3, RAD2, RAD1, RAD0}]; +endmodule + +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module PFUMX (input ALUT, BLUT, C0, output Z); + assign Z = C0 ? ALUT : BLUT; + specify + (ALUT => Z) = 98; + (BLUT => Z) = 98; + (C0 => Z) = 151; + endspecify +endmodule + +// --------------------------------------- +(* abc9_box, lib_whitebox *) +module TRELLIS_DPR16X4 ( + input [3:0] DI, + input [3:0] WAD, + input WRE, + input WCK, + input [3:0] RAD, + output [3:0] DO +); + parameter WCKMUX = "WCK"; + parameter WREMUX = "WRE"; + parameter [63:0] INITVAL = 64'h0000000000000000; + + reg [3:0] mem[15:0]; + + integer i; + initial begin + for (i = 0; i < 16; i = i + 1) + mem[i] <= INITVAL[4*i +: 4]; + end + + wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; + + reg muxwre; + always @(*) + case (WREMUX) + "1": muxwre = 1'b1; + "0": muxwre = 1'b0; + "INV": muxwre = ~WRE; + default: muxwre = WRE; + endcase + + always @(posedge muxwck) + if (muxwre) + mem[WAD] <= DI; + + assign DO = mem[RAD]; + + specify + // TODO + (RAD *> DO) = 0; + endspecify +endmodule + +// --------------------------------------- + +(* abc9_box, lib_whitebox *) +module DPR16X4C ( + input [3:0] DI, + input WCK, WRE, + input [3:0] RAD, + input [3:0] WAD, + output [3:0] DO +); + // For legacy Lattice compatibility, INITIVAL is a hex + // string rather than a numeric parameter + parameter INITVAL = "0x0000000000000000"; + + function [63:0] convert_initval; + input [143:0] hex_initval; + reg done; + reg [63:0] temp; + reg [7:0] char; + integer i; + begin + done = 1'b0; + temp = 0; + for (i = 0; i < 16; i = i + 1) begin + if (!done) begin + char = hex_initval[8*i +: 8]; + if (char == "x") begin + done = 1'b1; + end else begin + if (char >= "0" && char <= "9") + temp[4*i +: 4] = char - "0"; + else if (char >= "A" && char <= "F") + temp[4*i +: 4] = 10 + char - "A"; + else if (char >= "a" && char <= "f") + temp[4*i +: 4] = 10 + char - "a"; + end + end + end + convert_initval = temp; + end + endfunction + + localparam conv_initval = convert_initval(INITVAL); + + reg [3:0] ram[0:15]; + integer i; + initial begin + for (i = 0; i < 15; i = i + 1) begin + ram[i] <= conv_initval[4*i +: 4]; + end + end + + always @(posedge WCK) + if (WRE) + ram[WAD] <= DI; + + assign DO = ram[RAD]; + + specify + // TODO + (RAD *> DO) = 0; + endspecify +endmodule + +// --------------------------------------- + +(* lib_whitebox *) +module LUT2(input A, B, output Z); + parameter [3:0] INIT = 4'h0; + wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0]; + assign Z = A ? s1[1] : s1[0]; +endmodule + +// --------------------------------------- + +`ifdef YOSYS +(* abc9_flop=(SRMODE != "ASYNC"), abc9_box=(SRMODE == "ASYNC"), lib_whitebox *) +`endif +module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); + parameter GSR = "ENABLED"; + parameter [127:0] CEMUX = "1"; + parameter CLKMUX = "CLK"; + parameter LSRMUX = "LSR"; + parameter SRMODE = "LSR_OVER_CE"; + parameter REGSET = "RESET"; + parameter [127:0] LSRMODE = "LSR"; + + wire muxce; + generate + case (CEMUX) + "1": assign muxce = 1'b1; + "0": assign muxce = 1'b0; + "INV": assign muxce = ~CE; + default: assign muxce = CE; + endcase + endgenerate + + wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; + wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; + wire srval; + generate + if (LSRMODE == "PRLD") + assign srval = M; + else + assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; + endgenerate + + initial Q = srval; + + generate + if (SRMODE == "ASYNC") begin + always @(posedge muxclk, posedge muxlsr) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end else begin + always @(posedge muxclk) + if (muxlsr) + Q <= srval; + else if (muxce) + Q <= DI; + end + endgenerate + + specify + $setup(DI, negedge CLK &&& CLKMUX == "INV", 0); + $setup(CE, negedge CLK &&& CLKMUX == "INV", 0); + $setup(LSR, negedge CLK &&& CLKMUX == "INV", 0); + $setup(DI, posedge CLK &&& CLKMUX != "INV", 0); + $setup(CE, posedge CLK &&& CLKMUX != "INV", 0); + $setup(LSR, posedge CLK &&& CLKMUX != "INV", 0); +`ifndef YOSYS + if (SRMODE == "ASYNC" && muxlsr && CLKMUX == "INV") (negedge CLK => (Q : srval)) = 0; + if (SRMODE == "ASYNC" && muxlsr && CLKMUX != "INV") (posedge CLK => (Q : srval)) = 0; +`else + if (SRMODE == "ASYNC" && muxlsr) (LSR => Q) = 0; // Technically, this should be an edge sensitive path + // but for facilitating a bypass box, let's pretend it's + // a simple path +`endif + if (!muxlsr && muxce && CLKMUX == "INV") (negedge CLK => (Q : DI)) = 0; + if (!muxlsr && muxce && CLKMUX != "INV") (posedge CLK => (Q : DI)) = 0; + endspecify +endmodule + +// --------------------------------------- +(* keep *) +module TRELLIS_IO( + (* iopad_external_pin *) + inout B, + input I, + input T, + output O +); + parameter DIR = "INPUT"; + reg T_pd; + always @(*) if (T === 1'bz) T_pd <= 1'b0; else T_pd <= T; + + generate + if (DIR == "INPUT") begin + assign B = 1'bz; + assign O = B; + end else if (DIR == "OUTPUT") begin + assign B = T_pd ? 1'bz : I; + assign O = 1'bx; + end else if (DIR == "BIDIR") begin + assign B = T_pd ? 1'bz : I; + assign O = B; + end else begin + ERROR_UNKNOWN_IO_MODE error(); + end + endgenerate + +endmodule + +// --------------------------------------- + +module INV(input A, output Z); + assign Z = !A; +endmodule + +// --------------------------------------- + +module TRELLIS_COMB( + input A, B, C, D, M, + input FCI, F1, FXA, FXB, + input WD, + input WAD0, WAD1, WAD2, WAD3, + input WRE, WCK, + output F, FCO, OFX +); + parameter MODE = "LOGIC"; + parameter INITVAL = 16'h0; + parameter CCU2_INJECT1 = "NO"; + parameter WREMUX = "WRE"; + parameter IS_Z1 = 1'b0; + + generate + if (MODE == "LOGIC") begin: mode_logic + LUT4 #(.INIT(INITVAL)) lut4 (.A(A), .B(B), .C(C), .D(D), .Z(F)); + end else if (MODE == "CCU2") begin: mode_ccu2 + wire l4o, l2o; + LUT4 #(.INIT(INITVAL)) lut4_0(.A(A), .B(B), .C(C), .D(D), .Z(l4o)); + LUT2 #(.INIT(INITVAL[3:0])) lut2_0(.A(A), .B(B), .Z(l2o)); + wire gated_cin_0 = (CCU2_INJECT1 == "YES") ? 1'b0 : FCI; + assign F = l4o ^ gated_cin_0; + wire gated_lut2_0 = (CCU2_INJECT1 == "YES") ? 1'b0 : l2o; + wire FCO = (~l4o & gated_lut2_0) | (l4o & FCI); + end else if (MODE == "DPRAM") begin: mode_dpram + reg [15:0] ram = INITVAL; + always @(posedge WCK) + if (WRE) + ram[{WAD3, WAD2, WAD1, WAD0}] <= WD; + assign F = ram[{A, C, B, D}]; + end else begin + $error("unsupported COMB mode %s", MODE); + end + + if (IS_Z1) + L6MUX21 lutx_mux (.D0(FXA), .D1(FXB), .SD(M), .Z(OFX)); + else + PFUMX lut5_mux (.ALUT(F1), .BLUT(F), .C0(M), .Z(OFX)); + endgenerate + +endmodule + +`ifndef NO_INCLUDES + +`include "cells_ff.vh" +`include "cells_io.vh" + +`endif diff --git a/techlibs/lattice/dsp_map_18x18.v b/techlibs/lattice/dsp_map_18x18.v new file mode 100644 index 00000000000..df54d1d9f9f --- /dev/null +++ b/techlibs/lattice/dsp_map_18x18.v @@ -0,0 +1,17 @@ +module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y); + + parameter A_WIDTH = 18; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 36; + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + + MULT18X18D _TECHMAP_REPLACE_ ( + .A0(A[0]), .A1(A[1]), .A2(A[2]), .A3(A[3]), .A4(A[4]), .A5(A[5]), .A6(A[6]), .A7(A[7]), .A8(A[8]), .A9(A[9]), .A10(A[10]), .A11(A[11]), .A12(A[12]), .A13(A[13]), .A14(A[14]), .A15(A[15]), .A16(A[16]), .A17(A[17]), + .B0(B[0]), .B1(B[1]), .B2(B[2]), .B3(B[3]), .B4(B[4]), .B5(B[5]), .B6(B[6]), .B7(B[7]), .B8(B[8]), .B9(B[9]), .B10(B[10]), .B11(B[11]), .B12(B[12]), .B13(B[13]), .B14(B[14]), .B15(B[15]), .B16(B[16]), .B17(B[17]), + .C17(1'b0), .C16(1'b0), .C15(1'b0), .C14(1'b0), .C13(1'b0), .C12(1'b0), .C11(1'b0), .C10(1'b0), .C9(1'b0), .C8(1'b0), .C7(1'b0), .C6(1'b0), .C5(1'b0), .C4(1'b0), .C3(1'b0), .C2(1'b0), .C1(1'b0), .C0(1'b0), + .SIGNEDA(A_SIGNED ? 1'b1 : 1'b0), .SIGNEDB(B_SIGNED ? 1'b1 : 1'b0), .SOURCEA(1'b0), .SOURCEB(1'b0), + + .P0(Y[0]), .P1(Y[1]), .P2(Y[2]), .P3(Y[3]), .P4(Y[4]), .P5(Y[5]), .P6(Y[6]), .P7(Y[7]), .P8(Y[8]), .P9(Y[9]), .P10(Y[10]), .P11(Y[11]), .P12(Y[12]), .P13(Y[13]), .P14(Y[14]), .P15(Y[15]), .P16(Y[16]), .P17(Y[17]), .P18(Y[18]), .P19(Y[19]), .P20(Y[20]), .P21(Y[21]), .P22(Y[22]), .P23(Y[23]), .P24(Y[24]), .P25(Y[25]), .P26(Y[26]), .P27(Y[27]), .P28(Y[28]), .P29(Y[29]), .P30(Y[30]), .P31(Y[31]), .P32(Y[32]), .P33(Y[33]), .P34(Y[34]), .P35(Y[35]) + ); +endmodule diff --git a/techlibs/lattice/latches_map.v b/techlibs/lattice/latches_map.v new file mode 100644 index 00000000000..c28f88cf767 --- /dev/null +++ b/techlibs/lattice/latches_map.v @@ -0,0 +1,11 @@ +module \$_DLATCH_N_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = !E ? D : Q; +endmodule + +module \$_DLATCH_P_ (E, D, Q); + wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; + input E, D; + output Q = E ? D : Q; +endmodule diff --git a/techlibs/lattice/lutrams.txt b/techlibs/lattice/lutrams.txt new file mode 100644 index 00000000000..ea42d4fcb5e --- /dev/null +++ b/techlibs/lattice/lutrams.txt @@ -0,0 +1,12 @@ +ram distributed $__TRELLIS_DPR16X4_ { + abits 4; + width 4; + cost 4; + init any; + prune_rom; + port sw "W" { + clock anyedge; + } + port ar "R" { + } +} diff --git a/techlibs/lattice/lutrams_map.v b/techlibs/lattice/lutrams_map.v new file mode 100644 index 00000000000..3cb325f041e --- /dev/null +++ b/techlibs/lattice/lutrams_map.v @@ -0,0 +1,30 @@ +module $__TRELLIS_DPR16X4_(...); + +parameter INIT = 64'bx; +parameter PORT_W_CLK_POL = 1; + +input PORT_W_CLK; +input [3:0] PORT_W_ADDR; +input [3:0] PORT_W_WR_DATA; +input PORT_W_WR_EN; + +input [3:0] PORT_R_ADDR; +output [3:0] PORT_R_RD_DATA; + +localparam WCKMUX = PORT_W_CLK_POL ? "WCK" : "INV"; + +TRELLIS_DPR16X4 #( + .INITVAL(INIT), + .WCKMUX(WCKMUX), + .WREMUX("WRE") +) _TECHMAP_REPLACE_ ( + .RAD(PORT_R_ADDR), + .DO(PORT_R_RD_DATA), + + .WAD(PORT_W_ADDR), + .DI(PORT_W_WR_DATA), + .WCK(PORT_W_CLK), + .WRE(PORT_W_WR_EN) +); + +endmodule diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc new file mode 100644 index 00000000000..edca6855e08 --- /dev/null +++ b/techlibs/lattice/synth_lattice.cc @@ -0,0 +1,574 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2012 Claire Xenia Wolf + * Copyright (C) 2018 gatecat + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthLatticePass : public ScriptPass +{ + SynthLatticePass() : ScriptPass("synth_lattice", "synthesis for Lattice FPGAs") { } + + void on_register() override + { + RTLIL::constpad["synth_lattice.abc9.W"] = "300"; + } + + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_lattice [options]\n"); + log("\n"); + log("This command runs synthesis for Lattice FPGAs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -family \n"); + log(" run synthesis for the specified Lattice architecture\n"); + log(" generate the synthesis netlist for the specified family.\n"); + log(" supported values:\n"); + log(" - ecp5: ECP5\n"); + log(" - xo2: MachXO2\n"); + log(" - xo3: MachXO3L/LF\n"); + log(" - xo3d: MachXO3D\n"); + //log(" - xo: MachXO (EXPERIMENTAL)\n"); + //log(" - pm: Platform Manager (EXPERIMENTAL)\n"); + //log(" - pm2: Platform Manager 2 (EXPERIMENTAL)\n"); + //log(" - xp: LatticeXP (EXPERIMENTAL)\n"); + //log(" - xp2: LatticeXP2 (EXPERIMENTAL)\n"); + //log(" - ecp: LatticeECP/EC (EXPERIMENTAL)\n"); + //log(" - sm: LatticeSC/M (EXPERIMENTAL)\n"); + //log(" - ecp2: LatticeECP2/M (EXPERIMENTAL)\n"); + //log(" - ecp3: LatticeECP3 (EXPERIMENTAL)\n"); + //log(" - lifmd: LIFMD (EXPERIMENTAL)\n"); + //log(" - lifmdf: LIFMDF (EXPERIMENTAL)\n"); + log("\n"); + log(" -blif \n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -edif \n"); + log(" write the design to the specified EDIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -json \n"); + log(" write the design to the specified JSON file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -run :\n"); + log(" only run the commands between the labels (see below). an empty\n"); + log(" from label is synonymous to 'begin', and empty to label is\n"); + log(" synonymous to the end of the command list.\n"); + log("\n"); + log(" -noflatten\n"); + log(" do not flatten design before synthesis\n"); + log("\n"); + log(" -dff\n"); + log(" run 'abc'/'abc9' with -dff option\n"); + log("\n"); + log(" -retime\n"); + log(" run 'abc' with '-dff -D 1' options\n"); + log("\n"); + log(" -noccu2\n"); + log(" do not use CCU2 cells in output netlist\n"); + log("\n"); + log(" -nodffe\n"); + log(" do not use flipflops with CE in output netlist\n"); + log("\n"); + log(" -nobram\n"); + log(" do not use block RAM cells in output netlist\n"); + log("\n"); + log(" -nolutram\n"); + log(" do not use LUT RAM cells in output netlist\n"); + log("\n"); + log(" -nowidelut\n"); + log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); + log("\n"); + log(" -asyncprld\n"); + log(" use async PRLD mode to implement ALDFF (EXPERIMENTAL)\n"); + log("\n"); + log(" -abc2\n"); + log(" run two passes of 'abc' for slightly improved logic density\n"); + log("\n"); + log(" -abc9\n"); + log(" use new ABC9 flow (EXPERIMENTAL)\n"); + log("\n"); + log(" -vpr\n"); + log(" generate an output netlist (and BLIF file) suitable for VPR\n"); + log(" (this feature is experimental and incomplete)\n"); + log("\n"); + log(" -iopad\n"); + log(" insert IO buffers\n"); + log("\n"); + log(" -nodsp\n"); + log(" do not map multipliers to MULT18X18D\n"); + log("\n"); + log(" -no-rw-check\n"); + log(" marks all recognized read ports as \"return don't-care value on\n"); + log(" read/write collision\" (same result as setting the no_rw_check\n"); + log(" attribute on all memories).\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, blif_file, edif_file, json_file, family; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, vpr, no_rw_check, have_dsp; + string postfix, arith_map, brams_map, dsp_map; + + void clear_flags() override + { + top_opt = "-auto-top"; + blif_file = ""; + edif_file = ""; + json_file = ""; + family = ""; + noccu2 = false; + nodffe = false; + nobram = false; + nolutram = false; + nowidelut = false; + asyncprld = false; + flatten = true; + dff = false; + retime = false; + abc2 = false; + vpr = false; + abc9 = false; + iopad = false; + nodsp = false; + no_rw_check = false; + postfix = ""; + arith_map = ""; + brams_map = ""; + dsp_map = ""; + have_dsp = false; + } + + void execute(std::vector args, RTLIL::Design *design) override + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) { + family = args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-json" && argidx+1 < args.size()) { + json_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } + if (args[argidx] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-dff") { + dff = true; + continue; + } + if (args[argidx] == "-retime") { + retime = true; + continue; + } + if (args[argidx] == "-noccu2") { + noccu2 = true; + continue; + } + if (args[argidx] == "-nodffe") { + nodffe = true; + continue; + } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } + if (args[argidx] == "-asyncprld") { + asyncprld = true; + continue; + } + if (args[argidx] == "-nolutram" || /*deprecated alias*/ args[argidx] == "-nodram") { + nolutram = true; + continue; + } + if (args[argidx] == "-nowidelut" || /*deprecated alias*/ args[argidx] == "-nomux") { + nowidelut = true; + continue; + } + if (args[argidx] == "-abc2") { + abc2 = true; + continue; + } + if (args[argidx] == "-vpr") { + vpr = true; + continue; + } + if (args[argidx] == "-abc9") { + abc9 = true; + continue; + } + if (args[argidx] == "-iopad") { + iopad = true; + continue; + } + if (args[argidx] == "-nodsp") { + nodsp = true; + continue; + } + if (args[argidx] == "-no-rw-check") { + no_rw_check = true; + continue; + } + break; + } + extra_args(args, argidx, design); + + if (family.empty()) + log_cmd_error("Lattice family parameter must be set.\n"); + + if (family == "ecp5") { + postfix = "_ecp5"; + arith_map = "_ccu2c"; + brams_map = "_16kd"; + dsp_map = "_18x18"; + have_dsp = true; + } else if (family == "xo2" || + family == "xo3" || + family == "xo3d" /* || + family == "pm2"*/) { + postfix = "_" + family; + arith_map = "_ccu2d"; + brams_map = "_8kc"; + have_dsp = false; +/* } else if (family == "xo" || + family == "pm") { + } else if (family == "xp" || + family == "xp2" || + family == "ecp" || + family == "sm" || + family == "ecp2" || + family == "ecp3" || + family == "lifmd" || + family == "lifmdf") {*/ + } else + log_cmd_error("Invalid Lattice -family setting: '%s'.\n", family.c_str()); + + if (!design->full_selection()) + log_cmd_error("This command only operates on fully selected designs!\n"); + + if (abc9 && retime) + log_cmd_error("-retime option not currently compatible with -abc9!\n"); + + log_header(design, "Executing SYNTH_LATTICE pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() override + { + std::string no_rw_check_opt = ""; + if (no_rw_check) + no_rw_check_opt = " -no-rw-check"; + if (help_mode) + no_rw_check_opt = " [-no-rw-check]"; + + if (check_label("begin")) + { + run("read_verilog -lib -specify +/lattice/cells_sim" + postfix + ".v +/lattice/cells_bb" + postfix + ".v"); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (check_label("coarse")) + { + run("proc"); + if (flatten || help_mode) + run("flatten"); + run("tribuf -logic"); + run("deminout"); + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt -nodffe -nosdff"); + run("fsm"); + run("opt"); + run("wreduce"); + run("peepopt"); + run("opt_clean"); + run("share"); + run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4"); + run("opt_expr"); + run("opt_clean"); + if (have_dsp && !nodsp) { + run("techmap -map +/mul2dsp.v -map +/lattice/dsp_map" + dsp_map + ".v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=$__MUL18X18", "(unless -nodsp)"); + run("chtype -set $mul t:$__soft_mul", "(unless -nodsp)"); + } + run("alumacc"); + run("opt"); + run("memory -nomap" + no_rw_check_opt); + run("opt_clean"); + } + + if (check_label("map_ram")) + { + std::string args = ""; + if (nobram) + args += " -no-auto-block"; + if (nolutram) + args += " -no-auto-distributed"; + if (help_mode) + args += " [-no-auto-block] [-no-auto-distributed]"; + run("memory_libmap -lib +/lattice/lutrams.txt -lib +/lattice/brams" + brams_map + ".txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); + run("techmap -map +/lattice/lutrams_map.v -map +/lattice/brams_map" + brams_map + ".v"); + } + + if (check_label("map_ffram")) + { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map"); + run("opt -undriven -fine"); + } + + if (check_label("map_gates")) + { + if (noccu2) + run("techmap"); + else + run("techmap -map +/techmap.v -map +/lattice/arith_map" + arith_map + ".v"); + if (help_mode || iopad) { + run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); + run("attrmvcp -attr src -attr LOC t:OB %x:+[O] t:OBZ %x:+[O] t:BB %x:+[B]"); + run("attrmvcp -attr src -attr LOC -driven t:IB %x:+[I]"); + } + run("opt -fast"); + if (retime || help_mode) + run("abc -dff -D 1", "(only if -retime)"); + } + + if (check_label("map_ffs")) + { + run("opt_clean"); + std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r"; + if (help_mode) { + dfflegalize_args += " [-cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r]"; + } else if (!nodffe) { + dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r"; + } + if (help_mode) { + dfflegalize_args += " [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x]"; + } else if (asyncprld) { + dfflegalize_args += " -cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x"; + } else { + dfflegalize_args += " -cell $_DLATCH_?_ x"; + } + run("dfflegalize" + dfflegalize_args, "($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe)"); + if ((abc9 && dff) || help_mode) + run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff)"); + run("techmap -D NO_LUT -map +/lattice/cells_map.v"); + run("opt_expr -undriven -mux_undef"); + run("simplemap"); + run("lattice_gsr"); + run("attrmvcp -copy -attr syn_useioff"); + run("opt_clean"); + } + + if (check_label("map_luts")) + { + if (abc2 || help_mode) + run("abc", " (only if -abc2)"); + if (!asyncprld || help_mode) + run("techmap -map +/lattice/latches_map.v", "(skip if -asyncprld)"); + + if (abc9) { + std::string abc9_opts; + if (nowidelut) + abc9_opts += " -maxlut 4"; + std::string k = "synth_lattice.abc9.W"; + if (active_design && active_design->scratchpad.count(k)) + abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str()); + else + abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str()); + if (nowidelut) + abc9_opts += " -maxlut 4"; + if (dff) + abc9_opts += " -dff"; + run("abc9" + abc9_opts); + } else { + std::string abc_args = " -dress"; + if (nowidelut) + abc_args += " -lut 4"; + else + abc_args += " -lut 4:7"; + if (dff) + abc_args += " -dff"; + run("abc" + abc_args); + } + run("clean"); + } + + if (check_label("map_cells")) + { + if (help_mode) + run("techmap -map +/lattice/cells_map.v", "(skip if -vpr)"); + else if (!vpr) + run("techmap -map +/lattice/cells_map.v"); + run("opt_lut_ins -tech lattice"); + run("clean"); + } + + if (check_label("check")) + { + run("autoname"); + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + run("blackbox =A:whitebox"); + } + + if (check_label("blif")) + { + if (!blif_file.empty() || help_mode) { + if (vpr || help_mode) { + run(stringf("opt_clean -purge"), + " (vpr mode)"); + run(stringf("write_blif -attr -cname -conn -param %s", + help_mode ? "" : blif_file.c_str()), + " (vpr mode)"); + } + if (!vpr) + run(stringf("write_blif -gates -attr -param %s", + help_mode ? "" : blif_file.c_str()), + " (non-vpr mode)"); + } + } + + if (check_label("edif")) + { + if (!edif_file.empty() || help_mode) + run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); + } + + if (check_label("json")) + { + if (!json_file.empty() || help_mode) + run(stringf("write_json %s", help_mode ? "" : json_file.c_str())); + } + } +} SynthLatticePass; + +/* +struct SynthEcp5Pass : public Pass +{ + SynthEcp5Pass() : Pass("synth_ecp5", "synthesis for ECP5 FPGAs") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "ecp5"; + Pass::call(design, args); + } +} SynthEcp5Pass; +*/ + +struct SynthMachXO2Pass : public Pass +{ + SynthMachXO2Pass() : Pass("synth_machxo2", "synthesis for MachXO2 FPGAs.") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "xo2"; + Pass::call(design, args); + } +} SynthMachXO2Pass; + +struct SynthMachXO3Pass : public Pass +{ + SynthMachXO3Pass() : Pass("synth_machxo3", "synthesis for MachXO3 FPGAs.") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "xo3"; + Pass::call(design, args); + } +} SynthMachXO3Pass; + +struct SynthMachXO3DPass : public Pass +{ + SynthMachXO3DPass() : Pass("synth_machxo3d", "synthesis for MachXO3D FPGAs.") { } + + void execute(std::vector args, RTLIL::Design *design) override + { + args[0] = "synth_lattice"; + args.insert(args.begin()+1, std::string()); + args.insert(args.begin()+1, std::string()); + args[1] = "-family"; + args[2] = "xo3d"; + Pass::call(design, args); + } +} SynthMachXO3DPass; + +PRIVATE_NAMESPACE_END From 75fd706487d16c3d4cbd48665c86cef1c1f70959 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 10:54:17 +0200 Subject: [PATCH 260/303] delete machxo2 since it is now supported in lattice --- techlibs/machxo2/Makefile.inc | 14 -- techlibs/machxo2/arith_map.v | 90 ------- techlibs/machxo2/brams.txt | 50 ---- techlibs/machxo2/brams_map.v | 337 -------------------------- techlibs/machxo2/cells_bb.v | 227 ------------------ techlibs/machxo2/cells_map.v | 117 --------- techlibs/machxo2/cells_sim.v | 385 ------------------------------ techlibs/machxo2/synth_machxo2.cc | 297 ----------------------- 8 files changed, 1517 deletions(-) delete mode 100644 techlibs/machxo2/Makefile.inc delete mode 100644 techlibs/machxo2/arith_map.v delete mode 100644 techlibs/machxo2/brams.txt delete mode 100644 techlibs/machxo2/brams_map.v delete mode 100644 techlibs/machxo2/cells_bb.v delete mode 100644 techlibs/machxo2/cells_map.v delete mode 100644 techlibs/machxo2/cells_sim.v delete mode 100644 techlibs/machxo2/synth_machxo2.cc diff --git a/techlibs/machxo2/Makefile.inc b/techlibs/machxo2/Makefile.inc deleted file mode 100644 index cd4e27884fc..00000000000 --- a/techlibs/machxo2/Makefile.inc +++ /dev/null @@ -1,14 +0,0 @@ - -OBJS += techlibs/machxo2/synth_machxo2.o - -$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/cells_io.vh)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_map.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_sim.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/cells_bb.v)) - -$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams.txt)) -$(eval $(call add_share_file,share/machxo2,techlibs/ecp5/lutrams_map.v)) - -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams.txt)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/brams_map.v)) -$(eval $(call add_share_file,share/machxo2,techlibs/machxo2/arith_map.v)) diff --git a/techlibs/machxo2/arith_map.v b/techlibs/machxo2/arith_map.v deleted file mode 100644 index ab4a6b1da6c..00000000000 --- a/techlibs/machxo2/arith_map.v +++ /dev/null @@ -1,90 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * Copyright (C) 2018 gatecat - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -(* techmap_celltype = "$alu" *) -module _80_ecp5_alu (A, B, CI, BI, X, Y, CO); - parameter A_SIGNED = 0; - parameter B_SIGNED = 0; - parameter A_WIDTH = 1; - parameter B_WIDTH = 1; - parameter Y_WIDTH = 1; - - (* force_downto *) - input [A_WIDTH-1:0] A; - (* force_downto *) - input [B_WIDTH-1:0] B; - (* force_downto *) - output [Y_WIDTH-1:0] X, Y; - - input CI, BI; - (* force_downto *) - output [Y_WIDTH-1:0] CO; - - wire _TECHMAP_FAIL_ = Y_WIDTH <= 4; - - (* force_downto *) - wire [Y_WIDTH-1:0] A_buf, B_buf; - \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); - \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); - - function integer round_up2; - input integer N; - begin - round_up2 = ((N + 1) / 2) * 2; - end - endfunction - - localparam Y_WIDTH2 = round_up2(Y_WIDTH); - - (* force_downto *) - wire [Y_WIDTH2-1:0] AA = A_buf; - (* force_downto *) - wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf; - (* force_downto *) - wire [Y_WIDTH2-1:0] BX = B_buf; - (* force_downto *) - wire [Y_WIDTH2-1:0] C = {CO, CI}; - (* force_downto *) - wire [Y_WIDTH2-1:0] FCO, Y1; - - genvar i; - generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice - CCU2D #( - .INIT0(16'b0101_1010_1001_0110), - .INIT1(16'b0101_1010_1001_0110), - .INJECT1_0("NO"), - .INJECT1_1("NO") - ) ccu2d_i ( - .CIN(C[i]), - .A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b0), - .A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b0), - .S0(Y[i]), .S1(Y1[i]), - .COUT(FCO[i]) - ); - - assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); - if (i+1 < Y_WIDTH) begin - assign CO[i+1] = FCO[i]; - assign Y[i+1] = Y1[i]; - end - end endgenerate - - assign X = AA ^ BB; -endmodule diff --git a/techlibs/machxo2/brams.txt b/techlibs/machxo2/brams.txt deleted file mode 100644 index 3afbeda07e6..00000000000 --- a/techlibs/machxo2/brams.txt +++ /dev/null @@ -1,50 +0,0 @@ -ram block $__DP8KC_ { - abits 13; - widths 1 2 4 9 per_port; - cost 64; - init no_undef; - port srsw "A" "B" { - clock posedge; - clken; - portoption "WRITEMODE" "NORMAL" { - rdwr no_change; - } - portoption "WRITEMODE" "WRITETHROUGH" { - rdwr new; - } - portoption "WRITEMODE" "READBEFOREWRITE" { - rdwr old; - } - option "RESETMODE" "SYNC" { - rdsrst zero ungated block_wr; - } - option "RESETMODE" "ASYNC" { - rdarst zero; - } - rdinit zero; - } -} - -ram block $__PDPW8KC_ { - abits 13; - widths 1 2 4 9 18 per_port; - byte 9; - cost 64; - init no_undef; - port sr "R" { - clock posedge; - clken; - option "RESETMODE" "SYNC" { - rdsrst zero ungated; - } - option "RESETMODE" "ASYNC" { - rdarst zero; - } - rdinit zero; - } - port sw "W" { - width 18; - clock posedge; - clken; - } -} diff --git a/techlibs/machxo2/brams_map.v b/techlibs/machxo2/brams_map.v deleted file mode 100644 index 6783e5b2902..00000000000 --- a/techlibs/machxo2/brams_map.v +++ /dev/null @@ -1,337 +0,0 @@ -module $__DP8KC_ (...); - -parameter INIT = 0; -parameter OPTION_RESETMODE = "SYNC"; - -parameter PORT_A_WIDTH = 18; -parameter PORT_A_OPTION_WRITEMODE = "NORMAL"; - -input PORT_A_CLK; -input PORT_A_CLK_EN; -input PORT_A_WR_EN; -input PORT_A_RD_SRST; -input PORT_A_RD_ARST; -input [12:0] PORT_A_ADDR; -input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA; -output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA; - -parameter PORT_B_WIDTH = 18; -parameter PORT_B_OPTION_WRITEMODE = "NORMAL"; - -input PORT_B_CLK; -input PORT_B_CLK_EN; -input PORT_B_WR_EN; -input PORT_B_RD_SRST; -input PORT_B_RD_ARST; -input [12:0] PORT_B_ADDR; -input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA; -output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA; - -function [319:0] init_slice; - input integer idx; - integer i, j; - init_slice = 0; - for (i = 0; i < 16; i = i + 1) begin - init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; - end -endfunction - -wire [8:0] DOA; -wire [8:0] DOB; -wire [8:0] DIA = PORT_A_WR_DATA; -wire [8:0] DIB = PORT_B_WR_DATA; - -assign PORT_A_RD_DATA = DOA; -assign PORT_B_RD_DATA = DOB; - -DP8KC #( - .INITVAL_00(init_slice('h00)), - .INITVAL_01(init_slice('h01)), - .INITVAL_02(init_slice('h02)), - .INITVAL_03(init_slice('h03)), - .INITVAL_04(init_slice('h04)), - .INITVAL_05(init_slice('h05)), - .INITVAL_06(init_slice('h06)), - .INITVAL_07(init_slice('h07)), - .INITVAL_08(init_slice('h08)), - .INITVAL_09(init_slice('h09)), - .INITVAL_0A(init_slice('h0a)), - .INITVAL_0B(init_slice('h0b)), - .INITVAL_0C(init_slice('h0c)), - .INITVAL_0D(init_slice('h0d)), - .INITVAL_0E(init_slice('h0e)), - .INITVAL_0F(init_slice('h0f)), - .INITVAL_10(init_slice('h10)), - .INITVAL_11(init_slice('h11)), - .INITVAL_12(init_slice('h12)), - .INITVAL_13(init_slice('h13)), - .INITVAL_14(init_slice('h14)), - .INITVAL_15(init_slice('h15)), - .INITVAL_16(init_slice('h16)), - .INITVAL_17(init_slice('h17)), - .INITVAL_18(init_slice('h18)), - .INITVAL_19(init_slice('h19)), - .INITVAL_1A(init_slice('h1a)), - .INITVAL_1B(init_slice('h1b)), - .INITVAL_1C(init_slice('h1c)), - .INITVAL_1D(init_slice('h1d)), - .INITVAL_1E(init_slice('h1e)), - .INITVAL_1F(init_slice('h1f)), - .DATA_WIDTH_A(PORT_A_WIDTH), - .DATA_WIDTH_B(PORT_B_WIDTH), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .RESETMODE(OPTION_RESETMODE), - .ASYNC_RESET_RELEASE(OPTION_RESETMODE), - .CSDECODE_A("0b000"), - .CSDECODE_B("0b000"), - .WRITEMODE_A(PORT_A_OPTION_WRITEMODE), - .WRITEMODE_B(PORT_B_OPTION_WRITEMODE), - .GSR("AUTO") -) _TECHMAP_REPLACE_ ( - .CLKA(PORT_A_CLK), - .WEA(PORT_A_WR_EN), - .CEA(PORT_A_CLK_EN), - .OCEA(1'b1), - .RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST), - .CSA0(1'b0), - .CSA1(1'b0), - .CSA2(1'b0), - .ADA0(PORT_A_WIDTH == 9 ? 1'b1 : PORT_A_ADDR[0]), - .ADA1(PORT_A_ADDR[1]), - .ADA2(PORT_A_ADDR[2]), - .ADA3(PORT_A_ADDR[3]), - .ADA4(PORT_A_ADDR[4]), - .ADA5(PORT_A_ADDR[5]), - .ADA6(PORT_A_ADDR[6]), - .ADA7(PORT_A_ADDR[7]), - .ADA8(PORT_A_ADDR[8]), - .ADA9(PORT_A_ADDR[9]), - .ADA10(PORT_A_ADDR[10]), - .ADA11(PORT_A_ADDR[11]), - .ADA12(PORT_A_ADDR[12]), - .DIA0(DIA[0]), - .DIA1(DIA[1]), - .DIA2(DIA[2]), - .DIA3(DIA[3]), - .DIA4(DIA[4]), - .DIA5(DIA[5]), - .DIA6(DIA[6]), - .DIA7(DIA[7]), - .DIA8(DIA[8]), - .DOA0(DOA[0]), - .DOA1(DOA[1]), - .DOA2(DOA[2]), - .DOA3(DOA[3]), - .DOA4(DOA[4]), - .DOA5(DOA[5]), - .DOA6(DOA[6]), - .DOA7(DOA[7]), - .DOA8(DOA[8]), - - .CLKB(PORT_B_CLK), - .WEB(PORT_B_WR_EN), - .CEB(PORT_B_CLK_EN), - .OCEB(1'b1), - .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST), - .CSB0(1'b0), - .CSB1(1'b0), - .CSB2(1'b0), - .ADB0(PORT_B_WIDTH == 9 ? 1'b1 : PORT_B_ADDR[0]), - .ADB1(PORT_B_ADDR[1]), - .ADB2(PORT_B_ADDR[2]), - .ADB3(PORT_B_ADDR[3]), - .ADB4(PORT_B_ADDR[4]), - .ADB5(PORT_B_ADDR[5]), - .ADB6(PORT_B_ADDR[6]), - .ADB7(PORT_B_ADDR[7]), - .ADB8(PORT_B_ADDR[8]), - .ADB9(PORT_B_ADDR[9]), - .ADB10(PORT_B_ADDR[10]), - .ADB11(PORT_B_ADDR[11]), - .ADB12(PORT_B_ADDR[12]), - .DIB0(DIB[0]), - .DIB1(DIB[1]), - .DIB2(DIB[2]), - .DIB3(DIB[3]), - .DIB4(DIB[4]), - .DIB5(DIB[5]), - .DIB6(DIB[6]), - .DIB7(DIB[7]), - .DIB8(DIB[8]), - .DOB0(DOB[0]), - .DOB1(DOB[1]), - .DOB2(DOB[2]), - .DOB3(DOB[3]), - .DOB4(DOB[4]), - .DOB5(DOB[5]), - .DOB6(DOB[6]), - .DOB7(DOB[7]), - .DOB8(DOB[8]), -); - -endmodule - - -module $__PDPW8KC_ (...); - -parameter INIT = 0; -parameter OPTION_RESETMODE = "SYNC"; - -parameter PORT_R_WIDTH = 18; - -input PORT_R_CLK; -input PORT_R_CLK_EN; -input PORT_R_RD_SRST; -input PORT_R_RD_ARST; -input [12:0] PORT_R_ADDR; -output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA; - -parameter PORT_W_WIDTH = 18; -parameter PORT_W_WR_EN_WIDTH = 2; - -input PORT_W_CLK; -input PORT_W_CLK_EN; -input [12:0] PORT_W_ADDR; -input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN; -input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA; - -function [319:0] init_slice; - input integer idx; - integer i, j; - init_slice = 0; - for (i = 0; i < 16; i = i + 1) begin - init_slice[i*20+:18] = INIT[(idx * 16 + i) * 18+:18]; - end -endfunction - -wire [17:0] DI = PORT_W_WR_DATA; -wire [17:0] DO; - -assign PORT_R_RD_DATA = PORT_R_WIDTH == 18 ? DO : DO[17:9]; - -DP8KC #( - .INITVAL_00(init_slice('h00)), - .INITVAL_01(init_slice('h01)), - .INITVAL_02(init_slice('h02)), - .INITVAL_03(init_slice('h03)), - .INITVAL_04(init_slice('h04)), - .INITVAL_05(init_slice('h05)), - .INITVAL_06(init_slice('h06)), - .INITVAL_07(init_slice('h07)), - .INITVAL_08(init_slice('h08)), - .INITVAL_09(init_slice('h09)), - .INITVAL_0A(init_slice('h0a)), - .INITVAL_0B(init_slice('h0b)), - .INITVAL_0C(init_slice('h0c)), - .INITVAL_0D(init_slice('h0d)), - .INITVAL_0E(init_slice('h0e)), - .INITVAL_0F(init_slice('h0f)), - .INITVAL_10(init_slice('h10)), - .INITVAL_11(init_slice('h11)), - .INITVAL_12(init_slice('h12)), - .INITVAL_13(init_slice('h13)), - .INITVAL_14(init_slice('h14)), - .INITVAL_15(init_slice('h15)), - .INITVAL_16(init_slice('h16)), - .INITVAL_17(init_slice('h17)), - .INITVAL_18(init_slice('h18)), - .INITVAL_19(init_slice('h19)), - .INITVAL_1A(init_slice('h1a)), - .INITVAL_1B(init_slice('h1b)), - .INITVAL_1C(init_slice('h1c)), - .INITVAL_1D(init_slice('h1d)), - .INITVAL_1E(init_slice('h1e)), - .INITVAL_1F(init_slice('h1f)), - .DATA_WIDTH_A(PORT_W_WIDTH), - .DATA_WIDTH_B(PORT_R_WIDTH), - .REGMODE_A("NOREG"), - .REGMODE_B("NOREG"), - .RESETMODE(OPTION_RESETMODE), - .ASYNC_RESET_RELEASE(OPTION_RESETMODE), - .CSDECODE_A("0b000"), - .CSDECODE_B("0b000"), - .GSR("AUTO") -) _TECHMAP_REPLACE_ ( - .CLKA(PORT_W_CLK), - .WEA(PORT_W_WIDTH >= 9 ? 1'b1 : PORT_W_WR_EN[0]), - .CEA(PORT_W_CLK_EN), - .OCEA(1'b0), - .RSTA(1'b0), - .CSA0(1'b0), - .CSA1(1'b0), - .CSA2(1'b0), - .ADA0(PORT_W_WIDTH >= 9 ? PORT_W_WR_EN[0] : PORT_W_ADDR[0]), - .ADA1(PORT_W_WIDTH >= 18 ? PORT_W_WR_EN[1] : PORT_W_ADDR[1]), - .ADA2(PORT_W_ADDR[2]), - .ADA3(PORT_W_ADDR[3]), - .ADA4(PORT_W_ADDR[4]), - .ADA5(PORT_W_ADDR[5]), - .ADA6(PORT_W_ADDR[6]), - .ADA7(PORT_W_ADDR[7]), - .ADA8(PORT_W_ADDR[8]), - .ADA9(PORT_W_ADDR[9]), - .ADA10(PORT_W_ADDR[10]), - .ADA11(PORT_W_ADDR[11]), - .ADA12(PORT_W_ADDR[12]), - .DIA0(DI[0]), - .DIA1(DI[1]), - .DIA2(DI[2]), - .DIA3(DI[3]), - .DIA4(DI[4]), - .DIA5(DI[5]), - .DIA6(DI[6]), - .DIA7(DI[7]), - .DIA8(DI[8]), - .DIB0(DI[9]), - .DIB1(DI[10]), - .DIB2(DI[11]), - .DIB3(DI[12]), - .DIB4(DI[13]), - .DIB5(DI[14]), - .DIB6(DI[15]), - .DIB7(DI[16]), - .DIB8(DI[17]), - - .CLKB(PORT_R_CLK), - .WEB(1'b0), - .CEB(PORT_R_CLK_EN), - .OCEB(1'b1), - .RSTB(OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST), - .CSB0(1'b0), - .CSB1(1'b0), - .CSB2(1'b0), - .ADB0(PORT_R_ADDR[0]), - .ADB1(PORT_R_ADDR[1]), - .ADB2(PORT_R_ADDR[2]), - .ADB3(PORT_R_ADDR[3]), - .ADB4(PORT_R_ADDR[4]), - .ADB5(PORT_R_ADDR[5]), - .ADB6(PORT_R_ADDR[6]), - .ADB7(PORT_R_ADDR[7]), - .ADB8(PORT_R_ADDR[8]), - .ADB9(PORT_R_ADDR[9]), - .ADB10(PORT_R_ADDR[10]), - .ADB11(PORT_R_ADDR[11]), - .ADB12(PORT_R_ADDR[12]), - .DOA0(DO[0]), - .DOA1(DO[1]), - .DOA2(DO[2]), - .DOA3(DO[3]), - .DOA4(DO[4]), - .DOA5(DO[5]), - .DOA6(DO[6]), - .DOA7(DO[7]), - .DOA8(DO[8]), - .DOB0(DO[9]), - .DOB1(DO[10]), - .DOB2(DO[11]), - .DOB3(DO[12]), - .DOB4(DO[13]), - .DOB5(DO[14]), - .DOB6(DO[15]), - .DOB7(DO[16]), - .DOB8(DO[17]), -); - -endmodule diff --git a/techlibs/machxo2/cells_bb.v b/techlibs/machxo2/cells_bb.v deleted file mode 100644 index 3d047b1692a..00000000000 --- a/techlibs/machxo2/cells_bb.v +++ /dev/null @@ -1,227 +0,0 @@ -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); -endmodule - -(* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); -endmodule - -(* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); - parameter DATA_WIDTH_W = 18; - parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_W = "0b000"; - parameter CSDECODE_R = "0b000"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - -endmodule - -(* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); - parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE = "0b000"; - - parameter WRITEMODE = "NORMAL"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; -endmodule - -(* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); - parameter DATA_WIDTH_W = 18; - parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "ASYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_W = "0b00"; - parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; - parameter FULLPOINTER1 = "0b00000000000000"; -endmodule diff --git a/techlibs/machxo2/cells_map.v b/techlibs/machxo2/cells_map.v deleted file mode 100644 index 22994a634df..00000000000 --- a/techlibs/machxo2/cells_map.v +++ /dev/null @@ -1,117 +0,0 @@ -module \$_DFF_N_ (input D, C, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFF_P_ (input D, C, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_NN_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_PN_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_NP_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFFE_PP_ (input D, C, E, output Q); - parameter _TECHMAP_WIREINIT_Q_ = 1'bx; - generate if (_TECHMAP_WIREINIT_Q_ === 1'b1) - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - else - TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); - endgenerate - wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; -endmodule - -module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_SDFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_DFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_DFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_DFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_SDFFE_NP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_NP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$_SDFFE_NP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_NP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP0N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule -module \$_SDFFE_PP1N_ (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; endmodule - -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - input [WIDTH-1:0] A; - output Y; - - localparam rep = 1<<(4-WIDTH); - wire [3:0] I; - - generate - if(WIDTH == 1) begin - assign I = {1'b0, 1'b0, 1'b0, A[0]}; - end else if(WIDTH == 2) begin - assign I = {1'b0, 1'b0, A[1], A[0]}; - end else if(WIDTH == 3) begin - assign I = {1'b0, A[2], A[1], A[0]}; - end else if(WIDTH == 4) begin - assign I = {A[3], A[2], A[1], A[0]}; - end else begin - wire _TECHMAP_FAIL_ = 1; - end - endgenerate - - LUT4 #(.INIT({rep{LUT}})) _TECHMAP_REPLACE_ (.A(I[0]), .B(I[1]), .C(I[2]), .D(I[3]), .Z(Y)); -endmodule - -`include "cells_io.vh" diff --git a/techlibs/machxo2/cells_sim.v b/techlibs/machxo2/cells_sim.v deleted file mode 100644 index 8e0e411791c..00000000000 --- a/techlibs/machxo2/cells_sim.v +++ /dev/null @@ -1,385 +0,0 @@ -module LUT2(input A, B, output Z); - parameter [3:0] INIT = 4'h0; - wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0]; - assign Z = A ? s1[1] : s1[0]; -endmodule - -module LUT4 #( - parameter [15:0] INIT = 0 -) ( - input A, B, C, D, - output Z -); - // This form of LUT propagates as few x's as possible. - wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0]; - wire [3:0] s2 = C ? s3[ 7:4] : s3[3:0]; - wire [1:0] s1 = B ? s2[ 3:2] : s2[1:0]; - assign Z = A ? s1[1] : s1[0]; -endmodule - -module TRELLIS_FF #( - parameter GSR = "ENABLED", - parameter CEMUX = "1", - parameter CLKMUX = "0", - parameter LSRMUX = "LSR", - parameter LSRONMUX = "LSRMUX", - parameter SRMODE = "LSR_OVER_CE", - parameter REGSET = "SET", - parameter REGMODE = "FF" -) ( - input CLK, DI, LSR, CE, - output reg Q -); - - wire muxce; - generate - case (CEMUX) - "1": assign muxce = 1'b1; - "0": assign muxce = 1'b0; - "INV": assign muxce = ~CE; - default: assign muxce = CE; - endcase - endgenerate - - wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; - wire muxlsron = (LSRONMUX == "LSRMUX") ? muxlsr : 1'b0; - wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; - wire srval = (REGSET == "SET") ? 1'b1 : 1'b0; - - initial Q = srval; - - generate - if (REGMODE == "FF") begin - if (SRMODE == "ASYNC") begin - always @(posedge muxclk, posedge muxlsron) - if (muxlsron) - Q <= srval; - else if (muxce) - Q <= DI; - end else begin - always @(posedge muxclk) - if (muxlsron) - Q <= srval; - else if (muxce) - Q <= DI; - end - end else if (REGMODE == "LATCH") begin - ERROR_UNSUPPORTED_FF_MODE error(); - end else begin - ERROR_UNKNOWN_FF_MODE error(); - end - endgenerate -endmodule - -/* For consistency with ECP5; represents F0/F1 => OFX0 mux in a slice. */ -module PFUMX (input ALUT, BLUT, C0, output Z); - assign Z = C0 ? ALUT : BLUT; -endmodule - -/* For consistency with ECP5; represents FXA/FXB => OFX1 mux in a slice. */ -module L6MUX21 (input D0, D1, SD, output Z); - assign Z = SD ? D1 : D0; -endmodule - -/* For consistency, input order matches TRELLIS_SLICE even though the BELs in -prjtrellis were filled in clockwise order from bottom left. */ -module TRELLIS_SLICE #( - parameter MODE = "LOGIC", - parameter GSR = "ENABLED", - parameter SRMODE = "LSR_OVER_CE", - parameter CEMUX = "1", - parameter CLKMUX = "0", - parameter LSRMUX = "LSR", - parameter LSRONMUX = "LSRMUX", - parameter LUT0_INITVAL = 16'hFFFF, - parameter LUT1_INITVAL = 16'hFFFF, - parameter REGMODE = "FF", - parameter REG0_SD = "1", - parameter REG1_SD = "1", - parameter REG0_REGSET = "SET", - parameter REG1_REGSET = "SET", - parameter CCU2_INJECT1_0 = "YES", - parameter CCU2_INJECT1_1 = "YES", - parameter WREMUX = "INV" -) ( - input A0, B0, C0, D0, - input A1, B1, C1, D1, - input M0, M1, - input FCI, FXA, FXB, - - input CLK, LSR, CE, - input DI0, DI1, - - input WD0, WD1, - input WAD0, WAD1, WAD2, WAD3, - input WRE, WCK, - - output F0, Q0, - output F1, Q1, - output FCO, OFX0, OFX1, - - output WDO0, WDO1, WDO2, WDO3, - output WADO0, WADO1, WADO2, WADO3 -); - - generate - if (MODE == "LOGIC") begin - L6MUX21 FXMUX (.D0(FXA), .D1(FXB), .SD(M1), .Z(OFX1)); - - wire k0; - wire k1; - PFUMX K0K1MUX (.ALUT(k1), .BLUT(k0), .C0(M0), .Z(OFX0)); - - LUT4 #(.INIT(LUT0_INITVAL)) LUT_0 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k0)); - LUT4 #(.INIT(LUT1_INITVAL)) LUT_1 (.A(A0), .B(B0), .C(C0), .D(D0), .Z(k1)); - - assign F0 = k0; - assign F1 = k1; - end else if (MODE == "CCU2") begin - ERROR_UNSUPPORTED_SLICE_MODE error(); - end else if (MODE == "DPRAM") begin - ERROR_UNSUPPORTED_SLICE_MODE error(); - end else begin - ERROR_UNKNOWN_SLICE_MODE error(); - end - endgenerate - - /* Reg can be fed either by M, or DI inputs; DI inputs muxes OFX and F - outputs (in other words, feeds back into TRELLIS_SLICE). */ - wire di0 = (REG0_SD == "1") ? DI0 : M0; - wire di1 = (REG1_SD == "1") ? DI1 : M1; - - TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), - .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG0_REGSET), - .REGMODE(REGMODE)) REG_0 (.CLK(CLK), .DI(di0), .LSR(LSR), .CE(CE), .Q(Q0)); - TRELLIS_FF#(.GSR(GSR), .CEMUX(CEMUX), .CLKMUX(CLKMUX), .LSRMUX(LSRMUX), - .LSRONMUX(LSRONMUX), .SRMODE(SRMODE), .REGSET(REG1_REGSET), - .REGMODE(REGMODE)) REG_1 (.CLK(CLK), .DI(di1), .LSR(LSR), .CE(CE), .Q(Q1)); -endmodule - -module TRELLIS_IO #( - parameter DIR = "INPUT" -) ( - (* iopad_external_pin *) - inout B, - input I, T, - output O -); - generate - if (DIR == "INPUT") begin - assign O = B; - end else if (DIR == "OUTPUT") begin - assign B = T ? 1'bz : I; - end else if (DIR == "BIDIR") begin - assign B = T ? 1'bz : I; - assign O = B; - end else begin - ERROR_UNKNOWN_IO_MODE error(); - end - endgenerate -endmodule - -(* abc9_box, lib_whitebox *) -module TRELLIS_DPR16X4 ( - input [3:0] DI, - input [3:0] WAD, - input WRE, - input WCK, - input [3:0] RAD, - output [3:0] DO -); - parameter WCKMUX = "WCK"; - parameter WREMUX = "WRE"; - parameter [63:0] INITVAL = 64'h0000000000000000; - - reg [3:0] mem[15:0]; - - integer i; - initial begin - for (i = 0; i < 16; i = i + 1) - mem[i] <= INITVAL[4*i +: 4]; - end - - wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; - - reg muxwre; - always @(*) - case (WREMUX) - "1": muxwre = 1'b1; - "0": muxwre = 1'b0; - "INV": muxwre = ~WRE; - default: muxwre = WRE; - endcase - - always @(posedge muxwck) - if (muxwre) - mem[WAD] <= DI; - - assign DO = mem[RAD]; - - specify - // TODO - (RAD *> DO) = 0; - endspecify -endmodule - -(* abc9_box, lib_whitebox *) -module DPR16X4C ( - input [3:0] DI, - input WCK, WRE, - input [3:0] RAD, - input [3:0] WAD, - output [3:0] DO -); - parameter INITVAL = "0x0000000000000000"; - - function [63:0] convert_initval; - input [143:0] hex_initval; - reg done; - reg [63:0] temp; - reg [7:0] char; - integer i; - begin - done = 1'b0; - temp = 0; - for (i = 0; i < 16; i = i + 1) begin - if (!done) begin - char = hex_initval[8*i +: 8]; - if (char == "x") begin - done = 1'b1; - end else begin - if (char >= "0" && char <= "9") - temp[4*i +: 4] = char - "0"; - else if (char >= "A" && char <= "F") - temp[4*i +: 4] = 10 + char - "A"; - else if (char >= "a" && char <= "f") - temp[4*i +: 4] = 10 + char - "a"; - end - end - end - convert_initval = temp; - end - endfunction - - localparam conv_initval = convert_initval(INITVAL); - - reg [3:0] ram[0:15]; - integer i; - initial begin - for (i = 0; i < 15; i = i + 1) begin - ram[i] <= conv_initval[4*i +: 4]; - end - end - - always @(posedge WCK) - if (WRE) - ram[WAD] <= DI; - - assign DO = ram[RAD]; -endmodule - -// --------------------------------------- -(* lib_whitebox *) -module CCU2D ( - input CIN, - input A0, B0, C0, D0, A1, B1, C1, D1, - output S0, S1, - output COUT -); - parameter [15:0] INIT0 = 16'h0000; - parameter [15:0] INIT1 = 16'h0000; - parameter INJECT1_0 = "YES"; - parameter INJECT1_1 = "YES"; - - // First half - wire LUT4_0, LUT2_0; - LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0)); - LUT2 #(.INIT(~INIT0[15:12])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0)); - wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN; - assign S0 = LUT4_0 ^ gated_cin_0; - - wire gated_lut2_0 = (INJECT1_0 == "YES") ? 1'b0 : LUT2_0; - wire cout_0 = (~LUT4_0 & gated_lut2_0) | (LUT4_0 & CIN); - - // Second half - wire LUT4_1, LUT2_1; - LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1)); - LUT2 #(.INIT(~INIT1[15:12])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1)); - wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0; - assign S1 = LUT4_1 ^ gated_cin_1; - - wire gated_lut2_1 = (INJECT1_1 == "YES") ? 1'b0 : LUT2_1; - assign COUT = (~LUT4_1 & gated_lut2_1) | (LUT4_1 & cout_0); -endmodule - -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; - - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; -endmodule - -`ifndef NO_INCLUDES - -`include "cells_io.vh" - -`endif diff --git a/techlibs/machxo2/synth_machxo2.cc b/techlibs/machxo2/synth_machxo2.cc deleted file mode 100644 index 907c6659ed8..00000000000 --- a/techlibs/machxo2/synth_machxo2.cc +++ /dev/null @@ -1,297 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2020 William D. Jones - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" -#include "kernel/celltypes.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct SynthMachXO2Pass : public ScriptPass -{ - SynthMachXO2Pass() : ScriptPass("synth_machxo2", "synthesis for MachXO2 FPGAs. This work is experimental.") { } - - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" synth_machxo2 [options]\n"); - log("\n"); - log("This command runs synthesis for MachXO2 FPGAs.\n"); - log("\n"); - log(" -top \n"); - log(" use the specified module as top module\n"); - log("\n"); - log(" -blif \n"); - log(" write the design to the specified BLIF file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -edif \n"); - log(" write the design to the specified EDIF file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -json \n"); - log(" write the design to the specified JSON file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -run :\n"); - log(" only run the commands between the labels (see below). an empty\n"); - log(" from label is synonymous to 'begin', and empty to label is\n"); - log(" synonymous to the end of the command list.\n"); - log("\n"); - log(" -nobram\n"); - log(" do not use block RAM cells in output netlist\n"); - log("\n"); - log(" -nolutram\n"); - log(" do not use LUT RAM cells in output netlist\n"); - log("\n"); - log(" -noflatten\n"); - log(" do not flatten design before synthesis\n"); - log("\n"); - log(" -noiopad\n"); - log(" do not insert IO buffers\n"); - log("\n"); - log(" -ccu2\n"); - log(" use CCU2 cells in output netlist\n"); - log("\n"); - log(" -vpr\n"); - log(" generate an output netlist (and BLIF file) suitable for VPR\n"); - log(" (this feature is experimental and incomplete)\n"); - log("\n"); - log("\n"); - log("The following commands are executed by this synthesis command:\n"); - help_script(); - log("\n"); - } - - string top_opt, blif_file, edif_file, json_file; - bool ccu2, nobram, nolutram, flatten, vpr, noiopad; - - void clear_flags() override - { - top_opt = "-auto-top"; - blif_file = ""; - edif_file = ""; - json_file = ""; - ccu2 = false; - nobram = false; - nolutram = false; - flatten = true; - vpr = false; - noiopad = false; - } - - void execute(std::vector args, RTLIL::Design *design) override - { - string run_from, run_to; - clear_flags(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-top" && argidx+1 < args.size()) { - top_opt = "-top " + args[++argidx]; - continue; - } - if (args[argidx] == "-blif" && argidx+1 < args.size()) { - blif_file = args[++argidx]; - continue; - } - if (args[argidx] == "-edif" && argidx+1 < args.size()) { - edif_file = args[++argidx]; - continue; - } - if (args[argidx] == "-json" && argidx+1 < args.size()) { - json_file = args[++argidx]; - continue; - } - if (args[argidx] == "-run" && argidx+1 < args.size()) { - size_t pos = args[argidx+1].find(':'); - if (pos == std::string::npos) - break; - run_from = args[++argidx].substr(0, pos); - run_to = args[argidx].substr(pos+1); - continue; - } - if (args[argidx] == "-flatten") { - flatten = true; - continue; - } - if (args[argidx] == "-noflatten") { - flatten = false; - continue; - } - if (args[argidx] == "-nobram") { - nobram = true; - continue; - } - if (args[argidx] == "-nolutram") { - nolutram = true; - continue; - } - if (args[argidx] == "-noiopad") { - noiopad = true; - continue; - } - if (args[argidx] == "-ccu2") { - ccu2 = true; - continue; - } - if (args[argidx] == "-vpr") { - vpr = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - if (!design->full_selection()) - log_cmd_error("This command only operates on fully selected designs!\n"); - - log_header(design, "Executing SYNTH_MACHXO2 pass.\n"); - log_push(); - - run_script(design, run_from, run_to); - - log_pop(); - } - - void script() override - { - if (check_label("begin")) - { - run("read_verilog -lib -icells +/machxo2/cells_sim.v +/machxo2/cells_bb.v"); - run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); - } - - if (check_label("flatten", "(unless -noflatten)")) - { - if (flatten || help_mode) { - run("proc"); - run("flatten"); - run("tribuf -logic"); - run("deminout"); - } - } - - if (check_label("coarse")) - { - run("synth -run coarse"); - } - - if (check_label("map_ram")) - { - std::string args = ""; - if (nobram) - args += " -no-auto-block"; - if (nolutram) - args += " -no-auto-distributed"; - if (help_mode) - args += " [-no-auto-block] [-no-auto-distributed]"; - run("memory_libmap -lib +/machxo2/lutrams.txt -lib +/machxo2/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)"); - run("techmap -map +/machxo2/lutrams_map.v -map +/machxo2/brams_map.v"); - } - - if (check_label("fine")) - { - run("opt -fast -mux_undef -undriven -fine"); - run("memory_map"); - run("opt -undriven -fine"); - } - - if (check_label("map_gates", "(unless -noiopad)")) - { - if (!ccu2) - run("techmap"); - else - run("techmap -map +/techmap.v -map +/machxo2/arith_map.v"); - if (!noiopad || help_mode) - { - run("iopadmap -bits -outpad OB I:O -inpad IB O:I -toutpad OBZ ~T:I:O -tinoutpad BB ~T:O:I:B A:top", "(only if '-iopad')"); - run("attrmvcp -attr src -attr LOC t:OB %x:+[O] t:OBZ %x:+[O] t:BB %x:+[B]"); - run("attrmvcp -attr src -attr LOC -driven t:IB %x:+[I]"); - } - } - - if (check_label("map_ffs")) - { - run("opt_clean"); - std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r"; - run("dfflegalize" + dfflegalize_args); - run("techmap -D NO_LUT -map +/machxo2/cells_map.v"); - run("opt_expr -undriven -mux_undef"); - run("simplemap"); - run("lattice_gsr"); - run("attrmvcp -copy -attr syn_useioff"); - run("opt_clean"); - } - - if (check_label("map_luts")) - { - run("abc -lut 4 -dress"); - run("clean"); - } - - if (check_label("map_cells")) - { - run("techmap -map +/machxo2/cells_map.v"); - run("clean"); - } - - if (check_label("check")) - { - run("hierarchy -check"); - run("stat"); - run("blackbox =A:whitebox"); - } - - if (check_label("blif")) - { - if (!blif_file.empty() || help_mode) { - if (vpr || help_mode) { - run(stringf("opt_clean -purge"), - " (vpr mode)"); - run(stringf("write_blif -attr -cname -conn -param %s", - help_mode ? "" : blif_file.c_str()), - " (vpr mode)"); - } - if (!vpr) - run(stringf("write_blif -gates -attr -param %s", - help_mode ? "" : blif_file.c_str()), - " (non-vpr mode)"); - } - } - - if (check_label("edif")) - { - if (!edif_file.empty() || help_mode) - run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); - } - - if (check_label("json")) - { - if (!json_file.empty() || help_mode) - run(stringf("write_json %s", help_mode ? "" : json_file.c_str())); - } - } -} SynthMachXO2Pass; - -PRIVATE_NAMESPACE_END From ea50d96135ad5c337f41169c08383c460bf97e83 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 10:54:29 +0200 Subject: [PATCH 261/303] fixed tests --- tests/arch/machxo2/add_sub.ys | 2 +- tests/arch/machxo2/adffs.ys | 8 ++++---- tests/arch/machxo2/counter.ys | 2 +- tests/arch/machxo2/dffs.ys | 6 +++--- tests/arch/machxo2/fsm.ys | 2 +- tests/arch/machxo2/logic.ys | 2 +- tests/arch/machxo2/lutram.ys | 2 +- tests/arch/machxo2/mux.ys | 8 ++++---- tests/arch/machxo2/shifter.ys | 2 +- tests/arch/machxo2/tribuf.ys | 7 +++---- 10 files changed, 20 insertions(+), 21 deletions(-) diff --git a/tests/arch/machxo2/add_sub.ys b/tests/arch/machxo2/add_sub.ys index 97ee90fbbe2..6897363aaee 100644 --- a/tests/arch/machxo2/add_sub.ys +++ b/tests/arch/machxo2/add_sub.ys @@ -1,7 +1,7 @@ read_verilog ../common/add_sub.v hierarchy -top top proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 10 t:LUT4 diff --git a/tests/arch/machxo2/adffs.ys b/tests/arch/machxo2/adffs.ys index a9f8980c6e4..f1134a6ac67 100644 --- a/tests/arch/machxo2/adffs.ys +++ b/tests/arch/machxo2/adffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -12,7 +12,7 @@ select -assert-none t:TRELLIS_FF %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adffn # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -22,7 +22,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -32,7 +32,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/machxo2/cells_sim.v synth_machxo2 -noiopad # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF diff --git a/tests/arch/machxo2/counter.ys b/tests/arch/machxo2/counter.ys index 54ee80066ff..11560b551fc 100644 --- a/tests/arch/machxo2/counter.ys +++ b/tests/arch/machxo2/counter.ys @@ -2,7 +2,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -assert -multiclock -map +/machxo2/cells_sim.v synth_machxo2 -ccu2 -noiopad # equivalency check +equiv_opt -assert -multiclock -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 4 t:CCU2D diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 29dcafe2383..663a64294bf 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top dff proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -12,8 +12,8 @@ select -assert-none t:TRELLIS_FF t:TRELLIS_IO %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module -select -assert-count 2 t:TRELLIS_FF t:LUT4 +select -assert-count 1 t:TRELLIS_FF t:LUT4 select -assert-none t:TRELLIS_FF t:LUT4 t:TRELLIS_IO %% t:* %D diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index a61357fcdd2..70e1a632bdf 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/machxo2/cells_sim.v synth_machxo2 +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys index 0cf57310c81..5c799530519 100644 --- a/tests/arch/machxo2/logic.ys +++ b/tests/arch/machxo2/logic.ys @@ -1,7 +1,7 @@ read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 9 t:LUT4 diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys index dc6b86fd349..8f1918587c9 100644 --- a/tests/arch/machxo2/lutram.ys +++ b/tests/arch/machxo2/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/machxo2/cells_sim.v synth_machxo2 -noiopad +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut memory opt -full diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 27bffbe63aa..4fa1bd2fcc8 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT4 @@ -12,7 +12,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 2 t:LUT4 @@ -22,7 +22,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 5 t:LUT4 @@ -32,7 +32,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-max 12 t:LUT4 diff --git a/tests/arch/machxo2/shifter.ys b/tests/arch/machxo2/shifter.ys index bff881fb734..f6440c025e8 100644 --- a/tests/arch/machxo2/shifter.ys +++ b/tests/arch/machxo2/shifter.ys @@ -2,7 +2,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys index 840979439f8..08c86008da5 100644 --- a/tests/arch/machxo2/tribuf.ys +++ b/tests/arch/machxo2/tribuf.ys @@ -2,9 +2,8 @@ read_verilog ../common/tribuf.v hierarchy -top tristate proc flatten -equiv_opt -assert -map +/machxo2/cells_sim.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v -map +/simcells.v synth_machxo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module -select -assert-count 3 t:TRELLIS_IO -select -assert-count 1 t:LUT4 -select -assert-none t:TRELLIS_IO t:LUT4 %% t:* %D +select -assert-count 1 t:$_TBUF_ +select -assert-none t:$_TBUF_ %% t:* %D From 541c1ab567cb060cfc528b0143404e62efef126b Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 23 Aug 2023 11:51:00 +0200 Subject: [PATCH 262/303] add script for blackbox extraction --- techlibs/lattice/cells_bb_ecp5.v | 3040 ++++++++++++++++++++---------- techlibs/lattice/cells_bb_xo2.v | 634 +++++-- techlibs/lattice/cells_bb_xo3.v | 634 +++++-- techlibs/lattice/cells_bb_xo3d.v | 635 +++++-- techlibs/lattice/cells_xtra.py | 854 +++++++++ 5 files changed, 4244 insertions(+), 1553 deletions(-) create mode 100644 techlibs/lattice/cells_xtra.py diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v index 5cb90b97efc..9c4d1fde4ef 100644 --- a/techlibs/lattice/cells_bb_ecp5.v +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -1,1067 +1,2177 @@ -// ECP5 Blackbox cells -// FIXME: Create sim models +// Created by cells_xtra.py from Lattice models -(* blackbox *) -module DP16KD( - input DIA17, DIA16, DIA15, DIA14, DIA13, DIA12, DIA11, DIA10, DIA9, DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA13, ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA17, DOA16, DOA15, DOA14, DOA13, DOA12, DOA11, DOA10, DOA9, DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB17, DIB16, DIB15, DIB14, DIB13, DIB12, DIB11, DIB10, DIB9, DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB13, ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB17, DOB16, DOB15, DOB14, DOB13, DOB12, DOB11, DOB10, DOB9, DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 18; - parameter DATA_WIDTH_B = 18; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; - - parameter DIA17MUX = "DIA17"; - parameter DIA16MUX = "DIA16"; - parameter DIA15MUX = "DIA15"; - parameter DIA14MUX = "DIA14"; - parameter DIA13MUX = "DIA13"; - parameter DIA12MUX = "DIA12"; - parameter DIA11MUX = "DIA11"; - parameter DIA10MUX = "DIA10"; - parameter DIA9MUX = "DIA9"; - parameter DIA8MUX = "DIA8"; - parameter DIA7MUX = "DIA7"; - parameter DIA6MUX = "DIA6"; - parameter DIA5MUX = "DIA5"; - parameter DIA4MUX = "DIA4"; - parameter DIA3MUX = "DIA3"; - parameter DIA2MUX = "DIA2"; - parameter DIA1MUX = "DIA1"; - parameter DIA0MUX = "DIA0"; - parameter ADA13MUX = "ADA13"; - parameter ADA12MUX = "ADA12"; - parameter ADA11MUX = "ADA11"; - parameter ADA10MUX = "ADA10"; - parameter ADA9MUX = "ADA9"; - parameter ADA8MUX = "ADA8"; - parameter ADA7MUX = "ADA7"; - parameter ADA6MUX = "ADA6"; - parameter ADA5MUX = "ADA5"; - parameter ADA4MUX = "ADA4"; - parameter ADA3MUX = "ADA3"; - parameter ADA2MUX = "ADA2"; - parameter ADA1MUX = "ADA1"; - parameter ADA0MUX = "ADA0"; - parameter CEAMUX = "CEA"; - parameter OCEAMUX = "OCEA"; - parameter CLKAMUX = "CLKA"; - parameter WEAMUX = "WEA"; - parameter RSTAMUX = "RSTA"; - parameter CSA2MUX = "CSA2"; - parameter CSA1MUX = "CSA1"; - parameter CSA0MUX = "CSA0"; - parameter DOA17MUX = "DOA17"; - parameter DOA16MUX = "DOA16"; - parameter DOA15MUX = "DOA15"; - parameter DOA14MUX = "DOA14"; - parameter DOA13MUX = "DOA13"; - parameter DOA12MUX = "DOA12"; - parameter DOA11MUX = "DOA11"; - parameter DOA10MUX = "DOA10"; - parameter DOA9MUX = "DOA9"; - parameter DOA8MUX = "DOA8"; - parameter DOA7MUX = "DOA7"; - parameter DOA6MUX = "DOA6"; - parameter DOA5MUX = "DOA5"; - parameter DOA4MUX = "DOA4"; - parameter DOA3MUX = "DOA3"; - parameter DOA2MUX = "DOA2"; - parameter DOA1MUX = "DOA1"; - parameter DOA0MUX = "DOA0"; - parameter DIB17MUX = "DIB17"; - parameter DIB16MUX = "DIB16"; - parameter DIB15MUX = "DIB15"; - parameter DIB14MUX = "DIB14"; - parameter DIB13MUX = "DIB13"; - parameter DIB12MUX = "DIB12"; - parameter DIB11MUX = "DIB11"; - parameter DIB10MUX = "DIB10"; - parameter DIB9MUX = "DIB9"; - parameter DIB8MUX = "DIB8"; - parameter DIB7MUX = "DIB7"; - parameter DIB6MUX = "DIB6"; - parameter DIB5MUX = "DIB5"; - parameter DIB4MUX = "DIB4"; - parameter DIB3MUX = "DIB3"; - parameter DIB2MUX = "DIB2"; - parameter DIB1MUX = "DIB1"; - parameter DIB0MUX = "DIB0"; - parameter ADB13MUX = "ADB13"; - parameter ADB12MUX = "ADB12"; - parameter ADB11MUX = "ADB11"; - parameter ADB10MUX = "ADB10"; - parameter ADB9MUX = "ADB9"; - parameter ADB8MUX = "ADB8"; - parameter ADB7MUX = "ADB7"; - parameter ADB6MUX = "ADB6"; - parameter ADB5MUX = "ADB5"; - parameter ADB4MUX = "ADB4"; - parameter ADB3MUX = "ADB3"; - parameter ADB2MUX = "ADB2"; - parameter ADB1MUX = "ADB1"; - parameter ADB0MUX = "ADB0"; - parameter CEBMUX = "CEB"; - parameter OCEBMUX = "OCEB"; - parameter CLKBMUX = "CLKB"; - parameter WEBMUX = "WEB"; - parameter RSTBMUX = "RSTB"; - parameter CSB2MUX = "CSB2"; - parameter CSB1MUX = "CSB1"; - parameter CSB0MUX = "CSB0"; - parameter DOB17MUX = "DOB17"; - parameter DOB16MUX = "DOB16"; - parameter DOB15MUX = "DOB15"; - parameter DOB14MUX = "DOB14"; - parameter DOB13MUX = "DOB13"; - parameter DOB12MUX = "DOB12"; - parameter DOB11MUX = "DOB11"; - parameter DOB10MUX = "DOB10"; - parameter DOB9MUX = "DOB9"; - parameter DOB8MUX = "DOB8"; - parameter DOB7MUX = "DOB7"; - parameter DOB6MUX = "DOB6"; - parameter DOB5MUX = "DOB5"; - parameter DOB4MUX = "DOB4"; - parameter DOB3MUX = "DOB3"; - parameter DOB2MUX = "DOB2"; - parameter DOB1MUX = "DOB1"; - parameter DOB0MUX = "DOB0"; - - parameter WID = 0; - - parameter GSR = "ENABLED"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule (* blackbox *) -module MULT18X18D( - input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, - input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, - input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, - input SIGNEDA, SIGNEDB, SOURCEA, SOURCEB, - input CLK0, CLK1, CLK2, CLK3, - input CE0, CE1, CE2, CE3, - input RST0, RST1, RST2, RST3, - input SRIA0, SRIA1, SRIA2, SRIA3, SRIA4, SRIA5, SRIA6, SRIA7, SRIA8, SRIA9, SRIA10, SRIA11, SRIA12, SRIA13, SRIA14, SRIA15, SRIA16, SRIA17, - input SRIB0, SRIB1, SRIB2, SRIB3, SRIB4, SRIB5, SRIB6, SRIB7, SRIB8, SRIB9, SRIB10, SRIB11, SRIB12, SRIB13, SRIB14, SRIB15, SRIB16, SRIB17, - output SROA0, SROA1, SROA2, SROA3, SROA4, SROA5, SROA6, SROA7, SROA8, SROA9, SROA10, SROA11, SROA12, SROA13, SROA14, SROA15, SROA16, SROA17, - output SROB0, SROB1, SROB2, SROB3, SROB4, SROB5, SROB6, SROB7, SROB8, SROB9, SROB10, SROB11, SROB12, SROB13, SROB14, SROB15, SROB16, SROB17, - output ROA0, ROA1, ROA2, ROA3, ROA4, ROA5, ROA6, ROA7, ROA8, ROA9, ROA10, ROA11, ROA12, ROA13, ROA14, ROA15, ROA16, ROA17, - output ROB0, ROB1, ROB2, ROB3, ROB4, ROB5, ROB6, ROB7, ROB8, ROB9, ROB10, ROB11, ROB12, ROB13, ROB14, ROB15, ROB16, ROB17, - output ROC0, ROC1, ROC2, ROC3, ROC4, ROC5, ROC6, ROC7, ROC8, ROC9, ROC10, ROC11, ROC12, ROC13, ROC14, ROC15, ROC16, ROC17, - output P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23, P24, P25, P26, P27, P28, P29, P30, P31, P32, P33, P34, P35, - output SIGNEDP -); - parameter REG_INPUTA_CLK = "NONE"; - parameter REG_INPUTA_CE = "CE0"; - parameter REG_INPUTA_RST = "RST0"; - parameter REG_INPUTB_CLK = "NONE"; - parameter REG_INPUTB_CE = "CE0"; - parameter REG_INPUTB_RST = "RST0"; - parameter REG_INPUTC_CLK = "NONE"; - parameter REG_INPUTC_CE = "CE0"; - parameter REG_INPUTC_RST = "RST0"; - parameter REG_PIPELINE_CLK = "NONE"; - parameter REG_PIPELINE_CE = "CE0"; - parameter REG_PIPELINE_RST = "RST0"; - parameter REG_OUTPUT_CLK = "NONE"; - parameter REG_OUTPUT_CE = "CE0"; - parameter REG_OUTPUT_RST = "RST0"; - parameter [127:0] CLK0_DIV = "ENABLED"; - parameter [127:0] CLK1_DIV = "ENABLED"; - parameter [127:0] CLK2_DIV = "ENABLED"; - parameter [127:0] CLK3_DIV = "ENABLED"; - parameter HIGHSPEED_CLK = "NONE"; - parameter [127:0] GSR = "ENABLED"; - parameter CAS_MATCH_REG = "FALSE"; - parameter [127:0] SOURCEB_MODE = "B_SHIFT"; - parameter [127:0] MULT_BYPASS = "DISABLED"; - parameter [127:0] RESETMODE = "SYNC"; +module PUR (...); + parameter RST_PULSE = 1; + input PUR; endmodule -(* blackbox *) -module ALU54B( - input CLK0, CLK1, CLK2, CLK3, - input CE0, CE1, CE2, CE3, - input RST0, RST1, RST2, RST3, - input SIGNEDIA, SIGNEDIB, SIGNEDCIN, - input A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, - input B0, B1, B2, B3, B4, B5, B6, B7, B8, B9, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20, B21, B22, B23, B24, B25, B26, B27, B28, B29, B30, B31, B32, B33, B34, B35, - input C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26, C27, C28, C29, C30, C31, C32, C33, C34, C35, C36, C37, C38, C39, C40, C41, C42, C43, C44, C45, C46, C47, C48, C49, C50, C51, C52, C53, - input CFB0, CFB1, CFB2, CFB3, CFB4, CFB5, CFB6, CFB7, CFB8, CFB9, CFB10, CFB11, CFB12, CFB13, CFB14, CFB15, CFB16, CFB17, CFB18, CFB19, CFB20, CFB21, CFB22, CFB23, CFB24, CFB25, CFB26, CFB27, CFB28, CFB29, CFB30, CFB31, CFB32, CFB33, CFB34, CFB35, CFB36, CFB37, CFB38, CFB39, CFB40, CFB41, CFB42, CFB43, CFB44, CFB45, CFB46, CFB47, CFB48, CFB49, CFB50, CFB51, CFB52, CFB53, - input MA0, MA1, MA2, MA3, MA4, MA5, MA6, MA7, MA8, MA9, MA10, MA11, MA12, MA13, MA14, MA15, MA16, MA17, MA18, MA19, MA20, MA21, MA22, MA23, MA24, MA25, MA26, MA27, MA28, MA29, MA30, MA31, MA32, MA33, MA34, MA35, - input MB0, MB1, MB2, MB3, MB4, MB5, MB6, MB7, MB8, MB9, MB10, MB11, MB12, MB13, MB14, MB15, MB16, MB17, MB18, MB19, MB20, MB21, MB22, MB23, MB24, MB25, MB26, MB27, MB28, MB29, MB30, MB31, MB32, MB33, MB34, MB35, - input CIN0, CIN1, CIN2, CIN3, CIN4, CIN5, CIN6, CIN7, CIN8, CIN9, CIN10, CIN11, CIN12, CIN13, CIN14, CIN15, CIN16, CIN17, CIN18, CIN19, CIN20, CIN21, CIN22, CIN23, CIN24, CIN25, CIN26, CIN27, CIN28, CIN29, CIN30, CIN31, CIN32, CIN33, CIN34, CIN35, CIN36, CIN37, CIN38, CIN39, CIN40, CIN41, CIN42, CIN43, CIN44, CIN45, CIN46, CIN47, CIN48, CIN49, CIN50, CIN51, CIN52, CIN53, - input OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7, OP8, OP9, OP10, - output R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31, R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46, R47, R48, R49, R50, R51, R52, R53, - output CO0, CO1, CO2, CO3, CO4, CO5, CO6, CO7, CO8, CO9, CO10, CO11, CO12, CO13, CO14, CO15, CO16, CO17, CO18, CO19, CO20, CO21, CO22, CO23, CO24, CO25, CO26, CO27, CO28, CO29, CO30, CO31, CO32, CO33, CO34, CO35, CO36, CO37, CO38, CO39, CO40, CO41, CO42, CO43, CO44, CO45, CO46, CO47, CO48, CO49, CO50, CO51, CO52, CO53, - output EQZ, EQZM, EQOM, EQPAT, EQPATB, - output OVER, UNDER, OVERUNDER, - output SIGNEDR -); - parameter REG_INPUTC0_CLK = "NONE"; - parameter REG_INPUTC0_CE = "CE0"; - parameter REG_INPUTC0_RST = "RST0"; - parameter REG_INPUTC1_CLK = "NONE"; - parameter REG_INPUTC1_CE = "CE0"; - parameter REG_INPUTC1_RST = "RST0"; - parameter REG_OPCODEOP0_0_CLK = "NONE"; - parameter REG_OPCODEOP0_0_CE = "CE0"; - parameter REG_OPCODEOP0_0_RST = "RST0"; - parameter REG_OPCODEOP1_0_CLK = "NONE"; - parameter REG_OPCODEOP0_1_CLK = "NONE"; - parameter REG_OPCODEOP0_1_CE = "CE0"; - parameter REG_OPCODEOP0_1_RST = "RST0"; - parameter REG_OPCODEOP1_1_CLK = "NONE"; - parameter REG_OPCODEIN_0_CLK = "NONE"; - parameter REG_OPCODEIN_0_CE = "CE0"; - parameter REG_OPCODEIN_0_RST = "RST0"; - parameter REG_OPCODEIN_1_CLK = "NONE"; - parameter REG_OPCODEIN_1_CE = "CE0"; - parameter REG_OPCODEIN_1_RST = "RST0"; - parameter REG_OUTPUT0_CLK = "NONE"; - parameter REG_OUTPUT0_CE = "CE0"; - parameter REG_OUTPUT0_RST = "RST0"; - parameter REG_OUTPUT1_CLK = "NONE"; - parameter REG_OUTPUT1_CE = "CE0"; - parameter REG_OUTPUT1_RST = "RST0"; - parameter REG_FLAG_CLK = "NONE"; - parameter REG_FLAG_CE = "CE0"; - parameter REG_FLAG_RST = "RST0"; - parameter REG_INPUTCFB_CLK = "NONE"; - parameter REG_INPUTCFB_CE = "CE0"; - parameter REG_INPUTCFB_RST = "RST0"; - parameter [127:0] MCPAT_SOURCE = "STATIC"; - parameter [127:0] MASKPAT_SOURCE = "STATIC"; - parameter MASK01 = "0x00000000000000"; - parameter [127:0] CLK0_DIV = "ENABLED"; - parameter [127:0] CLK1_DIV = "ENABLED"; - parameter [127:0] CLK2_DIV = "ENABLED"; - parameter [127:0] CLK3_DIV = "ENABLED"; - parameter MCPAT = "0x00000000000000"; - parameter MASKPAT = "0x00000000000000"; - parameter RNDPAT = "0x00000000000000"; - parameter [127:0] GSR = "ENABLED"; - parameter [127:0] RESETMODE = "SYNC"; - parameter MULT9_MODE = "DISABLED"; - parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; - parameter LEGACY = "DISABLED"; +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module EHXPLLL ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, PHASELOADREG, - input STDBY, PLLWAKESYNC, - input RST, ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, - output CLKOP, CLKOS, CLKOS2, CLKOS3, - output LOCK, INTLOCK, - output REFCLK, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "DISABLED"; - parameter CLKOS2_ENABLE = "DISABLED"; - parameter CLKOS3_ENABLE = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter OUTDIVIDER_MUXA = "DIVA"; - parameter OUTDIVIDER_MUXB = "DIVB"; - parameter OUTDIVIDER_MUXC = "DIVC"; - parameter OUTDIVIDER_MUXD = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter PLL_LOCK_DELAY = 200; - parameter STDBY_ENABLE = "DISABLED"; - parameter REFIN_RESET = "DISABLED"; - parameter SYNC_ENABLE = "DISABLED"; - parameter INT_LOCK_STICKY = "ENABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; +module DP16KD (...); + parameter DATA_WIDTH_A = 18; + parameter DATA_WIDTH_B = 18; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter GSR = "ENABLED"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + input DIA17; + input DIA16; + input DIA15; + input DIA14; + input DIA13; + input DIA12; + input DIA11; + input DIA10; + input DIA9; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA13; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB17; + input DIB16; + input DIB15; + input DIB14; + input DIB13; + input DIB12; + input DIB11; + input DIB10; + input DIB9; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB13; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA17; + output DOA16; + output DOA15; + output DOA14; + output DOA13; + output DOA12; + output DOA11; + output DOA10; + output DOA9; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB17; + output DOB16; + output DOB15; + output DOB14; + output DOB13; + output DOB12; + output DOB11; + output DOB10; + output DOB9; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module DTR( - input STARTPULSE, - output DTROUT7, DTROUT6, DTROUT5, DTROUT4, DTROUT3, DTROUT2, DTROUT1, DTROUT0 -); +module PDPW16KD (...); + parameter DATA_WIDTH_W = 36; + parameter DATA_WIDTH_R = 36; + parameter GSR = "ENABLED"; + parameter REGMODE = "NOREG"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter CSDECODE_W = "0b000"; + parameter CSDECODE_R = "0b000"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_DATA = "STATIC"; + input DI35; + input DI34; + input DI33; + input DI32; + input DI31; + input DI30; + input DI29; + input DI28; + input DI27; + input DI26; + input DI25; + input DI24; + input DI23; + input DI22; + input DI21; + input DI20; + input DI19; + input DI18; + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE3; + input BE2; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR13; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO35; + output DO34; + output DO33; + output DO32; + output DO31; + output DO30; + output DO29; + output DO28; + output DO27; + output DO26; + output DO25; + output DO24; + output DO23; + output DO22; + output DO21; + output DO20; + output DO19; + output DO18; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module OSCG( - output OSC -); -parameter DIV = 128; +module MULT18X18D (...); + parameter REG_INPUTA_CLK = "NONE"; + parameter REG_INPUTA_CE = "CE0"; + parameter REG_INPUTA_RST = "RST0"; + parameter REG_INPUTB_CLK = "NONE"; + parameter REG_INPUTB_CE = "CE0"; + parameter REG_INPUTB_RST = "RST0"; + parameter REG_INPUTC_CLK = "NONE"; + parameter REG_INPUTC_CE = "CE0"; + parameter REG_INPUTC_RST = "RST0"; + parameter REG_PIPELINE_CLK = "NONE"; + parameter REG_PIPELINE_CE = "CE0"; + parameter REG_PIPELINE_RST = "RST0"; + parameter REG_OUTPUT_CLK = "NONE"; + parameter REG_OUTPUT_CE = "CE0"; + parameter REG_OUTPUT_RST = "RST0"; + parameter CLK0_DIV = "ENABLED"; + parameter CLK1_DIV = "ENABLED"; + parameter CLK2_DIV = "ENABLED"; + parameter CLK3_DIV = "ENABLED"; + parameter HIGHSPEED_CLK = "NONE"; + parameter GSR = "ENABLED"; + parameter CAS_MATCH_REG = "FALSE"; + parameter SOURCEB_MODE = "B_SHIFT"; + parameter MULT_BYPASS = "DISABLED"; + parameter RESETMODE = "SYNC"; + input A17; + input A16; + input A15; + input A14; + input A13; + input A12; + input A11; + input A10; + input A9; + input A8; + input A7; + input A6; + input A5; + input A4; + input A3; + input A2; + input A1; + input A0; + input B17; + input B16; + input B15; + input B14; + input B13; + input B12; + input B11; + input B10; + input B9; + input B8; + input B7; + input B6; + input B5; + input B4; + input B3; + input B2; + input B1; + input B0; + input C17; + input C16; + input C15; + input C14; + input C13; + input C12; + input C11; + input C10; + input C9; + input C8; + input C7; + input C6; + input C5; + input C4; + input C3; + input C2; + input C1; + input C0; + input SIGNEDA; + input SIGNEDB; + input SOURCEA; + input SOURCEB; + input CLK3; + input CLK2; + input CLK1; + input CLK0; + input CE3; + input CE2; + input CE1; + input CE0; + input RST3; + input RST2; + input RST1; + input RST0; + input SRIA17; + input SRIA16; + input SRIA15; + input SRIA14; + input SRIA13; + input SRIA12; + input SRIA11; + input SRIA10; + input SRIA9; + input SRIA8; + input SRIA7; + input SRIA6; + input SRIA5; + input SRIA4; + input SRIA3; + input SRIA2; + input SRIA1; + input SRIA0; + input SRIB17; + input SRIB16; + input SRIB15; + input SRIB14; + input SRIB13; + input SRIB12; + input SRIB11; + input SRIB10; + input SRIB9; + input SRIB8; + input SRIB7; + input SRIB6; + input SRIB5; + input SRIB4; + input SRIB3; + input SRIB2; + input SRIB1; + input SRIB0; + output SROA17; + output SROA16; + output SROA15; + output SROA14; + output SROA13; + output SROA12; + output SROA11; + output SROA10; + output SROA9; + output SROA8; + output SROA7; + output SROA6; + output SROA5; + output SROA4; + output SROA3; + output SROA2; + output SROA1; + output SROA0; + output SROB17; + output SROB16; + output SROB15; + output SROB14; + output SROB13; + output SROB12; + output SROB11; + output SROB10; + output SROB9; + output SROB8; + output SROB7; + output SROB6; + output SROB5; + output SROB4; + output SROB3; + output SROB2; + output SROB1; + output SROB0; + output ROA17; + output ROA16; + output ROA15; + output ROA14; + output ROA13; + output ROA12; + output ROA11; + output ROA10; + output ROA9; + output ROA8; + output ROA7; + output ROA6; + output ROA5; + output ROA4; + output ROA3; + output ROA2; + output ROA1; + output ROA0; + output ROB17; + output ROB16; + output ROB15; + output ROB14; + output ROB13; + output ROB12; + output ROB11; + output ROB10; + output ROB9; + output ROB8; + output ROB7; + output ROB6; + output ROB5; + output ROB4; + output ROB3; + output ROB2; + output ROB1; + output ROB0; + output ROC17; + output ROC16; + output ROC15; + output ROC14; + output ROC13; + output ROC12; + output ROC11; + output ROC10; + output ROC9; + output ROC8; + output ROC7; + output ROC6; + output ROC5; + output ROC4; + output ROC3; + output ROC2; + output ROC1; + output ROC0; + output P35; + output P34; + output P33; + output P32; + output P31; + output P30; + output P29; + output P28; + output P27; + output P26; + output P25; + output P24; + output P23; + output P22; + output P21; + output P20; + output P19; + output P18; + output P17; + output P16; + output P15; + output P14; + output P13; + output P12; + output P11; + output P10; + output P9; + output P8; + output P7; + output P6; + output P5; + output P4; + output P3; + output P2; + output P1; + output P0; + output SIGNEDP; endmodule -(* blackbox *) (* keep *) -module USRMCLK( - input USRMCLKI, USRMCLKTS, - output USRMCLKO -); +(* blackbox *) +module ALU54B (...); + parameter REG_INPUTC0_CLK = "NONE"; + parameter REG_INPUTC0_CE = "CE0"; + parameter REG_INPUTC0_RST = "RST0"; + parameter REG_INPUTC1_CLK = "NONE"; + parameter REG_INPUTC1_CE = "CE0"; + parameter REG_INPUTC1_RST = "RST0"; + parameter REG_OPCODEOP0_0_CLK = "NONE"; + parameter REG_OPCODEOP0_0_CE = "CE0"; + parameter REG_OPCODEOP0_0_RST = "RST0"; + parameter REG_OPCODEOP1_0_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CLK = "NONE"; + parameter REG_OPCODEOP0_1_CE = "CE0"; + parameter REG_OPCODEOP0_1_RST = "RST0"; + parameter REG_OPCODEOP1_1_CLK = "NONE"; + parameter REG_OPCODEIN_0_CLK = "NONE"; + parameter REG_OPCODEIN_0_CE = "CE0"; + parameter REG_OPCODEIN_0_RST = "RST0"; + parameter REG_OPCODEIN_1_CLK = "NONE"; + parameter REG_OPCODEIN_1_CE = "CE0"; + parameter REG_OPCODEIN_1_RST = "RST0"; + parameter REG_OUTPUT0_CLK = "NONE"; + parameter REG_OUTPUT0_CE = "CE0"; + parameter REG_OUTPUT0_RST = "RST0"; + parameter REG_OUTPUT1_CLK = "NONE"; + parameter REG_OUTPUT1_CE = "CE0"; + parameter REG_OUTPUT1_RST = "RST0"; + parameter REG_FLAG_CLK = "NONE"; + parameter REG_FLAG_CE = "CE0"; + parameter REG_FLAG_RST = "RST0"; + parameter MCPAT_SOURCE = "STATIC"; + parameter MASKPAT_SOURCE = "STATIC"; + parameter MASK01 = "0x00000000000000"; + parameter REG_INPUTCFB_CLK = "NONE"; + parameter REG_INPUTCFB_CE = "CE0"; + parameter REG_INPUTCFB_RST = "RST0"; + parameter CLK0_DIV = "ENABLED"; + parameter CLK1_DIV = "ENABLED"; + parameter CLK2_DIV = "ENABLED"; + parameter CLK3_DIV = "ENABLED"; + parameter MCPAT = "0x00000000000000"; + parameter MASKPAT = "0x00000000000000"; + parameter RNDPAT = "0x00000000000000"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter MULT9_MODE = "DISABLED"; + parameter FORCE_ZERO_BARREL_SHIFT = "DISABLED"; + parameter LEGACY = "DISABLED"; + input CE3; + input CE2; + input CE1; + input CE0; + input CLK3; + input CLK2; + input CLK1; + input CLK0; + input RST3; + input RST2; + input RST1; + input RST0; + input SIGNEDIA; + input SIGNEDIB; + input SIGNEDCIN; + input A35; + input A34; + input A33; + input A32; + input A31; + input A30; + input A29; + input A28; + input A27; + input A26; + input A25; + input A24; + input A23; + input A22; + input A21; + input A20; + input A19; + input A18; + input A17; + input A16; + input A15; + input A14; + input A13; + input A12; + input A11; + input A10; + input A9; + input A8; + input A7; + input A6; + input A5; + input A4; + input A3; + input A2; + input A1; + input A0; + input B35; + input B34; + input B33; + input B32; + input B31; + input B30; + input B29; + input B28; + input B27; + input B26; + input B25; + input B24; + input B23; + input B22; + input B21; + input B20; + input B19; + input B18; + input B17; + input B16; + input B15; + input B14; + input B13; + input B12; + input B11; + input B10; + input B9; + input B8; + input B7; + input B6; + input B5; + input B4; + input B3; + input B2; + input B1; + input B0; + input C53; + input C52; + input C51; + input C50; + input C49; + input C48; + input C47; + input C46; + input C45; + input C44; + input C43; + input C42; + input C41; + input C40; + input C39; + input C38; + input C37; + input C36; + input C35; + input C34; + input C33; + input C32; + input C31; + input C30; + input C29; + input C28; + input C27; + input C26; + input C25; + input C24; + input C23; + input C22; + input C21; + input C20; + input C19; + input C18; + input C17; + input C16; + input C15; + input C14; + input C13; + input C12; + input C11; + input C10; + input C9; + input C8; + input C7; + input C6; + input C5; + input C4; + input C3; + input C2; + input C1; + input C0; + input CFB53; + input CFB52; + input CFB51; + input CFB50; + input CFB49; + input CFB48; + input CFB47; + input CFB46; + input CFB45; + input CFB44; + input CFB43; + input CFB42; + input CFB41; + input CFB40; + input CFB39; + input CFB38; + input CFB37; + input CFB36; + input CFB35; + input CFB34; + input CFB33; + input CFB32; + input CFB31; + input CFB30; + input CFB29; + input CFB28; + input CFB27; + input CFB26; + input CFB25; + input CFB24; + input CFB23; + input CFB22; + input CFB21; + input CFB20; + input CFB19; + input CFB18; + input CFB17; + input CFB16; + input CFB15; + input CFB14; + input CFB13; + input CFB12; + input CFB11; + input CFB10; + input CFB9; + input CFB8; + input CFB7; + input CFB6; + input CFB5; + input CFB4; + input CFB3; + input CFB2; + input CFB1; + input CFB0; + input MA35; + input MA34; + input MA33; + input MA32; + input MA31; + input MA30; + input MA29; + input MA28; + input MA27; + input MA26; + input MA25; + input MA24; + input MA23; + input MA22; + input MA21; + input MA20; + input MA19; + input MA18; + input MA17; + input MA16; + input MA15; + input MA14; + input MA13; + input MA12; + input MA11; + input MA10; + input MA9; + input MA8; + input MA7; + input MA6; + input MA5; + input MA4; + input MA3; + input MA2; + input MA1; + input MA0; + input MB35; + input MB34; + input MB33; + input MB32; + input MB31; + input MB30; + input MB29; + input MB28; + input MB27; + input MB26; + input MB25; + input MB24; + input MB23; + input MB22; + input MB21; + input MB20; + input MB19; + input MB18; + input MB17; + input MB16; + input MB15; + input MB14; + input MB13; + input MB12; + input MB11; + input MB10; + input MB9; + input MB8; + input MB7; + input MB6; + input MB5; + input MB4; + input MB3; + input MB2; + input MB1; + input MB0; + input CIN53; + input CIN52; + input CIN51; + input CIN50; + input CIN49; + input CIN48; + input CIN47; + input CIN46; + input CIN45; + input CIN44; + input CIN43; + input CIN42; + input CIN41; + input CIN40; + input CIN39; + input CIN38; + input CIN37; + input CIN36; + input CIN35; + input CIN34; + input CIN33; + input CIN32; + input CIN31; + input CIN30; + input CIN29; + input CIN28; + input CIN27; + input CIN26; + input CIN25; + input CIN24; + input CIN23; + input CIN22; + input CIN21; + input CIN20; + input CIN19; + input CIN18; + input CIN17; + input CIN16; + input CIN15; + input CIN14; + input CIN13; + input CIN12; + input CIN11; + input CIN10; + input CIN9; + input CIN8; + input CIN7; + input CIN6; + input CIN5; + input CIN4; + input CIN3; + input CIN2; + input CIN1; + input CIN0; + input OP10; + input OP9; + input OP8; + input OP7; + input OP6; + input OP5; + input OP4; + input OP3; + input OP2; + input OP1; + input OP0; + output R53; + output R52; + output R51; + output R50; + output R49; + output R48; + output R47; + output R46; + output R45; + output R44; + output R43; + output R42; + output R41; + output R40; + output R39; + output R38; + output R37; + output R36; + output R35; + output R34; + output R33; + output R32; + output R31; + output R30; + output R29; + output R28; + output R27; + output R26; + output R25; + output R24; + output R23; + output R22; + output R21; + output R20; + output R19; + output R18; + output R17; + output R16; + output R15; + output R14; + output R13; + output R12; + output R11; + output R10; + output R9; + output R8; + output R7; + output R6; + output R5; + output R4; + output R3; + output R2; + output R1; + output R0; + output CO53; + output CO52; + output CO51; + output CO50; + output CO49; + output CO48; + output CO47; + output CO46; + output CO45; + output CO44; + output CO43; + output CO42; + output CO41; + output CO40; + output CO39; + output CO38; + output CO37; + output CO36; + output CO35; + output CO34; + output CO33; + output CO32; + output CO31; + output CO30; + output CO29; + output CO28; + output CO27; + output CO26; + output CO25; + output CO24; + output CO23; + output CO22; + output CO21; + output CO20; + output CO19; + output CO18; + output CO17; + output CO16; + output CO15; + output CO14; + output CO13; + output CO12; + output CO11; + output CO10; + output CO9; + output CO8; + output CO7; + output CO6; + output CO5; + output CO4; + output CO3; + output CO2; + output CO1; + output CO0; + output EQZ; + output EQZM; + output EQOM; + output EQPAT; + output EQPATB; + output OVER; + output UNDER; + output OVERUNDER; + output SIGNEDR; endmodule -(* blackbox *) (* keep *) -module JTAGG( - (* iopad_external_pin *) - input TCK, - (* iopad_external_pin *) - input TMS, - (* iopad_external_pin *) - input TDI, - input JTDO2, JTDO1, - (* iopad_external_pin *) - output TDO, - output JTDI, JTCK, JRTI2, JRTI1, - output JSHIFT, JUPDATE, JRSTN, JCE2, JCE1 -); -parameter ER1 = "ENABLED"; -parameter ER2 = "ENABLED"; +(* blackbox *) +module CLKDIVF (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input CLKI; + input RST; + input ALIGNWD; + output CDIVX; endmodule (* blackbox *) -module DELAYF( - input A, LOADN, MOVE, DIRECTION, - output Z, CFLAG -); - parameter DEL_MODE = "USER_DEFINED"; - parameter DEL_VALUE = 0; +module PCSCLKDIV (...); + parameter GSR = "DISABLED"; + input CLKI; + input RST; + input SEL2; + input SEL1; + input SEL0; + output CDIV1; + output CDIVX; endmodule (* blackbox *) -module DELAYG( - input A, - output Z -); - parameter DEL_MODE = "USER_DEFINED"; - parameter DEL_VALUE = 0; +module DCSC (...); + parameter DCSMODE = "POS"; + input CLK1; + input CLK0; + input SEL1; + input SEL0; + input MODESEL; + output DCSOUT; endmodule (* blackbox *) -module IDDRX1F( - input D, SCLK, RST, - output Q0, Q1 -); - parameter GSR = "ENABLED"; +module DCCA (...); + input CLKI; + input CE; + output CLKO; endmodule (* blackbox *) -module IDDRX2F( - input D, SCLK, ECLK, RST, ALIGNWD, - output Q0, Q1, Q2, Q3 -); - parameter GSR = "ENABLED"; +module ECLKSYNCB (...); + input ECLKI; + input STOP; + output ECLKO; endmodule (* blackbox *) -module IDDR71B( - input D, SCLK, ECLK, RST, ALIGNWD, - output Q0, Q1, Q2, Q3, Q4, Q5, Q6 -); - parameter GSR = "ENABLED"; +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; endmodule (* blackbox *) -module IDDRX2DQA( - input D, DQSR90, ECLK, SCLK, RST, - input RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, - output Q0, Q1, Q2, Q3, QWL -); - parameter GSR = "ENABLED"; +module DELAYF (...); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; + input A; + input LOADN; + input MOVE; + input DIRECTION; + output Z; + output CFLAG; endmodule (* blackbox *) -module ODDRX1F( - input SCLK, RST, D0, D1, - output Q -); - parameter GSR = "ENABLED"; +module DELAYG (...); + parameter DEL_MODE = "USER_DEFINED"; + parameter DEL_VALUE = 0; + input A; + output Z; endmodule -(* blackbox *) -module ODDRX2F( - input SCLK, ECLK, RST, D0, D1, D2, D3, - output Q -); - parameter GSR = "ENABLED"; +(* blackbox *) (* keep *) +module USRMCLK (...); + input USRMCLKI; + input USRMCLKTS; endmodule (* blackbox *) -module ODDR71B( - input SCLK, ECLK, RST, D0, D1, D2, D3, D4, D5, D6, - output Q -); - parameter GSR = "ENABLED"; +module DQSBUFM (...); + parameter DQS_LI_DEL_VAL = 4; + parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; + parameter DQS_LO_DEL_VAL = 0; + parameter DQS_LO_DEL_ADJ = "FACTORYONLY"; + parameter GSR = "ENABLED"; + input DQSI; + input READ1; + input READ0; + input READCLKSEL2; + input READCLKSEL1; + input READCLKSEL0; + input DDRDEL; + input ECLK; + input SCLK; + input RST; + input DYNDELAY7; + input DYNDELAY6; + input DYNDELAY5; + input DYNDELAY4; + input DYNDELAY3; + input DYNDELAY2; + input DYNDELAY1; + input DYNDELAY0; + input PAUSE; + input RDLOADN; + input RDMOVE; + input RDDIRECTION; + input WRLOADN; + input WRMOVE; + input WRDIRECTION; + output DQSR90; + output DQSW; + output DQSW270; + output RDPNTR2; + output RDPNTR1; + output RDPNTR0; + output WRPNTR2; + output WRPNTR1; + output WRPNTR0; + output DATAVALID; + output BURSTDET; + output RDCFLAG; + output WRCFLAG; endmodule (* blackbox *) -module OSHX2A( - input D0, D1, RST, ECLK, SCLK, - output Q -); - parameter GSR = "ENABLED"; +module DDRDLLA (...); + parameter FORCE_MAX_DELAY = "NO"; + parameter GSR = "ENABLED"; + input CLK; + input RST; + input UDDCNTLN; + input FREEZE; + output DDRDEL; + output LOCK; + output DCNTL7; + output DCNTL6; + output DCNTL5; + output DCNTL4; + output DCNTL3; + output DCNTL2; + output DCNTL1; + output DCNTL0; endmodule (* blackbox *) -module ODDRX2DQA( - input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW270, - output Q -); - parameter GSR = "ENABLED"; +module DLLDELD (...); + input A; + input DDRDEL; + input LOADN; + input MOVE; + input DIRECTION; + output Z; + output CFLAG; endmodule (* blackbox *) -module ODDRX2DQSB( - input D0, D1, D2, D3, RST, ECLK, SCLK, DQSW, - output Q -); - parameter GSR = "ENABLED"; +module IDDRX1F (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input RST; + output Q0; + output Q1; endmodule (* blackbox *) -module TSHX2DQA( - input T0, T1, SCLK, ECLK, DQSW270, RST, - output Q -); - parameter GSR = "ENABLED"; - parameter REGSET = "SET"; +module IDDRX2F (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input ECLK; + input RST; + input ALIGNWD; + output Q3; + output Q2; + output Q1; + output Q0; endmodule (* blackbox *) -module TSHX2DQSA( - input T0, T1, SCLK, ECLK, DQSW, RST, - output Q -); - parameter GSR = "ENABLED"; - parameter REGSET = "SET"; +module IDDR71B (...); + parameter GSR = "ENABLED"; + input D; + input SCLK; + input ECLK; + input RST; + input ALIGNWD; + output Q6; + output Q5; + output Q4; + output Q3; + output Q2; + output Q1; + output Q0; endmodule (* blackbox *) -module DQSBUFM( - input DQSI, READ1, READ0, READCLKSEL2, READCLKSEL1, READCLKSEL0, DDRDEL, - input ECLK, SCLK, - input DYNDELAY7, DYNDELAY6, DYNDELAY5, DYNDELAY4, - input DYNDELAY3, DYNDELAY2, DYNDELAY1, DYNDELAY0, - input RST, RDLOADN, RDMOVE, RDDIRECTION, WRLOADN, WRMOVE, WRDIRECTION, PAUSE, - output DQSR90, DQSW, DQSW270, - output RDPNTR2, RDPNTR1, RDPNTR0, WRPNTR2, WRPNTR1, WRPNTR0, - output DATAVALID, BURSTDET, RDCFLAG, WRCFLAG -); - parameter DQS_LI_DEL_ADJ = "FACTORYONLY"; - parameter DQS_LI_DEL_VAL = 0; - parameter DQS_LO_DEL_ADJ = "FACTORYONLY"; - parameter DQS_LO_DEL_VAL = 0; - parameter GSR = "ENABLED"; +module IDDRX2DQA (...); + parameter GSR = "ENABLED"; + input SCLK; + input ECLK; + input DQSR90; + input D; + input RST; + input RDPNTR2; + input RDPNTR1; + input RDPNTR0; + input WRPNTR2; + input WRPNTR1; + input WRPNTR0; + output Q3; + output Q2; + output Q1; + output Q0; + output QWL; endmodule (* blackbox *) -module DDRDLLA( - input CLK, RST, UDDCNTLN, FREEZE, - output LOCK, DDRDEL, DCNTL7, DCNTL6, DCNTL5, DCNTL4, DCNTL3, DCNTL2, DCNTL1, DCNTL0 -); - parameter FORCE_MAX_DELAY = "NO"; - parameter GSR = "ENABLED"; +module ODDRX1F (...); + parameter GSR = "ENABLED"; + input SCLK; + input RST; + input D0; + input D1; + output Q; endmodule (* blackbox *) -module DLLDELD( - input A, DDRDEL, LOADN, MOVE, DIRECTION, - output Z, CFLAG -); - parameter DEL_ADJ = "PLUS"; - parameter DEL_VAL = 0; +module ODDRX2F (...); + parameter GSR = "ENABLED"; + input SCLK; + input ECLK; + input RST; + input D3; + input D2; + input D1; + input D0; + output Q; endmodule (* blackbox *) -module CLKDIVF( - input CLKI, RST, ALIGNWD, - output CDIVX -); - parameter GSR = "DISABLED"; - parameter DIV = "2.0"; +module ODDR71B (...); + parameter GSR = "ENABLED"; + input SCLK; + input ECLK; + input RST; + input D6; + input D5; + input D4; + input D3; + input D2; + input D1; + input D0; + output Q; endmodule (* blackbox *) -module ECLKSYNCB( - input ECLKI, STOP, - output ECLKO -); +module OSHX2A (...); + parameter GSR = "ENABLED"; + input D1; + input D0; + input SCLK; + input ECLK; + input RST; + output Q; endmodule (* blackbox *) -module ECLKBRIDGECS( - input CLK0, CLK1, SEL, - output ECSOUT -); +module TSHX2DQA (...); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; + input T1; + input T0; + input SCLK; + input ECLK; + input DQSW270; + input RST; + output Q; endmodule (* blackbox *) -module DCCA( - input CLKI, CE, - output CLKO -); +module TSHX2DQSA (...); + parameter GSR = "ENABLED"; + parameter REGSET = "SET"; + input T1; + input T0; + input SCLK; + input ECLK; + input DQSW; + input RST; + output Q; endmodule (* blackbox *) -module DCSC( - input CLK1, CLK0, - input SEL1, SEL0, - input MODESEL, - output DCSOUT -); - parameter DCSMODE = "POS"; +module ODDRX2DQA (...); + parameter GSR = "ENABLED"; + input D3; + input D2; + input D1; + input D0; + input DQSW270; + input SCLK; + input ECLK; + input RST; + output Q; endmodule -(* blackbox *) (* keep *) -module DCUA( - (* iopad_external_pin *) - input CH0_HDINP, - (* iopad_external_pin *) - input CH1_HDINP, - (* iopad_external_pin *) - input CH0_HDINN, - (* iopad_external_pin *) - input CH1_HDINN, - input D_TXBIT_CLKP_FROM_ND, D_TXBIT_CLKN_FROM_ND, D_SYNC_ND, D_TXPLL_LOL_FROM_ND, - input CH0_RX_REFCLK, CH1_RX_REFCLK, CH0_FF_RXI_CLK, CH1_FF_RXI_CLK, CH0_FF_TXI_CLK, CH1_FF_TXI_CLK, CH0_FF_EBRD_CLK, CH1_FF_EBRD_CLK, - input CH0_FF_TX_D_0, CH1_FF_TX_D_0, CH0_FF_TX_D_1, CH1_FF_TX_D_1, CH0_FF_TX_D_2, CH1_FF_TX_D_2, CH0_FF_TX_D_3, CH1_FF_TX_D_3, - input CH0_FF_TX_D_4, CH1_FF_TX_D_4, CH0_FF_TX_D_5, CH1_FF_TX_D_5, CH0_FF_TX_D_6, CH1_FF_TX_D_6, CH0_FF_TX_D_7, CH1_FF_TX_D_7, - input CH0_FF_TX_D_8, CH1_FF_TX_D_8, CH0_FF_TX_D_9, CH1_FF_TX_D_9, CH0_FF_TX_D_10, CH1_FF_TX_D_10, CH0_FF_TX_D_11, CH1_FF_TX_D_11, - input CH0_FF_TX_D_12, CH1_FF_TX_D_12, CH0_FF_TX_D_13, CH1_FF_TX_D_13, CH0_FF_TX_D_14, CH1_FF_TX_D_14, CH0_FF_TX_D_15, CH1_FF_TX_D_15, - input CH0_FF_TX_D_16, CH1_FF_TX_D_16, CH0_FF_TX_D_17, CH1_FF_TX_D_17, CH0_FF_TX_D_18, CH1_FF_TX_D_18, CH0_FF_TX_D_19, CH1_FF_TX_D_19, - input CH0_FF_TX_D_20, CH1_FF_TX_D_20, CH0_FF_TX_D_21, CH1_FF_TX_D_21, CH0_FF_TX_D_22, CH1_FF_TX_D_22, CH0_FF_TX_D_23, CH1_FF_TX_D_23, - input CH0_FFC_EI_EN, CH1_FFC_EI_EN, CH0_FFC_PCIE_DET_EN, CH1_FFC_PCIE_DET_EN, CH0_FFC_PCIE_CT, CH1_FFC_PCIE_CT, CH0_FFC_SB_INV_RX, CH1_FFC_SB_INV_RX, - input CH0_FFC_ENABLE_CGALIGN, CH1_FFC_ENABLE_CGALIGN, CH0_FFC_SIGNAL_DETECT, CH1_FFC_SIGNAL_DETECT, CH0_FFC_FB_LOOPBACK, CH1_FFC_FB_LOOPBACK, CH0_FFC_SB_PFIFO_LP, CH1_FFC_SB_PFIFO_LP, - input CH0_FFC_PFIFO_CLR, CH1_FFC_PFIFO_CLR, CH0_FFC_RATE_MODE_RX, CH1_FFC_RATE_MODE_RX, CH0_FFC_RATE_MODE_TX, CH1_FFC_RATE_MODE_TX, CH0_FFC_DIV11_MODE_RX, CH1_FFC_DIV11_MODE_RX, CH0_FFC_RX_GEAR_MODE, CH1_FFC_RX_GEAR_MODE, CH0_FFC_TX_GEAR_MODE, CH1_FFC_TX_GEAR_MODE, - input CH0_FFC_DIV11_MODE_TX, CH1_FFC_DIV11_MODE_TX, CH0_FFC_LDR_CORE2TX_EN, CH1_FFC_LDR_CORE2TX_EN, CH0_FFC_LANE_TX_RST, CH1_FFC_LANE_TX_RST, CH0_FFC_LANE_RX_RST, CH1_FFC_LANE_RX_RST, - input CH0_FFC_RRST, CH1_FFC_RRST, CH0_FFC_TXPWDNB, CH1_FFC_TXPWDNB, CH0_FFC_RXPWDNB, CH1_FFC_RXPWDNB, CH0_LDR_CORE2TX, CH1_LDR_CORE2TX, - input D_SCIWDATA0, D_SCIWDATA1, D_SCIWDATA2, D_SCIWDATA3, D_SCIWDATA4, D_SCIWDATA5, D_SCIWDATA6, D_SCIWDATA7, - input D_SCIADDR0, D_SCIADDR1, D_SCIADDR2, D_SCIADDR3, D_SCIADDR4, D_SCIADDR5, D_SCIENAUX, D_SCISELAUX, - input CH0_SCIEN, CH1_SCIEN, CH0_SCISEL, CH1_SCISEL, D_SCIRD, D_SCIWSTN, D_CYAWSTN, D_FFC_SYNC_TOGGLE, - input D_FFC_DUAL_RST, D_FFC_MACRO_RST, D_FFC_MACROPDB, D_FFC_TRST, CH0_FFC_CDR_EN_BITSLIP, CH1_FFC_CDR_EN_BITSLIP, D_SCAN_ENABLE, D_SCAN_IN_0, - input D_SCAN_IN_1, D_SCAN_IN_2, D_SCAN_IN_3, D_SCAN_IN_4, D_SCAN_IN_5, D_SCAN_IN_6, D_SCAN_IN_7, D_SCAN_MODE, - input D_SCAN_RESET, D_CIN0, D_CIN1, D_CIN2, D_CIN3, D_CIN4, D_CIN5, D_CIN6,D_CIN7, D_CIN8, D_CIN9, D_CIN10, D_CIN11, - output CH0_HDOUTP, CH1_HDOUTP, CH0_HDOUTN, CH1_HDOUTN, D_TXBIT_CLKP_TO_ND, D_TXBIT_CLKN_TO_ND, D_SYNC_PULSE2ND, D_TXPLL_LOL_TO_ND, - output CH0_FF_RX_F_CLK, CH1_FF_RX_F_CLK, CH0_FF_RX_H_CLK, CH1_FF_RX_H_CLK, CH0_FF_TX_F_CLK, CH1_FF_TX_F_CLK, CH0_FF_TX_H_CLK, CH1_FF_TX_H_CLK, - output CH0_FF_RX_PCLK, CH1_FF_RX_PCLK, CH0_FF_TX_PCLK, CH1_FF_TX_PCLK, CH0_FF_RX_D_0, CH1_FF_RX_D_0, CH0_FF_RX_D_1, CH1_FF_RX_D_1, - output CH0_FF_RX_D_2, CH1_FF_RX_D_2, CH0_FF_RX_D_3, CH1_FF_RX_D_3, CH0_FF_RX_D_4, CH1_FF_RX_D_4, CH0_FF_RX_D_5, CH1_FF_RX_D_5, - output CH0_FF_RX_D_6, CH1_FF_RX_D_6, CH0_FF_RX_D_7, CH1_FF_RX_D_7, CH0_FF_RX_D_8, CH1_FF_RX_D_8, CH0_FF_RX_D_9, CH1_FF_RX_D_9, - output CH0_FF_RX_D_10, CH1_FF_RX_D_10, CH0_FF_RX_D_11, CH1_FF_RX_D_11, CH0_FF_RX_D_12, CH1_FF_RX_D_12, CH0_FF_RX_D_13, CH1_FF_RX_D_13, - output CH0_FF_RX_D_14, CH1_FF_RX_D_14, CH0_FF_RX_D_15, CH1_FF_RX_D_15, CH0_FF_RX_D_16, CH1_FF_RX_D_16, CH0_FF_RX_D_17, CH1_FF_RX_D_17, - output CH0_FF_RX_D_18, CH1_FF_RX_D_18, CH0_FF_RX_D_19, CH1_FF_RX_D_19, CH0_FF_RX_D_20, CH1_FF_RX_D_20, CH0_FF_RX_D_21, CH1_FF_RX_D_21, - output CH0_FF_RX_D_22, CH1_FF_RX_D_22, CH0_FF_RX_D_23, CH1_FF_RX_D_23, CH0_FFS_PCIE_DONE, CH1_FFS_PCIE_DONE, CH0_FFS_PCIE_CON, CH1_FFS_PCIE_CON, - output CH0_FFS_RLOS, CH1_FFS_RLOS, CH0_FFS_LS_SYNC_STATUS, CH1_FFS_LS_SYNC_STATUS, CH0_FFS_CC_UNDERRUN, CH1_FFS_CC_UNDERRUN, CH0_FFS_CC_OVERRUN, CH1_FFS_CC_OVERRUN, - output CH0_FFS_RXFBFIFO_ERROR, CH1_FFS_RXFBFIFO_ERROR, CH0_FFS_TXFBFIFO_ERROR, CH1_FFS_TXFBFIFO_ERROR, CH0_FFS_RLOL, CH1_FFS_RLOL, CH0_FFS_SKP_ADDED, CH1_FFS_SKP_ADDED, - output CH0_FFS_SKP_DELETED, CH1_FFS_SKP_DELETED, CH0_LDR_RX2CORE, CH1_LDR_RX2CORE, D_SCIRDATA0, D_SCIRDATA1, D_SCIRDATA2, D_SCIRDATA3, - output D_SCIRDATA4, D_SCIRDATA5, D_SCIRDATA6, D_SCIRDATA7, D_SCIINT, D_SCAN_OUT_0, D_SCAN_OUT_1, D_SCAN_OUT_2, D_SCAN_OUT_3, D_SCAN_OUT_4, D_SCAN_OUT_5, D_SCAN_OUT_6, D_SCAN_OUT_7, - output D_COUT0, D_COUT1, D_COUT2, D_COUT3, D_COUT4, D_COUT5, D_COUT6, D_COUT7, D_COUT8, D_COUT9, D_COUT10, D_COUT11, D_COUT12, D_COUT13, D_COUT14, D_COUT15, D_COUT16, D_COUT17, D_COUT18, D_COUT19, - - input D_REFCLKI, - output D_FFS_PLOL -); - parameter CH0_AUTO_CALIB_EN = "0b0"; - parameter CH0_AUTO_FACQ_EN = "0b0"; - parameter CH0_BAND_THRESHOLD = "0b000000"; - parameter CH0_CALIB_CK_MODE = "0b0"; - parameter CH0_CC_MATCH_1 = "0b0000000000"; - parameter CH0_CC_MATCH_2 = "0b0000000000"; - parameter CH0_CC_MATCH_3 = "0b0000000000"; - parameter CH0_CC_MATCH_4 = "0b0000000000"; - parameter CH0_CDR_CNT4SEL = "0b00"; - parameter CH0_CDR_CNT8SEL = "0b00"; - parameter CH0_CTC_BYPASS = "0b0"; - parameter CH0_DCOATDCFG = "0b00"; - parameter CH0_DCOATDDLY = "0b00"; - parameter CH0_DCOBYPSATD = "0b0"; - parameter CH0_DCOCALDIV = "0b000"; - parameter CH0_DCOCTLGI = "0b000"; - parameter CH0_DCODISBDAVOID = "0b0"; - parameter CH0_DCOFLTDAC = "0b00"; - parameter CH0_DCOFTNRG = "0b000"; - parameter CH0_DCOIOSTUNE = "0b000"; - parameter CH0_DCOITUNE = "0b00"; - parameter CH0_DCOITUNE4LSB = "0b000"; - parameter CH0_DCOIUPDNX2 = "0b0"; - parameter CH0_DCONUOFLSB = "0b000"; - parameter CH0_DCOSCALEI = "0b00"; - parameter CH0_DCOSTARTVAL = "0b000"; - parameter CH0_DCOSTEP = "0b00"; - parameter CH0_DEC_BYPASS = "0b0"; - parameter CH0_ENABLE_CG_ALIGN = "0b0"; - parameter CH0_ENC_BYPASS = "0b0"; - parameter CH0_FF_RX_F_CLK_DIS = "0b0"; - parameter CH0_FF_RX_H_CLK_EN = "0b0"; - parameter CH0_FF_TX_F_CLK_DIS = "0b0"; - parameter CH0_FF_TX_H_CLK_EN = "0b0"; - parameter CH0_GE_AN_ENABLE = "0b0"; - parameter CH0_INVERT_RX = "0b0"; - parameter CH0_INVERT_TX = "0b0"; - parameter CH0_LDR_CORE2TX_SEL = "0b0"; - parameter CH0_LDR_RX2CORE_SEL = "0b0"; - parameter CH0_LEQ_OFFSET_SEL = "0b0"; - parameter CH0_LEQ_OFFSET_TRIM = "0b000"; - parameter CH0_LSM_DISABLE = "0b0"; - parameter CH0_MATCH_2_ENABLE = "0b0"; - parameter CH0_MATCH_4_ENABLE = "0b0"; - parameter CH0_MIN_IPG_CNT = "0b00"; - parameter CH0_PCIE_EI_EN = "0b0"; - parameter CH0_PCIE_MODE = "0b0"; - parameter CH0_PCS_DET_TIME_SEL = "0b00"; - parameter CH0_PDEN_SEL = "0b0"; - parameter CH0_PRBS_ENABLE = "0b0"; - parameter CH0_PRBS_LOCK = "0b0"; - parameter CH0_PRBS_SELECTION = "0b0"; - parameter CH0_RATE_MODE_RX = "0b0"; - parameter CH0_RATE_MODE_TX = "0b0"; - parameter CH0_RCV_DCC_EN = "0b0"; - parameter CH0_REG_BAND_OFFSET = "0b0000"; - parameter CH0_REG_BAND_SEL = "0b000000"; - parameter CH0_REG_IDAC_EN = "0b0"; - parameter CH0_REG_IDAC_SEL = "0b0000000000"; - parameter CH0_REQ_EN = "0b0"; - parameter CH0_REQ_LVL_SET = "0b00"; - parameter CH0_RIO_MODE = "0b0"; - parameter CH0_RLOS_SEL = "0b0"; - parameter CH0_RPWDNB = "0b0"; - parameter CH0_RTERM_RX = "0b00000"; - parameter CH0_RTERM_TX = "0b00000"; - parameter CH0_RXIN_CM = "0b00"; - parameter CH0_RXTERM_CM = "0b00"; - parameter CH0_RX_DCO_CK_DIV = "0b000"; - parameter CH0_RX_DIV11_SEL = "0b0"; - parameter CH0_RX_GEAR_BYPASS = "0b0"; - parameter CH0_RX_GEAR_MODE = "0b0"; - parameter CH0_RX_LOS_CEQ = "0b00"; - parameter CH0_RX_LOS_EN = "0b0"; - parameter CH0_RX_LOS_HYST_EN = "0b0"; - parameter CH0_RX_LOS_LVL = "0b000"; - parameter CH0_RX_RATE_SEL = "0b0000"; - parameter CH0_RX_SB_BYPASS = "0b0"; - parameter CH0_SB_BYPASS = "0b0"; - parameter CH0_SEL_SD_RX_CLK = "0b0"; - parameter CH0_TDRV_DAT_SEL = "0b00"; - parameter CH0_TDRV_POST_EN = "0b0"; - parameter CH0_TDRV_PRE_EN = "0b0"; - parameter CH0_TDRV_SLICE0_CUR = "0b000"; - parameter CH0_TDRV_SLICE0_SEL = "0b00"; - parameter CH0_TDRV_SLICE1_CUR = "0b000"; - parameter CH0_TDRV_SLICE1_SEL = "0b00"; - parameter CH0_TDRV_SLICE2_CUR = "0b00"; - parameter CH0_TDRV_SLICE2_SEL = "0b00"; - parameter CH0_TDRV_SLICE3_CUR = "0b00"; - parameter CH0_TDRV_SLICE3_SEL = "0b00"; - parameter CH0_TDRV_SLICE4_CUR = "0b00"; - parameter CH0_TDRV_SLICE4_SEL = "0b00"; - parameter CH0_TDRV_SLICE5_CUR = "0b00"; - parameter CH0_TDRV_SLICE5_SEL = "0b00"; - parameter CH0_TPWDNB = "0b0"; - parameter CH0_TX_CM_SEL = "0b00"; - parameter CH0_TX_DIV11_SEL = "0b0"; - parameter CH0_TX_GEAR_BYPASS = "0b0"; - parameter CH0_TX_GEAR_MODE = "0b0"; - parameter CH0_TX_POST_SIGN = "0b0"; - parameter CH0_TX_PRE_SIGN = "0b0"; - parameter CH0_UC_MODE = "0b0"; - parameter CH0_UDF_COMMA_A = "0b0000000000"; - parameter CH0_UDF_COMMA_B = "0b0000000000"; - parameter CH0_UDF_COMMA_MASK = "0b0000000000"; - parameter CH0_WA_BYPASS = "0b0"; - parameter CH0_WA_MODE = "0b0"; - parameter CH1_AUTO_CALIB_EN = "0b0"; - parameter CH1_AUTO_FACQ_EN = "0b0"; - parameter CH1_BAND_THRESHOLD = "0b000000"; - parameter CH1_CALIB_CK_MODE = "0b0"; - parameter CH1_CC_MATCH_1 = "0b0000000000"; - parameter CH1_CC_MATCH_2 = "0b0000000000"; - parameter CH1_CC_MATCH_3 = "0b0000000000"; - parameter CH1_CC_MATCH_4 = "0b0000000000"; - parameter CH1_CDR_CNT4SEL = "0b00"; - parameter CH1_CDR_CNT8SEL = "0b00"; - parameter CH1_CTC_BYPASS = "0b0"; - parameter CH1_DCOATDCFG = "0b00"; - parameter CH1_DCOATDDLY = "0b00"; - parameter CH1_DCOBYPSATD = "0b0"; - parameter CH1_DCOCALDIV = "0b000"; - parameter CH1_DCOCTLGI = "0b000"; - parameter CH1_DCODISBDAVOID = "0b0"; - parameter CH1_DCOFLTDAC = "0b00"; - parameter CH1_DCOFTNRG = "0b000"; - parameter CH1_DCOIOSTUNE = "0b000"; - parameter CH1_DCOITUNE = "0b00"; - parameter CH1_DCOITUNE4LSB = "0b000"; - parameter CH1_DCOIUPDNX2 = "0b0"; - parameter CH1_DCONUOFLSB = "0b000"; - parameter CH1_DCOSCALEI = "0b00"; - parameter CH1_DCOSTARTVAL = "0b000"; - parameter CH1_DCOSTEP = "0b00"; - parameter CH1_DEC_BYPASS = "0b0"; - parameter CH1_ENABLE_CG_ALIGN = "0b0"; - parameter CH1_ENC_BYPASS = "0b0"; - parameter CH1_FF_RX_F_CLK_DIS = "0b0"; - parameter CH1_FF_RX_H_CLK_EN = "0b0"; - parameter CH1_FF_TX_F_CLK_DIS = "0b0"; - parameter CH1_FF_TX_H_CLK_EN = "0b0"; - parameter CH1_GE_AN_ENABLE = "0b0"; - parameter CH1_INVERT_RX = "0b0"; - parameter CH1_INVERT_TX = "0b0"; - parameter CH1_LDR_CORE2TX_SEL = "0b0"; - parameter CH1_LDR_RX2CORE_SEL = "0b0"; - parameter CH1_LEQ_OFFSET_SEL = "0b0"; - parameter CH1_LEQ_OFFSET_TRIM = "0b000"; - parameter CH1_LSM_DISABLE = "0b0"; - parameter CH1_MATCH_2_ENABLE = "0b0"; - parameter CH1_MATCH_4_ENABLE = "0b0"; - parameter CH1_MIN_IPG_CNT = "0b00"; - parameter CH1_PCIE_EI_EN = "0b0"; - parameter CH1_PCIE_MODE = "0b0"; - parameter CH1_PCS_DET_TIME_SEL = "0b00"; - parameter CH1_PDEN_SEL = "0b0"; - parameter CH1_PRBS_ENABLE = "0b0"; - parameter CH1_PRBS_LOCK = "0b0"; - parameter CH1_PRBS_SELECTION = "0b0"; - parameter CH1_RATE_MODE_RX = "0b0"; - parameter CH1_RATE_MODE_TX = "0b0"; - parameter CH1_RCV_DCC_EN = "0b0"; - parameter CH1_REG_BAND_OFFSET = "0b0000"; - parameter CH1_REG_BAND_SEL = "0b000000"; - parameter CH1_REG_IDAC_EN = "0b0"; - parameter CH1_REG_IDAC_SEL = "0b0000000000"; - parameter CH1_REQ_EN = "0b0"; - parameter CH1_REQ_LVL_SET = "0b00"; - parameter CH1_RIO_MODE = "0b0"; - parameter CH1_RLOS_SEL = "0b0"; - parameter CH1_RPWDNB = "0b0"; - parameter CH1_RTERM_RX = "0b00000"; - parameter CH1_RTERM_TX = "0b00000"; - parameter CH1_RXIN_CM = "0b00"; - parameter CH1_RXTERM_CM = "0b00"; - parameter CH1_RX_DCO_CK_DIV = "0b000"; - parameter CH1_RX_DIV11_SEL = "0b0"; - parameter CH1_RX_GEAR_BYPASS = "0b0"; - parameter CH1_RX_GEAR_MODE = "0b0"; - parameter CH1_RX_LOS_CEQ = "0b00"; - parameter CH1_RX_LOS_EN = "0b0"; - parameter CH1_RX_LOS_HYST_EN = "0b0"; - parameter CH1_RX_LOS_LVL = "0b000"; - parameter CH1_RX_RATE_SEL = "0b0000"; - parameter CH1_RX_SB_BYPASS = "0b0"; - parameter CH1_SB_BYPASS = "0b0"; - parameter CH1_SEL_SD_RX_CLK = "0b0"; - parameter CH1_TDRV_DAT_SEL = "0b00"; - parameter CH1_TDRV_POST_EN = "0b0"; - parameter CH1_TDRV_PRE_EN = "0b0"; - parameter CH1_TDRV_SLICE0_CUR = "0b000"; - parameter CH1_TDRV_SLICE0_SEL = "0b00"; - parameter CH1_TDRV_SLICE1_CUR = "0b000"; - parameter CH1_TDRV_SLICE1_SEL = "0b00"; - parameter CH1_TDRV_SLICE2_CUR = "0b00"; - parameter CH1_TDRV_SLICE2_SEL = "0b00"; - parameter CH1_TDRV_SLICE3_CUR = "0b00"; - parameter CH1_TDRV_SLICE3_SEL = "0b00"; - parameter CH1_TDRV_SLICE4_CUR = "0b00"; - parameter CH1_TDRV_SLICE4_SEL = "0b00"; - parameter CH1_TDRV_SLICE5_CUR = "0b00"; - parameter CH1_TDRV_SLICE5_SEL = "0b00"; - parameter CH1_TPWDNB = "0b0"; - parameter CH1_TX_CM_SEL = "0b00"; - parameter CH1_TX_DIV11_SEL = "0b0"; - parameter CH1_TX_GEAR_BYPASS = "0b0"; - parameter CH1_TX_GEAR_MODE = "0b0"; - parameter CH1_TX_POST_SIGN = "0b0"; - parameter CH1_TX_PRE_SIGN = "0b0"; - parameter CH1_UC_MODE = "0b0"; - parameter CH1_UDF_COMMA_A = "0b0000000000"; - parameter CH1_UDF_COMMA_B = "0b0000000000"; - parameter CH1_UDF_COMMA_MASK = "0b0000000000"; - parameter CH1_WA_BYPASS = "0b0"; - parameter CH1_WA_MODE = "0b0"; - parameter D_BITCLK_FROM_ND_EN = "0b0"; - parameter D_BITCLK_LOCAL_EN = "0b0"; - parameter D_BITCLK_ND_EN = "0b0"; - parameter D_BUS8BIT_SEL = "0b0"; - parameter D_CDR_LOL_SET = "0b00"; - parameter D_CMUSETBIASI = "0b00"; - parameter D_CMUSETI4CPP = "0b0000"; - parameter D_CMUSETI4CPZ = "0b0000"; - parameter D_CMUSETI4VCO = "0b00"; - parameter D_CMUSETICP4P = "0b00"; - parameter D_CMUSETICP4Z = "0b000"; - parameter D_CMUSETINITVCT = "0b00"; - parameter D_CMUSETISCL4VCO = "0b000"; - parameter D_CMUSETP1GM = "0b000"; - parameter D_CMUSETP2AGM = "0b000"; - parameter D_CMUSETZGM = "0b000"; - parameter D_DCO_CALIB_TIME_SEL = "0b00"; - parameter D_HIGH_MARK = "0b0000"; - parameter D_IB_PWDNB = "0b0"; - parameter D_ISETLOS = "0b00000000"; - parameter D_LOW_MARK = "0b0000"; - parameter D_MACROPDB = "0b0"; - parameter D_PD_ISET = "0b00"; - parameter D_PLL_LOL_SET = "0b00"; - parameter D_REFCK_MODE = "0b000"; - parameter D_REQ_ISET = "0b000"; - parameter D_RG_EN = "0b0"; - parameter D_RG_SET = "0b00"; - parameter D_SETICONST_AUX = "0b00"; - parameter D_SETICONST_CH = "0b00"; - parameter D_SETIRPOLY_AUX = "0b00"; - parameter D_SETIRPOLY_CH = "0b00"; - parameter D_SETPLLRC = "0b000000"; - parameter D_SYNC_LOCAL_EN = "0b0"; - parameter D_SYNC_ND_EN = "0b0"; - parameter D_TXPLL_PWDNB = "0b0"; - parameter D_TX_VCO_CK_DIV = "0b000"; - parameter D_XGE_MODE = "0b0"; - -// These parameters don't do anything but are -// needed for compatibility with Diamond - parameter D_TX_MAX_RATE = "2.5"; - parameter D_RX_MAX_RATE = "2.5"; - parameter CH0_TXAMPLITUDE = "0d1300"; - parameter CH1_TXAMPLITUDE = "0d1300"; - parameter CH0_PROTOCOL = "8B10B"; - parameter CH1_PROTOCOL = "8B10B"; - parameter CH0_CDR_MAX_RATE = "2.5"; - parameter CH1_CDR_MAX_RATE = "2.5"; - parameter CH0_TXDEPRE = "DISABLED"; - parameter CH1_TXDEPRE = "DISABLED"; - parameter CH0_TXDEPOST = "DISABLED"; - parameter CH1_TXDEPOST = "DISABLED"; +(* blackbox *) +module ODDRX2DQSB (...); + parameter GSR = "ENABLED"; + input D3; + input D2; + input D1; + input D0; + input SCLK; + input ECLK; + input DQSW; + input RST; + output Q; endmodule (* blackbox *) -module EXTREFB ( - (* iopad_external_pin *) - input REFCLKP, - (* iopad_external_pin *) - input REFCLKN, - output REFCLKO -); - parameter REFCK_PWDNB = "0b0"; - parameter REFCK_RTERM = "0b0"; - parameter REFCK_DCBIAS_EN = "0b0"; +module EHXPLLL (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "DISABLED"; + parameter CLKOS2_ENABLE = "DISABLED"; + parameter CLKOS3_ENABLE = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter OUTDIVIDER_MUXA = "DIVA"; + parameter OUTDIVIDER_MUXB = "DIVB"; + parameter OUTDIVIDER_MUXC = "DIVC"; + parameter OUTDIVIDER_MUXD = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter PLL_LOCK_DELAY = 200; + parameter STDBY_ENABLE = "DISABLED"; + parameter REFIN_RESET = "DISABLED"; + parameter SYNC_ENABLE = "DISABLED"; + parameter INT_LOCK_STICKY = "ENABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input PHASELOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output CLKINTFB; endmodule (* blackbox *) -module PCSCLKDIV ( - input CLKI, RST, SEL2, SEL1, SEL0, - output CDIV1, CDIVX -); - parameter GSR = "DISABLED"; +module DTR (...); + parameter DTR_TEMP = 25; + input STARTPULSE; + output DTROUT7; + output DTROUT6; + output DTROUT5; + output DTROUT4; + output DTROUT3; + output DTROUT2; + output DTROUT1; + output DTROUT0; endmodule -// Note: this module is not marked keep as we want it swept away in synth (sim use only) (* blackbox *) -module PUR ( - input PUR -); - parameter RST_PULSE = 1; +module OSCG (...); + parameter DIV = 128; + output OSC; endmodule -(* blackbox, keep *) -module GSR ( - input GSR -); +(* blackbox *) +module EXTREFB (...); + parameter REFCK_PWDNB = "DONTCARE"; + parameter REFCK_RTERM = "DONTCARE"; + parameter REFCK_DCBIAS_EN = "DONTCARE"; + (* iopad_external_pin *) + input REFCLKP; + (* iopad_external_pin *) + input REFCLKN; + output REFCLKO; + output ; endmodule -(* blackbox, keep *) -module SGSR ( - input GSR, CLK -); +(* blackbox *) (* keep *) +module JTAGG (...); + parameter ER1 = "ENABLED"; + parameter ER2 = "ENABLED"; + (* iopad_external_pin *) + input TCK; + (* iopad_external_pin *) + input TMS; + (* iopad_external_pin *) + input TDI; + input JTDO2; + input JTDO1; + (* iopad_external_pin *) + output TDO; + output JTDI; + output JTCK; + output JRTI2; + output JRTI1; + output JSHIFT; + output JUPDATE; + output JRSTN; + output JCE2; + output JCE1; endmodule - -(* blackbox *) -module PDPW16KD ( - input DI35, DI34, DI33, DI32, DI31, DI30, DI29, DI28, DI27, DI26, DI25, DI24, DI23, DI22, DI21, DI20, DI19, DI18, - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE3, BE2, BE1, BE0, CEW, CLKW, CSW2, CSW1, CSW0, - input ADR13, ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO35, DO34, DO33, DO32, DO31, DO30, DO29, DO28, DO27, DO26, DO25, DO24, DO23, DO22, DO21, DO20, DO19, DO18, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); - parameter DATA_WIDTH_W = 36; - parameter DATA_WIDTH_R = 36; - parameter GSR = "ENABLED"; - - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_W = "0b000"; - parameter CSDECODE_R = "0b000"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_20 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_21 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_22 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_23 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_24 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_25 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_26 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_27 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_28 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_29 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_2F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_30 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_31 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_32 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_33 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_34 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_35 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_36 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_37 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_38 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_39 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - parameter CLKWMUX = "CLKW"; - parameter CLKRMUX = "CLKR"; - +(* blackbox *) (* keep *) +module DCUA (...); + parameter D_MACROPDB = "DONTCARE"; + parameter D_IB_PWDNB = "DONTCARE"; + parameter D_XGE_MODE = "DONTCARE"; + parameter D_LOW_MARK = "DONTCARE"; + parameter D_HIGH_MARK = "DONTCARE"; + parameter D_BUS8BIT_SEL = "DONTCARE"; + parameter D_CDR_LOL_SET = "DONTCARE"; + parameter D_BITCLK_LOCAL_EN = "DONTCARE"; + parameter D_BITCLK_ND_EN = "DONTCARE"; + parameter D_BITCLK_FROM_ND_EN = "DONTCARE"; + parameter D_SYNC_LOCAL_EN = "DONTCARE"; + parameter D_SYNC_ND_EN = "DONTCARE"; + parameter CH0_UC_MODE = "DONTCARE"; + parameter CH1_UC_MODE = "DONTCARE"; + parameter CH0_PCIE_MODE = "DONTCARE"; + parameter CH1_PCIE_MODE = "DONTCARE"; + parameter CH0_RIO_MODE = "DONTCARE"; + parameter CH1_RIO_MODE = "DONTCARE"; + parameter CH0_WA_MODE = "DONTCARE"; + parameter CH1_WA_MODE = "DONTCARE"; + parameter CH0_INVERT_RX = "DONTCARE"; + parameter CH1_INVERT_RX = "DONTCARE"; + parameter CH0_INVERT_TX = "DONTCARE"; + parameter CH1_INVERT_TX = "DONTCARE"; + parameter CH0_PRBS_SELECTION = "DONTCARE"; + parameter CH1_PRBS_SELECTION = "DONTCARE"; + parameter CH0_GE_AN_ENABLE = "DONTCARE"; + parameter CH1_GE_AN_ENABLE = "DONTCARE"; + parameter CH0_PRBS_LOCK = "DONTCARE"; + parameter CH1_PRBS_LOCK = "DONTCARE"; + parameter CH0_PRBS_ENABLE = "DONTCARE"; + parameter CH1_PRBS_ENABLE = "DONTCARE"; + parameter CH0_ENABLE_CG_ALIGN = "DONTCARE"; + parameter CH1_ENABLE_CG_ALIGN = "DONTCARE"; + parameter CH0_TX_GEAR_MODE = "DONTCARE"; + parameter CH1_TX_GEAR_MODE = "DONTCARE"; + parameter CH0_RX_GEAR_MODE = "DONTCARE"; + parameter CH1_RX_GEAR_MODE = "DONTCARE"; + parameter CH0_PCS_DET_TIME_SEL = "DONTCARE"; + parameter CH1_PCS_DET_TIME_SEL = "DONTCARE"; + parameter CH0_PCIE_EI_EN = "DONTCARE"; + parameter CH1_PCIE_EI_EN = "DONTCARE"; + parameter CH0_TX_GEAR_BYPASS = "DONTCARE"; + parameter CH1_TX_GEAR_BYPASS = "DONTCARE"; + parameter CH0_ENC_BYPASS = "DONTCARE"; + parameter CH1_ENC_BYPASS = "DONTCARE"; + parameter CH0_SB_BYPASS = "DONTCARE"; + parameter CH1_SB_BYPASS = "DONTCARE"; + parameter CH0_RX_SB_BYPASS = "DONTCARE"; + parameter CH1_RX_SB_BYPASS = "DONTCARE"; + parameter CH0_WA_BYPASS = "DONTCARE"; + parameter CH1_WA_BYPASS = "DONTCARE"; + parameter CH0_DEC_BYPASS = "DONTCARE"; + parameter CH1_DEC_BYPASS = "DONTCARE"; + parameter CH0_CTC_BYPASS = "DONTCARE"; + parameter CH1_CTC_BYPASS = "DONTCARE"; + parameter CH0_RX_GEAR_BYPASS = "DONTCARE"; + parameter CH1_RX_GEAR_BYPASS = "DONTCARE"; + parameter CH0_LSM_DISABLE = "DONTCARE"; + parameter CH1_LSM_DISABLE = "DONTCARE"; + parameter CH0_MATCH_2_ENABLE = "DONTCARE"; + parameter CH1_MATCH_2_ENABLE = "DONTCARE"; + parameter CH0_MATCH_4_ENABLE = "DONTCARE"; + parameter CH1_MATCH_4_ENABLE = "DONTCARE"; + parameter CH0_MIN_IPG_CNT = "DONTCARE"; + parameter CH1_MIN_IPG_CNT = "DONTCARE"; + parameter CH0_CC_MATCH_1 = "DONTCARE"; + parameter CH1_CC_MATCH_1 = "DONTCARE"; + parameter CH0_CC_MATCH_2 = "DONTCARE"; + parameter CH1_CC_MATCH_2 = "DONTCARE"; + parameter CH0_CC_MATCH_3 = "DONTCARE"; + parameter CH1_CC_MATCH_3 = "DONTCARE"; + parameter CH0_CC_MATCH_4 = "DONTCARE"; + parameter CH1_CC_MATCH_4 = "DONTCARE"; + parameter CH0_UDF_COMMA_MASK = "DONTCARE"; + parameter CH1_UDF_COMMA_MASK = "DONTCARE"; + parameter CH0_UDF_COMMA_A = "DONTCARE"; + parameter CH1_UDF_COMMA_A = "DONTCARE"; + parameter CH0_UDF_COMMA_B = "DONTCARE"; + parameter CH1_UDF_COMMA_B = "DONTCARE"; + parameter CH0_RX_DCO_CK_DIV = "DONTCARE"; + parameter CH1_RX_DCO_CK_DIV = "DONTCARE"; + parameter CH0_RCV_DCC_EN = "DONTCARE"; + parameter CH1_RCV_DCC_EN = "DONTCARE"; + parameter CH0_REQ_LVL_SET = "DONTCARE"; + parameter CH1_REQ_LVL_SET = "DONTCARE"; + parameter CH0_REQ_EN = "DONTCARE"; + parameter CH1_REQ_EN = "DONTCARE"; + parameter CH0_RTERM_RX = "DONTCARE"; + parameter CH1_RTERM_RX = "DONTCARE"; + parameter CH0_PDEN_SEL = "DONTCARE"; + parameter CH1_PDEN_SEL = "DONTCARE"; + parameter CH0_LDR_RX2CORE_SEL = "DONTCARE"; + parameter CH1_LDR_RX2CORE_SEL = "DONTCARE"; + parameter CH0_LDR_CORE2TX_SEL = "DONTCARE"; + parameter CH1_LDR_CORE2TX_SEL = "DONTCARE"; + parameter CH0_TPWDNB = "DONTCARE"; + parameter CH1_TPWDNB = "DONTCARE"; + parameter CH0_RATE_MODE_TX = "DONTCARE"; + parameter CH1_RATE_MODE_TX = "DONTCARE"; + parameter CH0_RTERM_TX = "DONTCARE"; + parameter CH1_RTERM_TX = "DONTCARE"; + parameter CH0_TX_CM_SEL = "DONTCARE"; + parameter CH1_TX_CM_SEL = "DONTCARE"; + parameter CH0_TDRV_PRE_EN = "DONTCARE"; + parameter CH1_TDRV_PRE_EN = "DONTCARE"; + parameter CH0_TDRV_SLICE0_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE0_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE1_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE1_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE2_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE2_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE3_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE3_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE4_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE4_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE5_SEL = "DONTCARE"; + parameter CH1_TDRV_SLICE5_SEL = "DONTCARE"; + parameter CH0_TDRV_SLICE0_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE0_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE1_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE1_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE2_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE2_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE3_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE3_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE4_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE4_CUR = "DONTCARE"; + parameter CH0_TDRV_SLICE5_CUR = "DONTCARE"; + parameter CH1_TDRV_SLICE5_CUR = "DONTCARE"; + parameter CH0_TDRV_DAT_SEL = "DONTCARE"; + parameter CH1_TDRV_DAT_SEL = "DONTCARE"; + parameter CH0_TX_DIV11_SEL = "DONTCARE"; + parameter CH1_TX_DIV11_SEL = "DONTCARE"; + parameter CH0_RPWDNB = "DONTCARE"; + parameter CH1_RPWDNB = "DONTCARE"; + parameter CH0_RATE_MODE_RX = "DONTCARE"; + parameter CH1_RATE_MODE_RX = "DONTCARE"; + parameter CH0_RLOS_SEL = "DONTCARE"; + parameter CH1_RLOS_SEL = "DONTCARE"; + parameter CH0_RX_LOS_LVL = "DONTCARE"; + parameter CH1_RX_LOS_LVL = "DONTCARE"; + parameter CH0_RX_LOS_CEQ = "DONTCARE"; + parameter CH1_RX_LOS_CEQ = "DONTCARE"; + parameter CH0_RX_LOS_HYST_EN = "DONTCARE"; + parameter CH1_RX_LOS_HYST_EN = "DONTCARE"; + parameter CH0_RX_LOS_EN = "DONTCARE"; + parameter CH1_RX_LOS_EN = "DONTCARE"; + parameter CH0_RX_DIV11_SEL = "DONTCARE"; + parameter CH1_RX_DIV11_SEL = "DONTCARE"; + parameter CH0_SEL_SD_RX_CLK = "DONTCARE"; + parameter CH1_SEL_SD_RX_CLK = "DONTCARE"; + parameter CH0_FF_RX_H_CLK_EN = "DONTCARE"; + parameter CH1_FF_RX_H_CLK_EN = "DONTCARE"; + parameter CH0_FF_RX_F_CLK_DIS = "DONTCARE"; + parameter CH1_FF_RX_F_CLK_DIS = "DONTCARE"; + parameter CH0_FF_TX_H_CLK_EN = "DONTCARE"; + parameter CH1_FF_TX_H_CLK_EN = "DONTCARE"; + parameter CH0_FF_TX_F_CLK_DIS = "DONTCARE"; + parameter CH1_FF_TX_F_CLK_DIS = "DONTCARE"; + parameter CH0_RX_RATE_SEL = "DONTCARE"; + parameter CH1_RX_RATE_SEL = "DONTCARE"; + parameter CH0_TDRV_POST_EN = "DONTCARE"; + parameter CH1_TDRV_POST_EN = "DONTCARE"; + parameter CH0_TX_POST_SIGN = "DONTCARE"; + parameter CH1_TX_POST_SIGN = "DONTCARE"; + parameter CH0_TX_PRE_SIGN = "DONTCARE"; + parameter CH1_TX_PRE_SIGN = "DONTCARE"; + parameter CH0_RXTERM_CM = "DONTCARE"; + parameter CH1_RXTERM_CM = "DONTCARE"; + parameter CH0_RXIN_CM = "DONTCARE"; + parameter CH1_RXIN_CM = "DONTCARE"; + parameter CH0_LEQ_OFFSET_SEL = "DONTCARE"; + parameter CH1_LEQ_OFFSET_SEL = "DONTCARE"; + parameter CH0_LEQ_OFFSET_TRIM = "DONTCARE"; + parameter CH1_LEQ_OFFSET_TRIM = "DONTCARE"; + parameter D_TX_MAX_RATE = "DONTCARE"; + parameter CH0_CDR_MAX_RATE = "DONTCARE"; + parameter CH1_CDR_MAX_RATE = "DONTCARE"; + parameter CH0_TXAMPLITUDE = "DONTCARE"; + parameter CH1_TXAMPLITUDE = "DONTCARE"; + parameter CH0_TXDEPRE = "DONTCARE"; + parameter CH1_TXDEPRE = "DONTCARE"; + parameter CH0_TXDEPOST = "DONTCARE"; + parameter CH1_TXDEPOST = "DONTCARE"; + parameter CH0_PROTOCOL = "DONTCARE"; + parameter CH1_PROTOCOL = "DONTCARE"; + parameter D_ISETLOS = "DONTCARE"; + parameter D_SETIRPOLY_AUX = "DONTCARE"; + parameter D_SETICONST_AUX = "DONTCARE"; + parameter D_SETIRPOLY_CH = "DONTCARE"; + parameter D_SETICONST_CH = "DONTCARE"; + parameter D_REQ_ISET = "DONTCARE"; + parameter D_PD_ISET = "DONTCARE"; + parameter D_DCO_CALIB_TIME_SEL = "DONTCARE"; + parameter CH0_DCOCTLGI = "DONTCARE"; + parameter CH1_DCOCTLGI = "DONTCARE"; + parameter CH0_DCOATDDLY = "DONTCARE"; + parameter CH1_DCOATDDLY = "DONTCARE"; + parameter CH0_DCOATDCFG = "DONTCARE"; + parameter CH1_DCOATDCFG = "DONTCARE"; + parameter CH0_DCOBYPSATD = "DONTCARE"; + parameter CH1_DCOBYPSATD = "DONTCARE"; + parameter CH0_DCOSCALEI = "DONTCARE"; + parameter CH1_DCOSCALEI = "DONTCARE"; + parameter CH0_DCOITUNE4LSB = "DONTCARE"; + parameter CH1_DCOITUNE4LSB = "DONTCARE"; + parameter CH0_DCOIOSTUNE = "DONTCARE"; + parameter CH1_DCOIOSTUNE = "DONTCARE"; + parameter CH0_DCODISBDAVOID = "DONTCARE"; + parameter CH1_DCODISBDAVOID = "DONTCARE"; + parameter CH0_DCOCALDIV = "DONTCARE"; + parameter CH1_DCOCALDIV = "DONTCARE"; + parameter CH0_DCONUOFLSB = "DONTCARE"; + parameter CH1_DCONUOFLSB = "DONTCARE"; + parameter CH0_DCOIUPDNX2 = "DONTCARE"; + parameter CH1_DCOIUPDNX2 = "DONTCARE"; + parameter CH0_DCOSTEP = "DONTCARE"; + parameter CH1_DCOSTEP = "DONTCARE"; + parameter CH0_DCOSTARTVAL = "DONTCARE"; + parameter CH1_DCOSTARTVAL = "DONTCARE"; + parameter CH0_DCOFLTDAC = "DONTCARE"; + parameter CH1_DCOFLTDAC = "DONTCARE"; + parameter CH0_DCOITUNE = "DONTCARE"; + parameter CH1_DCOITUNE = "DONTCARE"; + parameter CH0_DCOFTNRG = "DONTCARE"; + parameter CH1_DCOFTNRG = "DONTCARE"; + parameter CH0_CDR_CNT4SEL = "DONTCARE"; + parameter CH1_CDR_CNT4SEL = "DONTCARE"; + parameter CH0_CDR_CNT8SEL = "DONTCARE"; + parameter CH1_CDR_CNT8SEL = "DONTCARE"; + parameter CH0_BAND_THRESHOLD = "DONTCARE"; + parameter CH1_BAND_THRESHOLD = "DONTCARE"; + parameter CH0_AUTO_FACQ_EN = "DONTCARE"; + parameter CH1_AUTO_FACQ_EN = "DONTCARE"; + parameter CH0_AUTO_CALIB_EN = "DONTCARE"; + parameter CH1_AUTO_CALIB_EN = "DONTCARE"; + parameter CH0_CALIB_CK_MODE = "DONTCARE"; + parameter CH1_CALIB_CK_MODE = "DONTCARE"; + parameter CH0_REG_BAND_OFFSET = "DONTCARE"; + parameter CH1_REG_BAND_OFFSET = "DONTCARE"; + parameter CH0_REG_BAND_SEL = "DONTCARE"; + parameter CH1_REG_BAND_SEL = "DONTCARE"; + parameter CH0_REG_IDAC_SEL = "DONTCARE"; + parameter CH1_REG_IDAC_SEL = "DONTCARE"; + parameter CH0_REG_IDAC_EN = "DONTCARE"; + parameter CH1_REG_IDAC_EN = "DONTCARE"; + parameter D_TXPLL_PWDNB = "DONTCARE"; + parameter D_SETPLLRC = "DONTCARE"; + parameter D_REFCK_MODE = "DONTCARE"; + parameter D_TX_VCO_CK_DIV = "DONTCARE"; + parameter D_PLL_LOL_SET = "DONTCARE"; + parameter D_RG_EN = "DONTCARE"; + parameter D_RG_SET = "DONTCARE"; + parameter D_CMUSETISCL4VCO = "DONTCARE"; + parameter D_CMUSETI4VCO = "DONTCARE"; + parameter D_CMUSETINITVCT = "DONTCARE"; + parameter D_CMUSETZGM = "DONTCARE"; + parameter D_CMUSETP2AGM = "DONTCARE"; + parameter D_CMUSETP1GM = "DONTCARE"; + parameter D_CMUSETI4CPZ = "DONTCARE"; + parameter D_CMUSETI4CPP = "DONTCARE"; + parameter D_CMUSETICP4Z = "DONTCARE"; + parameter D_CMUSETICP4P = "DONTCARE"; + parameter D_CMUSETBIASI = "DONTCARE"; + (* iopad_external_pin *) + (* iopad_external_pin *) + input CH0_HDINP; + (* iopad_external_pin *) + input CH1_HDINP; + (* iopad_external_pin *) + input CH0_HDINN; + (* iopad_external_pin *) + input CH1_HDINN; + input D_TXBIT_CLKP_FROM_ND; + input D_TXBIT_CLKN_FROM_ND; + input D_SYNC_ND; + input D_TXPLL_LOL_FROM_ND; + input CH0_RX_REFCLK; + input CH1_RX_REFCLK; + input CH0_FF_RXI_CLK; + input CH1_FF_RXI_CLK; + input CH0_FF_TXI_CLK; + input CH1_FF_TXI_CLK; + input CH0_FF_EBRD_CLK; + input CH1_FF_EBRD_CLK; + input CH0_FF_TX_D_0; + input CH1_FF_TX_D_0; + input CH0_FF_TX_D_1; + input CH1_FF_TX_D_1; + input CH0_FF_TX_D_2; + input CH1_FF_TX_D_2; + input CH0_FF_TX_D_3; + input CH1_FF_TX_D_3; + input CH0_FF_TX_D_4; + input CH1_FF_TX_D_4; + input CH0_FF_TX_D_5; + input CH1_FF_TX_D_5; + input CH0_FF_TX_D_6; + input CH1_FF_TX_D_6; + input CH0_FF_TX_D_7; + input CH1_FF_TX_D_7; + input CH0_FF_TX_D_8; + input CH1_FF_TX_D_8; + input CH0_FF_TX_D_9; + input CH1_FF_TX_D_9; + input CH0_FF_TX_D_10; + input CH1_FF_TX_D_10; + input CH0_FF_TX_D_11; + input CH1_FF_TX_D_11; + input CH0_FF_TX_D_12; + input CH1_FF_TX_D_12; + input CH0_FF_TX_D_13; + input CH1_FF_TX_D_13; + input CH0_FF_TX_D_14; + input CH1_FF_TX_D_14; + input CH0_FF_TX_D_15; + input CH1_FF_TX_D_15; + input CH0_FF_TX_D_16; + input CH1_FF_TX_D_16; + input CH0_FF_TX_D_17; + input CH1_FF_TX_D_17; + input CH0_FF_TX_D_18; + input CH1_FF_TX_D_18; + input CH0_FF_TX_D_19; + input CH1_FF_TX_D_19; + input CH0_FF_TX_D_20; + input CH1_FF_TX_D_20; + input CH0_FF_TX_D_21; + input CH1_FF_TX_D_21; + input CH0_FF_TX_D_22; + input CH1_FF_TX_D_22; + input CH0_FF_TX_D_23; + input CH1_FF_TX_D_23; + input CH0_FFC_EI_EN; + input CH1_FFC_EI_EN; + input CH0_FFC_PCIE_DET_EN; + input CH1_FFC_PCIE_DET_EN; + input CH0_FFC_PCIE_CT; + input CH1_FFC_PCIE_CT; + input CH0_FFC_SB_INV_RX; + input CH1_FFC_SB_INV_RX; + input CH0_FFC_ENABLE_CGALIGN; + input CH1_FFC_ENABLE_CGALIGN; + input CH0_FFC_SIGNAL_DETECT; + input CH1_FFC_SIGNAL_DETECT; + input CH0_FFC_FB_LOOPBACK; + input CH1_FFC_FB_LOOPBACK; + input CH0_FFC_SB_PFIFO_LP; + input CH1_FFC_SB_PFIFO_LP; + input CH0_FFC_PFIFO_CLR; + input CH1_FFC_PFIFO_CLR; + input CH0_FFC_RATE_MODE_RX; + input CH1_FFC_RATE_MODE_RX; + input CH0_FFC_RATE_MODE_TX; + input CH1_FFC_RATE_MODE_TX; + input CH0_FFC_DIV11_MODE_RX; + input CH1_FFC_DIV11_MODE_RX; + input CH0_FFC_RX_GEAR_MODE; + input CH1_FFC_RX_GEAR_MODE; + input CH0_FFC_TX_GEAR_MODE; + input CH1_FFC_TX_GEAR_MODE; + input CH0_FFC_DIV11_MODE_TX; + input CH1_FFC_DIV11_MODE_TX; + input CH0_FFC_LDR_CORE2TX_EN; + input CH1_FFC_LDR_CORE2TX_EN; + input CH0_FFC_LANE_TX_RST; + input CH1_FFC_LANE_TX_RST; + input CH0_FFC_LANE_RX_RST; + input CH1_FFC_LANE_RX_RST; + input CH0_FFC_RRST; + input CH1_FFC_RRST; + input CH0_FFC_TXPWDNB; + input CH1_FFC_TXPWDNB; + input CH0_FFC_RXPWDNB; + input CH1_FFC_RXPWDNB; + input CH0_LDR_CORE2TX; + input CH1_LDR_CORE2TX; + input D_SCIWDATA0; + input D_SCIWDATA1; + input D_SCIWDATA2; + input D_SCIWDATA3; + input D_SCIWDATA4; + input D_SCIWDATA5; + input D_SCIWDATA6; + input D_SCIWDATA7; + input D_SCIADDR0; + input D_SCIADDR1; + input D_SCIADDR2; + input D_SCIADDR3; + input D_SCIADDR4; + input D_SCIADDR5; + input D_SCIENAUX; + input D_SCISELAUX; + input CH0_SCIEN; + input CH1_SCIEN; + input CH0_SCISEL; + input CH1_SCISEL; + input D_SCIRD; + input D_SCIWSTN; + input D_CYAWSTN; + input D_FFC_SYNC_TOGGLE; + input D_FFC_DUAL_RST; + input D_FFC_MACRO_RST; + input D_FFC_MACROPDB; + input D_FFC_TRST; + input CH0_FFC_CDR_EN_BITSLIP; + input CH1_FFC_CDR_EN_BITSLIP; + input D_SCAN_ENABLE; + input D_SCAN_IN_0; + input D_SCAN_IN_1; + input D_SCAN_IN_2; + input D_SCAN_IN_3; + input D_SCAN_IN_4; + input D_SCAN_IN_5; + input D_SCAN_IN_6; + input D_SCAN_IN_7; + input D_SCAN_MODE; + input D_SCAN_RESET; + input D_CIN0; + input D_CIN1; + input D_CIN2; + input D_CIN3; + input D_CIN4; + input D_CIN5; + input D_CIN6; + input D_CIN7; + input D_CIN8; + input D_CIN9; + input D_CIN10; + input D_CIN11; + output CH0_HDOUTP; + output CH1_HDOUTP; + output CH0_HDOUTN; + output CH1_HDOUTN; + output D_TXBIT_CLKP_TO_ND; + output D_TXBIT_CLKN_TO_ND; + output D_SYNC_PULSE2ND; + output D_TXPLL_LOL_TO_ND; + output CH0_FF_RX_F_CLK; + output CH1_FF_RX_F_CLK; + output CH0_FF_RX_H_CLK; + output CH1_FF_RX_H_CLK; + output CH0_FF_TX_F_CLK; + output CH1_FF_TX_F_CLK; + output CH0_FF_TX_H_CLK; + output CH1_FF_TX_H_CLK; + output CH0_FF_RX_PCLK; + output CH1_FF_RX_PCLK; + output CH0_FF_TX_PCLK; + output CH1_FF_TX_PCLK; + output CH0_FF_RX_D_0; + output CH1_FF_RX_D_0; + output CH0_FF_RX_D_1; + output CH1_FF_RX_D_1; + output CH0_FF_RX_D_2; + output CH1_FF_RX_D_2; + output CH0_FF_RX_D_3; + output CH1_FF_RX_D_3; + output CH0_FF_RX_D_4; + output CH1_FF_RX_D_4; + output CH0_FF_RX_D_5; + output CH1_FF_RX_D_5; + output CH0_FF_RX_D_6; + output CH1_FF_RX_D_6; + output CH0_FF_RX_D_7; + output CH1_FF_RX_D_7; + output CH0_FF_RX_D_8; + output CH1_FF_RX_D_8; + output CH0_FF_RX_D_9; + output CH1_FF_RX_D_9; + output CH0_FF_RX_D_10; + output CH1_FF_RX_D_10; + output CH0_FF_RX_D_11; + output CH1_FF_RX_D_11; + output CH0_FF_RX_D_12; + output CH1_FF_RX_D_12; + output CH0_FF_RX_D_13; + output CH1_FF_RX_D_13; + output CH0_FF_RX_D_14; + output CH1_FF_RX_D_14; + output CH0_FF_RX_D_15; + output CH1_FF_RX_D_15; + output CH0_FF_RX_D_16; + output CH1_FF_RX_D_16; + output CH0_FF_RX_D_17; + output CH1_FF_RX_D_17; + output CH0_FF_RX_D_18; + output CH1_FF_RX_D_18; + output CH0_FF_RX_D_19; + output CH1_FF_RX_D_19; + output CH0_FF_RX_D_20; + output CH1_FF_RX_D_20; + output CH0_FF_RX_D_21; + output CH1_FF_RX_D_21; + output CH0_FF_RX_D_22; + output CH1_FF_RX_D_22; + output CH0_FF_RX_D_23; + output CH1_FF_RX_D_23; + output CH0_FFS_PCIE_DONE; + output CH1_FFS_PCIE_DONE; + output CH0_FFS_PCIE_CON; + output CH1_FFS_PCIE_CON; + output CH0_FFS_RLOS; + output CH1_FFS_RLOS; + output CH0_FFS_LS_SYNC_STATUS; + output CH1_FFS_LS_SYNC_STATUS; + output CH0_FFS_CC_UNDERRUN; + output CH1_FFS_CC_UNDERRUN; + output CH0_FFS_CC_OVERRUN; + output CH1_FFS_CC_OVERRUN; + output CH0_FFS_RXFBFIFO_ERROR; + output CH1_FFS_RXFBFIFO_ERROR; + output CH0_FFS_TXFBFIFO_ERROR; + output CH1_FFS_TXFBFIFO_ERROR; + output CH0_FFS_RLOL; + output CH1_FFS_RLOL; + output CH0_FFS_SKP_ADDED; + output CH1_FFS_SKP_ADDED; + output CH0_FFS_SKP_DELETED; + output CH1_FFS_SKP_DELETED; + output CH0_LDR_RX2CORE; + output CH1_LDR_RX2CORE; + output D_SCIRDATA0; + output D_SCIRDATA1; + output D_SCIRDATA2; + output D_SCIRDATA3; + output D_SCIRDATA4; + output D_SCIRDATA5; + output D_SCIRDATA6; + output D_SCIRDATA7; + output D_SCIINT; + output D_SCAN_OUT_0; + output D_SCAN_OUT_1; + output D_SCAN_OUT_2; + output D_SCAN_OUT_3; + output D_SCAN_OUT_4; + output D_SCAN_OUT_5; + output D_SCAN_OUT_6; + output D_SCAN_OUT_7; + output D_COUT0; + output D_COUT1; + output D_COUT2; + output D_COUT3; + output D_COUT4; + output D_COUT5; + output D_COUT6; + output D_COUT7; + output D_COUT8; + output D_COUT9; + output D_COUT10; + output D_COUT11; + output D_COUT12; + output D_COUT13; + output D_COUT14; + output D_COUT15; + output D_COUT16; + output D_COUT17; + output D_COUT18; + output D_COUT19; + input D_REFCLKI; + output D_FFS_PLOL; + output ; endmodule + diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v index 3363ed5710d..6e6b655c919 100644 --- a/techlibs/lattice/cells_bb_xo2.v +++ b/techlibs/lattice/cells_bb_xo2.v @@ -1,179 +1,153 @@ -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; +// Created by cells_xtra.py from Lattice models - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); +module DP8KC (...); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module PDPW8KC (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b000"; parameter CSDECODE_R = "0b000"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -206,29 +180,90 @@ module PDPW8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module SP8KC (...); parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE = "0b000"; - parameter WRITEMODE = "NORMAL"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -261,33 +296,240 @@ module SP8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input AD12; + input AD11; + input AD10; + input AD9; + input AD8; + input AD7; + input AD6; + input AD5; + input AD4; + input AD3; + input AD2; + input AD1; + input AD0; + input CE; + input OCE; + input CLK; + input WE; + input CS2; + input CS1; + input CS0; + input RST; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); +module FIFO8KB (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - parameter REGMODE = "NOREG"; - parameter RESETMODE = "ASYNC"; parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b00"; parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; parameter FULLPOINTER1 = "0b00000000000000"; + parameter GSR = "DISABLED"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input CSW0; + input CSW1; + input CSR0; + input CSR1; + input WE; + input RE; + input ORE; + input CLKW; + input CLKR; + input RST; + input RPRST; + input FULLI; + input EMPTYI; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output EF; + output AEF; + output AFF; + output FF; +endmodule + +(* blackbox *) +module DCMA (...); + input CLK0; + input CLK1; + input SEL; + output DCMOUT; +endmodule + +(* blackbox *) +module DCCA (...); + input CLKI; + input CE; + output CLKO; +endmodule + +(* blackbox *) +module EHXPLLJ (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input LOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input RESETM; + input RESETC; + input RESETD; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input PLLCLK; + input PLLRST; + input PLLSTB; + input PLLWE; + input PLLDATI7; + input PLLDATI6; + input PLLDATI5; + input PLLDATI4; + input PLLDATI3; + input PLLDATI2; + input PLLDATI1; + input PLLDATI0; + input PLLADDR4; + input PLLADDR3; + input PLLADDR2; + input PLLADDR1; + input PLLADDR0; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output PLLDATO7; + output PLLDATO6; + output PLLDATO5; + output PLLDATO4; + output PLLDATO3; + output PLLDATO2; + output PLLDATO1; + output PLLDATO0; + output PLLACK; + output DPHSRC; + output CLKINTFB; endmodule + +(* blackbox *) +module OSCH (...); + parameter NOM_FREQ = "2.08"; + input STDBY; + output OSC; + output SEDSTDBY; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v index 3363ed5710d..6e6b655c919 100644 --- a/techlibs/lattice/cells_bb_xo3.v +++ b/techlibs/lattice/cells_bb_xo3.v @@ -1,179 +1,153 @@ -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; +// Created by cells_xtra.py from Lattice models - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); +module DP8KC (...); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module PDPW8KC (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b000"; parameter CSDECODE_R = "0b000"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -206,29 +180,90 @@ module PDPW8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module SP8KC (...); parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE = "0b000"; - parameter WRITEMODE = "NORMAL"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -261,33 +296,240 @@ module SP8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input AD12; + input AD11; + input AD10; + input AD9; + input AD8; + input AD7; + input AD6; + input AD5; + input AD4; + input AD3; + input AD2; + input AD1; + input AD0; + input CE; + input OCE; + input CLK; + input WE; + input CS2; + input CS1; + input CS0; + input RST; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); +module FIFO8KB (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - parameter REGMODE = "NOREG"; - parameter RESETMODE = "ASYNC"; parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b00"; parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; parameter FULLPOINTER1 = "0b00000000000000"; + parameter GSR = "DISABLED"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input CSW0; + input CSW1; + input CSR0; + input CSR1; + input WE; + input RE; + input ORE; + input CLKW; + input CLKR; + input RST; + input RPRST; + input FULLI; + input EMPTYI; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output EF; + output AEF; + output AFF; + output FF; +endmodule + +(* blackbox *) +module DCMA (...); + input CLK0; + input CLK1; + input SEL; + output DCMOUT; +endmodule + +(* blackbox *) +module DCCA (...); + input CLKI; + input CE; + output CLKO; +endmodule + +(* blackbox *) +module EHXPLLJ (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input LOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input RESETM; + input RESETC; + input RESETD; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input PLLCLK; + input PLLRST; + input PLLSTB; + input PLLWE; + input PLLDATI7; + input PLLDATI6; + input PLLDATI5; + input PLLDATI4; + input PLLDATI3; + input PLLDATI2; + input PLLDATI1; + input PLLDATI0; + input PLLADDR4; + input PLLADDR3; + input PLLADDR2; + input PLLADDR1; + input PLLADDR0; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output PLLDATO7; + output PLLDATO6; + output PLLDATO5; + output PLLDATO4; + output PLLDATO3; + output PLLDATO2; + output PLLDATO1; + output PLLDATO0; + output PLLACK; + output DPHSRC; + output CLKINTFB; endmodule + +(* blackbox *) +module OSCH (...); + parameter NOM_FREQ = "2.08"; + input STDBY; + output OSC; + output SEDSTDBY; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v index 3363ed5710d..c957b00293e 100644 --- a/techlibs/lattice/cells_bb_xo3d.v +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -1,179 +1,153 @@ -(* blackbox *) -module DP8KC( - input DIA8, DIA7, DIA6, DIA5, DIA4, DIA3, DIA2, DIA1, DIA0, - input ADA12, ADA11, ADA10, ADA9, ADA8, ADA7, ADA6, ADA5, ADA4, ADA3, ADA2, ADA1, ADA0, - input CEA, OCEA, CLKA, WEA, RSTA, - input CSA2, CSA1, CSA0, - output DOA8, DOA7, DOA6, DOA5, DOA4, DOA3, DOA2, DOA1, DOA0, - - input DIB8, DIB7, DIB6, DIB5, DIB4, DIB3, DIB2, DIB1, DIB0, - input ADB12, ADB11, ADB10, ADB9, ADB8, ADB7, ADB6, ADB5, ADB4, ADB3, ADB2, ADB1, ADB0, - input CEB, OCEB, CLKB, WEB, RSTB, - input CSB2, CSB1, CSB0, - output DOB8, DOB7, DOB6, DOB5, DOB4, DOB3, DOB2, DOB1, DOB0 -); - parameter DATA_WIDTH_A = 9; - parameter DATA_WIDTH_B = 9; - - parameter REGMODE_A = "NOREG"; - parameter REGMODE_B = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - - parameter CSDECODE_A = "0b000"; - parameter CSDECODE_B = "0b000"; - - parameter WRITEMODE_A = "NORMAL"; - parameter WRITEMODE_B = "NORMAL"; +// Created by cells_xtra.py from Lattice models - parameter GSR = "ENABLED"; - parameter INIT_DATA = "STATIC"; - - parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; +(* blackbox *) (* keep *) +module GSR (...); + input GSR; endmodule -(* blackbox *) -module EHXPLLJ ( - input CLKI, CLKFB, - input PHASESEL1, PHASESEL0, PHASEDIR, PHASESTEP, - input LOADREG, STDBY, PLLWAKESYNC, RST, RESETM, RESETC, RESETD, - input ENCLKOP, ENCLKOS, ENCLKOS2, ENCLKOS3, PLLCLK, PLLRST, PLLSTB, PLLWE, - input PLLDATI7, PLLDATI6, PLLDATI5, PLLDATI4, PLLDATI3, PLLDATI2, PLLDATI1, PLLDATI0, - input PLLADDR4, PLLADDR3, PLLADDR2, PLLADDR1, PLLADDR0, - output CLKOP, CLKOS, CLKOS2, CLKOS3, LOCK, INTLOCK, REFCLK, - output PLLDATO7, PLLDATO6, PLLDATO5, PLLDATO4, PLLDATO3, PLLDATO2, PLLDATO1, PLLDATO0, PLLACK, - output DPHSRC, CLKINTFB -); - parameter CLKI_DIV = 1; - parameter CLKFB_DIV = 1; - parameter CLKOP_DIV = 8; - parameter CLKOS_DIV = 8; - parameter CLKOS2_DIV = 8; - parameter CLKOS3_DIV = 8; - parameter CLKOP_ENABLE = "ENABLED"; - parameter CLKOS_ENABLE = "ENABLED"; - parameter CLKOS2_ENABLE = "ENABLED"; - parameter CLKOS3_ENABLE = "ENABLED"; - parameter VCO_BYPASS_A0 = "DISABLED"; - parameter VCO_BYPASS_B0 = "DISABLED"; - parameter VCO_BYPASS_C0 = "DISABLED"; - parameter VCO_BYPASS_D0 = "DISABLED"; - parameter CLKOP_CPHASE = 0; - parameter CLKOS_CPHASE = 0; - parameter CLKOS2_CPHASE = 0; - parameter CLKOS3_CPHASE = 0; - parameter CLKOP_FPHASE = 0; - parameter CLKOS_FPHASE = 0; - parameter CLKOS2_FPHASE = 0; - parameter CLKOS3_FPHASE = 0; - parameter FEEDBK_PATH = "CLKOP"; - parameter FRACN_ENABLE = "DISABLED"; - parameter FRACN_DIV = 0; - parameter CLKOP_TRIM_POL = "RISING"; - parameter CLKOP_TRIM_DELAY = 0; - parameter CLKOS_TRIM_POL = "RISING"; - parameter CLKOS_TRIM_DELAY = 0; - parameter PLL_USE_WB = "DISABLED"; - parameter PREDIVIDER_MUXA1 = 0; - parameter PREDIVIDER_MUXB1 = 0; - parameter PREDIVIDER_MUXC1 = 0; - parameter PREDIVIDER_MUXD1 = 0; - parameter OUTDIVIDER_MUXA2 = "DIVA"; - parameter OUTDIVIDER_MUXB2 = "DIVB"; - parameter OUTDIVIDER_MUXC2 = "DIVC"; - parameter OUTDIVIDER_MUXD2 = "DIVD"; - parameter PLL_LOCK_MODE = 0; - parameter STDBY_ENABLE = "DISABLED"; - parameter DPHASE_SOURCE = "DISABLED"; - parameter PLLRST_ENA = "DISABLED"; - parameter MRST_ENA = "DISABLED"; - parameter DCRST_ENA = "DISABLED"; - parameter DDRST_ENA = "DISABLED"; - parameter INTFB_WAKE = "DISABLED"; -endmodule - -(* blackbox *) -module OSCH #( - parameter NOM_FREQ = "2.08" -) ( - input STDBY, - output OSC, - output SEDSTDBY -); -endmodule - -(* blackbox *) -module DCCA ( - input CLKI, - input CE, - output CLKO -); +(* blackbox *) (* keep *) +module SGSR (...); + input GSR; + input CLK; endmodule (* blackbox *) -module DCMA ( - input CLK0, - input CLK1, - input SEL, - output DCMOUT -); +module DP8KC (...); + parameter DATA_WIDTH_A = 9; + parameter DATA_WIDTH_B = 9; + parameter REGMODE_A = "NOREG"; + parameter REGMODE_B = "NOREG"; + parameter CSDECODE_A = "0b000"; + parameter CSDECODE_B = "0b000"; + parameter WRITEMODE_A = "NORMAL"; + parameter WRITEMODE_B = "NORMAL"; + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; + parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_03 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_04 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_05 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_06 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_07 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_08 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_09 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_0F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_10 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_11 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_12 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_13 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_14 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_15 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_16 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_17 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_18 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_19 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1A = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1B = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1C = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; + input DIA8; + input DIA7; + input DIA6; + input DIA5; + input DIA4; + input DIA3; + input DIA2; + input DIA1; + input DIA0; + input ADA12; + input ADA11; + input ADA10; + input ADA9; + input ADA8; + input ADA7; + input ADA6; + input ADA5; + input ADA4; + input ADA3; + input ADA2; + input ADA1; + input ADA0; + input CEA; + input OCEA; + input CLKA; + input WEA; + input CSA2; + input CSA1; + input CSA0; + input RSTA; + input DIB8; + input DIB7; + input DIB6; + input DIB5; + input DIB4; + input DIB3; + input DIB2; + input DIB1; + input DIB0; + input ADB12; + input ADB11; + input ADB10; + input ADB9; + input ADB8; + input ADB7; + input ADB6; + input ADB5; + input ADB4; + input ADB3; + input ADB2; + input ADB1; + input ADB0; + input CEB; + input OCEB; + input CLKB; + input WEB; + input CSB2; + input CSB1; + input CSB0; + input RSTB; + output DOA8; + output DOA7; + output DOA6; + output DOA5; + output DOA4; + output DOA3; + output DOA2; + output DOA1; + output DOA0; + output DOB8; + output DOB7; + output DOB6; + output DOB5; + output DOB4; + output DOB3; + output DOB2; + output DOB1; + output DOB0; endmodule (* blackbox *) -module PDPW8KC ( - input DI17, DI16, DI15, DI14, DI13, DI12, DI11, DI10, DI9, DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input ADW8, ADW7, ADW6, ADW5, ADW4, ADW3, ADW2, ADW1, ADW0, - input BE1, BE0, - input CEW, CLKW, CSW2, CSW1, CSW0, - input ADR12, ADR11, ADR10, ADR9, ADR8, ADR7, ADR6, ADR5, ADR4, ADR3, ADR2, ADR1, ADR0, - input CER, OCER, CLKR, CSR2, CSR1, CSR0, RST, - output DO17, DO16, DO15, DO14, DO13, DO12, DO11, DO10, DO9, DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module PDPW8KC (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 9; - - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b000"; parameter CSDECODE_R = "0b000"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -206,29 +180,90 @@ module PDPW8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; - + input DI17; + input DI16; + input DI15; + input DI14; + input DI13; + input DI12; + input DI11; + input DI10; + input DI9; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input ADW8; + input ADW7; + input ADW6; + input ADW5; + input ADW4; + input ADW3; + input ADW2; + input ADW1; + input ADW0; + input BE1; + input BE0; + input CEW; + input CLKW; + input CSW2; + input CSW1; + input CSW0; + input ADR12; + input ADR11; + input ADR10; + input ADR9; + input ADR8; + input ADR7; + input ADR6; + input ADR5; + input ADR4; + input ADR3; + input ADR2; + input ADR1; + input ADR0; + input CER; + input OCER; + input CLKR; + input CSR2; + input CSR1; + input CSR0; + input RST; + output DO17; + output DO16; + output DO15; + output DO14; + output DO13; + output DO12; + output DO11; + output DO10; + output DO9; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module SP8KC ( - input DI8, DI7, DI6, DI5, DI4, DI3, DI2, DI1, DI0, - input AD12, AD11, AD10, AD9, AD8, AD7, AD6, AD5, AD4, AD3, AD2, AD1, AD0, - input CE, OCE, CLK, WE, CS2, CS1, CS0, RST, - output DO8, DO7, DO6, DO5, DO4, DO3, DO2, DO1, DO0 -); +module SP8KC (...); parameter DATA_WIDTH = 9; - parameter GSR = "ENABLED"; - parameter REGMODE = "NOREG"; - - parameter RESETMODE = "SYNC"; - parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE = "0b000"; - parameter WRITEMODE = "NORMAL"; - + parameter GSR = "ENABLED"; + parameter RESETMODE = "SYNC"; + parameter ASYNC_RESET_RELEASE = "SYNC"; + parameter INIT_DATA = "STATIC"; parameter INITVAL_00 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_01 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_02 = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; @@ -261,33 +296,241 @@ module SP8KC ( parameter INITVAL_1D = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1E = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; parameter INITVAL_1F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000; - parameter INIT_DATA = "STATIC"; + input DI8; + input DI7; + input DI6; + input DI5; + input DI4; + input DI3; + input DI2; + input DI1; + input DI0; + input AD12; + input AD11; + input AD10; + input AD9; + input AD8; + input AD7; + input AD6; + input AD5; + input AD4; + input AD3; + input AD2; + input AD1; + input AD0; + input CE; + input OCE; + input CLK; + input WE; + input CS2; + input CS1; + input CS0; + input RST; + output DO8; + output DO7; + output DO6; + output DO5; + output DO4; + output DO3; + output DO2; + output DO1; + output DO0; endmodule (* blackbox *) -module FIFO8KB ( - input DI0, DI1, DI2, DI3, DI4, DI5, DI6, DI7, DI8, DI9, DI10, DI11, DI12, DI13, DI14, DI15, DI16, DI17, - input CSW0, CSW1, CSR0, CSR1, WE, RE, ORE, CLKW, CLKR, RST, RPRST, FULLI, EMPTYI, - output DO0, DO1, DO2, DO3, DO4, DO5, DO6, DO7, DO8, DO9, DO10, DO11, DO12, DO13, DO14, DO15, DO16, DO17, - input EF, AEF, AFF, FF -); +module FIFO8KB (...); parameter DATA_WIDTH_W = 18; parameter DATA_WIDTH_R = 18; - - parameter GSR = "DISABLED"; - parameter REGMODE = "NOREG"; - parameter RESETMODE = "ASYNC"; parameter ASYNC_RESET_RELEASE = "SYNC"; - parameter CSDECODE_W = "0b00"; parameter CSDECODE_R = "0b00"; - - parameter AEPOINTER = "0b00000000000000"; - parameter AEPOINTER1 = "0b00000000000000"; - parameter AFPOINTER = "0b00000000000000"; - parameter AFPOINTER1 = "0b00000000000000"; - parameter FULLPOINTER = "0b00000000000000"; + parameter AEPOINTER = "0b00000000000000"; + parameter AEPOINTER1 = "0b00000000000000"; + parameter AFPOINTER = "0b00000000000000"; + parameter AFPOINTER1 = "0b00000000000000"; + parameter FULLPOINTER = "0b00000000000000"; parameter FULLPOINTER1 = "0b00000000000000"; + parameter GSR = "DISABLED"; + input DI0; + input DI1; + input DI2; + input DI3; + input DI4; + input DI5; + input DI6; + input DI7; + input DI8; + input DI9; + input DI10; + input DI11; + input DI12; + input DI13; + input DI14; + input DI15; + input DI16; + input DI17; + input CSW0; + input CSW1; + input CSR0; + input CSR1; + input WE; + input RE; + input ORE; + input CLKW; + input CLKR; + input RST; + input RPRST; + input FULLI; + input EMPTYI; + output DO0; + output DO1; + output DO2; + output DO3; + output DO4; + output DO5; + output DO6; + output DO7; + output DO8; + output DO9; + output DO10; + output DO11; + output DO12; + output DO13; + output DO14; + output DO15; + output DO16; + output DO17; + output EF; + output AEF; + output AFF; + output FF; +endmodule + +(* blackbox *) +module DCMA (...); + input CLK0; + input CLK1; + input SEL; + output DCMOUT; +endmodule + +(* blackbox *) +module DCCA (...); + input CLKI; + input CE; + output CLKO; +endmodule + +(* blackbox *) +module EHXPLLJ (...); + parameter CLKI_DIV = 1; + parameter CLKFB_DIV = 1; + parameter CLKOP_DIV = 8; + parameter CLKOS_DIV = 8; + parameter CLKOS2_DIV = 8; + parameter CLKOS3_DIV = 8; + parameter CLKOP_ENABLE = "ENABLED"; + parameter CLKOS_ENABLE = "ENABLED"; + parameter CLKOS2_ENABLE = "ENABLED"; + parameter CLKOS3_ENABLE = "ENABLED"; + parameter VCO_BYPASS_A0 = "DISABLED"; + parameter VCO_BYPASS_B0 = "DISABLED"; + parameter VCO_BYPASS_C0 = "DISABLED"; + parameter VCO_BYPASS_D0 = "DISABLED"; + parameter CLKOP_CPHASE = 0; + parameter CLKOS_CPHASE = 0; + parameter CLKOS2_CPHASE = 0; + parameter CLKOS3_CPHASE = 0; + parameter CLKOP_FPHASE = 0; + parameter CLKOS_FPHASE = 0; + parameter CLKOS2_FPHASE = 0; + parameter CLKOS3_FPHASE = 0; + parameter FEEDBK_PATH = "CLKOP"; + parameter FRACN_ENABLE = "DISABLED"; + parameter FRACN_DIV = 0; + parameter CLKOP_TRIM_POL = "RISING"; + parameter CLKOP_TRIM_DELAY = 0; + parameter CLKOS_TRIM_POL = "RISING"; + parameter CLKOS_TRIM_DELAY = 0; + parameter PLL_USE_WB = "DISABLED"; + parameter PREDIVIDER_MUXA1 = 0; + parameter PREDIVIDER_MUXB1 = 0; + parameter PREDIVIDER_MUXC1 = 0; + parameter PREDIVIDER_MUXD1 = 0; + parameter OUTDIVIDER_MUXA2 = "DIVA"; + parameter OUTDIVIDER_MUXB2 = "DIVB"; + parameter OUTDIVIDER_MUXC2 = "DIVC"; + parameter OUTDIVIDER_MUXD2 = "DIVD"; + parameter PLL_LOCK_MODE = 0; + parameter STDBY_ENABLE = "DISABLED"; + parameter DPHASE_SOURCE = "DISABLED"; + parameter PLLRST_ENA = "DISABLED"; + parameter MRST_ENA = "DISABLED"; + parameter DCRST_ENA = "DISABLED"; + parameter DDRST_ENA = "DISABLED"; + parameter INTFB_WAKE = "DISABLED"; + input CLKI; + input CLKFB; + input PHASESEL1; + input PHASESEL0; + input PHASEDIR; + input PHASESTEP; + input LOADREG; + input STDBY; + input PLLWAKESYNC; + input RST; + input RESETM; + input RESETC; + input RESETD; + input ENCLKOP; + input ENCLKOS; + input ENCLKOS2; + input ENCLKOS3; + input PLLCLK; + input PLLRST; + input PLLSTB; + input PLLWE; + input PLLDATI7; + input PLLDATI6; + input PLLDATI5; + input PLLDATI4; + input PLLDATI3; + input PLLDATI2; + input PLLDATI1; + input PLLDATI0; + input PLLADDR4; + input PLLADDR3; + input PLLADDR2; + input PLLADDR1; + input PLLADDR0; + output CLKOP; + output CLKOS; + output CLKOS2; + output CLKOS3; + output LOCK; + output INTLOCK; + output REFCLK; + output PLLDATO7; + output PLLDATO6; + output PLLDATO5; + output PLLDATO4; + output PLLDATO3; + output PLLDATO2; + output PLLDATO1; + output PLLDATO0; + output PLLACK; + output DPHSRC; + output CLKINTFB; endmodule + +(* blackbox *) +module OSCJ (...); + parameter NOM_FREQ = "2.08"; + input STDBY; + output OSC; + output SEDSTDBY; + output OSCESB; +endmodule + diff --git a/techlibs/lattice/cells_xtra.py b/techlibs/lattice/cells_xtra.py new file mode 100644 index 00000000000..f2dd1f29749 --- /dev/null +++ b/techlibs/lattice/cells_xtra.py @@ -0,0 +1,854 @@ +#!/usr/bin/env python3 + +# Based on Xilinx cells_xtra.py; modified for Lattice's structure + +from argparse import ArgumentParser +from io import StringIO +from enum import Enum, auto +import os.path +import sys +import re + + +class Cell: + def __init__(self, name, keep=False, port_attrs={}): + self.name = name + self.keep = keep + self.port_attrs = port_attrs + self.found = False + +class State(Enum): + OUTSIDE = auto() + IN_MODULE = auto() + IN_OTHER_MODULE = auto() + IN_FUNCTION = auto() + IN_TASK = auto() + +devices = [ + ("cells_bb_ecp5.v", "ecp5u", [ + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("CCU2C"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("PFUMX"), + Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + Cell("SGSR", True), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + Cell("DP16KD"), + Cell("PDPW16KD"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + #Cell("LVDSOB"), + #Cell("IMIPI"), + #Cell("MULT9X9C"), + #Cell("MULT9X9D"), + #Cell("MULT18X18C"), + Cell("MULT18X18D"), + #Cell("ALU24A"), + #Cell("ALU54A"), + #Cell("ALU24B"), + Cell("ALU54B"), + #Cell("PRADD9A"), + #Cell("PRADD18A"), + #Cell("BCINRD"), + #Cell("BCLVDSOB"), + #Cell("INRDB"), + Cell("CLKDIVF"), + Cell("PCSCLKDIV"), + Cell("DCSC"), + Cell("DCCA"), + Cell("ECLKSYNCB"), + Cell("ECLKBRIDGECS"), + #Cell("PLLREFCS"), + Cell("DELAYF"), + Cell("DELAYG"), + #Cell("START"), + Cell("USRMCLK", True), + Cell("DQSBUFM"), + Cell("DDRDLLA"), + Cell("DLLDELD"), + Cell("IDDRX1F"), + Cell("IDDRX2F"), + Cell("IDDR71B"), + Cell("IDDRX2DQA"), + Cell("ODDRX1F"), + Cell("ODDRX2F"), + Cell("ODDR71B"), + Cell("OSHX2A"), + Cell("TSHX2DQA"), + Cell("TSHX2DQSA"), + Cell("ODDRX2DQA"), + Cell("ODDRX2DQSB"), + Cell("EHXPLLL"), + Cell("DTR"), + Cell("OSCG"), + Cell("EXTREFB"), + Cell("JTAGG", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + #Cell("SEDGA"), + Cell("DCUA", True, port_attrs={'CH0_HDINP': ['iopad_external_pin'], 'CH1_HDINP': ['iopad_external_pin'], 'CH0_HDINN': ['iopad_external_pin'], 'CH1_HDINN': ['iopad_external_pin']}), + ]), + ("cells_bb_xo2.v", "machxo2", [ + #Cell("AGEB2"), + #Cell("ALEB2"), + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("ANEB2"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("BBW"), + #Cell("CB2"), + #Cell("CD2"), + #Cell("CU2"), + #Cell("FADD2B"), + #Cell("FADSU2"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S1A"), + #Cell("FD1S1AY"), + #Cell("FD1S1B"), + #Cell("FD1S1D"), + #Cell("FD1S1I"), + #Cell("FD1S1J"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S1A"), + #Cell("FL1S1AY"), + #Cell("FL1S1B"), + #Cell("FL1S1D"), + #Cell("FL1S1I"), + #Cell("FL1S1J"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + #Cell("FSUB2B"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LB2P3AX"), + #Cell("LB2P3AY"), + #Cell("LB2P3BX"), + #Cell("LB2P3DX"), + #Cell("LB2P3IX"), + #Cell("LB2P3JX"), + #Cell("LD2P3AX"), + #Cell("LD2P3AY"), + #Cell("LD2P3BX"), + #Cell("LD2P3DX"), + #Cell("LD2P3IX"), + #Cell("LD2P3JX"), + #Cell("LU2P3AX"), + #Cell("LU2P3AY"), + #Cell("LU2P3BX"), + #Cell("LU2P3DX"), + #Cell("LU2P3IX"), + #Cell("LU2P3JX"), + #Cell("MULT2"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("PFUMX"), + #Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + #Cell("CCU2D"), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + Cell("SGSR", True), + Cell("DP8KC"), + Cell("PDPW8KC"), + Cell("SP8KC"), + Cell("FIFO8KB"), + #Cell("CLKDIVC"), + Cell("DCMA"), + #Cell("ECLKSYNCA"), + #Cell("ECLKBRIDGECS"), + Cell("DCCA"), + #Cell("JTAGF"), + #Cell("START"), + #Cell("SEDFA"), + #Cell("SEDFB"), + #Cell("IDDRXE"), + #Cell("IDDRX2E"), + #Cell("IDDRX4B"), + #Cell("IDDRDQSX1A"), + #Cell("IDDRX71A"), + #Cell("ODDRXE"), + #Cell("ODDRX2E"), + #Cell("ODDRX4B"), + #Cell("ODDRDQSX1A"), + #Cell("ODDRX71A"), + #Cell("TDDRA"), + #Cell("DQSBUFH"), + #Cell("DQSDLLC"), + #Cell("DELAYE"), + #Cell("DELAYD"), + #Cell("DLLDELC"), + #Cell("CLKFBBUFA"), + #Cell("PCNTR"), + #Cell("BCINRD"), + #Cell("BCLVDSO"), + #Cell("INRDB"), + #Cell("LVDSOB"), + #Cell("PG"), + Cell("EHXPLLJ"), + #Cell("PLLREFCS"), + Cell("OSCH"), + #Cell("EFB"), + #Cell("TSALL"), + ]), + ("cells_bb_xo3.v", "machxo3lf", [ + #Cell("AGEB2"), + #Cell("ALEB2"), + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("ANEB2"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("BBW"), + #Cell("CB2"), + #Cell("CD2"), + #Cell("CU2"), + #Cell("FADD2B"), + #Cell("FADSU2"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S1A"), + #Cell("FD1S1AY"), + #Cell("FD1S1B"), + #Cell("FD1S1D"), + #Cell("FD1S1I"), + #Cell("FD1S1J"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S1A"), + #Cell("FL1S1AY"), + #Cell("FL1S1B"), + #Cell("FL1S1D"), + #Cell("FL1S1I"), + #Cell("FL1S1J"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + #Cell("FSUB2B"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LB2P3AX"), + #Cell("LB2P3AY"), + #Cell("LB2P3BX"), + #Cell("LB2P3DX"), + #Cell("LB2P3IX"), + #Cell("LB2P3JX"), + #Cell("LD2P3AX"), + #Cell("LD2P3AY"), + #Cell("LD2P3BX"), + #Cell("LD2P3DX"), + #Cell("LD2P3IX"), + #Cell("LD2P3JX"), + #Cell("LU2P3AX"), + #Cell("LU2P3AY"), + #Cell("LU2P3BX"), + #Cell("LU2P3DX"), + #Cell("LU2P3IX"), + #Cell("LU2P3JX"), + #Cell("MULT2"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("PFUMX"), + #Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + #Cell("CCU2D"), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + Cell("SGSR", True), + Cell("DP8KC"), + Cell("PDPW8KC"), + Cell("SP8KC"), + Cell("FIFO8KB"), + #Cell("CLKDIVC"), + Cell("DCMA"), + #Cell("ECLKSYNCA"), + #Cell("ECLKBRIDGECS"), + Cell("DCCA"), + #Cell("JTAGF"), + #Cell("START"), + #Cell("SEDFA"), + #Cell("SEDFB"), + #Cell("IDDRXE"), + #Cell("IDDRX2E"), + #Cell("IDDRX4B"), + #Cell("IDDRX71A"), + #Cell("ODDRXE"), + #Cell("ODDRX2E"), + #Cell("ODDRX4B"), + #Cell("ODDRX71A"), + #Cell("DQSDLLC"), + #Cell("DELAYE"), + #Cell("DELAYD"), + #Cell("DLLDELC"), + #Cell("CLKFBBUFA"), + #Cell("PCNTR"), + #Cell("BCINRD"), + #Cell("BCLVDSO"), + #Cell("INRDB"), + #Cell("LVDSOB"), + #Cell("PG"), + Cell("EHXPLLJ"), + #Cell("PLLREFCS"), + Cell("OSCH"), + #Cell("EFB"), + #Cell("TSALL"), + ]), + ("cells_bb_xo3d.v", "machxo3d", [ + #Cell("AGEB2"), + #Cell("ALEB2"), + #Cell("AND2"), + #Cell("AND3"), + #Cell("AND4"), + #Cell("AND5"), + #Cell("ANEB2"), + #Cell("BB"), + #Cell("BBPD"), + #Cell("BBPU"), + #Cell("BBI3C"), + #Cell("BBW"), + #Cell("CB2"), + #Cell("CD2"), + #Cell("CU2"), + #Cell("FADD2B"), + #Cell("FADSU2"), + #Cell("FD1P3AX"), + #Cell("FD1P3AY"), + #Cell("FD1P3BX"), + #Cell("FD1P3DX"), + #Cell("FD1P3IX"), + #Cell("FD1P3JX"), + #Cell("FD1S1A"), + #Cell("FD1S1AY"), + #Cell("FD1S1B"), + #Cell("FD1S1D"), + #Cell("FD1S1I"), + #Cell("FD1S1J"), + #Cell("FD1S3AX"), + #Cell("FD1S3AY"), + #Cell("FD1S3BX"), + #Cell("FD1S3DX"), + #Cell("FD1S3IX"), + #Cell("FD1S3JX"), + #Cell("FL1P3AY"), + #Cell("FL1P3AZ"), + #Cell("FL1P3BX"), + #Cell("FL1P3DX"), + #Cell("FL1P3IY"), + #Cell("FL1P3JY"), + #Cell("FL1S1A"), + #Cell("FL1S1AY"), + #Cell("FL1S1B"), + #Cell("FL1S1D"), + #Cell("FL1S1I"), + #Cell("FL1S1J"), + #Cell("FL1S3AX"), + #Cell("FL1S3AY"), + #Cell("FSUB2B"), + Cell("GSR", True), + #Cell("IB"), + #Cell("IBPD"), + #Cell("IBPU"), + #Cell("IFS1P3BX"), + #Cell("IFS1P3DX"), + #Cell("IFS1P3IX"), + #Cell("IFS1P3JX"), + #Cell("ILVDS"), + #Cell("INV"), + #Cell("L6MUX21"), + #Cell("LB2P3AX"), + #Cell("LB2P3AY"), + #Cell("LB2P3BX"), + #Cell("LB2P3DX"), + #Cell("LB2P3IX"), + #Cell("LB2P3JX"), + #Cell("LD2P3AX"), + #Cell("LD2P3AY"), + #Cell("LD2P3BX"), + #Cell("LD2P3DX"), + #Cell("LD2P3IX"), + #Cell("LD2P3JX"), + #Cell("LU2P3AX"), + #Cell("LU2P3AY"), + #Cell("LU2P3BX"), + #Cell("LU2P3DX"), + #Cell("LU2P3IX"), + #Cell("LU2P3JX"), + #Cell("MULT2"), + #Cell("MUX161"), + #Cell("MUX21"), + #Cell("MUX321"), + #Cell("MUX41"), + #Cell("MUX81"), + #Cell("ND2"), + #Cell("ND3"), + #Cell("ND4"), + #Cell("ND5"), + #Cell("NR2"), + #Cell("NR3"), + #Cell("NR4"), + #Cell("NR5"), + #Cell("OB"), + #Cell("OBCO"), + #Cell("OBZ"), + #Cell("OBZPU"), + #Cell("OFS1P3BX"), + #Cell("OFS1P3DX"), + #Cell("OFS1P3IX"), + #Cell("OFS1P3JX"), + #Cell("OLVDS"), + #Cell("OR2"), + #Cell("OR3"), + #Cell("OR4"), + #Cell("OR5"), + #Cell("LUT4"), + #Cell("LUT5"), + #Cell("LUT6"), + #Cell("LUT7"), + #Cell("LUT8"), + #Cell("PFUMX"), + #Cell("PUR"), + #Cell("ROM128X1A"), + #Cell("ROM16X1A"), + #Cell("ROM256X1A"), + #Cell("ROM32X1A"), + #Cell("ROM64X1A"), + #Cell("CCU2D"), + #Cell("VHI"), + #Cell("VLO"), + #Cell("XNOR2"), + #Cell("XNOR3"), + #Cell("XNOR4"), + #Cell("XNOR5"), + #Cell("XOR11"), + #Cell("XOR2"), + #Cell("XOR21"), + #Cell("XOR3"), + #Cell("XOR4"), + #Cell("XOR5"), + #Cell("IFS1S1B"), + #Cell("IFS1S1D"), + #Cell("IFS1S1I"), + #Cell("IFS1S1J"), + #Cell("DPR16X4C"), + #Cell("SPR16X4C"), + Cell("SGSR", True), + Cell("DP8KC"), + Cell("PDPW8KC"), + Cell("SP8KC"), + Cell("FIFO8KB"), + #Cell("CLKDIVC"), + Cell("DCMA"), + #Cell("ECLKSYNCA"), + #Cell("ECLKBRIDGECS"), + Cell("DCCA"), + #Cell("JTAGF"), + #Cell("START"), + #Cell("SEDFA"), + #Cell("SEDFB"), + #Cell("IDDRXE"), + #Cell("IDDRX2E"), + #Cell("IDDRX4B"), + #Cell("IDDRX71A"), + #Cell("ODDRXE"), + #Cell("ODDRX2E"), + #Cell("ODDRX4B"), + #Cell("ODDRX71A"), + #Cell("DQSDLLC"), + #Cell("DELAYE"), + #Cell("DELAYD"), + #Cell("DLLDELC"), + #Cell("CLKFBBUFA"), + #Cell("PCNTR"), + #Cell("BCINRD"), + #Cell("BCLVDSO"), + #Cell("INRDB"), + #Cell("LVDSOB"), + #Cell("PG"), + Cell("EHXPLLJ"), + #Cell("PLLREFCS"), + Cell("OSCJ"), + #Cell("EFBB"), + #Cell("TSALL"), + #Cell("ESBA"), + #Cell("BCSLEWRATEA"), + ]) +] + +def xtract_cells_decl(device, cells, dirs, outf): + fname = os.path.join(dir, device + '.v') + with open(fname) as f: + state = State.OUTSIDE + # Probably the most horrible Verilog "parser" ever written. + cell = None + kind = None + for l in f: + l, _, comment = l.partition('//') + l = l.strip() + m = re.search(r'synthesis .*black_box_pad_pin="([^"]*)"', comment) + if m: + iopad_pin = set(m.group(1).split(",")) + + if l.startswith("module "): + cell_name = l[7:l.find('(')].strip() + cell = None + kind = None + module_ports = [] + iopad_pin = set() + if state != State.OUTSIDE: + print('Nested modules in {}.'.format(fname)) + sys.exit(1) + for c in cells: + if c.name != cell_name: + continue + cell = c + state = State.IN_MODULE + outf.write('(* blackbox *)') + if cell.keep: + outf.write(' (* keep *)\n') + else: + outf.write('\n') + outf.write('module {} (...);\n'.format(cell.name)) + cell.found = True + if cell is None: + state = State.IN_OTHER_MODULE + elif l.startswith('task '): + if state == State.IN_MODULE: + state = State.IN_TASK + elif l.startswith('function '): + if state == State.IN_MODULE: + state = State.IN_FUNCTION + elif l == 'endtask': + if state == State.IN_TASK: + state = State.IN_MODULE + elif l == 'endfunction': + if state == State.IN_FUNCTION: + state = State.IN_MODULE + elif l == 'endmodule': + if state == State.IN_MODULE: + for kind, rng, port in module_ports: + for attr in cell.port_attrs.get(port, []): + outf.write(' (* {} *)\n'.format(attr)) + if port in iopad_pin: + outf.write(' (* iopad_external_pin *)\n') + if rng is None: + outf.write(' {} {};\n'.format(kind, port)) + else: + outf.write(' {} {} {};\n'.format(kind, rng, port)) + outf.write(l + '\n') + outf.write('\n') + elif state != State.IN_OTHER_MODULE: + print('endmodule in weird place in {}.'.format(cell.name, fname)) + sys.exit(1) + state = State.OUTSIDE + elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: + l = l.strip() + if l == "": + continue + if l.endswith((';', ',', ")")): + l = l[:-1] + l = l.replace(")","") + if ';' in l: + print('Weird port line in {} [{}].'.format(fname, l)) + sys.exit(1) + kind, _, ports = l.partition(' ') + for port in ports.split(','): + port = port.strip() + if port.startswith('['): + rng, port = port.split() + else: + rng = None + module_ports.append((kind, rng, port)) + elif l.startswith('parameter ') and state == State.IN_MODULE: + l = l.strip() + if l.endswith((';', ',')): + l = l[:-1] + while ' ' in l: + l = l.replace(' ', ' ') + + if "INITVAL" in l: + l = l.replace('"0x', "320'h") + l = l.replace('"', '') + if ';' in l: + print('Weird parameter line in {} [{}].'.format(fname, l)) + sys.exit(1) + outf.write(' {};\n'.format(l)) + elif kind is not None and state == State.IN_MODULE: + l = l.strip() + if l == "": + continue + if l.endswith((';', ',', ")")): + l = l[:-1] + l = l.replace(")","") + if ';' in l: + print('Weird port line in {} [{}].'.format(fname, l)) + sys.exit(1) + ports = l + for port in ports.split(','): + port = port.strip() + if port.startswith('['): + rng, port = port.split() + else: + rng = None + module_ports.append((kind, rng, port)) + + if state != State.OUTSIDE: + print('endmodule not found in {}.'.format(fname)) + sys.exit(1) + for cell in cells: + if not cell.found: + print('cell {} not found in {}.'.format(cell.name, fname)) +if __name__ == '__main__': + parser = ArgumentParser(description='Extract Lattice blackbox cell definitions from Lattice Diamond.') + parser.add_argument('diamond_dir', nargs='?', default='/usr/local/diamond/3.12/') + args = parser.parse_args() + + dirs = [ + os.path.join(args.diamond_dir, 'cae_library/synthesis/verilog/'), + ] + for dir in dirs: + if not os.path.isdir(dir): + print('{} is not a directory'.format(dir)) + + for fn, device, cells in devices: + out = StringIO() + xtract_cells_decl(device, cells, dirs, out) + with open(fn, 'w') as f: + f.write('// Created by cells_xtra.py from Lattice models\n') + f.write('\n') + f.write(out.getvalue()) From 3b9ebfa672c2ecd413123368aff7eba64aecf0e6 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 25 Aug 2023 11:10:20 +0200 Subject: [PATCH 263/303] Addressed code review comments --- techlibs/lattice/synth_lattice.cc | 91 ++----------------------------- tests/arch/machxo2/add_sub.ys | 2 +- tests/arch/machxo2/adffs.ys | 8 +-- tests/arch/machxo2/counter.ys | 2 +- tests/arch/machxo2/dffs.ys | 4 +- tests/arch/machxo2/fsm.ys | 2 +- tests/arch/machxo2/logic.ys | 2 +- tests/arch/machxo2/lutram.ys | 2 +- tests/arch/machxo2/mux.ys | 8 +-- tests/arch/machxo2/shifter.ys | 2 +- tests/arch/machxo2/tribuf.ys | 2 +- 11 files changed, 21 insertions(+), 104 deletions(-) diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index edca6855e08..ff5070b8073 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -41,7 +41,7 @@ struct SynthLatticePass : public ScriptPass log("\n"); log(" synth_lattice [options]\n"); log("\n"); - log("This command runs synthesis for Lattice FPGAs.\n"); + log("This command runs synthesis for Lattice FPGAs (excluding iCE40 and Nexus).\n"); log("\n"); log(" -top \n"); log(" use the specified module as top module\n"); @@ -66,10 +66,6 @@ struct SynthLatticePass : public ScriptPass //log(" - lifmd: LIFMD (EXPERIMENTAL)\n"); //log(" - lifmdf: LIFMDF (EXPERIMENTAL)\n"); log("\n"); - log(" -blif \n"); - log(" write the design to the specified BLIF file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); log(" -edif \n"); log(" write the design to the specified EDIF file. writing of an output file\n"); log(" is omitted if this parameter is not specified.\n"); @@ -116,10 +112,6 @@ struct SynthLatticePass : public ScriptPass log(" -abc9\n"); log(" use new ABC9 flow (EXPERIMENTAL)\n"); log("\n"); - log(" -vpr\n"); - log(" generate an output netlist (and BLIF file) suitable for VPR\n"); - log(" (this feature is experimental and incomplete)\n"); - log("\n"); log(" -iopad\n"); log(" insert IO buffers\n"); log("\n"); @@ -137,14 +129,13 @@ struct SynthLatticePass : public ScriptPass log("\n"); } - string top_opt, blif_file, edif_file, json_file, family; - bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, vpr, no_rw_check, have_dsp; + string top_opt, edif_file, json_file, family; + bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, no_rw_check, have_dsp; string postfix, arith_map, brams_map, dsp_map; void clear_flags() override { top_opt = "-auto-top"; - blif_file = ""; edif_file = ""; json_file = ""; family = ""; @@ -158,7 +149,6 @@ struct SynthLatticePass : public ScriptPass dff = false; retime = false; abc2 = false; - vpr = false; abc9 = false; iopad = false; nodsp = false; @@ -186,10 +176,6 @@ struct SynthLatticePass : public ScriptPass family = args[++argidx]; continue; } - if (args[argidx] == "-blif" && argidx+1 < args.size()) { - blif_file = args[++argidx]; - continue; - } if (args[argidx] == "-edif" && argidx+1 < args.size()) { edif_file = args[++argidx]; continue; @@ -250,10 +236,6 @@ struct SynthLatticePass : public ScriptPass abc2 = true; continue; } - if (args[argidx] == "-vpr") { - vpr = true; - continue; - } if (args[argidx] == "-abc9") { abc9 = true; continue; @@ -461,10 +443,7 @@ struct SynthLatticePass : public ScriptPass if (check_label("map_cells")) { - if (help_mode) - run("techmap -map +/lattice/cells_map.v", "(skip if -vpr)"); - else if (!vpr) - run("techmap -map +/lattice/cells_map.v"); + run("techmap -map +/lattice/cells_map.v"); run("opt_lut_ins -tech lattice"); run("clean"); } @@ -478,23 +457,6 @@ struct SynthLatticePass : public ScriptPass run("blackbox =A:whitebox"); } - if (check_label("blif")) - { - if (!blif_file.empty() || help_mode) { - if (vpr || help_mode) { - run(stringf("opt_clean -purge"), - " (vpr mode)"); - run(stringf("write_blif -attr -cname -conn -param %s", - help_mode ? "" : blif_file.c_str()), - " (vpr mode)"); - } - if (!vpr) - run(stringf("write_blif -gates -attr -param %s", - help_mode ? "" : blif_file.c_str()), - " (non-vpr mode)"); - } - } - if (check_label("edif")) { if (!edif_file.empty() || help_mode) @@ -526,49 +488,4 @@ struct SynthEcp5Pass : public Pass } SynthEcp5Pass; */ -struct SynthMachXO2Pass : public Pass -{ - SynthMachXO2Pass() : Pass("synth_machxo2", "synthesis for MachXO2 FPGAs.") { } - - void execute(std::vector args, RTLIL::Design *design) override - { - args[0] = "synth_lattice"; - args.insert(args.begin()+1, std::string()); - args.insert(args.begin()+1, std::string()); - args[1] = "-family"; - args[2] = "xo2"; - Pass::call(design, args); - } -} SynthMachXO2Pass; - -struct SynthMachXO3Pass : public Pass -{ - SynthMachXO3Pass() : Pass("synth_machxo3", "synthesis for MachXO3 FPGAs.") { } - - void execute(std::vector args, RTLIL::Design *design) override - { - args[0] = "synth_lattice"; - args.insert(args.begin()+1, std::string()); - args.insert(args.begin()+1, std::string()); - args[1] = "-family"; - args[2] = "xo3"; - Pass::call(design, args); - } -} SynthMachXO3Pass; - -struct SynthMachXO3DPass : public Pass -{ - SynthMachXO3DPass() : Pass("synth_machxo3d", "synthesis for MachXO3D FPGAs.") { } - - void execute(std::vector args, RTLIL::Design *design) override - { - args[0] = "synth_lattice"; - args.insert(args.begin()+1, std::string()); - args.insert(args.begin()+1, std::string()); - args[1] = "-family"; - args[2] = "xo3d"; - Pass::call(design, args); - } -} SynthMachXO3DPass; - PRIVATE_NAMESPACE_END diff --git a/tests/arch/machxo2/add_sub.ys b/tests/arch/machxo2/add_sub.ys index 6897363aaee..cc6ffb41a29 100644 --- a/tests/arch/machxo2/add_sub.ys +++ b/tests/arch/machxo2/add_sub.ys @@ -1,7 +1,7 @@ read_verilog ../common/add_sub.v hierarchy -top top proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 10 t:LUT4 diff --git a/tests/arch/machxo2/adffs.ys b/tests/arch/machxo2/adffs.ys index f1134a6ac67..49e93f9ac30 100644 --- a/tests/arch/machxo2/adffs.ys +++ b/tests/arch/machxo2/adffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top adff proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adff # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -12,7 +12,7 @@ select -assert-none t:TRELLIS_FF %% t:* %D design -load read hierarchy -top adffn proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd adffn # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -22,7 +22,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top dffs proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffs # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -32,7 +32,7 @@ select -assert-none t:TRELLIS_FF t:LUT4 %% t:* %D design -load read hierarchy -top ndffnr proc -equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -async2sync -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd ndffnr # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF diff --git a/tests/arch/machxo2/counter.ys b/tests/arch/machxo2/counter.ys index 11560b551fc..3d68c9900fa 100644 --- a/tests/arch/machxo2/counter.ys +++ b/tests/arch/machxo2/counter.ys @@ -2,7 +2,7 @@ read_verilog ../common/counter.v hierarchy -top top proc flatten -equiv_opt -assert -multiclock -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -multiclock -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 4 t:CCU2D diff --git a/tests/arch/machxo2/dffs.ys b/tests/arch/machxo2/dffs.ys index 663a64294bf..531d5ca5a27 100644 --- a/tests/arch/machxo2/dffs.ys +++ b/tests/arch/machxo2/dffs.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top dff proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dff # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF @@ -12,7 +12,7 @@ select -assert-none t:TRELLIS_FF t:TRELLIS_IO %% t:* %D design -load read hierarchy -top dffe proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd dffe # Constrain all select calls below inside the top module select -assert-count 1 t:TRELLIS_FF t:LUT4 diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index 70e1a632bdf..43dd0c80e35 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter diff --git a/tests/arch/machxo2/logic.ys b/tests/arch/machxo2/logic.ys index 5c799530519..dbd702f905e 100644 --- a/tests/arch/machxo2/logic.ys +++ b/tests/arch/machxo2/logic.ys @@ -1,7 +1,7 @@ read_verilog ../common/logic.v hierarchy -top top proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module select -assert-count 9 t:LUT4 diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys index 8f1918587c9..bc81c9c8b29 100644 --- a/tests/arch/machxo2/lutram.ys +++ b/tests/arch/machxo2/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut memory opt -full diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 4fa1bd2fcc8..0ae9559cb48 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT4 @@ -12,7 +12,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 2 t:LUT4 @@ -22,7 +22,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 5 t:LUT4 @@ -32,7 +32,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-max 12 t:LUT4 diff --git a/tests/arch/machxo2/shifter.ys b/tests/arch/machxo2/shifter.ys index f6440c025e8..ca7abb8098b 100644 --- a/tests/arch/machxo2/shifter.ys +++ b/tests/arch/machxo2/shifter.ys @@ -2,7 +2,7 @@ read_verilog ../common/shifter.v hierarchy -top top proc flatten -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd top # Constrain all select calls below inside the top module diff --git a/tests/arch/machxo2/tribuf.ys b/tests/arch/machxo2/tribuf.ys index 08c86008da5..00c7012d748 100644 --- a/tests/arch/machxo2/tribuf.ys +++ b/tests/arch/machxo2/tribuf.ys @@ -2,7 +2,7 @@ read_verilog ../common/tribuf.v hierarchy -top tristate proc flatten -equiv_opt -assert -map +/lattice/cells_sim_xo2.v -map +/simcells.v synth_machxo2 # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v -map +/simcells.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd tristate # Constrain all select calls below inside the top module select -assert-count 1 t:$_TBUF_ From 0756285710b8ee0e561e9d2f961e3d873921db13 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 25 Aug 2023 11:45:25 +0200 Subject: [PATCH 264/303] enable more primitives supported with nextpnr --- techlibs/lattice/cells_bb_xo2.v | 36 ++++++++++++++++++++++++++++++++ techlibs/lattice/cells_bb_xo3.v | 36 ++++++++++++++++++++++++++++++++ techlibs/lattice/cells_bb_xo3d.v | 36 ++++++++++++++++++++++++++++++++ techlibs/lattice/cells_xtra.py | 36 ++++++++++++++++---------------- techlibs/lattice/common_sim.vh | 9 ++++++++ 5 files changed, 135 insertions(+), 18 deletions(-) diff --git a/techlibs/lattice/cells_bb_xo2.v b/techlibs/lattice/cells_bb_xo2.v index 6e6b655c919..fdf8331b731 100644 --- a/techlibs/lattice/cells_bb_xo2.v +++ b/techlibs/lattice/cells_bb_xo2.v @@ -408,6 +408,17 @@ module FIFO8KB (...); output FF; endmodule +(* blackbox *) +module CLKDIVC (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input RST; + input CLKI; + input ALIGNWD; + output CDIV1; + output CDIVX; +endmodule + (* blackbox *) module DCMA (...); input CLK0; @@ -416,6 +427,21 @@ module DCMA (...); output DCMOUT; endmodule +(* blackbox *) +module ECLKSYNCA (...); + input ECLKI; + input STOP; + output ECLKO; +endmodule + +(* blackbox *) +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; +endmodule + (* blackbox *) module DCCA (...); input CLKI; @@ -423,6 +449,11 @@ module DCCA (...); output CLKO; endmodule +(* blackbox *) (* keep *) +module START (...); + input STARTCLK; +endmodule + (* blackbox *) module EHXPLLJ (...); parameter CLKI_DIV = 1; @@ -533,3 +564,8 @@ module OSCH (...); output SEDSTDBY; endmodule +(* blackbox *) (* keep *) +module TSALL (...); + input TSALL; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3.v b/techlibs/lattice/cells_bb_xo3.v index 6e6b655c919..fdf8331b731 100644 --- a/techlibs/lattice/cells_bb_xo3.v +++ b/techlibs/lattice/cells_bb_xo3.v @@ -408,6 +408,17 @@ module FIFO8KB (...); output FF; endmodule +(* blackbox *) +module CLKDIVC (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input RST; + input CLKI; + input ALIGNWD; + output CDIV1; + output CDIVX; +endmodule + (* blackbox *) module DCMA (...); input CLK0; @@ -416,6 +427,21 @@ module DCMA (...); output DCMOUT; endmodule +(* blackbox *) +module ECLKSYNCA (...); + input ECLKI; + input STOP; + output ECLKO; +endmodule + +(* blackbox *) +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; +endmodule + (* blackbox *) module DCCA (...); input CLKI; @@ -423,6 +449,11 @@ module DCCA (...); output CLKO; endmodule +(* blackbox *) (* keep *) +module START (...); + input STARTCLK; +endmodule + (* blackbox *) module EHXPLLJ (...); parameter CLKI_DIV = 1; @@ -533,3 +564,8 @@ module OSCH (...); output SEDSTDBY; endmodule +(* blackbox *) (* keep *) +module TSALL (...); + input TSALL; +endmodule + diff --git a/techlibs/lattice/cells_bb_xo3d.v b/techlibs/lattice/cells_bb_xo3d.v index c957b00293e..84d7d960198 100644 --- a/techlibs/lattice/cells_bb_xo3d.v +++ b/techlibs/lattice/cells_bb_xo3d.v @@ -408,6 +408,17 @@ module FIFO8KB (...); output FF; endmodule +(* blackbox *) +module CLKDIVC (...); + parameter GSR = "DISABLED"; + parameter DIV = "2.0"; + input RST; + input CLKI; + input ALIGNWD; + output CDIV1; + output CDIVX; +endmodule + (* blackbox *) module DCMA (...); input CLK0; @@ -416,6 +427,21 @@ module DCMA (...); output DCMOUT; endmodule +(* blackbox *) +module ECLKSYNCA (...); + input ECLKI; + input STOP; + output ECLKO; +endmodule + +(* blackbox *) +module ECLKBRIDGECS (...); + input CLK0; + input CLK1; + input SEL; + output ECSOUT; +endmodule + (* blackbox *) module DCCA (...); input CLKI; @@ -423,6 +449,11 @@ module DCCA (...); output CLKO; endmodule +(* blackbox *) (* keep *) +module START (...); + input STARTCLK; +endmodule + (* blackbox *) module EHXPLLJ (...); parameter CLKI_DIV = 1; @@ -534,3 +565,8 @@ module OSCJ (...); output OSCESB; endmodule +(* blackbox *) (* keep *) +module TSALL (...); + input TSALL; +endmodule + diff --git a/techlibs/lattice/cells_xtra.py b/techlibs/lattice/cells_xtra.py index f2dd1f29749..fa4e38ace03 100644 --- a/techlibs/lattice/cells_xtra.py +++ b/techlibs/lattice/cells_xtra.py @@ -315,13 +315,13 @@ class State(Enum): Cell("PDPW8KC"), Cell("SP8KC"), Cell("FIFO8KB"), - #Cell("CLKDIVC"), + Cell("CLKDIVC"), Cell("DCMA"), - #Cell("ECLKSYNCA"), - #Cell("ECLKBRIDGECS"), + Cell("ECLKSYNCA"), + Cell("ECLKBRIDGECS"), Cell("DCCA"), - #Cell("JTAGF"), - #Cell("START"), + #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + Cell("START", True), #Cell("SEDFA"), #Cell("SEDFB"), #Cell("IDDRXE"), @@ -351,7 +351,7 @@ class State(Enum): #Cell("PLLREFCS"), Cell("OSCH"), #Cell("EFB"), - #Cell("TSALL"), + Cell("TSALL", True), ]), ("cells_bb_xo3.v", "machxo3lf", [ #Cell("AGEB2"), @@ -495,13 +495,13 @@ class State(Enum): Cell("PDPW8KC"), Cell("SP8KC"), Cell("FIFO8KB"), - #Cell("CLKDIVC"), + Cell("CLKDIVC"), Cell("DCMA"), - #Cell("ECLKSYNCA"), - #Cell("ECLKBRIDGECS"), + Cell("ECLKSYNCA"), + Cell("ECLKBRIDGECS"), Cell("DCCA"), - #Cell("JTAGF"), - #Cell("START"), + #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + Cell("START", True), #Cell("SEDFA"), #Cell("SEDFB"), #Cell("IDDRXE"), @@ -527,7 +527,7 @@ class State(Enum): #Cell("PLLREFCS"), Cell("OSCH"), #Cell("EFB"), - #Cell("TSALL"), + Cell("TSALL", True), ]), ("cells_bb_xo3d.v", "machxo3d", [ #Cell("AGEB2"), @@ -672,13 +672,13 @@ class State(Enum): Cell("PDPW8KC"), Cell("SP8KC"), Cell("FIFO8KB"), - #Cell("CLKDIVC"), + Cell("CLKDIVC"), Cell("DCMA"), - #Cell("ECLKSYNCA"), - #Cell("ECLKBRIDGECS"), + Cell("ECLKSYNCA"), + Cell("ECLKBRIDGECS"), Cell("DCCA"), - #Cell("JTAGF"), - #Cell("START"), + #Cell("JTAGF", True, port_attrs={'TCK': ['iopad_external_pin'], 'TMS': ['iopad_external_pin'], 'TDO': ['iopad_external_pin'], 'TDI': ['iopad_external_pin']}), + Cell("START", True), #Cell("SEDFA"), #Cell("SEDFB"), #Cell("IDDRXE"), @@ -704,7 +704,7 @@ class State(Enum): #Cell("PLLREFCS"), Cell("OSCJ"), #Cell("EFBB"), - #Cell("TSALL"), + Cell("TSALL", True), #Cell("ESBA"), #Cell("BCSLEWRATEA"), ]) diff --git a/techlibs/lattice/common_sim.vh b/techlibs/lattice/common_sim.vh index e6c2e57b507..2f8e1db1a82 100644 --- a/techlibs/lattice/common_sim.vh +++ b/techlibs/lattice/common_sim.vh @@ -394,6 +394,15 @@ module TRELLIS_COMB( endmodule +// Constants +module VLO(output Z); + assign Z = 1'b0; +endmodule + +module VHI(output Z); + assign Z = 1'b1; +endmodule + `ifndef NO_INCLUDES `include "cells_ff.vh" From de54cf1a0c76b67052248f9c1a2428039f398dc6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 26 Aug 2023 00:13:58 +0000 Subject: [PATCH 265/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 09cf4992dab..f0d94b0c91d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+51 +YOSYS_VER := 0.32+63 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From e017f6603ce98fd80199598efd5d6b65c2df11bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gr=C3=B6ber?= Date: Tue, 22 Aug 2023 19:58:03 +0200 Subject: [PATCH 266/303] Fix i386 FP excess-precision issue in fstapi (Fixes: #3898) Likely related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323#c225 Thanks to @jix for digging this up --- libs/fst/fstapi.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/fst/fstapi.cc b/libs/fst/fstapi.cc index da0d959a0de..dddf7d39a54 100644 --- a/libs/fst/fstapi.cc +++ b/libs/fst/fstapi.cc @@ -4334,7 +4334,7 @@ int fstReaderInit(struct fstReaderContext *xc) hdr_incomplete = (xc->start_time == 0) && (xc->end_time == 0); fstFread(&dcheck, 8, 1, xc->f); - xc->double_endian_match = (dcheck == FST_DOUBLE_ENDTEST); + xc->double_endian_match = (dcheck == (double)FST_DOUBLE_ENDTEST); if (!xc->double_endian_match) { union { From e4189ddfd1259adf164dd506a1ff896598151c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gr=C3=B6ber?= Date: Sun, 27 Aug 2023 15:01:27 +0200 Subject: [PATCH 267/303] Fix fstGetUint32 crash on mips64el due to misaligned access See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1025307 --- libs/fst/fstapi.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/fst/fstapi.cc b/libs/fst/fstapi.cc index da0d959a0de..ac1a0afa3d5 100644 --- a/libs/fst/fstapi.cc +++ b/libs/fst/fstapi.cc @@ -348,17 +348,17 @@ static void *fstMmap2(size_t __len, int __fd, fst_off_t __off) #ifdef FST_DO_MISALIGNED_OPS #define fstGetUint32(x) (*(uint32_t *)(x)) #else -static uint32_t fstGetUint32(unsigned char *mem) +static inline uint32_t fstGetUint32(unsigned char *mem) { - uint32_t u32; - unsigned char *buf = (unsigned char *)(&u32); + union { + uint8_t u8[sizeof(uint32_t)]; + uint32_t u32; + } u; - buf[0] = mem[0]; - buf[1] = mem[1]; - buf[2] = mem[2]; - buf[3] = mem[3]; + for (size_t i=0; i < sizeof(u.u8); i++) + u.u8[i] = mem[i]; - return (*(uint32_t *)buf); + return u.u32; } #endif From 2f901a82979d05893ff24997968a84f9fa477199 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 00:15:18 +0000 Subject: [PATCH 268/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f0d94b0c91d..c0b7c88c0d9 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+63 +YOSYS_VER := 0.32+66 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From b168ff99d07041284cf8f2ee16678d8ed5bd2305 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 28 Aug 2023 16:26:26 +0200 Subject: [PATCH 269/303] fix generated blackboxes for ecp5 --- techlibs/lattice/cells_bb_ecp5.v | 2 -- techlibs/lattice/cells_xtra.py | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/lattice/cells_bb_ecp5.v b/techlibs/lattice/cells_bb_ecp5.v index 9c4d1fde4ef..fc22495e2ff 100644 --- a/techlibs/lattice/cells_bb_ecp5.v +++ b/techlibs/lattice/cells_bb_ecp5.v @@ -1580,7 +1580,6 @@ module EXTREFB (...); (* iopad_external_pin *) input REFCLKN; output REFCLKO; - output ; endmodule (* blackbox *) (* keep *) @@ -2172,6 +2171,5 @@ module DCUA (...); output D_COUT19; input D_REFCLKI; output D_FFS_PLOL; - output ; endmodule diff --git a/techlibs/lattice/cells_xtra.py b/techlibs/lattice/cells_xtra.py index fa4e38ace03..c17281cc753 100644 --- a/techlibs/lattice/cells_xtra.py +++ b/techlibs/lattice/cells_xtra.py @@ -815,6 +815,8 @@ def xtract_cells_decl(device, cells, dirs, outf): if l.endswith((';', ',', ")")): l = l[:-1] l = l.replace(")","") + if l == "": + continue if ';' in l: print('Weird port line in {} [{}].'.format(fname, l)) sys.exit(1) From 572ad341b7190a4596e99edf6b81f5a1c29e9afb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Aug 2023 00:14:35 +0000 Subject: [PATCH 270/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c0b7c88c0d9..f146210e5c7 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+66 +YOSYS_VER := 0.32+70 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 792cf8326eb2b825ac0039f18cad9fb3deea47c0 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 29 Aug 2023 10:08:55 +0200 Subject: [PATCH 271/303] defult nowidelut for xo2/3/3d --- techlibs/lattice/synth_lattice.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/techlibs/lattice/synth_lattice.cc b/techlibs/lattice/synth_lattice.cc index ff5070b8073..e2987d0259e 100644 --- a/techlibs/lattice/synth_lattice.cc +++ b/techlibs/lattice/synth_lattice.cc @@ -102,6 +102,10 @@ struct SynthLatticePass : public ScriptPass log("\n"); log(" -nowidelut\n"); log(" do not use PFU muxes to implement LUTs larger than LUT4s\n"); + log(" (by default enabled on MachXO2/XO3/XO3D)\n"); + log("\n"); + log(" -widelut\n"); + log(" force use of PFU muxes to implement LUTs larger than LUT4s\n"); log("\n"); log(" -asyncprld\n"); log(" use async PRLD mode to implement ALDFF (EXPERIMENTAL)\n"); @@ -163,6 +167,7 @@ struct SynthLatticePass : public ScriptPass void execute(std::vector args, RTLIL::Design *design) override { string run_from, run_to; + bool force_widelut = false; clear_flags(); size_t argidx; @@ -230,6 +235,12 @@ struct SynthLatticePass : public ScriptPass } if (args[argidx] == "-nowidelut" || /*deprecated alias*/ args[argidx] == "-nomux") { nowidelut = true; + force_widelut = true; + continue; + } + if (args[argidx] == "-widelut") { + nowidelut = false; + force_widelut = true; continue; } if (args[argidx] == "-abc2") { @@ -273,6 +284,7 @@ struct SynthLatticePass : public ScriptPass arith_map = "_ccu2d"; brams_map = "_8kc"; have_dsp = false; + if (!force_widelut) nowidelut = true; /* } else if (family == "xo" || family == "pm") { } else if (family == "xp" || From a42c630264f8e76ae788707af6e76a8156b21ad6 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 29 Aug 2023 10:21:58 +0200 Subject: [PATCH 272/303] put back previous test state, due to default change --- tests/arch/machxo2/fsm.ys | 2 +- tests/arch/machxo2/lutram.ys | 2 +- tests/arch/machxo2/mux.ys | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/arch/machxo2/fsm.ys b/tests/arch/machxo2/fsm.ys index 43dd0c80e35..3e10a069a74 100644 --- a/tests/arch/machxo2/fsm.ys +++ b/tests/arch/machxo2/fsm.ys @@ -3,7 +3,7 @@ hierarchy -top fsm proc flatten -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 miter -equiv -make_assert -flatten gold gate miter sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter diff --git a/tests/arch/machxo2/lutram.ys b/tests/arch/machxo2/lutram.ys index bc81c9c8b29..65af7b2c267 100644 --- a/tests/arch/machxo2/lutram.ys +++ b/tests/arch/machxo2/lutram.ys @@ -2,7 +2,7 @@ read_verilog ../common/lutram.v hierarchy -top lutram_1w1r proc memory -nomap -equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut +equiv_opt -run :prove -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 memory opt -full diff --git a/tests/arch/machxo2/mux.ys b/tests/arch/machxo2/mux.ys index 0ae9559cb48..6d4e10dc7e7 100644 --- a/tests/arch/machxo2/mux.ys +++ b/tests/arch/machxo2/mux.ys @@ -3,7 +3,7 @@ design -save read hierarchy -top mux2 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux2 # Constrain all select calls below inside the top module select -assert-count 1 t:LUT4 @@ -12,7 +12,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux4 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux4 # Constrain all select calls below inside the top module select -assert-count 2 t:LUT4 @@ -22,7 +22,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux8 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux8 # Constrain all select calls below inside the top module select -assert-count 5 t:LUT4 @@ -32,7 +32,7 @@ select -assert-none t:LUT4 t:TRELLIS_IO %% t:* %D design -load read hierarchy -top mux16 proc -equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 -nowidelut # equivalency check +equiv_opt -assert -map +/lattice/cells_sim_xo2.v synth_lattice -family xo2 # equivalency check design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design) cd mux16 # Constrain all select calls below inside the top module select -assert-max 12 t:LUT4 From b739213d9f00b409ef7b9a9e1834d659ea8008d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 00:14:38 +0000 Subject: [PATCH 273/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f146210e5c7..4f7f94cf167 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+70 +YOSYS_VER := 0.32+74 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 72bec94ef4f0ce8090f22c16cd5163b816e8c698 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 1 Sep 2023 10:15:51 +0200 Subject: [PATCH 274/303] Add missing file for XO3D --- techlibs/lattice/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/lattice/Makefile.inc b/techlibs/lattice/Makefile.inc index 4a908fa3ead..fd9ec2ed5e0 100644 --- a/techlibs/lattice/Makefile.inc +++ b/techlibs/lattice/Makefile.inc @@ -15,6 +15,7 @@ $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3d.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_ecp5.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo2.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3.v)) +$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3d.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map.v)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams.txt)) $(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_16kd.v)) From 73cb4977b2e493b840b23419919a63be7c83e6df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:14:04 +0000 Subject: [PATCH 275/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4f7f94cf167..960a31a01f3 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+74 +YOSYS_VER := 0.32+76 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 50d117956c7913d2bb661a948f0a1bff6bd0f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:49:19 +0200 Subject: [PATCH 276/303] sim: Add print support --- passes/sat/sim.cc | 92 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 325e123201c..7b2236ad6fa 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -25,6 +25,7 @@ #include "kernel/ff.h" #include "kernel/yw.h" #include "kernel/json.h" +#include "kernel/fmt.h" #include @@ -168,11 +169,38 @@ struct SimInstance Const data; }; + struct print_state_t + { + Const past_trg; + Const past_en; + Const past_args; + + Cell *cell; + Fmt fmt; + + std::tuple _sort_label() const + { + return std::make_tuple( + cell->getParam(ID::TRG_ENABLE).as_bool(), // Group by trigger + cell->getPort(ID::TRG), + cell->getParam(ID::TRG_POLARITY), + -cell->getParam(ID::PRIORITY).as_int(), // Then sort by descending PRIORITY + cell + ); + } + + bool operator<(const print_state_t &other) const + { + return _sort_label() < other._sort_label(); + } + }; + dict ff_database; dict mem_database; pool formal_database; pool initstate_database; dict mem_cells; + std::vector print_database; std::vector memories; @@ -289,13 +317,26 @@ struct SimInstance if (shared->fst) fst_memories[name] = shared->fst->getMemoryHandles(scope + "." + RTLIL::unescape_id(name)); } - if (cell->type.in(ID($assert), ID($cover), ID($assume))) { + + if (cell->type.in(ID($assert), ID($cover), ID($assume))) formal_database.insert(cell); - } + if (cell->type == ID($initstate)) initstate_database.insert(cell); + + if (cell->type == ID($print)) { + print_database.emplace_back(); + auto &print = print_database.back(); + print.cell = cell; + print.fmt.parse_rtlil(cell); + print.past_trg = Const(State::Sx, cell->getPort(ID::TRG).size()); + print.past_args = Const(State::Sx, cell->getPort(ID::ARGS).size()); + print.past_en = State::Sx; + } } + std::sort(print_database.begin(), print_database.end()); + if (shared->zinit) { for (auto &it : ff_database) @@ -519,6 +560,9 @@ struct SimInstance return; } + if (cell->type == ID($print)) + return; + log_error("Unsupported cell type: %s (%s.%s)\n", log_id(cell->type), log_id(module), log_id(cell)); } @@ -760,6 +804,50 @@ struct SimInstance } } + // Do prints *before* assertions + for (auto &print : print_database) { + Cell *cell = print.cell; + bool triggered = false; + + Const trg = get_state(cell->getPort(ID::TRG)); + Const en = get_state(cell->getPort(ID::EN)); + Const args = get_state(cell->getPort(ID::ARGS)); + + if (!en.as_bool()) + goto update_print; + + if (cell->getParam(ID::TRG_ENABLE).as_bool()) { + Const trg_pol = cell->getParam(ID::TRG_POLARITY); + for (int i = 0; i < trg.size(); i++) { + bool pol = trg_pol[i] == State::S1; + State curr = trg[i], past = print.past_trg[i]; + if (pol && curr == State::S1 && past == State::S0) + triggered = true; + if (!pol && curr == State::S0 && past == State::S1) + triggered = true; + } + } else { + if (args != print.past_args || en != print.past_en) + triggered = true; + } + + if (triggered) { + int pos = 0; + for (auto &part : print.fmt.parts) { + part.sig = args.extract(pos, part.sig.size()); + pos += part.sig.size(); + } + + std::string rendered = print.fmt.render(); + log("%s", rendered.c_str()); + } + + update_print: + print.past_trg = trg; + print.past_en = en; + print.past_args = args; + } + if (check_assertions) { for (auto cell : formal_database) From 3de84b959f2d77244d1a5d8a18aac4d8c67a8de8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:48:49 +0200 Subject: [PATCH 277/303] memory_libmap: Tweak whitespace --- passes/memory/memory_libmap.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/memory/memory_libmap.cc b/passes/memory/memory_libmap.cc index 6e5a806fd0e..f8b0eec1d8d 100644 --- a/passes/memory/memory_libmap.cc +++ b/passes/memory/memory_libmap.cc @@ -667,7 +667,7 @@ void MemMapping::assign_wr_ports() { if (used >= GetSize(pg.names)) { log_reject(*cfg.def, pg, "not enough unassigned ports remaining"); continue; - } + } for (int pvi = 0; pvi < GetSize(pg.variants); pvi++) { auto &def = pg.variants[pvi]; // Make sure the target is a write port. @@ -2114,7 +2114,7 @@ struct MemoryLibMapPass : public Pass { log(" memory_libmap -lib [-D ] [selection]\n"); log("\n"); log("This pass takes a description of available RAM cell types and maps\n"); - log("all selected memories to one of them, or leaves them to be mapped to FFs.\n"); + log("all selected memories to one of them, or leaves them to be mapped to FFs.\n"); log("\n"); log(" -lib \n"); log(" Selects a library file containing RAM cell definitions. This option\n"); From c6566b660f8343be882cbb4fadedfa823f48e7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:49:01 +0200 Subject: [PATCH 278/303] memlib.md: Fix typo --- passes/memory/memlib.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/memory/memlib.md b/passes/memory/memlib.md index fdc2d4bed27..855aa1345fb 100644 --- a/passes/memory/memlib.md +++ b/passes/memory/memlib.md @@ -267,7 +267,7 @@ The address is always `abits` wide. If a non-narrowest width is used, the appro bits will be tied to 0. -### Port `width` prooperty +### Port `width` property If the RAM has `per_port` widths, the available width selection can be further described on per-port basis, by using one of the following properties: From b75959f1f25573d8c67436e748223290a3645074 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 00:14:21 +0000 Subject: [PATCH 279/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 960a31a01f3..492ea14832c 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+76 +YOSYS_VER := 0.32+79 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 2584903a0605cc7ffdfc1996254ccc1f548403f2 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 5 Sep 2023 08:08:51 +0200 Subject: [PATCH 280/303] Release version 0.33 --- CHANGELOG | 12 +++++++++++- Makefile | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 027187b6d9f..f388705ccf3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,18 @@ List of major changes and improvements between releases ======================================================= -Yosys 0.32 .. Yosys 0.33-dev +Yosys 0.32 .. Yosys 0.33 -------------------------- + * Various + - Added "$print" cell, produced by "$display" and "$write" + Verilog tasks. + - Added "$print" cell handling in CXXRTL. + + * Lattice FPGA support + - Added generic "synth_lattice" pass (for now MachXO2/XO3/XO3D) + - Removed "synth_machxo2" pass + - Pass "ecp5_gsr" renamed to "lattice_gsr" + - "synth_machxo2" equivalent is "synth_lattice -family xo2" Yosys 0.31 .. Yosys 0.32 -------------------------- diff --git a/Makefile b/Makefile index 492ea14832c..c7a9ed6b63a 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.32+79 +YOSYS_VER := 0.33 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: - sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile +# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From 11a2de815ae6e799dd37c4d220255042f1bd5608 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 5 Sep 2023 08:11:03 +0200 Subject: [PATCH 281/303] Next dev cycle --- CHANGELOG | 3 +++ Makefile | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f388705ccf3..465918a36d8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,9 @@ List of major changes and improvements between releases ======================================================= +Yosys 0.33 .. Yosys 0.34-dev +-------------------------- + Yosys 0.32 .. Yosys 0.33 -------------------------- * Various diff --git a/Makefile b/Makefile index c7a9ed6b63a..fa95b7b7035 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33 +YOSYS_VER := 0.33+0 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo @@ -157,7 +157,7 @@ endif OBJS = kernel/version_$(GIT_REV).o bumpversion: -# sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline fbab08a.. | wc -l`/;" Makefile + sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 2584903.. | wc -l`/;" Makefile # set 'ABCREV = default' to use abc/ as it is # From e995dddeaaa4bcdefdeebb082e1f1a8215d467bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Wed, 16 Aug 2023 12:42:00 +0200 Subject: [PATCH 282/303] abc: Warn about replacing undef bits --- passes/techmap/abc.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index 364a8e54458..b2d5c5e36f3 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -127,10 +127,15 @@ bool clk_polarity, en_polarity, arst_polarity, srst_polarity; RTLIL::SigSpec clk_sig, en_sig, arst_sig, srst_sig; dict pi_map, po_map; +int undef_bits_lost; + int map_signal(RTLIL::SigBit bit, gate_type_t gate_type = G(NONE), int in1 = -1, int in2 = -1, int in3 = -1, int in4 = -1) { assign_map.apply(bit); + if (bit == State::Sx) + undef_bits_lost++; + if (signal_map.count(bit) == 0) { gate_t gate; gate.id = signal_list.size(); @@ -880,10 +885,15 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin } } + undef_bits_lost = 0; + had_init = false; for (auto c : cells) extract_cell(c, keepff); + if (undef_bits_lost) + log("Replacing %d occurrences of constant undef bits with constant zero bits\n", undef_bits_lost); + for (auto wire : module->wires()) { if (wire->port_id > 0 || wire->get_bool_attribute(ID::keep)) mark_port(wire); From d4d951657fbf273d58070076009453d541361f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 4 Sep 2023 14:55:11 +0200 Subject: [PATCH 283/303] sim: Add `-assert` option to fail on failed assertions --- passes/sat/sim.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 325e123201c..e04fa564235 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -109,6 +109,7 @@ struct SimShared int next_output_id = 0; int step = 0; std::vector triggered_assertions; + bool serious_asserts = false; }; void zinit(State &v) @@ -781,8 +782,12 @@ struct SimInstance if (cell->type == ID($assume) && en == State::S1 && a != State::S1) log("Assumption %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); - if (cell->type == ID($assert) && en == State::S1 && a != State::S1) - log_warning("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); + if (cell->type == ID($assert) && en == State::S1 && a != State::S1) { + if (shared->serious_asserts) + log_error("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); + else + log_warning("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str()); + } } } @@ -2497,6 +2502,10 @@ struct SimPass : public Pass { log(" -sim-gate\n"); log(" co-simulation, x in FST can match any value in simulation\n"); log("\n"); + log(" -assert\n"); + log(" fail the simulation command if, in the course of simulating,\n"); + log(" any of the asserts in the design fail\n"); + log("\n"); log(" -q\n"); log(" disable per-cycle/sample log message\n"); log("\n"); @@ -2651,6 +2660,10 @@ struct SimPass : public Pass { worker.sim_mode = SimulationMode::gate; continue; } + if (args[argidx] == "-assert") { + worker.serious_asserts = true; + continue; + } if (args[argidx] == "-x") { worker.ignore_x = true; continue; From 2d0fc040cfe4413e3b2c8209b4b5a23b5866374b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 5 Sep 2023 21:40:24 +0200 Subject: [PATCH 284/303] ast: Substitute rvalues when parsing out print arguments Apply the local substitutions stemming from process context when parsing out format arguments to `$display` or other statements. --- frontends/ast/genrtlil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index 81fb3189d94..d62f06ae549 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -759,7 +759,7 @@ struct AST_INTERNAL::ProcessGenerator arg.realtime = true; } else { arg.type = VerilogFmtArg::INTEGER; - arg.sig = node->genRTLIL(); + arg.sig = node->genWidthRTLIL(-1, false, &subst_rvalue_map.stdmap()); arg.signed_ = is_signed; } args.push_back(arg); From 83b1a57eed27604fa1a45193ee6894a5e0764971 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 6 Sep 2023 00:14:34 +0000 Subject: [PATCH 285/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fa95b7b7035..907891db33f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+0 +YOSYS_VER := 0.33+3 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From e187fc915e87ee3b24b0f6b351862c32bbe91a89 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Wed, 6 Sep 2023 19:25:47 +0200 Subject: [PATCH 286/303] xprop: Fix polarity errors and generate hdlnames * Fixes a non-deterministic polarity error for $eqx/$nex cells * Fixes a deterministic polarity error for $_NOR_ and $_ORNOT_ cells * Generates hdlnames when xprop is run after flatten --- passes/cmds/xprop.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 5e78ff9fce4..310d6d773d5 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -493,8 +493,9 @@ struct XpropWorker auto sig_b = cell->getPort(ID::B); auto name = cell->name; + auto type = cell->type; module->remove(cell); - if (cell->type == ID($eqx)) + if (type == ID($eqx)) module->addEq(name, sig_a, sig_b, sig_y); else module->addNe(name, sig_a, sig_b, sig_y); @@ -534,7 +535,7 @@ struct XpropWorker auto enc_b = encoded(sig_b); auto enc_y = encoded(sig_y, true); - if (cell->type.in(ID($or), ID($_OR_))) + if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_), ID($_ORNOT_))) enc_a.invert(), enc_b.invert(), enc_y.invert(); if (cell->type.in(ID($_NAND_), ID($_NOR_))) enc_y.invert(); @@ -1027,12 +1028,25 @@ struct XpropWorker for (auto wire : module->selected_wires()) { if (wire->port_input || wire->port_output || !wire->name.isPublic()) continue; - auto name_d = module->uniquify(stringf("%s_d", wire->name.c_str())); - auto name_x = module->uniquify(stringf("%s_x", wire->name.c_str())); + int index_d = 0; + int index_x = 0; + auto name_d = module->uniquify(stringf("%s_d", wire->name.c_str()), index_d); + auto name_x = module->uniquify(stringf("%s_x", wire->name.c_str()), index_x); + + auto hdlname = wire->get_hdlname_attribute(); auto wire_d = module->addWire(name_d, GetSize(wire)); auto wire_x = module->addWire(name_x, GetSize(wire)); + if (!hdlname.empty()) { + auto hdlname_d = hdlname; + auto hdlname_x = hdlname; + hdlname_d.back() += index_d ? stringf("_d_%d", index_d) : "_d"; + hdlname_x.back() += index_x ? stringf("_x_%d", index_x) : "_x"; + wire_d->set_hdlname_attribute(hdlname_d); + wire_x->set_hdlname_attribute(hdlname_x); + } + auto enc = encoded(wire); module->connect(wire_d, enc.is_1); module->connect(wire_x, enc.is_x); From 41b34a19353dbbe00aa08f3561e25e0bfa4c84d2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Sep 2023 00:14:30 +0000 Subject: [PATCH 287/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 907891db33f..9474d37a19d 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+3 +YOSYS_VER := 0.33+6 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From bef7ffccc1103ac6e96934acf3bf8fd806df851a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 11 Sep 2023 16:25:58 +0200 Subject: [PATCH 288/303] Update ABC to latest --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9474d37a19d..c3fc4145837 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = bb64142 +ABCREV = 9537f39 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From 7b134c2a8cd63222fd005315f1a07c20e97fd546 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 12 Sep 2023 11:56:15 +0200 Subject: [PATCH 289/303] verific - respect order of read and write for rams --- frontends/verific/verific.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index b0d789d8fa3..4f4fbcb746e 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -2951,6 +2951,9 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("db_infer_wide_operators", 1); RuntimeFlags::SetVar("db_infer_set_reset_registers", 0); + // Properly respect order of read and write for rams + RuntimeFlags::SetVar("db_change_inplace_ram_blocking_write_before_read", 1); + RuntimeFlags::SetVar("veri_extract_dualport_rams", 0); RuntimeFlags::SetVar("veri_extract_multiport_rams", 1); RuntimeFlags::SetVar("veri_allow_any_ram_in_loop", 1); From cbc4ec8178ddc67e397ccd0800048a26d1f41451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 12 Sep 2023 14:54:03 +0200 Subject: [PATCH 290/303] mem: Fix index confusion in write port merging Fix mistaking the read-port and write-port indices for each other when we are adding the partial transparency emulation to be able to merge two write ports. --- kernel/mem.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/mem.cc b/kernel/mem.cc index 628f6210499..269a476a125 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -1252,12 +1252,12 @@ void Mem::prepare_wr_merge(int idx1, int idx2, FfInitVals *initvals) { // If transparent with only one, emulate it, and remove the collision-X // flag that emulate_transparency will set (to align with the other port). if (rport.transparency_mask[idx1]) { - emulate_transparency(i, idx1, initvals); + emulate_transparency(idx1, i, initvals); rport.collision_x_mask[idx1] = false; continue; } if (rport.transparency_mask[idx2]) { - emulate_transparency(i, idx2, initvals); + emulate_transparency(idx2, i, initvals); rport.collision_x_mask[idx2] = false; continue; } From 98b9459535681a0c3a4739f208a32dfc50c9bfea Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 12 Sep 2023 18:12:07 +0200 Subject: [PATCH 291/303] fmt: Fix C++ string assertion when buf is empty Signed-off-by: gatecat --- kernel/fmt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/fmt.cc b/kernel/fmt.cc index 69bdbb013b0..965e58ebce4 100644 --- a/kernel/fmt.cc +++ b/kernel/fmt.cc @@ -740,7 +740,7 @@ std::string Fmt::render() const log_assert(part.width == 0 || part.padding != '\0'); if (part.justify == FmtPart::RIGHT && buf.size() < part.width) { size_t pad_width = part.width - buf.size(); - if (part.padding == '0' && (buf.front() == '+' || buf.front() == '-')) { + if (part.padding == '0' && (!buf.empty() && (buf.front() == '+' || buf.front() == '-'))) { str += buf.front(); buf.erase(0, 1); } From 9e004426e0783d5bbbe846be54b8266451cd5f7f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 00:14:55 +0000 Subject: [PATCH 292/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c3fc4145837..0c79636497f 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+6 +YOSYS_VER := 0.33+21 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo From 54050a8c16dbd9bf8bf17db08201fca23a3b4723 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 7 Jun 2023 10:20:16 +0200 Subject: [PATCH 293/303] Basic support for tag primitives --- frontends/verific/verific.cc | 32 +++++++++++++++ kernel/celltypes.h | 4 ++ kernel/constids.inc | 1 + kernel/rtlil.cc | 77 ++++++++++++++++++++++++++++++++++++ kernel/rtlil.h | 5 +++ techlibs/common/simlib.v | 57 ++++++++++++++++++++++++++ 6 files changed, 176 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 4f4fbcb746e..6000df9e628 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1103,6 +1103,38 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr return true; } + if (inst->Type() == OPER_YOSYSHQ_SET_TAG) + { + RTLIL::SigSpec sig_expr = operatorInport(inst, "expr"); + RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); + RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); + RTLIL::SigSpec sig_o = operatorOutput(inst); + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->connect(sig_o, module->SetTag(new_verific_id(inst), tag, sig_expr, sig_set_mask, sig_clr_mask)); + return true; + } + if (inst->Type() == OPER_YOSYSHQ_GET_TAG) + { + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->connect(operatorOutput(inst),module->GetTag(new_verific_id(inst), tag, operatorInput(inst))); + return true; + } + if (inst->Type() == OPER_YOSYSHQ_OVERWRITE_TAG) + { + RTLIL::SigSpec sig_signal = operatorInport(inst, "signal"); + RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); + RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->addOverwriteTag(new_verific_id(inst), tag, sig_signal, sig_set_mask, sig_clr_mask); + return true; + } + if (inst->Type() == OPER_YOSYSHQ_ORIGINAL_TAG) + { + std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + module->connect(operatorOutput(inst),module->OriginalTag(new_verific_id(inst), tag, operatorInput(inst))); + return true; + } + #undef IN #undef IN1 #undef IN2 diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 4a0621a7386..573ea0b4276 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -102,6 +102,10 @@ struct CellTypes setup_type(ID($specify3), {ID::EN, ID::SRC, ID::DST, ID::DAT}, pool(), true); setup_type(ID($specrule), {ID::EN_SRC, ID::EN_DST, ID::SRC, ID::DST}, pool(), true); setup_type(ID($print), {ID::EN, ID::ARGS, ID::TRG}, pool()); + setup_type(ID($set_tag), {ID::A, ID::SET, ID::CLR}, {ID::Y}); + setup_type(ID($get_tag), {ID::A}, {ID::Y}); + setup_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, pool()); + setup_type(ID($original_tag), {ID::A}, {ID::Y}); } void setup_internals_eval() diff --git a/kernel/constids.inc b/kernel/constids.inc index 08b0ecdc2b4..93101282a0b 100644 --- a/kernel/constids.inc +++ b/kernel/constids.inc @@ -208,6 +208,7 @@ X(syn_romstyle) X(S_WIDTH) X(T) X(TABLE) +X(TAG) X(techmap_autopurge) X(_TECHMAP_BITS_CONNMAP_) X(_TECHMAP_CELLNAME_) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7a59c526275..2563aa21aa6 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1828,6 +1828,33 @@ namespace { ID($_DLATCHSR_PNN_), ID($_DLATCHSR_PNP_), ID($_DLATCHSR_PPN_), ID($_DLATCHSR_PPP_))) { port(ID::E,1); port(ID::S,1); port(ID::R,1); port(ID::D,1); port(ID::Q,1); check_expected(); return; } + if (cell->type.in(ID($set_tag))) { + param(ID::WIDTH); + param(ID::TAG); + port(ID::A, param(ID::WIDTH)); + port(ID::SET, param(ID::WIDTH)); + port(ID::CLR, param(ID::WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type.in(ID($get_tag),ID($original_tag))) { + param(ID::WIDTH); + param(ID::TAG); + port(ID::A, param(ID::WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } + if (cell->type.in(ID($overwrite_tag))) { + param(ID::WIDTH); + param(ID::TAG); + port(ID::A, param(ID::WIDTH)); + port(ID::SET, param(ID::WIDTH)); + port(ID::CLR, param(ID::WIDTH)); + check_expected(); + return; + } error(__LINE__); } }; @@ -3246,6 +3273,56 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string return sig; } +RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($set_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::SET, sig_s); + cell->setPort(ID::CLR, sig_c); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + +RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($get_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + +RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +{ + RTLIL::Cell *cell = addCell(name, ID($overwrite_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::SET, sig_s); + cell->setPort(ID::CLR, sig_c); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($original_tag)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_e); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + RTLIL::Wire::Wire() { static unsigned int hashidx_count = 123456789; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a69ce480baf..d29150d32ce 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1465,6 +1465,11 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = ""); RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = ""); + RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + #ifdef WITH_PYTHON static std::map *get_all_modules(void); #endif diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index cdb6e02e762..429e95b2853 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2671,3 +2671,60 @@ endmodule `endif // -------------------------------------------------------- + +module \$set_tag (A, SET, CLR, Y); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +input [WIDTH-1:0] SET; +input [WIDTH-1:0] CLR; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- + +module \$get_tag (A, Y); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- + +module \$overwrite_tag (A, SET, CLR); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +input [WIDTH-1:0] SET; +input [WIDTH-1:0] CLR; + +endmodule + +// -------------------------------------------------------- + +module \$original_tag (A, Y); + +parameter TAG = ""; +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- From 9c255c98b17a8c5258666edf2d323818431def9d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 21 Jun 2023 17:09:28 +0200 Subject: [PATCH 294/303] unescape string tag attribute --- frontends/verific/verific.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 6000df9e628..be417c9dc63 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -251,6 +251,14 @@ static const RTLIL::Const verific_const(const char *value, bool allow_string = t return c; } +static const std::string verific_unescape(const char *value) +{ + std::string val = std::string(value); + if (val.size()>1 && val[0]=='\"' && val.back()=='\"') + return val.substr(1,val.size()-2); + return value; +} + void VerificImporter::import_attributes(dict &attributes, DesignObj *obj, Netlist *nl) { MapIter mi; @@ -1109,13 +1117,13 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); RTLIL::SigSpec sig_o = operatorOutput(inst); - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->connect(sig_o, module->SetTag(new_verific_id(inst), tag, sig_expr, sig_set_mask, sig_clr_mask)); return true; } if (inst->Type() == OPER_YOSYSHQ_GET_TAG) { - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->connect(operatorOutput(inst),module->GetTag(new_verific_id(inst), tag, operatorInput(inst))); return true; } @@ -1124,13 +1132,13 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr RTLIL::SigSpec sig_signal = operatorInport(inst, "signal"); RTLIL::SigSpec sig_set_mask = operatorInport(inst, "set_mask"); RTLIL::SigSpec sig_clr_mask = operatorInport(inst, "clr_mask"); - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->addOverwriteTag(new_verific_id(inst), tag, sig_signal, sig_set_mask, sig_clr_mask); return true; } if (inst->Type() == OPER_YOSYSHQ_ORIGINAL_TAG) { - std::string tag = inst->GetAtt("tag") ? inst->GetAttValue("tag") : ""; + std::string tag = inst->GetAtt("tag") ? verific_unescape(inst->GetAttValue("tag")) : ""; module->connect(operatorOutput(inst),module->OriginalTag(new_verific_id(inst), tag, operatorInput(inst))); return true; } From 27ac91270991ad7c2304e5f90a5c1001c2f08ec1 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 24 Aug 2023 11:55:30 +0200 Subject: [PATCH 295/303] Support import of $future_ff --- frontends/verific/verific.cc | 5 +++++ kernel/celltypes.h | 1 + kernel/rtlil.cc | 18 ++++++++++++++++++ kernel/rtlil.h | 1 + techlibs/common/simlib.v | 13 +++++++++++++ 5 files changed, 38 insertions(+) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index be417c9dc63..d30b46082e1 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -1142,6 +1142,11 @@ bool VerificImporter::import_netlist_instance_cells(Instance *inst, RTLIL::IdStr module->connect(operatorOutput(inst),module->OriginalTag(new_verific_id(inst), tag, operatorInput(inst))); return true; } + if (inst->Type() == OPER_YOSYSHQ_FUTURE_FF) + { + module->connect(operatorOutput(inst),module->FutureFF(new_verific_id(inst), operatorInput(inst))); + return true; + } #undef IN #undef IN1 diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 573ea0b4276..cad505d9afd 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -106,6 +106,7 @@ struct CellTypes setup_type(ID($get_tag), {ID::A}, {ID::Y}); setup_type(ID($overwrite_tag), {ID::A, ID::SET, ID::CLR}, pool()); setup_type(ID($original_tag), {ID::A}, {ID::Y}); + setup_type(ID($future_ff), {ID::A}, {ID::Y}); } void setup_internals_eval() diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2563aa21aa6..7d257714460 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1855,6 +1855,13 @@ namespace { check_expected(); return; } + if (cell->type.in(ID($future_ff))) { + param(ID::WIDTH); + port(ID::A, param(ID::WIDTH)); + port(ID::Y, param(ID::WIDTH)); + check_expected(); + return; + } error(__LINE__); } }; @@ -3323,6 +3330,17 @@ RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::strin return sig; } +RTLIL::SigSpec RTLIL::Module::FutureFF(RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($future_ff)); + cell->parameters[ID::WIDTH] = sig_e.size(); + cell->setPort(ID::A, sig_e); + cell->setPort(ID::Y, sig); + cell->set_src_attribute(src); + return sig; +} + RTLIL::Wire::Wire() { static unsigned int hashidx_count = 123456789; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d29150d32ce..012865a75c6 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1469,6 +1469,7 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = ""); #ifdef WITH_PYTHON static std::map *get_all_modules(void); diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index 429e95b2853..fd804786fd8 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -2728,3 +2728,16 @@ assign Y = A; endmodule // -------------------------------------------------------- + +module \$future_ff (A, Y); + +parameter WIDTH = 0; + +input [WIDTH-1:0] A; +output [WIDTH-1:0] Y; + +assign Y = A; + +endmodule + +// -------------------------------------------------------- From 7a0c37b62d5fadf1ae95afbc9daced71a44fc724 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Thu, 13 Jul 2023 14:04:40 +0200 Subject: [PATCH 296/303] Initial dft_tag implementation This is still missing a mode to rewrite $overwrite_tag and $original_tag by injecting $set_tag and $get_tag in the right places. It's also missing bit-precise propagation models for shifts and arithmetic and requires the design to be flattened. --- passes/cmds/Makefile.inc | 1 + passes/cmds/dft_tag.cc | 932 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 933 insertions(+) create mode 100644 passes/cmds/dft_tag.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index 29b3a1132ad..f3cd9b9509b 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -46,3 +46,4 @@ OBJS += passes/cmds/printattrs.o OBJS += passes/cmds/sta.o OBJS += passes/cmds/clean_zerowidth.o OBJS += passes/cmds/xprop.o +OBJS += passes/cmds/dft_tag.o diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc new file mode 100644 index 00000000000..24fdf9714c8 --- /dev/null +++ b/passes/cmds/dft_tag.cc @@ -0,0 +1,932 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2022 Jannis Harder + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/celltypes.h" +#include "kernel/ff.h" +#include "kernel/modtools.h" +#include "kernel/sigtools.h" +#include "kernel/yosys.h" +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct DftTagOptions { + bool tag_public; +}; + +struct DftTagWorker { + Module *module; + DftTagOptions options; + ModWalker modwalker; + SigMap &sigmap; + FfInitVals initvals; + + struct tag_set { + int index = 0; + + tag_set(int index = 0) : index(index) {} + + bool operator<(const tag_set &other) const { return index < other.index; } + bool operator==(const tag_set &other) const { return index == other.index; } + + unsigned int hash() const { return hash_ops::hash(index); } + + bool empty() const { return index == 0; } + }; + + idict> tag_sets; + + pool tmp_tag_set; + dict, tag_set> tag_set_union_cache; + + dict tagged_signals; + + dict> tag_groups; + dict group_of_tag; + pool all_tags; + + pool pending_cells; + std::deque pending_cell_queue; + + dict, SigBit> tag_signals; + + // Uses SigSpec instead of SigBit so we can use coarse grained cells to combine the individual tags + dict, SigSpec> tag_group_signals; + + pool warned_cells; + + DftTagWorker(Module *module, DftTagOptions options) : + module(module), options(options), modwalker(module->design), sigmap(modwalker.sigmap) + { + modwalker.setup(module); + initvals.set(&modwalker.sigmap, module); + tag_sets(tmp_tag_set); + } + + const pool &tag_pool(tag_set set) { return tag_sets[set.index]; } + + tag_set singleton(IdString tag) + { + tmp_tag_set.clear(); + tmp_tag_set.emplace(tag); + return tag_sets(tmp_tag_set); + } + + tag_set merge(tag_set a, tag_set b) + { + if (b < a) + std::swap(a, b); + if (a.empty() || a == b) + return b; + auto found = tag_set_union_cache.find(std::make_pair(a, b)); + if (found == tag_set_union_cache.end()) { + tmp_tag_set.clear(); + auto &a_tags = tag_pool(a); + auto &b_tags = tag_pool(b); + tmp_tag_set.insert(a_tags.begin(), a_tags.end()); + tmp_tag_set.insert(b_tags.begin(), b_tags.end()); + tag_set result = tag_sets(tmp_tag_set); + tag_set_union_cache.emplace(std::make_pair(a, b), result); + return result; + } + return found->second; + } + + tag_set tags(SigBit bit) + { + sigmap.apply(bit); + auto found = tagged_signals.find(bit); + if (found != tagged_signals.end()) + return found->second; + return tag_set(); + } + + tag_set tags(SigSpec sig) + { + tag_set result; + for (auto bit : sig) + result = merge(result, tags(bit)); + return result; + } + + tag_set tags(Cell *cell) + { + tag_set result; + for (auto &conn : cell->connections()) { + if (cell->input(conn.first)) + result = merge(result, tags(conn.second)); + } + return result; + } + + void add_tags(SigBit bit, tag_set new_tags) + { + sigmap.apply(bit); + auto &tags = tagged_signals[bit]; + tag_set merged_tags = merge(tags, new_tags); + if (merged_tags == tags) + return; + tags = merged_tags; + auto it = modwalker.signal_consumers.find(bit); + if (it == modwalker.signal_consumers.end()) + return; + for (auto &consumer : it->second) + if (pending_cells.insert(consumer.cell).second) + pending_cell_queue.push_back(consumer.cell); + } + + void add_tags(SigSpec sig, tag_set new_tags) + { + for (auto bit : sigmap(sig)) + add_tags(bit, new_tags); + } + + void add_tags(Cell *cell, tag_set new_tags) + { + for (auto &conn : cell->connections()) + if (cell->output(conn.first)) + add_tags(conn.second, new_tags); + } + + void forward_tags(SigSpec dst, SigSpec src) + { + log_assert(GetSize(dst) == GetSize(src)); + for (int i = 0; i < GetSize(dst); i++) + add_tags(dst[i], tags(src[i])); + } + + void propagate_tags() + { + for (auto cell : module->cells()) { + if (cell->type == ID($set_tag)) { + pending_cells.insert(cell); + pending_cell_queue.push_back(cell); + } + } + + while (!pending_cell_queue.empty()) { + Cell *cell = pending_cell_queue.front(); + pending_cell_queue.pop_front(); + pending_cells.erase(cell); + + propagate_tags(cell); + } + } + + SigBit tag_signal(IdString tag, SigBit bit) + { + sigmap.apply(bit); + if (!bit.is_wire()) + return State::S0; // Constant value - no tags + + auto found = tag_signals.find(std::make_pair(tag, bit)); + if (found != tag_signals.end()) + return found->second; + + if (!tag_pool(tags(bit)).count(tag)) + return State::S0; // Statically known to not have this tag + + // TODO handle module inputs + auto drivers = modwalker.signal_drivers.find(bit); + if (drivers == modwalker.signal_drivers.end() || drivers->second.empty()) + return State::S0; // No driver - no tags + + log_assert(drivers->second.size() == 1); + auto driver = *drivers->second.begin(); + + emit_tag_signals(tag, driver.cell); + + found = tag_signals.find(std::make_pair(tag, bit)); + log_assert(found != tag_signals.end()); + return found->second; + } + + SigSpec tag_signal(IdString tag, SigSpec sig) + { + SigSpec result; + for (auto bit : sig) + result.append(tag_signal(tag, bit)); + return result; + } + + SigSpec tag_group_signal(IdString tag_group, SigSpec sig) + { + sigmap.apply(sig); + if (sig.is_fully_const() || tag_groups.count(tag_group) == 0) + return Const(0, GetSize(sig)); + + auto found = tag_group_signals.find(std::make_pair(tag_group, sig)); + if (found != tag_group_signals.end()) + return found->second; + + SigSpec combined; + + for (auto &tag : tag_groups[tag_group]) { + auto tag_sig = tag_signal(tag, sig); + + if (!GetSize(combined)) + combined = tag_sig; + else + combined = autoOr(NEW_ID, combined, tag_sig); + } + + if (!GetSize(combined)) + combined = Const(0, GetSize(sig)); + + tag_group_signals.emplace(std::make_pair(tag_group, sig), combined); + return combined; + } + + void emit_tag_signal(IdString tag, SigBit bit, SigBit tag_bit) + { + sigmap.apply(bit); + sigmap.apply(tag_bit); + + if (!tag_pool(tags(bit)).count(tag)) + return; + + auto key = std::make_pair(tag, bit); + auto found = tag_signals.find(key); + if (found != tag_signals.end()) { + module->connect(found->second, tag_bit); + return; + } + tag_signals.emplace(key, tag_bit); + } + + void emit_tag_signal(IdString tag, SigSpec sig, SigSpec tag_sig) + { + log_assert(GetSize(sig) == GetSize(tag_sig)); + for (int i = 0; i < GetSize(sig); i++) + emit_tag_signal(tag, sig[i], tag_sig[i]); + } + + void emit_tag_signals(IdString tag, Cell *cell) + { + if (!pending_cells.insert(cell).second) { + // We have a cycle, emit placeholder wires which will be connected + // when the outer call for this tag/cell returns + for (auto &conn : cell->connections()) + if (cell->output(conn.first)) + emit_tag_signal(tag, conn.second, module->addWire(NEW_ID, GetSize(conn.second))); + + return; + } + + process_cell(tag, cell); + + pending_cells.erase(cell); + } + + void propagate_tags(Cell *cell) + { + if (cell->type == ID($set_tag)) { + IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + if (all_tags.insert(tag).second) { + auto group_sep = tag.str().find(':'); + IdString tag_group = group_sep != std::string::npos ? tag.str().substr(0, group_sep) : tag; + tag_groups[tag_group].insert(tag); + group_of_tag[tag] = tag_group; + } + + auto &sig_y = cell->getPort(ID::Y); + auto &sig_a = cell->getPort(ID::A); + // TODO handle constant set/clr masks + add_tags(sig_y, singleton(tag)); + forward_tags(sig_y, sig_a); + return; + } + + if (cell->type == ID($get_tag)) { + return; + } + + if (cell->type.in(ID($not), ID($pos))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + if (cell->type.in(ID($not), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + } + forward_tags(sig_y, sig_a); + return; + } + + if (cell->type.in(ID($and), ID($or), ID($xor), ID($xnor), ID($bweqx))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + if (cell->type.in(ID($and), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); + } + forward_tags(sig_y, sig_a); + forward_tags(sig_y, sig_b); + return; + } + + if (cell->type.in(ID($mux), ID($bwmux))) { + auto &sig_y = cell->getPort(ID::Y); + auto &sig_a = cell->getPort(ID::A); + auto &sig_b = cell->getPort(ID::B); + auto sig_s = cell->getPort(ID::S); + + if (cell->type == ID($mux)) + sig_s = SigSpec(sig_s[0], GetSize(sig_y)); + + forward_tags(sig_y, sig_a); + forward_tags(sig_y, sig_b); + forward_tags(sig_y, sig_s); + return; + } + + if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + FfData ff(&initvals, cell); + + if (ff.has_clk || ff.has_gclk) + forward_tags(ff.sig_q, ff.sig_d); + return; + } + + // Single output but, sensitive to all inputs + if (cell->type.in( + ID($le), ID($lt), ID($ge), ID($gt), + ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), + ID($reduce_bool), ID($logic_not), ID($logic_or), ID($logic_and), + ID($eq), ID($ne) + )) { + auto &sig_y = cell->getPort(ID::Y); + + add_tags(sig_y[0], tags(cell)); + return; + } + + + // Fallback, propagate tags from all inputs to all outputs + add_tags(cell, tags(cell)); + + if (cell->type.in( + ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_), + ID($_XOR_), ID($_XNOR_), ID($_NOT_), ID($_BUF_), ID($_MUX_), + + ID($assert), ID($assume) + )) { + return; + } + + // This isn't a correctness concern (unless cell is a module generating + // tags), but we may end up generating a lot of extra logic when + // reaching this + if (!warned_cells.insert(cell).second) + return; + if (cell->type.isPublic()) + log_warning("Unhandled cell %s (%s) during tag propagation\n", log_id(cell), log_id(cell->type)); + else + log_debug("Unhandled cell %s (%s) during tag propagation\n", log_id(cell), log_id(cell->type)); + } + + void process_cell(IdString tag, Cell *cell) + { + if (cell->type == ID($set_tag)) { + IdString cell_tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + + auto tag_sig_a = tag_signal(tag, cell->getPort(ID::A)); + auto &sig_y = cell->getPort(ID::Y); + + if (cell_tag == tag) { + auto &sig_set = cell->getPort(ID::SET); + auto &sig_clr = cell->getPort(ID::CLR); + tag_sig_a = autoAnd(NEW_ID, tag_sig_a, autoNot(NEW_ID, sig_clr)); + tag_sig_a = autoOr(NEW_ID, tag_sig_a, sig_set); + } + + emit_tag_signal(tag, sig_y, tag_sig_a); + return; + } + + if (cell->type == ID($get_tag)) { + log_assert(false); + } + + if (cell->type.in(ID($not), ID($pos), ID($_NOT_), ID($_BUF_))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + if (cell->type.in(ID($not), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + } + emit_tag_signal(tag, sig_y, tag_signal(tag, sig_a)); + return; + } + + if (cell->type.in( + ID($and), ID($or), + ID($_AND_), ID($_OR_), ID($_NAND_), ID($_NOR_), ID($_ANDNOT_), ID($_ORNOT_) + )) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + if (cell->type.in(ID($and), ID($or))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); + } + + bool inv_a = false; + bool inv_b = false; + + if (cell->type.in(ID($or), ID($_OR_), ID($_NOR_), ID($_ORNOT_))) + inv_a ^= true, inv_b ^= true; + if (cell->type.in(ID($_ANDNOT_), ID($_ORNOT_))) + inv_b ^= true; + + if (inv_a) + sig_a = autoNot(NEW_ID, sig_a); + if (inv_b) + sig_b = autoNot(NEW_ID, sig_b); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + + // Does this input allow propagating (doesn't fix output or same tag group) + sig_a = autoOr(NEW_ID, sig_a, group_sig_a); + sig_b = autoOr(NEW_ID, sig_b, group_sig_b); + + // Mask input tags by whether the other side allows propagation + tag_sig_a = autoAnd(NEW_ID, tag_sig_a, sig_b); + tag_sig_b = autoAnd(NEW_ID, tag_sig_b, sig_a); + + + auto tag_sig = autoOr(NEW_ID, tag_sig_a, tag_sig_b); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (cell->type.in(ID($xor), ID($xnor), ID($bweqx), ID($_XOR_), ID($_XNOR_))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + if (cell->type.in(ID($xor), ID($xnor))) { + sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(GetSize(sig_y), cell->getParam(ID::B_SIGNED).as_bool()); + } + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + auto tag_sig = autoOr(NEW_ID, tag_sig_a, tag_sig_b); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + + if (cell->type.in(ID($_MUX_), ID($mux), ID($bwmux))) { + auto &sig_y = cell->getPort(ID::Y); + auto &sig_a = cell->getPort(ID::A); + auto &sig_b = cell->getPort(ID::B); + auto sig_s = cell->getPort(ID::S); + + if (cell->type == ID($mux)) + sig_s = SigSpec(sig_s[0], GetSize(sig_y)); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + auto group_sig_s = tag_group_signal(tag, sig_s); + + auto prop_s = autoOr(NEW_ID, + autoXor(NEW_ID, sig_a, sig_b), + autoOr(NEW_ID, group_sig_a, group_sig_b)); + + auto prop_a = autoOr(NEW_ID, autoNot(NEW_ID, sig_s), group_sig_s); + auto prop_b = autoOr(NEW_ID, sig_s, group_sig_s); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + auto tag_sig_s = tag_signal(tag, sig_s); + + tag_sig_a = autoAnd(NEW_ID, tag_sig_a, prop_a); + tag_sig_b = autoAnd(NEW_ID, tag_sig_b, prop_b); + tag_sig_s = autoAnd(NEW_ID, tag_sig_s, prop_s); + + auto tag_sig = autoOr(NEW_ID, tag_sig_s, + autoOr(NEW_ID, tag_sig_a, tag_sig_b)); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (cell->type.in(ID($eq), ID($ne), ID($eqx), ID($nex))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + int width = std::max(GetSize(sig_a), GetSize(sig_b)); + sig_a.extend_u0(width, cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(width, cell->getParam(ID::B_SIGNED).as_bool()); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + auto group_sig = autoOr(NEW_ID, group_sig_a, group_sig_b); + // The output can only be affected by the tagged inputs if all group-untagged bits are equal + + auto masked_a = autoOr(NEW_ID, sig_a, group_sig); + auto masked_b = autoOr(NEW_ID, sig_b, group_sig); + + auto prop = autoEq(NEW_ID, masked_a, masked_b); + + auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b})); + tag_sig.extend_u0(GetSize(sig_y), false); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + + if (cell->type.in(ID($lt), ID($gt), ID($le), ID($ge))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + auto sig_b = cell->getPort(ID::B); + int width = std::max(GetSize(sig_a), GetSize(sig_b)); + sig_a.extend_u0(width, cell->getParam(ID::A_SIGNED).as_bool()); + sig_b.extend_u0(width, cell->getParam(ID::B_SIGNED).as_bool()); + + if (cell->type.in(ID($gt), ID($le))) + std::swap(sig_a, sig_b); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto group_sig_b = tag_group_signal(tag, sig_b); + + auto tag_sig_a = tag_signal(tag, sig_a); + auto tag_sig_b = tag_signal(tag, sig_b); + + auto group_sig = autoOr(NEW_ID, group_sig_a, group_sig_b); + // The output can only be affected by the tagged inputs if the greatest possible sig_a is + // greater or equal to the least possible sig_b + auto masked_a = autoOr(NEW_ID, sig_a, group_sig); + auto masked_b = autoAnd(NEW_ID, sig_b, autoNot(NEW_ID, group_sig)); + + auto prop = autoGe(NEW_ID, masked_a, masked_b); + + auto tag_sig = autoAnd(NEW_ID, prop, autoReduceOr(NEW_ID, {tag_sig_a, tag_sig_b})); + tag_sig.extend_u0(GetSize(sig_y), false); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (cell->type.in(ID($reduce_and), ID($reduce_or), ID($reduce_bool), ID($logic_not))) { + auto &sig_y = cell->getPort(ID::Y); + auto sig_a = cell->getPort(ID::A); + + if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($logic_not))) + sig_a = autoNot(NEW_ID, sig_a); + + auto group_sig_a = tag_group_signal(tag, sig_a); + auto tag_sig_a = tag_signal(tag, sig_a); + + auto filled = autoOr(NEW_ID, sig_a, group_sig_a); + + auto prop = autoReduceAnd(NEW_ID, filled); + auto tagged = autoReduceOr(NEW_ID, tag_sig_a); + auto tag_sig = autoAnd(NEW_ID, prop, tagged); + tag_sig.extend_u0(GetSize(sig_y), false); + emit_tag_signal(tag, sig_y, tag_sig); + return; + } + + if (RTLIL::builtin_ff_cell_types().count(cell->type) || cell->type == ID($anyinit)) { + FfData ff(&initvals, cell); + // TODO handle some more variants + if ((ff.has_clk || ff.has_gclk) && !ff.has_ce && !ff.has_aload && !ff.has_srst && !ff.has_arst && !ff.has_sr) { + if (ff.has_clk && !tags(ff.sig_clk).empty()) + log_warning("Tags on CLK input ignored for %s (%s)\n", log_id(cell), log_id(cell->type)); + + int width = ff.width; + + auto sig_q = ff.sig_q; + auto sig_d = ff.sig_d; + + ff.name = NEW_ID; + ff.cell = nullptr; + ff.sig_d = tag_signal(tag, ff.sig_d); + ff.sig_q = module->addWire(NEW_ID, width); + ff.is_anyinit = false; + ff.val_init = Const(0, width); + ff.emit(); + + emit_tag_signal(tag, sig_q, ff.sig_q); + return; + } else { + log_warning("Unhandled FF-cell %s (%s), consider running clk2fflogic, async2sync and/or dffunmap\n", log_id(cell), log_id(cell->type)); + + // For unhandled FFs, the default propagation would cause combinational loops + emit_tag_signal(tag, ff.sig_q, Const(0, ff.width)); + return; + } + } + + // Fallback + SigSpec tag_input; + + for (auto &conn : cell->connections()) { + if (cell->input(conn.first)) { + auto tag_sig = tag_signal(tag, conn.second); + tag_input.append(tag_sig); + } + } + + SigBit any_tagged = autoReduceOr(NEW_ID, tag_input); + + for (auto &conn : cell->connections()) { + if (cell->output(conn.first)) { + emit_tag_signal(tag, conn.second, SigSpec(any_tagged, GetSize(conn.second))); + } + } + + // As fallback we propagate all tags from all inputs to all outputs, + // which is an over-approximation (unless the cell is a module that + // generates tags itself in which case it could be arbitrary). + if (warned_cells.insert(cell).second) + log_warning("Unhandled cell %s (%s) while emitting tag signals\n", log_id(cell), log_id(cell->type)); + } + + void emit_tags() + { + warned_cells.clear(); + std::vector get_tag_cells; + for (auto cell : module->selected_cells()) + if (cell->type == ID($get_tag)) + get_tag_cells.push_back(cell); + + for (auto cell : get_tag_cells) { + auto &sig_a = cell->getPort(ID::A); + IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + + tag_signal(tag, sig_a); + } + + if (options.tag_public) + { + std::vector public_wires; + + for (auto wire : module->selected_wires()) + if (wire->name.isPublic()) + public_wires.push_back(wire); + + for (auto wire : public_wires) { + for (auto tag : tag_pool(tags(SigSpec(wire)))) { + auto tag_sig = tag_signal(tag, SigSpec(wire)); + if (tag_sig.is_fully_zero()) + continue; + + int index = 0; + auto name = module->uniquify(stringf("%s:%s", wire->name.c_str(), tag.c_str() + 1), index); + auto hdlname = wire->get_hdlname_attribute(); + + if (!hdlname.empty()) + hdlname.back() += index ? + stringf(":%s_%d", tag.c_str() + 1, index) : + stringf(":%s", tag.c_str() + 1); + + auto tag_wire = module->addWire(name, wire->width); + + tag_wire->set_bool_attribute(ID::keep); + tag_wire->set_bool_attribute(ID(dft_tag)); + if (!hdlname.empty()) + tag_wire->set_hdlname_attribute(hdlname); + + module->connect(tag_wire, tag_sig); + } + } + } + } + + void replace_dft_cells() + { + std::vector get_tag_cells; + std::vector set_tag_cells; + for (auto cell : module->cells()) { + if (cell->type == ID($get_tag)) + get_tag_cells.push_back(cell); + + if (cell->type == ID($set_tag)) + set_tag_cells.push_back(cell); + + if (cell->type.in(ID($overwrite_tag), ID($original_tag))) + log_error("$overwrite_tag and $original_tag are not supported yet\n"); + // TODO these have to be rewritten as early as possible, so it should be a separate pass invocation + } + + for (auto cell : set_tag_cells) { + auto &sig_a = cell->getPort(ID::A); + auto &sig_y = cell->getPort(ID::Y); + module->connect(sig_y, sig_a); + module->remove(cell); + } + + for (auto cell : get_tag_cells) { + auto &sig_a = cell->getPort(ID::A); + auto &sig_y = cell->getPort(ID::Y); + IdString tag = stringf("\\%s", cell->getParam(ID::TAG).decode_string().c_str()); + + auto tag_sig = tag_signal(tag, sig_a); + module->connect(sig_y, tag_sig); + module->remove(cell); + } + } + + + SigSpec autoAnd(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a.is_fully_zero() || sig_b.is_fully_ones() || sig_a == sig_b) + return sig_a; + if (sig_a.is_fully_ones() || sig_b.is_fully_zero()) + return sig_b; + + return module->And(name, sig_a, sig_b); + } + + SigSpec autoOr(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a.is_fully_ones() || sig_b.is_fully_zero() || sig_a == sig_b) + return sig_a; + if (sig_a.is_fully_zero() || sig_b.is_fully_ones()) + return sig_b; + + return module->Or(name, sig_a, sig_b); + } + + SigSpec autoXor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b) + return Const(State::S0, GetSize(sig_a)); + if (sig_a.is_fully_zero()) + return sig_b; + if (sig_b.is_fully_zero()) + return sig_a; + if (sig_a.is_fully_ones()) + return autoNot(name, sig_b); + if (sig_b.is_fully_ones()) + return autoNot(name, sig_a); + return module->Xor(name, sig_a, sig_b); + } + + SigSpec autoXnor(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b) + return Const(State::S1, GetSize(sig_a)); + if (sig_a.is_fully_ones()) + return sig_b; + if (sig_b.is_fully_ones()) + return sig_a; + if (sig_a.is_fully_zero()) + return autoNot(name, sig_b); + if (sig_b.is_fully_zero()) + return autoNot(name, sig_a); + return module->Xnor(name, sig_a, sig_b); + } + + SigSpec autoNot(IdString name, const SigSpec &sig_a) + { + if (sig_a.is_fully_const()) { + auto const_val = sig_a.as_const(); + for (auto &bit : const_val.bits) + bit = bit == State::S0 ? State::S1 : bit == State::S1 ? State::S0 : bit; + return const_val; + } + return module->Not(name, sig_a); + } + + SigSpec autoEq(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b) + return State::S1; + for (int i = 0; i < GetSize(sig_a); i++) { + auto bit_a = sig_a[i]; + auto bit_b = sig_b[i]; + if (bit_a.is_wire() || bit_b.is_wire()) + continue; + if ((bit_a.data == State::S0 && bit_b.data == State::S1) || + (bit_a.data == State::S1 && bit_b.data == State::S0)) + return State::S0; + } + + return module->Eq(name, sig_a, sig_b); + } + + SigSpec autoGe(IdString name, const SigSpec &sig_a, const SigSpec &sig_b) + { + log_assert(GetSize(sig_a) == GetSize(sig_b)); + if (sig_a == sig_b || sig_a.is_fully_ones()) + return State::S1; + if (sig_b.is_fully_zero()) + return State::S1; + + return module->Ge(name, sig_a, sig_b); + } + + SigSpec autoReduceAnd(IdString name, const SigSpec &sig_a) + { + if (GetSize(sig_a) == 0) + return State::S1; + + if (GetSize(sig_a) == 1 || sig_a == SigSpec(sig_a[0], GetSize(sig_a))) + return sig_a[0]; + for (auto bit : sig_a) + if (!bit.is_wire() && bit.data == State::S0) + return State::S0; + if (sig_a.is_fully_ones()) + return State::S1; + return module->ReduceAnd(name, sig_a); + } + + SigSpec autoReduceOr(IdString name, const SigSpec &sig_a) + { + if (GetSize(sig_a) == 0) + return State::S0; + + if (GetSize(sig_a) == 1 || sig_a == SigSpec(sig_a[0], GetSize(sig_a))) + return sig_a[0]; + for (auto bit : sig_a) + if (!bit.is_wire() && bit.data == State::S1) + return State::S1; + if (sig_a.is_fully_zero()) + return State::S0; + return module->ReduceOr(name, sig_a); + } +}; + +struct DftTagPass : public Pass { + DftTagPass() : Pass("dft_tag", "create tagging logic for data flow tracking") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" dft_tag [options] [selection]\n"); + log("\n"); + log("This pass... TODO\n"); + log("\n"); + log(" -tag-public\n"); + log(" For each public wire that may carry tagged data, create a new public\n"); + log(" wire (named :) that carries the tag bits. Note\n"); + log(" that without this, tagging logic will only be emitted as required\n"); + log(" for uses of $get_tag.\n"); + log("\n"); + } + + void execute(std::vector args, RTLIL::Design *design) override + { + DftTagOptions options; + + log_header(design, "Executing DFT_TAG pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + if (args[argidx] == "-tag-public") { + options.tag_public = true; + continue; + } + break; + } + + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + DftTagWorker worker(module, options); + + log_debug("Propagate tagged signals.\n"); + worker.propagate_tags(); + + log_debug("Emit tag signals and logic.\n"); + worker.emit_tags(); + + log_debug("Replace dft cells.\n"); + worker.replace_dft_cells(); + } + } +} DftTagPass; + +PRIVATE_NAMESPACE_END From 46a35da28cfe832b5da6b87ec6642574efb47d92 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 29 Aug 2023 15:47:05 +0200 Subject: [PATCH 297/303] Add `future` pass to resolve `$future_ff` cells --- passes/cmds/Makefile.inc | 1 + passes/cmds/future.cc | 140 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 passes/cmds/future.cc diff --git a/passes/cmds/Makefile.inc b/passes/cmds/Makefile.inc index f3cd9b9509b..d7e572462b0 100644 --- a/passes/cmds/Makefile.inc +++ b/passes/cmds/Makefile.inc @@ -47,3 +47,4 @@ OBJS += passes/cmds/sta.o OBJS += passes/cmds/clean_zerowidth.o OBJS += passes/cmds/xprop.o OBJS += passes/cmds/dft_tag.o +OBJS += passes/cmds/future.o diff --git a/passes/cmds/future.cc b/passes/cmds/future.cc new file mode 100644 index 00000000000..b03613c9bd2 --- /dev/null +++ b/passes/cmds/future.cc @@ -0,0 +1,140 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2023 Jannis Harder + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "kernel/celltypes.h" +#include "kernel/ff.h" +#include "kernel/ffinit.h" +#include "kernel/modtools.h" +#include "kernel/sigtools.h" +#include "kernel/utils.h" +#include "kernel/yosys.h" +#include + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct FutureOptions { +}; + +struct FutureWorker { + Module *module; + FutureOptions options; + ModWalker modwalker; + SigMap &sigmap; + FfInitVals initvals; + + dict future_ff_signals; + + FutureWorker(Module *module, FutureOptions options) : + module(module), options(options), modwalker(module->design), sigmap(modwalker.sigmap) + { + modwalker.setup(module); + initvals.set(&modwalker.sigmap, module); + + std::vector replaced_cells; + for (auto cell : module->selected_cells()) { + if (cell->type != ID($future_ff)) + continue; + + module->connect(cell->getPort(ID::Y), future_ff(cell->getPort(ID::A))); + replaced_cells.push_back(cell); + } + + for (auto cell : replaced_cells) { + module->remove(cell); + } + } + + SigSpec future_ff(SigSpec sig) + { + for (auto &bit : sig) { + bit = future_ff(bit); + } + return sig; + } + + SigBit future_ff(SigBit bit) + { + if (!bit.is_wire()) + return bit; + + auto found = future_ff_signals.find(bit); + if (found != future_ff_signals.end()) + return found->second; + + auto found_driver = modwalker.signal_drivers.find(bit); + if (found_driver == modwalker.signal_drivers.end() || found_driver->second.size() < 1) + log_error("No driver for future_ff target signal %s found\n", log_signal(bit)); + if (found_driver->second.size() > 1) + log_error("Found multiple drivers for future_ff target signal %s\n", log_signal(bit)); + auto driver = *found_driver->second.begin(); + if (!RTLIL::builtin_ff_cell_types().count(driver.cell->type) && driver.cell->type != ID($anyinit)) + log_error("Driver for future_ff target signal %s has non-FF cell type %s\n", log_signal(bit), log_id(driver.cell->type)); + + FfData ff(&initvals, driver.cell); + + if (!ff.has_clk && !ff.has_gclk) + log_error("Driver for future_ff target signal %s has cell type %s, which is not clocked\n", log_signal(bit), + log_id(driver.cell->type)); + + ff.unmap_ce_srst(); + + // We insert all bits into the mapping, because unmap_ce_srst might + // have removed the cell which is still present in the modwalker data. + // By inserting all bits driven by th FF we ensure that we'll never use + // that stale modwalker data again. + + for (int i = 0; i < ff.width; ++i) { + future_ff_signals.emplace(ff.sig_q[i], ff.sig_d[i]); + } + + return future_ff_signals.at(bit); + } +}; + +struct FuturePass : public Pass { + FuturePass() : Pass("future", "resolve future sampled value functions") {} + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" future [options] [selection]\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) override + { + FutureOptions options; + + log_header(design, "Executing FUTURE pass.\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + + break; + } + + extra_args(args, argidx, design); + + for (auto module : design->selected_modules()) { + FutureWorker worker(module, options); + } + } +} FuturePass; + +PRIVATE_NAMESPACE_END From 78ff40d1b28ed62f3d98c1ed970ce7ba482cf8d6 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 29 Aug 2023 15:50:17 +0200 Subject: [PATCH 298/303] Run `future` as part of `prep` --- techlibs/common/prep.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/techlibs/common/prep.cc b/techlibs/common/prep.cc index c354956bcf4..e9176304d48 100644 --- a/techlibs/common/prep.cc +++ b/techlibs/common/prep.cc @@ -189,6 +189,7 @@ struct PrepPass : public ScriptPass run(ifxmode ? "proc -ifx" : "proc"); if (help_mode || flatten) run("flatten", "(if -flatten)"); + run("future"); run(nokeepdc ? "opt_expr" : "opt_expr -keepdc"); run("opt_clean"); run("check"); From 62b4df49891034d48b3f24e78b83e7c49b23432c Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 29 Aug 2023 17:40:51 +0200 Subject: [PATCH 299/303] dft_tag: Implement `$overwrite_tag` and `$original_tag` This does not correctly handle an `$overwrite_tag` on a module output, but since we currently require the user to flatten the design for cross-module dft, this cannot be observed from within the design, only by manually inspecting the signals in the design. --- kernel/rtlil.cc | 43 ++++++++++++------- kernel/rtlil.h | 9 ++-- passes/cmds/dft_tag.cc | 91 +++++++++++++++++++++++++++++++++++++++-- passes/opt/opt_clean.cc | 3 ++ 4 files changed, 123 insertions(+), 23 deletions(-) diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7d257714460..51d02091308 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -3280,13 +3280,13 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const std::string return sig; } -RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) { - RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($set_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::SET, sig_s); cell->setPort(ID::CLR, sig_c); cell->setPort(ID::Y, sig); @@ -3294,37 +3294,50 @@ RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &ta return sig; } -RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +RTLIL::Cell* RTLIL::Module::addSetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const std::string &src) { - RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + Cell *cell = addCell(name, ID($set_tag)); + cell->parameters[ID::WIDTH] = sig_a.size(); + cell->parameters[ID::TAG] = tag; + cell->setPort(ID::A, sig_a); + cell->setPort(ID::SET, sig_s); + cell->setPort(ID::CLR, sig_c); + cell->setPort(ID::Y, sig_y); + cell->set_src_attribute(src); + return cell; +} + +RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src) +{ + RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($get_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; } -RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) +RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src) { RTLIL::Cell *cell = addCell(name, ID($overwrite_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::SET, sig_s); cell->setPort(ID::CLR, sig_c); cell->set_src_attribute(src); return cell; } -RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src) +RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src) { - RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); + RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($original_tag)); - cell->parameters[ID::WIDTH] = sig_e.size(); + cell->parameters[ID::WIDTH] = sig_a.size(); cell->parameters[ID::TAG] = tag; - cell->setPort(ID::A, sig_e); + cell->setPort(ID::A, sig_a); cell->setPort(ID::Y, sig); cell->set_src_attribute(src); return sig; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 012865a75c6..c50d75e9087 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1465,10 +1465,11 @@ struct RTLIL::Module : public RTLIL::AttrObject RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = ""); RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = ""); - RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); - RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); - RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); - RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_e, const std::string &src = ""); + RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::Cell* addSetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const std::string &src = ""); + RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = ""); + RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = ""); + RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = ""); RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = ""); #ifdef WITH_PYTHON diff --git a/passes/cmds/dft_tag.cc b/passes/cmds/dft_tag.cc index 24fdf9714c8..9fd356ef65d 100644 --- a/passes/cmds/dft_tag.cc +++ b/passes/cmds/dft_tag.cc @@ -28,7 +28,8 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN struct DftTagOptions { - bool tag_public; + bool tag_public = false; + bool overwrite_only = false; }; struct DftTagWorker { @@ -80,6 +81,78 @@ struct DftTagWorker { tag_sets(tmp_tag_set); } + void resolve_overwrites() + { + std::vector overwrite_cells; + std::vector original_cells; + + bool design_changed = false; + + for (auto cell : module->cells()) { + if (cell->type == ID($overwrite_tag)) + overwrite_cells.push_back(cell); + + if (cell->type == ID($original_tag)) + original_cells.push_back(cell); + } + + for (auto cell : overwrite_cells) { + log_debug("Applying $overwrite_tag %s for signal %s\n", log_id(cell->name), log_signal(cell->getPort(ID::A))); + SigSpec orig_signal = cell->getPort(ID::A); + SigSpec interposed_signal = divert_users(orig_signal); + auto *set_tag_cell = module->addSetTag(NEW_ID, cell->getParam(ID::TAG).decode_string(), orig_signal, cell->getPort(ID::SET), cell->getPort(ID::CLR), interposed_signal); + modwalker.add_cell(set_tag_cell); // Make sure the next $overwrite_tag sees the new connections + design_changed = true; + } + + for (auto cell : overwrite_cells) { + module->remove(cell); + } + for (auto cell : original_cells) { + cell->type = ID($get_tag); + } + + if (design_changed) + modwalker.setup(module); + } + + SigSpec divert_users(SigSpec signal) + { + SigSpec signal_mapped = sigmap(signal); + signal_mapped.sort_and_unify(); + if (GetSize(signal_mapped) < GetSize(signal)) + log_warning("Detected $overwrite_tag on signal %s which contains repeated bits, this can result in unexpected behavior.\n", log_signal(signal)); + SigSpec new_wire = module->addWire(NEW_ID, GetSize(signal)); + for (int i = 0; i < GetSize(new_wire); ++i) + divert_users(signal[i], new_wire[i]); + return new_wire; + } + + void divert_users(SigBit driver_bit, SigBit interposed_bit) + { + dict, SigSpec> updated_ports; + // TODO also check module outputs + auto found = modwalker.signal_consumers.find(driver_bit); + if (found == modwalker.signal_consumers.end()) + return; + for (auto &consumer : found->second) { + if (consumer.cell->type.in(ID($original_tag))) + continue; + if (sigmap(consumer.cell->getPort(consumer.port)[consumer.offset]) != driver_bit) + continue; + std::pair key = {consumer.cell, consumer.port}; + auto found_port = updated_ports.find(key); + if (found_port == updated_ports.end()) { + updated_ports.emplace(key, consumer.cell->getPort(consumer.port)); + } + updated_ports[key][consumer.offset] = interposed_bit; + } + for (auto &update : updated_ports) { + update.first.first->setPort(update.first.second, update.second); + modwalker.add_cell(update.first.first); // Make sure the next $overwrite_tag sees the new connections + } + } + const pool &tag_pool(tag_set set) { return tag_sets[set.index]; } tag_set singleton(IdString tag) @@ -730,9 +803,7 @@ struct DftTagWorker { if (cell->type == ID($set_tag)) set_tag_cells.push_back(cell); - if (cell->type.in(ID($overwrite_tag), ID($original_tag))) - log_error("$overwrite_tag and $original_tag are not supported yet\n"); - // TODO these have to be rewritten as early as possible, so it should be a separate pass invocation + log_assert(!cell->type.in(ID($overwrite_tag), ID($original_tag))); } for (auto cell : set_tag_cells) { @@ -889,6 +960,8 @@ struct DftTagPass : public Pass { log("\n"); log("This pass... TODO\n"); log("\n"); + log(" -overwrite-only\n"); + log(" Only process $overwrite_tag and $original_tag cells.\n"); log(" -tag-public\n"); log(" For each public wire that may carry tagged data, create a new public\n"); log(" wire (named :) that carries the tag bits. Note\n"); @@ -909,6 +982,10 @@ struct DftTagPass : public Pass { options.tag_public = true; continue; } + if (args[argidx] == "-overwrite-only") { + options.overwrite_only = true; + continue; + } break; } @@ -917,6 +994,12 @@ struct DftTagPass : public Pass { for (auto module : design->selected_modules()) { DftTagWorker worker(module, options); + log_debug("Resolve overwrite_tag and original_tag.\n"); + worker.resolve_overwrites(); + + if (options.overwrite_only) + continue; + log_debug("Propagate tagged signals.\n"); worker.propagate_tags(); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 4da67cf630f..a219e470813 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -76,6 +76,9 @@ struct keep_cache_t if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) return true; + if (cell->type.in(ID($overwrite_tag))) + return true; + if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule))) return true; From 0e8a4adb59f34e70acbe1cb1b8af5b015f4eb2b3 Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Tue, 5 Sep 2023 11:52:21 +0200 Subject: [PATCH 300/303] verific: Update YOSYSHQ_VERIFIC_API_VERSION --- frontends/verific/verific.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index d30b46082e1..a67244d7ab3 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -74,7 +74,7 @@ USING_YOSYS_NAMESPACE # error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific." #endif -#if YOSYSHQ_VERIFIC_API_VERSION < 20210801 +#if YOSYSHQ_VERIFIC_API_VERSION < 20230901 # error "Please update your version of YosysHQ flavored Verific." #endif From e9a11dd08863ad0bfcb4d21f7d152da710bacdd8 Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 13 Sep 2023 11:35:46 +0000 Subject: [PATCH 301/303] Update ABC for WASI support. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0c79636497f..b5a89ae0782 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 9537f39 +ABCREV = 6b66b81 ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From c7d7cfeaca6c79b871aca39c0878cf189390c497 Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 13 Sep 2023 15:06:27 +0000 Subject: [PATCH 302/303] Update ABC for WASI support. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b5a89ae0782..178d6ee4d30 100644 --- a/Makefile +++ b/Makefile @@ -165,7 +165,7 @@ bumpversion: # is just a symlink to your actual ABC working directory, as 'make mrproper' # will remove the 'abc' directory and you do not want to accidentally # delete your work on ABC.. -ABCREV = 6b66b81 +ABCREV = daad9ed ABCPULL = 1 ABCURL ?= https://github.com/YosysHQ/abc ABCMKARGS = CC="$(CXX)" CXX="$(CXX)" ABC_USE_LIBSTDCXX=1 ABC_USE_NAMESPACE=abc VERBOSE=$(Q) From b84ed5d3ad2ac8b533e1d6a83dbdb6d5c2be9ce7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 00:14:42 +0000 Subject: [PATCH 303/303] Bump version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 178d6ee4d30..d7ecff99921 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ LDLIBS += -lrt endif endif -YOSYS_VER := 0.33+21 +YOSYS_VER := 0.33+34 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo