From cf79fd43761b6501f392ee6ad4ed0f961b93a56f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Oct 2018 15:28:57 +0100 Subject: Basic SmartFusion2 and IGLOO2 synthesis support Signed-off-by: Clifford Wolf --- techlibs/sf2/Makefile.inc | 7 ++ techlibs/sf2/arith_map.v | 21 +++++ techlibs/sf2/cells_map.v | 68 +++++++++++++++ techlibs/sf2/cells_sim.v | 75 +++++++++++++++++ techlibs/sf2/synth_sf2.cc | 206 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 377 insertions(+) create mode 100644 techlibs/sf2/Makefile.inc create mode 100644 techlibs/sf2/arith_map.v create mode 100644 techlibs/sf2/cells_map.v create mode 100644 techlibs/sf2/cells_sim.v create mode 100644 techlibs/sf2/synth_sf2.cc (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/Makefile.inc b/techlibs/sf2/Makefile.inc new file mode 100644 index 000000000..cade49f37 --- /dev/null +++ b/techlibs/sf2/Makefile.inc @@ -0,0 +1,7 @@ + +OBJS += techlibs/sf2/synth_sf2.o + +$(eval $(call add_share_file,share/sf2,techlibs/sf2/arith_map.v)) +$(eval $(call add_share_file,share/sf2,techlibs/sf2/cells_map.v)) +$(eval $(call add_share_file,share/sf2,techlibs/sf2/cells_sim.v)) + diff --git a/techlibs/sf2/arith_map.v b/techlibs/sf2/arith_map.v new file mode 100644 index 000000000..462d3ce50 --- /dev/null +++ b/techlibs/sf2/arith_map.v @@ -0,0 +1,21 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * 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. + * + */ + + +// nothing here yet diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v new file mode 100644 index 000000000..7585323a8 --- /dev/null +++ b/techlibs/sf2/cells_map.v @@ -0,0 +1,68 @@ +// module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule + +module \$_DFF_P_ (input D, C, output Q); + SLE _TECHMAP_REPLACE_ ( + .D(D), + .CLK(C), + .EN(1'b1), + .ALn(1'b1), + .ADn(1'b1), + .SLn(1'b1), + .SD(1'b0), + .LAT(1'b0), + .Q(Q) + ); +endmodule + +// module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule +// module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule +// +// module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule +// module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule +// +// module \$_DFF_NN0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule +// module \$_DFF_NN1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule +// module \$_DFF_PN0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule +// module \$_DFF_PN1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule +// +// module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule +// module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule +// module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule +// module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule +// +// module \$__DFFE_NN0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule +// module \$__DFFE_NN1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule +// module \$__DFFE_PN0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule +// module \$__DFFE_PN1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule +// +// module \$__DFFE_NP0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule +// module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule +// module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule +// module \$__DFFE_PP1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); 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 + CFG1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0])); + end else + if (WIDTH == 2) begin + CFG2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0]), .B(A[1])); + end else + if (WIDTH == 3) begin + CFG3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0]), .B(A[1]), .C(A[2])); + end else + if (WIDTH == 4) begin + CFG4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule +`endif diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v new file mode 100644 index 000000000..89b8c55fd --- /dev/null +++ b/techlibs/sf2/cells_sim.v @@ -0,0 +1,75 @@ +module SLE ( + output Q, + input ADn, + input ALn, + input CLK, + input D, + input LAT, + input SD, + input EN, + input SLn +); + reg q_latch, q_ff; + + always @(posedge CLK, negedge ALn) begin + if (!ALn) begin + q_ff <= !ADn; + end else if (EN) begin + if (!SLn) + q_ff <= SD; + else + q_ff <= D; + end + end + + always @* begin + if (!ALn) begin + q_latch <= !ADn; + end else if (CLK && EN) begin + if (!SLn) + q_ff <= SD; + else + q_ff <= D; + end + end + + assign Q = LAT ? q_latch : q_ff; +endmodule + +module CFG1 ( + output O, + input A +); + parameter [1:0] INIT = 2'h0; + assign O = INIT >> A; +endmodule + +module CFG2 ( + output O, + input A, + input B +); + parameter [3:0] INIT = 4'h0; + assign O = INIT >> {B, A}; +endmodule + +module CFG3 ( + output O, + input A, + input B, + input C +); + parameter [7:0] INIT = 8'h0; + assign O = INIT >> {C, B, A}; +endmodule + +module CFG4 ( + output O, + input A, + input B, + input C, + input D +); + parameter [15:0] INIT = 16'h0; + assign O = INIT >> {D, C, B, A}; +endmodule diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc new file mode 100644 index 000000000..2676ea657 --- /dev/null +++ b/techlibs/sf2/synth_sf2.cc @@ -0,0 +1,206 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * 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/register.h" +#include "kernel/celltypes.h" +#include "kernel/rtlil.h" +#include "kernel/log.h" + +USING_YOSYS_NAMESPACE +PRIVATE_NAMESPACE_BEGIN + +struct SynthSf2Pass : public ScriptPass +{ + SynthSf2Pass() : ScriptPass("synth_sf2", "synthesis for SmartFusion2 and IGLOO2 FPGAs") { } + + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_sf2 [options]\n"); + log("\n"); + log("This command runs synthesis for SmartFusion2 and IGLOO2 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 comannd only operates on fully selected designs!\n"); + + log_header(design, "Executing SYNTH_SF2 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 +/sf2/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 +/sf2/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 +/sf2/cells_map.v"); + run("opt_expr -mux_undef"); + run("simplemap"); + // run("sf2_ffinit"); + // run("sf2_ffssr"); + // run("sf2_opt -full"); + } + + if (check_label("map_luts")) + { + run("abc -lut 4"); + run("clean"); + } + + if (check_label("map_cells")) + { + run("techmap -map +/sf2/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())); + } + } +} SynthSf2Pass; + +PRIVATE_NAMESPACE_END -- cgit v1.2.3 From d084fb4c3f389b99c08909666d8e953017cb7656 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 31 Oct 2018 15:36:53 +0100 Subject: Fix sf2 LUT interface Signed-off-by: Clifford Wolf --- techlibs/sf2/cells_map.v | 8 ++++---- techlibs/sf2/cells_sim.v | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v index 7585323a8..5b8888294 100644 --- a/techlibs/sf2/cells_map.v +++ b/techlibs/sf2/cells_map.v @@ -50,16 +50,16 @@ module \$lut (A, Y); generate if (WIDTH == 1) begin - CFG1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0])); + CFG1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0])); end else if (WIDTH == 2) begin - CFG2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0]), .B(A[1])); + CFG2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]), .B(A[1])); end else if (WIDTH == 3) begin - CFG3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0]), .B(A[1]), .C(A[2])); + CFG3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]), .B(A[1]), .C(A[2])); end else if (WIDTH == 4) begin - CFG4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y), .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); + CFG4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.Y(Y), .A(A[0]), .B(A[1]), .C(A[2]), .D(A[3])); end else begin wire _TECHMAP_FAIL_ = 1; end diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index 89b8c55fd..b03b2c750 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -37,39 +37,39 @@ module SLE ( endmodule module CFG1 ( - output O, + output Y, input A ); parameter [1:0] INIT = 2'h0; - assign O = INIT >> A; + assign Y = INIT >> A; endmodule module CFG2 ( - output O, + output Y, input A, input B ); parameter [3:0] INIT = 4'h0; - assign O = INIT >> {B, A}; + assign Y = INIT >> {B, A}; endmodule module CFG3 ( - output O, + output Y, input A, input B, input C ); parameter [7:0] INIT = 8'h0; - assign O = INIT >> {C, B, A}; + assign Y = INIT >> {C, B, A}; endmodule module CFG4 ( - output O, + output Y, input A, input B, input C, input D ); parameter [15:0] INIT = 16'h0; - assign O = INIT >> {D, C, B, A}; + assign Y = INIT >> {D, C, B, A}; endmodule -- cgit v1.2.3 From efa278e232d20ea080743801bd91d55ec62955cf Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 7 Dec 2018 19:14:07 +0000 Subject: Fix typographical and grammatical errors and inconsistencies. The initial list of hits was generated with the codespell command below, and each hit was evaluated and fixed manually while taking context into consideration. DIRS="kernel/ frontends/ backends/ passes/ techlibs/" DIRS="${DIRS} libs/ezsat/ libs/subcircuit" codespell $DIRS -S *.o -L upto,iff,thru,synopsys,uint More hits were found by looking through comments and strings manually. --- techlibs/sf2/synth_sf2.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 2676ea657..62b3cd0e2 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -118,7 +118,7 @@ struct SynthSf2Pass : public ScriptPass extra_args(args, argidx, design); if (!design->full_selection()) - log_cmd_error("This comannd only operates on fully selected designs!\n"); + log_cmd_error("This command only operates on fully selected designs!\n"); log_header(design, "Executing SYNTH_SF2 pass.\n"); log_push(); -- cgit v1.2.3 From 841ca74c90872985ae4e128608260b4a38d04762 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jan 2019 13:33:45 +0100 Subject: Add "synth_sf2 -vlog", fix "synth_sf2 -edif" Signed-off-by: Clifford Wolf --- techlibs/sf2/synth_sf2.cc | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 62b3cd0e2..6828a4298 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -44,6 +44,10 @@ struct SynthSf2Pass : public ScriptPass 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(" -vlog \n"); + log(" write the design to the specified Verilog 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"); @@ -65,13 +69,14 @@ struct SynthSf2Pass : public ScriptPass log("\n"); } - string top_opt, edif_file, json_file; + string top_opt, edif_file, vlog_file, json_file; bool flatten, retime; void clear_flags() YS_OVERRIDE { top_opt = "-auto-top"; edif_file = ""; + vlog_file = ""; json_file = ""; flatten = true; retime = false; @@ -93,6 +98,10 @@ struct SynthSf2Pass : public ScriptPass edif_file = args[++argidx]; continue; } + if (args[argidx] == "-vlog" && argidx+1 < args.size()) { + vlog_file = args[++argidx]; + continue; + } if (args[argidx] == "-json" && argidx+1 < args.size()) { json_file = args[++argidx]; continue; @@ -192,7 +201,13 @@ struct SynthSf2Pass : public ScriptPass if (check_label("edif")) { if (!edif_file.empty() || help_mode) - run(stringf("write_edif %s", help_mode ? "" : edif_file.c_str())); + run(stringf("write_edif -gndvccy %s", help_mode ? "" : edif_file.c_str())); + } + + if (check_label("vlog")) + { + if (!vlog_file.empty() || help_mode) + run(stringf("write_verilog %s", help_mode ? "" : vlog_file.c_str())); } if (check_label("json")) -- cgit v1.2.3 From db5765b443c26b5b2dc3ac56d5a448fc8b861d43 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 17 Jan 2019 14:38:37 +0100 Subject: Add SF2 IO buffer insertion Signed-off-by: Clifford Wolf --- techlibs/sf2/Makefile.inc | 1 + techlibs/sf2/cells_sim.v | 21 ++++++++ techlibs/sf2/sf2_iobs.cc | 130 ++++++++++++++++++++++++++++++++++++++++++++++ techlibs/sf2/synth_sf2.cc | 17 +++++- 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 techlibs/sf2/sf2_iobs.cc (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/Makefile.inc b/techlibs/sf2/Makefile.inc index cade49f37..cc3054ace 100644 --- a/techlibs/sf2/Makefile.inc +++ b/techlibs/sf2/Makefile.inc @@ -1,5 +1,6 @@ OBJS += techlibs/sf2/synth_sf2.o +OBJS += techlibs/sf2/sf2_iobs.o $(eval $(call add_share_file,share/sf2,techlibs/sf2/arith_map.v)) $(eval $(call add_share_file,share/sf2,techlibs/sf2/cells_map.v)) diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index b03b2c750..f967068af 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -73,3 +73,24 @@ module CFG4 ( parameter [15:0] INIT = 16'h0; assign Y = INIT >> {D, C, B, A}; endmodule + +module CLKBUF ( + input PAD, + output Y +); + assign Y = PAD; +endmodule + +module INBUF ( + input PAD, + output Y +); + assign Y = PAD; +endmodule + +module OUTBUF ( + input D, + output PAD +); + assign PAD = D; +endmodule diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc new file mode 100644 index 000000000..27141430c --- /dev/null +++ b/techlibs/sf2/sf2_iobs.cc @@ -0,0 +1,130 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * 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 + +struct Sf2IobsPass : public Pass { + Sf2IobsPass() : Pass("sf2_iobs", "SF2: insert IO buffers") { } + void help() YS_OVERRIDE + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" sf2_iobs [options] [selection]\n"); + log("\n"); + log("Add SF2 I/O buffers to top module IOs as needed.\n"); + log("\n"); + } + void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE + { + log_header(design, "Executing sf2_iobs pass (insert IO buffers).\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + // if (args[argidx] == "-singleton") { + // singleton_mode = true; + // continue; + // } + break; + } + extra_args(args, argidx, design); + + Module *module = design->top_module(); + + if (module == nullptr) + log_cmd_error("No top module found.\n"); + + SigMap sigmap(module); + + pool clk_bits; + pool handled_io_bits; + dict rewrite_bits; + vector> pad_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\SLE") { + for (auto bit : sigmap(cell->getPort("\\CLK"))) + clk_bits.insert(bit); + } + if (cell->type.in("\\INBUF", "\\OUTBUF", "\\CLKBUF")) { + for (auto bit : sigmap(cell->getPort("\\PAD"))) + handled_io_bits.insert(bit); + } + } + + for (auto wire : vector(module->wires())) + { + if (!wire->port_input && !wire->port_output) + continue; + + for (int index = 0; index < GetSize(wire); index++) + { + SigBit bit(wire, index); + SigBit canonical_bit = sigmap(bit); + + if (handled_io_bits.count(canonical_bit)) + continue; + + if (wire->port_input && wire->port_output) + log_error("Failed to add buffer for inout port bit %s.\n", log_signal(bit)); + + IdString buf_type, buf_port; + + if (wire->port_output) { + buf_type = "\\OUTBUF"; + buf_port = "\\D"; + } else if (clk_bits.count(canonical_bit)) { + buf_type = "\\CLKBUF"; + buf_port = "\\Y"; + } else { + buf_type = "\\INBUF"; + buf_port = "\\Y"; + } + + Cell *c = module->addCell(NEW_ID, buf_type); + SigBit new_bit = module->addWire(NEW_ID); + c->setPort(buf_port, new_bit); + 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("\\PAD", it.second); + } +} Sf2IobsPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index 6828a4298..bdc20456d 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -60,6 +60,9 @@ struct SynthSf2Pass : public ScriptPass log(" -noflatten\n"); log(" do not flatten design before synthesis\n"); log("\n"); + log(" -noiobs\n"); + log(" run synthesis in \"block mode\", i.e. do not insert IO buffers\n"); + log("\n"); log(" -retime\n"); log(" run 'abc' with -dff option\n"); log("\n"); @@ -70,7 +73,7 @@ struct SynthSf2Pass : public ScriptPass } string top_opt, edif_file, vlog_file, json_file; - bool flatten, retime; + bool flatten, retime, iobs; void clear_flags() YS_OVERRIDE { @@ -80,6 +83,7 @@ struct SynthSf2Pass : public ScriptPass json_file = ""; flatten = true; retime = false; + iobs = true; } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -122,6 +126,10 @@ struct SynthSf2Pass : public ScriptPass retime = true; continue; } + if (args[argidx] == "-noiobs") { + iobs = false; + continue; + } break; } extra_args(args, argidx, design); @@ -191,6 +199,13 @@ struct SynthSf2Pass : public ScriptPass run("clean"); } + if (check_label("map_iobs")) + { + if (iobs || help_mode) + run("sf2_iobs", "(unless -noiobs)"); + run("clean"); + } + if (check_label("check")) { run("hierarchy -check"); -- cgit v1.2.3 From da5181a3df6ceed96f1762e4cdaec5cbe3ea23db Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Mar 2019 19:49:39 -0800 Subject: Improvements in SF2 flow and demo Signed-off-by: Clifford Wolf --- techlibs/sf2/sf2_iobs.cc | 15 ++++++++++----- techlibs/sf2/synth_sf2.cc | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc index 27141430c..a85552575 100644 --- a/techlibs/sf2/sf2_iobs.cc +++ b/techlibs/sf2/sf2_iobs.cc @@ -33,18 +33,23 @@ struct Sf2IobsPass : public Pass { log("\n"); log("Add SF2 I/O buffers to top module IOs as needed.\n"); log("\n"); + log(" -noclkbuf\n"); + log(" Do not insert clock buffers\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { + bool noclkbuf_mode = false; + log_header(design, "Executing sf2_iobs pass (insert IO buffers).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } + if (args[argidx] == "-noclkbuf") { + noclkbuf_mode = true; + continue; + } break; } extra_args(args, argidx, design); @@ -94,7 +99,7 @@ struct Sf2IobsPass : public Pass { if (wire->port_output) { buf_type = "\\OUTBUF"; buf_port = "\\D"; - } else if (clk_bits.count(canonical_bit)) { + } else if (clk_bits.count(canonical_bit) && !noclkbuf_mode) { buf_type = "\\CLKBUF"; buf_port = "\\Y"; } else { diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index bdc20456d..b834af07d 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -63,6 +63,9 @@ struct SynthSf2Pass : public ScriptPass log(" -noiobs\n"); log(" run synthesis in \"block mode\", i.e. do not insert IO buffers\n"); log("\n"); + log(" -noclkbuf\n"); + log(" do not inser clock buffers, only simpe IO buffers\n"); + log("\n"); log(" -retime\n"); log(" run 'abc' with -dff option\n"); log("\n"); @@ -73,7 +76,7 @@ struct SynthSf2Pass : public ScriptPass } string top_opt, edif_file, vlog_file, json_file; - bool flatten, retime, iobs; + bool flatten, retime, iobs, clkbuf; void clear_flags() YS_OVERRIDE { @@ -84,6 +87,7 @@ struct SynthSf2Pass : public ScriptPass flatten = true; retime = false; iobs = true; + clkbuf = true; } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -130,6 +134,10 @@ struct SynthSf2Pass : public ScriptPass iobs = false; continue; } + if (args[argidx] == "-noclkbuf") { + clkbuf = false; + continue; + } break; } extra_args(args, argidx, design); @@ -201,8 +209,10 @@ struct SynthSf2Pass : public ScriptPass if (check_label("map_iobs")) { - if (iobs || help_mode) - run("sf2_iobs", "(unless -noiobs)"); + if (help_mode) + run("sf2_iobs [-noclkbuf]", "(unless -noiobs)"); + else if (iobs) + run(clkbuf ? "sf2_iobs" : "sf2_iobs -noclkbuf"); run("clean"); } -- cgit v1.2.3 From 78762316aabf6d6fb55cfd4ab5b5a161a69ba203 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Mar 2019 00:41:02 -0800 Subject: Refactor SF2 iobuf insertion, Add clkint insertion Signed-off-by: Clifford Wolf --- techlibs/sf2/cells_sim.v | 7 ++ techlibs/sf2/sf2_iobs.cc | 214 ++++++++++++++++++++++++++++++---------------- techlibs/sf2/synth_sf2.cc | 14 +-- 3 files changed, 152 insertions(+), 83 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index f967068af..b49101616 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -74,6 +74,13 @@ module CFG4 ( assign Y = INIT >> {D, C, B, A}; endmodule +module CLKINT ( + input A, + output Y +); + assign Y = A; +endmodule + module CLKBUF ( input PAD, output Y diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc index a85552575..dea8e353b 100644 --- a/techlibs/sf2/sf2_iobs.cc +++ b/techlibs/sf2/sf2_iobs.cc @@ -23,6 +23,136 @@ USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN +static void handle_iobufs(Module *module, bool clkbuf_mode) +{ + SigMap sigmap(module); + + pool clk_bits; + pool handled_io_bits; + dict rewrite_bits; + vector> pad_bits; + + for (auto cell : module->cells()) + { + if (clkbuf_mode && cell->type == "\\SLE") { + for (auto bit : sigmap(cell->getPort("\\CLK"))) + clk_bits.insert(bit); + } + if (cell->type.in("\\INBUF", "\\OUTBUF", "\\TRIBUF", "\\BIBUF", "\\CLKBUF", "\\CLKBIBUF", + "\\INBUF_DIFF", "\\OUTBUF_DIFF", "\\BIBUFF_DIFF", "\\TRIBUF_DIFF", "\\CLKBUF_DIFF", + "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF")) { + for (auto bit : sigmap(cell->getPort("\\PAD"))) + handled_io_bits.insert(bit); + } + } + + for (auto wire : vector(module->wires())) + { + if (!wire->port_input && !wire->port_output) + continue; + + for (int index = 0; index < GetSize(wire); index++) + { + SigBit bit(wire, index); + SigBit canonical_bit = sigmap(bit); + + if (handled_io_bits.count(canonical_bit)) + continue; + + if (wire->port_input && wire->port_output) + log_error("Failed to add buffer for inout port bit %s.\n", log_signal(bit)); + + IdString buf_type, buf_port; + + if (wire->port_output) { + buf_type = "\\OUTBUF"; + buf_port = "\\D"; + } else if (clkbuf_mode && clk_bits.count(canonical_bit)) { + buf_type = "\\CLKBUF"; + buf_port = "\\Y"; + } else { + buf_type = "\\INBUF"; + buf_port = "\\Y"; + } + + Cell *c = module->addCell(NEW_ID, buf_type); + SigBit new_bit = module->addWire(NEW_ID); + c->setPort(buf_port, new_bit); + 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("\\PAD", it.second); +} + +static void handle_clkint(Module *module) +{ + SigMap sigmap(module); + + pool clk_bits; + vector handled_clk_bits; + + for (auto cell : module->cells()) + { + if (cell->type == "\\SLE") { + for (auto bit : sigmap(cell->getPort("\\CLK"))) + clk_bits.insert(bit); + } + if (cell->type.in("\\CLKBUF", "\\CLKBIBUF", "\\CLKBUF_DIFF", "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF", + "\\CLKINT", "\\CLKINT_PRESERVE", "\\GCLKINT", "\\RCLKINT", "\\RGCLKINT")) { + for (auto bit : sigmap(cell->getPort("\\Y"))) + handled_clk_bits.push_back(bit); + } + } + + for (auto bit : handled_clk_bits) + clk_bits.erase(bit); + + for (auto cell : vector(module->cells())) + for (auto &conn : cell->connections()) + { + if (!cell->output(conn.first)) + continue; + + SigSpec sig = conn.second; + bool did_something = false; + + for (auto &bit : sig) { + SigBit canonical_bit = sigmap(bit); + if (clk_bits.count(canonical_bit)) { + Cell *c = module->addCell(NEW_ID, "\\CLKINT"); + SigBit new_bit = module->addWire(NEW_ID); + c->setPort("\\A", new_bit); + c->setPort("\\Y", bit); + log("Added %s cell %s for clock signal %s.\n", log_id(c->type), log_id(c), log_signal(bit)); + clk_bits.erase(canonical_bit); + did_something = true; + bit = new_bit; + } + } + + if (did_something) + cell->setPort(conn.first, sig); + } + + for (auto bit : clk_bits) + log_error("Failed to insert CLKINT for clock signal %s.\n", log_signal(bit)); +} + struct Sf2IobsPass : public Pass { Sf2IobsPass() : Pass("sf2_iobs", "SF2: insert IO buffers") { } void help() YS_OVERRIDE @@ -31,23 +161,23 @@ struct Sf2IobsPass : public Pass { log("\n"); log(" sf2_iobs [options] [selection]\n"); log("\n"); - log("Add SF2 I/O buffers to top module IOs as needed.\n"); + log("Add SF2 I/O buffers and global buffers to top module as needed.\n"); log("\n"); - log(" -noclkbuf\n"); - log(" Do not insert clock buffers\n"); + log(" -clkbuf\n"); + log(" Insert PAD->global_net clock buffers\n"); log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { - bool noclkbuf_mode = false; + bool clkbuf_mode = false; log_header(design, "Executing sf2_iobs pass (insert IO buffers).\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { - if (args[argidx] == "-noclkbuf") { - noclkbuf_mode = true; + if (args[argidx] == "-clkbuf") { + clkbuf_mode = true; continue; } break; @@ -59,76 +189,8 @@ struct Sf2IobsPass : public Pass { if (module == nullptr) log_cmd_error("No top module found.\n"); - SigMap sigmap(module); - - pool clk_bits; - pool handled_io_bits; - dict rewrite_bits; - vector> pad_bits; - - for (auto cell : module->cells()) - { - if (cell->type == "\\SLE") { - for (auto bit : sigmap(cell->getPort("\\CLK"))) - clk_bits.insert(bit); - } - if (cell->type.in("\\INBUF", "\\OUTBUF", "\\CLKBUF")) { - for (auto bit : sigmap(cell->getPort("\\PAD"))) - handled_io_bits.insert(bit); - } - } - - for (auto wire : vector(module->wires())) - { - if (!wire->port_input && !wire->port_output) - continue; - - for (int index = 0; index < GetSize(wire); index++) - { - SigBit bit(wire, index); - SigBit canonical_bit = sigmap(bit); - - if (handled_io_bits.count(canonical_bit)) - continue; - - if (wire->port_input && wire->port_output) - log_error("Failed to add buffer for inout port bit %s.\n", log_signal(bit)); - - IdString buf_type, buf_port; - - if (wire->port_output) { - buf_type = "\\OUTBUF"; - buf_port = "\\D"; - } else if (clk_bits.count(canonical_bit) && !noclkbuf_mode) { - buf_type = "\\CLKBUF"; - buf_port = "\\Y"; - } else { - buf_type = "\\INBUF"; - buf_port = "\\Y"; - } - - Cell *c = module->addCell(NEW_ID, buf_type); - SigBit new_bit = module->addWire(NEW_ID); - c->setPort(buf_port, new_bit); - 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("\\PAD", it.second); + handle_iobufs(module, clkbuf_mode); + handle_clkint(module); } } Sf2IobsPass; diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc index b834af07d..0924df7a6 100644 --- a/techlibs/sf2/synth_sf2.cc +++ b/techlibs/sf2/synth_sf2.cc @@ -63,8 +63,8 @@ struct SynthSf2Pass : public ScriptPass log(" -noiobs\n"); log(" run synthesis in \"block mode\", i.e. do not insert IO buffers\n"); log("\n"); - log(" -noclkbuf\n"); - log(" do not inser clock buffers, only simpe IO buffers\n"); + log(" -clkbuf\n"); + log(" insert direct PAD->global_net buffers\n"); log("\n"); log(" -retime\n"); log(" run 'abc' with -dff option\n"); @@ -87,7 +87,7 @@ struct SynthSf2Pass : public ScriptPass flatten = true; retime = false; iobs = true; - clkbuf = true; + clkbuf = false; } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE @@ -134,8 +134,8 @@ struct SynthSf2Pass : public ScriptPass iobs = false; continue; } - if (args[argidx] == "-noclkbuf") { - clkbuf = false; + if (args[argidx] == "-clkbuf") { + clkbuf = true; continue; } break; @@ -210,9 +210,9 @@ struct SynthSf2Pass : public ScriptPass if (check_label("map_iobs")) { if (help_mode) - run("sf2_iobs [-noclkbuf]", "(unless -noiobs)"); + run("sf2_iobs [-clkbuf]", "(unless -noiobs)"); else if (iobs) - run(clkbuf ? "sf2_iobs" : "sf2_iobs -noclkbuf"); + run(clkbuf ? "sf2_iobs -clkbuf" : "sf2_iobs"); run("clean"); } -- cgit v1.2.3 From 2d2c1617ee3015368336ceb014a9cd98c60181ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Mar 2019 15:47:54 -0800 Subject: Add sf2 techmap rules for more FF types Signed-off-by: Clifford Wolf --- techlibs/sf2/cells_map.v | 64 +++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 25 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/cells_map.v b/techlibs/sf2/cells_map.v index 5b8888294..6ad7807d2 100644 --- a/techlibs/sf2/cells_map.v +++ b/techlibs/sf2/cells_map.v @@ -1,40 +1,54 @@ -// module \$_DFF_N_ (input D, C, output Q); SB_DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C)); endmodule +module \$_DFF_N_ (input D, C, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule module \$_DFF_P_ (input D, C, output Q); - SLE _TECHMAP_REPLACE_ ( - .D(D), - .CLK(C), - .EN(1'b1), - .ALn(1'b1), - .ADn(1'b1), - .SLn(1'b1), - .SD(1'b0), - .LAT(1'b0), - .Q(Q) - ); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(1'b1), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_NN0_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_NN1_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_NP0_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_NP1_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(!C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_PN0_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_PN1_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_PP0_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b1), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); +endmodule + +module \$_DFF_PP1_ (input D, C, R, output Q); + SLE _TECHMAP_REPLACE_ (.D(D), .CLK(C), .EN(1'b1), .ALn(!R), .ADn(1'b0), .SLn(1'b1), .SD(1'b0), .LAT(1'b0), .Q(Q)); endmodule // module \$_DFFE_NN_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule // module \$_DFFE_PN_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(!E)); endmodule -// +// // module \$_DFFE_NP_ (input D, C, E, output Q); SB_DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule // module \$_DFFE_PP_ (input D, C, E, output Q); SB_DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E)); endmodule -// -// module \$_DFF_NN0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule -// module \$_DFF_NN1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule -// module \$_DFF_PN0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(!R)); endmodule -// module \$_DFF_PN1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(!R)); endmodule -// -// module \$_DFF_NP0_ (input D, C, R, output Q); SB_DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule -// module \$_DFF_NP1_ (input D, C, R, output Q); SB_DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule -// module \$_DFF_PP0_ (input D, C, R, output Q); SB_DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(R)); endmodule -// module \$_DFF_PP1_ (input D, C, R, output Q); SB_DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .S(R)); endmodule -// +// // module \$__DFFE_NN0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule // module \$__DFFE_NN1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule // module \$__DFFE_PN0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(!R)); endmodule // module \$__DFFE_PN1 (input D, C, E, R, output Q); SB_DFFES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(!R)); endmodule -// +// // module \$__DFFE_NP0 (input D, C, E, R, output Q); SB_DFFNER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule // module \$__DFFE_NP1 (input D, C, E, R, output Q); SB_DFFNES _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .S(R)); endmodule // module \$__DFFE_PP0 (input D, C, E, R, output Q); SB_DFFER _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .E(E), .R(R)); endmodule -- cgit v1.2.3 From 8b0719d1e328751a50c0c07ec1fc65884fd119fc Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Mar 2019 16:18:49 -0800 Subject: Improvements in sf2 cells_sim.v Signed-off-by: Clifford Wolf --- techlibs/sf2/cells_sim.v | 277 ++++++++++++++++++++++++++++++++++++++++++----- techlibs/sf2/sf2_iobs.cc | 4 +- 2 files changed, 251 insertions(+), 30 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index b49101616..f3f7695cf 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -1,3 +1,111 @@ +module CFG1 ( + output Y, + input A +); + parameter [1:0] INIT = 2'h0; + assign Y = INIT >> A; +endmodule + +module CFG2 ( + output Y, + input A, + input B +); + parameter [3:0] INIT = 4'h0; + assign Y = INIT >> {B, A}; +endmodule + +module CFG3 ( + output Y, + input A, + input B, + input C +); + parameter [7:0] INIT = 8'h0; + assign Y = INIT >> {C, B, A}; +endmodule + +module CFG4 ( + output Y, + input A, + input B, + input C, + input D +); + parameter [15:0] INIT = 16'h0; + assign Y = INIT >> {D, C, B, A}; +endmodule + +module ADD2 ( + input A, B, + output Y +); + assign Y = A & B; +endmodule + +module ADD3 ( + input A, B, C, + output Y +); + assign Y = A & B & C; +endmodule + +module ADD4 ( + input A, B, C, D, + output Y +); + assign Y = A & B & C & D; +endmodule + +module BUFF ( + input A, + output Y +); + assign Y = A; +endmodule + +module BUFD ( + input A, + output Y +); + assign Y = A; +endmodule + +module CLKINT ( + input A, + output Y +); + assign Y = A; +endmodule + +module CLKINT_PRESERVE ( + input A, + output Y +); + assign Y = A; +endmodule + +module GCLKINT ( + input A, EN, + output Y +); + assign Y = A & EN; +endmodule + +module RCLKINT ( + input A, + output Y +); + assign Y = A; +endmodule + +module RGCLKINT ( + input A, EN, + output Y +); + assign Y = A & EN; +endmodule + module SLE ( output Q, input ADn, @@ -36,51 +144,151 @@ module SLE ( assign Q = LAT ? q_latch : q_ff; endmodule -module CFG1 ( - output Y, - input A +// module AR1 +// module FCEND_BUFF +// module FCINIT_BUFF +// module FLASH_FREEZE +// module OSCILLATOR +// module SYSRESET +// module SYSCTRL_RESET_STATUS +// module LIVE_PROBE_FB +// module GCLKBUF +// module GCLKBUF_DIFF +// module GCLKBIBUF +// module DFN1 +// module DFN1C0 +// module DFN1E1 +// module DFN1E1C0 +// module DFN1E1P0 +// module DFN1P0 +// module DLN1 +// module DLN1C0 +// module DLN1P0 + +module INV ( + input A, + output Y ); - parameter [1:0] INIT = 2'h0; - assign Y = INIT >> A; + assign Y = !A; endmodule -module CFG2 ( - output Y, +module INVD ( input A, - input B + output Y ); - parameter [3:0] INIT = 4'h0; - assign Y = INIT >> {B, A}; + assign Y = !A; endmodule -module CFG3 ( - output Y, - input A, - input B, - input C +module MX2 ( + input A, B, S, + output Y ); - parameter [7:0] INIT = 8'h0; - assign Y = INIT >> {C, B, A}; + assign Y = S ? B : A; endmodule -module CFG4 ( - output Y, - input A, - input B, - input C, - input D +module MX4 ( + input D0, D1, D2, D3, S0, S1, + output Y ); - parameter [15:0] INIT = 16'h0; - assign Y = INIT >> {D, C, B, A}; + assign Y = S1 ? (S0 ? D3 : D2) : (S0 ? D1 : D0); endmodule -module CLKINT ( - input A, +module NAND2 ( + input A, B, output Y ); - assign Y = A; + assign Y = !(A & B); +endmodule + +module NAND3 ( + input A, B, C, + output Y +); + assign Y = !(A & B & C); endmodule +module NAND4 ( + input A, B, C, D, + output Y +); + assign Y = !(A & B & C & D); +endmodule + +module NOR2 ( + input A, B, + output Y +); + assign Y = !(A | B); +endmodule + +module NOR3 ( + input A, B, C, + output Y +); + assign Y = !(A | B | C); +endmodule + +module NOR4 ( + input A, B, C, D, + output Y +); + assign Y = !(A | B | C | D); +endmodule + +module OR2 ( + input A, B, + output Y +); + assign Y = A | B; +endmodule + +module OR3 ( + input A, B, C, + output Y +); + assign Y = A | B | C; +endmodule + +module OR4 ( + input A, B, C, D, + output Y +); + assign Y = A | B | C | D; +endmodule + +module XOR2 ( + input A, B, + output Y +); + assign Y = A ^ B; +endmodule + +module XOR3 ( + input A, B, C, + output Y +); + assign Y = A ^ B ^ C; +endmodule + +module XOR4 ( + input A, B, C, D, + output Y +); + assign Y = A ^ B ^ C ^ D; +endmodule + +module XOR8 ( + input A, B, C, D, E, F, G, H, + output Y +); + assign Y = A ^ B ^ C ^ D ^ E ^ F ^ G ^ H; +endmodule + +// module UJTAG +// module BIBUF +// module BIBUF_DIFF +// module CLKBIBUF + module CLKBUF ( input PAD, output Y @@ -88,6 +296,8 @@ module CLKBUF ( assign Y = PAD; endmodule +// module CLKBUF_DIFF + module INBUF ( input PAD, output Y @@ -95,9 +305,20 @@ module INBUF ( assign Y = PAD; endmodule +// module INBUF_DIFF + module OUTBUF ( input D, output PAD ); assign PAD = D; endmodule + +// module OUTBUF_DIFF +// module TRIBUFF +// module TRIBUFF_DIFF +// module DDR_IN +// module DDR_OUT +// module RAM1K18 +// module RAM64x18 +// module MACC diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc index dea8e353b..3d43332e2 100644 --- a/techlibs/sf2/sf2_iobs.cc +++ b/techlibs/sf2/sf2_iobs.cc @@ -38,8 +38,8 @@ static void handle_iobufs(Module *module, bool clkbuf_mode) for (auto bit : sigmap(cell->getPort("\\CLK"))) clk_bits.insert(bit); } - if (cell->type.in("\\INBUF", "\\OUTBUF", "\\TRIBUF", "\\BIBUF", "\\CLKBUF", "\\CLKBIBUF", - "\\INBUF_DIFF", "\\OUTBUF_DIFF", "\\BIBUFF_DIFF", "\\TRIBUF_DIFF", "\\CLKBUF_DIFF", + if (cell->type.in("\\INBUF", "\\OUTBUF", "\\TRIBUFF", "\\BIBUF", "\\CLKBUF", "\\CLKBIBUF", + "\\INBUF_DIFF", "\\OUTBUF_DIFF", "\\BIBUFF_DIFF", "\\TRIBUFF_DIFF", "\\CLKBUF_DIFF", "\\GCLKBUF", "\\GCLKBUF_DIFF", "\\GCLKBIBUF")) { for (auto bit : sigmap(cell->getPort("\\PAD"))) handled_io_bits.insert(bit); -- cgit v1.2.3 From 350dfd3745ec2efa92a601d3bab7712fd9bec07c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Mar 2019 09:08:26 -0800 Subject: Add link to SF2 / igloo2 macro library guide Signed-off-by: Clifford Wolf --- techlibs/sf2/cells_sim.v | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'techlibs/sf2') diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v index f3f7695cf..c62748b11 100644 --- a/techlibs/sf2/cells_sim.v +++ b/techlibs/sf2/cells_sim.v @@ -1,3 +1,27 @@ +// https://coredocs.s3.amazonaws.com/Libero/12_0_0/Tool/sf2_mlg.pdf + +module ADD2 ( + + input A, B, + output Y +); + assign Y = A & B; +endmodule + +module ADD3 ( + input A, B, C, + output Y +); + assign Y = A & B & C; +endmodule + +module ADD4 ( + input A, B, C, D, + output Y +); + assign Y = A & B & C & D; +endmodule + module CFG1 ( output Y, input A @@ -36,27 +60,6 @@ module CFG4 ( assign Y = INIT >> {D, C, B, A}; endmodule -module ADD2 ( - input A, B, - output Y -); - assign Y = A & B; -endmodule - -module ADD3 ( - input A, B, C, - output Y -); - assign Y = A & B & C; -endmodule - -module ADD4 ( - input A, B, C, D, - output Y -); - assign Y = A & B & C & D; -endmodule - module BUFF ( input A, output Y -- cgit v1.2.3