aboutsummaryrefslogtreecommitdiff
path: root/src/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtl')
-rw-r--r--src/rtl/modexpa7_factor.v2
-rw-r--r--src/rtl/modexpa7_n_coeff.v8
-rw-r--r--src/rtl/modexpa7_systolic_multiplier.v10
-rw-r--r--src/rtl/pe/artix7/dsp48e1_wrapper_ext.v159
-rw-r--r--src/rtl/pe/artix7/multiplier32_artix7.v208
-rw-r--r--src/rtl/pe/artix7/systolic_pe_artix7.v126
-rw-r--r--src/rtl/pe/generic/systolic_pe_generic.v85
-rw-r--r--src/rtl/pe/modexpa7_adder32.v76
-rw-r--r--src/rtl/pe/modexpa7_lowlevel_settings.v15
-rw-r--r--src/rtl/pe/modexpa7_subtractor32.v76
-rw-r--r--src/rtl/pe/modexpa7_systolic_pe.v75
11 files changed, 770 insertions, 70 deletions
diff --git a/src/rtl/modexpa7_factor.v b/src/rtl/modexpa7_factor.v
index b3ad130..3f90e5d 100644
--- a/src/rtl/modexpa7_factor.v
+++ b/src/rtl/modexpa7_factor.v
@@ -276,7 +276,7 @@ module modexpa7_factor #
/* mask borrow into the very first word */
sub_b_in_mask <= (fsm_next_state == FSM_STATE_CALC_3) ? 1'b1 : 1'b0;
- modexpa7_pe_sub sub_inst
+ modexpa7_subtractor32 sub_inst
(
.clk (clk),
.ce (1'b1),
diff --git a/src/rtl/modexpa7_n_coeff.v b/src/rtl/modexpa7_n_coeff.v
index d416898..c2d7c9d 100644
--- a/src/rtl/modexpa7_n_coeff.v
+++ b/src/rtl/modexpa7_n_coeff.v
@@ -315,10 +315,10 @@ module modexpa7_n_coeff #
/* delay carry masking flag by one clock cycle (used later) */
always @(posedge clk) add1_c_in_mask_dly <= add1_c_in_mask;
- modexpa7_pe_add add1_inst
+ modexpa7_adder32 add1_inst
(
.clk (clk), //
- .ce (1'b1),
+ .ce (1'b1), //
.a (~n_bram_out), // ~N
.b ({{31{1'b0}}, add1_b_lsb}), // 1
.c_in (add1_c_in), //
@@ -339,7 +339,7 @@ module modexpa7_n_coeff #
reg add2_c_in; // carry input
wire add2_c_out; // carry output
- modexpa7_pe_add add2_inst
+ modexpa7_adder32 add2_inst
(
.clk (clk),
.ce (1'b1),
@@ -367,7 +367,7 @@ module modexpa7_n_coeff #
wire [31: 0] pe_p;
wire [31: 0] pe_c_out;
- modexpa7_pe_mul pe_mul_inst
+ modexpa7_systolic_pe pe_mul_inst
(
.clk (clk),
.a (pe_a),
diff --git a/src/rtl/modexpa7_systolic_multiplier.v b/src/rtl/modexpa7_systolic_multiplier.v
index fa99c54..cb1c716 100644
--- a/src/rtl/modexpa7_systolic_multiplier.v
+++ b/src/rtl/modexpa7_systolic_multiplier.v
@@ -400,7 +400,7 @@ module modexpa7_systolic_multiplier #
generate for (syst=0; syst<SYSTOLIC_ARRAY_LENGTH; syst=syst+1)
begin : gen_mul
- modexpa7_pe_mul mul_ab_inst
+ modexpa7_systolic_pe mul_ab_inst
(
.clk (clk),
.a (mul_ab_a),
@@ -412,7 +412,7 @@ module modexpa7_systolic_multiplier #
.c_out (mul_ab_c_out[syst])
);
- modexpa7_pe_mul mul_q_inst
+ modexpa7_systolic_pe mul_q_inst
(
.clk (clk),
.a (mul_q_a),
@@ -425,7 +425,7 @@ module modexpa7_systolic_multiplier #
);
- modexpa7_pe_mul mul_qn_inst
+ modexpa7_systolic_pe mul_qn_inst
(
.clk (clk),
.a (mul_qn_a),
@@ -616,7 +616,7 @@ module modexpa7_systolic_multiplier #
pe_sub_b_in <= (mult_cnt_s == mult_cnt_zero) ? 1'b0 : pe_sub_b_out;
- modexpa7_pe_add pe_add_inst
+ modexpa7_adder32 pe_add_inst
(
.clk (clk),
.ce (pe_add_ce),
@@ -627,7 +627,7 @@ module modexpa7_systolic_multiplier #
.c_out (pe_add_c_out)
);
- modexpa7_pe_sub pe_sub_inst
+ modexpa7_subtractor32 pe_sub_inst
(
.clk (clk),
.ce (pe_sub_ce),
diff --git a/src/rtl/pe/artix7/dsp48e1_wrapper_ext.v b/src/rtl/pe/artix7/dsp48e1_wrapper_ext.v
new file mode 100644
index 0000000..83fb78c
--- /dev/null
+++ b/src/rtl/pe/artix7/dsp48e1_wrapper_ext.v
@@ -0,0 +1,159 @@
+//------------------------------------------------------------------------------
+//
+// dsp48e1_wrapper_ext.v
+// -----------------------------------------------------------------------------
+// Extended hardware (Artix-7 DSP48E1) tile wrapper.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2016-2017, NORDUnet A/S
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//------------------------------------------------------------------------------
+
+module dsp48e1_wrapper_ext #
+ (
+ parameter AREG = 1'b0,
+ parameter PREG = 1'b0,
+
+ parameter A_INPUT = "DIRECT"
+ )
+ (
+ input clk,
+ input [ 6: 0] opmode,
+ input [29: 0] a,
+ input [17: 0] b,
+ output [47: 0] p,
+ input [29: 0] acin,
+ input [47: 0] pcin,
+ output [29: 0] acout,
+ output [47: 0] pcout
+ );
+
+ //
+ // Tile instantiation
+ //
+ DSP48E1 #
+ (
+ .AREG (AREG),
+ .BREG (1'b1),
+ .CREG (0),
+ .DREG (0),
+ .MREG (0),
+ .PREG (PREG),
+ .ADREG (0),
+
+ .ACASCREG (AREG),
+ .BCASCREG (1'b1),
+ .ALUMODEREG (0),
+ .INMODEREG (0),
+ .OPMODEREG (0),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+
+ .A_INPUT (A_INPUT),
+ .B_INPUT ("DIRECT"),
+
+ .USE_DPORT ("FALSE"),
+ .USE_MULT ("MULTIPLY"),
+ .USE_SIMD ("ONE48"),
+
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .SEL_PATTERN ("PATTERN"),
+ .SEL_MASK ("MASK"),
+ .PATTERN (48'h000000000000),
+ .MASK (48'h3fffffffffff),
+ .AUTORESET_PATDET ("NO_RESET")
+ )
+ DSP48E1_inst
+ (
+ .CLK (clk),
+
+ .RSTA (1'b0),
+ .RSTB (1'b0),
+ .RSTC (1'b0),
+ .RSTD (1'b0),
+ .RSTM (1'b0),
+ .RSTP (1'b0),
+
+ .RSTCTRL (1'b0),
+ .RSTINMODE (1'b0),
+ .RSTALUMODE (1'b0),
+ .RSTALLCARRYIN (1'b0),
+
+ .CEA1 (1'b0),
+ .CEA2 (AREG),
+ .CEB1 (1'b0),
+ .CEB2 (1'b1),
+ .CEC (1'b0),
+ .CED (1'b0),
+ .CEM (1'b0),
+ .CEP (PREG),
+ .CEAD (1'b0),
+ .CEALUMODE (1'b0),
+ .CEINMODE (1'b0),
+
+ .CECTRL (1'b0),
+ .CECARRYIN (1'b0),
+
+ .A (a),
+ .B (b),
+ .C ({48{1'b0}}),
+ .D ({25{1'b1}}),
+ .P (p),
+
+ .CARRYIN (1'b0),
+ .CARRYOUT (),
+ .CARRYINSEL (3'b000),
+
+ .CARRYCASCIN (1'b0),
+ .CARRYCASCOUT (),
+
+ .PATTERNDETECT (),
+ .PATTERNBDETECT (),
+
+ .OPMODE (opmode),
+ .ALUMODE (4'b0000),
+ .INMODE (5'b00000),
+
+ .MULTSIGNIN (1'b0),
+ .MULTSIGNOUT (),
+
+ .UNDERFLOW (),
+ .OVERFLOW (),
+
+ .ACIN (acin),
+ .BCIN (18'd0),
+ .PCIN (pcin),
+
+ .ACOUT (acout),
+ .BCOUT (),
+ .PCOUT (pcout)
+ );
+
+endmodule
diff --git a/src/rtl/pe/artix7/multiplier32_artix7.v b/src/rtl/pe/artix7/multiplier32_artix7.v
index 5cc6340..1fc6d30 100644
--- a/src/rtl/pe/artix7/multiplier32_artix7.v
+++ b/src/rtl/pe/artix7/multiplier32_artix7.v
@@ -1,83 +1,171 @@
-`timescale 1ns / 1ps
+//------------------------------------------------------------------------------
+//
+// multiplier32_artix7.v
+// -----------------------------------------------------------------------------
+// Hardware (Artix-7 DSP48E1) 32-bit multiplier.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2016-2017, NORDUnet A/S
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//------------------------------------------------------------------------------
module multiplier32_artix7
(
input clk,
input [31: 0] a,
input [31: 0] b,
- input [31: 0] t,
- input [31: 0] c_in,
- output [31: 0] p,
- output [31: 0] c_out
+ output [63: 0] p
);
+
+ /* split a, b into smaller words */
+ wire [16: 0] a_lo = a[16: 0];
+ wire [16: 0] b_lo = b[16: 0];
+ wire [14: 0] a_hi = a[31:17];
+ wire [14: 0] b_hi = b[31:17];
+
+ /* smaller sub-products */
+ wire [47: 0] dsp1_p;
+ wire [47: 0] dsp2_p;
+ wire [47: 0] dsp4_p;
+
+ /* direct output mapping */
+ assign p[63:34] = dsp4_p[29: 0];
- reg [31: 0] t_dly;
- reg [31: 0] c_in_dly;
-
- always @(posedge clk) t_dly <= t;
- always @(posedge clk) c_in_dly <= c_in;
-
- wire [31: 0] t_c_in_s;
- wire t_c_in_c_out;
-
- reg t_c_in_c_out_dly;
-
- always @(posedge clk) t_c_in_c_out_dly <= t_c_in_c_out;
+ /* delayed output mapping */
+ genvar fd;
+ generate for (fd=0; fd<17; fd=fd+1)
+ begin : gen_FD
+ FD # (.INIT( 1'b0)) FD_inst1 (.C(clk), .D(dsp1_p[fd]), .Q(p[fd + 0]));
+ FD # (.INIT( 1'b0)) FD_inst3 (.C(clk), .D(dsp2_p[fd]), .Q(p[fd + 17]));
+ end
+ endgenerate
+
+ /* product chains */
+ wire [47: 0] dsp1_p_chain;
+ wire [47: 0] dsp3_p_chain;
+ wire [47: 0] dsp2_p_chain;
- adder32_artix7 add_t_c_in
+ /* operand chains */
+ wire [29: 0] a_lo_chain;
+ wire [29: 0] a_hi_chain;
+
+ //
+ // a_lo * b_lo
+ //
+ dsp48e1_wrapper_ext #
+ (
+ .AREG (1'b1),
+ .PREG (1'b0),
+ .A_INPUT ("DIRECT")
+ )
+ dsp1
(
.clk (clk),
- .a (t_dly),
- .b (c_in_dly),
- .c_in (1'b0),
- .s (t_c_in_s),
- .c_out (t_c_in_c_out)
+ .opmode (7'b0110101),
+ .a ({13'd0, a_lo}),
+ .b ({1'b0, b_lo}),
+ .p (dsp1_p),
+ .acin (30'd0),
+ .pcin (48'd0),
+ .acout (a_lo_chain),
+ .pcout (dsp1_p_chain)
);
-
- wire [63: 0] a_b;
-
- wire [31: 0] a_b_lsb = a_b[31: 0];
- wire [31: 0] a_b_msb = a_b[63:32];
-
- reg [31: 0] a_b_msb_dly;
-
- always @(posedge clk) a_b_msb_dly <= a_b_msb;
- ip_mul32 mul_a_b
+ //
+ // a_hi * b_lo
+ //
+ dsp48e1_wrapper_ext #
(
- .clk (clk),
- .a (a),
- .b (b),
- .p (a_b)
+ .AREG (1'b1),
+ .PREG (1'b0),
+ .A_INPUT ("DIRECT")
+ )
+ dsp2
+ (
+ .clk (clk),
+ .opmode (7'b0010101),
+ .a ({15'd0, a_hi}),
+ .b ({1'd0, b_lo}),
+ .p (dsp2_p),
+ .acin (30'd0),
+ .pcin (dsp3_p_chain),
+ .acout (a_hi_chain),
+ .pcout (dsp2_p_chain)
);
- wire [31: 0] add_p_s;
- wire add_p_c_out;
-
- reg [31: 0] add_p_s_dly;
-
- always @(posedge clk) add_p_s_dly <= add_p_s;
-
- assign p = add_p_s_dly;
-
- adder32_artix7 add_p
+ //
+ // a_lo * b_hi
+ //
+ dsp48e1_wrapper_ext #
+ (
+ .AREG (1'b0),
+ .PREG (1'b0),
+ .A_INPUT ("CASCADE")
+ )
+ dsp3
(
.clk (clk),
- .a (a_b_lsb),
- .b (t_c_in_s),
- .c_in (1'b0),
- .s (add_p_s),
- .c_out (add_p_c_out)
- );
-
- adder32_artix7 add_c_out
+ .opmode (7'b1010101),
+ .a (30'd0),
+ .b ({3'd0, b_hi}),
+ .p (),
+ .acin (a_lo_chain),
+ .pcin (dsp1_p_chain),
+ .acout (),
+ .pcout (dsp3_p_chain)
+ );
+
+ //
+ // a_hi * b_hi
+ //
+ dsp48e1_wrapper_ext #
+ (
+ .AREG (1'b0),
+ .PREG (1'b1),
+ .A_INPUT ("CASCADE")
+ )
+ dsp4
(
.clk (clk),
- .a (a_b_msb_dly),
- .b ({{31{1'b0}}, t_c_in_c_out_dly}),
- .c_in (add_p_c_out),
- .s (c_out),
- .c_out ()
+ .opmode (7'b1010101),
+ .a (30'd0),
+ .b ({3'd0, b_hi}),
+ .p (dsp4_p),
+ .acin (a_hi_chain),
+ .pcin (dsp2_p_chain),
+ .acout (),
+ .pcout ()
);
endmodule
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/src/rtl/pe/artix7/systolic_pe_artix7.v b/src/rtl/pe/artix7/systolic_pe_artix7.v
new file mode 100644
index 0000000..b29f2c0
--- /dev/null
+++ b/src/rtl/pe/artix7/systolic_pe_artix7.v
@@ -0,0 +1,126 @@
+//------------------------------------------------------------------------------
+//
+// systolic_pe_artix7.v
+// -----------------------------------------------------------------------------
+// Hardware (Artix-7 DSP48E1) low-level systolic array processing element.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2016-2017, NORDUnet A/S
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+//------------------------------------------------------------------------------
+
+module systolic_pe_artix7
+ (
+ input clk,
+ input [31: 0] a,
+ input [31: 0] b,
+ input [31: 0] t,
+ input [31: 0] c_in,
+ output [31: 0] p,
+ output [31: 0] c_out
+ );
+
+ reg [31: 0] t_dly;
+ reg [31: 0] c_in_dly;
+
+ always @(posedge clk) t_dly <= t;
+ always @(posedge clk) c_in_dly <= c_in;
+
+ wire [31: 0] t_c_in_s;
+ wire t_c_in_c_out;
+
+ reg t_c_in_c_out_dly;
+
+ always @(posedge clk) t_c_in_c_out_dly <= t_c_in_c_out;
+
+ adder32_artix7 add_t_c_in
+ (
+ .clk (clk),
+ .ce (1'b1),
+ .a (t_dly),
+ .b (c_in_dly),
+ .c_in (1'b0),
+ .s (t_c_in_s),
+ .c_out (t_c_in_c_out)
+ );
+
+ wire [63: 0] a_b;
+
+ wire [31: 0] a_b_lsb = a_b[31: 0];
+ wire [31: 0] a_b_msb = a_b[63:32];
+
+ reg [31: 0] a_b_msb_dly;
+
+ always @(posedge clk) a_b_msb_dly <= a_b_msb;
+
+ multiplier32_artix7 mul_a_b
+ (
+ .clk (clk),
+ .a (a),
+ .b (b),
+ .p (a_b)
+ );
+
+ wire [31: 0] add_p_s;
+ wire add_p_c_out;
+
+ reg [31: 0] add_p_s_dly;
+
+ always @(posedge clk) add_p_s_dly <= add_p_s;
+
+ assign p = add_p_s_dly;
+
+ adder32_artix7 add_p
+ (
+ .clk (clk),
+ .ce (1'b1),
+ .a (a_b_lsb),
+ .b (t_c_in_s),
+ .c_in (1'b0),
+ .s (add_p_s),
+ .c_out (add_p_c_out)
+ );
+
+ adder32_artix7 add_c_out
+ (
+ .clk (clk),
+ .ce (1'b1),
+ .a (a_b_msb_dly),
+ .b ({{31{1'b0}}, t_c_in_c_out_dly}),
+ .c_in (add_p_c_out),
+ .s (c_out),
+ .c_out ()
+ );
+
+endmodule
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/src/rtl/pe/generic/systolic_pe_generic.v b/src/rtl/pe/generic/systolic_pe_generic.v
new file mode 100644
index 0000000..6c98f44
--- /dev/null
+++ b/src/rtl/pe/generic/systolic_pe_generic.v
@@ -0,0 +1,85 @@
+//======================================================================
+//
+// systolic_pe_generic.v
+// -----------------------------------------------------------------------------
+// Generic low-level systolic array processing element.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2017, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module systolic_pe_generic
+ (
+ input clk,
+ input [31: 0] a,
+ input [31: 0] b,
+ input [31: 0] t,
+ input [31: 0] c_in,
+ output [31: 0] p,
+ output [31: 0] c_out
+ );
+
+ //
+ // Customizable Latency
+ //
+ parameter LATENCY = 4;
+
+ //
+ // Delay Line
+ //
+ reg [63: 0] abct[1:LATENCY];
+
+ //
+ // Outputs
+ //
+ assign p = abct[LATENCY][31: 0];
+ assign c_out = abct[LATENCY][63:32];
+
+ //
+ // Sub-products
+ //
+ wire [63: 0] ab = {{32{1'b0}}, a} * {{32{1'b0}}, b};
+ wire [63: 0] ct = {{32{1'b0}}, c_in} + {{32{1'b0}}, t};
+
+ //
+ // Delay
+ //
+ integer i;
+ always @(posedge clk)
+ //
+ for (i=1; i<=LATENCY; i=i+1)
+ abct[i] <= (i == 1) ? ab + ct : abct[i-1];
+
+endmodule
+
+//======================================================================
+// End of file
+//======================================================================
diff --git a/src/rtl/pe/modexpa7_adder32.v b/src/rtl/pe/modexpa7_adder32.v
new file mode 100644
index 0000000..ad296b1
--- /dev/null
+++ b/src/rtl/pe/modexpa7_adder32.v
@@ -0,0 +1,76 @@
+//======================================================================
+//
+// modexpa7_adder32.v
+// -----------------------------------------------------------------------------
+// Low-level processing element wrapper (adder).
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2017, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module modexpa7_adder32
+ (
+ input clk,
+ input ce,
+ input [31: 0] a,
+ input [31: 0] b,
+ input c_in,
+ output [31: 0] s,
+ output c_out
+ );
+
+
+ //
+ // Include Primitive Selector
+ //
+ `include "modexpa7_lowlevel_settings.v"
+
+
+ //
+ // Instantiate Vendor/Generic Primitive
+ //
+ `ADDER32_PRIMITIVE adder32_inst
+ (
+ .clk(clk),
+ .ce(ce),
+ .a(a),
+ .b(b),
+ .s(s),
+ .c_in(c_in),
+ .c_out(c_out)
+ );
+
+
+endmodule
+
+//======================================================================
+// End of file
+//======================================================================
diff --git a/src/rtl/pe/modexpa7_lowlevel_settings.v b/src/rtl/pe/modexpa7_lowlevel_settings.v
new file mode 100644
index 0000000..93f5f34
--- /dev/null
+++ b/src/rtl/pe/modexpa7_lowlevel_settings.v
@@ -0,0 +1,15 @@
+//`define USE_VENDOR_PRIMITIVES
+
+`ifdef USE_VENDOR_PRIMITIVES
+
+`define ADDER32_PRIMITIVE adder32_artix7
+`define SUBTRACTOR32_PRIMITIVE subtractor32_artix7
+`define SYSTOLIC_PE_PRIMITIVE systolic_pe_artix7
+
+`else
+
+`define ADDER32_PRIMITIVE adder32_generic
+`define SUBTRACTOR32_PRIMITIVE subtractor32_generic
+`define SYSTOLIC_PE_PRIMITIVE systolic_pe_generic
+
+`endif
diff --git a/src/rtl/pe/modexpa7_subtractor32.v b/src/rtl/pe/modexpa7_subtractor32.v
new file mode 100644
index 0000000..75b9c13
--- /dev/null
+++ b/src/rtl/pe/modexpa7_subtractor32.v
@@ -0,0 +1,76 @@
+//======================================================================
+//
+// modexpa7_subtractor32.v
+// -----------------------------------------------------------------------------
+// Low-level processing element wrapper (subtractor).
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2017, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module modexpa7_subtractor32
+ (
+ input clk,
+ input ce,
+ input [31: 0] a,
+ input [31: 0] b,
+ input b_in,
+ output [31: 0] d,
+ output b_out
+ );
+
+
+ //
+ // Include Primitive Selector
+ //
+ `include "modexpa7_lowlevel_settings.v"
+
+
+ //
+ // Instantiate Vendor/Generic Primitive
+ //
+ `SUBTRACTOR32_PRIMITIVE subtractor32_inst
+ (
+ .clk(clk),
+ .ce(ce),
+ .a(a),
+ .b(b),
+ .d(d),
+ .b_in(b_in),
+ .b_out(b_out)
+ );
+
+
+endmodule
+
+//======================================================================
+// End of file
+//======================================================================
diff --git a/src/rtl/pe/modexpa7_systolic_pe.v b/src/rtl/pe/modexpa7_systolic_pe.v
new file mode 100644
index 0000000..22e6874
--- /dev/null
+++ b/src/rtl/pe/modexpa7_systolic_pe.v
@@ -0,0 +1,75 @@
+//======================================================================
+//
+// modexpa7_systolic_pe.v
+// -----------------------------------------------------------------------------
+// Low-level processing element wrapper (systolic array processing element).
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2017, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module modexpa7_systolic_pe
+ (
+ input clk,
+ input [31: 0] a,
+ input [31: 0] b,
+ input [31: 0] t,
+ input [31: 0] c_in,
+ output [31: 0] p,
+ output [31: 0] c_out
+ );
+
+
+ //
+ // Include Primitive Selector
+ //
+ `include "modexpa7_lowlevel_settings.v"
+
+
+ //
+ // Instantiate Vendor/Generic Primitive
+ //
+ `SYSTOLIC_PE_PRIMITIVE systolic_pe_inst
+ (
+ .clk(clk),
+ .a(a),
+ .b(b),
+ .t(t),
+ .c_in(c_in),
+ .p(p),
+ .c_out(c_out)
+ );
+
+endmodule
+
+//======================================================================
+// End of file
+//======================================================================