From d600245ccf254f1aefbea6dcfe9858ba22253594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Tue, 4 Feb 2025 10:30:15 +0100 Subject: [PATCH] qlf_k6n10f: New ql_dsp pass, move to DSPV2 --- techlibs/quicklogic/Makefile.inc | 3 + techlibs/quicklogic/ql_dsp.cc | 58 + techlibs/quicklogic/ql_dsp.pmg | 266 ++ techlibs/quicklogic/qlf_k6n10f/dsp_map.v | 135 +- techlibs/quicklogic/qlf_k6n10f/dsp_sim.v | 5481 +++++----------------- techlibs/quicklogic/synth_quicklogic.cc | 19 +- 6 files changed, 1553 insertions(+), 4409 deletions(-) create mode 100644 techlibs/quicklogic/ql_dsp.cc create mode 100644 techlibs/quicklogic/ql_dsp.pmg diff --git a/techlibs/quicklogic/Makefile.inc b/techlibs/quicklogic/Makefile.inc index ade144371..f3f88edf7 100644 --- a/techlibs/quicklogic/Makefile.inc +++ b/techlibs/quicklogic/Makefile.inc @@ -10,9 +10,12 @@ OBJS += techlibs/quicklogic/ql_dsp_io_regs.o # -------------------------------------- OBJS += techlibs/quicklogic/ql_dsp_macc.o +OBJS += techlibs/quicklogic/ql_dsp.o GENFILES += techlibs/quicklogic/ql_dsp_macc_pm.h techlibs/quicklogic/qlf_k6n10f/bram_types_sim.v techlibs/quicklogic/ql_dsp_macc.o: techlibs/quicklogic/ql_dsp_macc_pm.h +techlibs/quicklogic/ql_dsp.o: techlibs/quicklogic/ql_dsp_pm.h $(eval $(call add_extra_objs,techlibs/quicklogic/ql_dsp_macc_pm.h)) +$(eval $(call add_extra_objs,techlibs/quicklogic/ql_dsp_pm.h)) # -------------------------------------- diff --git a/techlibs/quicklogic/ql_dsp.cc b/techlibs/quicklogic/ql_dsp.cc new file mode 100644 index 000000000..aa8ed6631 --- /dev/null +++ b/techlibs/quicklogic/ql_dsp.cc @@ -0,0 +1,58 @@ +/* + * yosys -- Yosys Open SYnthesis Suite + * + * 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/rtlil.h" +#include "kernel/register.h" +#include "kernel/sigtools.h" + +PRIVATE_NAMESPACE_BEGIN +USING_YOSYS_NAMESPACE + +#include "ql_dsp_pm.h" + +struct QlDspPass : Pass { + QlDspPass() : Pass("ql_dsp", "pack into QuickLogic DSPs") {} + void execute(std::vector args, RTLIL::Design *d) override + { + log_header(d, "Executing QL_DSP pass. (pack into QuickLogic DSPs)\n"); + + size_t argidx; + for (argidx = 1; argidx < args.size(); argidx++) { + break; + } + extra_args(args, argidx, d); + + for (auto module : d->selected_modules()) { + { + ql_dsp_pm pm(module, module->selected_cells()); + pm.run_ql_dsp_pack_regs(); + } + + { + ql_dsp_pm pm(module, module->selected_cells()); + pm.run_ql_dsp_cascade(); + } + + { + ql_dsp_pm pm(module, module->selected_cells()); + pm.run_ql_dsp_pack_regs(); + } + } + } +} QlDspPass; + +PRIVATE_NAMESPACE_END diff --git a/techlibs/quicklogic/ql_dsp.pmg b/techlibs/quicklogic/ql_dsp.pmg new file mode 100644 index 000000000..e7c253bf5 --- /dev/null +++ b/techlibs/quicklogic/ql_dsp.pmg @@ -0,0 +1,266 @@ +// derived from passes/pmgen/xilinx_dsp.pmg +pattern ql_dsp_pack_regs + +state clock reset +state clock_inferred + +// Variables used for subpatterns +state argQ argD +udata dffD dffQ +udata dffclock dffreset +udata dff + +match dsp + select dsp->type == \dspv2_32x18x64_cfg_ports +endmatch + +code clock_inferred clock reset + clock_inferred = false; + clock = port(dsp, \clock_i); + reset = port(dsp, \reset_i); +endcode + +// try packing on Z output +code argD clock_inferred clock reset + if (port(dsp, \output_select_i)[2] == RTLIL::S0 && + (!dsp->hasPort(\z_cout_o) || nusers(port(dsp, \z_cout_o)) == 1) && + nusers(port(dsp, \z_o)) == 2) { + argD = port(dsp, \z_o); + subpattern(out_dffe); + if (dff) { + clock_inferred = true; + clock = dffclock; + reset = dffreset; + log("%s: inferring Z path register from flip-flop %s\n", log_id(dsp), log_id(dff)); + dsp->connections_[\output_select_i][2] = RTLIL::S1; + dsp->setPort(\z_o, dffQ); + } + } +endcode + +// try packing on B input +code argQ clock_inferred clock reset + if ((!dsp->hasPort(\b_cout_o) || nusers(port(dsp, \b_cout_o)) == 1) && + !param(dsp, \B_REG).as_bool() && + nusers(port(dsp, \b_i)) == 2) { + argQ = port(dsp, \b_i); + subpattern(in_dffe); + if (dff) { + clock_inferred = true; + clock = dffclock; + reset = dffreset; + log("%s: inferring B path register from flip-flop %s\n", log_id(dsp), log_id(dff)); + dsp->parameters[\B_REG] = true; + dsp->setPort(\b_i, dffD); + } + } +endcode + +// try packing on A input +code argQ clock_inferred clock reset + if ((!dsp->hasPort(\a_cout_o) || nusers(port(dsp, \a_cout_o)) == 1) && + !param(dsp, \A_REG).as_bool() && + nusers(port(dsp, \a_i)) == 2) { + argQ = port(dsp, \a_i); + subpattern(in_dffe); + if (dff) { + clock_inferred = true; + clock = dffclock; + reset = dffreset; + log("%s: inferring A path register from flip-flop %s\n", log_id(dsp), log_id(dff)); + dsp->parameters[\A_REG] = true; + dsp->setPort(\a_i, dffD); + } + } +endcode + +code + if (clock_inferred) { + dsp->setPort(\clock_i, clock); + dsp->setPort(\reset_i, reset); + } +endcode + +// ####################### +// Subpattern for matching against input registers, based on knowledge of the +// 'Q' output. +subpattern in_dffe +arg argQ clock reset + +code + dff = nullptr; + if (argQ.empty()) + reject; + for (const auto &c : argQ.chunks()) { + if (!c.wire) { + // Abandon matches when constant Q bits are non-zero + // (doesn't match DSPv2 init/reset behavior) + if (!SigSpec(c).is_fully_zero()) + reject; + continue; + } + + // Abandon matches when 'Q' has the keep attribute set + if (c.wire->get_bool_attribute(\keep)) + reject; + // Abandon matches when 'Q' has a non-zero init attribute set (not supported by DSPv2) + Const init = c.wire->attributes.at(\init, Const()); + if (!init.empty()) + for (auto b : init.extract(c.offset, c.width)) + if (b != State::Sx && b != State::S0) + reject; + } +endcode + +match ff + select ff->type.in($dff, $dffe, $adff, $adffe) + // DSPv2 does not support polarity inversion + select param(ff, \CLK_POLARITY).as_bool() + + // Check that reset value, if present, is fully 0. + filter ff->type.in($dff, $dffe) || param(ff, \ARST_VALUE).is_fully_zero() + + // Check reset polarity, if present + filter ff->type.in($dff, $dffe) || param(ff, \ARST_POLARITY).as_bool() + + // Check that the LSB argQ bit is present (the rest follow by the nusers(...)=2 condition) + slice offset GetSize(port(ff, \D)) + index port(ff, \Q)[offset] === argQ[0] + + define ff_reset (ff->type.in($dff, $dffe) ? RTLIL::S0 : port(ff, \ARST)) + filter clock == RTLIL::Sx || port(ff, \CLK)[0] == clock + filter clock == RTLIL::Sx || ff_reset == reset +endmatch + +code argD + dff = ff; + dffclock = port(ff, \CLK); + dffreset = (ff->type.in($dff, $dffe) ? RTLIL::S0 : port(ff, \ARST)); + dffD = argQ; + dffD.replace(port(ff, \Q), port(ff, \D)); +endcode + + +// ####################### +// Subpattern for matching against output registers, based on knowledge of the +// 'D' input. + +subpattern out_dffe +arg argD clock reset + +code + dff = nullptr; + if (argD.empty()) + reject; + for (const auto &c : argD.chunks()) { + // Abandon matches when 'D' has the keep attribute set + if (!c.wire || c.wire->get_bool_attribute(\keep)) + reject; + } +endcode + +match ff + select ff->type.in($dff, $dffe, $adff, $adffe) + // DSPv2 does not support polarity inversion + select param(ff, \CLK_POLARITY).as_bool() + + // Check that reset value, if present, is fully 0. + filter ff->type.in($dff, $dffe) || param(ff, \ARST_VALUE).is_fully_zero() + + // Check reset polarity, if present + filter ff->type.in($dff, $dffe) || param(ff, \ARST_POLARITY).as_bool() + + slice offset GetSize(port(ff, \D)) + index port(ff, \D)[offset] === argD[0] + + define ff_reset (ff->type.in($dff, $dffe) ? RTLIL::S0 : port(ff, \ARST)) + filter clock == RTLIL::Sx || port(ff, \CLK)[0] == clock + filter clock == RTLIL::Sx || ff_reset == reset +endmatch + +code + dff = ff; + dffclock = port(ff, \CLK); + dffreset = (ff->type.in($dff, $dffe) ? RTLIL::S0 : port(ff, \ARST)); + dffQ = argD; + dffQ.replace(port(ff, \D), port(ff, \Q)); + + // Abandon matches when 'Q' has a defined init attribute set + // (not supported by DSPv2) + for (auto c : dffQ.chunks()) { + Const init = c.wire->attributes.at(\init, Const()); + if (!init.empty()) + for (auto b : init.extract(c.offset, c.width)) + if (b != State::Sx) + reject; + } + + { + // Rewire retired flip-flop slice + SigSpec D = port(ff, \D); + SigSpec Q = port(ff, \Q); + D.replace(argD, module->addWire(NEW_ID, argD.size()), &Q); + D.replace(argD, Const(RTLIL::Sx, argD.size())); + ff->setPort(\D, D); + ff->setPort(\Q, Q); + } +endcode + +pattern ql_dsp_cascade + +match dsp1 + select dsp1->type == \dspv2_32x18x64_cfg_ports + filter !dsp1->hasPort(\z_cout_o) || nusers(port(dsp1, \z_cout_o)) == 1 +endmatch + +match dsp2 + select dsp2->type == \dspv2_32x18x64_cfg_ports + filter port(dsp2, \output_select_i).is_fully_const() + define output_sel port(dsp2, \output_select_i).as_int() + filter output_sel == 3 || (output_sel == 4 && !param(dsp2, \M_REG).as_bool()) + // expect `dsp2` and `add` for exclusive users + filter nusers(port(dsp2, \z_o)) == 2 + filter !dsp2->hasPort(\z_cout_o) || nusers(port(dsp2, \z_cout_o)) == 1 +endmatch + +match add + select add->type.in($add, $sub) + define width param(add, \Y_WIDTH).as_int() + + index port(add, \A)[0] === port(dsp1, \z_o)[0] + filter port(add, \A).size() >= width && port(dsp1, \z_o).size() >= width + filter port(add, \A).extract(0, width) == port(dsp1, \z_o).extract(0, width) + + index port(add, \B)[0] === port(dsp2, \z_o)[0] + filter port(add, \B).size() >= width && port(dsp2, \z_o).size() >= width + filter port(add, \B).extract(0, width) == port(dsp2, \z_o).extract(0, width) +endmatch + +code +endcode + +code + const int z_width = 50; + + log("%s: inferring post-adder from %s (type %s)\n", log_id(dsp2), log_id(add), log_id(add->type)); + + // link up z_cout_o of dsp1 to z_cin_i of dsp2 + Wire *link = module->addWire(NEW_ID, z_width); + dsp1->setPort(\z_cout_o, link); + dsp2->setPort(\z_cin_i, link); + + // configure the path inside dsp2 + if (port(dsp2, \output_select_i).as_int() == 4) { + log("%s: inferring M register\n", log_id(dsp2)); + dsp2->setParam(\M_REG, Const(1, 1)); + } + dsp2->setParam(\SUBTRACT, Const(add->type == $sub, 1)); + dsp2->setPort(\feedback_i, Const(3, 3)); + dsp2->setPort(\output_select_i, Const(3, 3)); + dsp2->setParam(\ROUND, Const(0, 3)); + dsp2->setParam(\SHIFT_REG, Const(0, 6)); + dsp2->setParam(\SATURATE, Const(0, 1)); + + dsp2->setPort(\z_o, {port(dsp2, \z_o).extract_end(port(add, \Y).size()), port(add, \Y)}); + module->remove(add); +endcode diff --git a/techlibs/quicklogic/qlf_k6n10f/dsp_map.v b/techlibs/quicklogic/qlf_k6n10f/dsp_map.v index 127145b71..ded1f592e 100644 --- a/techlibs/quicklogic/qlf_k6n10f/dsp_map.v +++ b/techlibs/quicklogic/qlf_k6n10f/dsp_map.v @@ -1,102 +1,59 @@ -// Copyright 2020-2022 F4PGA Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - -module \$__QL_MUL20X18 (input [19:0] A, input [17:0] B, output [37:0] Y); +module \$__MUL32X18 (input [31:0] A, input [17:0] B, output [49:0] Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; - parameter A_WIDTH = 0; - parameter B_WIDTH = 0; - parameter Y_WIDTH = 0; + parameter A_WIDTH = 32; + parameter B_WIDTH = 18; + parameter Y_WIDTH = 50; - wire [19:0] a; - wire [17:0] b; - wire [37:0] z; + dspv2_32x18x64_cfg_ports _TECHMAP_REPLACE_ ( + .a_i(A), + .b_i(B), + .c_i(18'd0), + .z_o(Y), - assign a = (A_WIDTH == 20) ? A : - (A_SIGNED) ? {{(20 - A_WIDTH){A[A_WIDTH-1]}}, A} : - {{(20 - A_WIDTH){1'b0}}, A}; - - assign b = (B_WIDTH == 18) ? B : - (B_SIGNED) ? {{(18 - B_WIDTH){B[B_WIDTH-1]}}, B} : - {{(18 - B_WIDTH){1'b0}}, B}; - - (* is_inferred=1 *) - dsp_t1_20x18x64_cfg_ports _TECHMAP_REPLACE_ ( - .a_i (a), - .b_i (b), - .acc_fir_i (6'd0), - .z_o (z), - - .feedback_i (3'd0), - .load_acc_i (1'b0), - .unsigned_a_i (!A_SIGNED), - .unsigned_b_i (!B_SIGNED), - - .output_select_i (3'd0), - .saturate_enable_i (1'b0), - .shift_right_i (6'd0), - .round_i (1'b0), - .subtract_i (1'b0), - .register_inputs_i (1'b0) + .clock_i(1'bx), + .reset_i(1'bx), + .acc_reset_i(1'b0), + .feedback_i(3'd0), + .load_acc_i(1'b0), + .output_select_i(3'd0), + .a_cin_i(32'dx), + .b_cin_i(18'dx), + .z_cin_i(50'dx), +/* TODO: connect to dummy wires? + .a_cout_o(), + .b_cout_o(), + .z_cout_o(), +*/ ); - - assign Y = z; - endmodule -module \$__QL_MUL10X9 (input [9:0] A, input [8:0] B, output [18:0] Y); +module \$__MUL16X9 (input [15:0] A, input [8:0] B, output [24:0] Y); parameter A_SIGNED = 0; parameter B_SIGNED = 0; - parameter A_WIDTH = 0; - parameter B_WIDTH = 0; - parameter Y_WIDTH = 0; + parameter A_WIDTH = 16; + parameter B_WIDTH = 9; + parameter Y_WIDTH = 25; - wire [ 9:0] a; - wire [ 8:0] b; - wire [18:0] z; + dspv2_16x9x32_cfg_ports _TECHMAP_REPLACE_ ( + .a_i(A), + .b_i(B), + .c_i(10'd0), + .z_o(Y), - assign a = (A_WIDTH == 10) ? A : - (A_SIGNED) ? {{(10 - A_WIDTH){A[A_WIDTH-1]}}, A} : - {{(10 - A_WIDTH){1'b0}}, A}; - - assign b = (B_WIDTH == 9) ? B : - (B_SIGNED) ? {{( 9 - B_WIDTH){B[B_WIDTH-1]}}, B} : - {{( 9 - B_WIDTH){1'b0}}, B}; - - (* is_inferred=1 *) - dsp_t1_10x9x32_cfg_ports _TECHMAP_REPLACE_ ( - .a_i (a), - .b_i (b), - .acc_fir_i (6'd0), - .z_o (z), - - .feedback_i (3'd0), - .load_acc_i (1'b0), - .unsigned_a_i (!A_SIGNED), - .unsigned_b_i (!B_SIGNED), - - .output_select_i (3'd0), - .saturate_enable_i (1'b0), - .shift_right_i (6'd0), - .round_i (1'b0), - .subtract_i (1'b0), - .register_inputs_i (1'b0) + .clock_i(1'bx), + .reset_i(1'bx), + .acc_reset_i(1'b0), + .feedback_i(3'd0), + .load_acc_i(1'b0), + .output_select_i(3'd0), + .a_cin_i(32'dx), + .b_cin_i(18'dx), + .z_cin_i(50'dx), +/* TODO: connect to dummy wires? + .a_cout_o(), + .b_cout_o(), + .z_cout_o(), +*/ ); - - - assign Y = z; - endmodule diff --git a/techlibs/quicklogic/qlf_k6n10f/dsp_sim.v b/techlibs/quicklogic/qlf_k6n10f/dsp_sim.v index 5f43b3229..40056bfdb 100644 --- a/techlibs/quicklogic/qlf_k6n10f/dsp_sim.v +++ b/techlibs/quicklogic/qlf_k6n10f/dsp_sim.v @@ -1,4527 +1,1382 @@ -// Copyright 2020-2022 F4PGA Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 - `timescale 1ps/1ps `default_nettype none -(* blackbox *) -module QL_DSP1 ( - input wire [19:0] a, - input wire [17:0] b, - (* clkbuf_sink *) - input wire clk0, - (* clkbuf_sink *) - input wire clk1, - input wire [ 1:0] feedback0, - input wire [ 1:0] feedback1, - input wire load_acc0, - input wire load_acc1, - input wire reset0, - input wire reset1, - output reg [37:0] z -); - parameter MODE_BITS = 27'b00000000000000000000000000; -endmodule /* QL_DSP1 */ - - - // ---------------------------------------- // // ----- DSP cells simulation modules ----- // // --------- Control bits in ports -------- // // ---------------------------------------- // -module QL_DSP2 ( // TODO: Name subject to change - input wire [19:0] a, - input wire [17:0] b, - input wire [ 5:0] acc_fir, - output wire [37:0] z, - output wire [17:0] dly_b, +module QL_DSPV2 ( // TODO: Name subject to change + input wire [31:0] a, + input wire [17:0] b, + input wire [17:0] c, + input wire load_acc, + input wire [2:0] feedback, + input wire [2:0] output_select, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, - - input wire [2:0] feedback, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [2:0] output_select, - input wire saturate_enable, - input wire [5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + (* clkbuf_sink *) + input wire clk, + input wire reset, + input wire acc_reset, + + input wire [31:0] a_cin, + input wire [17:0] b_cin, + input wire [49:0] z_cin, + output wire [49:0] z_cout, + output wire [31:0] a_cout, + output wire [17:0] b_cout ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h00000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + + localparam NBITS_ACC = 64; + localparam NBITS_A = 32; + localparam NBITS_BC = 18; + localparam NBITS_Z = 50; - localparam NBITS_ACC = 64; - localparam NBITS_A = 20; - localparam NBITS_B = 18; - localparam NBITS_Z = 38; + wire [NBITS_Z-1:0] dsp_full_z; + wire [(NBITS_Z/2)-1:0] dsp_frac0_z; + wire [(NBITS_Z/2)-1:0] dsp_frac1_z; + + wire [NBITS_Z-1:0] dsp_full_z_cout; + wire [(NBITS_Z/2)-1:0] dsp_frac0_z_cout; + wire [(NBITS_Z/2)-1:0] dsp_frac1_z_cout; - wire [NBITS_Z-1:0] dsp_full_z; - wire [(NBITS_Z/2)-1:0] dsp_frac0_z; - wire [(NBITS_Z/2)-1:0] dsp_frac1_z; + wire [NBITS_A-1:0] dsp_full_a_cout; + wire [(NBITS_A/2)-1:0] dsp_frac0_a_cout; + wire [(NBITS_A/2)-1:0] dsp_frac1_a_cout; + + wire [NBITS_BC-1:0] dsp_full_b_cout; + wire [(NBITS_BC/2)-1:0] dsp_frac0_b_cout; + wire [(NBITS_BC/2)-1:0] dsp_frac1_b_cout; - wire [NBITS_B-1:0] dsp_full_dly_b; - wire [(NBITS_B/2)-1:0] dsp_frac0_dly_b; - wire [(NBITS_B/2)-1:0] dsp_frac1_dly_b; + assign z = FRAC_MODE ? {dsp_frac1_z, dsp_frac0_z} : dsp_full_z; + assign z_cout = FRAC_MODE ? {dsp_frac1_z_cout, dsp_frac0_z_cout} : dsp_full_z_cout; + assign a_cout = FRAC_MODE ? {dsp_frac1_a_cout, dsp_frac0_a_cout} : dsp_full_a_cout; + assign b_cout = FRAC_MODE ? {dsp_frac1_b_cout, dsp_frac0_b_cout} : dsp_full_b_cout; - assign z = f_mode ? {dsp_frac1_z, dsp_frac0_z} : dsp_full_z; - assign dly_b = f_mode ? {dsp_frac1_dly_b, dsp_frac0_dly_b} : dsp_full_dly_b; - - // Output used when fmode == 1 - dsp_t1_sim_cfg_ports #( - .NBITS_A(NBITS_A/2), - .NBITS_B(NBITS_B/2), - .NBITS_ACC(NBITS_ACC/2), - .NBITS_Z(NBITS_Z/2) - ) dsp_frac0 ( + // Output used when fmode == 1 + dspv2_sim_cfg_ports #( + .NBITS_A(NBITS_A/2), + .NBITS_BC(NBITS_BC/2), + .NBITS_ACC(NBITS_ACC/2), + .NBITS_Z(NBITS_Z/2) + ) dsp_frac0 ( + // active/fabric ports + .clock_i(clk), + .s_reset(reset), .a_i(a[(NBITS_A/2)-1:0]), - .b_i(b[(NBITS_B/2)-1:0]), + .b_i(b[(NBITS_BC/2)-1:0]), + .c_i(c[(NBITS_BC/2)-1:0]), + .feedback_i(feedback), + .output_select_i(output_select), + .load_acc_i(load_acc), + .rst_acc_i(acc_reset), .z_o(dsp_frac0_z), - .dly_b_o(dsp_frac0_dly_b), - - .acc_fir_i(acc_fir), - .feedback_i(feedback), - .load_acc_i(load_acc), - - .unsigned_a_i(unsigned_a), - .unsigned_b_i(unsigned_b), + // cascade ports (connect to dedicated cascade routing) + .a_cin_i(a_cin[(NBITS_A/2)-1:0]), + .b_cin_i(b_cin[(NBITS_BC/2)-1:0]), + .z_cin_i(z_cin[(NBITS_Z/2)-1:0]), + .z_cout_o(dsp_frac0_z_cout), + .a_cout_o(dsp_frac0_a_cout), + .b_cout_o(dsp_frac0_b_cout), + // configuration ports (tie-offs) + .coeff_i(COEFF_0[(NBITS_A/2)-1:0]), + .acc_fir_i(ACC_FIR), + .round_i(ROUND), + .zc_shift_i(ZC_SHIFT), + .zreg_shift_i(ZREG_SHIFT), + .shift_right_i(SHIFT_REG), + .saturate_enable_i(SATURATE), + .subtract_i(SUBTRACT), + .pre_add_sel_i(PRE_ADD), + .a_sel_i(A_SEL), + .a_reg_i(A_REG), + .b_sel_i(B_SEL), + .b_reg_i(B_REG), + .c_reg_i(C_REG), + .bc_reg_i(BC_REG), + .m_reg_i(M_REG) + ); + // Output used when fmode == 1 + dspv2_sim_cfg_ports #( + .NBITS_A(NBITS_A/2), + .NBITS_BC(NBITS_BC/2), + .NBITS_ACC(NBITS_ACC/2), + .NBITS_Z(NBITS_Z/2) + ) dsp_frac1 ( + // active/fabric ports .clock_i(clk), .s_reset(reset), - - .saturate_enable_i(saturate_enable), - .output_select_i(output_select), - .round_i(round), - .shift_right_i(shift_right), - .subtract_i(subtract), - .register_inputs_i(register_inputs), - .coef_0_i(COEFF_0[(NBITS_A/2)-1:0]), - .coef_1_i(COEFF_1[(NBITS_A/2)-1:0]), - .coef_2_i(COEFF_2[(NBITS_A/2)-1:0]), - .coef_3_i(COEFF_3[(NBITS_A/2)-1:0]) - ); - - // Output used when fmode == 1 - dsp_t1_sim_cfg_ports #( - .NBITS_A(NBITS_A/2), - .NBITS_B(NBITS_B/2), - .NBITS_ACC(NBITS_ACC/2), - .NBITS_Z(NBITS_Z/2) - ) dsp_frac1 ( .a_i(a[NBITS_A-1:NBITS_A/2]), - .b_i(b[NBITS_B-1:NBITS_B/2]), - .z_o(dsp_frac1_z), - .dly_b_o(dsp_frac1_dly_b), - - .acc_fir_i(acc_fir), + .b_i(b[NBITS_BC-1:NBITS_BC/2]), + .c_i(c[NBITS_BC-1:NBITS_BC/2]), .feedback_i(feedback), + .output_select_i(output_select), .load_acc_i(load_acc), + .rst_acc_i(acc_reset), + .z_o(dsp_frac1_z), + // cascade ports (connect to dedicated cascade routing) + .a_cin_i(a_cin[NBITS_A-1:NBITS_A/2]), + .b_cin_i(b_cin[NBITS_BC-1:NBITS_BC/2]), + .z_cin_i(z_cin[NBITS_Z-1:NBITS_Z/2]), + .z_cout_o(dsp_frac1_z_cout), + .a_cout_o(dsp_frac1_a_cout), + .b_cout_o(dsp_frac1_b_cout), + // configuration ports (tie-offs) + .coeff_i(COEFF_0[NBITS_A-1:NBITS_A/2]), + .acc_fir_i(ACC_FIR), + .round_i(ROUND), + .zc_shift_i(ZC_SHIFT), + .zreg_shift_i(ZREG_SHIFT), + .shift_right_i(SHIFT_REG), + .saturate_enable_i(SATURATE), + .subtract_i(SUBTRACT), + .pre_add_sel_i(PRE_ADD), + .a_sel_i(A_SEL), + .a_reg_i(A_REG), + .b_sel_i(B_SEL), + .b_reg_i(B_REG), + .c_reg_i(C_REG), + .bc_reg_i(BC_REG), + .m_reg_i(M_REG) + ); - .unsigned_a_i(unsigned_a), - .unsigned_b_i(unsigned_b), - + // Output used when fmode == 0 + dspv2_sim_cfg_ports #( + .NBITS_A(NBITS_A), + .NBITS_BC(NBITS_BC), + .NBITS_ACC(NBITS_ACC), + .NBITS_Z(NBITS_Z) + ) dsp_full ( + // active/fabric ports .clock_i(clk), .s_reset(reset), - - .saturate_enable_i(saturate_enable), - .output_select_i(output_select), - .round_i(round), - .shift_right_i(shift_right), - .subtract_i(subtract), - .register_inputs_i(register_inputs), - .coef_0_i(COEFF_0[NBITS_A-1:NBITS_A/2]), - .coef_1_i(COEFF_1[NBITS_A-1:NBITS_A/2]), - .coef_2_i(COEFF_2[NBITS_A-1:NBITS_A/2]), - .coef_3_i(COEFF_3[NBITS_A-1:NBITS_A/2]) - ); - - // Output used when fmode == 0 - dsp_t1_sim_cfg_ports #( - .NBITS_A(NBITS_A), - .NBITS_B(NBITS_B), - .NBITS_ACC(NBITS_ACC), - .NBITS_Z(NBITS_Z) - ) dsp_full ( .a_i(a), .b_i(b), - .z_o(dsp_full_z), - .dly_b_o(dsp_full_dly_b), - - .acc_fir_i(acc_fir), + .c_i(c), .feedback_i(feedback), - .load_acc_i(load_acc), - - .unsigned_a_i(unsigned_a), - .unsigned_b_i(unsigned_b), - - .clock_i(clk), - .s_reset(reset), - - .saturate_enable_i(saturate_enable), .output_select_i(output_select), - .round_i(round), - .shift_right_i(shift_right), - .subtract_i(subtract), - .register_inputs_i(register_inputs), - .coef_0_i(COEFF_0), - .coef_1_i(COEFF_1), - .coef_2_i(COEFF_2), - .coef_3_i(COEFF_3) - ); -endmodule - -module QL_DSP2_MULT ( // TODO: Name subject to change - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, - - input wire reset, - - input wire [2:0] feedback, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [2:0] output_select, - input wire register_inputs -); - - parameter [79:0] MODE_BITS = 80'd0; - - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .clk(1'b0), - .reset(reset), - - .f_mode(f_mode), - - .feedback(feedback), - .load_acc(1'b0), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - - .output_select(output_select), // unregistered output: a * b (0) - .saturate_enable(1'b0), - .shift_right(6'b0), - .round(1'b0), - .subtract(1'b0), - .register_inputs(register_inputs) // unregistered inputs - ); - -`ifdef SDF_SIM - specify - (a[0] => z[0]) = 0; - (a[1] => z[0]) = 0; - (a[2] => z[0]) = 0; - (a[3] => z[0]) = 0; - (a[4] => z[0]) = 0; - (a[5] => z[0]) = 0; - (a[6] => z[0]) = 0; - (a[7] => z[0]) = 0; - (a[8] => z[0]) = 0; - (a[9] => z[0]) = 0; - (a[10] => z[0]) = 0; - (a[11] => z[0]) = 0; - (a[12] => z[0]) = 0; - (a[13] => z[0]) = 0; - (a[14] => z[0]) = 0; - (a[15] => z[0]) = 0; - (a[16] => z[0]) = 0; - (a[17] => z[0]) = 0; - (a[18] => z[0]) = 0; - (a[19] => z[0]) = 0; - (b[0] => z[0]) = 0; - (b[1] => z[0]) = 0; - (b[2] => z[0]) = 0; - (b[3] => z[0]) = 0; - (b[4] => z[0]) = 0; - (b[5] => z[0]) = 0; - (b[6] => z[0]) = 0; - (b[7] => z[0]) = 0; - (b[8] => z[0]) = 0; - (b[9] => z[0]) = 0; - (b[10] => z[0]) = 0; - (b[11] => z[0]) = 0; - (b[12] => z[0]) = 0; - (b[13] => z[0]) = 0; - (b[14] => z[0]) = 0; - (b[15] => z[0]) = 0; - (b[16] => z[0]) = 0; - (b[17] => z[0]) = 0; - (a[0] => z[1]) = 0; - (a[1] => z[1]) = 0; - (a[2] => z[1]) = 0; - (a[3] => z[1]) = 0; - (a[4] => z[1]) = 0; - (a[5] => z[1]) = 0; - (a[6] => z[1]) = 0; - (a[7] => z[1]) = 0; - (a[8] => z[1]) = 0; - (a[9] => z[1]) = 0; - (a[10] => z[1]) = 0; - (a[11] => z[1]) = 0; - (a[12] => z[1]) = 0; - (a[13] => z[1]) = 0; - (a[14] => z[1]) = 0; - (a[15] => z[1]) = 0; - (a[16] => z[1]) = 0; - (a[17] => z[1]) = 0; - (a[18] => z[1]) = 0; - (a[19] => z[1]) = 0; - (b[0] => z[1]) = 0; - (b[1] => z[1]) = 0; - (b[2] => z[1]) = 0; - (b[3] => z[1]) = 0; - (b[4] => z[1]) = 0; - (b[5] => z[1]) = 0; - (b[6] => z[1]) = 0; - (b[7] => z[1]) = 0; - (b[8] => z[1]) = 0; - (b[9] => z[1]) = 0; - (b[10] => z[1]) = 0; - (b[11] => z[1]) = 0; - (b[12] => z[1]) = 0; - (b[13] => z[1]) = 0; - (b[14] => z[1]) = 0; - (b[15] => z[1]) = 0; - (b[16] => z[1]) = 0; - (b[17] => z[1]) = 0; - (a[0] => z[2]) = 0; - (a[1] => z[2]) = 0; - (a[2] => z[2]) = 0; - (a[3] => z[2]) = 0; - (a[4] => z[2]) = 0; - (a[5] => z[2]) = 0; - (a[6] => z[2]) = 0; - (a[7] => z[2]) = 0; - (a[8] => z[2]) = 0; - (a[9] => z[2]) = 0; - (a[10] => z[2]) = 0; - (a[11] => z[2]) = 0; - (a[12] => z[2]) = 0; - (a[13] => z[2]) = 0; - (a[14] => z[2]) = 0; - (a[15] => z[2]) = 0; - (a[16] => z[2]) = 0; - (a[17] => z[2]) = 0; - (a[18] => z[2]) = 0; - (a[19] => z[2]) = 0; - (b[0] => z[2]) = 0; - (b[1] => z[2]) = 0; - (b[2] => z[2]) = 0; - (b[3] => z[2]) = 0; - (b[4] => z[2]) = 0; - (b[5] => z[2]) = 0; - (b[6] => z[2]) = 0; - (b[7] => z[2]) = 0; - (b[8] => z[2]) = 0; - (b[9] => z[2]) = 0; - (b[10] => z[2]) = 0; - (b[11] => z[2]) = 0; - (b[12] => z[2]) = 0; - (b[13] => z[2]) = 0; - (b[14] => z[2]) = 0; - (b[15] => z[2]) = 0; - (b[16] => z[2]) = 0; - (b[17] => z[2]) = 0; - (a[0] => z[3]) = 0; - (a[1] => z[3]) = 0; - (a[2] => z[3]) = 0; - (a[3] => z[3]) = 0; - (a[4] => z[3]) = 0; - (a[5] => z[3]) = 0; - (a[6] => z[3]) = 0; - (a[7] => z[3]) = 0; - (a[8] => z[3]) = 0; - (a[9] => z[3]) = 0; - (a[10] => z[3]) = 0; - (a[11] => z[3]) = 0; - (a[12] => z[3]) = 0; - (a[13] => z[3]) = 0; - (a[14] => z[3]) = 0; - (a[15] => z[3]) = 0; - (a[16] => z[3]) = 0; - (a[17] => z[3]) = 0; - (a[18] => z[3]) = 0; - (a[19] => z[3]) = 0; - (b[0] => z[3]) = 0; - (b[1] => z[3]) = 0; - (b[2] => z[3]) = 0; - (b[3] => z[3]) = 0; - (b[4] => z[3]) = 0; - (b[5] => z[3]) = 0; - (b[6] => z[3]) = 0; - (b[7] => z[3]) = 0; - (b[8] => z[3]) = 0; - (b[9] => z[3]) = 0; - (b[10] => z[3]) = 0; - (b[11] => z[3]) = 0; - (b[12] => z[3]) = 0; - (b[13] => z[3]) = 0; - (b[14] => z[3]) = 0; - (b[15] => z[3]) = 0; - (b[16] => z[3]) = 0; - (b[17] => z[3]) = 0; - (a[0] => z[4]) = 0; - (a[1] => z[4]) = 0; - (a[2] => z[4]) = 0; - (a[3] => z[4]) = 0; - (a[4] => z[4]) = 0; - (a[5] => z[4]) = 0; - (a[6] => z[4]) = 0; - (a[7] => z[4]) = 0; - (a[8] => z[4]) = 0; - (a[9] => z[4]) = 0; - (a[10] => z[4]) = 0; - (a[11] => z[4]) = 0; - (a[12] => z[4]) = 0; - (a[13] => z[4]) = 0; - (a[14] => z[4]) = 0; - (a[15] => z[4]) = 0; - (a[16] => z[4]) = 0; - (a[17] => z[4]) = 0; - (a[18] => z[4]) = 0; - (a[19] => z[4]) = 0; - (b[0] => z[4]) = 0; - (b[1] => z[4]) = 0; - (b[2] => z[4]) = 0; - (b[3] => z[4]) = 0; - (b[4] => z[4]) = 0; - (b[5] => z[4]) = 0; - (b[6] => z[4]) = 0; - (b[7] => z[4]) = 0; - (b[8] => z[4]) = 0; - (b[9] => z[4]) = 0; - (b[10] => z[4]) = 0; - (b[11] => z[4]) = 0; - (b[12] => z[4]) = 0; - (b[13] => z[4]) = 0; - (b[14] => z[4]) = 0; - (b[15] => z[4]) = 0; - (b[16] => z[4]) = 0; - (b[17] => z[4]) = 0; - (a[0] => z[5]) = 0; - (a[1] => z[5]) = 0; - (a[2] => z[5]) = 0; - (a[3] => z[5]) = 0; - (a[4] => z[5]) = 0; - (a[5] => z[5]) = 0; - (a[6] => z[5]) = 0; - (a[7] => z[5]) = 0; - (a[8] => z[5]) = 0; - (a[9] => z[5]) = 0; - (a[10] => z[5]) = 0; - (a[11] => z[5]) = 0; - (a[12] => z[5]) = 0; - (a[13] => z[5]) = 0; - (a[14] => z[5]) = 0; - (a[15] => z[5]) = 0; - (a[16] => z[5]) = 0; - (a[17] => z[5]) = 0; - (a[18] => z[5]) = 0; - (a[19] => z[5]) = 0; - (b[0] => z[5]) = 0; - (b[1] => z[5]) = 0; - (b[2] => z[5]) = 0; - (b[3] => z[5]) = 0; - (b[4] => z[5]) = 0; - (b[5] => z[5]) = 0; - (b[6] => z[5]) = 0; - (b[7] => z[5]) = 0; - (b[8] => z[5]) = 0; - (b[9] => z[5]) = 0; - (b[10] => z[5]) = 0; - (b[11] => z[5]) = 0; - (b[12] => z[5]) = 0; - (b[13] => z[5]) = 0; - (b[14] => z[5]) = 0; - (b[15] => z[5]) = 0; - (b[16] => z[5]) = 0; - (b[17] => z[5]) = 0; - (a[0] => z[6]) = 0; - (a[1] => z[6]) = 0; - (a[2] => z[6]) = 0; - (a[3] => z[6]) = 0; - (a[4] => z[6]) = 0; - (a[5] => z[6]) = 0; - (a[6] => z[6]) = 0; - (a[7] => z[6]) = 0; - (a[8] => z[6]) = 0; - (a[9] => z[6]) = 0; - (a[10] => z[6]) = 0; - (a[11] => z[6]) = 0; - (a[12] => z[6]) = 0; - (a[13] => z[6]) = 0; - (a[14] => z[6]) = 0; - (a[15] => z[6]) = 0; - (a[16] => z[6]) = 0; - (a[17] => z[6]) = 0; - (a[18] => z[6]) = 0; - (a[19] => z[6]) = 0; - (b[0] => z[6]) = 0; - (b[1] => z[6]) = 0; - (b[2] => z[6]) = 0; - (b[3] => z[6]) = 0; - (b[4] => z[6]) = 0; - (b[5] => z[6]) = 0; - (b[6] => z[6]) = 0; - (b[7] => z[6]) = 0; - (b[8] => z[6]) = 0; - (b[9] => z[6]) = 0; - (b[10] => z[6]) = 0; - (b[11] => z[6]) = 0; - (b[12] => z[6]) = 0; - (b[13] => z[6]) = 0; - (b[14] => z[6]) = 0; - (b[15] => z[6]) = 0; - (b[16] => z[6]) = 0; - (b[17] => z[6]) = 0; - (a[0] => z[7]) = 0; - (a[1] => z[7]) = 0; - (a[2] => z[7]) = 0; - (a[3] => z[7]) = 0; - (a[4] => z[7]) = 0; - (a[5] => z[7]) = 0; - (a[6] => z[7]) = 0; - (a[7] => z[7]) = 0; - (a[8] => z[7]) = 0; - (a[9] => z[7]) = 0; - (a[10] => z[7]) = 0; - (a[11] => z[7]) = 0; - (a[12] => z[7]) = 0; - (a[13] => z[7]) = 0; - (a[14] => z[7]) = 0; - (a[15] => z[7]) = 0; - (a[16] => z[7]) = 0; - (a[17] => z[7]) = 0; - (a[18] => z[7]) = 0; - (a[19] => z[7]) = 0; - (b[0] => z[7]) = 0; - (b[1] => z[7]) = 0; - (b[2] => z[7]) = 0; - (b[3] => z[7]) = 0; - (b[4] => z[7]) = 0; - (b[5] => z[7]) = 0; - (b[6] => z[7]) = 0; - (b[7] => z[7]) = 0; - (b[8] => z[7]) = 0; - (b[9] => z[7]) = 0; - (b[10] => z[7]) = 0; - (b[11] => z[7]) = 0; - (b[12] => z[7]) = 0; - (b[13] => z[7]) = 0; - (b[14] => z[7]) = 0; - (b[15] => z[7]) = 0; - (b[16] => z[7]) = 0; - (b[17] => z[7]) = 0; - (a[0] => z[8]) = 0; - (a[1] => z[8]) = 0; - (a[2] => z[8]) = 0; - (a[3] => z[8]) = 0; - (a[4] => z[8]) = 0; - (a[5] => z[8]) = 0; - (a[6] => z[8]) = 0; - (a[7] => z[8]) = 0; - (a[8] => z[8]) = 0; - (a[9] => z[8]) = 0; - (a[10] => z[8]) = 0; - (a[11] => z[8]) = 0; - (a[12] => z[8]) = 0; - (a[13] => z[8]) = 0; - (a[14] => z[8]) = 0; - (a[15] => z[8]) = 0; - (a[16] => z[8]) = 0; - (a[17] => z[8]) = 0; - (a[18] => z[8]) = 0; - (a[19] => z[8]) = 0; - (b[0] => z[8]) = 0; - (b[1] => z[8]) = 0; - (b[2] => z[8]) = 0; - (b[3] => z[8]) = 0; - (b[4] => z[8]) = 0; - (b[5] => z[8]) = 0; - (b[6] => z[8]) = 0; - (b[7] => z[8]) = 0; - (b[8] => z[8]) = 0; - (b[9] => z[8]) = 0; - (b[10] => z[8]) = 0; - (b[11] => z[8]) = 0; - (b[12] => z[8]) = 0; - (b[13] => z[8]) = 0; - (b[14] => z[8]) = 0; - (b[15] => z[8]) = 0; - (b[16] => z[8]) = 0; - (b[17] => z[8]) = 0; - (a[0] => z[9]) = 0; - (a[1] => z[9]) = 0; - (a[2] => z[9]) = 0; - (a[3] => z[9]) = 0; - (a[4] => z[9]) = 0; - (a[5] => z[9]) = 0; - (a[6] => z[9]) = 0; - (a[7] => z[9]) = 0; - (a[8] => z[9]) = 0; - (a[9] => z[9]) = 0; - (a[10] => z[9]) = 0; - (a[11] => z[9]) = 0; - (a[12] => z[9]) = 0; - (a[13] => z[9]) = 0; - (a[14] => z[9]) = 0; - (a[15] => z[9]) = 0; - (a[16] => z[9]) = 0; - (a[17] => z[9]) = 0; - (a[18] => z[9]) = 0; - (a[19] => z[9]) = 0; - (b[0] => z[9]) = 0; - (b[1] => z[9]) = 0; - (b[2] => z[9]) = 0; - (b[3] => z[9]) = 0; - (b[4] => z[9]) = 0; - (b[5] => z[9]) = 0; - (b[6] => z[9]) = 0; - (b[7] => z[9]) = 0; - (b[8] => z[9]) = 0; - (b[9] => z[9]) = 0; - (b[10] => z[9]) = 0; - (b[11] => z[9]) = 0; - (b[12] => z[9]) = 0; - (b[13] => z[9]) = 0; - (b[14] => z[9]) = 0; - (b[15] => z[9]) = 0; - (b[16] => z[9]) = 0; - (b[17] => z[9]) = 0; - (a[0] => z[10]) = 0; - (a[1] => z[10]) = 0; - (a[2] => z[10]) = 0; - (a[3] => z[10]) = 0; - (a[4] => z[10]) = 0; - (a[5] => z[10]) = 0; - (a[6] => z[10]) = 0; - (a[7] => z[10]) = 0; - (a[8] => z[10]) = 0; - (a[9] => z[10]) = 0; - (a[10] => z[10]) = 0; - (a[11] => z[10]) = 0; - (a[12] => z[10]) = 0; - (a[13] => z[10]) = 0; - (a[14] => z[10]) = 0; - (a[15] => z[10]) = 0; - (a[16] => z[10]) = 0; - (a[17] => z[10]) = 0; - (a[18] => z[10]) = 0; - (a[19] => z[10]) = 0; - (b[0] => z[10]) = 0; - (b[1] => z[10]) = 0; - (b[2] => z[10]) = 0; - (b[3] => z[10]) = 0; - (b[4] => z[10]) = 0; - (b[5] => z[10]) = 0; - (b[6] => z[10]) = 0; - (b[7] => z[10]) = 0; - (b[8] => z[10]) = 0; - (b[9] => z[10]) = 0; - (b[10] => z[10]) = 0; - (b[11] => z[10]) = 0; - (b[12] => z[10]) = 0; - (b[13] => z[10]) = 0; - (b[14] => z[10]) = 0; - (b[15] => z[10]) = 0; - (b[16] => z[10]) = 0; - (b[17] => z[10]) = 0; - (a[0] => z[11]) = 0; - (a[1] => z[11]) = 0; - (a[2] => z[11]) = 0; - (a[3] => z[11]) = 0; - (a[4] => z[11]) = 0; - (a[5] => z[11]) = 0; - (a[6] => z[11]) = 0; - (a[7] => z[11]) = 0; - (a[8] => z[11]) = 0; - (a[9] => z[11]) = 0; - (a[10] => z[11]) = 0; - (a[11] => z[11]) = 0; - (a[12] => z[11]) = 0; - (a[13] => z[11]) = 0; - (a[14] => z[11]) = 0; - (a[15] => z[11]) = 0; - (a[16] => z[11]) = 0; - (a[17] => z[11]) = 0; - (a[18] => z[11]) = 0; - (a[19] => z[11]) = 0; - (b[0] => z[11]) = 0; - (b[1] => z[11]) = 0; - (b[2] => z[11]) = 0; - (b[3] => z[11]) = 0; - (b[4] => z[11]) = 0; - (b[5] => z[11]) = 0; - (b[6] => z[11]) = 0; - (b[7] => z[11]) = 0; - (b[8] => z[11]) = 0; - (b[9] => z[11]) = 0; - (b[10] => z[11]) = 0; - (b[11] => z[11]) = 0; - (b[12] => z[11]) = 0; - (b[13] => z[11]) = 0; - (b[14] => z[11]) = 0; - (b[15] => z[11]) = 0; - (b[16] => z[11]) = 0; - (b[17] => z[11]) = 0; - (a[0] => z[12]) = 0; - (a[1] => z[12]) = 0; - (a[2] => z[12]) = 0; - (a[3] => z[12]) = 0; - (a[4] => z[12]) = 0; - (a[5] => z[12]) = 0; - (a[6] => z[12]) = 0; - (a[7] => z[12]) = 0; - (a[8] => z[12]) = 0; - (a[9] => z[12]) = 0; - (a[10] => z[12]) = 0; - (a[11] => z[12]) = 0; - (a[12] => z[12]) = 0; - (a[13] => z[12]) = 0; - (a[14] => z[12]) = 0; - (a[15] => z[12]) = 0; - (a[16] => z[12]) = 0; - (a[17] => z[12]) = 0; - (a[18] => z[12]) = 0; - (a[19] => z[12]) = 0; - (b[0] => z[12]) = 0; - (b[1] => z[12]) = 0; - (b[2] => z[12]) = 0; - (b[3] => z[12]) = 0; - (b[4] => z[12]) = 0; - (b[5] => z[12]) = 0; - (b[6] => z[12]) = 0; - (b[7] => z[12]) = 0; - (b[8] => z[12]) = 0; - (b[9] => z[12]) = 0; - (b[10] => z[12]) = 0; - (b[11] => z[12]) = 0; - (b[12] => z[12]) = 0; - (b[13] => z[12]) = 0; - (b[14] => z[12]) = 0; - (b[15] => z[12]) = 0; - (b[16] => z[12]) = 0; - (b[17] => z[12]) = 0; - (a[0] => z[13]) = 0; - (a[1] => z[13]) = 0; - (a[2] => z[13]) = 0; - (a[3] => z[13]) = 0; - (a[4] => z[13]) = 0; - (a[5] => z[13]) = 0; - (a[6] => z[13]) = 0; - (a[7] => z[13]) = 0; - (a[8] => z[13]) = 0; - (a[9] => z[13]) = 0; - (a[10] => z[13]) = 0; - (a[11] => z[13]) = 0; - (a[12] => z[13]) = 0; - (a[13] => z[13]) = 0; - (a[14] => z[13]) = 0; - (a[15] => z[13]) = 0; - (a[16] => z[13]) = 0; - (a[17] => z[13]) = 0; - (a[18] => z[13]) = 0; - (a[19] => z[13]) = 0; - (b[0] => z[13]) = 0; - (b[1] => z[13]) = 0; - (b[2] => z[13]) = 0; - (b[3] => z[13]) = 0; - (b[4] => z[13]) = 0; - (b[5] => z[13]) = 0; - (b[6] => z[13]) = 0; - (b[7] => z[13]) = 0; - (b[8] => z[13]) = 0; - (b[9] => z[13]) = 0; - (b[10] => z[13]) = 0; - (b[11] => z[13]) = 0; - (b[12] => z[13]) = 0; - (b[13] => z[13]) = 0; - (b[14] => z[13]) = 0; - (b[15] => z[13]) = 0; - (b[16] => z[13]) = 0; - (b[17] => z[13]) = 0; - (a[0] => z[14]) = 0; - (a[1] => z[14]) = 0; - (a[2] => z[14]) = 0; - (a[3] => z[14]) = 0; - (a[4] => z[14]) = 0; - (a[5] => z[14]) = 0; - (a[6] => z[14]) = 0; - (a[7] => z[14]) = 0; - (a[8] => z[14]) = 0; - (a[9] => z[14]) = 0; - (a[10] => z[14]) = 0; - (a[11] => z[14]) = 0; - (a[12] => z[14]) = 0; - (a[13] => z[14]) = 0; - (a[14] => z[14]) = 0; - (a[15] => z[14]) = 0; - (a[16] => z[14]) = 0; - (a[17] => z[14]) = 0; - (a[18] => z[14]) = 0; - (a[19] => z[14]) = 0; - (b[0] => z[14]) = 0; - (b[1] => z[14]) = 0; - (b[2] => z[14]) = 0; - (b[3] => z[14]) = 0; - (b[4] => z[14]) = 0; - (b[5] => z[14]) = 0; - (b[6] => z[14]) = 0; - (b[7] => z[14]) = 0; - (b[8] => z[14]) = 0; - (b[9] => z[14]) = 0; - (b[10] => z[14]) = 0; - (b[11] => z[14]) = 0; - (b[12] => z[14]) = 0; - (b[13] => z[14]) = 0; - (b[14] => z[14]) = 0; - (b[15] => z[14]) = 0; - (b[16] => z[14]) = 0; - (b[17] => z[14]) = 0; - (a[0] => z[15]) = 0; - (a[1] => z[15]) = 0; - (a[2] => z[15]) = 0; - (a[3] => z[15]) = 0; - (a[4] => z[15]) = 0; - (a[5] => z[15]) = 0; - (a[6] => z[15]) = 0; - (a[7] => z[15]) = 0; - (a[8] => z[15]) = 0; - (a[9] => z[15]) = 0; - (a[10] => z[15]) = 0; - (a[11] => z[15]) = 0; - (a[12] => z[15]) = 0; - (a[13] => z[15]) = 0; - (a[14] => z[15]) = 0; - (a[15] => z[15]) = 0; - (a[16] => z[15]) = 0; - (a[17] => z[15]) = 0; - (a[18] => z[15]) = 0; - (a[19] => z[15]) = 0; - (b[0] => z[15]) = 0; - (b[1] => z[15]) = 0; - (b[2] => z[15]) = 0; - (b[3] => z[15]) = 0; - (b[4] => z[15]) = 0; - (b[5] => z[15]) = 0; - (b[6] => z[15]) = 0; - (b[7] => z[15]) = 0; - (b[8] => z[15]) = 0; - (b[9] => z[15]) = 0; - (b[10] => z[15]) = 0; - (b[11] => z[15]) = 0; - (b[12] => z[15]) = 0; - (b[13] => z[15]) = 0; - (b[14] => z[15]) = 0; - (b[15] => z[15]) = 0; - (b[16] => z[15]) = 0; - (b[17] => z[15]) = 0; - (a[0] => z[16]) = 0; - (a[1] => z[16]) = 0; - (a[2] => z[16]) = 0; - (a[3] => z[16]) = 0; - (a[4] => z[16]) = 0; - (a[5] => z[16]) = 0; - (a[6] => z[16]) = 0; - (a[7] => z[16]) = 0; - (a[8] => z[16]) = 0; - (a[9] => z[16]) = 0; - (a[10] => z[16]) = 0; - (a[11] => z[16]) = 0; - (a[12] => z[16]) = 0; - (a[13] => z[16]) = 0; - (a[14] => z[16]) = 0; - (a[15] => z[16]) = 0; - (a[16] => z[16]) = 0; - (a[17] => z[16]) = 0; - (a[18] => z[16]) = 0; - (a[19] => z[16]) = 0; - (b[0] => z[16]) = 0; - (b[1] => z[16]) = 0; - (b[2] => z[16]) = 0; - (b[3] => z[16]) = 0; - (b[4] => z[16]) = 0; - (b[5] => z[16]) = 0; - (b[6] => z[16]) = 0; - (b[7] => z[16]) = 0; - (b[8] => z[16]) = 0; - (b[9] => z[16]) = 0; - (b[10] => z[16]) = 0; - (b[11] => z[16]) = 0; - (b[12] => z[16]) = 0; - (b[13] => z[16]) = 0; - (b[14] => z[16]) = 0; - (b[15] => z[16]) = 0; - (b[16] => z[16]) = 0; - (b[17] => z[16]) = 0; - (a[0] => z[17]) = 0; - (a[1] => z[17]) = 0; - (a[2] => z[17]) = 0; - (a[3] => z[17]) = 0; - (a[4] => z[17]) = 0; - (a[5] => z[17]) = 0; - (a[6] => z[17]) = 0; - (a[7] => z[17]) = 0; - (a[8] => z[17]) = 0; - (a[9] => z[17]) = 0; - (a[10] => z[17]) = 0; - (a[11] => z[17]) = 0; - (a[12] => z[17]) = 0; - (a[13] => z[17]) = 0; - (a[14] => z[17]) = 0; - (a[15] => z[17]) = 0; - (a[16] => z[17]) = 0; - (a[17] => z[17]) = 0; - (a[18] => z[17]) = 0; - (a[19] => z[17]) = 0; - (b[0] => z[17]) = 0; - (b[1] => z[17]) = 0; - (b[2] => z[17]) = 0; - (b[3] => z[17]) = 0; - (b[4] => z[17]) = 0; - (b[5] => z[17]) = 0; - (b[6] => z[17]) = 0; - (b[7] => z[17]) = 0; - (b[8] => z[17]) = 0; - (b[9] => z[17]) = 0; - (b[10] => z[17]) = 0; - (b[11] => z[17]) = 0; - (b[12] => z[17]) = 0; - (b[13] => z[17]) = 0; - (b[14] => z[17]) = 0; - (b[15] => z[17]) = 0; - (b[16] => z[17]) = 0; - (b[17] => z[17]) = 0; - (a[0] => z[18]) = 0; - (a[1] => z[18]) = 0; - (a[2] => z[18]) = 0; - (a[3] => z[18]) = 0; - (a[4] => z[18]) = 0; - (a[5] => z[18]) = 0; - (a[6] => z[18]) = 0; - (a[7] => z[18]) = 0; - (a[8] => z[18]) = 0; - (a[9] => z[18]) = 0; - (a[10] => z[18]) = 0; - (a[11] => z[18]) = 0; - (a[12] => z[18]) = 0; - (a[13] => z[18]) = 0; - (a[14] => z[18]) = 0; - (a[15] => z[18]) = 0; - (a[16] => z[18]) = 0; - (a[17] => z[18]) = 0; - (a[18] => z[18]) = 0; - (a[19] => z[18]) = 0; - (b[0] => z[18]) = 0; - (b[1] => z[18]) = 0; - (b[2] => z[18]) = 0; - (b[3] => z[18]) = 0; - (b[4] => z[18]) = 0; - (b[5] => z[18]) = 0; - (b[6] => z[18]) = 0; - (b[7] => z[18]) = 0; - (b[8] => z[18]) = 0; - (b[9] => z[18]) = 0; - (b[10] => z[18]) = 0; - (b[11] => z[18]) = 0; - (b[12] => z[18]) = 0; - (b[13] => z[18]) = 0; - (b[14] => z[18]) = 0; - (b[15] => z[18]) = 0; - (b[16] => z[18]) = 0; - (b[17] => z[18]) = 0; - (a[0] => z[19]) = 0; - (a[1] => z[19]) = 0; - (a[2] => z[19]) = 0; - (a[3] => z[19]) = 0; - (a[4] => z[19]) = 0; - (a[5] => z[19]) = 0; - (a[6] => z[19]) = 0; - (a[7] => z[19]) = 0; - (a[8] => z[19]) = 0; - (a[9] => z[19]) = 0; - (a[10] => z[19]) = 0; - (a[11] => z[19]) = 0; - (a[12] => z[19]) = 0; - (a[13] => z[19]) = 0; - (a[14] => z[19]) = 0; - (a[15] => z[19]) = 0; - (a[16] => z[19]) = 0; - (a[17] => z[19]) = 0; - (a[18] => z[19]) = 0; - (a[19] => z[19]) = 0; - (b[0] => z[19]) = 0; - (b[1] => z[19]) = 0; - (b[2] => z[19]) = 0; - (b[3] => z[19]) = 0; - (b[4] => z[19]) = 0; - (b[5] => z[19]) = 0; - (b[6] => z[19]) = 0; - (b[7] => z[19]) = 0; - (b[8] => z[19]) = 0; - (b[9] => z[19]) = 0; - (b[10] => z[19]) = 0; - (b[11] => z[19]) = 0; - (b[12] => z[19]) = 0; - (b[13] => z[19]) = 0; - (b[14] => z[19]) = 0; - (b[15] => z[19]) = 0; - (b[16] => z[19]) = 0; - (b[17] => z[19]) = 0; - (a[0] => z[20]) = 0; - (a[1] => z[20]) = 0; - (a[2] => z[20]) = 0; - (a[3] => z[20]) = 0; - (a[4] => z[20]) = 0; - (a[5] => z[20]) = 0; - (a[6] => z[20]) = 0; - (a[7] => z[20]) = 0; - (a[8] => z[20]) = 0; - (a[9] => z[20]) = 0; - (a[10] => z[20]) = 0; - (a[11] => z[20]) = 0; - (a[12] => z[20]) = 0; - (a[13] => z[20]) = 0; - (a[14] => z[20]) = 0; - (a[15] => z[20]) = 0; - (a[16] => z[20]) = 0; - (a[17] => z[20]) = 0; - (a[18] => z[20]) = 0; - (a[19] => z[20]) = 0; - (b[0] => z[20]) = 0; - (b[1] => z[20]) = 0; - (b[2] => z[20]) = 0; - (b[3] => z[20]) = 0; - (b[4] => z[20]) = 0; - (b[5] => z[20]) = 0; - (b[6] => z[20]) = 0; - (b[7] => z[20]) = 0; - (b[8] => z[20]) = 0; - (b[9] => z[20]) = 0; - (b[10] => z[20]) = 0; - (b[11] => z[20]) = 0; - (b[12] => z[20]) = 0; - (b[13] => z[20]) = 0; - (b[14] => z[20]) = 0; - (b[15] => z[20]) = 0; - (b[16] => z[20]) = 0; - (b[17] => z[20]) = 0; - (a[0] => z[21]) = 0; - (a[1] => z[21]) = 0; - (a[2] => z[21]) = 0; - (a[3] => z[21]) = 0; - (a[4] => z[21]) = 0; - (a[5] => z[21]) = 0; - (a[6] => z[21]) = 0; - (a[7] => z[21]) = 0; - (a[8] => z[21]) = 0; - (a[9] => z[21]) = 0; - (a[10] => z[21]) = 0; - (a[11] => z[21]) = 0; - (a[12] => z[21]) = 0; - (a[13] => z[21]) = 0; - (a[14] => z[21]) = 0; - (a[15] => z[21]) = 0; - (a[16] => z[21]) = 0; - (a[17] => z[21]) = 0; - (a[18] => z[21]) = 0; - (a[19] => z[21]) = 0; - (b[0] => z[21]) = 0; - (b[1] => z[21]) = 0; - (b[2] => z[21]) = 0; - (b[3] => z[21]) = 0; - (b[4] => z[21]) = 0; - (b[5] => z[21]) = 0; - (b[6] => z[21]) = 0; - (b[7] => z[21]) = 0; - (b[8] => z[21]) = 0; - (b[9] => z[21]) = 0; - (b[10] => z[21]) = 0; - (b[11] => z[21]) = 0; - (b[12] => z[21]) = 0; - (b[13] => z[21]) = 0; - (b[14] => z[21]) = 0; - (b[15] => z[21]) = 0; - (b[16] => z[21]) = 0; - (b[17] => z[21]) = 0; - (a[0] => z[22]) = 0; - (a[1] => z[22]) = 0; - (a[2] => z[22]) = 0; - (a[3] => z[22]) = 0; - (a[4] => z[22]) = 0; - (a[5] => z[22]) = 0; - (a[6] => z[22]) = 0; - (a[7] => z[22]) = 0; - (a[8] => z[22]) = 0; - (a[9] => z[22]) = 0; - (a[10] => z[22]) = 0; - (a[11] => z[22]) = 0; - (a[12] => z[22]) = 0; - (a[13] => z[22]) = 0; - (a[14] => z[22]) = 0; - (a[15] => z[22]) = 0; - (a[16] => z[22]) = 0; - (a[17] => z[22]) = 0; - (a[18] => z[22]) = 0; - (a[19] => z[22]) = 0; - (b[0] => z[22]) = 0; - (b[1] => z[22]) = 0; - (b[2] => z[22]) = 0; - (b[3] => z[22]) = 0; - (b[4] => z[22]) = 0; - (b[5] => z[22]) = 0; - (b[6] => z[22]) = 0; - (b[7] => z[22]) = 0; - (b[8] => z[22]) = 0; - (b[9] => z[22]) = 0; - (b[10] => z[22]) = 0; - (b[11] => z[22]) = 0; - (b[12] => z[22]) = 0; - (b[13] => z[22]) = 0; - (b[14] => z[22]) = 0; - (b[15] => z[22]) = 0; - (b[16] => z[22]) = 0; - (b[17] => z[22]) = 0; - (a[0] => z[23]) = 0; - (a[1] => z[23]) = 0; - (a[2] => z[23]) = 0; - (a[3] => z[23]) = 0; - (a[4] => z[23]) = 0; - (a[5] => z[23]) = 0; - (a[6] => z[23]) = 0; - (a[7] => z[23]) = 0; - (a[8] => z[23]) = 0; - (a[9] => z[23]) = 0; - (a[10] => z[23]) = 0; - (a[11] => z[23]) = 0; - (a[12] => z[23]) = 0; - (a[13] => z[23]) = 0; - (a[14] => z[23]) = 0; - (a[15] => z[23]) = 0; - (a[16] => z[23]) = 0; - (a[17] => z[23]) = 0; - (a[18] => z[23]) = 0; - (a[19] => z[23]) = 0; - (b[0] => z[23]) = 0; - (b[1] => z[23]) = 0; - (b[2] => z[23]) = 0; - (b[3] => z[23]) = 0; - (b[4] => z[23]) = 0; - (b[5] => z[23]) = 0; - (b[6] => z[23]) = 0; - (b[7] => z[23]) = 0; - (b[8] => z[23]) = 0; - (b[9] => z[23]) = 0; - (b[10] => z[23]) = 0; - (b[11] => z[23]) = 0; - (b[12] => z[23]) = 0; - (b[13] => z[23]) = 0; - (b[14] => z[23]) = 0; - (b[15] => z[23]) = 0; - (b[16] => z[23]) = 0; - (b[17] => z[23]) = 0; - (a[0] => z[24]) = 0; - (a[1] => z[24]) = 0; - (a[2] => z[24]) = 0; - (a[3] => z[24]) = 0; - (a[4] => z[24]) = 0; - (a[5] => z[24]) = 0; - (a[6] => z[24]) = 0; - (a[7] => z[24]) = 0; - (a[8] => z[24]) = 0; - (a[9] => z[24]) = 0; - (a[10] => z[24]) = 0; - (a[11] => z[24]) = 0; - (a[12] => z[24]) = 0; - (a[13] => z[24]) = 0; - (a[14] => z[24]) = 0; - (a[15] => z[24]) = 0; - (a[16] => z[24]) = 0; - (a[17] => z[24]) = 0; - (a[18] => z[24]) = 0; - (a[19] => z[24]) = 0; - (b[0] => z[24]) = 0; - (b[1] => z[24]) = 0; - (b[2] => z[24]) = 0; - (b[3] => z[24]) = 0; - (b[4] => z[24]) = 0; - (b[5] => z[24]) = 0; - (b[6] => z[24]) = 0; - (b[7] => z[24]) = 0; - (b[8] => z[24]) = 0; - (b[9] => z[24]) = 0; - (b[10] => z[24]) = 0; - (b[11] => z[24]) = 0; - (b[12] => z[24]) = 0; - (b[13] => z[24]) = 0; - (b[14] => z[24]) = 0; - (b[15] => z[24]) = 0; - (b[16] => z[24]) = 0; - (b[17] => z[24]) = 0; - (a[0] => z[25]) = 0; - (a[1] => z[25]) = 0; - (a[2] => z[25]) = 0; - (a[3] => z[25]) = 0; - (a[4] => z[25]) = 0; - (a[5] => z[25]) = 0; - (a[6] => z[25]) = 0; - (a[7] => z[25]) = 0; - (a[8] => z[25]) = 0; - (a[9] => z[25]) = 0; - (a[10] => z[25]) = 0; - (a[11] => z[25]) = 0; - (a[12] => z[25]) = 0; - (a[13] => z[25]) = 0; - (a[14] => z[25]) = 0; - (a[15] => z[25]) = 0; - (a[16] => z[25]) = 0; - (a[17] => z[25]) = 0; - (a[18] => z[25]) = 0; - (a[19] => z[25]) = 0; - (b[0] => z[25]) = 0; - (b[1] => z[25]) = 0; - (b[2] => z[25]) = 0; - (b[3] => z[25]) = 0; - (b[4] => z[25]) = 0; - (b[5] => z[25]) = 0; - (b[6] => z[25]) = 0; - (b[7] => z[25]) = 0; - (b[8] => z[25]) = 0; - (b[9] => z[25]) = 0; - (b[10] => z[25]) = 0; - (b[11] => z[25]) = 0; - (b[12] => z[25]) = 0; - (b[13] => z[25]) = 0; - (b[14] => z[25]) = 0; - (b[15] => z[25]) = 0; - (b[16] => z[25]) = 0; - (b[17] => z[25]) = 0; - (a[0] => z[26]) = 0; - (a[1] => z[26]) = 0; - (a[2] => z[26]) = 0; - (a[3] => z[26]) = 0; - (a[4] => z[26]) = 0; - (a[5] => z[26]) = 0; - (a[6] => z[26]) = 0; - (a[7] => z[26]) = 0; - (a[8] => z[26]) = 0; - (a[9] => z[26]) = 0; - (a[10] => z[26]) = 0; - (a[11] => z[26]) = 0; - (a[12] => z[26]) = 0; - (a[13] => z[26]) = 0; - (a[14] => z[26]) = 0; - (a[15] => z[26]) = 0; - (a[16] => z[26]) = 0; - (a[17] => z[26]) = 0; - (a[18] => z[26]) = 0; - (a[19] => z[26]) = 0; - (b[0] => z[26]) = 0; - (b[1] => z[26]) = 0; - (b[2] => z[26]) = 0; - (b[3] => z[26]) = 0; - (b[4] => z[26]) = 0; - (b[5] => z[26]) = 0; - (b[6] => z[26]) = 0; - (b[7] => z[26]) = 0; - (b[8] => z[26]) = 0; - (b[9] => z[26]) = 0; - (b[10] => z[26]) = 0; - (b[11] => z[26]) = 0; - (b[12] => z[26]) = 0; - (b[13] => z[26]) = 0; - (b[14] => z[26]) = 0; - (b[15] => z[26]) = 0; - (b[16] => z[26]) = 0; - (b[17] => z[26]) = 0; - (a[0] => z[27]) = 0; - (a[1] => z[27]) = 0; - (a[2] => z[27]) = 0; - (a[3] => z[27]) = 0; - (a[4] => z[27]) = 0; - (a[5] => z[27]) = 0; - (a[6] => z[27]) = 0; - (a[7] => z[27]) = 0; - (a[8] => z[27]) = 0; - (a[9] => z[27]) = 0; - (a[10] => z[27]) = 0; - (a[11] => z[27]) = 0; - (a[12] => z[27]) = 0; - (a[13] => z[27]) = 0; - (a[14] => z[27]) = 0; - (a[15] => z[27]) = 0; - (a[16] => z[27]) = 0; - (a[17] => z[27]) = 0; - (a[18] => z[27]) = 0; - (a[19] => z[27]) = 0; - (b[0] => z[27]) = 0; - (b[1] => z[27]) = 0; - (b[2] => z[27]) = 0; - (b[3] => z[27]) = 0; - (b[4] => z[27]) = 0; - (b[5] => z[27]) = 0; - (b[6] => z[27]) = 0; - (b[7] => z[27]) = 0; - (b[8] => z[27]) = 0; - (b[9] => z[27]) = 0; - (b[10] => z[27]) = 0; - (b[11] => z[27]) = 0; - (b[12] => z[27]) = 0; - (b[13] => z[27]) = 0; - (b[14] => z[27]) = 0; - (b[15] => z[27]) = 0; - (b[16] => z[27]) = 0; - (b[17] => z[27]) = 0; - (a[0] => z[28]) = 0; - (a[1] => z[28]) = 0; - (a[2] => z[28]) = 0; - (a[3] => z[28]) = 0; - (a[4] => z[28]) = 0; - (a[5] => z[28]) = 0; - (a[6] => z[28]) = 0; - (a[7] => z[28]) = 0; - (a[8] => z[28]) = 0; - (a[9] => z[28]) = 0; - (a[10] => z[28]) = 0; - (a[11] => z[28]) = 0; - (a[12] => z[28]) = 0; - (a[13] => z[28]) = 0; - (a[14] => z[28]) = 0; - (a[15] => z[28]) = 0; - (a[16] => z[28]) = 0; - (a[17] => z[28]) = 0; - (a[18] => z[28]) = 0; - (a[19] => z[28]) = 0; - (b[0] => z[28]) = 0; - (b[1] => z[28]) = 0; - (b[2] => z[28]) = 0; - (b[3] => z[28]) = 0; - (b[4] => z[28]) = 0; - (b[5] => z[28]) = 0; - (b[6] => z[28]) = 0; - (b[7] => z[28]) = 0; - (b[8] => z[28]) = 0; - (b[9] => z[28]) = 0; - (b[10] => z[28]) = 0; - (b[11] => z[28]) = 0; - (b[12] => z[28]) = 0; - (b[13] => z[28]) = 0; - (b[14] => z[28]) = 0; - (b[15] => z[28]) = 0; - (b[16] => z[28]) = 0; - (b[17] => z[28]) = 0; - (a[0] => z[29]) = 0; - (a[1] => z[29]) = 0; - (a[2] => z[29]) = 0; - (a[3] => z[29]) = 0; - (a[4] => z[29]) = 0; - (a[5] => z[29]) = 0; - (a[6] => z[29]) = 0; - (a[7] => z[29]) = 0; - (a[8] => z[29]) = 0; - (a[9] => z[29]) = 0; - (a[10] => z[29]) = 0; - (a[11] => z[29]) = 0; - (a[12] => z[29]) = 0; - (a[13] => z[29]) = 0; - (a[14] => z[29]) = 0; - (a[15] => z[29]) = 0; - (a[16] => z[29]) = 0; - (a[17] => z[29]) = 0; - (a[18] => z[29]) = 0; - (a[19] => z[29]) = 0; - (b[0] => z[29]) = 0; - (b[1] => z[29]) = 0; - (b[2] => z[29]) = 0; - (b[3] => z[29]) = 0; - (b[4] => z[29]) = 0; - (b[5] => z[29]) = 0; - (b[6] => z[29]) = 0; - (b[7] => z[29]) = 0; - (b[8] => z[29]) = 0; - (b[9] => z[29]) = 0; - (b[10] => z[29]) = 0; - (b[11] => z[29]) = 0; - (b[12] => z[29]) = 0; - (b[13] => z[29]) = 0; - (b[14] => z[29]) = 0; - (b[15] => z[29]) = 0; - (b[16] => z[29]) = 0; - (b[17] => z[29]) = 0; - (a[0] => z[30]) = 0; - (a[1] => z[30]) = 0; - (a[2] => z[30]) = 0; - (a[3] => z[30]) = 0; - (a[4] => z[30]) = 0; - (a[5] => z[30]) = 0; - (a[6] => z[30]) = 0; - (a[7] => z[30]) = 0; - (a[8] => z[30]) = 0; - (a[9] => z[30]) = 0; - (a[10] => z[30]) = 0; - (a[11] => z[30]) = 0; - (a[12] => z[30]) = 0; - (a[13] => z[30]) = 0; - (a[14] => z[30]) = 0; - (a[15] => z[30]) = 0; - (a[16] => z[30]) = 0; - (a[17] => z[30]) = 0; - (a[18] => z[30]) = 0; - (a[19] => z[30]) = 0; - (b[0] => z[30]) = 0; - (b[1] => z[30]) = 0; - (b[2] => z[30]) = 0; - (b[3] => z[30]) = 0; - (b[4] => z[30]) = 0; - (b[5] => z[30]) = 0; - (b[6] => z[30]) = 0; - (b[7] => z[30]) = 0; - (b[8] => z[30]) = 0; - (b[9] => z[30]) = 0; - (b[10] => z[30]) = 0; - (b[11] => z[30]) = 0; - (b[12] => z[30]) = 0; - (b[13] => z[30]) = 0; - (b[14] => z[30]) = 0; - (b[15] => z[30]) = 0; - (b[16] => z[30]) = 0; - (b[17] => z[30]) = 0; - (a[0] => z[31]) = 0; - (a[1] => z[31]) = 0; - (a[2] => z[31]) = 0; - (a[3] => z[31]) = 0; - (a[4] => z[31]) = 0; - (a[5] => z[31]) = 0; - (a[6] => z[31]) = 0; - (a[7] => z[31]) = 0; - (a[8] => z[31]) = 0; - (a[9] => z[31]) = 0; - (a[10] => z[31]) = 0; - (a[11] => z[31]) = 0; - (a[12] => z[31]) = 0; - (a[13] => z[31]) = 0; - (a[14] => z[31]) = 0; - (a[15] => z[31]) = 0; - (a[16] => z[31]) = 0; - (a[17] => z[31]) = 0; - (a[18] => z[31]) = 0; - (a[19] => z[31]) = 0; - (b[0] => z[31]) = 0; - (b[1] => z[31]) = 0; - (b[2] => z[31]) = 0; - (b[3] => z[31]) = 0; - (b[4] => z[31]) = 0; - (b[5] => z[31]) = 0; - (b[6] => z[31]) = 0; - (b[7] => z[31]) = 0; - (b[8] => z[31]) = 0; - (b[9] => z[31]) = 0; - (b[10] => z[31]) = 0; - (b[11] => z[31]) = 0; - (b[12] => z[31]) = 0; - (b[13] => z[31]) = 0; - (b[14] => z[31]) = 0; - (b[15] => z[31]) = 0; - (b[16] => z[31]) = 0; - (b[17] => z[31]) = 0; - (a[0] => z[32]) = 0; - (a[1] => z[32]) = 0; - (a[2] => z[32]) = 0; - (a[3] => z[32]) = 0; - (a[4] => z[32]) = 0; - (a[5] => z[32]) = 0; - (a[6] => z[32]) = 0; - (a[7] => z[32]) = 0; - (a[8] => z[32]) = 0; - (a[9] => z[32]) = 0; - (a[10] => z[32]) = 0; - (a[11] => z[32]) = 0; - (a[12] => z[32]) = 0; - (a[13] => z[32]) = 0; - (a[14] => z[32]) = 0; - (a[15] => z[32]) = 0; - (a[16] => z[32]) = 0; - (a[17] => z[32]) = 0; - (a[18] => z[32]) = 0; - (a[19] => z[32]) = 0; - (b[0] => z[32]) = 0; - (b[1] => z[32]) = 0; - (b[2] => z[32]) = 0; - (b[3] => z[32]) = 0; - (b[4] => z[32]) = 0; - (b[5] => z[32]) = 0; - (b[6] => z[32]) = 0; - (b[7] => z[32]) = 0; - (b[8] => z[32]) = 0; - (b[9] => z[32]) = 0; - (b[10] => z[32]) = 0; - (b[11] => z[32]) = 0; - (b[12] => z[32]) = 0; - (b[13] => z[32]) = 0; - (b[14] => z[32]) = 0; - (b[15] => z[32]) = 0; - (b[16] => z[32]) = 0; - (b[17] => z[32]) = 0; - (a[0] => z[33]) = 0; - (a[1] => z[33]) = 0; - (a[2] => z[33]) = 0; - (a[3] => z[33]) = 0; - (a[4] => z[33]) = 0; - (a[5] => z[33]) = 0; - (a[6] => z[33]) = 0; - (a[7] => z[33]) = 0; - (a[8] => z[33]) = 0; - (a[9] => z[33]) = 0; - (a[10] => z[33]) = 0; - (a[11] => z[33]) = 0; - (a[12] => z[33]) = 0; - (a[13] => z[33]) = 0; - (a[14] => z[33]) = 0; - (a[15] => z[33]) = 0; - (a[16] => z[33]) = 0; - (a[17] => z[33]) = 0; - (a[18] => z[33]) = 0; - (a[19] => z[33]) = 0; - (b[0] => z[33]) = 0; - (b[1] => z[33]) = 0; - (b[2] => z[33]) = 0; - (b[3] => z[33]) = 0; - (b[4] => z[33]) = 0; - (b[5] => z[33]) = 0; - (b[6] => z[33]) = 0; - (b[7] => z[33]) = 0; - (b[8] => z[33]) = 0; - (b[9] => z[33]) = 0; - (b[10] => z[33]) = 0; - (b[11] => z[33]) = 0; - (b[12] => z[33]) = 0; - (b[13] => z[33]) = 0; - (b[14] => z[33]) = 0; - (b[15] => z[33]) = 0; - (b[16] => z[33]) = 0; - (b[17] => z[33]) = 0; - (a[0] => z[34]) = 0; - (a[1] => z[34]) = 0; - (a[2] => z[34]) = 0; - (a[3] => z[34]) = 0; - (a[4] => z[34]) = 0; - (a[5] => z[34]) = 0; - (a[6] => z[34]) = 0; - (a[7] => z[34]) = 0; - (a[8] => z[34]) = 0; - (a[9] => z[34]) = 0; - (a[10] => z[34]) = 0; - (a[11] => z[34]) = 0; - (a[12] => z[34]) = 0; - (a[13] => z[34]) = 0; - (a[14] => z[34]) = 0; - (a[15] => z[34]) = 0; - (a[16] => z[34]) = 0; - (a[17] => z[34]) = 0; - (a[18] => z[34]) = 0; - (a[19] => z[34]) = 0; - (b[0] => z[34]) = 0; - (b[1] => z[34]) = 0; - (b[2] => z[34]) = 0; - (b[3] => z[34]) = 0; - (b[4] => z[34]) = 0; - (b[5] => z[34]) = 0; - (b[6] => z[34]) = 0; - (b[7] => z[34]) = 0; - (b[8] => z[34]) = 0; - (b[9] => z[34]) = 0; - (b[10] => z[34]) = 0; - (b[11] => z[34]) = 0; - (b[12] => z[34]) = 0; - (b[13] => z[34]) = 0; - (b[14] => z[34]) = 0; - (b[15] => z[34]) = 0; - (b[16] => z[34]) = 0; - (b[17] => z[34]) = 0; - (a[0] => z[35]) = 0; - (a[1] => z[35]) = 0; - (a[2] => z[35]) = 0; - (a[3] => z[35]) = 0; - (a[4] => z[35]) = 0; - (a[5] => z[35]) = 0; - (a[6] => z[35]) = 0; - (a[7] => z[35]) = 0; - (a[8] => z[35]) = 0; - (a[9] => z[35]) = 0; - (a[10] => z[35]) = 0; - (a[11] => z[35]) = 0; - (a[12] => z[35]) = 0; - (a[13] => z[35]) = 0; - (a[14] => z[35]) = 0; - (a[15] => z[35]) = 0; - (a[16] => z[35]) = 0; - (a[17] => z[35]) = 0; - (a[18] => z[35]) = 0; - (a[19] => z[35]) = 0; - (b[0] => z[35]) = 0; - (b[1] => z[35]) = 0; - (b[2] => z[35]) = 0; - (b[3] => z[35]) = 0; - (b[4] => z[35]) = 0; - (b[5] => z[35]) = 0; - (b[6] => z[35]) = 0; - (b[7] => z[35]) = 0; - (b[8] => z[35]) = 0; - (b[9] => z[35]) = 0; - (b[10] => z[35]) = 0; - (b[11] => z[35]) = 0; - (b[12] => z[35]) = 0; - (b[13] => z[35]) = 0; - (b[14] => z[35]) = 0; - (b[15] => z[35]) = 0; - (b[16] => z[35]) = 0; - (b[17] => z[35]) = 0; - (a[0] => z[36]) = 0; - (a[1] => z[36]) = 0; - (a[2] => z[36]) = 0; - (a[3] => z[36]) = 0; - (a[4] => z[36]) = 0; - (a[5] => z[36]) = 0; - (a[6] => z[36]) = 0; - (a[7] => z[36]) = 0; - (a[8] => z[36]) = 0; - (a[9] => z[36]) = 0; - (a[10] => z[36]) = 0; - (a[11] => z[36]) = 0; - (a[12] => z[36]) = 0; - (a[13] => z[36]) = 0; - (a[14] => z[36]) = 0; - (a[15] => z[36]) = 0; - (a[16] => z[36]) = 0; - (a[17] => z[36]) = 0; - (a[18] => z[36]) = 0; - (a[19] => z[36]) = 0; - (b[0] => z[36]) = 0; - (b[1] => z[36]) = 0; - (b[2] => z[36]) = 0; - (b[3] => z[36]) = 0; - (b[4] => z[36]) = 0; - (b[5] => z[36]) = 0; - (b[6] => z[36]) = 0; - (b[7] => z[36]) = 0; - (b[8] => z[36]) = 0; - (b[9] => z[36]) = 0; - (b[10] => z[36]) = 0; - (b[11] => z[36]) = 0; - (b[12] => z[36]) = 0; - (b[13] => z[36]) = 0; - (b[14] => z[36]) = 0; - (b[15] => z[36]) = 0; - (b[16] => z[36]) = 0; - (b[17] => z[36]) = 0; - (a[0] => z[37]) = 0; - (a[1] => z[37]) = 0; - (a[2] => z[37]) = 0; - (a[3] => z[37]) = 0; - (a[4] => z[37]) = 0; - (a[5] => z[37]) = 0; - (a[6] => z[37]) = 0; - (a[7] => z[37]) = 0; - (a[8] => z[37]) = 0; - (a[9] => z[37]) = 0; - (a[10] => z[37]) = 0; - (a[11] => z[37]) = 0; - (a[12] => z[37]) = 0; - (a[13] => z[37]) = 0; - (a[14] => z[37]) = 0; - (a[15] => z[37]) = 0; - (a[16] => z[37]) = 0; - (a[17] => z[37]) = 0; - (a[18] => z[37]) = 0; - (a[19] => z[37]) = 0; - (b[0] => z[37]) = 0; - (b[1] => z[37]) = 0; - (b[2] => z[37]) = 0; - (b[3] => z[37]) = 0; - (b[4] => z[37]) = 0; - (b[5] => z[37]) = 0; - (b[6] => z[37]) = 0; - (b[7] => z[37]) = 0; - (b[8] => z[37]) = 0; - (b[9] => z[37]) = 0; - (b[10] => z[37]) = 0; - (b[11] => z[37]) = 0; - (b[12] => z[37]) = 0; - (b[13] => z[37]) = 0; - (b[14] => z[37]) = 0; - (b[15] => z[37]) = 0; - (b[16] => z[37]) = 0; - (b[17] => z[37]) = 0; - endspecify -`endif + .load_acc_i(load_acc), + .rst_acc_i(acc_reset), + .z_o(dsp_full_z), + // cascade ports (connect to dedicated cascade routing) + .a_cin_i(a_cin), + .b_cin_i(b_cin), + .z_cin_i(z_cin), + .z_cout_o(dsp_full_z_cout), + .a_cout_o(dsp_full_a_cout), + .b_cout_o(dsp_full_b_cout), + // configuration ports (tie-offs) + .coeff_i(COEFF_0), + .acc_fir_i(ACC_FIR), + .round_i(ROUND), + .zc_shift_i(ZC_SHIFT), + .zreg_shift_i(ZREG_SHIFT), + .shift_right_i(SHIFT_REG), + .saturate_enable_i(SATURATE), + .subtract_i(SUBTRACT), + .pre_add_sel_i(PRE_ADD), + .a_sel_i(A_SEL), + .a_reg_i(A_REG), + .b_sel_i(B_SEL), + .b_reg_i(B_REG), + .c_reg_i(C_REG), + .bc_reg_i(BC_REG), + .m_reg_i(M_REG) + ); endmodule -module QL_DSP2_MULT_REGIN ( // TODO: Name subject to change - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, +module QL_DSPV2_MULT ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - input wire [2:0] feedback, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [2:0] output_select, - input wire register_inputs + input wire [2:0] feedback, + input wire [2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h00000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), .feedback(feedback), - .load_acc(1'b0), + .output_select(output_select), + .z(z), + + .clk(), + .reset(), + .acc_reset(1'b0), - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + +endmodule + +module QL_DSPV2_MULT_REGIN ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, + + (* clkbuf_sink *) + input wire clk, + input wire reset, + + input wire [2:0] feedback, + input wire [2:0] output_select +); + + parameter [67:0] MODE_BITS = 68'h0A000000000000000; + + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), + .feedback(feedback), + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(1'b0), - .output_select(output_select), // unregistered output: a * b (0) - .saturate_enable(1'b0), - .shift_right(6'b0), - .round(1'b0), - .subtract(1'b0), - .register_inputs(register_inputs) // registered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULT_REGOUT ( // TODO: Name subject to change - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULT_REGOUT ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, + (* clkbuf_sink *) + input wire clk, + input wire reset, - input wire [2:0] feedback, - input wire unsigned_a, - input wire unsigned_b, - input wire f_mode, - input wire [2:0] output_select, - input wire register_inputs + input wire [2:0] feedback, + input wire [2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h00000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), .feedback(feedback), - .load_acc(1'b0), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(1'b0), - .output_select(output_select), // registered output: a * b (4) - .saturate_enable(1'b0), - .shift_right(6'b0), - .round(1'b0), - .subtract(1'b0), - .register_inputs(register_inputs) // unregistered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULT_REGIN_REGOUT ( // TODO: Name subject to change - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULT_REGIN_REGOUT ( // TODO: Name subject to change + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, + (* clkbuf_sink *) + input wire clk, + input wire reset, - input wire [2:0] feedback, - input wire unsigned_a, - input wire unsigned_b, - input wire f_mode, - input wire [2:0] output_select, - input wire register_inputs + input wire [2:0] feedback, + input wire [2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h0A000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), .feedback(feedback), - .load_acc(1'b0), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(1'b0), - .output_select(output_select), // registered output: a * b (4) - .saturate_enable(1'b0), - .shift_right(6'b0), - .round(1'b0), - .subtract(1'b0), - .register_inputs(register_inputs) // registered inputs - ); + .a_cin(), + .b_cin(), + .z_cin(), -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - endspecify -`endif + .z_cout(), + .a_cout(), + .b_cout() + ); + +endmodule + +module QL_DSPV2_MULTADD ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, + + input wire [ 2:0] feedback, + input wire [ 2:0] output_select +); + + parameter [67:0] MODE_BITS = 68'h00000000000000000; + + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), + .feedback(feedback), + .output_select(output_select), + .z(z), + + .clk(), + .reset(), + .acc_reset(1'b0), + + .a_cin(), + .b_cin(), + .z_cin(), + + .z_cout(), + .a_cout(), + .b_cout() + ); endmodule -module QL_DSP2_MULTADD ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTADD_REGIN ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - input wire reset, + (* clkbuf_sink *) + input wire clk, + input wire reset, - input wire [ 2:0] feedback, - input wire [ 5:0] acc_fir, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h0A000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .dly_b(), - .z(z), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), .feedback(feedback), - .acc_fir(acc_fir), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - - //.clk(1'b0), - .reset(reset), - - .output_select(output_select), // unregistered output: ACCin (2, 3) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // unregistered inputs - ); - -`ifdef SDF_SIM - specify - (a[0] => z[0]) = 0; - (a[1] => z[0]) = 0; - (a[2] => z[0]) = 0; - (a[3] => z[0]) = 0; - (a[4] => z[0]) = 0; - (a[5] => z[0]) = 0; - (a[6] => z[0]) = 0; - (a[7] => z[0]) = 0; - (a[8] => z[0]) = 0; - (a[9] => z[0]) = 0; - (a[10] => z[0]) = 0; - (a[11] => z[0]) = 0; - (a[12] => z[0]) = 0; - (a[13] => z[0]) = 0; - (a[14] => z[0]) = 0; - (a[15] => z[0]) = 0; - (a[16] => z[0]) = 0; - (a[17] => z[0]) = 0; - (a[18] => z[0]) = 0; - (a[19] => z[0]) = 0; - (b[0] => z[0]) = 0; - (b[1] => z[0]) = 0; - (b[2] => z[0]) = 0; - (b[3] => z[0]) = 0; - (b[4] => z[0]) = 0; - (b[5] => z[0]) = 0; - (b[6] => z[0]) = 0; - (b[7] => z[0]) = 0; - (b[8] => z[0]) = 0; - (b[9] => z[0]) = 0; - (b[10] => z[0]) = 0; - (b[11] => z[0]) = 0; - (b[12] => z[0]) = 0; - (b[13] => z[0]) = 0; - (b[14] => z[0]) = 0; - (b[15] => z[0]) = 0; - (b[16] => z[0]) = 0; - (b[17] => z[0]) = 0; - (a[0] => z[1]) = 0; - (a[1] => z[1]) = 0; - (a[2] => z[1]) = 0; - (a[3] => z[1]) = 0; - (a[4] => z[1]) = 0; - (a[5] => z[1]) = 0; - (a[6] => z[1]) = 0; - (a[7] => z[1]) = 0; - (a[8] => z[1]) = 0; - (a[9] => z[1]) = 0; - (a[10] => z[1]) = 0; - (a[11] => z[1]) = 0; - (a[12] => z[1]) = 0; - (a[13] => z[1]) = 0; - (a[14] => z[1]) = 0; - (a[15] => z[1]) = 0; - (a[16] => z[1]) = 0; - (a[17] => z[1]) = 0; - (a[18] => z[1]) = 0; - (a[19] => z[1]) = 0; - (b[0] => z[1]) = 0; - (b[1] => z[1]) = 0; - (b[2] => z[1]) = 0; - (b[3] => z[1]) = 0; - (b[4] => z[1]) = 0; - (b[5] => z[1]) = 0; - (b[6] => z[1]) = 0; - (b[7] => z[1]) = 0; - (b[8] => z[1]) = 0; - (b[9] => z[1]) = 0; - (b[10] => z[1]) = 0; - (b[11] => z[1]) = 0; - (b[12] => z[1]) = 0; - (b[13] => z[1]) = 0; - (b[14] => z[1]) = 0; - (b[15] => z[1]) = 0; - (b[16] => z[1]) = 0; - (b[17] => z[1]) = 0; - (a[0] => z[2]) = 0; - (a[1] => z[2]) = 0; - (a[2] => z[2]) = 0; - (a[3] => z[2]) = 0; - (a[4] => z[2]) = 0; - (a[5] => z[2]) = 0; - (a[6] => z[2]) = 0; - (a[7] => z[2]) = 0; - (a[8] => z[2]) = 0; - (a[9] => z[2]) = 0; - (a[10] => z[2]) = 0; - (a[11] => z[2]) = 0; - (a[12] => z[2]) = 0; - (a[13] => z[2]) = 0; - (a[14] => z[2]) = 0; - (a[15] => z[2]) = 0; - (a[16] => z[2]) = 0; - (a[17] => z[2]) = 0; - (a[18] => z[2]) = 0; - (a[19] => z[2]) = 0; - (b[0] => z[2]) = 0; - (b[1] => z[2]) = 0; - (b[2] => z[2]) = 0; - (b[3] => z[2]) = 0; - (b[4] => z[2]) = 0; - (b[5] => z[2]) = 0; - (b[6] => z[2]) = 0; - (b[7] => z[2]) = 0; - (b[8] => z[2]) = 0; - (b[9] => z[2]) = 0; - (b[10] => z[2]) = 0; - (b[11] => z[2]) = 0; - (b[12] => z[2]) = 0; - (b[13] => z[2]) = 0; - (b[14] => z[2]) = 0; - (b[15] => z[2]) = 0; - (b[16] => z[2]) = 0; - (b[17] => z[2]) = 0; - (a[0] => z[3]) = 0; - (a[1] => z[3]) = 0; - (a[2] => z[3]) = 0; - (a[3] => z[3]) = 0; - (a[4] => z[3]) = 0; - (a[5] => z[3]) = 0; - (a[6] => z[3]) = 0; - (a[7] => z[3]) = 0; - (a[8] => z[3]) = 0; - (a[9] => z[3]) = 0; - (a[10] => z[3]) = 0; - (a[11] => z[3]) = 0; - (a[12] => z[3]) = 0; - (a[13] => z[3]) = 0; - (a[14] => z[3]) = 0; - (a[15] => z[3]) = 0; - (a[16] => z[3]) = 0; - (a[17] => z[3]) = 0; - (a[18] => z[3]) = 0; - (a[19] => z[3]) = 0; - (b[0] => z[3]) = 0; - (b[1] => z[3]) = 0; - (b[2] => z[3]) = 0; - (b[3] => z[3]) = 0; - (b[4] => z[3]) = 0; - (b[5] => z[3]) = 0; - (b[6] => z[3]) = 0; - (b[7] => z[3]) = 0; - (b[8] => z[3]) = 0; - (b[9] => z[3]) = 0; - (b[10] => z[3]) = 0; - (b[11] => z[3]) = 0; - (b[12] => z[3]) = 0; - (b[13] => z[3]) = 0; - (b[14] => z[3]) = 0; - (b[15] => z[3]) = 0; - (b[16] => z[3]) = 0; - (b[17] => z[3]) = 0; - (a[0] => z[4]) = 0; - (a[1] => z[4]) = 0; - (a[2] => z[4]) = 0; - (a[3] => z[4]) = 0; - (a[4] => z[4]) = 0; - (a[5] => z[4]) = 0; - (a[6] => z[4]) = 0; - (a[7] => z[4]) = 0; - (a[8] => z[4]) = 0; - (a[9] => z[4]) = 0; - (a[10] => z[4]) = 0; - (a[11] => z[4]) = 0; - (a[12] => z[4]) = 0; - (a[13] => z[4]) = 0; - (a[14] => z[4]) = 0; - (a[15] => z[4]) = 0; - (a[16] => z[4]) = 0; - (a[17] => z[4]) = 0; - (a[18] => z[4]) = 0; - (a[19] => z[4]) = 0; - (b[0] => z[4]) = 0; - (b[1] => z[4]) = 0; - (b[2] => z[4]) = 0; - (b[3] => z[4]) = 0; - (b[4] => z[4]) = 0; - (b[5] => z[4]) = 0; - (b[6] => z[4]) = 0; - (b[7] => z[4]) = 0; - (b[8] => z[4]) = 0; - (b[9] => z[4]) = 0; - (b[10] => z[4]) = 0; - (b[11] => z[4]) = 0; - (b[12] => z[4]) = 0; - (b[13] => z[4]) = 0; - (b[14] => z[4]) = 0; - (b[15] => z[4]) = 0; - (b[16] => z[4]) = 0; - (b[17] => z[4]) = 0; - (a[0] => z[5]) = 0; - (a[1] => z[5]) = 0; - (a[2] => z[5]) = 0; - (a[3] => z[5]) = 0; - (a[4] => z[5]) = 0; - (a[5] => z[5]) = 0; - (a[6] => z[5]) = 0; - (a[7] => z[5]) = 0; - (a[8] => z[5]) = 0; - (a[9] => z[5]) = 0; - (a[10] => z[5]) = 0; - (a[11] => z[5]) = 0; - (a[12] => z[5]) = 0; - (a[13] => z[5]) = 0; - (a[14] => z[5]) = 0; - (a[15] => z[5]) = 0; - (a[16] => z[5]) = 0; - (a[17] => z[5]) = 0; - (a[18] => z[5]) = 0; - (a[19] => z[5]) = 0; - (b[0] => z[5]) = 0; - (b[1] => z[5]) = 0; - (b[2] => z[5]) = 0; - (b[3] => z[5]) = 0; - (b[4] => z[5]) = 0; - (b[5] => z[5]) = 0; - (b[6] => z[5]) = 0; - (b[7] => z[5]) = 0; - (b[8] => z[5]) = 0; - (b[9] => z[5]) = 0; - (b[10] => z[5]) = 0; - (b[11] => z[5]) = 0; - (b[12] => z[5]) = 0; - (b[13] => z[5]) = 0; - (b[14] => z[5]) = 0; - (b[15] => z[5]) = 0; - (b[16] => z[5]) = 0; - (b[17] => z[5]) = 0; - (a[0] => z[6]) = 0; - (a[1] => z[6]) = 0; - (a[2] => z[6]) = 0; - (a[3] => z[6]) = 0; - (a[4] => z[6]) = 0; - (a[5] => z[6]) = 0; - (a[6] => z[6]) = 0; - (a[7] => z[6]) = 0; - (a[8] => z[6]) = 0; - (a[9] => z[6]) = 0; - (a[10] => z[6]) = 0; - (a[11] => z[6]) = 0; - (a[12] => z[6]) = 0; - (a[13] => z[6]) = 0; - (a[14] => z[6]) = 0; - (a[15] => z[6]) = 0; - (a[16] => z[6]) = 0; - (a[17] => z[6]) = 0; - (a[18] => z[6]) = 0; - (a[19] => z[6]) = 0; - (b[0] => z[6]) = 0; - (b[1] => z[6]) = 0; - (b[2] => z[6]) = 0; - (b[3] => z[6]) = 0; - (b[4] => z[6]) = 0; - (b[5] => z[6]) = 0; - (b[6] => z[6]) = 0; - (b[7] => z[6]) = 0; - (b[8] => z[6]) = 0; - (b[9] => z[6]) = 0; - (b[10] => z[6]) = 0; - (b[11] => z[6]) = 0; - (b[12] => z[6]) = 0; - (b[13] => z[6]) = 0; - (b[14] => z[6]) = 0; - (b[15] => z[6]) = 0; - (b[16] => z[6]) = 0; - (b[17] => z[6]) = 0; - (a[0] => z[7]) = 0; - (a[1] => z[7]) = 0; - (a[2] => z[7]) = 0; - (a[3] => z[7]) = 0; - (a[4] => z[7]) = 0; - (a[5] => z[7]) = 0; - (a[6] => z[7]) = 0; - (a[7] => z[7]) = 0; - (a[8] => z[7]) = 0; - (a[9] => z[7]) = 0; - (a[10] => z[7]) = 0; - (a[11] => z[7]) = 0; - (a[12] => z[7]) = 0; - (a[13] => z[7]) = 0; - (a[14] => z[7]) = 0; - (a[15] => z[7]) = 0; - (a[16] => z[7]) = 0; - (a[17] => z[7]) = 0; - (a[18] => z[7]) = 0; - (a[19] => z[7]) = 0; - (b[0] => z[7]) = 0; - (b[1] => z[7]) = 0; - (b[2] => z[7]) = 0; - (b[3] => z[7]) = 0; - (b[4] => z[7]) = 0; - (b[5] => z[7]) = 0; - (b[6] => z[7]) = 0; - (b[7] => z[7]) = 0; - (b[8] => z[7]) = 0; - (b[9] => z[7]) = 0; - (b[10] => z[7]) = 0; - (b[11] => z[7]) = 0; - (b[12] => z[7]) = 0; - (b[13] => z[7]) = 0; - (b[14] => z[7]) = 0; - (b[15] => z[7]) = 0; - (b[16] => z[7]) = 0; - (b[17] => z[7]) = 0; - (a[0] => z[8]) = 0; - (a[1] => z[8]) = 0; - (a[2] => z[8]) = 0; - (a[3] => z[8]) = 0; - (a[4] => z[8]) = 0; - (a[5] => z[8]) = 0; - (a[6] => z[8]) = 0; - (a[7] => z[8]) = 0; - (a[8] => z[8]) = 0; - (a[9] => z[8]) = 0; - (a[10] => z[8]) = 0; - (a[11] => z[8]) = 0; - (a[12] => z[8]) = 0; - (a[13] => z[8]) = 0; - (a[14] => z[8]) = 0; - (a[15] => z[8]) = 0; - (a[16] => z[8]) = 0; - (a[17] => z[8]) = 0; - (a[18] => z[8]) = 0; - (a[19] => z[8]) = 0; - (b[0] => z[8]) = 0; - (b[1] => z[8]) = 0; - (b[2] => z[8]) = 0; - (b[3] => z[8]) = 0; - (b[4] => z[8]) = 0; - (b[5] => z[8]) = 0; - (b[6] => z[8]) = 0; - (b[7] => z[8]) = 0; - (b[8] => z[8]) = 0; - (b[9] => z[8]) = 0; - (b[10] => z[8]) = 0; - (b[11] => z[8]) = 0; - (b[12] => z[8]) = 0; - (b[13] => z[8]) = 0; - (b[14] => z[8]) = 0; - (b[15] => z[8]) = 0; - (b[16] => z[8]) = 0; - (b[17] => z[8]) = 0; - (a[0] => z[9]) = 0; - (a[1] => z[9]) = 0; - (a[2] => z[9]) = 0; - (a[3] => z[9]) = 0; - (a[4] => z[9]) = 0; - (a[5] => z[9]) = 0; - (a[6] => z[9]) = 0; - (a[7] => z[9]) = 0; - (a[8] => z[9]) = 0; - (a[9] => z[9]) = 0; - (a[10] => z[9]) = 0; - (a[11] => z[9]) = 0; - (a[12] => z[9]) = 0; - (a[13] => z[9]) = 0; - (a[14] => z[9]) = 0; - (a[15] => z[9]) = 0; - (a[16] => z[9]) = 0; - (a[17] => z[9]) = 0; - (a[18] => z[9]) = 0; - (a[19] => z[9]) = 0; - (b[0] => z[9]) = 0; - (b[1] => z[9]) = 0; - (b[2] => z[9]) = 0; - (b[3] => z[9]) = 0; - (b[4] => z[9]) = 0; - (b[5] => z[9]) = 0; - (b[6] => z[9]) = 0; - (b[7] => z[9]) = 0; - (b[8] => z[9]) = 0; - (b[9] => z[9]) = 0; - (b[10] => z[9]) = 0; - (b[11] => z[9]) = 0; - (b[12] => z[9]) = 0; - (b[13] => z[9]) = 0; - (b[14] => z[9]) = 0; - (b[15] => z[9]) = 0; - (b[16] => z[9]) = 0; - (b[17] => z[9]) = 0; - (a[0] => z[10]) = 0; - (a[1] => z[10]) = 0; - (a[2] => z[10]) = 0; - (a[3] => z[10]) = 0; - (a[4] => z[10]) = 0; - (a[5] => z[10]) = 0; - (a[6] => z[10]) = 0; - (a[7] => z[10]) = 0; - (a[8] => z[10]) = 0; - (a[9] => z[10]) = 0; - (a[10] => z[10]) = 0; - (a[11] => z[10]) = 0; - (a[12] => z[10]) = 0; - (a[13] => z[10]) = 0; - (a[14] => z[10]) = 0; - (a[15] => z[10]) = 0; - (a[16] => z[10]) = 0; - (a[17] => z[10]) = 0; - (a[18] => z[10]) = 0; - (a[19] => z[10]) = 0; - (b[0] => z[10]) = 0; - (b[1] => z[10]) = 0; - (b[2] => z[10]) = 0; - (b[3] => z[10]) = 0; - (b[4] => z[10]) = 0; - (b[5] => z[10]) = 0; - (b[6] => z[10]) = 0; - (b[7] => z[10]) = 0; - (b[8] => z[10]) = 0; - (b[9] => z[10]) = 0; - (b[10] => z[10]) = 0; - (b[11] => z[10]) = 0; - (b[12] => z[10]) = 0; - (b[13] => z[10]) = 0; - (b[14] => z[10]) = 0; - (b[15] => z[10]) = 0; - (b[16] => z[10]) = 0; - (b[17] => z[10]) = 0; - (a[0] => z[11]) = 0; - (a[1] => z[11]) = 0; - (a[2] => z[11]) = 0; - (a[3] => z[11]) = 0; - (a[4] => z[11]) = 0; - (a[5] => z[11]) = 0; - (a[6] => z[11]) = 0; - (a[7] => z[11]) = 0; - (a[8] => z[11]) = 0; - (a[9] => z[11]) = 0; - (a[10] => z[11]) = 0; - (a[11] => z[11]) = 0; - (a[12] => z[11]) = 0; - (a[13] => z[11]) = 0; - (a[14] => z[11]) = 0; - (a[15] => z[11]) = 0; - (a[16] => z[11]) = 0; - (a[17] => z[11]) = 0; - (a[18] => z[11]) = 0; - (a[19] => z[11]) = 0; - (b[0] => z[11]) = 0; - (b[1] => z[11]) = 0; - (b[2] => z[11]) = 0; - (b[3] => z[11]) = 0; - (b[4] => z[11]) = 0; - (b[5] => z[11]) = 0; - (b[6] => z[11]) = 0; - (b[7] => z[11]) = 0; - (b[8] => z[11]) = 0; - (b[9] => z[11]) = 0; - (b[10] => z[11]) = 0; - (b[11] => z[11]) = 0; - (b[12] => z[11]) = 0; - (b[13] => z[11]) = 0; - (b[14] => z[11]) = 0; - (b[15] => z[11]) = 0; - (b[16] => z[11]) = 0; - (b[17] => z[11]) = 0; - (a[0] => z[12]) = 0; - (a[1] => z[12]) = 0; - (a[2] => z[12]) = 0; - (a[3] => z[12]) = 0; - (a[4] => z[12]) = 0; - (a[5] => z[12]) = 0; - (a[6] => z[12]) = 0; - (a[7] => z[12]) = 0; - (a[8] => z[12]) = 0; - (a[9] => z[12]) = 0; - (a[10] => z[12]) = 0; - (a[11] => z[12]) = 0; - (a[12] => z[12]) = 0; - (a[13] => z[12]) = 0; - (a[14] => z[12]) = 0; - (a[15] => z[12]) = 0; - (a[16] => z[12]) = 0; - (a[17] => z[12]) = 0; - (a[18] => z[12]) = 0; - (a[19] => z[12]) = 0; - (b[0] => z[12]) = 0; - (b[1] => z[12]) = 0; - (b[2] => z[12]) = 0; - (b[3] => z[12]) = 0; - (b[4] => z[12]) = 0; - (b[5] => z[12]) = 0; - (b[6] => z[12]) = 0; - (b[7] => z[12]) = 0; - (b[8] => z[12]) = 0; - (b[9] => z[12]) = 0; - (b[10] => z[12]) = 0; - (b[11] => z[12]) = 0; - (b[12] => z[12]) = 0; - (b[13] => z[12]) = 0; - (b[14] => z[12]) = 0; - (b[15] => z[12]) = 0; - (b[16] => z[12]) = 0; - (b[17] => z[12]) = 0; - (a[0] => z[13]) = 0; - (a[1] => z[13]) = 0; - (a[2] => z[13]) = 0; - (a[3] => z[13]) = 0; - (a[4] => z[13]) = 0; - (a[5] => z[13]) = 0; - (a[6] => z[13]) = 0; - (a[7] => z[13]) = 0; - (a[8] => z[13]) = 0; - (a[9] => z[13]) = 0; - (a[10] => z[13]) = 0; - (a[11] => z[13]) = 0; - (a[12] => z[13]) = 0; - (a[13] => z[13]) = 0; - (a[14] => z[13]) = 0; - (a[15] => z[13]) = 0; - (a[16] => z[13]) = 0; - (a[17] => z[13]) = 0; - (a[18] => z[13]) = 0; - (a[19] => z[13]) = 0; - (b[0] => z[13]) = 0; - (b[1] => z[13]) = 0; - (b[2] => z[13]) = 0; - (b[3] => z[13]) = 0; - (b[4] => z[13]) = 0; - (b[5] => z[13]) = 0; - (b[6] => z[13]) = 0; - (b[7] => z[13]) = 0; - (b[8] => z[13]) = 0; - (b[9] => z[13]) = 0; - (b[10] => z[13]) = 0; - (b[11] => z[13]) = 0; - (b[12] => z[13]) = 0; - (b[13] => z[13]) = 0; - (b[14] => z[13]) = 0; - (b[15] => z[13]) = 0; - (b[16] => z[13]) = 0; - (b[17] => z[13]) = 0; - (a[0] => z[14]) = 0; - (a[1] => z[14]) = 0; - (a[2] => z[14]) = 0; - (a[3] => z[14]) = 0; - (a[4] => z[14]) = 0; - (a[5] => z[14]) = 0; - (a[6] => z[14]) = 0; - (a[7] => z[14]) = 0; - (a[8] => z[14]) = 0; - (a[9] => z[14]) = 0; - (a[10] => z[14]) = 0; - (a[11] => z[14]) = 0; - (a[12] => z[14]) = 0; - (a[13] => z[14]) = 0; - (a[14] => z[14]) = 0; - (a[15] => z[14]) = 0; - (a[16] => z[14]) = 0; - (a[17] => z[14]) = 0; - (a[18] => z[14]) = 0; - (a[19] => z[14]) = 0; - (b[0] => z[14]) = 0; - (b[1] => z[14]) = 0; - (b[2] => z[14]) = 0; - (b[3] => z[14]) = 0; - (b[4] => z[14]) = 0; - (b[5] => z[14]) = 0; - (b[6] => z[14]) = 0; - (b[7] => z[14]) = 0; - (b[8] => z[14]) = 0; - (b[9] => z[14]) = 0; - (b[10] => z[14]) = 0; - (b[11] => z[14]) = 0; - (b[12] => z[14]) = 0; - (b[13] => z[14]) = 0; - (b[14] => z[14]) = 0; - (b[15] => z[14]) = 0; - (b[16] => z[14]) = 0; - (b[17] => z[14]) = 0; - (a[0] => z[15]) = 0; - (a[1] => z[15]) = 0; - (a[2] => z[15]) = 0; - (a[3] => z[15]) = 0; - (a[4] => z[15]) = 0; - (a[5] => z[15]) = 0; - (a[6] => z[15]) = 0; - (a[7] => z[15]) = 0; - (a[8] => z[15]) = 0; - (a[9] => z[15]) = 0; - (a[10] => z[15]) = 0; - (a[11] => z[15]) = 0; - (a[12] => z[15]) = 0; - (a[13] => z[15]) = 0; - (a[14] => z[15]) = 0; - (a[15] => z[15]) = 0; - (a[16] => z[15]) = 0; - (a[17] => z[15]) = 0; - (a[18] => z[15]) = 0; - (a[19] => z[15]) = 0; - (b[0] => z[15]) = 0; - (b[1] => z[15]) = 0; - (b[2] => z[15]) = 0; - (b[3] => z[15]) = 0; - (b[4] => z[15]) = 0; - (b[5] => z[15]) = 0; - (b[6] => z[15]) = 0; - (b[7] => z[15]) = 0; - (b[8] => z[15]) = 0; - (b[9] => z[15]) = 0; - (b[10] => z[15]) = 0; - (b[11] => z[15]) = 0; - (b[12] => z[15]) = 0; - (b[13] => z[15]) = 0; - (b[14] => z[15]) = 0; - (b[15] => z[15]) = 0; - (b[16] => z[15]) = 0; - (b[17] => z[15]) = 0; - (a[0] => z[16]) = 0; - (a[1] => z[16]) = 0; - (a[2] => z[16]) = 0; - (a[3] => z[16]) = 0; - (a[4] => z[16]) = 0; - (a[5] => z[16]) = 0; - (a[6] => z[16]) = 0; - (a[7] => z[16]) = 0; - (a[8] => z[16]) = 0; - (a[9] => z[16]) = 0; - (a[10] => z[16]) = 0; - (a[11] => z[16]) = 0; - (a[12] => z[16]) = 0; - (a[13] => z[16]) = 0; - (a[14] => z[16]) = 0; - (a[15] => z[16]) = 0; - (a[16] => z[16]) = 0; - (a[17] => z[16]) = 0; - (a[18] => z[16]) = 0; - (a[19] => z[16]) = 0; - (b[0] => z[16]) = 0; - (b[1] => z[16]) = 0; - (b[2] => z[16]) = 0; - (b[3] => z[16]) = 0; - (b[4] => z[16]) = 0; - (b[5] => z[16]) = 0; - (b[6] => z[16]) = 0; - (b[7] => z[16]) = 0; - (b[8] => z[16]) = 0; - (b[9] => z[16]) = 0; - (b[10] => z[16]) = 0; - (b[11] => z[16]) = 0; - (b[12] => z[16]) = 0; - (b[13] => z[16]) = 0; - (b[14] => z[16]) = 0; - (b[15] => z[16]) = 0; - (b[16] => z[16]) = 0; - (b[17] => z[16]) = 0; - (a[0] => z[17]) = 0; - (a[1] => z[17]) = 0; - (a[2] => z[17]) = 0; - (a[3] => z[17]) = 0; - (a[4] => z[17]) = 0; - (a[5] => z[17]) = 0; - (a[6] => z[17]) = 0; - (a[7] => z[17]) = 0; - (a[8] => z[17]) = 0; - (a[9] => z[17]) = 0; - (a[10] => z[17]) = 0; - (a[11] => z[17]) = 0; - (a[12] => z[17]) = 0; - (a[13] => z[17]) = 0; - (a[14] => z[17]) = 0; - (a[15] => z[17]) = 0; - (a[16] => z[17]) = 0; - (a[17] => z[17]) = 0; - (a[18] => z[17]) = 0; - (a[19] => z[17]) = 0; - (b[0] => z[17]) = 0; - (b[1] => z[17]) = 0; - (b[2] => z[17]) = 0; - (b[3] => z[17]) = 0; - (b[4] => z[17]) = 0; - (b[5] => z[17]) = 0; - (b[6] => z[17]) = 0; - (b[7] => z[17]) = 0; - (b[8] => z[17]) = 0; - (b[9] => z[17]) = 0; - (b[10] => z[17]) = 0; - (b[11] => z[17]) = 0; - (b[12] => z[17]) = 0; - (b[13] => z[17]) = 0; - (b[14] => z[17]) = 0; - (b[15] => z[17]) = 0; - (b[16] => z[17]) = 0; - (b[17] => z[17]) = 0; - (a[0] => z[18]) = 0; - (a[1] => z[18]) = 0; - (a[2] => z[18]) = 0; - (a[3] => z[18]) = 0; - (a[4] => z[18]) = 0; - (a[5] => z[18]) = 0; - (a[6] => z[18]) = 0; - (a[7] => z[18]) = 0; - (a[8] => z[18]) = 0; - (a[9] => z[18]) = 0; - (a[10] => z[18]) = 0; - (a[11] => z[18]) = 0; - (a[12] => z[18]) = 0; - (a[13] => z[18]) = 0; - (a[14] => z[18]) = 0; - (a[15] => z[18]) = 0; - (a[16] => z[18]) = 0; - (a[17] => z[18]) = 0; - (a[18] => z[18]) = 0; - (a[19] => z[18]) = 0; - (b[0] => z[18]) = 0; - (b[1] => z[18]) = 0; - (b[2] => z[18]) = 0; - (b[3] => z[18]) = 0; - (b[4] => z[18]) = 0; - (b[5] => z[18]) = 0; - (b[6] => z[18]) = 0; - (b[7] => z[18]) = 0; - (b[8] => z[18]) = 0; - (b[9] => z[18]) = 0; - (b[10] => z[18]) = 0; - (b[11] => z[18]) = 0; - (b[12] => z[18]) = 0; - (b[13] => z[18]) = 0; - (b[14] => z[18]) = 0; - (b[15] => z[18]) = 0; - (b[16] => z[18]) = 0; - (b[17] => z[18]) = 0; - (a[0] => z[19]) = 0; - (a[1] => z[19]) = 0; - (a[2] => z[19]) = 0; - (a[3] => z[19]) = 0; - (a[4] => z[19]) = 0; - (a[5] => z[19]) = 0; - (a[6] => z[19]) = 0; - (a[7] => z[19]) = 0; - (a[8] => z[19]) = 0; - (a[9] => z[19]) = 0; - (a[10] => z[19]) = 0; - (a[11] => z[19]) = 0; - (a[12] => z[19]) = 0; - (a[13] => z[19]) = 0; - (a[14] => z[19]) = 0; - (a[15] => z[19]) = 0; - (a[16] => z[19]) = 0; - (a[17] => z[19]) = 0; - (a[18] => z[19]) = 0; - (a[19] => z[19]) = 0; - (b[0] => z[19]) = 0; - (b[1] => z[19]) = 0; - (b[2] => z[19]) = 0; - (b[3] => z[19]) = 0; - (b[4] => z[19]) = 0; - (b[5] => z[19]) = 0; - (b[6] => z[19]) = 0; - (b[7] => z[19]) = 0; - (b[8] => z[19]) = 0; - (b[9] => z[19]) = 0; - (b[10] => z[19]) = 0; - (b[11] => z[19]) = 0; - (b[12] => z[19]) = 0; - (b[13] => z[19]) = 0; - (b[14] => z[19]) = 0; - (b[15] => z[19]) = 0; - (b[16] => z[19]) = 0; - (b[17] => z[19]) = 0; - (a[0] => z[20]) = 0; - (a[1] => z[20]) = 0; - (a[2] => z[20]) = 0; - (a[3] => z[20]) = 0; - (a[4] => z[20]) = 0; - (a[5] => z[20]) = 0; - (a[6] => z[20]) = 0; - (a[7] => z[20]) = 0; - (a[8] => z[20]) = 0; - (a[9] => z[20]) = 0; - (a[10] => z[20]) = 0; - (a[11] => z[20]) = 0; - (a[12] => z[20]) = 0; - (a[13] => z[20]) = 0; - (a[14] => z[20]) = 0; - (a[15] => z[20]) = 0; - (a[16] => z[20]) = 0; - (a[17] => z[20]) = 0; - (a[18] => z[20]) = 0; - (a[19] => z[20]) = 0; - (b[0] => z[20]) = 0; - (b[1] => z[20]) = 0; - (b[2] => z[20]) = 0; - (b[3] => z[20]) = 0; - (b[4] => z[20]) = 0; - (b[5] => z[20]) = 0; - (b[6] => z[20]) = 0; - (b[7] => z[20]) = 0; - (b[8] => z[20]) = 0; - (b[9] => z[20]) = 0; - (b[10] => z[20]) = 0; - (b[11] => z[20]) = 0; - (b[12] => z[20]) = 0; - (b[13] => z[20]) = 0; - (b[14] => z[20]) = 0; - (b[15] => z[20]) = 0; - (b[16] => z[20]) = 0; - (b[17] => z[20]) = 0; - (a[0] => z[21]) = 0; - (a[1] => z[21]) = 0; - (a[2] => z[21]) = 0; - (a[3] => z[21]) = 0; - (a[4] => z[21]) = 0; - (a[5] => z[21]) = 0; - (a[6] => z[21]) = 0; - (a[7] => z[21]) = 0; - (a[8] => z[21]) = 0; - (a[9] => z[21]) = 0; - (a[10] => z[21]) = 0; - (a[11] => z[21]) = 0; - (a[12] => z[21]) = 0; - (a[13] => z[21]) = 0; - (a[14] => z[21]) = 0; - (a[15] => z[21]) = 0; - (a[16] => z[21]) = 0; - (a[17] => z[21]) = 0; - (a[18] => z[21]) = 0; - (a[19] => z[21]) = 0; - (b[0] => z[21]) = 0; - (b[1] => z[21]) = 0; - (b[2] => z[21]) = 0; - (b[3] => z[21]) = 0; - (b[4] => z[21]) = 0; - (b[5] => z[21]) = 0; - (b[6] => z[21]) = 0; - (b[7] => z[21]) = 0; - (b[8] => z[21]) = 0; - (b[9] => z[21]) = 0; - (b[10] => z[21]) = 0; - (b[11] => z[21]) = 0; - (b[12] => z[21]) = 0; - (b[13] => z[21]) = 0; - (b[14] => z[21]) = 0; - (b[15] => z[21]) = 0; - (b[16] => z[21]) = 0; - (b[17] => z[21]) = 0; - (a[0] => z[22]) = 0; - (a[1] => z[22]) = 0; - (a[2] => z[22]) = 0; - (a[3] => z[22]) = 0; - (a[4] => z[22]) = 0; - (a[5] => z[22]) = 0; - (a[6] => z[22]) = 0; - (a[7] => z[22]) = 0; - (a[8] => z[22]) = 0; - (a[9] => z[22]) = 0; - (a[10] => z[22]) = 0; - (a[11] => z[22]) = 0; - (a[12] => z[22]) = 0; - (a[13] => z[22]) = 0; - (a[14] => z[22]) = 0; - (a[15] => z[22]) = 0; - (a[16] => z[22]) = 0; - (a[17] => z[22]) = 0; - (a[18] => z[22]) = 0; - (a[19] => z[22]) = 0; - (b[0] => z[22]) = 0; - (b[1] => z[22]) = 0; - (b[2] => z[22]) = 0; - (b[3] => z[22]) = 0; - (b[4] => z[22]) = 0; - (b[5] => z[22]) = 0; - (b[6] => z[22]) = 0; - (b[7] => z[22]) = 0; - (b[8] => z[22]) = 0; - (b[9] => z[22]) = 0; - (b[10] => z[22]) = 0; - (b[11] => z[22]) = 0; - (b[12] => z[22]) = 0; - (b[13] => z[22]) = 0; - (b[14] => z[22]) = 0; - (b[15] => z[22]) = 0; - (b[16] => z[22]) = 0; - (b[17] => z[22]) = 0; - (a[0] => z[23]) = 0; - (a[1] => z[23]) = 0; - (a[2] => z[23]) = 0; - (a[3] => z[23]) = 0; - (a[4] => z[23]) = 0; - (a[5] => z[23]) = 0; - (a[6] => z[23]) = 0; - (a[7] => z[23]) = 0; - (a[8] => z[23]) = 0; - (a[9] => z[23]) = 0; - (a[10] => z[23]) = 0; - (a[11] => z[23]) = 0; - (a[12] => z[23]) = 0; - (a[13] => z[23]) = 0; - (a[14] => z[23]) = 0; - (a[15] => z[23]) = 0; - (a[16] => z[23]) = 0; - (a[17] => z[23]) = 0; - (a[18] => z[23]) = 0; - (a[19] => z[23]) = 0; - (b[0] => z[23]) = 0; - (b[1] => z[23]) = 0; - (b[2] => z[23]) = 0; - (b[3] => z[23]) = 0; - (b[4] => z[23]) = 0; - (b[5] => z[23]) = 0; - (b[6] => z[23]) = 0; - (b[7] => z[23]) = 0; - (b[8] => z[23]) = 0; - (b[9] => z[23]) = 0; - (b[10] => z[23]) = 0; - (b[11] => z[23]) = 0; - (b[12] => z[23]) = 0; - (b[13] => z[23]) = 0; - (b[14] => z[23]) = 0; - (b[15] => z[23]) = 0; - (b[16] => z[23]) = 0; - (b[17] => z[23]) = 0; - (a[0] => z[24]) = 0; - (a[1] => z[24]) = 0; - (a[2] => z[24]) = 0; - (a[3] => z[24]) = 0; - (a[4] => z[24]) = 0; - (a[5] => z[24]) = 0; - (a[6] => z[24]) = 0; - (a[7] => z[24]) = 0; - (a[8] => z[24]) = 0; - (a[9] => z[24]) = 0; - (a[10] => z[24]) = 0; - (a[11] => z[24]) = 0; - (a[12] => z[24]) = 0; - (a[13] => z[24]) = 0; - (a[14] => z[24]) = 0; - (a[15] => z[24]) = 0; - (a[16] => z[24]) = 0; - (a[17] => z[24]) = 0; - (a[18] => z[24]) = 0; - (a[19] => z[24]) = 0; - (b[0] => z[24]) = 0; - (b[1] => z[24]) = 0; - (b[2] => z[24]) = 0; - (b[3] => z[24]) = 0; - (b[4] => z[24]) = 0; - (b[5] => z[24]) = 0; - (b[6] => z[24]) = 0; - (b[7] => z[24]) = 0; - (b[8] => z[24]) = 0; - (b[9] => z[24]) = 0; - (b[10] => z[24]) = 0; - (b[11] => z[24]) = 0; - (b[12] => z[24]) = 0; - (b[13] => z[24]) = 0; - (b[14] => z[24]) = 0; - (b[15] => z[24]) = 0; - (b[16] => z[24]) = 0; - (b[17] => z[24]) = 0; - (a[0] => z[25]) = 0; - (a[1] => z[25]) = 0; - (a[2] => z[25]) = 0; - (a[3] => z[25]) = 0; - (a[4] => z[25]) = 0; - (a[5] => z[25]) = 0; - (a[6] => z[25]) = 0; - (a[7] => z[25]) = 0; - (a[8] => z[25]) = 0; - (a[9] => z[25]) = 0; - (a[10] => z[25]) = 0; - (a[11] => z[25]) = 0; - (a[12] => z[25]) = 0; - (a[13] => z[25]) = 0; - (a[14] => z[25]) = 0; - (a[15] => z[25]) = 0; - (a[16] => z[25]) = 0; - (a[17] => z[25]) = 0; - (a[18] => z[25]) = 0; - (a[19] => z[25]) = 0; - (b[0] => z[25]) = 0; - (b[1] => z[25]) = 0; - (b[2] => z[25]) = 0; - (b[3] => z[25]) = 0; - (b[4] => z[25]) = 0; - (b[5] => z[25]) = 0; - (b[6] => z[25]) = 0; - (b[7] => z[25]) = 0; - (b[8] => z[25]) = 0; - (b[9] => z[25]) = 0; - (b[10] => z[25]) = 0; - (b[11] => z[25]) = 0; - (b[12] => z[25]) = 0; - (b[13] => z[25]) = 0; - (b[14] => z[25]) = 0; - (b[15] => z[25]) = 0; - (b[16] => z[25]) = 0; - (b[17] => z[25]) = 0; - (a[0] => z[26]) = 0; - (a[1] => z[26]) = 0; - (a[2] => z[26]) = 0; - (a[3] => z[26]) = 0; - (a[4] => z[26]) = 0; - (a[5] => z[26]) = 0; - (a[6] => z[26]) = 0; - (a[7] => z[26]) = 0; - (a[8] => z[26]) = 0; - (a[9] => z[26]) = 0; - (a[10] => z[26]) = 0; - (a[11] => z[26]) = 0; - (a[12] => z[26]) = 0; - (a[13] => z[26]) = 0; - (a[14] => z[26]) = 0; - (a[15] => z[26]) = 0; - (a[16] => z[26]) = 0; - (a[17] => z[26]) = 0; - (a[18] => z[26]) = 0; - (a[19] => z[26]) = 0; - (b[0] => z[26]) = 0; - (b[1] => z[26]) = 0; - (b[2] => z[26]) = 0; - (b[3] => z[26]) = 0; - (b[4] => z[26]) = 0; - (b[5] => z[26]) = 0; - (b[6] => z[26]) = 0; - (b[7] => z[26]) = 0; - (b[8] => z[26]) = 0; - (b[9] => z[26]) = 0; - (b[10] => z[26]) = 0; - (b[11] => z[26]) = 0; - (b[12] => z[26]) = 0; - (b[13] => z[26]) = 0; - (b[14] => z[26]) = 0; - (b[15] => z[26]) = 0; - (b[16] => z[26]) = 0; - (b[17] => z[26]) = 0; - (a[0] => z[27]) = 0; - (a[1] => z[27]) = 0; - (a[2] => z[27]) = 0; - (a[3] => z[27]) = 0; - (a[4] => z[27]) = 0; - (a[5] => z[27]) = 0; - (a[6] => z[27]) = 0; - (a[7] => z[27]) = 0; - (a[8] => z[27]) = 0; - (a[9] => z[27]) = 0; - (a[10] => z[27]) = 0; - (a[11] => z[27]) = 0; - (a[12] => z[27]) = 0; - (a[13] => z[27]) = 0; - (a[14] => z[27]) = 0; - (a[15] => z[27]) = 0; - (a[16] => z[27]) = 0; - (a[17] => z[27]) = 0; - (a[18] => z[27]) = 0; - (a[19] => z[27]) = 0; - (b[0] => z[27]) = 0; - (b[1] => z[27]) = 0; - (b[2] => z[27]) = 0; - (b[3] => z[27]) = 0; - (b[4] => z[27]) = 0; - (b[5] => z[27]) = 0; - (b[6] => z[27]) = 0; - (b[7] => z[27]) = 0; - (b[8] => z[27]) = 0; - (b[9] => z[27]) = 0; - (b[10] => z[27]) = 0; - (b[11] => z[27]) = 0; - (b[12] => z[27]) = 0; - (b[13] => z[27]) = 0; - (b[14] => z[27]) = 0; - (b[15] => z[27]) = 0; - (b[16] => z[27]) = 0; - (b[17] => z[27]) = 0; - (a[0] => z[28]) = 0; - (a[1] => z[28]) = 0; - (a[2] => z[28]) = 0; - (a[3] => z[28]) = 0; - (a[4] => z[28]) = 0; - (a[5] => z[28]) = 0; - (a[6] => z[28]) = 0; - (a[7] => z[28]) = 0; - (a[8] => z[28]) = 0; - (a[9] => z[28]) = 0; - (a[10] => z[28]) = 0; - (a[11] => z[28]) = 0; - (a[12] => z[28]) = 0; - (a[13] => z[28]) = 0; - (a[14] => z[28]) = 0; - (a[15] => z[28]) = 0; - (a[16] => z[28]) = 0; - (a[17] => z[28]) = 0; - (a[18] => z[28]) = 0; - (a[19] => z[28]) = 0; - (b[0] => z[28]) = 0; - (b[1] => z[28]) = 0; - (b[2] => z[28]) = 0; - (b[3] => z[28]) = 0; - (b[4] => z[28]) = 0; - (b[5] => z[28]) = 0; - (b[6] => z[28]) = 0; - (b[7] => z[28]) = 0; - (b[8] => z[28]) = 0; - (b[9] => z[28]) = 0; - (b[10] => z[28]) = 0; - (b[11] => z[28]) = 0; - (b[12] => z[28]) = 0; - (b[13] => z[28]) = 0; - (b[14] => z[28]) = 0; - (b[15] => z[28]) = 0; - (b[16] => z[28]) = 0; - (b[17] => z[28]) = 0; - (a[0] => z[29]) = 0; - (a[1] => z[29]) = 0; - (a[2] => z[29]) = 0; - (a[3] => z[29]) = 0; - (a[4] => z[29]) = 0; - (a[5] => z[29]) = 0; - (a[6] => z[29]) = 0; - (a[7] => z[29]) = 0; - (a[8] => z[29]) = 0; - (a[9] => z[29]) = 0; - (a[10] => z[29]) = 0; - (a[11] => z[29]) = 0; - (a[12] => z[29]) = 0; - (a[13] => z[29]) = 0; - (a[14] => z[29]) = 0; - (a[15] => z[29]) = 0; - (a[16] => z[29]) = 0; - (a[17] => z[29]) = 0; - (a[18] => z[29]) = 0; - (a[19] => z[29]) = 0; - (b[0] => z[29]) = 0; - (b[1] => z[29]) = 0; - (b[2] => z[29]) = 0; - (b[3] => z[29]) = 0; - (b[4] => z[29]) = 0; - (b[5] => z[29]) = 0; - (b[6] => z[29]) = 0; - (b[7] => z[29]) = 0; - (b[8] => z[29]) = 0; - (b[9] => z[29]) = 0; - (b[10] => z[29]) = 0; - (b[11] => z[29]) = 0; - (b[12] => z[29]) = 0; - (b[13] => z[29]) = 0; - (b[14] => z[29]) = 0; - (b[15] => z[29]) = 0; - (b[16] => z[29]) = 0; - (b[17] => z[29]) = 0; - (a[0] => z[30]) = 0; - (a[1] => z[30]) = 0; - (a[2] => z[30]) = 0; - (a[3] => z[30]) = 0; - (a[4] => z[30]) = 0; - (a[5] => z[30]) = 0; - (a[6] => z[30]) = 0; - (a[7] => z[30]) = 0; - (a[8] => z[30]) = 0; - (a[9] => z[30]) = 0; - (a[10] => z[30]) = 0; - (a[11] => z[30]) = 0; - (a[12] => z[30]) = 0; - (a[13] => z[30]) = 0; - (a[14] => z[30]) = 0; - (a[15] => z[30]) = 0; - (a[16] => z[30]) = 0; - (a[17] => z[30]) = 0; - (a[18] => z[30]) = 0; - (a[19] => z[30]) = 0; - (b[0] => z[30]) = 0; - (b[1] => z[30]) = 0; - (b[2] => z[30]) = 0; - (b[3] => z[30]) = 0; - (b[4] => z[30]) = 0; - (b[5] => z[30]) = 0; - (b[6] => z[30]) = 0; - (b[7] => z[30]) = 0; - (b[8] => z[30]) = 0; - (b[9] => z[30]) = 0; - (b[10] => z[30]) = 0; - (b[11] => z[30]) = 0; - (b[12] => z[30]) = 0; - (b[13] => z[30]) = 0; - (b[14] => z[30]) = 0; - (b[15] => z[30]) = 0; - (b[16] => z[30]) = 0; - (b[17] => z[30]) = 0; - (a[0] => z[31]) = 0; - (a[1] => z[31]) = 0; - (a[2] => z[31]) = 0; - (a[3] => z[31]) = 0; - (a[4] => z[31]) = 0; - (a[5] => z[31]) = 0; - (a[6] => z[31]) = 0; - (a[7] => z[31]) = 0; - (a[8] => z[31]) = 0; - (a[9] => z[31]) = 0; - (a[10] => z[31]) = 0; - (a[11] => z[31]) = 0; - (a[12] => z[31]) = 0; - (a[13] => z[31]) = 0; - (a[14] => z[31]) = 0; - (a[15] => z[31]) = 0; - (a[16] => z[31]) = 0; - (a[17] => z[31]) = 0; - (a[18] => z[31]) = 0; - (a[19] => z[31]) = 0; - (b[0] => z[31]) = 0; - (b[1] => z[31]) = 0; - (b[2] => z[31]) = 0; - (b[3] => z[31]) = 0; - (b[4] => z[31]) = 0; - (b[5] => z[31]) = 0; - (b[6] => z[31]) = 0; - (b[7] => z[31]) = 0; - (b[8] => z[31]) = 0; - (b[9] => z[31]) = 0; - (b[10] => z[31]) = 0; - (b[11] => z[31]) = 0; - (b[12] => z[31]) = 0; - (b[13] => z[31]) = 0; - (b[14] => z[31]) = 0; - (b[15] => z[31]) = 0; - (b[16] => z[31]) = 0; - (b[17] => z[31]) = 0; - (a[0] => z[32]) = 0; - (a[1] => z[32]) = 0; - (a[2] => z[32]) = 0; - (a[3] => z[32]) = 0; - (a[4] => z[32]) = 0; - (a[5] => z[32]) = 0; - (a[6] => z[32]) = 0; - (a[7] => z[32]) = 0; - (a[8] => z[32]) = 0; - (a[9] => z[32]) = 0; - (a[10] => z[32]) = 0; - (a[11] => z[32]) = 0; - (a[12] => z[32]) = 0; - (a[13] => z[32]) = 0; - (a[14] => z[32]) = 0; - (a[15] => z[32]) = 0; - (a[16] => z[32]) = 0; - (a[17] => z[32]) = 0; - (a[18] => z[32]) = 0; - (a[19] => z[32]) = 0; - (b[0] => z[32]) = 0; - (b[1] => z[32]) = 0; - (b[2] => z[32]) = 0; - (b[3] => z[32]) = 0; - (b[4] => z[32]) = 0; - (b[5] => z[32]) = 0; - (b[6] => z[32]) = 0; - (b[7] => z[32]) = 0; - (b[8] => z[32]) = 0; - (b[9] => z[32]) = 0; - (b[10] => z[32]) = 0; - (b[11] => z[32]) = 0; - (b[12] => z[32]) = 0; - (b[13] => z[32]) = 0; - (b[14] => z[32]) = 0; - (b[15] => z[32]) = 0; - (b[16] => z[32]) = 0; - (b[17] => z[32]) = 0; - (a[0] => z[33]) = 0; - (a[1] => z[33]) = 0; - (a[2] => z[33]) = 0; - (a[3] => z[33]) = 0; - (a[4] => z[33]) = 0; - (a[5] => z[33]) = 0; - (a[6] => z[33]) = 0; - (a[7] => z[33]) = 0; - (a[8] => z[33]) = 0; - (a[9] => z[33]) = 0; - (a[10] => z[33]) = 0; - (a[11] => z[33]) = 0; - (a[12] => z[33]) = 0; - (a[13] => z[33]) = 0; - (a[14] => z[33]) = 0; - (a[15] => z[33]) = 0; - (a[16] => z[33]) = 0; - (a[17] => z[33]) = 0; - (a[18] => z[33]) = 0; - (a[19] => z[33]) = 0; - (b[0] => z[33]) = 0; - (b[1] => z[33]) = 0; - (b[2] => z[33]) = 0; - (b[3] => z[33]) = 0; - (b[4] => z[33]) = 0; - (b[5] => z[33]) = 0; - (b[6] => z[33]) = 0; - (b[7] => z[33]) = 0; - (b[8] => z[33]) = 0; - (b[9] => z[33]) = 0; - (b[10] => z[33]) = 0; - (b[11] => z[33]) = 0; - (b[12] => z[33]) = 0; - (b[13] => z[33]) = 0; - (b[14] => z[33]) = 0; - (b[15] => z[33]) = 0; - (b[16] => z[33]) = 0; - (b[17] => z[33]) = 0; - (a[0] => z[34]) = 0; - (a[1] => z[34]) = 0; - (a[2] => z[34]) = 0; - (a[3] => z[34]) = 0; - (a[4] => z[34]) = 0; - (a[5] => z[34]) = 0; - (a[6] => z[34]) = 0; - (a[7] => z[34]) = 0; - (a[8] => z[34]) = 0; - (a[9] => z[34]) = 0; - (a[10] => z[34]) = 0; - (a[11] => z[34]) = 0; - (a[12] => z[34]) = 0; - (a[13] => z[34]) = 0; - (a[14] => z[34]) = 0; - (a[15] => z[34]) = 0; - (a[16] => z[34]) = 0; - (a[17] => z[34]) = 0; - (a[18] => z[34]) = 0; - (a[19] => z[34]) = 0; - (b[0] => z[34]) = 0; - (b[1] => z[34]) = 0; - (b[2] => z[34]) = 0; - (b[3] => z[34]) = 0; - (b[4] => z[34]) = 0; - (b[5] => z[34]) = 0; - (b[6] => z[34]) = 0; - (b[7] => z[34]) = 0; - (b[8] => z[34]) = 0; - (b[9] => z[34]) = 0; - (b[10] => z[34]) = 0; - (b[11] => z[34]) = 0; - (b[12] => z[34]) = 0; - (b[13] => z[34]) = 0; - (b[14] => z[34]) = 0; - (b[15] => z[34]) = 0; - (b[16] => z[34]) = 0; - (b[17] => z[34]) = 0; - (a[0] => z[35]) = 0; - (a[1] => z[35]) = 0; - (a[2] => z[35]) = 0; - (a[3] => z[35]) = 0; - (a[4] => z[35]) = 0; - (a[5] => z[35]) = 0; - (a[6] => z[35]) = 0; - (a[7] => z[35]) = 0; - (a[8] => z[35]) = 0; - (a[9] => z[35]) = 0; - (a[10] => z[35]) = 0; - (a[11] => z[35]) = 0; - (a[12] => z[35]) = 0; - (a[13] => z[35]) = 0; - (a[14] => z[35]) = 0; - (a[15] => z[35]) = 0; - (a[16] => z[35]) = 0; - (a[17] => z[35]) = 0; - (a[18] => z[35]) = 0; - (a[19] => z[35]) = 0; - (b[0] => z[35]) = 0; - (b[1] => z[35]) = 0; - (b[2] => z[35]) = 0; - (b[3] => z[35]) = 0; - (b[4] => z[35]) = 0; - (b[5] => z[35]) = 0; - (b[6] => z[35]) = 0; - (b[7] => z[35]) = 0; - (b[8] => z[35]) = 0; - (b[9] => z[35]) = 0; - (b[10] => z[35]) = 0; - (b[11] => z[35]) = 0; - (b[12] => z[35]) = 0; - (b[13] => z[35]) = 0; - (b[14] => z[35]) = 0; - (b[15] => z[35]) = 0; - (b[16] => z[35]) = 0; - (b[17] => z[35]) = 0; - (a[0] => z[36]) = 0; - (a[1] => z[36]) = 0; - (a[2] => z[36]) = 0; - (a[3] => z[36]) = 0; - (a[4] => z[36]) = 0; - (a[5] => z[36]) = 0; - (a[6] => z[36]) = 0; - (a[7] => z[36]) = 0; - (a[8] => z[36]) = 0; - (a[9] => z[36]) = 0; - (a[10] => z[36]) = 0; - (a[11] => z[36]) = 0; - (a[12] => z[36]) = 0; - (a[13] => z[36]) = 0; - (a[14] => z[36]) = 0; - (a[15] => z[36]) = 0; - (a[16] => z[36]) = 0; - (a[17] => z[36]) = 0; - (a[18] => z[36]) = 0; - (a[19] => z[36]) = 0; - (b[0] => z[36]) = 0; - (b[1] => z[36]) = 0; - (b[2] => z[36]) = 0; - (b[3] => z[36]) = 0; - (b[4] => z[36]) = 0; - (b[5] => z[36]) = 0; - (b[6] => z[36]) = 0; - (b[7] => z[36]) = 0; - (b[8] => z[36]) = 0; - (b[9] => z[36]) = 0; - (b[10] => z[36]) = 0; - (b[11] => z[36]) = 0; - (b[12] => z[36]) = 0; - (b[13] => z[36]) = 0; - (b[14] => z[36]) = 0; - (b[15] => z[36]) = 0; - (b[16] => z[36]) = 0; - (b[17] => z[36]) = 0; - (a[0] => z[37]) = 0; - (a[1] => z[37]) = 0; - (a[2] => z[37]) = 0; - (a[3] => z[37]) = 0; - (a[4] => z[37]) = 0; - (a[5] => z[37]) = 0; - (a[6] => z[37]) = 0; - (a[7] => z[37]) = 0; - (a[8] => z[37]) = 0; - (a[9] => z[37]) = 0; - (a[10] => z[37]) = 0; - (a[11] => z[37]) = 0; - (a[12] => z[37]) = 0; - (a[13] => z[37]) = 0; - (a[14] => z[37]) = 0; - (a[15] => z[37]) = 0; - (a[16] => z[37]) = 0; - (a[17] => z[37]) = 0; - (a[18] => z[37]) = 0; - (a[19] => z[37]) = 0; - (b[0] => z[37]) = 0; - (b[1] => z[37]) = 0; - (b[2] => z[37]) = 0; - (b[3] => z[37]) = 0; - (b[4] => z[37]) = 0; - (b[5] => z[37]) = 0; - (b[6] => z[37]) = 0; - (b[7] => z[37]) = 0; - (b[8] => z[37]) = 0; - (b[9] => z[37]) = 0; - (b[10] => z[37]) = 0; - (b[11] => z[37]) = 0; - (b[12] => z[37]) = 0; - (b[13] => z[37]) = 0; - (b[14] => z[37]) = 0; - (b[15] => z[37]) = 0; - (b[16] => z[37]) = 0; - (b[17] => z[37]) = 0; - (subtract => z[0]) = 0; - (subtract => z[1]) = 0; - (subtract => z[2]) = 0; - (subtract => z[3]) = 0; - (subtract => z[4]) = 0; - (subtract => z[5]) = 0; - (subtract => z[6]) = 0; - (subtract => z[7]) = 0; - (subtract => z[8]) = 0; - (subtract => z[9]) = 0; - (subtract => z[10]) = 0; - (subtract => z[11]) = 0; - (subtract => z[12]) = 0; - (subtract => z[13]) = 0; - (subtract => z[14]) = 0; - (subtract => z[15]) = 0; - (subtract => z[16]) = 0; - (subtract => z[17]) = 0; - (subtract => z[18]) = 0; - (subtract => z[19]) = 0; - (subtract => z[20]) = 0; - (subtract => z[21]) = 0; - (subtract => z[22]) = 0; - (subtract => z[23]) = 0; - (subtract => z[24]) = 0; - (subtract => z[25]) = 0; - (subtract => z[26]) = 0; - (subtract => z[27]) = 0; - (subtract => z[28]) = 0; - (subtract => z[29]) = 0; - (subtract => z[30]) = 0; - (subtract => z[31]) = 0; - (subtract => z[32]) = 0; - (subtract => z[33]) = 0; - (subtract => z[34]) = 0; - (subtract => z[35]) = 0; - (subtract => z[36]) = 0; - (subtract => z[37]) = 0; - (acc_fir[0] => z[0]) = 0; - (acc_fir[1] => z[0]) = 0; - (acc_fir[2] => z[0]) = 0; - (acc_fir[3] => z[0]) = 0; - (acc_fir[4] => z[0]) = 0; - (acc_fir[5] => z[0]) = 0; - (acc_fir[0] => z[1]) = 0; - (acc_fir[1] => z[1]) = 0; - (acc_fir[2] => z[1]) = 0; - (acc_fir[3] => z[1]) = 0; - (acc_fir[4] => z[1]) = 0; - (acc_fir[5] => z[1]) = 0; - (acc_fir[0] => z[2]) = 0; - (acc_fir[1] => z[2]) = 0; - (acc_fir[2] => z[2]) = 0; - (acc_fir[3] => z[2]) = 0; - (acc_fir[4] => z[2]) = 0; - (acc_fir[5] => z[2]) = 0; - (acc_fir[0] => z[3]) = 0; - (acc_fir[1] => z[3]) = 0; - (acc_fir[2] => z[3]) = 0; - (acc_fir[3] => z[3]) = 0; - (acc_fir[4] => z[3]) = 0; - (acc_fir[5] => z[3]) = 0; - (acc_fir[0] => z[4]) = 0; - (acc_fir[1] => z[4]) = 0; - (acc_fir[2] => z[4]) = 0; - (acc_fir[3] => z[4]) = 0; - (acc_fir[4] => z[4]) = 0; - (acc_fir[5] => z[4]) = 0; - (acc_fir[0] => z[5]) = 0; - (acc_fir[1] => z[5]) = 0; - (acc_fir[2] => z[5]) = 0; - (acc_fir[3] => z[5]) = 0; - (acc_fir[4] => z[5]) = 0; - (acc_fir[5] => z[5]) = 0; - (acc_fir[0] => z[6]) = 0; - (acc_fir[1] => z[6]) = 0; - (acc_fir[2] => z[6]) = 0; - (acc_fir[3] => z[6]) = 0; - (acc_fir[4] => z[6]) = 0; - (acc_fir[5] => z[6]) = 0; - (acc_fir[0] => z[7]) = 0; - (acc_fir[1] => z[7]) = 0; - (acc_fir[2] => z[7]) = 0; - (acc_fir[3] => z[7]) = 0; - (acc_fir[4] => z[7]) = 0; - (acc_fir[5] => z[7]) = 0; - (acc_fir[0] => z[8]) = 0; - (acc_fir[1] => z[8]) = 0; - (acc_fir[2] => z[8]) = 0; - (acc_fir[3] => z[8]) = 0; - (acc_fir[4] => z[8]) = 0; - (acc_fir[5] => z[8]) = 0; - (acc_fir[0] => z[9]) = 0; - (acc_fir[1] => z[9]) = 0; - (acc_fir[2] => z[9]) = 0; - (acc_fir[3] => z[9]) = 0; - (acc_fir[4] => z[9]) = 0; - (acc_fir[5] => z[9]) = 0; - (acc_fir[0] => z[10]) = 0; - (acc_fir[1] => z[10]) = 0; - (acc_fir[2] => z[10]) = 0; - (acc_fir[3] => z[10]) = 0; - (acc_fir[4] => z[10]) = 0; - (acc_fir[5] => z[10]) = 0; - (acc_fir[0] => z[11]) = 0; - (acc_fir[1] => z[11]) = 0; - (acc_fir[2] => z[11]) = 0; - (acc_fir[3] => z[11]) = 0; - (acc_fir[4] => z[11]) = 0; - (acc_fir[5] => z[11]) = 0; - (acc_fir[0] => z[12]) = 0; - (acc_fir[1] => z[12]) = 0; - (acc_fir[2] => z[12]) = 0; - (acc_fir[3] => z[12]) = 0; - (acc_fir[4] => z[12]) = 0; - (acc_fir[5] => z[12]) = 0; - (acc_fir[0] => z[13]) = 0; - (acc_fir[1] => z[13]) = 0; - (acc_fir[2] => z[13]) = 0; - (acc_fir[3] => z[13]) = 0; - (acc_fir[4] => z[13]) = 0; - (acc_fir[5] => z[13]) = 0; - (acc_fir[0] => z[14]) = 0; - (acc_fir[1] => z[14]) = 0; - (acc_fir[2] => z[14]) = 0; - (acc_fir[3] => z[14]) = 0; - (acc_fir[4] => z[14]) = 0; - (acc_fir[5] => z[14]) = 0; - (acc_fir[0] => z[15]) = 0; - (acc_fir[1] => z[15]) = 0; - (acc_fir[2] => z[15]) = 0; - (acc_fir[3] => z[15]) = 0; - (acc_fir[4] => z[15]) = 0; - (acc_fir[5] => z[15]) = 0; - (acc_fir[0] => z[16]) = 0; - (acc_fir[1] => z[16]) = 0; - (acc_fir[2] => z[16]) = 0; - (acc_fir[3] => z[16]) = 0; - (acc_fir[4] => z[16]) = 0; - (acc_fir[5] => z[16]) = 0; - (acc_fir[0] => z[17]) = 0; - (acc_fir[1] => z[17]) = 0; - (acc_fir[2] => z[17]) = 0; - (acc_fir[3] => z[17]) = 0; - (acc_fir[4] => z[17]) = 0; - (acc_fir[5] => z[17]) = 0; - (acc_fir[0] => z[18]) = 0; - (acc_fir[1] => z[18]) = 0; - (acc_fir[2] => z[18]) = 0; - (acc_fir[3] => z[18]) = 0; - (acc_fir[4] => z[18]) = 0; - (acc_fir[5] => z[18]) = 0; - (acc_fir[0] => z[19]) = 0; - (acc_fir[1] => z[19]) = 0; - (acc_fir[2] => z[19]) = 0; - (acc_fir[3] => z[19]) = 0; - (acc_fir[4] => z[19]) = 0; - (acc_fir[5] => z[19]) = 0; - (acc_fir[0] => z[20]) = 0; - (acc_fir[1] => z[20]) = 0; - (acc_fir[2] => z[20]) = 0; - (acc_fir[3] => z[20]) = 0; - (acc_fir[4] => z[20]) = 0; - (acc_fir[5] => z[20]) = 0; - (acc_fir[0] => z[21]) = 0; - (acc_fir[1] => z[21]) = 0; - (acc_fir[2] => z[21]) = 0; - (acc_fir[3] => z[21]) = 0; - (acc_fir[4] => z[21]) = 0; - (acc_fir[5] => z[21]) = 0; - (acc_fir[0] => z[22]) = 0; - (acc_fir[1] => z[22]) = 0; - (acc_fir[2] => z[22]) = 0; - (acc_fir[3] => z[22]) = 0; - (acc_fir[4] => z[22]) = 0; - (acc_fir[5] => z[22]) = 0; - (acc_fir[0] => z[23]) = 0; - (acc_fir[1] => z[23]) = 0; - (acc_fir[2] => z[23]) = 0; - (acc_fir[3] => z[23]) = 0; - (acc_fir[4] => z[23]) = 0; - (acc_fir[5] => z[23]) = 0; - (acc_fir[0] => z[24]) = 0; - (acc_fir[1] => z[24]) = 0; - (acc_fir[2] => z[24]) = 0; - (acc_fir[3] => z[24]) = 0; - (acc_fir[4] => z[24]) = 0; - (acc_fir[5] => z[24]) = 0; - (acc_fir[0] => z[25]) = 0; - (acc_fir[1] => z[25]) = 0; - (acc_fir[2] => z[25]) = 0; - (acc_fir[3] => z[25]) = 0; - (acc_fir[4] => z[25]) = 0; - (acc_fir[5] => z[25]) = 0; - (acc_fir[0] => z[26]) = 0; - (acc_fir[1] => z[26]) = 0; - (acc_fir[2] => z[26]) = 0; - (acc_fir[3] => z[26]) = 0; - (acc_fir[4] => z[26]) = 0; - (acc_fir[5] => z[26]) = 0; - (acc_fir[0] => z[27]) = 0; - (acc_fir[1] => z[27]) = 0; - (acc_fir[2] => z[27]) = 0; - (acc_fir[3] => z[27]) = 0; - (acc_fir[4] => z[27]) = 0; - (acc_fir[5] => z[27]) = 0; - (acc_fir[0] => z[28]) = 0; - (acc_fir[1] => z[28]) = 0; - (acc_fir[2] => z[28]) = 0; - (acc_fir[3] => z[28]) = 0; - (acc_fir[4] => z[28]) = 0; - (acc_fir[5] => z[28]) = 0; - (acc_fir[0] => z[29]) = 0; - (acc_fir[1] => z[29]) = 0; - (acc_fir[2] => z[29]) = 0; - (acc_fir[3] => z[29]) = 0; - (acc_fir[4] => z[29]) = 0; - (acc_fir[5] => z[29]) = 0; - (acc_fir[0] => z[30]) = 0; - (acc_fir[1] => z[30]) = 0; - (acc_fir[2] => z[30]) = 0; - (acc_fir[3] => z[30]) = 0; - (acc_fir[4] => z[30]) = 0; - (acc_fir[5] => z[30]) = 0; - (acc_fir[0] => z[31]) = 0; - (acc_fir[1] => z[31]) = 0; - (acc_fir[2] => z[31]) = 0; - (acc_fir[3] => z[31]) = 0; - (acc_fir[4] => z[31]) = 0; - (acc_fir[5] => z[31]) = 0; - (acc_fir[0] => z[32]) = 0; - (acc_fir[1] => z[32]) = 0; - (acc_fir[2] => z[32]) = 0; - (acc_fir[3] => z[32]) = 0; - (acc_fir[4] => z[32]) = 0; - (acc_fir[5] => z[32]) = 0; - (acc_fir[0] => z[33]) = 0; - (acc_fir[1] => z[33]) = 0; - (acc_fir[2] => z[33]) = 0; - (acc_fir[3] => z[33]) = 0; - (acc_fir[4] => z[33]) = 0; - (acc_fir[5] => z[33]) = 0; - (acc_fir[0] => z[34]) = 0; - (acc_fir[1] => z[34]) = 0; - (acc_fir[2] => z[34]) = 0; - (acc_fir[3] => z[34]) = 0; - (acc_fir[4] => z[34]) = 0; - (acc_fir[5] => z[34]) = 0; - (acc_fir[0] => z[35]) = 0; - (acc_fir[1] => z[35]) = 0; - (acc_fir[2] => z[35]) = 0; - (acc_fir[3] => z[35]) = 0; - (acc_fir[4] => z[35]) = 0; - (acc_fir[5] => z[35]) = 0; - (acc_fir[0] => z[36]) = 0; - (acc_fir[1] => z[36]) = 0; - (acc_fir[2] => z[36]) = 0; - (acc_fir[3] => z[36]) = 0; - (acc_fir[4] => z[36]) = 0; - (acc_fir[5] => z[36]) = 0; - (acc_fir[0] => z[37]) = 0; - (acc_fir[1] => z[37]) = 0; - (acc_fir[2] => z[37]) = 0; - (acc_fir[3] => z[37]) = 0; - (acc_fir[4] => z[37]) = 0; - (acc_fir[5] => z[37]) = 0; - endspecify -`endif - -endmodule - -module QL_DSP2_MULTADD_REGIN ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, - - (* clkbuf_sink *) - input wire clk, - input wire reset, - - input wire [ 2:0] feedback, - input wire [ 5:0] acc_fir, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs -); - - parameter [79:0] MODE_BITS = 80'd0; - - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .dly_b(), - .z(z), - - .f_mode(f_mode), - - .feedback(feedback), - .acc_fir(acc_fir), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(1'b0), - .output_select(output_select), // unregistered output: ACCin (2, 3) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // registered inputs - ); + .a_cin(), + .b_cin(), + .z_cin(), -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - $setuphold(posedge clk, acc_fir, 0, 0); - endspecify -`endif + .z_cout(), + .a_cout(), + .b_cout() + ); endmodule -module QL_DSP2_MULTADD_REGOUT ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTADD_REGOUT ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, + (* clkbuf_sink *) + input wire clk, + input wire reset, - input wire [ 2:0] feedback, - input wire [ 5:0] acc_fir, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h00000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .dly_b(), - .z(z), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), .feedback(feedback), - .acc_fir(acc_fir), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(1'b0), - .output_select(output_select), // registered output: ACCin (6, 7) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // unregistered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - $setuphold(posedge clk, acc_fir, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULTADD_REGIN_REGOUT ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTADD_REGIN_REGOUT ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, + (* clkbuf_sink *) + input wire clk, + input wire reset, - input wire [ 2:0] feedback, - input wire [ 5:0] acc_fir, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h0A000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .dly_b(), - .z(z), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(1'b0), .feedback(feedback), - .acc_fir(acc_fir), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(1'b0), - .output_select(output_select), // registered output: ACCin (6, 7) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // registered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - $setuphold(posedge clk, acc_fir, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULTACC ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTACC ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, - - input wire load_acc, - input wire [ 2:0] feedback, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + (* clkbuf_sink *) + input wire clk, + input wire reset, + input wire acc_reset, + input wire load_acc, + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h00000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(load_acc), .feedback(feedback), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(acc_reset), - .output_select(output_select), // unregistered output: ACCout (1) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // unregistered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULTACC_REGIN ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTACC_REGIN ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, - - input wire [ 2:0] feedback, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + (* clkbuf_sink *) + input wire clk, + input wire reset, + input wire acc_reset, + input wire load_acc, + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h04000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(load_acc), .feedback(feedback), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(acc_reset), - .output_select(output_select), // unregistered output: ACCout (1) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // registered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULTACC_REGOUT ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTACC_REGOUT ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, - - input wire [ 2:0] feedback, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + (* clkbuf_sink *) + input wire clk, + input wire reset, + input wire acc_reset, + input wire load_acc, + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h00000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(load_acc), .feedback(feedback), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(acc_reset), - .output_select(output_select), // registered output: ACCout (5) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // unregistered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module QL_DSP2_MULTACC_REGIN_REGOUT ( - input wire [19:0] a, - input wire [17:0] b, - output wire [37:0] z, +module QL_DSPV2_MULTACC_REGIN_REGOUT ( + input wire [31:0] a, + input wire [17:0] b, + output wire [49:0] z, - (* clkbuf_sink *) - input wire clk, - input wire reset, - - input wire [ 2:0] feedback, - input wire load_acc, - input wire unsigned_a, - input wire unsigned_b, - - input wire f_mode, - input wire [ 2:0] output_select, - input wire saturate_enable, - input wire [ 5:0] shift_right, - input wire round, - input wire subtract, - input wire register_inputs + (* clkbuf_sink *) + input wire clk, + input wire reset, + input wire acc_reset, + input wire load_acc, + input wire [ 2:0] feedback, + input wire [ 2:0] output_select ); - parameter [79:0] MODE_BITS = 80'd0; + parameter [67:0] MODE_BITS = 68'h04000000000000000; - localparam [19:0] COEFF_0 = MODE_BITS[19:0]; - localparam [19:0] COEFF_1 = MODE_BITS[39:20]; - localparam [19:0] COEFF_2 = MODE_BITS[59:40]; - localparam [19:0] COEFF_3 = MODE_BITS[79:60]; - - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a), - .b(b), - .acc_fir(6'b0), - .z(z), - .dly_b(), - - .f_mode(f_mode), + localparam [31:0] COEFF_0 = MODE_BITS[31:0]; + localparam [5:0] ACC_FIR = MODE_BITS[37:32]; + localparam [2:0] ROUND = MODE_BITS[40:38]; + localparam [4:0] ZC_SHIFT = MODE_BITS[45:41]; + localparam [4:0] ZREG_SHIFT= MODE_BITS[50:46]; + localparam [5:0] SHIFT_REG = MODE_BITS[56:51]; + localparam SATURATE = MODE_BITS[57]; + localparam SUBTRACT = MODE_BITS[58]; + localparam PRE_ADD = MODE_BITS[59]; + localparam A_SEL = MODE_BITS[60]; + localparam A_REG = MODE_BITS[61]; + localparam B_SEL = MODE_BITS[62]; + localparam B_REG = MODE_BITS[63]; + localparam C_REG = MODE_BITS[64]; + localparam BC_REG = MODE_BITS[65]; + localparam M_REG = MODE_BITS[66]; + localparam FRAC_MODE = MODE_BITS[67]; + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a), + .b(b), + .c(18'h0), + .load_acc(load_acc), .feedback(feedback), - .load_acc(load_acc), - - .unsigned_a(unsigned_a), - .unsigned_b(unsigned_b), - + .output_select(output_select), + .z(z), + .clk(clk), - .reset(reset), + .reset(reset), + .acc_reset(acc_reset), - .output_select(output_select), // registered output: ACCout (5) - .saturate_enable(saturate_enable), - .shift_right(shift_right), - .round(round), - .subtract(subtract), - .register_inputs(register_inputs) // registered inputs - ); - -`ifdef SDF_SIM - specify - (posedge clk => (z +: a)) = 0; - (posedge clk => (z +: b)) = 0; - $setuphold(posedge clk, a, 0, 0); - $setuphold(posedge clk, b, 0, 0); - $setuphold(posedge clk, feedback, 0, 0); - $setuphold(posedge clk, load_acc, 0, 0); - $setuphold(posedge clk, subtract, 0, 0); - endspecify -`endif + .a_cin(), + .b_cin(), + .z_cin(), + .z_cout(), + .a_cout(), + .b_cout() + ); + endmodule -module dsp_t1_20x18x64_cfg_ports ( - input wire [19:0] a_i, - input wire [17:0] b_i, - input wire [ 5:0] acc_fir_i, - output wire [37:0] z_o, - output wire [17:0] dly_b_o, +module dspv2_32x18x64_cfg_ports ( + input wire [31:0] a_i, + input wire [17:0] b_i, + input wire [17:0] c_i, + output wire [49:0] z_o, - (* clkbuf_sink *) - input wire clock_i, - input wire reset_i, + (* clkbuf_sink *) + input wire clock_i, + input wire reset_i, + input wire acc_reset_i, - input wire [ 2:0] feedback_i, - input wire load_acc_i, - input wire unsigned_a_i, - input wire unsigned_b_i, + input wire [ 2:0] feedback_i, + input wire load_acc_i, + input wire [ 2:0] output_select_i, + + input wire [31:0] a_cin_i, + input wire [17:0] b_cin_i, + input wire [49:0] z_cin_i, + + output wire [31:0] a_cout_o, + output wire [17:0] b_cout_o, + output wire [49:0] z_cout_o - input wire [ 2:0] output_select_i, - input wire saturate_enable_i, - input wire [ 5:0] shift_right_i, - input wire round_i, - input wire subtract_i, - input wire register_inputs_i ); - parameter [19:0] COEFF_0 = 20'd0; - parameter [19:0] COEFF_1 = 20'd0; - parameter [19:0] COEFF_2 = 20'd0; - parameter [19:0] COEFF_3 = 20'd0; + parameter [31:0] COEFF_0 = 32'h0; + parameter [5:0] ACC_FIR = 6'h0; + parameter [2:0] ROUND = 3'h0; + parameter [4:0] ZC_SHIFT = 5'h0; + parameter [4:0] ZREG_SHIFT = 5'h0; + parameter [5:0] SHIFT_REG = 6'h0; + parameter SATURATE = 1'b0; + parameter SUBTRACT = 1'b0; + parameter PRE_ADD = 1'b0; + parameter A_SEL = 1'b0; + parameter A_REG = 1'b0; + parameter B_SEL = 1'b0; + parameter B_REG = 1'b0; + parameter C_REG = 1'b0; + parameter BC_REG = 1'b0; + parameter M_REG = 1'b0; + parameter FRAC_MODE = 1'b0; // 32x18x64 DSP - QL_DSP2 #( - .MODE_BITS({COEFF_3, COEFF_2, COEFF_1, COEFF_0}) - ) dsp ( - .a(a_i), - .b(b_i), - .z(z_o), - .dly_b(dly_b_o), - - .f_mode(1'b0), // 20x18x64 DSP - - .acc_fir(acc_fir_i), + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,COEFF_0}) + ) dsp ( + .a(a_i), + .b(b_i), + .c(c_i), + .load_acc(load_acc_i), .feedback(feedback_i), - .load_acc(load_acc_i), - - .unsigned_a(unsigned_a_i), - .unsigned_b(unsigned_b_i), - - .clk(clock_i), - .reset(reset_i), - - .saturate_enable(saturate_enable_i), .output_select(output_select_i), - .round(round_i), - .shift_right(shift_right_i), - .subtract(subtract_i), - .register_inputs(register_inputs_i) - ); + .z(z_o), + + .clk(clock_i), + .reset(reset_i), + .acc_reset(acc_reset_i), + + .a_cin(a_cin_i), + .b_cin(b_cin_i), + .z_cin(z_cin_i), + + .z_cout(a_cout_o), + .a_cout(b_cout_o), + .b_cout(z_cout_o) + ); + endmodule -module dsp_t1_10x9x32_cfg_ports ( - input wire [ 9:0] a_i, - input wire [ 8:0] b_i, - input wire [ 5:0] acc_fir_i, - output wire [18:0] z_o, - output wire [ 8:0] dly_b_o, +module dspv2_16x9x32_cfg_ports ( + input wire [15:0] a_i, + input wire [8:0] b_i, + input wire [9:0] c_i, + output wire [24:0] z_o, - (* clkbuf_sink *) - input wire clock_i, - input wire reset_i, + (* clkbuf_sink *) + input wire clock_i, + input wire reset_i, + input wire acc_reset_i, - input wire [ 2:0] feedback_i, - input wire load_acc_i, - input wire unsigned_a_i, - input wire unsigned_b_i, + input wire [ 2:0] feedback_i, + input wire load_acc_i, + input wire [ 2:0] output_select_i, + + input wire [15:0] a_cin_i, + input wire [8:0] b_cin_i, + input wire [24:0] z_cin_i, + + output wire [15:0] a_cout_o, + output wire [8:0] b_cout_o, + output wire [24:0] z_cout_o - input wire [ 2:0] output_select_i, - input wire saturate_enable_i, - input wire [ 5:0] shift_right_i, - input wire round_i, - input wire subtract_i, - input wire register_inputs_i ); - parameter [9:0] COEFF_0 = 10'd0; - parameter [9:0] COEFF_1 = 10'd0; - parameter [9:0] COEFF_2 = 10'd0; - parameter [9:0] COEFF_3 = 10'd0; + parameter [15:0] COEFF_0 = 16'h0; + parameter [5:0] ACC_FIR = 6'h0; + parameter [2:0] ROUND = 3'h0; + parameter [4:0] ZC_SHIFT = 5'h0; + parameter [4:0] ZREG_SHIFT = 5'h0; + parameter [5:0] SHIFT_REG = 6'h0; + parameter SATURATE = 1'b0; + parameter SUBTRACT = 1'b0; + parameter PRE_ADD = 1'b0; + parameter A_SEL = 1'b0; + parameter A_REG = 1'b0; + parameter B_SEL = 1'b0; + parameter B_REG = 1'b0; + parameter C_REG = 1'b0; + parameter BC_REG = 1'b0; + parameter M_REG = 1'b0; + parameter FRAC_MODE = 1'b1; // 16x9x32 DSP - wire [18:0] z_rem; - wire [8:0] dly_b_rem; - - QL_DSP2 #( - .MODE_BITS({10'd0, COEFF_3, - 10'd0, COEFF_2, - 10'd0, COEFF_1, - 10'd0, COEFF_0}) - ) dsp ( - .a({10'd0, a_i}), - .b({9'd0, b_i}), - .z({z_rem, z_o}), - .dly_b({dly_b_rem, dly_b_o}), - - .f_mode(1'b1), // 10x9x32 DSP - - .acc_fir(acc_fir_i), + QL_DSPV2 #( + .MODE_BITS({FRAC_MODE,M_REG,BC_REG,C_REG,B_REG,B_SEL,A_REG,A_SEL,PRE_ADD,SUBTRACT,SATURATE,SHIFT_REG,ZREG_SHIFT,ZC_SHIFT,ROUND,ACC_FIR,16'h0,COEFF_0}) + ) dsp ( + .a(a_i), + .b(b_i), + .c(c_i), + .load_acc(load_acc_i), .feedback(feedback_i), - .load_acc(load_acc_i), - - .unsigned_a(unsigned_a_i), - .unsigned_b(unsigned_b_i), - - .clk(clock_i), - .reset(reset_i), - - .saturate_enable(saturate_enable_i), .output_select(output_select_i), - .round(round_i), - .shift_right(shift_right_i), - .subtract(subtract_i), - .register_inputs(register_inputs_i) - ); + .z(z_o), + + .clk(clock_i), + .reset(reset_i), + .acc_reset(acc_reset_i), + + .a_cin(a_cin_i), + .b_cin(b_cin_i), + .z_cin(z_cin_i), + + .z_cout(a_cout_o), + .a_cout(b_cout_o), + .b_cout(z_cout_o) + ); + endmodule -module dsp_t1_sim_cfg_ports # ( - parameter NBITS_ACC = 64, - parameter NBITS_A = 20, - parameter NBITS_B = 18, - parameter NBITS_Z = 38 + +module dspv2_sim_cfg_ports # ( + parameter NBITS_ACC = 64, + parameter NBITS_A = 32, + parameter NBITS_BC = 18, + parameter NBITS_Z = 50 )( - input wire [NBITS_A-1:0] a_i, - input wire [NBITS_B-1:0] b_i, - output wire [NBITS_Z-1:0] z_o, - output reg [NBITS_B-1:0] dly_b_o, - - input wire [5:0] acc_fir_i, - input wire [2:0] feedback_i, - input wire load_acc_i, - - input wire unsigned_a_i, - input wire unsigned_b_i, - - input wire clock_i, - input wire s_reset, - + // active/fabric ports + input wire clock_i, + input wire s_reset, + input wire [NBITS_A-1:0] a_i, + input wire [NBITS_BC-1:0] b_i, + input wire [NBITS_BC-1:0] c_i, + input wire [2:0] feedback_i, + input wire [2:0] output_select_i, + input wire load_acc_i, + input wire rst_acc_i, + output wire [NBITS_Z-1:0] z_o, + + // cascade ports (connect to dedicated cascade routing) + input wire [NBITS_A-1:0] a_cin_i, + input wire [NBITS_BC-1:0] b_cin_i, + input wire [NBITS_Z-1:0] z_cin_i, + output wire [NBITS_Z-1:0] z_cout_o, + output wire [NBITS_A-1:0] a_cout_o, + output wire [NBITS_BC-1:0] b_cout_o, + + // configuration ports (tie-offs) + input wire [NBITS_A-1:0] coeff_i, + input wire [5:0] acc_fir_i, + input wire [2:0] round_i, + input wire [4:0] zc_shift_i, + input wire [4:0] zreg_shift_i, + input wire [5:0] shift_right_i, input wire saturate_enable_i, - input wire [2:0] output_select_i, - input wire round_i, - input wire [5:0] shift_right_i, input wire subtract_i, - input wire register_inputs_i, - input wire [NBITS_A-1:0] coef_0_i, - input wire [NBITS_A-1:0] coef_1_i, - input wire [NBITS_A-1:0] coef_2_i, - input wire [NBITS_A-1:0] coef_3_i + input wire pre_add_sel_i, + input wire a_sel_i, + input wire a_reg_i, + input wire b_sel_i, + input wire b_reg_i, + input wire c_reg_i, + input wire bc_reg_i, + input wire m_reg_i ); -// FIXME: The version of Icarus Verilog from Conda seems not to recognize the -// $error macro. Disable this sanity check for now because of that. + // Input registers + reg [NBITS_A-1:0] r_a; + reg [NBITS_BC-1:0] r_b; + reg [NBITS_BC-1:0] r_c; + reg [NBITS_ACC-1:0] acc; + + wire [NBITS_A-1:0] a_acin_dat; + wire [NBITS_BC-1:0] b_bcin_dat; + + wire [NBITS_A-1:0] a; + wire [NBITS_BC-1:0] b; + wire [NBITS_BC-1:0] c; + + wire [NBITS_BC:0] preadd_raw; + + reg [NBITS_BC-1:0] preadd_sat; + reg [NBITS_BC-1:0] preadd_sat_r; + wire [NBITS_BC-1:0] preadd; - // Input registers - reg [NBITS_A-1:0] r_a; - reg [NBITS_B-1:0] r_b; - reg [5:0] r_acc_fir; - reg r_unsigned_a; - reg r_unsigned_b; - reg r_load_acc; - reg [2:0] r_feedback; - reg [5:0] r_shift_d1; - reg [5:0] r_shift_d2; - reg r_subtract; - reg r_sat; - reg r_rnd; - reg [NBITS_ACC-1:0] acc; + initial begin + r_a <= 0; + r_b <= 0; + r_c <= 0; + end + + assign a_acin_dat = (a_sel_i)? a_cin_i: a_i; + assign b_bcin_dat = (b_sel_i)? b_cin_i: b_i; - initial begin - r_a <= 0; - r_b <= 0; - - r_acc_fir <= 0; - r_unsigned_a <= 0; - r_unsigned_b <= 0; - r_feedback <= 0; - r_shift_d1 <= 0; - r_shift_d2 <= 0; - r_subtract <= 0; - r_load_acc <= 0; - r_sat <= 0; - r_rnd <= 0; - end - - always @(posedge clock_i or posedge s_reset) begin - if (s_reset) begin - - r_a <= 'h0; - r_b <= 'h0; - - r_acc_fir <= 0; - r_unsigned_a <= 0; - r_unsigned_b <= 0; - r_feedback <= 0; - r_shift_d1 <= 0; - r_shift_d2 <= 0; - r_subtract <= 0; - r_load_acc <= 0; - r_sat <= 0; - r_rnd <= 0; + always @(posedge clock_i or posedge s_reset) begin + if (s_reset) begin + r_a <= 0; + r_b <= 0; + r_c <= 0; + end else begin + r_a <= a_acin_dat; + r_b <= b_bcin_dat; + r_c <= c_i; + end + end + // Registered / non-registered input path select + assign a = (a_reg_i) ? r_a : a_acin_dat; + assign b = (b_reg_i) ? r_b : b_bcin_dat; + assign c = (c_reg_i) ? r_c : c_i; + + assign preadd_raw = b + c; + + always @(*) begin + if (!b[(NBITS_BC-1)] && !c[(NBITS_BC-1)]) begin // pos+pos + if (preadd_raw[(NBITS_BC-1)]) begin + preadd_sat = {1'b0, {(NBITS_BC-1){1'b1}}}; // max pos # + end else begin + preadd_sat = preadd_raw[(NBITS_BC-1):0]; + end end else begin - - r_a <= a_i; - r_b <= b_i; - - r_acc_fir <= acc_fir_i; - r_unsigned_a <= unsigned_a_i; - r_unsigned_b <= unsigned_b_i; - r_feedback <= feedback_i; - r_shift_d1 <= shift_right_i; - r_shift_d2 <= r_shift_d1; - r_subtract <= subtract_i; - r_load_acc <= load_acc_i; - r_sat <= r_sat; - r_rnd <= r_rnd; - + if (b[(NBITS_BC-1)] && c[(NBITS_BC-1)]) begin // neg+neg + if (!preadd_raw[(NBITS_BC-1)]) begin + preadd_sat = {1'b1, {(NBITS_BC-1){1'b0}}}; // max neg # + end else begin + preadd_sat = preadd_raw[(NBITS_BC-1):0]; + end + end else begin // pos+neg or neg+pos + preadd_sat = preadd_raw[(NBITS_BC-1):0]; + end end end + + always @(posedge clock_i or posedge s_reset) begin + if (s_reset) begin + preadd_sat_r <= 0; + end else begin + preadd_sat_r <= preadd_sat; + end + end + + assign preadd = (bc_reg_i)? preadd_sat_r : preadd_sat; - // Registered / non-registered input path select - wire [NBITS_A-1:0] a = register_inputs_i ? r_a : a_i; - wire [NBITS_B-1:0] b = register_inputs_i ? r_b : b_i; - wire [5:0] acc_fir = register_inputs_i ? r_acc_fir : acc_fir_i; - wire unsigned_a = register_inputs_i ? r_unsigned_a : unsigned_a_i; - wire unsigned_b = register_inputs_i ? r_unsigned_b : unsigned_b_i; - wire [2:0] feedback = register_inputs_i ? r_feedback : feedback_i; - wire load_acc = register_inputs_i ? r_load_acc : load_acc_i; - wire subtract = register_inputs_i ? r_subtract : subtract_i; - wire sat = register_inputs_i ? r_sat : saturate_enable_i; - wire rnd = register_inputs_i ? r_rnd : round_i; + // Multiplier + wire [NBITS_A-1:0] mult_a; + wire [NBITS_BC-1:0] mult_b; + wire mult_sgn_a; + wire [NBITS_A-1:0] mult_mag_a; + wire mult_sgn_b; + wire [NBITS_BC-1:0] mult_mag_b; + + wire [NBITS_A+NBITS_BC-1:0] mult_mag; + wire mult_sgn; + wire [NBITS_A+NBITS_BC-1:0] mult; + wire [NBITS_ACC-1:0] mult_xtnd; + + reg [NBITS_ACC-1:0] mult_xtnd_r; + wire [NBITS_ACC-1:0] mult_xtnd_sel; + wire [NBITS_ACC-1:0] mult_xtnd_sub; + wire [NBITS_ACC-1:0] add_a; + wire [NBITS_ACC-1:0] add_b; + wire [NBITS_ACC-1:0] add_o; + wire [NBITS_ACC-1:0] acc_fir_int; + + wire [NBITS_ACC-1:0] acc_out; + + wire [NBITS_ACC-1:0] zcin_rshift; + wire [NBITS_ACC-1:0] zcin_xtnd; + wire [NBITS_ACC-1:0] zreg_rshift; + + // Output signals + wire [NBITS_Z-1:0] z0; + reg [NBITS_Z-1:0] z1; + wire [NBITS_Z-1:0] z2; + + assign mult_a = (feedback_i == 3'h0) ? a : + (feedback_i == 3'h1) ? a : + (feedback_i == 3'h2) ? a : + (feedback_i == 3'h3) ? a : + (feedback_i == 3'h4) ? a : + (feedback_i == 3'h5) ? a : + (feedback_i == 3'h6) ? acc[NBITS_A-1:0]: + coeff_i; // if feedback_i == 3'h7 - // Shift right control - wire [5:0] shift_d1 = register_inputs_i ? r_shift_d1 : shift_right_i; - wire [5:0] shift_d2 = output_select_i[1] ? shift_d1 : r_shift_d2; + assign mult_b = (pre_add_sel_i) ? preadd : b; - // Multiplier - wire unsigned_mode = unsigned_a & unsigned_b; - wire [NBITS_A-1:0] mult_a; - assign mult_a = (feedback == 3'h0) ? a : - (feedback == 3'h1) ? a : - (feedback == 3'h2) ? a : - (feedback == 3'h3) ? acc[NBITS_A-1:0] : - (feedback == 3'h4) ? coef_0_i : - (feedback == 3'h5) ? coef_1_i : - (feedback == 3'h6) ? coef_2_i : - coef_3_i; // if feedback == 3'h7 + assign mult_sgn_a = mult_a[NBITS_A-1]; + assign mult_mag_a = (mult_sgn_a) ? (~mult_a + 1) : mult_a; + assign mult_sgn_b = mult_b[NBITS_BC-1]; + assign mult_mag_b = (mult_sgn_b) ? (~mult_b + 1) : mult_b; - wire [NBITS_B-1:0] mult_b = (feedback == 2'h2) ? {NBITS_B{1'b0}} : b; + assign mult_mag = mult_mag_a * mult_mag_b; + assign mult_sgn = (mult_sgn_a ^ mult_sgn_b); - wire [NBITS_A-1:0] mult_sgn_a = mult_a[NBITS_A-1]; - wire [NBITS_A-1:0] mult_mag_a = (mult_sgn_a && !unsigned_a) ? (~mult_a + 1) : mult_a; - wire [NBITS_B-1:0] mult_sgn_b = mult_b[NBITS_B-1]; - wire [NBITS_B-1:0] mult_mag_b = (mult_sgn_b && !unsigned_b) ? (~mult_b + 1) : mult_b; - - wire [NBITS_A+NBITS_B-1:0] mult_mag = mult_mag_a * mult_mag_b; - wire mult_sgn = (mult_sgn_a && !unsigned_a) ^ (mult_sgn_b && !unsigned_b); - - wire [NBITS_A+NBITS_B-1:0] mult = (unsigned_a && unsigned_b) ? - (mult_a * mult_b) : (mult_sgn ? (~mult_mag + 1) : mult_mag); - - // Sign extension - wire [NBITS_ACC-1:0] mult_xtnd = unsigned_mode ? - {{(NBITS_ACC-NBITS_A-NBITS_B){1'b0}}, mult[NBITS_A+NBITS_B-1:0]} : - {{(NBITS_ACC-NBITS_A-NBITS_B){mult[NBITS_A+NBITS_B-1]}}, mult[NBITS_A+NBITS_B-1:0]}; + assign mult = (mult_sgn)? (~mult_mag + 1) : mult_mag; + // Sign extension + assign mult_xtnd = {{(NBITS_ACC-NBITS_A-NBITS_BC){mult[NBITS_A+NBITS_BC-1]}}, mult[NBITS_A+NBITS_BC-1:0]}; + + always @(posedge clock_i or posedge s_reset) begin + if (s_reset) begin + mult_xtnd_r <= 0; + end else begin + mult_xtnd_r <= mult_xtnd; + end + end + + assign mult_xtnd_sel = m_reg_i ? mult_xtnd_r : mult_xtnd; + // Adder - wire [NBITS_ACC-1:0] acc_fir_int = unsigned_a ? {{(NBITS_ACC-NBITS_A){1'b0}}, a} : - {{(NBITS_ACC-NBITS_A){a[NBITS_A-1]}}, a} ; + assign mult_xtnd_sub = subtract_i ? (~mult_xtnd_sel + 1) : mult_xtnd_sel; + assign add_a = (feedback_i[2:0] == 2) ? {a,b} : mult_xtnd_sub; + + assign acc_fir_int = a <<< acc_fir_i; + + assign zcin_rshift = z_cin_i >>> zc_shift_i; + assign zcin_xtnd = {{(NBITS_ACC-NBITS_Z){z_cin_i[NBITS_Z-1]}}, z_cin_i}; + + assign zreg_rshift = z1 >>> zreg_shift_i; + + assign add_b = (feedback_i == 3'h0) ? acc : + (feedback_i == 3'h1) ? zcin_rshift : + (feedback_i == 3'h2) ? zcin_xtnd : + (feedback_i == 3'h3) ? zcin_xtnd : + (feedback_i == 3'h4) ? z1 : + (feedback_i == 3'h5) ? zreg_rshift : + acc_fir_int; + + assign add_o = add_a + add_b; - wire [NBITS_ACC-1:0] add_a = (subtract) ? (~mult_xtnd + 1) : mult_xtnd; - wire [NBITS_ACC-1:0] add_b = (feedback_i == 3'h0) ? acc : - (feedback_i == 3'h1) ? {{NBITS_ACC}{1'b0}} : (acc_fir_int << acc_fir); + // Accumulator + initial acc <= 0; - wire [NBITS_ACC-1:0] add_o = add_a + add_b; + always @(posedge clock_i or posedge s_reset) + if (s_reset) + acc <= 'h0; + else begin + if (rst_acc_i) + acc <= 'h0; + else if (load_acc_i) + acc <= add_o; + else + acc <= acc; + end - // Accumulator - initial acc <= 0; + // Adder/accumulator output selection + assign acc_out = (output_select_i[1]) ? add_o : acc; - always @(posedge clock_i or posedge s_reset) - if (s_reset) acc <= 'h0; - else begin - if (load_acc) - acc <= add_o; - else - acc <= acc; - end + // Round, shift, saturate + wire a_sign; + wire [NBITS_ACC-1:0] onehalf; + wire [NBITS_ACC-1:0] int_mask; + wire [NBITS_ACC-1:0] frac_mask; + wire [NBITS_ACC-1:0] a_frac; + wire [NBITS_ACC-1:0] a_int; + + reg [NBITS_ACC-1:0] acc_rnd; + wire [NBITS_ACC-1:0] acc_shr; + wire [NBITS_ACC-1:0] acc_sat_s; + wire [NBITS_ACC-1:0] acc_sat; + + assign a_sign = acc_out[(NBITS_ACC-1)]; + assign onehalf = (shift_right_i == 6'b0) ? {NBITS_ACC{1'b0}} : ({{(NBITS_ACC-1){1'b0}},1'b1} << (shift_right_i-1)); + assign int_mask = ({NBITS_ACC{1'b1}} << shift_right_i); + assign frac_mask = ~int_mask; + assign a_frac = acc_out & frac_mask; + assign a_int = acc_out >>> shift_right_i; + + always @(*) begin + case(round_i) + 3'b000 : // no rounding + acc_rnd = acc_out; - // Adder/accumulator output selection - wire [NBITS_ACC-1:0] acc_out = (output_select_i[1]) ? add_o : acc; + 3'b001 : // round half up, asymmetrical + // add 1/2 + acc_rnd = acc_out + onehalf; - // Round, shift, saturate - wire [NBITS_ACC-1:0] acc_rnd = (rnd && (shift_right_i != 0)) ? (acc_out + ({{(NBITS_ACC-1){1'b0}}, 1'b1} << (shift_right_i - 1))) : - acc_out; + 3'b010 : // round half up, symmetrical + // if a is neg and a_frac = 1/2, do nothing, else add 1/2 + if ((a_sign == 1'b1) && (a_frac == onehalf)) + acc_rnd = acc_out; + else + acc_rnd = acc_out + onehalf; - wire [NBITS_ACC-1:0] acc_shr = (unsigned_mode) ? (acc_rnd >> shift_right_i) : - (acc_rnd >>> shift_right_i); + 3'b011 : // round half down, symmetrical + // if a is pos and a_frac = 1/2, do nothing, else add 1/2 + if ((a_sign == 1'b0) && (a_frac == onehalf)) + acc_rnd = acc_out; + else + acc_rnd = acc_out + onehalf; - wire [NBITS_ACC-1:0] acc_sat_u = (acc_shr[NBITS_ACC-1:NBITS_Z] != 0) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{NBITS_Z{1'b1}}} : - {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}}; + 3'b100 : // round half even + // if a is even and a_frac = 1/2, do nothing, else add 1/2 + if ((a_int[0] == 1'b0) && (a_frac == onehalf)) + acc_rnd = acc_out; + else + acc_rnd = acc_out + onehalf; - wire [NBITS_ACC-1:0] acc_sat_s = ((|acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b0) || - (&acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b1)) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}} : - {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_ACC-1],{NBITS_Z-1{~acc_shr[NBITS_ACC-1]}}}}; + 3'b100 : // round half odd + // if a is odd and a_frac = 1/2, do nothing, else add 1/2 + if ((a_int[0] == 1'b1) && (a_frac == onehalf)) + acc_rnd = acc_out; + else + acc_rnd = acc_out + onehalf; - wire [NBITS_ACC-1:0] acc_sat = (sat) ? ((unsigned_mode) ? acc_sat_u : acc_sat_s) : acc_shr; + default : // no rounding + acc_rnd = acc_out; - // Output signals - wire [NBITS_Z-1:0] z0; - reg [NBITS_Z-1:0] z1; - wire [NBITS_Z-1:0] z2; + endcase + end + + assign acc_shr = (acc_rnd >>> shift_right_i); - assign z0 = mult_xtnd[NBITS_Z-1:0]; - assign z2 = acc_sat[NBITS_Z-1:0]; + assign acc_sat_s = ((|acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b0) || + (&acc_shr[NBITS_ACC-1:NBITS_Z-1] == 1'b1)) ? {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_Z-1:0]}} : + {{(NBITS_ACC-NBITS_Z){1'b0}},{acc_shr[NBITS_ACC-1],{NBITS_Z-1{~acc_shr[NBITS_ACC-1]}}}}; - initial z1 <= 0; + assign acc_sat = (saturate_enable_i)? acc_sat_s : acc_shr; - always @(posedge clock_i or posedge s_reset) - if (s_reset) - z1 <= 0; - else begin - z1 <= (output_select_i == 3'b100) ? z0 : z2; - end + assign z0 = mult_xtnd_sel[NBITS_Z-1:0]; + assign z2 = acc_sat[NBITS_Z-1:0]; - // Output mux - assign z_o = (output_select_i == 3'h0) ? z0 : - (output_select_i == 3'h1) ? z2 : - (output_select_i == 3'h2) ? z2 : - (output_select_i == 3'h3) ? z2 : - (output_select_i == 3'h4) ? z1 : - (output_select_i == 3'h5) ? z1 : - (output_select_i == 3'h6) ? z1 : - z1; // if output_select_i == 3'h7 + initial z1 <= 0; - // B input delayed passthrough - initial dly_b_o <= 0; + always @(posedge clock_i or posedge s_reset) + if (s_reset) + z1 <= 0; + else begin + z1 <= (output_select_i == 3'b100) ? z0 : z2; + end - always @(posedge clock_i or posedge s_reset) - if (s_reset) - dly_b_o <= 0; - else - dly_b_o <= b_i; + // Output mux + assign z_o = (output_select_i == 3'h0) ? z0 : + (output_select_i == 3'h1) ? z2 : + (output_select_i == 3'h2) ? z2 : + (output_select_i == 3'h3) ? z2 : + (output_select_i == 3'h4) ? z1 : + (output_select_i == 3'h5) ? z1 : + (output_select_i == 3'h6) ? z1 : + z1; // if output_select_i == 3'h7 + + assign z_cout_o = z_o; + assign a_cout_o = r_a; + assign b_cout_o = r_b; endmodule diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index 76ef44570..3d4d9c84f 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -222,16 +222,21 @@ struct SynthQuickLogicPass : public ScriptPass { if (check_label("map_dsp", "(for qlf_k6n10f, skip if -nodsp)") && ((dsp && family == "qlf_k6n10f") || help_mode)) { run("wreduce t:$mul"); - run("ql_dsp_macc"); + //run("ql_dsp_macc"); - run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=20 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=11 -D DSP_B_MINWIDTH=10 -D DSP_NAME=$__QL_MUL20X18"); - run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=10 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=$__QL_MUL10X9"); + + run("techmap -map +/mul2dsp.v -map " + lib_path + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0 -D DSP_SIGNEDONLY " + "-D DSP_A_MAXWIDTH=32 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=10 -D DSP_NAME=$__MUL32X18"); + run("chtype -set $mul t:$__soft_mul"); + run("techmap -map +/mul2dsp.v -map " + lib_path + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0 -D DSP_SIGNEDONLY " + "-D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=$__MUL16X9"); run("chtype -set $mul t:$__soft_mul"); - run("techmap -map " + lib_path + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0"); - run("ql_dsp_simd"); - run("techmap -map " + lib_path + family + "/dsp_final_map.v"); - run("ql_dsp_io_regs"); + run("ql_dsp"); + + //run("ql_dsp_simd"); + //run("techmap -map " + lib_path + family + "/dsp_final_map.v"); + //run("ql_dsp_io_regs"); } if (check_label("coarse")) {