From c5352f45c3604b60e0bec7a9219d2c139d276573 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 16 Sep 2015 09:28:37 +0200 Subject: [PATCH] Added GreenPAK4 skeleton --- techlibs/greenpak4/Makefile.inc | 5 + techlibs/greenpak4/cells_map.v | 38 +++++ techlibs/greenpak4/cells_sim.v | 25 +++ techlibs/greenpak4/synth_greenpak4.cc | 229 ++++++++++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 techlibs/greenpak4/Makefile.inc create mode 100644 techlibs/greenpak4/cells_map.v create mode 100644 techlibs/greenpak4/cells_sim.v create mode 100644 techlibs/greenpak4/synth_greenpak4.cc diff --git a/techlibs/greenpak4/Makefile.inc b/techlibs/greenpak4/Makefile.inc new file mode 100644 index 000000000..39e385d1b --- /dev/null +++ b/techlibs/greenpak4/Makefile.inc @@ -0,0 +1,5 @@ + +OBJS += techlibs/greenpak4/synth_greenpak4.o + +$(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_map.v)) +$(eval $(call add_share_file,share/greenpak4,techlibs/greenpak4/cells_sim.v)) diff --git a/techlibs/greenpak4/cells_map.v b/techlibs/greenpak4/cells_map.v new file mode 100644 index 000000000..976687434 --- /dev/null +++ b/techlibs/greenpak4/cells_map.v @@ -0,0 +1,38 @@ +module \$_DFF_P_ (input D, C, output Q); + DFF _TECHMAP_REPLACE_ ( + .D(D), + .Q(Q), + .CLK(C), + .nRSTZ(1'b1), + .nSETZ(1'b1) + ); +endmodule + +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(1'b0)); + end else + if (WIDTH == 2) begin + LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(A[1])); + end else + if (WIDTH == 3) begin + LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(A[1]), .IN2(A[2])); + end else + if (WIDTH == 4) begin + LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), + .IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3])); + end else begin + wire _TECHMAP_FAIL_ = 1; + end + endgenerate +endmodule diff --git a/techlibs/greenpak4/cells_sim.v b/techlibs/greenpak4/cells_sim.v new file mode 100644 index 000000000..6bcbda8e5 --- /dev/null +++ b/techlibs/greenpak4/cells_sim.v @@ -0,0 +1,25 @@ +module DFF(input D, CLK, nRSTZ, nSETZ, output reg Q); + always @(posedge CLK, negedge nRSTZ, negedge nSETZ) begin + if (!nRSTZ) + Q <= 1'b0; + else if (!nSETZ) + Q <= 1'b1; + else + Q <= D; + end +endmodule + +module LUT2(input IN0, IN1, output OUT); + parameter [3:0] INIT = 0; + assign OUT = INIT[{IN1, IN0}]; +endmodule + +module LUT3(input IN0, IN1, IN2, output OUT); + parameter [7:0] INIT = 0; + assign OUT = INIT[{IN2, IN1, IN0}]; +endmodule + +module LUT4(input IN0, IN1, IN2, IN3, output OUT); + parameter [15:0] INIT = 0; + assign OUT = INIT[{IN3, IN2, IN1, IN0}]; +endmodule diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc new file mode 100644 index 000000000..ce1b7604a --- /dev/null +++ b/techlibs/greenpak4/synth_greenpak4.cc @@ -0,0 +1,229 @@ +/* + * 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 + +bool check_label(bool &active, std::string run_from, std::string run_to, std::string label) +{ + if (label == run_from) + active = true; + if (label == run_to) + active = false; + return active; +} + +struct SynthIce40Pass : public Pass { + SynthIce40Pass() : Pass("synth_greenpak4", "synthesis for GreenPAK4 FPGAs") { } + virtual void help() + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log(" synth_greenpak4 [options]\n"); + log("\n"); + log("This command runs synthesis for GreenPAK4 FPGAs. This work is experimental.\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module (default='top')\n"); + log("\n"); + log(" -blif \n"); + log(" write the design to the specified BLIF file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -edif \n"); + log(" write the design to the specified edif file. writing of an output file\n"); + log(" is omitted if this parameter is not specified.\n"); + log("\n"); + log(" -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"); + log("\n"); + log(" begin:\n"); + log(" read_verilog -lib +/greenpak4/cells_sim.v\n"); + log(" hierarchy -check -top \n"); + log("\n"); + log(" flatten: (unless -noflatten)\n"); + log(" proc\n"); + log(" flatten\n"); + log(" tribuf -logic\n"); + log("\n"); + log(" coarse:\n"); + log(" synth -run coarse\n"); + log("\n"); + log(" fine:\n"); + log(" opt -fast -mux_undef -undriven -fine\n"); + log(" memory_map\n"); + log(" opt -undriven -fine\n"); + log(" techmap\n"); + log(" abc -dff (only if -retime)\n"); + log("\n"); + log(" map_luts:\n"); + log(" abc -lut 4\n"); + log(" clean\n"); + log("\n"); + log(" map_cells:\n"); + log(" techmap -map +/greenpak4/cells_map.v\n"); + log(" clean\n"); + log("\n"); + log(" check:\n"); + log(" hierarchy -check\n"); + log(" stat\n"); + log(" check -noinit\n"); + log("\n"); + log(" blif:\n"); + log(" write_blif -gates -attr -param \n"); + log("\n"); + log(" edif:\n"); + log(" write_edif \n"); + log("\n"); + } + virtual void execute(std::vector args, RTLIL::Design *design) + { + std::string top_opt = "-auto-top"; + std::string run_from, run_to; + std::string blif_file, edif_file; + bool flatten = true; + bool retime = false; + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-run" && argidx+1 < args.size()) { + size_t pos = args[argidx+1].find(':'); + if (pos == std::string::npos) + break; + run_from = args[++argidx].substr(0, pos); + run_to = args[argidx].substr(pos+1); + continue; + } + if (args[argidx] == "-flatten") { + flatten = true; + continue; + } + if (args[argidx] == "-noflatten") { + flatten = false; + continue; + } + if (args[argidx] == "-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"); + + bool active = run_from.empty(); + + log_header("Executing SYNTH_GREENPAK4 pass.\n"); + log_push(); + + if (check_label(active, run_from, run_to, "begin")) + { + Pass::call(design, "read_verilog -lib +/greenpak4/cells_sim.v"); + Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str())); + } + + if (flatten && check_label(active, run_from, run_to, "flatten")) + { + Pass::call(design, "proc"); + Pass::call(design, "flatten"); + Pass::call(design, "tribuf -logic"); + } + + if (check_label(active, run_from, run_to, "coarse")) + { + Pass::call(design, "synth -run coarse"); + } + + if (check_label(active, run_from, run_to, "fine")) + { + Pass::call(design, "opt -fast -mux_undef -undriven -fine"); + Pass::call(design, "memory_map"); + Pass::call(design, "opt -undriven -fine"); + Pass::call(design, "techmap"); + if (retime) + Pass::call(design, "abc -dff"); + } + + if (check_label(active, run_from, run_to, "map_luts")) + { + Pass::call(design, "abc -lut 4"); + Pass::call(design, "clean"); + } + + if (check_label(active, run_from, run_to, "map_cells")) + { + Pass::call(design, "techmap -map +/greenpak4/cells_map.v"); + Pass::call(design, "clean"); + } + + if (check_label(active, run_from, run_to, "check")) + { + Pass::call(design, "hierarchy -check"); + Pass::call(design, "stat"); + Pass::call(design, "check -noinit"); + } + + if (check_label(active, run_from, run_to, "blif")) + { + if (!blif_file.empty()) + Pass::call(design, stringf("write_blif -gates -attr -param %s", blif_file.c_str())); + } + + if (check_label(active, run_from, run_to, "edif")) + { + if (!edif_file.empty()) + Pass::call(design, stringf("write_edif %s", edif_file.c_str())); + } + + log_pop(); + } +} SynthIce40Pass; + +PRIVATE_NAMESPACE_END