aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_storage_block.v
blob: f1d5ae2be955fb7fbfc3f28ed335391ffc0e7c04 (plain) (tree)
1
2
3

                             
                      



























                        
                    

  


              
                                     
 
 


            


                                                          
 




























                                                                      
    






                                      
                         
          








                                                         



                     




                                                                              
 
                                                                              
                                                                            

                                                                            




                     
                                               

                             
                                                                                                             
              
                                                    
             
                              








                                               
                                                                    

              
                                                    
             
                              








                                               
                                                                    



               



                       
                                                
     
                      











                                         
                                                
     
                      











                                         


                       
                                              
     
                      











                                       
                                              
     
                      











                                       
 
         
 
module modexpng_storage_block
(
    clk, clk_bus, rst,
    
    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
);

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


    //
    // Ports
    //
    input                                         clk;
    input                                         clk_bus;
    input                                         rst;

    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;

    
    //
    // 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;

    always @(posedge clk)
        //
        if (rst) begin
            rd_wide_xy_reg_ena     <= 1'b0;
            rd_wide_xy_reg_ena_aux <= 1'b0;
            rd_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;
        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;

    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};

    //
    // "Wide" Storage
    //
    genvar z;
    generate for (z=0; z<NUM_MULTS_HALF; z=z+1)
        begin : gen_wide_bram
            //
            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_wrapper wide_bram_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_wrapper wide_bram_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
    
    //
    // Auxilary Storage
    //
    modexpng_sdp_36k_x18_wrapper wide_bram_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_wrapper wide_bram_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_wrapper narrow_bram_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_wrapper narrow_bram_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)
    );


endmodule