aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs
diff options
context:
space:
mode:
authorEddie Hung <eddie@fpgeh.com>2019-12-30 14:31:42 -0800
committerEddie Hung <eddie@fpgeh.com>2019-12-30 14:31:42 -0800
commit405e974fe51f4ede0b374ddddc398a26e04b0265 (patch)
tree61f646fe54f9f57d18236058aca8746d8603eed8 /techlibs
parentece423415cbc17654c6ac81a0f4b15783c558660 (diff)
parentc0a17c2457532726b05586d3b7a030bd9f372dea (diff)
downloadyosys-405e974fe51f4ede0b374ddddc398a26e04b0265.tar.gz
yosys-405e974fe51f4ede0b374ddddc398a26e04b0265.tar.bz2
yosys-405e974fe51f4ede0b374ddddc398a26e04b0265.zip
Merge remote-tracking branch 'origin/master' into xaig_dff
Diffstat (limited to 'techlibs')
-rw-r--r--techlibs/ecp5/cells_sim.v12
-rw-r--r--techlibs/ecp5/synth_ecp5.cc2
-rw-r--r--techlibs/xilinx/cells_sim.v6
-rw-r--r--techlibs/xilinx/synth_xilinx.cc22
-rw-r--r--techlibs/xilinx/tests/.gitignore4
-rw-r--r--techlibs/xilinx/tests/test_dsp48a1_model.sh17
-rw-r--r--techlibs/xilinx/tests/test_dsp48a1_model.v331
-rw-r--r--techlibs/xilinx/tests/test_dsp_model.sh11
-rw-r--r--techlibs/xilinx/xc3sda_dsp_map.v2
-rw-r--r--techlibs/xilinx/xc6s_dsp_map.v2
10 files changed, 377 insertions, 32 deletions
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index f467218cc..0d3ec4e5b 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -1,5 +1,6 @@
// ---------------------------------------
+(* lib_whitebox *)
module LUT4(input A, B, C, D, output Z);
parameter [15:0] INIT = 16'h0000;
wire [7:0] s3 = D ? INIT[15:8] : INIT[7:0];
@@ -31,13 +32,8 @@ module CCU2C(
// First half
wire LUT4_0, LUT2_0;
-`ifdef _ABC
- assign LUT4_0 = INIT0[{D0, C0, B0, A0}];
- assign LUT2_0 = INIT0[{2'b00, B0, A0}];
-`else
LUT4 #(.INIT(INIT0)) lut4_0(.A(A0), .B(B0), .C(C0), .D(D0), .Z(LUT4_0));
LUT2 #(.INIT(INIT0[3:0])) lut2_0(.A(A0), .B(B0), .Z(LUT2_0));
-`endif
wire gated_cin_0 = (INJECT1_0 == "YES") ? 1'b0 : CIN;
assign S0 = LUT4_0 ^ gated_cin_0;
@@ -46,13 +42,8 @@ module CCU2C(
// Second half
wire LUT4_1, LUT2_1;
-`ifdef _ABC
- assign LUT4_1 = INIT1[{D1, C1, B1, A1}];
- assign LUT2_1 = INIT1[{2'b00, B1, A1}];
-`else
LUT4 #(.INIT(INIT1)) lut4_1(.A(A1), .B(B1), .C(C1), .D(D1), .Z(LUT4_1));
LUT2 #(.INIT(INIT1[3:0])) lut2_1(.A(A1), .B(B1), .Z(LUT2_1));
-`endif
wire gated_cin_1 = (INJECT1_1 == "YES") ? 1'b0 : cout_0;
assign S1 = LUT4_1 ^ gated_cin_1;
@@ -209,6 +200,7 @@ endmodule
// ---------------------------------------
+(* lib_whitebox *)
module LUT2(input A, B, output Z);
parameter [3:0] INIT = 4'h0;
wire [1:0] s1 = B ? INIT[ 3:2] : INIT[1:0];
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index b71bb2395..a0ea6d1f9 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -230,7 +230,7 @@ struct SynthEcp5Pass : public ScriptPass
{
if (check_label("begin"))
{
- run("read_verilog -D_ABC -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
+ run("read_verilog -lib +/ecp5/cells_sim.v +/ecp5/cells_bb.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index 78ae23e1b..4d20e1d2c 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -2107,7 +2107,7 @@ always @* begin
2'b00: XMUX <= 0;
2'b01: XMUX <= M;
2'b10: XMUX <= P;
- 2'b11: XMUX <= {D_OUT[11:0], B1_OUT, A1_OUT};
+ 2'b11: XMUX <= {D_OUT[11:0], A1_OUT, B1_OUT};
default: XMUX <= 48'hxxxxxxxxxxxx;
endcase
end
@@ -2125,8 +2125,8 @@ end
// The post-adder.
wire signed [48:0] X_EXT;
wire signed [48:0] Z_EXT;
-assign X_EXT = XMUX;
-assign Z_EXT = ZMUX;
+assign X_EXT = {1'b0, XMUX};
+assign Z_EXT = {1'b0, ZMUX};
assign {CARRYOUT_IN, P_IN} = OPMODE_OUT[7] ? (Z_EXT - (X_EXT + CARRYIN_OUT)) : (Z_EXT + X_EXT + CARRYIN_OUT);
// Cascade outputs.
diff --git a/techlibs/xilinx/synth_xilinx.cc b/techlibs/xilinx/synth_xilinx.cc
index e7069f286..f2a9ae982 100644
--- a/techlibs/xilinx/synth_xilinx.cc
+++ b/techlibs/xilinx/synth_xilinx.cc
@@ -64,7 +64,7 @@ struct SynthXilinxPass : public ScriptPass
log(" (this feature is experimental and incomplete)\n");
log("\n");
log(" -ise\n");
- log(" generate an output netlist suitable for ISE (enables -iopad)\n");
+ log(" generate an output netlist suitable for ISE\n");
log("\n");
log(" -nobram\n");
log(" do not use block RAM cells in output netlist\n");
@@ -84,11 +84,9 @@ struct SynthXilinxPass : public ScriptPass
log(" -nodsp\n");
log(" do not use DSP48E1s to implement multipliers and associated logic\n");
log("\n");
- log(" -iopad\n");
- log(" enable I/O buffer insertion (selected automatically by -ise)\n");
- log("\n");
log(" -noiopad\n");
- log(" disable I/O buffer insertion (only useful with -ise)\n");
+ log(" disable I/O buffer insertion (useful for hierarchical or \n");
+ log(" out-of-context flows)\n");
log("\n");
log(" -noclkbuf\n");
log(" disable automatic clock buffer insertion\n");
@@ -125,7 +123,7 @@ struct SynthXilinxPass : public ScriptPass
}
std::string top_opt, edif_file, blif_file, family;
- bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram;
+ bool flatten, retime, vpr, ise, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp, uram;
bool abc9, dff_mode;
bool flatten_before_abc;
int widemux;
@@ -140,7 +138,6 @@ struct SynthXilinxPass : public ScriptPass
retime = false;
vpr = false;
ise = false;
- iopad = false;
noiopad = false;
noclkbuf = false;
nocarry = false;
@@ -218,7 +215,6 @@ struct SynthXilinxPass : public ScriptPass
continue;
}
if (args[argidx] == "-iopad") {
- iopad = true;
continue;
}
if (args[argidx] == "-noiopad") {
@@ -291,7 +287,6 @@ struct SynthXilinxPass : public ScriptPass
void script() YS_OVERRIDE
{
- bool do_iopad = iopad || (ise && !noiopad);
std::string ff_map_file;
if (help_mode)
ff_map_file = "+/xilinx/{family}_ff_map.v";
@@ -397,7 +392,10 @@ struct SynthXilinxPass : public ScriptPass
run("opt_expr -fine");
run("wreduce");
run("select -clear");
- run("xilinx_dsp");
+ if (help_mode)
+ run("xilinx_dsp -family <family>");
+ else
+ run("xilinx_dsp -family " + family);
run("chtype -set $mul t:$__soft_mul");
}
}
@@ -524,8 +522,8 @@ struct SynthXilinxPass : public ScriptPass
if (check_label("map_cells")) {
// Needs to be done before logic optimization, so that inverters (OE vs T) are handled.
- if (help_mode || do_iopad)
- run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
+ if (help_mode || !noiopad)
+ run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I -toutpad $__XILINX_TOUTPAD OE:I:O -tinoutpad $__XILINX_TINOUTPAD OE:O:I:IO A:top", "(only if not '-noiopad')");
std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
if (widemux > 0)
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
diff --git a/techlibs/xilinx/tests/.gitignore b/techlibs/xilinx/tests/.gitignore
index ef3699bd2..848f88d53 100644
--- a/techlibs/xilinx/tests/.gitignore
+++ b/techlibs/xilinx/tests/.gitignore
@@ -8,4 +8,8 @@ dsp_work*/
test_dsp_model_ref.v
test_dsp_model_uut.v
test_dsp_model
+test_dsp48a_model_ref.v
+test_dsp48a1_model_ref.v
+test_dsp48a1_model_uut.v
+test_dsp48a1_model
*.vcd
diff --git a/techlibs/xilinx/tests/test_dsp48a1_model.sh b/techlibs/xilinx/tests/test_dsp48a1_model.sh
new file mode 100644
index 000000000..a14a78e72
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp48a1_model.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -ex
+if [ -z $ISE_DIR ]; then
+ ISE_DIR=/opt/Xilinx/ISE/14.7
+fi
+sed 's/DSP48A1/MARKER1/; s/DSP48A/DSP48A_UUT/; s/MARKER1/DSP48A1_UUT/; /module DSP48A_UUT/,/endmodule/ p; /module DSP48A1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp48a1_model_uut.v
+if [ ! -f "test_dsp48a1_model_ref.v" ]; then
+ cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48A1.v test_dsp48a1_model_ref.v
+fi
+if [ ! -f "test_dsp48a_model_ref.v" ]; then
+ cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48A.v test_dsp48a_model_ref.v
+fi
+for tb in mult_allreg mult_noreg mult_inreg
+do
+ iverilog -s $tb -s glbl -o test_dsp48a1_model test_dsp48a1_model.v test_dsp48a1_model_uut.v test_dsp48a1_model_ref.v test_dsp48a_model_ref.v $ISE_DIR/ISE_DS/ISE/verilog/src/glbl.v
+ vvp -N ./test_dsp48a1_model
+done
diff --git a/techlibs/xilinx/tests/test_dsp48a1_model.v b/techlibs/xilinx/tests/test_dsp48a1_model.v
new file mode 100644
index 000000000..66346b47b
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp48a1_model.v
@@ -0,0 +1,331 @@
+`timescale 1ns / 1ps
+
+module testbench;
+ parameter integer A0REG = 1;
+ parameter integer A1REG = 1;
+ parameter integer B0REG = 1;
+ parameter integer B1REG = 1;
+ parameter integer CREG = 1;
+ parameter integer DREG = 1;
+ parameter integer MREG = 1;
+ parameter integer PREG = 1;
+ parameter integer CARRYINREG = 1;
+ parameter integer CARRYOUTREG = 1;
+ parameter integer OPMODEREG = 1;
+ parameter CARRYINSEL = "OPMODE5";
+ parameter RSTTYPE = "SYNC";
+
+ reg CLK;
+ reg CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE;
+ reg RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE;
+ reg [17:0] A;
+ reg [17:0] B;
+ reg [47:0] C;
+ reg [17:0] D;
+ reg [47:0] PCIN;
+ reg [7:0] OPMODE;
+ reg CARRYIN;
+
+ output CARRYOUTF, REF_CARRYOUTF;
+ output CARRYOUT, REF_CARRYOUT, REF_OLD_CARRYOUT;
+ output [35:0] M, REF_M;
+ output [47:0] P, REF_P, REF_OLD_P;
+ output [17:0] BCOUT, REF_BCOUT, REF_OLD_BCOUT;
+ output [47:0] PCOUT, REF_PCOUT, REF_OLD_PCOUT;
+
+ integer errcount = 0;
+
+ reg ERROR_FLAG = 0;
+
+ task clkcycle;
+ begin
+ #5;
+ CLK = ~CLK;
+ #10;
+ CLK = ~CLK;
+ #2;
+ ERROR_FLAG = 0;
+ if (REF_BCOUT !== BCOUT || REF_OLD_BCOUT != BCOUT) begin
+ $display("ERROR at %1t: REF_BCOUT=%b REF_OLD_BCOUT=%b UUT_BCOUT=%b DIFF=%b", $time, REF_BCOUT, REF_OLD_BCOUT, BCOUT, REF_BCOUT ^ BCOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_M !== M) begin
+ $display("ERROR at %1t: REF_M=%b UUT_M=%b DIFF=%b", $time, REF_M, M, REF_M ^ M);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_P !== P || REF_OLD_P != P) begin
+ $display("ERROR at %1t: REF_P=%b REF_OLD_P=%b UUT_P=%b DIFF=%b", $time, REF_P, REF_OLD_P, P, REF_P ^ P);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_PCOUT !== PCOUT || REF_OLD_PCOUT != PCOUT) begin
+ $display("ERROR at %1t: REF_PCOUT=%b REF_OLD_PCOUT=%b UUT_PCOUT=%b DIFF=%b", $time, REF_PCOUT, REF_OLD_PCOUT, PCOUT, REF_PCOUT ^ PCOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_CARRYOUT !== CARRYOUT || (REF_OLD_CARRYOUT != CARRYOUT && !CARRYOUTREG)) begin
+ $display("ERROR at %1t: REF_CARRYOUT=%b REF_OLD_CARRYOUT=%b UUT_CARRYOUT=%b DIFF=%b", $time, REF_CARRYOUT, REF_OLD_CARRYOUT, CARRYOUT, REF_CARRYOUT ^ CARRYOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_CARRYOUTF !== CARRYOUTF) begin
+ $display("ERROR at %1t: REF_CARRYOUTF=%b UUT_CARRYOUTF=%b", $time, REF_CARRYOUTF, CARRYOUTF);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ #3;
+ end
+ endtask
+
+ reg config_valid = 0;
+ task drc;
+ begin
+ config_valid = 1;
+
+ if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
+ if (OPMODE[3:2] == 2'b10 && PREG != 1) config_valid = 0;
+ end
+ endtask
+
+ initial begin
+ $dumpfile("test_dsp48a1_model.vcd");
+ $dumpvars(0, testbench);
+
+ #2;
+ CLK = 1'b0;
+ {CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = 8'b11111111;
+ {A, B, C, D, PCIN, OPMODE, CARRYIN} = 0;
+ {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 8'b11111111;
+ repeat (10) begin
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ end
+ {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 0;
+
+ repeat (10000) begin
+ clkcycle;
+ config_valid = 0;
+ while (!config_valid) begin
+ A = $urandom;
+ B = $urandom;
+ C = {$urandom, $urandom};
+ D = $urandom;
+ PCIN = {$urandom, $urandom};
+
+ {CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = $urandom | $urandom | $urandom;
+ {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
+ {CARRYIN, OPMODE} = $urandom;
+
+ drc;
+ end
+ end
+
+ if (errcount == 0) begin
+ $display("All tests passed.");
+ $finish;
+ end else begin
+ $display("Caught %1d errors.", errcount);
+ $stop;
+ end
+ end
+
+ DSP48A #(
+ .A0REG (A0REG),
+ .A1REG (A1REG),
+ .B0REG (B0REG),
+ .B1REG (B1REG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .OPMODEREG (OPMODEREG),
+ .CARRYINSEL (CARRYINSEL),
+ .RSTTYPE (RSTTYPE)
+ ) ref_old (
+ .A (A),
+ .B (B),
+ .C (C),
+ .D (D),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .BCOUT (REF_OLD_BCOUT),
+ .CARRYOUT (REF_OLD_CARRYOUT),
+ .P (REF_OLD_P),
+ .PCOUT (REF_OLD_PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CED (CED),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CEOPMODE (CEOPMODE),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTD (RSTD),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTOPMODE (RSTOPMODE)
+ );
+
+ DSP48A1 #(
+ .A0REG (A0REG),
+ .A1REG (A1REG),
+ .B0REG (B0REG),
+ .B1REG (B1REG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .CARRYOUTREG (CARRYOUTREG),
+ .OPMODEREG (OPMODEREG),
+ .CARRYINSEL (CARRYINSEL),
+ .RSTTYPE (RSTTYPE)
+ ) ref (
+ .A (A),
+ .B (B),
+ .C (C),
+ .D (D),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .BCOUT (REF_BCOUT),
+ .CARRYOUTF (REF_CARRYOUTF),
+ .CARRYOUT (REF_CARRYOUT),
+ .P (REF_P),
+ .M (REF_M),
+ .PCOUT (REF_PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CED (CED),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CEOPMODE (CEOPMODE),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTD (RSTD),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTOPMODE (RSTOPMODE)
+ );
+
+ DSP48A1_UUT #(
+ .A0REG (A0REG),
+ .A1REG (A1REG),
+ .B0REG (B0REG),
+ .B1REG (B1REG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .CARRYOUTREG (CARRYOUTREG),
+ .OPMODEREG (OPMODEREG),
+ .CARRYINSEL (CARRYINSEL),
+ .RSTTYPE (RSTTYPE)
+ ) uut (
+ .A (A),
+ .B (B),
+ .C (C),
+ .D (D),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .BCOUT (BCOUT),
+ .CARRYOUTF (CARRYOUTF),
+ .CARRYOUT (CARRYOUT),
+ .P (P),
+ .M (M),
+ .PCOUT (PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CED (CED),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CEOPMODE (CEOPMODE),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTD (RSTD),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTOPMODE (RSTOPMODE)
+ );
+endmodule
+
+module mult_noreg;
+ testbench #(
+ .A0REG (0),
+ .A1REG (0),
+ .B0REG (0),
+ .B1REG (0),
+ .CREG (0),
+ .DREG (0),
+ .MREG (0),
+ .PREG (0),
+ .CARRYINREG (0),
+ .CARRYOUTREG (0),
+ .OPMODEREG (0),
+ .CARRYINSEL ("CARRYIN"),
+ .RSTTYPE ("SYNC")
+ ) testbench ();
+endmodule
+
+module mult_allreg;
+ testbench #(
+ .A0REG (1),
+ .A1REG (1),
+ .B0REG (1),
+ .B1REG (1),
+ .CREG (1),
+ .DREG (1),
+ .MREG (1),
+ .PREG (1),
+ .CARRYINREG (1),
+ .CARRYOUTREG (1),
+ .OPMODEREG (1),
+ .CARRYINSEL ("OPMODE5"),
+ .RSTTYPE ("SYNC")
+ ) testbench ();
+endmodule
+
+module mult_inreg;
+ testbench #(
+ .A0REG (1),
+ .A1REG (1),
+ .B0REG (1),
+ .B1REG (1),
+ .CREG (1),
+ .DREG (1),
+ .MREG (0),
+ .PREG (0),
+ .CARRYINREG (1),
+ .CARRYOUTREG (0),
+ .OPMODEREG (0),
+ .CARRYINSEL ("CARRYIN"),
+ .RSTTYPE ("SYNC")
+ ) testbench ();
+endmodule
diff --git a/techlibs/xilinx/tests/test_dsp_model.sh b/techlibs/xilinx/tests/test_dsp_model.sh
index ae925c402..d005cd40c 100644
--- a/techlibs/xilinx/tests/test_dsp_model.sh
+++ b/techlibs/xilinx/tests/test_dsp_model.sh
@@ -1,14 +1,17 @@
#!/bin/bash
set -ex
+if [ -z $VIVADO_DIR ]; then
+ VIVADO_DIR=/opt/Xilinx/Vivado/2019.1
+fi
sed 's/DSP48E1/DSP48E1_UUT/; /DSP48E1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v
if [ ! -f "test_dsp_model_ref.v" ]; then
- cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v
+ cp $VIVADO_DIR/data/verilog/src/unisims/DSP48E1.v test_dsp_model_ref.v
fi
for tb in macc_overflow_underflow \
- simd24_preadd_noreg_nocasc simd12_preadd_noreg_nocasc \
- mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc \
+ simd24_preadd_noreg_nocasc simd12_preadd_noreg_nocasc \
+ mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc \
mult_allreg_preadd_nocasc mult_noreg_preadd_nocasc mult_inreg_preadd_nocasc
do
- iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v /opt/Xilinx/Vivado/2019.1/data/verilog/src/glbl.v
+ iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v $VIVADO_DIR/data/verilog/src/glbl.v
vvp -N ./test_dsp_model
done
diff --git a/techlibs/xilinx/xc3sda_dsp_map.v b/techlibs/xilinx/xc3sda_dsp_map.v
index 87348a173..258f90395 100644
--- a/techlibs/xilinx/xc3sda_dsp_map.v
+++ b/techlibs/xilinx/xc3sda_dsp_map.v
@@ -27,7 +27,7 @@ module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
.D(18'b0),
.P(P_48),
- .OPMODE(8'b0000010)
+ .OPMODE(8'b0000001)
);
assign Y = P_48;
endmodule
diff --git a/techlibs/xilinx/xc6s_dsp_map.v b/techlibs/xilinx/xc6s_dsp_map.v
index e8705723b..bdce60c14 100644
--- a/techlibs/xilinx/xc6s_dsp_map.v
+++ b/techlibs/xilinx/xc6s_dsp_map.v
@@ -27,7 +27,7 @@ module \$__MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
.D(18'b0),
.P(P_48),
- .OPMODE(8'b0000010)
+ .OPMODE(8'b0000001)
);
assign Y = P_48;
endmodule