module modexpng_dsp_array_block
(
clk,
ce_a, ce_b, ce_m, ce_p, ce_mode,
mode_z,
a, b, p
);
`include "modexpng_parameters.vh"
`include "modexpng_dsp48e1.vh"
`include "modexpng_dsp_slice_primitive.vh"
input clk;
input ce_a;
input ce_b;
input ce_m;
input ce_p;
input ce_mode;
input [ NUM_MULTS_AUX -1:0] mode_z;
input [NUM_MULTS_HALF_AUX * WORD_EXT_W -1:0] a;
input [ WORD_W -1:0] b;
output [NUM_MULTS_AUX * MAC_W -1:0] p;
wire [WORD_EXT_W -1:0] casc_a[0:NUM_MULTS_HALF-1];
wire [ WORD_W -1:0] casc_b[0:NUM_MULTS_HALF-1];
wire ce_a0 = ce_a;
reg ce_a1 = 1'b0;
reg ce_a2 = 1'b0;
wire ce_b0 = ce_b;
reg ce_b1 = 1'b0;
always @(posedge clk) begin
ce_a1 <= ce_a0;
ce_a2 <= ce_a1;
ce_b1 <= ce_b0;
end
///
wire [46:0] p_debug_direct;
wire [17:0] casc_a_debug_direct;
wire [15:0] casc_b_debug_direct;
wire [46:0] p_debug_cascade;
wire [46:0] p_ref_direct = p[ 0 +: MAC_W];
wire [46:0] p_ref_cascade = p[MAC_W +: MAC_W];
modexpng_dsp_slice_wrapper_xilinx #
(
.AB_INPUT("DIRECT"),
.B_REG(2)
)
dsp_debug_direct
(
.clk (clk),
.ce_a1 (ce_a0),
.ce_b1 (ce_b0),
.ce_a2 (ce_a1),
.ce_b2 (ce_b1),
.ce_m (ce_m),
.ce_p (ce_p),
.ce_mode (ce_mode),
.a (a[0 +: 18]),
.b (b),
.p (p_debug_direct),
.inmode ({DSP48E1_INMODE_W{1'b0}}),
.opmode ({1'b0, mode_z[0], 1'b0, 2'b01, 2'b01}),
.alumode ({DSP48E1_ALUMODE_W{1'b0}}),
.casc_a_in (WORD_EXT_ZERO),
.casc_b_in (WORD_ZERO),
.casc_a_out (casc_a_debug_direct),
.casc_b_out (casc_b_debug_direct)
);
modexpng_dsp_slice_wrapper_xilinx #
(
.AB_INPUT("CASCADE"),
.B_REG(1)
)
dsp_debug_cascade
(
.clk (clk),
.ce_a1 (ce_a1),
.ce_b1 (1'b0),
.ce_a2 (ce_a2),
.ce_b2 (ce_b1),
.ce_m (ce_m),
.ce_p (ce_p),
.ce_mode (ce_mode),
.a (a[0 +: 18]),
.b (b),
.p (p_debug_cascade),
.inmode ({DSP48E1_INMODE_W{1'b0}}),
.opmode ({1'b0, mode_z[1], 1'b0, 2'b01, 2'b01}),
.alumode ({DSP48E1_ALUMODE_W{1'b0}}),
.casc_a_in (casc_a_debug_direct),
.casc_b_in (casc_b_debug_direct),
.casc_a_out (),
.casc_b_out ()
);
genvar z;
generate for (z=0; z<NUM_MULTS_HALF; z=z+1)
//
begin : gen_DSP48E1
//
`MODEXPNG_DSP_SLICE #
(
.AB_INPUT("DIRECT"),
.B_REG(2)
)
dsp_direct
(
.clk (clk),
.ce_a1 (ce_a0),
.ce_b1 (ce_b0),
.ce_a2 (ce_a1),
.ce_b2 (ce_b1),
.ce_m (ce_m),
.ce_p (ce_p),
.ce_mode (ce_mode),
.a (a[z*WORD_EXT_W +: WORD_EXT_W]),
.b (b),
.p (p[(2*z)*MAC_W +: MAC_W]),
.inmode ({DSP48E1_INMODE_W{1'b0}}),
.opmode ({1'b0, mode_z[2*z], 1'b0, 2'b01, 2'b01}),
.alumode ({DSP48E1_ALUMODE_W{1'b0}}),
.casc_a_in (WORD_EXT_ZERO),
.casc_b_in (WORD_ZERO),
.casc_a_out (casc_a[z]),
.casc_b_out (casc_b[z])
);
//
`MODEXPNG_DSP_SLICE #
(
.AB_INPUT("CASCADE"),
.B_REG(1)
)
dsp_cascade
(
.clk (clk),
.ce_a1 (ce_a1),
.ce_b1 (1'b0),
.ce_a2 (ce_a2),
.ce_b2 (ce_b1),
.ce_m (ce_m),
.ce_p (ce_p),
.ce_mode (ce_mode),
.a (a[z*WORD_EXT_W +: WORD_EXT_W]),
.b (b),
.p (p[(2*z+1)*MAC_W +: MAC_W]),
.inmode ({DSP48E1_INMODE_W{1'b0}}),
.opmode ({1'b0, mode_z[2*z+1], 1'b0, 2'b01, 2'b01}),
.alumode ({DSP48E1_ALUMODE_W{1'b0}}),
.casc_a_in (casc_a[z]),
.casc_b_in (casc_b[z]),
.casc_a_out (),
.casc_b_out ()
);
//
end
//
endgenerate
`MODEXPNG_DSP_SLICE #
(
.AB_INPUT("DIRECT"),
.B_REG(2)
)
dsp_aux
(
.clk (clk),
.ce_a1 (ce_a0),
.ce_b1 (ce_b0),
.ce_a2 (ce_a1),
.ce_b2 (ce_b1),
.ce_m (ce_m),
.ce_p (ce_p),
.ce_mode (ce_mode),
.a (a[NUM_MULTS_HALF*WORD_EXT_W +: WORD_EXT_W]),
.b (b),
.p (p[(2*NUM_MULTS_HALF)*MAC_W +: MAC_W]),
.inmode ({DSP48E1_INMODE_W{1'b0}}),
.opmode ({1'b0, mode_z[2*NUM_MULTS_HALF], 1'b0, 2'b01, 2'b01}),
.alumode ({DSP48E1_ALUMODE_W{1'b0}}),
.casc_a_in (WORD_EXT_ZERO),
.casc_b_in (WORD_ZERO),
.casc_a_out (),
.casc_b_out ()
);
endmodule