aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_dsp_array_block.v
blob: daee8142da50c3d1906bc7d9ae51c526ee566f30 (plain) (tree)































                                                                           

                               





                                    
                                     
                                  
                                               
 
                                                         
    




                                                             
 




                                                            
    

                                                       











                               
           

             
                                               


                           
                                      















                                          
                                                                
                                    
                                                          
                
                                                           
                                                                          
                                                            
                

                                   




                                            
                                      















                                          
                                                                
                                    
                                                            
                
                                                           
                                                                            
                                                            











                                            
                              















                                  
                                                                     
                            
                                                               
        


                                                                               
        

                           






                           
//======================================================================
//
// Copyright (c) 2019, 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 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_primitives.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 [DSP48E1_A_W -1:0] casc_a[0:NUM_MULTS_HALF-1];
    wire [DSP48E1_B_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    
    
    genvar z;
    generate for (z=0; z<NUM_MULTS_HALF; z=z+1)
        //
        begin : gen_DSP48E1
            //        
            `MODEXPNG_DSP_SLICE_MULT #
            (
                .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      (),
                .casc_b_in      (),
                
                .casc_a_out     (casc_a[z]),
                .casc_b_out     (casc_b[z])
            );
            //
            `MODEXPNG_DSP_SLICE_MULT #
            (
                .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_MULT #
    (
        .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      (),
        .casc_b_in      (),
        
        .casc_a_out     (),
        .casc_b_out     ()
    );


endmodule