aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_storage_manager.v
blob: c949742a0a6bcea856344694ec4f4d556d70a111 (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_manager
(
    clk, rst_n,
    
    wr_wide_xy_ena,      wr_wide_xy_bank,     wr_wide_xy_addr,     wr_wide_x_dout,    wr_wide_y_dout,
    wr_narrow_xy_ena,    wr_narrow_xy_bank,   wr_narrow_xy_addr,   wr_narrow_x_dout,  wr_narrow_y_dout,    

    io_narrow_xy_ena,    io_narrow_xy_bank,   io_narrow_xy_addr,   io_narrow_x_din,   io_narrow_y_din,
    io_wide_xy_ena,      io_wide_xy_bank,     io_wide_xy_addr,     io_wide_x_din,     io_wide_y_din,
    
    rcmb_wide_xy_ena,    rcmb_wide_xy_bank,   rcmb_wide_xy_addr,   rcmb_wide_x_din,   rcmb_wide_y_din,
    rcmb_narrow_xy_ena,  rcmb_narrow_xy_bank, rcmb_narrow_xy_addr, rcmb_narrow_x_din, rcmb_narrow_y_din,
    
    rdct_wide_xy_bank,   rdct_wide_xy_addr,   rdct_wide_x_din,     rdct_wide_y_din,   rdct_wide_xy_valid,
    rdct_narrow_xy_bank, rdct_narrow_xy_addr, rdct_narrow_x_din,   rdct_narrow_y_din, rdct_narrow_xy_valid,
    
    wrk_wide_xy_ena,     wrk_wide_xy_bank,    wrk_wide_xy_addr,    wrk_wide_x_din,    wrk_wide_y_din,
    wrk_narrow_xy_ena,   wrk_narrow_xy_bank,  wrk_narrow_xy_addr,  wrk_narrow_x_din,  wrk_narrow_y_din
);


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


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

    output                    wr_wide_xy_ena;
    output [BANK_ADDR_W -1:0] wr_wide_xy_bank;
    output [  OP_ADDR_W -1:0] wr_wide_xy_addr;
    output [ WORD_EXT_W -1:0] wr_wide_x_dout;
    output [ WORD_EXT_W -1:0] wr_wide_y_dout;

    output                    wr_narrow_xy_ena;
    output [BANK_ADDR_W -1:0] wr_narrow_xy_bank;
    output [  OP_ADDR_W -1:0] wr_narrow_xy_addr;
    output [ WORD_EXT_W -1:0] wr_narrow_x_dout;
    output [ WORD_EXT_W -1:0] wr_narrow_y_dout;
   
    input                     io_wide_xy_ena;
    input  [BANK_ADDR_W -1:0] io_wide_xy_bank;
    input  [  OP_ADDR_W -1:0] io_wide_xy_addr;
    input  [ WORD_EXT_W -1:0] io_wide_x_din;
    input  [ WORD_EXT_W -1:0] io_wide_y_din;

    input                     io_narrow_xy_ena;
    input  [BANK_ADDR_W -1:0] io_narrow_xy_bank;
    input  [  OP_ADDR_W -1:0] io_narrow_xy_addr;
    input  [ WORD_EXT_W -1:0] io_narrow_x_din;
    input  [ WORD_EXT_W -1:0] io_narrow_y_din;
    
    input                     rcmb_wide_xy_ena;
    input  [BANK_ADDR_W -1:0] rcmb_wide_xy_bank;
    input  [  OP_ADDR_W -1:0] rcmb_wide_xy_addr;
    input  [ WORD_EXT_W -1:0] rcmb_wide_x_din;
    input  [ WORD_EXT_W -1:0] rcmb_wide_y_din;

    input                     rcmb_narrow_xy_ena;
    input  [BANK_ADDR_W -1:0] rcmb_narrow_xy_bank;
    input  [  OP_ADDR_W -1:0] rcmb_narrow_xy_addr;
    input  [ WORD_EXT_W -1:0] rcmb_narrow_x_din;
    input  [ WORD_EXT_W -1:0] rcmb_narrow_y_din;
    
    input  [BANK_ADDR_W -1:0] rdct_wide_xy_bank;
    input  [  OP_ADDR_W -1:0] rdct_wide_xy_addr;
    input  [ WORD_EXT_W -1:0] rdct_wide_x_din;
    input  [ WORD_EXT_W -1:0] rdct_wide_y_din;
    input                     rdct_wide_xy_valid;

    input  [BANK_ADDR_W -1:0] rdct_narrow_xy_bank;
    input  [  OP_ADDR_W -1:0] rdct_narrow_xy_addr;
    input  [ WORD_EXT_W -1:0] rdct_narrow_x_din;
    input  [ WORD_EXT_W -1:0] rdct_narrow_y_din;
    input                     rdct_narrow_xy_valid;
    
    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;
    input  [ WORD_EXT_W -1:0] wrk_wide_x_din;
    input  [ WORD_EXT_W -1:0] wrk_wide_y_din;

    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;
    input  [ WORD_EXT_W -1:0] wrk_narrow_x_din;
    input  [ WORD_EXT_W -1:0] wrk_narrow_y_din;
    

    //
    // Output Registers
    //
    reg                    wr_wide_xy_ena_reg = 1'b0;
    reg [BANK_ADDR_W -1:0] wr_wide_xy_bank_reg;
    reg [  OP_ADDR_W -1:0] wr_wide_xy_addr_reg;
    reg [ WORD_EXT_W -1:0] wr_wide_x_din_reg;
    reg [ WORD_EXT_W -1:0] wr_wide_y_din_reg;

    reg                    wr_narrow_xy_ena_reg = 1'b0;
    reg [BANK_ADDR_W -1:0] wr_narrow_xy_bank_reg;
    reg [  OP_ADDR_W -1:0] wr_narrow_xy_addr_reg;
    reg [ WORD_EXT_W -1:0] wr_narrow_x_din_reg;
    reg [ WORD_EXT_W -1:0] wr_narrow_y_din_reg;
    
    task _update_wide;
        input                    xy_ena;
        input [BANK_ADDR_W -1:0] xy_bank;
        input [  OP_ADDR_W -1:0] xy_addr;
        input [ WORD_EXT_W -1:0] x_din;
        input [ WORD_EXT_W -1:0] y_din;
        begin
            wr_wide_xy_ena_reg  <= xy_ena;
            wr_wide_xy_bank_reg <= xy_bank;
            wr_wide_xy_addr_reg <= xy_addr;
            wr_wide_x_din_reg   <= x_din;
            wr_wide_y_din_reg   <= y_din;
        end
    endtask
    
    task _update_narrow;
        input        xy_ena;
        input [BANK_ADDR_W -1:0] xy_bank;
        input [  OP_ADDR_W -1:0] xy_addr;
        input [ WORD_EXT_W -1:0] x_din;
        input [ WORD_EXT_W -1:0] y_din;
        begin
            wr_narrow_xy_ena_reg  <= xy_ena;
            wr_narrow_xy_bank_reg <= xy_bank;
            wr_narrow_xy_addr_reg <= xy_addr;
            wr_narrow_x_din_reg   <= x_din;
            wr_narrow_y_din_reg   <= y_din;
        end
    endtask
    
    task enable_wide;
        input [BANK_ADDR_W -1:0] xy_bank;
        input [  OP_ADDR_W -1:0] xy_addr;
        input [ WORD_EXT_W -1:0] x_din;
        input [ WORD_EXT_W -1:0] y_din;
        begin
            _update_wide(1'b1, xy_bank, xy_addr, x_din, y_din);
        end
    endtask
    
    task enable_narrow;
        input [BANK_ADDR_W -1:0] xy_bank;
        input [  OP_ADDR_W -1:0] xy_addr;
        input [ WORD_EXT_W -1:0] x_din;
        input [ WORD_EXT_W -1:0] y_din;
        begin
            _update_narrow(1'b1, xy_bank, xy_addr, x_din, y_din);
        end
    endtask
    
    task disable_wide;
        begin
            _update_wide(1'b0, BANK_DNC, OP_ADDR_DNC, WORD_EXT_DNC, WORD_EXT_DNC);
        end
    endtask
    
    task disable_narrow;
        begin
            _update_narrow(1'b0, BANK_DNC, OP_ADDR_DNC, WORD_EXT_DNC, WORD_EXT_DNC);
        end
    endtask
    
    
    //
    // Write Arbiter
    //
    always @(posedge clk or negedge rst_n)
        //
        if (!rst_n)                      disable_wide;
        else begin
            //
            if      (io_wide_xy_ena)     enable_wide(io_wide_xy_bank,   io_wide_xy_addr,   io_wide_x_din,   io_wide_y_din);
            else if (rcmb_wide_xy_ena)   enable_wide(rcmb_wide_xy_bank, rcmb_wide_xy_addr, rcmb_wide_x_din, rcmb_wide_y_din);
            else if (rdct_wide_xy_valid) enable_wide(rdct_wide_xy_bank, rdct_wide_xy_addr, rdct_wide_x_din, rdct_wide_y_din);
            else if (wrk_wide_xy_ena)    enable_wide(wrk_wide_xy_bank,  wrk_wide_xy_addr,  wrk_wide_x_din,  wrk_wide_y_din);
            else                         disable_wide;
            //
        end
            
    
    //
    // Read Arbiter
    //
    always @(posedge clk or negedge rst_n)
        //
        if (!rst_n)                        disable_narrow;
        else begin
            //
            if      (io_narrow_xy_ena)     enable_narrow(io_narrow_xy_bank,   io_narrow_xy_addr,   io_narrow_x_din,   io_narrow_y_din);
            else if (rcmb_narrow_xy_ena)   enable_narrow(rcmb_narrow_xy_bank, rcmb_narrow_xy_addr, rcmb_narrow_x_din, rcmb_narrow_y_din);
            else if (rdct_narrow_xy_valid) enable_narrow(rdct_narrow_xy_bank, rdct_narrow_xy_addr, rdct_narrow_x_din, rdct_narrow_y_din);
            else if (wrk_narrow_xy_ena)    enable_narrow(wrk_narrow_xy_bank,  wrk_narrow_xy_addr,  wrk_narrow_x_din,  wrk_narrow_y_din);
            else                           disable_narrow;
            //
        end

    
    //
    // Port Mapping
    //
    assign wr_wide_xy_ena  = wr_wide_xy_ena_reg;
    assign wr_wide_xy_bank = wr_wide_xy_bank_reg;
    assign wr_wide_xy_addr = wr_wide_xy_addr_reg;
    assign wr_wide_x_dout  = wr_wide_x_din_reg;
    assign wr_wide_y_dout  = wr_wide_y_din_reg;

    assign wr_narrow_xy_ena  = wr_narrow_xy_ena_reg;
    assign wr_narrow_xy_bank = wr_narrow_xy_bank_reg;
    assign wr_narrow_xy_addr = wr_narrow_xy_addr_reg;
    assign wr_narrow_x_dout  = wr_narrow_x_din_reg;
    assign wr_narrow_y_dout  = wr_narrow_y_din_reg;
    
endmodule