diff options
Diffstat (limited to 'rtl/modexpng_recombinator_cell.v')
-rw-r--r-- | rtl/modexpng_recombinator_cell.v | 94 |
1 files changed, 77 insertions, 17 deletions
diff --git a/rtl/modexpng_recombinator_cell.v b/rtl/modexpng_recombinator_cell.v index ef0ca2d..9761d9c 100644 --- a/rtl/modexpng_recombinator_cell.v +++ b/rtl/modexpng_recombinator_cell.v @@ -33,14 +33,19 @@ module modexpng_recombinator_cell ( clk, - ce, clr, - din, dout + ce, clr, cry, + cin, + din, dout, dout_ext ); + // // Headers // - `include "../rtl/modexpng_parameters.vh" + `include "modexpng_parameters.vh" + `include "modexpng_dsp48e1.vh" + `include "modexpng_dsp_slice_primitives.vh" + // // Ports @@ -48,25 +53,80 @@ module modexpng_recombinator_cell input clk; input ce; input clr; + input cry; + input [WORD_W -1:0] cin; input [ MAC_W -1:0] din; output [WORD_W -1:0] dout; + output [WORD_W :0] dout_ext; + + + // + // din <=> {z[13:0], y[15:0], x[15:0]} + // + wire [WORD_W -3:0] din_z = din[3 * WORD_W -3 : 2 * WORD_W]; // [45:32] + wire [WORD_W -1:0] din_y = din[2 * WORD_W -1 : WORD_W]; // [31:16] + wire [WORD_W -1:0] din_x = din[ WORD_W -1 : 0]; // [15: 0] + + + // + // Delayed Clock Enable + // + reg ce_dly = 1'b0; + always @(posedge clk) ce_dly <= ce; + + + // + // DSP Slice Buses + // + wire [DSP48E1_A_W-1:0] a_int; + wire [DSP48E1_B_W-1:0] b_int; + wire [DSP48E1_C_W-1:0] c_int; + wire [DSP48E1_P_W-1:0] p_int; - reg [WORD_W -2:0] z; - reg [WORD_W :0] y; - reg [WORD_W +1:0] x; - - assign dout = x[WORD_W-1:0]; + assign {a_int, b_int} = {{(DSP48E1_C_W-WORD_W){1'b0}}, cin}; + assign {c_int} = {din_z, 1'b0, din_y, 1'b1, din_x}; + - wire [WORD_W -2:0] din_z = din[3*WORD_W -2 :2*WORD_W]; // [46:32] - wire [WORD_W -1:0] din_y = din[2*WORD_W -1 : WORD_W]; // [31:16] - wire [WORD_W -1:0] din_x = din[ WORD_W -1 : 0]; // [15: 0] + // + // Combinational OPMODE Switch + // + reg [DSP48E1_OPMODE_W-1:0] opmode; - always @(posedge clk) + always @(clr, cry) // - if (ce) begin - z <= din_z; - y <= clr ? {1'b0, din_y} : {1'b0, din_y} + {2'b00, z}; - x <= clr ? {2'b00, din_x} : {2'b00, din_x} + {1'b0, y} + {WORD_ZERO, x[WORD_EXT_W-1:WORD_W]}; - end + casez ({clr, cry}) // clr has priority over cry! + 2'b1?: opmode = DSP48E1_OPMODE_Z0_YC_X0; + 2'b00: opmode = DSP48E1_OPMODE_ZP17_YC_X0; + 2'b01: opmode = DSP48E1_OPMODE_ZP17_YC_XAB; + endcase + + + // + // DSP Slice Instance + // + `MODEXPNG_DSP_SLICE_ADDSUB dsp_inst + ( + .clk (clk), + .ce_abc (ce), + .ce_p (ce_dly), + .ce_ctrl (ce), + .x ({a_int, b_int}), + .y (c_int), + .p (p_int), + .op_mode (opmode), + .alu_mode (DSP48E1_ALUMODE_Z_PLUS_X_AND_Y_AND_CIN), + .carry_in_sel (DSP48E1_CARRYINSEL_CARRYIN), + .casc_p_in (), + .casc_p_out (), + .carry_out () + ); + + + // + // Output Mapping + // + assign dout = {p_int[WORD_W-1:0]}; + assign dout_ext = {p_int[WORD_W+1], dout}; + endmodule |