From 435918347fe5315f985a71ccd920084d701a8076 Mon Sep 17 00:00:00 2001 From: Lalit Narain Sharma <61820431+lnsharma@users.noreply.github.com> Date: Fri, 26 Feb 2021 15:36:19 +0530 Subject: [PATCH 1/5] Adding qlf_k4n8 device support to yosys --- techlibs/quicklogic/Makefile.inc | 8 + techlibs/quicklogic/cells_sim.v | 24 ++ techlibs/quicklogic/qlf_k4n8_arith_map.v | 135 ++++++++++++ techlibs/quicklogic/qlf_k4n8_cells_sim.v | 70 ++++++ techlibs/quicklogic/qlf_k4n8_lut_map.v | 30 +++ techlibs/quicklogic/synth_quicklogic.cc | 266 +++++++++++++++++++++++ tests/arch/quicklogic/dffs.ys | 27 +++ tests/arch/quicklogic/iob_no_flatten.ys | 6 + tests/arch/quicklogic/latches.ys | 18 ++ tests/arch/quicklogic/logic.ys | 9 + tests/arch/quicklogic/run-test.sh | 20 ++ tests/arch/quicklogic/soft_adder.ys | 13 ++ tests/arch/quicklogic/v/add.v | 10 + tests/arch/quicklogic/v/dffs.v | 24 ++ tests/arch/quicklogic/v/iob_no_flatten.v | 28 +++ tests/arch/quicklogic/v/latches.v | 22 ++ tests/arch/quicklogic/v/logic.v | 16 ++ tests/arch/quicklogic/v/sub.v | 10 + 18 files changed, 736 insertions(+) create mode 100644 techlibs/quicklogic/Makefile.inc create mode 100644 techlibs/quicklogic/cells_sim.v create mode 100644 techlibs/quicklogic/qlf_k4n8_arith_map.v create mode 100644 techlibs/quicklogic/qlf_k4n8_cells_sim.v create mode 100644 techlibs/quicklogic/qlf_k4n8_lut_map.v create mode 100644 techlibs/quicklogic/synth_quicklogic.cc create mode 100644 tests/arch/quicklogic/dffs.ys create mode 100644 tests/arch/quicklogic/iob_no_flatten.ys create mode 100644 tests/arch/quicklogic/latches.ys create mode 100644 tests/arch/quicklogic/logic.ys create mode 100755 tests/arch/quicklogic/run-test.sh create mode 100644 tests/arch/quicklogic/soft_adder.ys create mode 100644 tests/arch/quicklogic/v/add.v create mode 100644 tests/arch/quicklogic/v/dffs.v create mode 100644 tests/arch/quicklogic/v/iob_no_flatten.v create mode 100644 tests/arch/quicklogic/v/latches.v create mode 100644 tests/arch/quicklogic/v/logic.v create mode 100644 tests/arch/quicklogic/v/sub.v diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc new file mode 100644 index 00000000000..f7e9633e3a9 --- /dev/null +++ b/techlibs/quicklogic/Makefile.inc @@ -0,0 +1,8 @@ + +OBJS += techlibs/quicklogic/synth_quicklogic.o + +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_lut_map.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_cells_sim.v)) +$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_arith_map.v)) + diff --git a/techlibs/quicklogic/cells_sim.v b/techlibs/quicklogic/cells_sim.v new file mode 100644 index 00000000000..4c17762ebed --- /dev/null +++ b/techlibs/quicklogic/cells_sim.v @@ -0,0 +1,24 @@ + +module inv(output Q, input A); + assign Q = A ? 0 : 1; +endmodule + +module buff(output Q, input A); + assign Q = A; +endmodule + +module logic_0(output a); + assign a = 0; +endmodule + +module logic_1(output a); + assign a = 1; +endmodule + +(* blackbox *) +module gclkbuff (input A, output Z); + +assign Z = A; + +endmodule + diff --git a/techlibs/quicklogic/qlf_k4n8_arith_map.v b/techlibs/quicklogic/qlf_k4n8_arith_map.v new file mode 100644 index 00000000000..5cbfdc7918a --- /dev/null +++ b/techlibs/quicklogic/qlf_k4n8_arith_map.v @@ -0,0 +1,135 @@ +(* techmap_celltype = "$alu" *) +module _80_quicklogic_alu (A, B, CI, BI, X, Y, CO); + parameter A_SIGNED = 0; + parameter B_SIGNED = 0; + parameter A_WIDTH = 1; + parameter B_WIDTH = 1; + parameter Y_WIDTH = 1; + + parameter _TECHMAP_CONSTMSK_CI_ = 0; + parameter _TECHMAP_CONSTVAL_CI_ = 0; + + (* force_downto *) + input [A_WIDTH-1:0] A; + (* force_downto *) + input [B_WIDTH-1:0] B; + (* force_downto *) + output [Y_WIDTH-1:0] X, Y; + + input CI, BI; + (* force_downto *) + output [Y_WIDTH-1:0] CO; + + wire _TECHMAP_FAIL_ = Y_WIDTH <= 2; + + (* force_downto *) + wire [Y_WIDTH-1:0] A_buf, B_buf; + \$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf)); + \$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf)); + + (* force_downto *) + wire [Y_WIDTH-1:0] AA = A_buf; + (* force_downto *) + wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf; + (* force_downto *) + wire [Y_WIDTH-1:0] C; + + assign CO = C[Y_WIDTH-1]; + + genvar i; + generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice + + wire ci; + wire co; + + // First in chain + generate if (i == 0) begin + + // CI connected to a constant + if (_TECHMAP_CONSTMSK_CI_ == 1) begin + + localparam INIT = (_TECHMAP_CONSTVAL_CI_ == 0) ? + 16'b0110_0000_0000_0001 : + 16'b1001_0000_0000_0111; + + // LUT4 configured as 1-bit adder with CI=const + adder_lut4 #( + .LUT(INIT), + .IN2_IS_CIN(1'b0) + ) lut_ci_adder ( + .in({AA[i], BB[i], 1'b0, 1'b0}), + .cin(), + .lut4_out(Y[i]), + .cout(ci) + ); + + // CI connected to a non-const driver + end else begin + + // LUT4 configured as passthrough to drive CI of the next stage + adder_lut4 #( + .LUT(16'b1100_0000_0000_0011), + .IN2_IS_CIN(1'b0) + ) lut_ci ( + .in({1'b0,CI,1'b0,1'b0}), + .cin(), + .lut4_out(), + .cout(ci) + ); + end + + // Not first in chain + end else begin + assign ci = C[i-1]; + + end endgenerate + + // .................................................... + + // Single 1-bit adder, mid-chain adder or non-const CI + // adder + generate if ((i == 0 && _TECHMAP_CONSTMSK_CI_ == 0) || (i > 0)) begin + + // LUT4 configured as full 1-bit adder + adder_lut4 #( + .LUT(16'b0110_1001_0110_0001), + .IN2_IS_CIN(1'b1) + ) lut_adder ( + .in({AA[i], BB[i], 1'b0, 1'b0}), + .cin(ci), + .lut4_out(Y[i]), + .cout(co) + ); + end else begin + assign co = ci; + + end endgenerate + + // .................................................... + + // Last in chain + generate if (i == Y_WIDTH-1) begin + + // LUT4 configured for passing its CI input to output. This should + // get pruned if the actual CO port is not connected anywhere. + adder_lut4 #( + .LUT(16'b0000_1111_0000_1111), + .IN2_IS_CIN(1'b1) + ) lut_co ( + .in({1'b0, co, 1'b0, 1'b0}), + .cin(co), + .lut4_out(C[i]), + .cout() + ); + // Not last in chain + end else begin + assign C[i] = co; + + end endgenerate + + end: slice + endgenerate + + /* End implementation */ + assign X = AA ^ BB; +endmodule diff --git a/techlibs/quicklogic/qlf_k4n8_cells_sim.v b/techlibs/quicklogic/qlf_k4n8_cells_sim.v new file mode 100644 index 00000000000..a66a88d674a --- /dev/null +++ b/techlibs/quicklogic/qlf_k4n8_cells_sim.v @@ -0,0 +1,70 @@ +(* abc9_box, lib_whitebox *) +module adder_lut4( + output lut4_out, + (* abc9_carry *) + output cout, + input [0:3] in, + (* abc9_carry *) + input cin +); + parameter [0:15] LUT=0; + parameter IN2_IS_CIN = 0; + + wire [0:3] li = (IN2_IS_CIN) ? {in[0], in[1], cin, in[3]} : {in[0], in[1], in[2], in[3]}; + + // Output function + wire [0:7] s1 = li[0] ? + {LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]}: + {LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]}; + + wire [0:3] s2 = li[1] ? {s1[1], s1[3], s1[5], s1[7]} : + {s1[0], s1[2], s1[4], s1[6]}; + + wire [0:1] s3 = li[2] ? {s2[1], s2[3]} : {s2[0], s2[2]}; + + assign lut4_out = li[3] ? s3[1] : s3[0]; + + // Carry out function + assign cout = (s2[2]) ? cin : s2[3]; +endmodule + +(* abc9_lut=1, lib_whitebox *) +module frac_lut4( + input [0:3] in, + output [0:1] lut2_out, + output lut4_out +); + parameter [0:15] LUT = 0; + + // Effective LUT input + wire [0:3] li = in; + + // Output function + wire [0:7] s1 = li[0] ? + {LUT[1], LUT[3], LUT[5], LUT[7], LUT[9], LUT[11], LUT[13], LUT[15]}: + {LUT[0], LUT[2], LUT[4], LUT[6], LUT[8], LUT[10], LUT[12], LUT[14]}; + + wire [0:3] s2 = li[1] ? {s1[1], s1[3], s1[5], s1[7]} : + {s1[0], s1[2], s1[4], s1[6]}; + + wire [0:1] s3 = li[2] ? {s2[1], s2[3]} : {s2[0], s2[2]}; + + assign lut2_out[0] = s2[2]; + assign lut2_out[1] = s2[3]; + + assign lut4_out = li[3] ? s3[1] : s3[0]; + +endmodule + +(* abc9_flop, lib_whitebox *) +module scff( + output reg Q, + input D, + input clk +); + parameter [0:0] INIT = 1'b0; + initial Q = INIT; + + always @(posedge clk) + Q <= D; +endmodule diff --git a/techlibs/quicklogic/qlf_k4n8_lut_map.v b/techlibs/quicklogic/qlf_k4n8_lut_map.v new file mode 100644 index 00000000000..3eb524793d1 --- /dev/null +++ b/techlibs/quicklogic/qlf_k4n8_lut_map.v @@ -0,0 +1,30 @@ +`ifndef NO_LUT +module \$lut (A, Y); + parameter WIDTH = 0; + parameter LUT = 0; + + (* force_downto *) + input [WIDTH-1:0] A; + output Y; + + generate + if (WIDTH == 1) begin + localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; + LUT4 #(.EQN(""),.INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y),.I0(1'b0), .I1(1'b0), .I2(1'b0), .I3(A[0])); + end else + if (WIDTH == 2) begin + localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; + LUT4 #(.EQN(""),.INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y),.I0(1'b0), .I1(1'b0), .I2(A[0]), .I3(A[1])); + end else + if (WIDTH == 3) begin + localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; + LUT4 #(.EQN(""),.INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y),.I0(1'b0), .I1(A[0]), .I2(A[1]), .I3(A[2])); + end else + if (WIDTH == 4) begin + LUT4 #(.EQN(""),.INIT(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 \ No newline at end of file diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc new file mode 100644 index 00000000000..1f1b78eb747 --- /dev/null +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -0,0 +1,266 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * Copyright (C) 2021 Lalit Sharma + * + * 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 SynthQuickLogicPass : public ScriptPass { + + SynthQuickLogicPass() : ScriptPass("synth_quicklogic", "Synthesis for QuickLogic FPGAs") {} + + void help() override + { + log("\n"); + log(" synth_quicklogic [options]\n"); + log("This command runs synthesis for QuickLogic FPGAs\n"); + log("\n"); + log(" -top \n"); + log(" use the specified module as top module\n"); + log("\n"); + log(" -family \n"); + log(" run synthesis for the specified QuickLogic architecture\n"); + log(" generate the synthesis netlist for the specified family.\n"); + log(" supported values:\n"); + log(" - qlf_k4n8: qlf_k4n8 \n"); + log("\n"); + log(" -no_abc_opt\n"); + log(" By default most of ABC logic optimization features is\n"); + log(" enabled. Specifying this switch turns them off.\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(" -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(" -verilog \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(" -no_adder\n"); + log(" By default use adder cells in output netlist.\n"); + log(" Specifying this switch turns it off.\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, blif_file, family, currmodule, verilog_file; + bool inferAdder; + bool abcOpt; + + void clear_flags() override + { + top_opt = "-auto-top"; + edif_file = ""; + blif_file = ""; + verilog_file = ""; + currmodule = ""; + family = "qlf_k4n8"; + inferAdder = true; + abcOpt = true; + } + + void execute(std::vector args, RTLIL::Design *design) override + { + string run_from, run_to; + clear_flags(); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) + { + if (args[argidx] == "-top" && argidx+1 < args.size()) { + top_opt = "-top " + args[++argidx]; + continue; + } + if (args[argidx] == "-edif" && argidx+1 < args.size()) { + edif_file = args[++argidx]; + continue; + } + + if (args[argidx] == "-family" && argidx+1 < args.size()) { + family = args[++argidx]; + continue; + } + if (args[argidx] == "-blif" && argidx+1 < args.size()) { + blif_file = args[++argidx]; + continue; + } + if (args[argidx] == "-verilog" && argidx+1 < args.size()) { + verilog_file = args[++argidx]; + continue; + } + if (args[argidx] == "-no_adder") { + inferAdder = false; + continue; + } + if (args[argidx] == "-no_abc_opt") { + abcOpt = false; + 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_QUICKLOGIC pass.\n"); + log_push(); + + run_script(design, run_from, run_to); + + log_pop(); + } + + void script() override + { + if (check_label("begin")) { + std::string readVelArgs; + readVelArgs = " +/quicklogic/" + family + "_cells_sim.v"; + + run("read_verilog -lib -specify +/quicklogic/cells_sim.v" + readVelArgs); + run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt.c_str())); + } + + if (check_label("prepare")) { + run("proc"); + run("flatten"); + run("opt_expr"); + run("opt_clean"); + run("deminout"); + run("opt"); + } + + if (check_label("coarse")) { + run("opt_expr"); + run("opt_clean"); + run("check"); + run("opt"); + run("wreduce -keepdc"); + run("peepopt"); + run("pmuxtree"); + run("opt_clean"); + + run("alumacc"); + run("opt"); + run("fsm"); + run("opt -fast"); + run("memory -nomap"); + run("opt_clean"); + } + + if (check_label("map_ffram")) { + run("opt -fast -mux_undef -undriven -fine"); + run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block " + "-attr syn_ramstyle=auto -attr syn_ramstyle=registers " + "-attr syn_romstyle=auto -attr syn_romstyle=logic"); + run("opt -undriven -fine"); + } + + if (check_label("map_gates")) { + if(family == "qlf_k4n8") { + run("async2sync"); + } + if (inferAdder) { + run("techmap -map +/techmap.v -map +/quicklogic/" + family + "_arith_map.v"); + } else { + run("techmap"); + } + run("opt -fast"); + + run("opt -fast"); + run("opt_expr"); + run("opt_merge"); + run("opt_clean"); + run("opt"); + } + + if (check_label("map_ffs")) { + + run("opt_expr -mux_undef"); + run("simplemap"); + run("opt_expr"); + run("opt_merge"); + run("opt_clean"); + run("opt"); + } + + if (check_label("map_luts")) { + run("abc -lut 4 "); + run("clean"); + run("opt_lut"); + } + + if (check_label("map_cells")) { + + std::string techMapArgs; + techMapArgs += " -D NO_LUT -map +/quicklogic/" + family + "_lut_map.v"; + + run("techmap" + techMapArgs); + run("clean"); + } + + if (check_label("check")) { + run("autoname"); + run("hierarchy -check"); + run("stat"); + run("check -noinit"); + } + + if (check_label("finalize")) { + run("check"); + } + + if (check_label("edif")) { + if (!edif_file.empty() || help_mode) + run(stringf("write_edif -nogndvcc -attrprop -pvector par %s %s", this->currmodule.c_str(), edif_file.c_str())); + } + + if (check_label("blif")) { + if (!blif_file.empty() || help_mode) { + run(stringf("opt_clean -purge"), + " (qlf_k4n8 mode)"); + if (inferAdder) { + run(stringf("write_blif -param %s", help_mode ? "" : blif_file.c_str())); + } else { + run(stringf("write_blif %s", help_mode ? "" : blif_file.c_str())); + } + } + } + + if (check_label("verilog")) { + if (!verilog_file.empty()) { + run("write_verilog -noattr -nohex " + verilog_file); + } + } + } + +} SynthQuicklogicPass; + +PRIVATE_NAMESPACE_END diff --git a/tests/arch/quicklogic/dffs.ys b/tests/arch/quicklogic/dffs.ys new file mode 100644 index 00000000000..62720194855 --- /dev/null +++ b/tests/arch/quicklogic/dffs.ys @@ -0,0 +1,27 @@ +read_verilog v/dffs.v +design -save read + +# DFF +hierarchy -top my_dff +proc +equiv_opt -assert -map +/quicklogic/qlf_k4n8_cells_sim.v synth_quicklogic -top my_dff +design -load postopt +cd my_dff +stat +select -assert-count 1 t:*_DFF_P_ + +# DFFC +design -load read +synth_quicklogic -top my_dffc +cd my_dffc +stat +select -assert-count 1 t:*DFF_P* +select -assert-count 1 t:$lut + +# DFFP +design -load read +synth_quicklogic -top my_dffp +cd my_dffp +stat +select -assert-count 1 t:*DFF_P* +select -assert-count 1 t:$lut diff --git a/tests/arch/quicklogic/iob_no_flatten.ys b/tests/arch/quicklogic/iob_no_flatten.ys new file mode 100644 index 00000000000..4530a8d72ea --- /dev/null +++ b/tests/arch/quicklogic/iob_no_flatten.ys @@ -0,0 +1,6 @@ +read_verilog v/iob_no_flatten.v + +synth_quicklogic -top my_top +stat +cd my_top +select -assert-count 2 t:$_DFF_P_ diff --git a/tests/arch/quicklogic/latches.ys b/tests/arch/quicklogic/latches.ys new file mode 100644 index 00000000000..6afe6670f0a --- /dev/null +++ b/tests/arch/quicklogic/latches.ys @@ -0,0 +1,18 @@ +read_verilog v/latches.v +design -save read + +# LATCHP +synth_quicklogic -top latchp +cd latchp +stat +select -assert-count 1 t:$lut +select -assert-count 1 t:$*_FF_* + +# LATCHN +design -load read +synth_quicklogic -top latchn +cd latchn +stat +select -assert-count 1 t:$lut +select -assert-count 1 t:$*_FF_* + diff --git a/tests/arch/quicklogic/logic.ys b/tests/arch/quicklogic/logic.ys new file mode 100644 index 00000000000..c6534d2e175 --- /dev/null +++ b/tests/arch/quicklogic/logic.ys @@ -0,0 +1,9 @@ +read_verilog v/logic.v +hierarchy -top top +proc +equiv_opt -assert -map +/quicklogic/qlf_k4n8_cells_sim.v synth_quicklogic +design -load postopt +cd top + +stat +select -assert-count 9 t:$lut diff --git a/tests/arch/quicklogic/run-test.sh b/tests/arch/quicklogic/run-test.sh new file mode 100755 index 00000000000..bf19b887d99 --- /dev/null +++ b/tests/arch/quicklogic/run-test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e +{ +echo "all::" +for x in *.ys; do + echo "all:: run-$x" + echo "run-$x:" + echo " @echo 'Running $x..'" + echo " @../../../yosys -ql ${x%.ys}.log -w 'Yosys has only limited support for tri-state logic at the moment.' $x" +done +for s in *.sh; do + if [ "$s" != "run-test.sh" ]; then + echo "all:: run-$s" + echo "run-$s:" + echo " @echo 'Running $s..'" + echo " @bash $s" + fi +done +} > run-test.mk +exec ${MAKE:-make} -f run-test.mk diff --git a/tests/arch/quicklogic/soft_adder.ys b/tests/arch/quicklogic/soft_adder.ys new file mode 100644 index 00000000000..5590208ae36 --- /dev/null +++ b/tests/arch/quicklogic/soft_adder.ys @@ -0,0 +1,13 @@ +# Equivalence check for adder synthesis +read_verilog -icells -DWIDTH=4 v/add.v +hierarchy -check -auto-top +proc +equiv_opt -assert -map +/quicklogic/qlf_k4n8_cells_sim.v synth_quicklogic -family qlf_k4n8 + +design -reset + +# Equivalence check for subtractor synthesis +read_verilog -icells -DWIDTH=4 v/sub.v +hierarchy -check -auto-top +proc +equiv_opt -assert -map +/quicklogic/qlf_k4n8_cells_sim.v synth_quicklogic -family qlf_k4n8 diff --git a/tests/arch/quicklogic/v/add.v b/tests/arch/quicklogic/v/add.v new file mode 100644 index 00000000000..e34268692b5 --- /dev/null +++ b/tests/arch/quicklogic/v/add.v @@ -0,0 +1,10 @@ +module adder ( + input wire [`WIDTH-1:0] A, + input wire [`WIDTH-1:0] B, + output wire [`WIDTH :0] S, +); + + // Implicit adder + assign S = A + B; + +endmodule diff --git a/tests/arch/quicklogic/v/dffs.v b/tests/arch/quicklogic/v/dffs.v new file mode 100644 index 00000000000..32f02b63e51 --- /dev/null +++ b/tests/arch/quicklogic/v/dffs.v @@ -0,0 +1,24 @@ +module my_dff ( input d, clk, output reg q ); + initial q <= 1'b0; + always @( posedge clk ) + q <= d; +endmodule + +module my_dffc ( input d, clk, clr, output reg q ); + initial q <= 1'b0; + always @( posedge clk or posedge clr ) + if ( clr ) + q <= 1'b0; + else + q <= d; +endmodule + +module my_dffp ( input d, clk, pre, output reg q ); + initial q <= 1'b0; + always @( posedge clk or posedge pre ) + if ( pre ) + q <= 1'b1; + else + q <= d; +endmodule + diff --git a/tests/arch/quicklogic/v/iob_no_flatten.v b/tests/arch/quicklogic/v/iob_no_flatten.v new file mode 100644 index 00000000000..ce713a7ced7 --- /dev/null +++ b/tests/arch/quicklogic/v/iob_no_flatten.v @@ -0,0 +1,28 @@ +module my_dff ( input d, clk, output reg q ); + initial q <= 1'b0; + always @( posedge clk ) + q <= d; +endmodule + +module my_top ( + inout wire pad, + input wire i, + input wire t, + output wire o, + input wire clk +); + + wire i_r; + wire t_r; + wire o_r; + + // IOB + assign pad = (t_r) ? i_r : 1'bz; + assign o_r = pad; + + // DFFs + my_dff dff_i (i, clk, i_r); + my_dff dff_t (t, clk, t_r); + my_dff dff_o (o_r, clk, o); + +endmodule diff --git a/tests/arch/quicklogic/v/latches.v b/tests/arch/quicklogic/v/latches.v new file mode 100644 index 00000000000..1485ffb99d0 --- /dev/null +++ b/tests/arch/quicklogic/v/latches.v @@ -0,0 +1,22 @@ +module latchp ( input d, clk, en, output reg q ); + initial q <= 1'b0; + always @* + if ( en ) + q <= d; +endmodule + +module latchn ( input d, clk, en, output reg q ); + always @* + if ( !en ) + q <= d; +endmodule + +module latchsr ( input d, clk, en, clr, pre, output reg q ); + always @* + if ( clr ) + q <= 1'b0; + else if ( pre ) + q <= 1'b1; + else if ( en ) + q <= d; +endmodule diff --git a/tests/arch/quicklogic/v/logic.v b/tests/arch/quicklogic/v/logic.v new file mode 100644 index 00000000000..62a2aa02772 --- /dev/null +++ b/tests/arch/quicklogic/v/logic.v @@ -0,0 +1,16 @@ +module top +( + input I0,I1,I2,I3, + output B1,B2,B3,B4,B5,B6,B7,B8,B9,B10 +); + assign B1 = I0 & I1; + assign B2 = I0 | I1; + assign B3 = I0 ~& I1; + assign B4 = I0 ~| I1; + assign B5 = I0 ^ I1; + assign B6 = I0 ~^ I1; + assign B7 = ~I0; + assign B8 = I0; + assign B9 = {I1,I0} && {I3,I3}; + assign B10 = {I1,I0} || {I3,I2}; +endmodule diff --git a/tests/arch/quicklogic/v/sub.v b/tests/arch/quicklogic/v/sub.v new file mode 100644 index 00000000000..a623c4c2fcf --- /dev/null +++ b/tests/arch/quicklogic/v/sub.v @@ -0,0 +1,10 @@ +module subtractor ( + input wire [`WIDTH-1:0] A, + input wire [`WIDTH-1:0] B, + output wire [`WIDTH :0] S, +); + + // Implicit subtractor + assign S = A - B; + +endmodule From 2d2ce1ec832f63507d1b1bbbd2478d49ada0024d Mon Sep 17 00:00:00 2001 From: Lalit Narain Sharma <61820431+lnsharma@users.noreply.github.com> Date: Mon, 1 Mar 2021 21:55:36 +0530 Subject: [PATCH 2/5] Incorporating review comments. Removed async2sync stmt, removed duplicate call to 'opt -fast' and removed help_mode stmt. --- techlibs/quicklogic/synth_quicklogic.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index 1f1b78eb747..23191f32ada 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -184,16 +184,11 @@ struct SynthQuickLogicPass : public ScriptPass { } if (check_label("map_gates")) { - if(family == "qlf_k4n8") { - run("async2sync"); - } if (inferAdder) { run("techmap -map +/techmap.v -map +/quicklogic/" + family + "_arith_map.v"); } else { run("techmap"); } - run("opt -fast"); - run("opt -fast"); run("opt_expr"); run("opt_merge"); @@ -238,12 +233,12 @@ struct SynthQuickLogicPass : public ScriptPass { } if (check_label("edif")) { - if (!edif_file.empty() || help_mode) + if (!edif_file.empty()) run(stringf("write_edif -nogndvcc -attrprop -pvector par %s %s", this->currmodule.c_str(), edif_file.c_str())); } if (check_label("blif")) { - if (!blif_file.empty() || help_mode) { + if (!blif_file.empty()) { run(stringf("opt_clean -purge"), " (qlf_k4n8 mode)"); if (inferAdder) { From 7acf304b08a40aa65a1b3f78d6a7b83770f3b8b7 Mon Sep 17 00:00:00 2001 From: Lalit Narain Sharma <61820431+lnsharma@users.noreply.github.com> Date: Tue, 2 Mar 2021 09:32:49 +0530 Subject: [PATCH 3/5] Incorporating review comments --- techlibs/quicklogic/synth_quicklogic.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index 23191f32ada..b0261ab0b48 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -230,7 +230,8 @@ struct SynthQuickLogicPass : public ScriptPass { if (check_label("finalize")) { run("check"); - } + run("opt_clean -purge"); + } if (check_label("edif")) { if (!edif_file.empty()) @@ -239,8 +240,6 @@ struct SynthQuickLogicPass : public ScriptPass { if (check_label("blif")) { if (!blif_file.empty()) { - run(stringf("opt_clean -purge"), - " (qlf_k4n8 mode)"); if (inferAdder) { run(stringf("write_blif -param %s", help_mode ? "" : blif_file.c_str())); } else { From 9a3af93b042d59c0b3e04cc31c1932f13e9f86ea Mon Sep 17 00:00:00 2001 From: Lalit Narain Sharma <61820431+lnsharma@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:24:42 +0530 Subject: [PATCH 4/5] Incorporating review comment about redundant lut_map file --- techlibs/quicklogic/Makefile.inc | 1 - techlibs/quicklogic/qlf_k4n8_lut_map.v | 30 ------------------------- techlibs/quicklogic/synth_quicklogic.cc | 9 -------- 3 files changed, 40 deletions(-) delete mode 100644 techlibs/quicklogic/qlf_k4n8_lut_map.v diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc index f7e9633e3a9..6604d7d4cc5 100644 --- a/techlibs/quicklogic/Makefile.inc +++ b/techlibs/quicklogic/Makefile.inc @@ -2,7 +2,6 @@ OBJS += techlibs/quicklogic/synth_quicklogic.o $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/cells_sim.v)) -$(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_lut_map.v)) $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_cells_sim.v)) $(eval $(call add_share_file,share/quicklogic,techlibs/quicklogic/qlf_k4n8_arith_map.v)) diff --git a/techlibs/quicklogic/qlf_k4n8_lut_map.v b/techlibs/quicklogic/qlf_k4n8_lut_map.v deleted file mode 100644 index 3eb524793d1..00000000000 --- a/techlibs/quicklogic/qlf_k4n8_lut_map.v +++ /dev/null @@ -1,30 +0,0 @@ -`ifndef NO_LUT -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - - (* force_downto *) - input [WIDTH-1:0] A; - output Y; - - generate - if (WIDTH == 1) begin - localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; - LUT4 #(.EQN(""),.INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y),.I0(1'b0), .I1(1'b0), .I2(1'b0), .I3(A[0])); - end else - if (WIDTH == 2) begin - localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; - LUT4 #(.EQN(""),.INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y),.I0(1'b0), .I1(1'b0), .I2(A[0]), .I3(A[1])); - end else - if (WIDTH == 3) begin - localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}}; - LUT4 #(.EQN(""),.INIT(INIT)) _TECHMAP_REPLACE_ (.O(Y),.I0(1'b0), .I1(A[0]), .I2(A[1]), .I3(A[2])); - end else - if (WIDTH == 4) begin - LUT4 #(.EQN(""),.INIT(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 \ No newline at end of file diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index b0261ab0b48..ca38fd20490 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -212,15 +212,6 @@ struct SynthQuickLogicPass : public ScriptPass { run("opt_lut"); } - if (check_label("map_cells")) { - - std::string techMapArgs; - techMapArgs += " -D NO_LUT -map +/quicklogic/" + family + "_lut_map.v"; - - run("techmap" + techMapArgs); - run("clean"); - } - if (check_label("check")) { run("autoname"); run("hierarchy -check"); From ab89e917d8ead1697b904c9710a1471c738fb5ab Mon Sep 17 00:00:00 2001 From: Lalit Narain Sharma <61820431+lnsharma@users.noreply.github.com> Date: Tue, 2 Mar 2021 15:27:56 +0530 Subject: [PATCH 5/5] Incorporating review comment on using common logic.v --- tests/arch/quicklogic/logic.ys | 2 +- tests/arch/quicklogic/v/logic.v | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 tests/arch/quicklogic/v/logic.v diff --git a/tests/arch/quicklogic/logic.ys b/tests/arch/quicklogic/logic.ys index c6534d2e175..ae40af153b1 100644 --- a/tests/arch/quicklogic/logic.ys +++ b/tests/arch/quicklogic/logic.ys @@ -1,4 +1,4 @@ -read_verilog v/logic.v +read_verilog ../common/logic.v hierarchy -top top proc equiv_opt -assert -map +/quicklogic/qlf_k4n8_cells_sim.v synth_quicklogic diff --git a/tests/arch/quicklogic/v/logic.v b/tests/arch/quicklogic/v/logic.v deleted file mode 100644 index 62a2aa02772..00000000000 --- a/tests/arch/quicklogic/v/logic.v +++ /dev/null @@ -1,16 +0,0 @@ -module top -( - input I0,I1,I2,I3, - output B1,B2,B3,B4,B5,B6,B7,B8,B9,B10 -); - assign B1 = I0 & I1; - assign B2 = I0 | I1; - assign B3 = I0 ~& I1; - assign B4 = I0 ~| I1; - assign B5 = I0 ^ I1; - assign B6 = I0 ~^ I1; - assign B7 = ~I0; - assign B8 = I0; - assign B9 = {I1,I0} && {I3,I3}; - assign B10 = {I1,I0} || {I3,I2}; -endmodule