diff --git a/passes/opt/opt_lut.cc b/passes/opt/opt_lut.cc index d1b8ab358..26855fd70 100644 --- a/passes/opt/opt_lut.cc +++ b/passes/opt/opt_lut.cc @@ -36,7 +36,7 @@ struct OptLutWorker dict> luts_dlogics; dict> luts_dlogic_inputs; - int combined_count = 0; + int eliminated_count = 0, combined_count = 0; bool evaluate_lut(RTLIL::Cell *lut, dict inputs) { @@ -189,8 +189,16 @@ struct OptLutWorker log("\n"); log("Eliminating LUTs.\n"); - for (auto lut : luts) + pool worklist = luts; + while (worklist.size()) { + if (limit == 0) + { + log("Limit reached.\n"); + break; + } + + auto lut = worklist.pop(); SigSpec lut_input = sigmap(lut->getPort("\\A")); pool &lut_dlogic_inputs = luts_dlogic_inputs[lut]; @@ -256,13 +264,24 @@ struct OptLutWorker else { SigSpec lut_output = lut->getPort("\\Y"); + for (auto &port : index.query_ports(lut_output)) + { + if (port.cell != lut && luts.count(port.cell)) + worklist.insert(port.cell); + } + module->connect(lut_output, value); + sigmap.add(lut_output, value); module->remove(lut); luts.erase(lut); luts_arity.erase(lut); luts_dlogics.erase(lut); luts_dlogic_inputs.erase(lut); + + eliminated_count++; + if (limit > 0) + limit--; } } } @@ -270,7 +289,7 @@ struct OptLutWorker log("\n"); log("Combining LUTs.\n"); - pool worklist = luts; + worklist = luts; while (worklist.size()) { if (limit == 0) @@ -568,16 +587,20 @@ struct OptLutPass : public Pass { } extra_args(args, argidx, design); - int total_count = 0; + int eliminated_count = 0, combined_count = 0; for (auto module : design->selected_modules()) { - OptLutWorker worker(dlogic, module, limit - total_count); - total_count += worker.combined_count; + OptLutWorker worker(dlogic, module, limit - eliminated_count - combined_count); + eliminated_count += worker.eliminated_count; + combined_count += worker.combined_count; } - if (total_count) + if (eliminated_count) + design->scratchpad_set_bool("opt.did_something", true); + if (combined_count) design->scratchpad_set_bool("opt.did_something", true); log("\n"); - log("Combined %d LUTs.\n", total_count); + log("Eliminated %d LUTs.\n", eliminated_count); + log("Combined %d LUTs.\n", combined_count); } } OptLutPass; diff --git a/passes/techmap/dffinit.cc b/passes/techmap/dffinit.cc index a8eecc970..48390488e 100644 --- a/passes/techmap/dffinit.cc +++ b/passes/techmap/dffinit.cc @@ -43,18 +43,37 @@ struct DffinitPass : public Pass { log(" initial value of 1 or 0. (multi-bit values are not supported in this\n"); log(" mode.)\n"); log("\n"); + log(" -strinit \n"); + log(" use string values in the command line to represent a single-bit\n"); + log(" initial value of 1 or 0. (multi-bit values are not supported in this\n"); + log(" mode.)\n"); + log("\n"); + log(" -noreinit\n"); + log(" fail if the FF cell has already a defined initial value set in other\n"); + log(" passes and the initial value of the net it drives is not equal to\n"); + log(" the already defined initial value.\n"); + log("\n"); } void execute(std::vector args, RTLIL::Design *design) YS_OVERRIDE { log_header(design, "Executing DFFINIT pass (set INIT param on FF cells).\n"); dict> ff_types; - bool highlow_mode = false; + bool highlow_mode = false, noreinit = false; + std::string high_string, low_string; size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { if (args[argidx] == "-highlow") { highlow_mode = true; + high_string = "high"; + low_string = "low"; + continue; + } + if (args[argidx] == "-strinit" && argidx+2 < args.size()) { + highlow_mode = true; + high_string = args[++argidx]; + low_string = args[++argidx]; continue; } if (args[argidx] == "-ff" && argidx+3 < args.size()) { @@ -64,6 +83,10 @@ struct DffinitPass : public Pass { ff_types[cell_name][output_port] = init_param; continue; } + if (args[argidx] == "-noreinit") { + noreinit = true; + continue; + } break; } extra_args(args, argidx, design); @@ -112,6 +135,10 @@ struct DffinitPass : public Pass { continue; while (GetSize(value.bits) <= i) value.bits.push_back(State::S0); + if (noreinit && value.bits[i] != State::Sx && value.bits[i] != init_bits.at(sig[i])) + log_error("Trying to assign a different init value for %s.%s.%s which technically " + "have a conflicted init value.\n", + log_id(module), log_id(cell), log_id(it.second)); value.bits[i] = init_bits.at(sig[i]); cleanup_bits.insert(sig[i]); } @@ -121,9 +148,9 @@ struct DffinitPass : public Pass { log_error("Multi-bit init value for %s.%s.%s is incompatible with -highlow mode.\n", log_id(module), log_id(cell), log_id(it.second)); if (value[0] == State::S1) - value = Const("high"); + value = Const(high_string); else - value = Const("low"); + value = Const(low_string); } log("Setting %s.%s.%s (port=%s, net=%s) to %s.\n", log_id(module), log_id(cell), log_id(it.second), diff --git a/techlibs/anlogic/cells_map.v b/techlibs/anlogic/cells_map.v index f54a81dcc..cfc743a4b 100644 --- a/techlibs/anlogic/cells_map.v +++ b/techlibs/anlogic/cells_map.v @@ -1,19 +1,19 @@ -module \$_DFF_N_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(1'b0)); endmodule -module \$_DFF_P_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(1'b0)); endmodule +module \$_DFF_N_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(1'b0)); endmodule +module \$_DFF_P_ (input D, C, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(1'b0)); endmodule -module \$_DFFE_NN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_NP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_PN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule -module \$_DFFE_PP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule +module \$_DFFE_NN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule +module \$_DFFE_NP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(E), .sr(1'b0)); endmodule +module \$_DFFE_PN_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule +module \$_DFFE_PP_ (input D, C, E, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'bx), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(E), .sr(1'b0)); endmodule -module \$_DFF_NN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_NP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) , .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("RESET"), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule -module \$_DFF_PP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET("SET"), .SRMUX("SR"), . SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_NN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_NN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_NP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_NP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(~C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_PN0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C) , .ce(1'b1), .sr(R)); endmodule +module \$_DFF_PN1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("INV"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_PP0_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b0), .SRMUX("SR"), .SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule +module \$_DFF_PP1_ (input D, C, R, output Q); AL_MAP_SEQ #(.DFFMODE("FF"), .REGSET(1'b1), .SRMUX("SR"), . SRMODE("SYNC")) _TECHMAP_REPLACE_ (.d(D), .q(Q), .clk(C), .ce(1'b1), .sr(R)); endmodule module \$_DLATCH_N_ (E, D, Q); wire [1023:0] _TECHMAP_DO_ = "simplemap; opt"; diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 68f4399d4..fab199fd7 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -170,6 +170,7 @@ struct SynthAnlogicPass : public ScriptPass { run("dffsr2dff"); run("techmap -D NO_LUT -map +/anlogic/cells_map.v"); + run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit"); run("opt_expr -mux_undef"); run("simplemap"); } diff --git a/techlibs/common/Makefile.inc b/techlibs/common/Makefile.inc index 70074f653..0e05620bc 100644 --- a/techlibs/common/Makefile.inc +++ b/techlibs/common/Makefile.inc @@ -26,5 +26,5 @@ $(eval $(call add_share_file,share,techlibs/common/pmux2mux.v)) $(eval $(call add_share_file,share,techlibs/common/adff2dff.v)) $(eval $(call add_share_file,share,techlibs/common/dff2ff.v)) $(eval $(call add_share_file,share,techlibs/common/gate2lut.v)) +$(eval $(call add_share_file,share,techlibs/common/cmp2lut.v)) $(eval $(call add_share_file,share,techlibs/common/cells.lib)) - diff --git a/techlibs/common/cmp2lut.v b/techlibs/common/cmp2lut.v new file mode 100644 index 000000000..8aa1eb957 --- /dev/null +++ b/techlibs/common/cmp2lut.v @@ -0,0 +1,105 @@ +// Certain arithmetic operations between a signal of width n and a constant can be directly mapped +// to a single k-LUT (where n <= k). This is preferable to normal alumacc techmapping process +// because for many targets, arithmetic techmapping creates hard logic (such as carry cells) which often +// cannot be optimized further. +// +// TODO: Currently, only comparisons with 1-bit output are mapped. Potentially, all arithmetic cells +// with n <= k inputs should be techmapped in this way, because this shortens the critical path +// from n to 1 by avoiding carry chains. + +(* techmap_celltype = "$eq $ne $lt $le $gt $ge" *) +module _90_lut_cmp_ (A, B, Y); + +parameter A_SIGNED = 0; +parameter B_SIGNED = 0; +parameter A_WIDTH = 0; +parameter B_WIDTH = 0; +parameter Y_WIDTH = 0; + +input [A_WIDTH-1:0] A; +input [B_WIDTH-1:0] B; +output [Y_WIDTH-1:0] Y; + +parameter _TECHMAP_CELLTYPE_ = ""; + +parameter _TECHMAP_CONSTMSK_A_ = 0; +parameter _TECHMAP_CONSTVAL_A_ = 0; +parameter _TECHMAP_CONSTMSK_B_ = 0; +parameter _TECHMAP_CONSTVAL_B_ = 0; + +function automatic integer gen_lut; + input integer width; + input integer operation; + input integer swap; + input integer sign; + input integer operand; + integer n, i_var, i_cst, lhs, rhs, o_bit; + begin + gen_lut = width'b0; + for (n = 0; n < (1 << width); n++) begin + if (sign) + i_var = n[width-1:0]; + else + i_var = n; + i_cst = operand; + if (swap) begin + lhs = i_cst; + rhs = i_var; + end else begin + lhs = i_var; + rhs = i_cst; + end + if (operation == 0) + o_bit = (lhs < rhs); + if (operation == 1) + o_bit = (lhs <= rhs); + if (operation == 2) + o_bit = (lhs > rhs); + if (operation == 3) + o_bit = (lhs >= rhs); + if (operation == 4) + o_bit = (lhs == rhs); + if (operation == 5) + o_bit = (lhs != rhs); + gen_lut = gen_lut | (o_bit << n); + end + end +endfunction + +generate + if (_TECHMAP_CELLTYPE_ == "$lt") + localparam operation = 0; + if (_TECHMAP_CELLTYPE_ == "$le") + localparam operation = 1; + if (_TECHMAP_CELLTYPE_ == "$gt") + localparam operation = 2; + if (_TECHMAP_CELLTYPE_ == "$ge") + localparam operation = 3; + if (_TECHMAP_CELLTYPE_ == "$eq") + localparam operation = 4; + if (_TECHMAP_CELLTYPE_ == "$ne") + localparam operation = 5; + + if (A_WIDTH > `LUT_WIDTH || B_WIDTH > `LUT_WIDTH || Y_WIDTH != 1) + wire _TECHMAP_FAIL_ = 1; + else if (&_TECHMAP_CONSTMSK_B_) + \$lut #( + .WIDTH(A_WIDTH), + .LUT({ gen_lut(A_WIDTH, operation, 0, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_B_) }) + ) _TECHMAP_REPLACE_ ( + .A(A), + .Y(Y) + ); + else if (&_TECHMAP_CONSTMSK_A_) + \$lut #( + .WIDTH(B_WIDTH), + .LUT({ gen_lut(B_WIDTH, operation, 1, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_A_) }) + ) _TECHMAP_REPLACE_ ( + .A(B), + .Y(Y) + ); + else + wire _TECHMAP_FAIL_ = 1; +endgenerate + +endmodule diff --git a/techlibs/common/synth.cc b/techlibs/common/synth.cc index d9565131e..ccfa76e02 100644 --- a/techlibs/common/synth.cc +++ b/techlibs/common/synth.cc @@ -51,6 +51,9 @@ struct SynthPass : public ScriptPass log(" -encfile \n"); log(" passed to 'fsm_recode' via 'fsm'\n"); log("\n"); + log(" -lut \n"); + log(" perform synthesis for a k-LUT architecture.\n"); + log("\n"); log(" -nofsm\n"); log(" do not run FSM optimization\n"); log("\n"); @@ -80,6 +83,7 @@ struct SynthPass : public ScriptPass string top_module, fsm_opts, memory_opts; bool autotop, flatten, noalumacc, nofsm, noabc, noshare; + int lut; void clear_flags() YS_OVERRIDE { @@ -89,6 +93,7 @@ struct SynthPass : public ScriptPass autotop = false; flatten = false; + lut = 0; noalumacc = false; nofsm = false; noabc = false; @@ -130,6 +135,10 @@ struct SynthPass : public ScriptPass flatten = true; continue; } + if (args[argidx] == "-lut") { + lut = atoi(args[++argidx].c_str()); + continue; + } if (args[argidx] == "-nofsm") { nofsm = true; continue; @@ -186,19 +195,23 @@ struct SynthPass : public ScriptPass { run("proc"); if (help_mode || flatten) - run("flatten", "(if -flatten)"); + run("flatten", " (if -flatten)"); run("opt_expr"); run("opt_clean"); run("check"); run("opt"); run("wreduce"); + if (help_mode) + run("techmap -map +/cmp2lut.v", " (if -lut)"); + else + run(stringf("techmap -map +/cmp2lut.v -D LUT_WIDTH=%d", lut)); if (!noalumacc) - run("alumacc"); + run("alumacc", " (unless -noalumacc)"); if (!noshare) - run("share"); + run("share", " (unless -noshare)"); run("opt"); if (!nofsm) - run("fsm" + fsm_opts); + run("fsm" + fsm_opts, " (unless -nofsm)"); run("opt -fast"); run("memory -nomap" + memory_opts); run("opt_clean"); @@ -210,12 +223,33 @@ struct SynthPass : public ScriptPass run("memory_map"); run("opt -full"); run("techmap"); + if (help_mode) + { + run("techmap -map +/gate2lut.v", "(if -noabc and -lut)"); + run("clean; opt_lut", " (if -noabc and -lut)"); + } + else if (noabc && lut) + { + run(stringf("techmap -map +/gate2lut.v -D LUT_WIDTH=%d", lut)); + run("clean; opt_lut"); + } run("opt -fast"); if (!noabc) { #ifdef YOSYS_ENABLE_ABC - run("abc -fast"); - run("opt -fast"); + if (help_mode) + { + run("abc -fast", " (unless -noabc, unless -lut)"); + run("abc -fast -lut k", "(unless -noabc, if -lut)"); + } + else + { + if (lut) + run(stringf("abc -fast -lut %d", lut)); + else + run("abc -fast"); + } + run("opt -fast", " (unless -noabc)"); #endif } } diff --git a/techlibs/ice40/synth_ice40.cc b/techlibs/ice40/synth_ice40.cc index 626f6d381..f900453e8 100644 --- a/techlibs/ice40/synth_ice40.cc +++ b/techlibs/ice40/synth_ice40.cc @@ -226,7 +226,7 @@ struct SynthIce40Pass : public ScriptPass if (check_label("coarse")) { - run("synth -run coarse"); + run("synth -lut 4 -run coarse"); } if (!nobram && check_label("bram", "(skip if -nobram)")) diff --git a/tests/lut/check_map.ys b/tests/lut/check_map.ys index dc0aaffc2..46854e82e 100644 --- a/tests/lut/check_map.ys +++ b/tests/lut/check_map.ys @@ -1,4 +1,6 @@ simplemap -equiv_opt -assert techmap -map +/gate2lut.v -D LUT_WIDTH=4 +equiv_opt -assert techmap -D LUT_WIDTH=4 -map +/cmp2lut.v design -load postopt -select -assert-count 1 t:$lut +equiv_opt -assert techmap -D LUT_WIDTH=4 -map +/gate2lut.v +design -load postopt +select -assert-count 0 t:* t:$lut %d diff --git a/tests/lut/map_cmp.v b/tests/lut/map_cmp.v new file mode 100644 index 000000000..5e413f894 --- /dev/null +++ b/tests/lut/map_cmp.v @@ -0,0 +1,29 @@ +module top(...); + input [3:0] a; + + output o1_1 = 4'b1010 <= a; + output o1_2 = 4'b1010 < a; + output o1_3 = 4'b1010 >= a; + output o1_4 = 4'b1010 > a; + output o1_5 = 4'b1010 == a; + output o1_6 = 4'b1010 != a; + + output o2_1 = a <= 4'b1010; + output o2_2 = a < 4'b1010; + output o2_3 = a >= 4'b1010; + output o2_4 = a > 4'b1010; + output o2_5 = a == 4'b1010; + output o2_6 = a != 4'b1010; + + output o3_1 = 4'sb0101 <= $signed(a); + output o3_2 = 4'sb0101 < $signed(a); + output o3_3 = 4'sb0101 >= $signed(a); + output o3_4 = 4'sb0101 > $signed(a); + output o3_5 = 4'sb0101 == $signed(a); + output o3_6 = 4'sb0101 != $signed(a); + + output o4_1 = $signed(a) <= 4'sb0000; + output o4_2 = $signed(a) < 4'sb0000; + output o4_3 = $signed(a) >= 4'sb0000; + output o4_4 = $signed(a) > 4'sb0000; +endmodule diff --git a/tests/lut/run-test.sh b/tests/lut/run-test.sh old mode 100644 new mode 100755