From ab98f604fd1319e0f42b0c5dc8bb6be5d3d2ba38 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 3 Aug 2019 12:29:30 +0200 Subject: [PATCH 01/32] Initial EFINIX support --- techlibs/efinix/Makefile.inc | 6 + techlibs/efinix/arith_map.v | 78 ++++++++++++ techlibs/efinix/cells_map.v | 45 +++++++ techlibs/efinix/cells_sim.v | 36 ++++++ techlibs/efinix/synth_efinix.cc | 205 ++++++++++++++++++++++++++++++++ 5 files changed, 370 insertions(+) create mode 100644 techlibs/efinix/Makefile.inc create mode 100644 techlibs/efinix/arith_map.v create mode 100644 techlibs/efinix/cells_map.v create mode 100644 techlibs/efinix/cells_sim.v create mode 100644 techlibs/efinix/synth_efinix.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc new file mode 100644 index 000000000..3f3394c96 --- /dev/null +++ b/techlibs/efinix/Makefile.inc @@ -0,0 +1,6 @@ + +OBJS += techlibs/efinix/synth_efinix.o + +$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v new file mode 100644 index 000000000..ae955663c --- /dev/null +++ b/techlibs/efinix/arith_map.v @@ -0,0 +1,78 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2018 Miodrag Milanovic + * Copyright (C) 2012 Clifford Wolf + * + * 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_efinix_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; + + input [A_WIDTH-1:0] A; + input [B_WIDTH-1:0] B; + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + output CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; + + 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)); + + wire [Y_WIDTH-1:0] AA = A_buf; + wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + wire [Y_WIDTH+1:0] COx; + wire [Y_WIDTH+2:0] C = {COx, CI}; + + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cin ( + .I0(C[0]), + .I1(1'b1), + .CI(1'b0), + .CO(COx[0]) + ); + + genvar i; + generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_i ( + .I0(AA[i]), + .I1(BB[i]), + .CI(C[i+1]), + .O(Y[i]), + .CO(COx[i+1]) + ); + end: slice + endgenerate + + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cout ( + .I0(1'b0), + .I1(1'b0), + .CI(C[Y_WIDTH+1]), + .O(COx[Y_WIDTH+1]) + ); + assign CO = COx[Y_WIDTH+1]; + /* End implementation */ + assign X = AA ^ BB; +endmodule \ No newline at end of file diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v new file mode 100644 index 000000000..70c19635e --- /dev/null +++ b/techlibs/efinix/cells_map.v @@ -0,0 +1,45 @@ +module \$_DFF_N_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +module \$_DFF_P_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + +module \$_DFFE_NN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +module \$_DFFE_NP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + +module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule + +module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule + +`ifndef NO_LUT +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(1'b0), .I2(1'b0), .I3(1'b0)); + end else + if (WIDTH == 2) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(1'b0), .I3(1'b0)); + end else + if (WIDTH == 3) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(1'b0)); + end else + if (WIDTH == 4) begin + EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3])); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule +`endif diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v new file mode 100644 index 000000000..aaff955a2 --- /dev/null +++ b/techlibs/efinix/cells_sim.v @@ -0,0 +1,36 @@ +module EFX_LUT4( + output O, + input I0, + input I1, + input I2, + input I3 +); + parameter LUTMASK = 16'h0000; +endmodule + +module EFX_ADD( + output O, + output CO, + input I0, + input I1, + input CI +); + parameter I0_POLARITY = 1; + parameter I1_POLARITY = 1; +endmodule + +module EFX_FF( + output Q, + input D, + input CE, + input CLK, + input SR +); + parameter CLK_POLARITY = 1; + parameter CE_POLARITY = 1; + parameter SR_POLARITY = 1; + parameter SR_SYNC = 0; + parameter SR_VALUE = 0; + parameter SR_SYNC_PRIORITY = 0; + parameter D_POLARITY = 1; +endmodule \ No newline at end of file diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc new file mode 100644 index 000000000..9c644d363 --- /dev/null +++ b/techlibs/efinix/synth_efinix.cc @@ -0,0 +1,205 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 Miodrag Milanovic + * Copyright (C) 2019 Clifford Wolf + * + * 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 SynthEfinixPass : public ScriptPass +{ + SynthEfinixPass() : ScriptPass("synth_efinix", "synthesis for Efinix FPGAs") { } + + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_efinix [options]\n"); + log("\n"); + log("This command runs synthesis for Efinix FPGAs.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\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(" -retime\n"); + log(" run 'abc' with -dff option\n"); + log("\n"); + log("\n"); + log("The following commands are executed by this synthesis command:\n"); + help_script(); + log("\n"); + } + + string top_opt, edif_file, json_file; + bool flatten, retime; + + void clear_flags() YS_OVERRIDE + { + top_opt = "-auto-top"; + edif_file = ""; + json_file = ""; + flatten = true; + retime = false; + } + + void execute(std::vector args, RTLIL::Design *design) YS_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] == "-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] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-retime") { + retime = 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_EFINIX pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() YS_OVERRIDE + { + if (check_label("begin")) + { + run("read_verilog -lib +/efinix/cells_sim.v"); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (flatten && check_label("flatten", "(unless -noflatten)")) + { + run("proc"); + run("flatten"); + run("tribuf -logic"); + run("deminout"); + } + + if (check_label("coarse")) + { + run("synth -run coarse"); + } + + if (check_label("fine")) + { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map"); + run("opt -undriven -fine"); + run("techmap -map +/techmap.v -map +/efinix/arith_map.v"); + if (retime || help_mode) + run("abc -dff", "(only if -retime)"); + } + + if (check_label("map_ffs")) + { + run("dffsr2dff"); + run("techmap -D NO_LUT -map +/efinix/cells_map.v"); + run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); + run("opt_expr -mux_undef"); + run("simplemap"); + } + + if (check_label("map_luts")) + { + run("abc -lut 4"); + run("clean"); + } + + if (check_label("map_cells")) + { + run("techmap -map +/efinix/cells_map.v"); + run("clean"); + } + + if (check_label("check")) + { + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + } + + 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())); + } + } +} SynthEfinixPass; + +PRIVATE_NAMESPACE_END From 6e210f26fa97fa65c420534f0ec0e26eeb1b078a Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sat, 3 Aug 2019 14:40:23 +0200 Subject: [PATCH 02/32] Custom step to add global clock buffers --- techlibs/efinix/Makefile.inc | 1 + techlibs/efinix/cells_sim.v | 10 ++- techlibs/efinix/efinix_gbuf.cc | 113 ++++++++++++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 6 ++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 techlibs/efinix/efinix_gbuf.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 3f3394c96..82dfa3cd8 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,5 +1,6 @@ OBJS += techlibs/efinix/synth_efinix.o +OBJS += techlibs/efinix/efinix_gbuf.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index aaff955a2..2cbf8ae4b 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -33,4 +33,12 @@ module EFX_FF( parameter SR_VALUE = 0; parameter SR_SYNC_PRIORITY = 0; parameter D_POLARITY = 1; -endmodule \ No newline at end of file +endmodule + +module EFX_GBUFCE ( + input CE, + input I, + output O +); + parameter CE_POLARITY = 1'b1; +endmodule diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc new file mode 100644 index 000000000..50f84c30c --- /dev/null +++ b/techlibs/efinix/efinix_gbuf.cc @@ -0,0 +1,113 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 Miodrag Milanovic + * Copyright (C) 2012 Clifford Wolf + * + * 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" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +static void handle_gbufs(Module *module) +{ + SigMap sigmap(module); + + pool clk_bits; + dict rewrite_bits; + vector> pad_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\EFX_FF") { + for (auto bit : sigmap(cell->getPort("\\CLK"))) + clk_bits.insert(bit); + } + } + + for (auto wire : vector(module->wires())) + { + if (!wire->port_input) + continue; + + for (int index = 0; index < GetSize(wire); index++) + { + SigBit bit(wire, index); + SigBit canonical_bit = sigmap(bit); + + if (!clk_bits.count(canonical_bit)) + continue; + + Cell *c = module->addCell(NEW_ID, "\\EFX_GBUFCE"); + SigBit new_bit = module->addWire(NEW_ID); + c->setParam("\\CE_POLARITY", State::S1); + c->setPort("\\O", new_bit); + c->setPort("\\CE", State::S1); + pad_bits.push_back(make_pair(c, bit)); + rewrite_bits[canonical_bit] = new_bit; + + log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit)); + } + } + + auto rewrite_function = [&](SigSpec &s) { + for (auto &bit : s) { + SigBit canonical_bit = sigmap(bit); + if (rewrite_bits.count(canonical_bit)) + bit = rewrite_bits.at(canonical_bit); + } + }; + + module->rewrite_sigspecs(rewrite_function); + + for (auto &it : pad_bits) + it.first->setPort("\\I", it.second); +} + +struct EfinixGbufPass : public Pass { + EfinixGbufPass() : Pass("efinix_gbuf", "Efinix: insert global clock buffers") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" efinix_gbuf [options] [selection]\n"); + log("\n"); + log("Add Efinix global clock buffers to top module as needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing efinix_gbuf pass (insert global clock buffers).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + handle_gbufs(module); + } +} EfinixGbufPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 9c644d363..3f17bafa3 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -181,6 +181,12 @@ struct SynthEfinixPass : public ScriptPass run("clean"); } + if (check_label("map_gbuf")) + { + run("efinix_gbuf"); + run("clean"); + } + if (check_label("check")) { run("hierarchy -check"); From cf96f41c6d9c405ddc039a8d0629731924b774ed Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 4 Aug 2019 11:46:36 +0200 Subject: [PATCH 03/32] Added bram support --- techlibs/efinix/Makefile.inc | 3 + techlibs/efinix/bram.txt | 32 +++++++++ techlibs/efinix/brams_map.v | 65 +++++++++++++++++ techlibs/efinix/cells_sim.v | 65 ++++++++++++++++- techlibs/efinix/efinix_determine_init.cc | 89 ++++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 7 ++ 6 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 techlibs/efinix/bram.txt create mode 100644 techlibs/efinix/brams_map.v create mode 100644 techlibs/efinix/efinix_determine_init.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 82dfa3cd8..d0593baec 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,7 +1,10 @@ OBJS += techlibs/efinix/synth_efinix.o OBJS += techlibs/efinix/efinix_gbuf.o +OBJS += techlibs/efinix/efinix_determine_init.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) +$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) \ No newline at end of file diff --git a/techlibs/efinix/bram.txt b/techlibs/efinix/bram.txt new file mode 100644 index 000000000..0b3fd9308 --- /dev/null +++ b/techlibs/efinix/bram.txt @@ -0,0 +1,32 @@ +bram $__EFINIX_5K + init 1 + + abits 8 @a8d16 + dbits 16 @a8d16 + abits 9 @a9d8 + dbits 8 @a9d8 + abits 10 @a10d4 + dbits 4 @a10d4 + abits 11 @a11d2 + dbits 2 @a11d2 + abits 12 @a12d1 + dbits 1 @a12d1 + abits 8 @a8d20 + dbits 20 @a8d20 + abits 9 @a9d10 + dbits 10 @a9d10 + + groups 2 + ports 1 1 + wrmode 1 0 + enable 1 1 + transp 0 2 + clocks 2 3 + clkpol 2 3 +endbram + +match $__EFINIX_5K + min bits 256 + min efficiency 5 + shuffle_enable B +endmatch diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v new file mode 100644 index 000000000..9ef01d026 --- /dev/null +++ b/techlibs/efinix/brams_map.v @@ -0,0 +1,65 @@ +module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 8; + parameter CFG_DBITS = 20; + parameter CFG_ENABLE_A = 2; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [5119:0] INIT = 5119'bx; + parameter TRANSP2 = 0; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + input [CFG_DBITS-1:0] A1DATA; + input [CFG_ENABLE_A-1:0] A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + output [CFG_DBITS-1:0] B1DATA; + input B1EN; + + localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"; + + EFX_RAM_5K #( + .READ_WIDTH(20), + .WRITE_WIDTH(20), + .OUTPUT_REG(1'b0), + .RCLK_POLARITY(1'b1), + .RE_POLARITY(1'b1), + .WCLK_POLARITY(1'b1), + .WE_POLARITY(1'b1), + .WCLKE_POLARITY(1'b1), + .WRITE_MODE(WRITEMODE_A), + .INIT_0(INIT[ 0*256 +: 256]), + .INIT_1(INIT[ 1*256 +: 256]), + .INIT_2(INIT[ 2*256 +: 256]), + .INIT_3(INIT[ 3*256 +: 256]), + .INIT_4(INIT[ 4*256 +: 256]), + .INIT_5(INIT[ 5*256 +: 256]), + .INIT_6(INIT[ 6*256 +: 256]), + .INIT_7(INIT[ 7*256 +: 256]), + .INIT_8(INIT[ 8*256 +: 256]), + .INIT_9(INIT[ 9*256 +: 256]), + .INIT_A(INIT[10*256 +: 256]), + .INIT_B(INIT[11*256 +: 256]), + .INIT_C(INIT[12*256 +: 256]), + .INIT_D(INIT[13*256 +: 256]), + .INIT_E(INIT[14*256 +: 256]), + .INIT_F(INIT[15*256 +: 256]), + .INIT_10(INIT[16*256 +: 256]), + .INIT_11(INIT[17*256 +: 256]), + .INIT_12(INIT[18*256 +: 256]), + .INIT_13(INIT[19*256 +: 256]) + ) _TECHMAP_REPLACE_ ( + .WDATA(A1DATA), + .WADDR(A1ADDR), + .WE(A1EN), + .WCLK(CLK2), + .WCLKE(1'b1), + .RDATA(B1DATA), + .RADDR(B1ADDR), + .RE(B1EN), + .RCLK(CLK3) + ); +endmodule diff --git a/techlibs/efinix/cells_sim.v b/techlibs/efinix/cells_sim.v index 2cbf8ae4b..8c8f6afaa 100644 --- a/techlibs/efinix/cells_sim.v +++ b/techlibs/efinix/cells_sim.v @@ -35,10 +35,73 @@ module EFX_FF( parameter D_POLARITY = 1; endmodule -module EFX_GBUFCE ( +module EFX_GBUFCE( input CE, input I, output O ); parameter CE_POLARITY = 1'b1; endmodule + +module EFX_RAM_5K( + input [WRITE_WIDTH-1:0] WDATA, + input [WRITE_ADDR_WIDTH-1:0] WADDR, + input WE, + input WCLK, + input WCLKE, + output [READ_WIDTH-1:0] RDATA, + input [READ_ADDR_WIDTH-1:0] RADDR, + input RE, + input RCLK +); + parameter READ_WIDTH = 20; + parameter WRITE_WIDTH = 20; + parameter OUTPUT_REG = 1'b0; + parameter RCLK_POLARITY = 1'b1; + parameter RE_POLARITY = 1'b1; + parameter WCLK_POLARITY = 1'b1; + parameter WE_POLARITY = 1'b1; + parameter WCLKE_POLARITY = 1'b1; + parameter WRITE_MODE = "READ_FIRST"; + parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + localparam READ_ADDR_WIDTH = + (READ_WIDTH == 16) ? 8 : // 256x16 + (READ_WIDTH == 8) ? 9 : // 512x8 + (READ_WIDTH == 4) ? 10 : // 1024x4 + (READ_WIDTH == 2) ? 11 : // 2048x2 + (READ_WIDTH == 1) ? 12 : // 4096x1 + (READ_WIDTH == 20) ? 8 : // 256x20 + (READ_WIDTH == 10) ? 9 : // 512x10 + (READ_WIDTH == 5) ? 10 : -1; // 1024x5 + + localparam WRITE_ADDR_WIDTH = + (WRITE_WIDTH == 16) ? 8 : // 256x16 + (WRITE_WIDTH == 8) ? 9 : // 512x8 + (WRITE_WIDTH == 4) ? 10 : // 1024x4 + (WRITE_WIDTH == 2) ? 11 : // 2048x2 + (WRITE_WIDTH == 1) ? 12 : // 4096x1 + (WRITE_WIDTH == 20) ? 8 : // 256x20 + (WRITE_WIDTH == 10) ? 9 : // 512x10 + (WRITE_WIDTH == 5) ? 10 : -1; // 1024x5 + +endmodule \ No newline at end of file diff --git a/techlibs/efinix/efinix_determine_init.cc b/techlibs/efinix/efinix_determine_init.cc new file mode 100644 index 000000000..54da703ff --- /dev/null +++ b/techlibs/efinix/efinix_determine_init.cc @@ -0,0 +1,89 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2018 Icenowy Zheng + * + * 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" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct EfinixDetermineInitPass : public Pass { + EfinixDetermineInitPass() : Pass("efinix_determine_init", "Efinix: Determine the init value of cells") { } + void help() YS_OVERRIDE + { + log("\n"); + log(" efinix_determine_init [selection]\n"); + log("\n"); + log("Determine the init value of cells that doesn't allow unknown init value.\n"); + log("\n"); + } + + Const determine_init(Const init) + { + for (int i = 0; i < GetSize(init); i++) { + if (init[i] != State::S0 && init[i] != State::S1) + init[i] = State::S0; + } + + return init; + } + + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing EFINIX_DETERMINE_INIT pass (determine init value for cells).\n"); + + extra_args(args, args.size(), design); + + int cnt = 0; + for (auto module : design->selected_modules()) + { + for (auto cell : module->selected_cells()) + { + if (cell->type == "\\EFX_RAM_5K") + { + cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0"))); + cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1"))); + cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2"))); + cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3"))); + cell->setParam("\\INIT_4", determine_init(cell->getParam("\\INIT_4"))); + cell->setParam("\\INIT_5", determine_init(cell->getParam("\\INIT_5"))); + cell->setParam("\\INIT_6", determine_init(cell->getParam("\\INIT_6"))); + cell->setParam("\\INIT_7", determine_init(cell->getParam("\\INIT_7"))); + cell->setParam("\\INIT_8", determine_init(cell->getParam("\\INIT_8"))); + cell->setParam("\\INIT_9", determine_init(cell->getParam("\\INIT_9"))); + cell->setParam("\\INIT_A", determine_init(cell->getParam("\\INIT_A"))); + cell->setParam("\\INIT_B", determine_init(cell->getParam("\\INIT_B"))); + cell->setParam("\\INIT_C", determine_init(cell->getParam("\\INIT_C"))); + cell->setParam("\\INIT_D", determine_init(cell->getParam("\\INIT_D"))); + cell->setParam("\\INIT_E", determine_init(cell->getParam("\\INIT_E"))); + cell->setParam("\\INIT_F", determine_init(cell->getParam("\\INIT_F"))); + cell->setParam("\\INIT_10", determine_init(cell->getParam("\\INIT_10"))); + cell->setParam("\\INIT_11", determine_init(cell->getParam("\\INIT_11"))); + cell->setParam("\\INIT_12", determine_init(cell->getParam("\\INIT_12"))); + cell->setParam("\\INIT_13", determine_init(cell->getParam("\\INIT_13"))); + + cnt++; + } + } + } + log_header(design, "Updated %d cells with determined init value.\n", cnt); + } +} EfinixDetermineInitPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 3f17bafa3..000a17310 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -150,6 +150,13 @@ struct SynthEfinixPass : public ScriptPass run("synth -run coarse"); } + if (check_label("map_bram", "(skip if -nobram)")) + { + run("memory_bram -rules +/efinix/bram.txt"); + run("techmap -map +/efinix/brams_map.v"); + run("efinix_determine_init"); + } + if (check_label("fine")) { run("opt -fast -mux_undef -undriven -fine"); From 8a3329871ba7bab98982a101327b8375cd73344d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 4 Aug 2019 12:17:55 +0200 Subject: [PATCH 04/32] clock for ram trough gbuf --- techlibs/efinix/efinix_gbuf.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/techlibs/efinix/efinix_gbuf.cc b/techlibs/efinix/efinix_gbuf.cc index 50f84c30c..e75fb3f4d 100644 --- a/techlibs/efinix/efinix_gbuf.cc +++ b/techlibs/efinix/efinix_gbuf.cc @@ -38,6 +38,12 @@ static void handle_gbufs(Module *module) for (auto bit : sigmap(cell->getPort("\\CLK"))) clk_bits.insert(bit); } + if (cell->type == "\\EFX_RAM_5K") { + for (auto bit : sigmap(cell->getPort("\\RCLK"))) + clk_bits.insert(bit); + for (auto bit : sigmap(cell->getPort("\\WCLK"))) + clk_bits.insert(bit); + } } for (auto wire : vector(module->wires())) From d51b135e331326032b003934905c17750e116014 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 9 Aug 2019 12:37:10 +0200 Subject: [PATCH 05/32] Fix CO --- techlibs/efinix/arith_map.v | 50 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index ae955663c..ef903171f 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -31,7 +31,7 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); output [Y_WIDTH-1:0] X, Y; input CI, BI; - output CO; + output [Y_WIDTH-1:0] CO; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; @@ -41,38 +41,36 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+2:0] C = {COx, CI}; + wire [Y_WIDTH:0] C; - EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) - adder_cin ( - .I0(C[0]), + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cin ( + .I0(CI), .I1(1'b1), .CI(1'b0), - .CO(COx[0]) + .CO(C[0]) ); genvar i; generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice - EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) - adder_i ( - .I0(AA[i]), - .I1(BB[i]), - .CI(C[i+1]), - .O(Y[i]), - .CO(COx[i+1]) - ); - end: slice + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_i ( + .I0(AA[i]), + .I1(BB[i]), + .CI(C[i]), + .O(Y[i]), + .CO(C[i+1]) + ); + EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) + adder_cout ( + .I0(1'b0), + .I1(1'b0), + .CI(C[i+1]), + .O(CO[i]) + ); + end: slice endgenerate - EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) - adder_cout ( - .I0(1'b0), - .I1(1'b0), - .CI(C[Y_WIDTH+1]), - .O(COx[Y_WIDTH+1]) - ); - assign CO = COx[Y_WIDTH+1]; - /* End implementation */ - assign X = AA ^ BB; + /* End implementation */ + assign X = AA ^ BB; endmodule \ No newline at end of file From b3a91d6508943c8e5656af0a624e6ad115aec9c3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 08:37:56 +0200 Subject: [PATCH 06/32] cleanup --- techlibs/efinix/arith_map.v | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index ef903171f..56e1b039f 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -32,6 +32,9 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); input CI, BI; output [Y_WIDTH-1:0] CO; + + wire CIx; + wire [Y_WIDTH-1:0] COx; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; @@ -41,14 +44,14 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - wire [Y_WIDTH:0] C; + wire [Y_WIDTH-1:0] C = { COx, CIx }; EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) adder_cin ( .I0(CI), .I1(1'b1), .CI(1'b0), - .CO(C[0]) + .CO(CIx) ); genvar i; @@ -59,13 +62,13 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); .I1(BB[i]), .CI(C[i]), .O(Y[i]), - .CO(C[i+1]) + .CO(COx[i]) ); EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1)) adder_cout ( .I0(1'b0), .I1(1'b0), - .CI(C[i+1]), + .CI(COx[i]), .O(CO[i]) ); end: slice From 8c8100e0df51401870fba13fccf5240461f76051 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 10:17:49 +0200 Subject: [PATCH 07/32] Adding new pass to fix carry chain --- techlibs/efinix/Makefile.inc | 1 + techlibs/efinix/efinix_fixcarry.cc | 122 +++++++++++++++++++++++++++++ techlibs/efinix/synth_efinix.cc | 1 + 3 files changed, 124 insertions(+) create mode 100644 techlibs/efinix/efinix_fixcarry.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index d0593baec..47dadccdd 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -2,6 +2,7 @@ OBJS += techlibs/efinix/synth_efinix.o OBJS += techlibs/efinix/efinix_gbuf.o OBJS += techlibs/efinix/efinix_determine_init.o +OBJS += techlibs/efinix/efinix_fixcarry.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) diff --git a/techlibs/efinix/efinix_fixcarry.cc b/techlibs/efinix/efinix_fixcarry.cc new file mode 100644 index 000000000..b7cd995b8 --- /dev/null +++ b/techlibs/efinix/efinix_fixcarry.cc @@ -0,0 +1,122 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 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" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +static SigBit get_bit_or_zero(const SigSpec &sig) +{ + if (GetSize(sig) == 0) + return State::S0; + return sig[0]; +} + +static void fix_carry_chain(Module *module) +{ + SigMap sigmap(module); + + pool ci_bits; + dict mapping_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\EFX_ADD") { + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1")); + if (bit_i0 == State::S0 && bit_i1== State::S0) { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); + SigBit bit_o = sigmap(cell->getPort("\\O")); + ci_bits.insert(bit_ci); + mapping_bits[bit_ci] = bit_o; + } + } + } + + vector adders_to_fix_cells; + for (auto cell : module->cells()) + { + if (cell->type == "\\EFX_ADD") { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1")); + SigBit canonical_bit = sigmap(bit_ci); + if (!ci_bits.count(canonical_bit)) + continue; + if (bit_i0 == State::S0 && bit_i1== State::S0) + continue; + + adders_to_fix_cells.push_back(cell); + log("Found %s cell named %s with invalid CI signal.\n", log_id(cell->type), log_id(cell)); + } + } + + for (auto cell : adders_to_fix_cells) + { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI")); + SigBit canonical_bit = sigmap(bit_ci); + auto bit = mapping_bits.at(canonical_bit); + log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); + Cell *c = module->addCell(NEW_ID, "\\EFX_ADD"); + SigBit new_bit = module->addWire(NEW_ID); + c->setParam("\\I0_POLARITY", State::S1); + c->setParam("\\I1_POLARITY", State::S1); + c->setPort("\\I0", bit); + c->setPort("\\I1", State::S1); + c->setPort("\\CI", State::S0); + c->setPort("\\CO", new_bit); + + cell->setPort("\\CI", new_bit); + } +} + +struct EfinixCarryFixPass : public Pass { + EfinixCarryFixPass() : Pass("efinix_fixcarry", "Efinix: fix carry chain") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" efinix_fixcarry [options] [selection]\n"); + log("\n"); + log("Add Efinix adders to fix carry chain if needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing efinix_fixcarry pass (fix invalid carry chain).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + fix_carry_chain(module); + } +} EfinixCarryFixPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index 000a17310..d64491ca8 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -191,6 +191,7 @@ struct SynthEfinixPass : public ScriptPass if (check_label("map_gbuf")) { run("efinix_gbuf"); + run("efinix_fixcarry"); run("clean"); } From e609537e386535047f045bf0b8df7ebc5f23c469 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 10:46:48 +0200 Subject: [PATCH 08/32] Fixed data width --- techlibs/efinix/brams_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v index 9ef01d026..3236f39a5 100644 --- a/techlibs/efinix/brams_map.v +++ b/techlibs/efinix/brams_map.v @@ -22,8 +22,8 @@ module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST"; EFX_RAM_5K #( - .READ_WIDTH(20), - .WRITE_WIDTH(20), + .READ_WIDTH(CFG_DBITS), + .WRITE_WIDTH(CFG_DBITS), .OUTPUT_REG(1'b0), .RCLK_POLARITY(1'b1), .RE_POLARITY(1'b1), From 853c755a0ca67ae0a75b5cf7783e395d9f49f389 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 11:01:46 +0200 Subject: [PATCH 09/32] Replaced custom step with setundef --- techlibs/efinix/Makefile.inc | 1 - techlibs/efinix/efinix_determine_init.cc | 89 ------------------------ techlibs/efinix/synth_efinix.cc | 2 +- 3 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 techlibs/efinix/efinix_determine_init.cc diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index 47dadccdd..f1ce58276 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -1,7 +1,6 @@ OBJS += techlibs/efinix/synth_efinix.o OBJS += techlibs/efinix/efinix_gbuf.o -OBJS += techlibs/efinix/efinix_determine_init.o OBJS += techlibs/efinix/efinix_fixcarry.o $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) diff --git a/techlibs/efinix/efinix_determine_init.cc b/techlibs/efinix/efinix_determine_init.cc deleted file mode 100644 index 54da703ff..000000000 --- a/techlibs/efinix/efinix_determine_init.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2018 Icenowy Zheng - * - * 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" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct EfinixDetermineInitPass : public Pass { - EfinixDetermineInitPass() : Pass("efinix_determine_init", "Efinix: Determine the init value of cells") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" efinix_determine_init [selection]\n"); - log("\n"); - log("Determine the init value of cells that doesn't allow unknown init value.\n"); - log("\n"); - } - - Const determine_init(Const init) - { - for (int i = 0; i < GetSize(init); i++) { - if (init[i] != State::S0 && init[i] != State::S1) - init[i] = State::S0; - } - - return init; - } - - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing EFINIX_DETERMINE_INIT pass (determine init value for cells).\n"); - - extra_args(args, args.size(), design); - - int cnt = 0; - for (auto module : design->selected_modules()) - { - for (auto cell : module->selected_cells()) - { - if (cell->type == "\\EFX_RAM_5K") - { - cell->setParam("\\INIT_0", determine_init(cell->getParam("\\INIT_0"))); - cell->setParam("\\INIT_1", determine_init(cell->getParam("\\INIT_1"))); - cell->setParam("\\INIT_2", determine_init(cell->getParam("\\INIT_2"))); - cell->setParam("\\INIT_3", determine_init(cell->getParam("\\INIT_3"))); - cell->setParam("\\INIT_4", determine_init(cell->getParam("\\INIT_4"))); - cell->setParam("\\INIT_5", determine_init(cell->getParam("\\INIT_5"))); - cell->setParam("\\INIT_6", determine_init(cell->getParam("\\INIT_6"))); - cell->setParam("\\INIT_7", determine_init(cell->getParam("\\INIT_7"))); - cell->setParam("\\INIT_8", determine_init(cell->getParam("\\INIT_8"))); - cell->setParam("\\INIT_9", determine_init(cell->getParam("\\INIT_9"))); - cell->setParam("\\INIT_A", determine_init(cell->getParam("\\INIT_A"))); - cell->setParam("\\INIT_B", determine_init(cell->getParam("\\INIT_B"))); - cell->setParam("\\INIT_C", determine_init(cell->getParam("\\INIT_C"))); - cell->setParam("\\INIT_D", determine_init(cell->getParam("\\INIT_D"))); - cell->setParam("\\INIT_E", determine_init(cell->getParam("\\INIT_E"))); - cell->setParam("\\INIT_F", determine_init(cell->getParam("\\INIT_F"))); - cell->setParam("\\INIT_10", determine_init(cell->getParam("\\INIT_10"))); - cell->setParam("\\INIT_11", determine_init(cell->getParam("\\INIT_11"))); - cell->setParam("\\INIT_12", determine_init(cell->getParam("\\INIT_12"))); - cell->setParam("\\INIT_13", determine_init(cell->getParam("\\INIT_13"))); - - cnt++; - } - } - } - log_header(design, "Updated %d cells with determined init value.\n", cnt); - } -} EfinixDetermineInitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/efinix/synth_efinix.cc b/techlibs/efinix/synth_efinix.cc index d64491ca8..26a8d4eda 100644 --- a/techlibs/efinix/synth_efinix.cc +++ b/techlibs/efinix/synth_efinix.cc @@ -154,7 +154,7 @@ struct SynthEfinixPass : public ScriptPass { run("memory_bram -rules +/efinix/bram.txt"); run("techmap -map +/efinix/brams_map.v"); - run("efinix_determine_init"); + run("setundef -zero -params t:EFX_RAM_5K"); } if (check_label("fine")) From aa0c37722a99a308e64ea9581111adea2d97e46d Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 11:40:15 +0200 Subject: [PATCH 10/32] fix mixing signals on FF mapping --- techlibs/efinix/cells_map.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/techlibs/efinix/cells_map.v b/techlibs/efinix/cells_map.v index 70c19635e..0aeab1902 100644 --- a/techlibs/efinix/cells_map.v +++ b/techlibs/efinix/cells_map.v @@ -8,14 +8,14 @@ module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule module \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule `ifndef NO_LUT module \$lut (A, Y); From ead2b52b5a123e2c93578555de394a7a406e1fa5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 13:59:39 +0200 Subject: [PATCH 11/32] one bit enable signal --- techlibs/efinix/brams_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/efinix/brams_map.v b/techlibs/efinix/brams_map.v index 3236f39a5..6786ae769 100644 --- a/techlibs/efinix/brams_map.v +++ b/techlibs/efinix/brams_map.v @@ -1,7 +1,7 @@ module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); parameter CFG_ABITS = 8; parameter CFG_DBITS = 20; - parameter CFG_ENABLE_A = 2; + parameter CFG_ENABLE_A = 1; parameter CLKPOL2 = 1; parameter CLKPOL3 = 1; From 2897fe4d09118e37934b7e76f4990cc1d69a0cb5 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 11 Aug 2019 17:05:24 +0200 Subject: [PATCH 12/32] Fix formating --- techlibs/efinix/arith_map.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/techlibs/efinix/arith_map.v b/techlibs/efinix/arith_map.v index 56e1b039f..178f57bc5 100644 --- a/techlibs/efinix/arith_map.v +++ b/techlibs/efinix/arith_map.v @@ -33,8 +33,8 @@ module _80_efinix_alu (A, B, CI, BI, X, Y, CO); input CI, BI; output [Y_WIDTH-1:0] CO; - wire CIx; - wire [Y_WIDTH-1:0] COx; + wire CIx; + wire [Y_WIDTH-1:0] COx; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; From 5f561bdcb1d562d6f975b4a27beca1b8b7af908f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Mon, 12 Aug 2019 20:19:54 +0200 Subject: [PATCH 13/32] Proper arith for Anlogic and use standard pass --- techlibs/anlogic/Makefile.inc | 2 +- techlibs/anlogic/anlogic_determine_init.cc | 72 ------------ techlibs/anlogic/anlogic_fixcarry.cc | 130 +++++++++++++++++++++ techlibs/anlogic/arith_map.v | 42 ++++--- techlibs/anlogic/synth_anlogic.cc | 7 +- 5 files changed, 162 insertions(+), 91 deletions(-) delete mode 100644 techlibs/anlogic/anlogic_determine_init.cc create mode 100644 techlibs/anlogic/anlogic_fixcarry.cc diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 67cf9cf10..9426b5ca5 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -1,7 +1,7 @@ OBJS += techlibs/anlogic/synth_anlogic.o OBJS += techlibs/anlogic/anlogic_eqn.o -OBJS += techlibs/anlogic/anlogic_determine_init.o +OBJS += techlibs/anlogic/anlogic_fixcarry.o $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v)) diff --git a/techlibs/anlogic/anlogic_determine_init.cc b/techlibs/anlogic/anlogic_determine_init.cc deleted file mode 100644 index c4089dac2..000000000 --- a/techlibs/anlogic/anlogic_determine_init.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2018 Icenowy Zheng - * - * 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" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct AnlogicDetermineInitPass : public Pass { - AnlogicDetermineInitPass() : Pass("anlogic_determine_init", "Anlogic: Determine the init value of cells") { } - void help() YS_OVERRIDE - { - log("\n"); - log(" anlogic_determine_init [selection]\n"); - log("\n"); - log("Determine the init value of cells that doesn't allow unknown init value.\n"); - log("\n"); - } - - Const determine_init(Const init) - { - for (int i = 0; i < GetSize(init); i++) { - if (init[i] != State::S0 && init[i] != State::S1) - init[i] = State::S0; - } - - return init; - } - - void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE - { - log_header(design, "Executing ANLOGIC_DETERMINE_INIT pass (determine init value for cells).\n"); - - extra_args(args, args.size(), design); - - int cnt = 0; - for (auto module : design->selected_modules()) - { - for (auto cell : module->selected_cells()) - { - if (cell->type == "\\EG_LOGIC_DRAM16X4") - { - cell->setParam("\\INIT_D0", determine_init(cell->getParam("\\INIT_D0"))); - cell->setParam("\\INIT_D1", determine_init(cell->getParam("\\INIT_D1"))); - cell->setParam("\\INIT_D2", determine_init(cell->getParam("\\INIT_D2"))); - cell->setParam("\\INIT_D3", determine_init(cell->getParam("\\INIT_D3"))); - cnt++; - } - } - } - log_header(design, "Updated %d cells with determined init value.\n", cnt); - } -} AnlogicDetermineInitPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/anlogic/anlogic_fixcarry.cc b/techlibs/anlogic/anlogic_fixcarry.cc new file mode 100644 index 000000000..87164d375 --- /dev/null +++ b/techlibs/anlogic/anlogic_fixcarry.cc @@ -0,0 +1,130 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2019 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" +#include "kernel/sigtools.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +static SigBit get_bit_or_zero(const SigSpec &sig) +{ + if (GetSize(sig) == 0) + return State::S0; + return sig[0]; +} + +static void fix_carry_chain(Module *module) +{ + SigMap sigmap(module); + + pool ci_bits; + dict mapping_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\AL_MAP_ADDER") { + if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue; + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b")); + if (bit_i0 == State::S0 && bit_i1== State::S0) { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); + SigSpec o = cell->getPort("\\o"); + if (GetSize(o) == 2) { + SigBit bit_o = o[0]; + ci_bits.insert(bit_ci); + mapping_bits[bit_ci] = bit_o; + } + } + } + } + vector adders_to_fix_cells; + for (auto cell : module->cells()) + { + if (cell->type == "\\AL_MAP_ADDER") { + if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue; + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); + SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a")); + SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b")); + SigBit canonical_bit = sigmap(bit_ci); + if (!ci_bits.count(canonical_bit)) + continue; + if (bit_i0 == State::S0 && bit_i1== State::S0) + continue; + + adders_to_fix_cells.push_back(cell); + log("Found %s cell named %s with invalid 'c' signal.\n", log_id(cell->type), log_id(cell)); + } + } + + for (auto cell : adders_to_fix_cells) + { + SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c")); + SigBit canonical_bit = sigmap(bit_ci); + auto bit = mapping_bits.at(canonical_bit); + log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell)); + Cell *c = module->addCell(NEW_ID, "\\AL_MAP_ADDER"); + SigBit new_bit = module->addWire(NEW_ID); + SigBit dummy_bit = module->addWire(NEW_ID); + SigSpec bits; + bits.append(dummy_bit); + bits.append(new_bit); + c->setParam("\\ALUTYPE", Const("ADD_CARRY")); + c->setPort("\\a", bit); + c->setPort("\\b", State::S0); + c->setPort("\\c", State::S0); + c->setPort("\\o", bits); + + cell->setPort("\\c", new_bit); + } + +} + +struct AnlogicCarryFixPass : public Pass { + AnlogicCarryFixPass() : Pass("anlogic_fixcarry", "Anlogic: fix carry chain") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" anlogic_fixcarry [options] [selection]\n"); + log("\n"); + log("Add Anlogic adders to fix carry chain if needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing anlogic_fixcarry pass (fix invalid carry chain).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + fix_carry_chain(module); + } +} AnlogicCarryFixPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index 6d6a7ca37..d783b0212 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -31,7 +31,10 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); output [Y_WIDTH-1:0] X, Y; input CI, BI; - output CO; + output [Y_WIDTH-1:0] CO; + + wire CIx; + wire [Y_WIDTH-1:0] COx; wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; @@ -41,15 +44,16 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); wire [Y_WIDTH-1:0] AA = A_buf; wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; - wire [Y_WIDTH+1:0] COx; - wire [Y_WIDTH+2:0] C = {COx, CI}; + wire [Y_WIDTH-1:0] C = { COx, CIx }; wire dummy; AL_MAP_ADDER #( .ALUTYPE("ADD_CARRY")) adder_cin ( - .a(C[0]), - .o({COx[0], dummy}) + .a(CI), + .b(1'b0), + .c(1'b0), + .o({CIx, dummy}) ); genvar i; @@ -59,18 +63,22 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); ) adder_i ( .a(AA[i]), .b(BB[i]), - .c(C[i+1]), - .o({COx[i+1],Y[i]}) + .c(C[i]), + .o({COx[i],Y[i]}) ); - end: slice + + wire cout; + AL_MAP_ADDER #( + .ALUTYPE("ADD")) + adder_cout ( + .a(1'b0), + .b(1'b0), + .c(COx[i]), + .o({cout, CO[i]}) + ); + end: slice endgenerate - /* End implementation */ - AL_MAP_ADDER #( - .ALUTYPE("ADD")) - adder_cout ( - .c(C[Y_WIDTH+1]), - .o(COx[Y_WIDTH+1]) - ); - assign CO = COx[Y_WIDTH+1]; - assign X = AA ^ BB; + + /* End implementation */ + assign X = AA ^ BB; endmodule \ No newline at end of file diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 620bf3965..b87fc8566 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -154,7 +154,7 @@ struct SynthAnlogicPass : public ScriptPass { run("memory_bram -rules +/anlogic/drams.txt"); run("techmap -map +/anlogic/drams_map.v"); - run("anlogic_determine_init"); + run("setundef -zero -params t:EG_LOGIC_DRAM16X4"); } if (check_label("fine")) @@ -186,6 +186,11 @@ struct SynthAnlogicPass : public ScriptPass { run("techmap -map +/anlogic/cells_map.v"); run("clean"); + } + + if (check_label("map_anlogic")) + { + run("anlogic_fixcarry"); run("anlogic_eqn"); } From 948b6f91a140dafa4bd47177769eb4974d08f203 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Wed, 21 Aug 2019 17:00:24 +0200 Subject: [PATCH 14/32] Fix test_pmgen deps --- passes/pmgen/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc index 382a1b4ad..8e0cbdca8 100644 --- a/passes/pmgen/Makefile.inc +++ b/passes/pmgen/Makefile.inc @@ -4,7 +4,7 @@ # -------------------------------------- OBJS += passes/pmgen/test_pmgen.o -passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h +passes/pmgen/test_pmgen.o: passes/pmgen/test_pmgen_pm.h passes/pmgen/ice40_dsp_pm.h passes/pmgen/peepopt_pm.h $(eval $(call add_extra_objs,passes/pmgen/test_pmgen_pm.h)) # -------------------------------------- From a6776ee35ee5404ca7d5b63fd2daccc46354112c Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 13:36:01 -0700 Subject: [PATCH 15/32] mem2reg to preserve user attributes and src --- frontends/ast/simplify.cc | 4 ++++ tests/various/mem2reg.ys | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/various/mem2reg.ys diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 54b9efaad..8493aa513 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -150,6 +150,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->str = stringf("%s[%d]", node->str.c_str(), i); reg->is_reg = true; reg->is_signed = node->is_signed; + for (auto &it : node->attributes) + reg->attributes.emplace(it.first, it.second->clone()); + reg->filename = node->filename; + reg->linenum = node->linenum; children.push_back(reg); while (reg->simplify(true, false, false, 1, -1, false, false)) { } } diff --git a/tests/various/mem2reg.ys b/tests/various/mem2reg.ys new file mode 100644 index 000000000..00389c700 --- /dev/null +++ b/tests/various/mem2reg.ys @@ -0,0 +1,13 @@ +read_verilog < Date: Wed, 21 Aug 2019 19:18:05 -0700 Subject: [PATCH 16/32] opt_expr to trim A port of $shiftx if Y_WIDTH == 1 --- passes/opt/opt_expr.cc | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 858b3560c..b56ce252f 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -745,6 +745,23 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } + if (cell->type == ID($shiftx) && cell->getPort(ID::Y).size() == 1) { + SigSpec sig_a = assign_map(cell->getPort(ID::A)); + int width; + for (width = GetSize(sig_a); width > 1; width--) { + if (sig_a[width-1] != State::Sx) + break; + } + + if (width < GetSize(sig_a)) { + sig_a.remove(width, GetSize(sig_a)-width); + cell->setPort(ID::A, sig_a); + cell->setParam(ID(A_WIDTH), width); + did_something = true; + goto next_cell; + } + } + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); From bb1a8a019030022e8e5ad794691497c725ec86b2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 21:58:20 -0700 Subject: [PATCH 17/32] Add test --- tests/opt/opt_expr.ys | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index f0306efa1..4affc1ac8 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -221,3 +221,17 @@ check equiv_opt opt_expr -fine design -load postopt select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i + +########### + +design -reset +read_verilog -icells < Date: Thu, 22 Aug 2019 08:05:01 -0700 Subject: [PATCH 18/32] Canonical form --- passes/opt/opt_expr.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index b56ce252f..7fdfa82bd 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -369,7 +369,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons for (auto cell : module->cells()) if (design->selected(module, cell) && cell->type[0] == '$') { if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && - cell->getPort(ID::A).size() == 1 && cell->getPort(ID::Y).size() == 1) + GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::Y)) == 1) invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A)); if (cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0)) @@ -740,12 +740,12 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($reduce_xor), ID($reduce_xnor), ID($lt), ID($le), ID($ge), ID($gt))) replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::State::Sx); else - replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, cell->getPort(ID::Y).size())); + replace_cell(assign_map, module, cell, "x-bit in input", ID::Y, RTLIL::SigSpec(RTLIL::State::Sx, GetSize(cell->getPort(ID::Y)))); goto next_cell; } } - if (cell->type == ID($shiftx) && cell->getPort(ID::Y).size() == 1) { + if (cell->type == ID($shiftx) && GetSize(cell->getPort(ID::Y)) == 1) { SigSpec sig_a = assign_map(cell->getPort(ID::A)); int width; for (width = GetSize(sig_a); width > 1; width--) { @@ -762,7 +762,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && cell->getPort(ID::Y).size() == 1 && + if (cell->type.in(ID($_NOT_), ID($not), ID($logic_not)) && GetSize(cell->getPort(ID::Y)) == 1 && invert_map.count(assign_map(cell->getPort(ID::A))) != 0) { cover_list("opt.opt_expr.invert.double", "$_NOT_", "$not", "$logic_not", cell->type.str()); replace_cell(assign_map, module, cell, "double_invert", ID::Y, invert_map.at(assign_map(cell->getPort(ID::A)))); @@ -1159,7 +1159,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (mux_undef && cell->type.in(ID($mux), ID($pmux))) { RTLIL::SigSpec new_a, new_b, new_s; - int width = cell->getPort(ID::A).size(); + int width = GetSize(cell->getPort(ID::A)); if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) || cell->getPort(ID(S)).is_fully_undef()) { cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str()); From 9e31f01b343a9b246430419e81da647e75bd1626 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 08:06:24 -0700 Subject: [PATCH 19/32] Add cover() --- passes/opt/opt_expr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 7fdfa82bd..aca15e5f2 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -754,6 +754,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (width < GetSize(sig_a)) { + cover("opt.opt_expr.trim_shiftx"); sig_a.remove(width, GetSize(sig_a)-width); cell->setPort(ID::A, sig_a); cell->setParam(ID(A_WIDTH), width); From 379f33af5489850ef8e2e58ef12ff5b22da87711 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 08:22:23 -0700 Subject: [PATCH 20/32] Handle $shift and Y_WIDTH > 1 as per @cliffordwolf --- passes/opt/opt_expr.cc | 12 ++++++++---- tests/opt/opt_expr.ys | 44 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index aca15e5f2..c4da613ab 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -745,16 +745,20 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } } - if (cell->type == ID($shiftx) && GetSize(cell->getPort(ID::Y)) == 1) { + if (cell->type.in(ID($shiftx), ID($shift))) { SigSpec sig_a = assign_map(cell->getPort(ID::A)); int width; + bool trim_x = true; + bool trim_0 = cell->type == ID($shift); for (width = GetSize(sig_a); width > 1; width--) { - if (sig_a[width-1] != State::Sx) - break; + if ((trim_x && sig_a[width-1] == State::Sx) || + (trim_0 && sig_a[width-1] == State::S0)) + continue; + break; } if (width < GetSize(sig_a)) { - cover("opt.opt_expr.trim_shiftx"); + cover_list("opt.opt_expr.xbit", "$shiftx", "$shift", cell->type.str()); sig_a.remove(width, GetSize(sig_a)-width); cell->setPort(ID::A, sig_a); cell->setParam(ID(A_WIDTH), width); diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index 4affc1ac8..02be20a62 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -226,7 +226,7 @@ select -assert-count 1 t:$alu r:A_WIDTH=8 r:B_WIDTH=8 r:Y_WIDTH=9 %i %i %i design -reset read_verilog -icells < Date: Thu, 22 Aug 2019 08:37:27 -0700 Subject: [PATCH 21/32] Respect opt_expr -keepdc as per @cliffordwolf --- passes/opt/opt_expr.cc | 2 +- tests/opt/opt_expr.ys | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index c4da613ab..73f48317a 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -748,7 +748,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons if (cell->type.in(ID($shiftx), ID($shift))) { SigSpec sig_a = assign_map(cell->getPort(ID::A)); int width; - bool trim_x = true; + bool trim_x = cell->type == ID($shiftx) || !keepdc; bool trim_0 = cell->type == ID($shift); for (width = GetSize(sig_a); width > 1; width--) { if ((trim_x && sig_a[width-1] == State::Sx) || diff --git a/tests/opt/opt_expr.ys b/tests/opt/opt_expr.ys index 02be20a62..ecc2c8da8 100644 --- a/tests/opt/opt_expr.ys +++ b/tests/opt/opt_expr.ys @@ -277,3 +277,17 @@ check equiv_opt opt_expr design -load postopt select -assert-count 1 t:$shift r:A_WIDTH=10 %i + +########### + +design -reset +read_verilog -icells < Date: Thu, 22 Aug 2019 16:37:40 +0100 Subject: [PATCH 22/32] require tcl-tk in Brewfile --- Brewfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Brewfile b/Brewfile index 0c58ce161..4ffe50e86 100644 --- a/Brewfile +++ b/Brewfile @@ -6,3 +6,4 @@ brew "git" brew "graphviz" brew "pkg-config" brew "python3" +brew "tcl-tk" From 9245f0d3f564644290b6650b3f8f642789062e9e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 08:43:44 -0700 Subject: [PATCH 23/32] Copy-paste typo --- passes/opt/opt_expr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc index 73f48317a..00d7d6063 100644 --- a/passes/opt/opt_expr.cc +++ b/passes/opt/opt_expr.cc @@ -758,7 +758,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons } if (width < GetSize(sig_a)) { - cover_list("opt.opt_expr.xbit", "$shiftx", "$shift", cell->type.str()); + cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str()); sig_a.remove(width, GetSize(sig_a)-width); cell->setPort(ID::A, sig_a); cell->setParam(ID(A_WIDTH), width); From 4c449caf9bb7a855b8e61cb96f99f59141ea6ef5 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Aug 2019 18:06:36 +0200 Subject: [PATCH 24/32] Fix missing newline at end of file Signed-off-by: Clifford Wolf --- techlibs/efinix/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/efinix/Makefile.inc b/techlibs/efinix/Makefile.inc index f1ce58276..5013f7fc1 100644 --- a/techlibs/efinix/Makefile.inc +++ b/techlibs/efinix/Makefile.inc @@ -7,4 +7,4 @@ $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v)) $(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v)) -$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) \ No newline at end of file +$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt)) From 151db528e44fd12f3c31561df3bb37c12dca48ad Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Aug 2019 18:09:37 +0200 Subject: [PATCH 25/32] Fix missing newline at end of file Signed-off-by: Clifford Wolf --- techlibs/anlogic/arith_map.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/techlibs/anlogic/arith_map.v b/techlibs/anlogic/arith_map.v index d783b0212..1186543da 100644 --- a/techlibs/anlogic/arith_map.v +++ b/techlibs/anlogic/arith_map.v @@ -81,4 +81,4 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO); /* End implementation */ assign X = AA ^ BB; -endmodule \ No newline at end of file +endmodule From e9f3eb97607bc49b6bb77229f1fad9796aea1483 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 22 Aug 2019 18:43:16 +0200 Subject: [PATCH 26/32] Bump year in copyright notice Signed-off-by: Clifford Wolf --- COPYING | 2 +- README.md | 2 +- kernel/yosys.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/COPYING b/COPYING index a121cdfe9..0839088c3 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 2012 - 2018 Clifford Wolf +Copyright (C) 2012 - 2019 Clifford Wolf Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/README.md b/README.md index 56f428548..a31bd6c37 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ``` yosys -- Yosys Open SYnthesis Suite -Copyright (C) 2012 - 2018 Clifford Wolf +Copyright (C) 2012 - 2019 Clifford Wolf Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/kernel/yosys.cc b/kernel/yosys.cc index 747f2d739..5018a4888 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -129,7 +129,7 @@ void yosys_banner() log(" | |\n"); log(" | yosys -- Yosys Open SYnthesis Suite |\n"); log(" | |\n"); - log(" | Copyright (C) 2012 - 2018 Clifford Wolf |\n"); + log(" | Copyright (C) 2012 - 2019 Clifford Wolf |\n"); log(" | |\n"); log(" | Permission to use, copy, modify, and/or distribute this software for any |\n"); log(" | purpose with or without fee is hereby granted, provided that the above |\n"); From e5dac8096d92f526476f2d0b02def2298e6f5bbf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 22 Aug 2019 20:43:52 +0200 Subject: [PATCH 27/32] do not require boost if pyosys is not used --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 666223076..a742f2e50 100644 --- a/Makefile +++ b/Makefile @@ -91,8 +91,10 @@ PLUGIN_LDFLAGS += -undefined dynamic_lookup ifneq ($(shell which brew),) BREW_PREFIX := $(shell brew --prefix)/opt $(info $$BREW_PREFIX is [${BREW_PREFIX}]) +ifeq ($(ENABLE_PYOSYS),1) CXXFLAGS += -I$(BREW_PREFIX)/boost/include/boost LDFLAGS += -L$(BREW_PREFIX)/boost/lib +endif CXXFLAGS += -I$(BREW_PREFIX)/readline/include LDFLAGS += -L$(BREW_PREFIX)/readline/lib PKG_CONFIG_PATH := $(BREW_PREFIX)/libffi/lib/pkgconfig:$(PKG_CONFIG_PATH) From c50d68653d093a8daa47f589836e6178be82b54f Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 14:20:03 -0700 Subject: [PATCH 28/32] Spelling --- passes/equiv/equiv_make.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/equiv/equiv_make.cc b/passes/equiv/equiv_make.cc index dbd8682e6..4855ce29e 100644 --- a/passes/equiv/equiv_make.cc +++ b/passes/equiv/equiv_make.cc @@ -532,10 +532,10 @@ struct EquivMakePass : public Pass { log_cmd_error("Equiv module %s already exists.\n", args[argidx+2].c_str()); if (worker.gold_mod->has_memories() || worker.gold_mod->has_processes()) - log_cmd_error("Gold module contains memories or procresses. Run 'memory' or 'proc' respectively.\n"); + log_cmd_error("Gold module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); if (worker.gate_mod->has_memories() || worker.gate_mod->has_processes()) - log_cmd_error("Gate module contains memories or procresses. Run 'memory' or 'proc' respectively.\n"); + log_cmd_error("Gate module contains memories or processes. Run 'memory' or 'proc' respectively.\n"); worker.read_blacklists(); worker.read_encfiles(); From fe1b2337fd7950e1d563be5b8ccbaa81688261e4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 22 Aug 2019 16:57:59 -0700 Subject: [PATCH 29/32] Do not propagate mem2reg attribute through to result --- frontends/ast/simplify.cc | 3 ++- tests/various/mem2reg.ys | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 8493aa513..86dd80c65 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -151,7 +151,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, reg->is_reg = true; reg->is_signed = node->is_signed; for (auto &it : node->attributes) - reg->attributes.emplace(it.first, it.second->clone()); + if (it.first != ID(mem2reg)) + reg->attributes.emplace(it.first, it.second->clone()); reg->filename = node->filename; reg->linenum = node->linenum; children.push_back(reg); diff --git a/tests/various/mem2reg.ys b/tests/various/mem2reg.ys index 00389c700..85d6267c5 100644 --- a/tests/various/mem2reg.ys +++ b/tests/various/mem2reg.ys @@ -11,3 +11,4 @@ proc cd top select -assert-count 1 m:data1 a:src=< Date: Fri, 23 Aug 2019 10:37:50 +0200 Subject: [PATCH 30/32] Make macOS depenency clear --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a31bd6c37..606c4942e 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,14 @@ prerequisites for building yosys: graphviz xdot pkg-config python3 libboost-system-dev \ libboost-python-dev libboost-filesystem-dev zlib1g-dev -Similarily, on Mac OS X MacPorts or Homebrew can be used to install dependencies: +Similarily, on Mac OS X Homebrew can be used to install dependencies: $ brew tap Homebrew/bundle && brew bundle + +or MacPorts: + $ sudo port install bison flex readline gawk libffi \ - git graphviz pkgconfig python36 boost zlib + git graphviz pkgconfig python36 boost zlib tcl On FreeBSD use the following command to install all prerequisites: From a270af00cc133ac03ec97cf81ed0a7146b7b225e Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 11:21:44 -0700 Subject: [PATCH 31/32] Put abc_* attributes above port --- techlibs/ecp5/cells_sim.v | 15 ++++++++++----- techlibs/ice40/cells_sim.v | 6 ++++-- techlibs/xilinx/cells_sim.v | 21 ++++++++++++++------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 2fcb0369e..dc8334acb 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -17,10 +17,12 @@ endmodule // --------------------------------------- (* abc_box_id=1, lib_whitebox *) module CCU2C( - (* abc_carry *) input CIN, + (* abc_carry *) + input CIN, input A0, B0, C0, D0, A1, B1, C1, D1, output S0, S1, - (* abc_carry *) output COUT + (* abc_carry *) + output COUT ); parameter [15:0] INIT0 = 16'h0000; parameter [15:0] INIT1 = 16'h0000; @@ -109,9 +111,12 @@ endmodule // --------------------------------------- //(* abc_box_id=2 *) module TRELLIS_DPR16X4 ( - (* abc_scc_break *) input [3:0] DI, - (* abc_scc_break *) input [3:0] WAD, - (* abc_scc_break *) input WRE, + (* abc_scc_break *) + input [3:0] DI, + (* abc_scc_break *) + input [3:0] WAD, + (* abc_scc_break *) + input WRE, input WCK, input [3:0] RAD, output [3:0] DO diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index ab04808f4..c7f3bdad2 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -143,11 +143,13 @@ endmodule (* abc_box_id = 1, lib_whitebox *) module \$__ICE40_FULL_ADDER ( - (* abc_carry *) output CO, + (* abc_carry *) + output CO, output O, input A, input B, - (* abc_carry *) input CI + (* abc_carry *) + input CI ); SB_CARRY carry ( .I0(A), diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index bec9ea1a0..e3897d9a6 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -183,9 +183,11 @@ endmodule (* abc_box_id = 4, lib_whitebox *) module CARRY4( - (* abc_carry *) output [3:0] CO, + (* abc_carry *) + output [3:0] CO, output [3:0] O, - (* abc_carry *) input CI, + (* abc_carry *) + input CI, input CYINIT, input [3:0] DI, S ); @@ -298,9 +300,11 @@ endmodule (* abc_box_id = 5 *) module RAM32X1D ( output DPO, SPO, - (* abc_scc_break *) input D, + (* abc_scc_break *) + input D, input WCLK, - (* abc_scc_break *) input WE, + (* abc_scc_break *) + input WE, input A0, A1, A2, A3, A4, input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 ); @@ -318,7 +322,8 @@ endmodule (* abc_box_id = 6 *) module RAM64X1D ( output DPO, SPO, - (* abc_scc_break *) input D, + (* abc_scc_break *) + input D, input WCLK, (* abc_scc_break *) input WE, input A0, A1, A2, A3, A4, A5, @@ -338,9 +343,11 @@ endmodule (* abc_box_id = 7 *) module RAM128X1D ( output DPO, SPO, - (* abc_scc_break *) input D, + (* abc_scc_break *) + input D, input WCLK, - (* abc_scc_break *) input WE, + (* abc_scc_break *) + input WE, input [6:0] A, DPRA ); parameter INIT = 128'h0; From 509c353fe981c95ca667a637bf2b47477962a60b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 23 Aug 2019 11:23:50 -0700 Subject: [PATCH 32/32] Forgot one --- techlibs/xilinx/cells_sim.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index e3897d9a6..3ad96d7fb 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -325,7 +325,8 @@ module RAM64X1D ( (* abc_scc_break *) input D, input WCLK, - (* abc_scc_break *) input WE, + (* abc_scc_break *) + input WE, input A0, A1, A2, A3, A4, A5, input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 );