aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_recombinator_cell.v
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/modexpng_recombinator_cell.v')
-rw-r--r--rtl/modexpng_recombinator_cell.v94
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