aboutsummaryrefslogblamecommitdiff
path: root/rtl/_modexpng_storage_block.v
blob: d6ef1ee77745201efccb471da956289e28f07c5b (plain) (tree)


























































































































































































































                                                                                                       
module modexpng_storage_block
(
    clk, 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                     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) begin
        //
        rd_wide_xy_reg_ena     <= rst ? 1'b0 : rd_wide_xy_ena;
        rd_wide_xy_reg_ena_aux <= rst ? 1'b0 : rd_wide_xy_ena_aux;
        rd_narrow_xy_reg_ena   <= rst ? 1'b0 : rd_narrow_xy_ena;
        //
    end

    
    //
    // Helper Signals
    //
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] wr_wide_xy_offset;
    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] wr_narrow_xy_offset;
    wire [BANK_ADDR_W + OP_ADDR_W -1:0] rd_narrow_xy_offset;

    assign wr_wide_xy_offset     = {wr_wide_xy_bank,     wr_wide_xy_addr};
    assign rd_wide_xy_offset_aux = {rd_wide_xy_bank_aux, rd_wide_xy_addr_aux};
    assign wr_narrow_xy_offset   = {wr_narrow_xy_bank,   wr_narrow_xy_addr};
    assign rd_narrow_xy_offset   = {rd_narrow_xy_bank,   rd_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] = {rd_wide_xy_bank, rd_wide_xy_addr[z*OP_ADDR_W +: OP_ADDR_W]};
            //
            modexpng_sdp_36k_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_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_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_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_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_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