aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_dsp_array_block.v
blob: 6b4ad3c617360c75c404966c1f5fd42aed69fbec (plain) (tree)
1
2
3
4
5
6
7
8
9

                               





                                    
                                     

                                              
 
                                                         
    




                                                             
 




                                                            
    

                                                      












                               









































































                                                                

             
                                               


                           
                                 















                                          
                                                                
                                    
                                                          
                
                                                           
                                                                          
                                                            
                

                                                




                                            
                                 















                                          
                                                                
                                    
                                                            
                
                                                           
                                                                            
                                                            











                                            
                         















                                  
                                                                     
                            
                                                               
        


                                                                               
        

                                        






                           
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