aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_storage_block.v
blob: 2a0df0014fdf359dd5e515923db8df170232c0da (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_storage_block
(
    clk, rst_n,
    
    wr_wide_xy_ena,
    wr_wide_xy_bank,
    wr_wide_xy_addr,
    wr_wide_x_din,
    wr_wide_y_din,

    wr_narrow_xy_ena,
    wr_narrow_xy_bank,
    wr_narrow_xy_addr,
    wr_narrow_x_din,
    wr_narrow_y_din,

    rd_wide_xy_ena,
    rd_wide_xy_ena_aux,
    rd_wide_xy_bank,
    rd_wide_xy_bank_aux,
    rd_wide_xy_addr,
    rd_wide_xy_addr_aux,
    rd_wide_x_dout,
    rd_wide_y_dout,
    rd_wide_x_dout_aux,
    rd_wide_y_dout_aux,
    
    rd_narrow_xy_ena,
    rd_narrow_xy_bank,
    rd_narrow_xy_addr,
    rd_narrow_x_dout,
    rd_narrow_y_dout,
    
    wrk_wide_xy_ena,
    wrk_wide_xy_bank,
    wrk_wide_xy_addr,
    wrk_wide_x_dout,
    wrk_wide_y_dout,
    
    wrk_narrow_xy_ena,
    wrk_narrow_xy_bank,
    wrk_narrow_xy_addr,
    wrk_narrow_x_dout,
    wrk_narrow_y_dout
);

    //
    // Headers
    //
    `include "modexpng_parameters.vh"
    `include "modexpng_storage_primitives.vh"


    //
    // Ports
    //
    input                                         clk;
    input                                         rst_n;

    input                                         wr_wide_xy_ena;
    input  [                  BANK_ADDR_W   -1:0] wr_wide_xy_bank;
    input  [                  OP_ADDR_W     -1:0] wr_wide_xy_addr;
    input  [                  WORD_EXT_W    -1:0] wr_wide_x_din;
    input  [                  WORD_EXT_W    -1:0] wr_wide_y_din;
    
    input                                         wr_narrow_xy_ena;
    input  [                  BANK_ADDR_W   -1:0] wr_narrow_xy_bank;
    input  [                  OP_ADDR_W     -1:0] wr_narrow_xy_addr;
    input  [                  WORD_EXT_W    -1:0] wr_narrow_x_din;
    input  [                  WORD_EXT_W    -1:0] wr_narrow_y_din;

    input                                         rd_wide_xy_ena;
    input                                         rd_wide_xy_ena_aux;
    input  [                  BANK_ADDR_W   -1:0] rd_wide_xy_bank;
    input  [                  BANK_ADDR_W   -1:0] rd_wide_xy_bank_aux;
    input  [ NUM_MULTS_HALF * OP_ADDR_W     -1:0] rd_wide_xy_addr;
    input  [                  OP_ADDR_W     -1:0] rd_wide_xy_addr_aux;
    output [ NUM_MULTS_HALF * WORD_EXT_W    -1:0] rd_wide_x_dout;
    output [ NUM_MULTS_HALF * WORD_EXT_W    -1:0] rd_wide_y_dout;
    output [                  WORD_EXT_W    -1:0] rd_wide_x_dout_aux;
    output [                  WORD_EXT_W    -1:0] rd_wide_y_dout_aux;
    
    input                                         rd_narrow_xy_ena;
    input  [                  BANK_ADDR_W   -1:0] rd_narrow_xy_bank;
    input  [                  OP_ADDR_W     -1:0] rd_narrow_xy_addr;
    output [                  WORD_EXT_W    -1:0] rd_narrow_x_dout;
    output [                  WORD_EXT_W    -1:0] rd_narrow_y_dout;

    input                                         wrk_wide_xy_ena;
    input  [                  BANK_ADDR_W   -1:0] wrk_wide_xy_bank;
    input  [                  OP_ADDR_W     -1:0] wrk_wide_xy_addr;
    output [                  WORD_EXT_W    -1:0] wrk_wide_x_dout;
    output [                  WORD_EXT_W    -1:0] wrk_wide_y_dout;
    
    input                                         wrk_narrow_xy_ena;
    input  [                  BANK_ADDR_W   -1:0] wrk_narrow_xy_bank;
    input  [                  OP_ADDR_W     -1:0] wrk_narrow_xy_addr;
    output [                  WORD_EXT_W    -1:0] wrk_narrow_x_dout;
    output [                  WORD_EXT_W    -1:0] wrk_narrow_y_dout;
    
    
    //
    // Internal Registers
    //
    reg rd_wide_xy_reg_ena     = 1'b0;
    reg rd_wide_xy_reg_ena_aux = 1'b0;
    reg rd_narrow_xy_reg_ena   = 1'b0;
    reg wrk_wide_xy_reg_ena    = 1'b0;
    reg wrk_narrow_xy_reg_ena  = 1'b0;

    always @(posedge clk or negedge rst_n)
        //
        if (!rst_n) begin
            rd_wide_xy_reg_ena     <= 1'b0;
            rd_wide_xy_reg_ena_aux <= 1'b0;
            rd_narrow_xy_reg_ena   <= 1'b0;
            wrk_wide_xy_reg_ena    <= 1'b0;
            wrk_narrow_xy_reg_ena  <= 1'b0;
        end else begin
            rd_wide_xy_reg_ena     <= rd_wide_xy_ena;
            rd_wide_xy_reg_ena_aux <= rd_wide_xy_ena_aux;
            rd_narrow_xy_reg_ena   <= rd_narrow_xy_ena;
            wrk_wide_xy_reg_ena    <= wrk_wide_xy_ena;
            wrk_narrow_xy_reg_ena  <= wrk_narrow_xy_ena;
        end
    
    //
    // Helper Signals
    //
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] rd_wide_xy_offset[0:NUM_MULTS_HALF-1];
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] rd_wide_xy_offset_aux;
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] rd_narrow_xy_offset;
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] wr_wide_xy_offset;
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] wr_narrow_xy_offset;
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] wrk_wide_xy_offset;
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] wrk_narrow_xy_offset;

    assign rd_wide_xy_offset_aux = {rd_wide_xy_bank_aux, rd_wide_xy_addr_aux};
    assign rd_narrow_xy_offset   = {rd_narrow_xy_bank,   rd_narrow_xy_addr  };
    assign wr_wide_xy_offset     = {wr_wide_xy_bank,     wr_wide_xy_addr    };
    assign wr_narrow_xy_offset   = {wr_narrow_xy_bank,   wr_narrow_xy_addr  };
    assign wrk_wide_xy_offset    = {wrk_wide_xy_bank,    wrk_wide_xy_addr   };
    assign wrk_narrow_xy_offset  = {wrk_narrow_xy_bank,  wrk_narrow_xy_addr };

    //
    // "Wide" Storage
    //
    genvar z;
    generate for (z=0; z<NUM_MULTS_HALF; z=z+1)
        begin : gen_wide
            //
            assign rd_wide_xy_offset[z] = {1'b0, rd_wide_xy_bank, rd_wide_xy_addr[z*OP_ADDR_W +: OP_ADDR_W]};
            //
            `MODEXPNG_SDP_36K_X18 wide_x
            (
                .clk    (clk),
                
                .ena    (wr_wide_xy_ena),
                .wea    (wr_wide_xy_ena),
                .addra  (wr_wide_xy_offset),
                .dina   (wr_wide_x_din),
                
                .enb    (rd_wide_xy_ena),
                .regceb (rd_wide_xy_reg_ena),
                .addrb  (rd_wide_xy_offset[z]),
                .doutb  (rd_wide_x_dout[z*WORD_EXT_W +: WORD_EXT_W])
            );
            //
            `MODEXPNG_SDP_36K_X18 wide_y
            (
                .clk    (clk),

                .ena    (wr_wide_xy_ena),
                .wea    (wr_wide_xy_ena),
                .addra  (wr_wide_xy_offset),
                .dina   (wr_wide_y_din),
            
                .enb    (rd_wide_xy_ena),
                .regceb (rd_wide_xy_reg_ena),
                .addrb  (rd_wide_xy_offset[z]),
                .doutb  (rd_wide_y_dout[z*WORD_EXT_W +: WORD_EXT_W])
            );
            //
        end
    endgenerate
    
    //
    // Worker "Wide" Storage
    //
    `MODEXPNG_SDP_36K_X18 wrk_wide_x
    (
        .clk    (clk),
        
        .ena    (wr_wide_xy_ena),
        .wea    (wr_wide_xy_ena),
        .addra  (wr_wide_xy_offset),
        .dina   (wr_wide_x_din),
        
        .enb    (wrk_wide_xy_ena),
        .regceb (wrk_wide_xy_reg_ena),
        .addrb  (wrk_wide_xy_offset),
        .doutb  (wrk_wide_x_dout)
    );
    //
    `MODEXPNG_SDP_36K_X18 wrk_wide_y
    (
        .clk    (clk),

        .ena    (wr_wide_xy_ena),
        .wea    (wr_wide_xy_ena),
        .addra  (wr_wide_xy_offset),
        .dina   (wr_wide_y_din),
    
        .enb    (wrk_wide_xy_ena),
        .regceb (wrk_wide_xy_reg_ena),
        .addrb  (wrk_wide_xy_offset),
        .doutb  (wrk_wide_y_dout)
    );
    
    //
    // Auxilary "Wide" Storage
    //
    `MODEXPNG_SDP_36K_X18 wide_x_aux
    (
        .clk    (clk),

        .ena    (wr_wide_xy_ena),
        .wea    (wr_wide_xy_ena),
        .addra  (wr_wide_xy_offset),
        .dina   (wr_wide_x_din),

        .enb    (rd_wide_xy_ena_aux),
        .regceb (rd_wide_xy_reg_ena_aux),
        .addrb  (rd_wide_xy_offset_aux),
        .doutb  (rd_wide_x_dout_aux)
    );
    //
    `MODEXPNG_SDP_36K_X18 wide_y_aux
    (
        .clk    (clk),

        .ena    (wr_wide_xy_ena),
        .wea    (wr_wide_xy_ena),
        .addra  (wr_wide_xy_offset),
        .dina   (wr_wide_y_din),

        .enb    (rd_wide_xy_ena_aux),
        .regceb (rd_wide_xy_reg_ena_aux),
        .addrb  (rd_wide_xy_offset_aux),
        .doutb  (rd_wide_y_dout_aux)
    );

    //
    // "Narrow" Storage
    //
    `MODEXPNG_SDP_36K_X18 narrow_x
    (
        .clk    (clk),

        .ena    (wr_narrow_xy_ena),
        .wea    (wr_narrow_xy_ena),
        .addra  (wr_narrow_xy_offset),
        .dina   (wr_narrow_x_din),
    
        .enb    (rd_narrow_xy_ena),
        .regceb (rd_narrow_xy_reg_ena),
        .addrb  (rd_narrow_xy_offset),
        .doutb  (rd_narrow_x_dout)
    );

    `MODEXPNG_SDP_36K_X18 narrow_y
    (
        .clk    (clk),

        .ena    (wr_narrow_xy_ena),
        .wea    (wr_narrow_xy_ena),
        .addra  (wr_narrow_xy_offset),
        .dina   (wr_narrow_y_din),
    
        .enb    (rd_narrow_xy_ena),
        .regceb (rd_narrow_xy_reg_ena),
        .addrb  (rd_narrow_xy_offset),
        .doutb  (rd_narrow_y_dout)
    );
    
    //
    // Worker "Narrow" Storage
    //
    `MODEXPNG_SDP_36K_X18 wrk_narrow_x
    (
        .clk    (clk),

        .ena    (wr_narrow_xy_ena),
        .wea    (wr_narrow_xy_ena),
        .addra  (wr_narrow_xy_offset),
        .dina   (wr_narrow_x_din),
    
        .enb    (wrk_narrow_xy_ena),
        .regceb (wrk_narrow_xy_reg_ena),
        .addrb  (wrk_narrow_xy_offset),
        .doutb  (wrk_narrow_x_dout)
    );

    `MODEXPNG_SDP_36K_X18 wrk_narrow_y
    (
        .clk    (clk),

        .ena    (wr_narrow_xy_ena),
        .wea    (wr_narrow_xy_ena),
        .addra  (wr_narrow_xy_offset),
        .dina   (wr_narrow_y_din),
    
        .enb    (wrk_narrow_xy_ena),
        .regceb (wrk_narrow_xy_reg_ena),
        .addrb  (wrk_narrow_xy_offset),
        .doutb  (wrk_narrow_y_dout)
    );

endmodule