aboutsummaryrefslogblamecommitdiff
path: root/rtl/_modexpng_storage_manager.v
blob: 958596aeea21af749c59e9e1017608037102216e (plain) (tree)






































































































































































































                                                                                                                                       
module modexpng_storage_manager
(
    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,
    
    ext_wide_xy_ena,
    ext_wide_xy_bank,
    ext_wide_xy_addr,
    ext_wide_x_din,
    ext_wide_y_din,

    ext_narrow_xy_ena,
    ext_narrow_xy_bank,
    ext_narrow_xy_addr,
    ext_narrow_x_din,
    ext_narrow_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
);


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


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

    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_din;
    output [ WORD_EXT_W -1:0] wr_wide_y_din;

    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_din;
    output [ WORD_EXT_W -1:0] wr_narrow_y_din;
   
    input                     ext_wide_xy_ena;
    input  [BANK_ADDR_W -1:0] ext_wide_xy_bank;
    input  [  OP_ADDR_W -1:0] ext_wide_xy_addr;
    input  [ WORD_EXT_W -1:0] ext_wide_x_din;
    input  [ WORD_EXT_W -1:0] ext_wide_y_din;

    input                     ext_narrow_xy_ena;
    input  [BANK_ADDR_W -1:0] ext_narrow_xy_bank;
    input  [  OP_ADDR_W -1:0] ext_narrow_xy_addr;
    input  [ WORD_EXT_W -1:0] ext_narrow_x_din;
    input  [ WORD_EXT_W -1:0] ext_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;

    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_DONT_CARE, OP_ADDR_DONT_CARE, WORD_EXT_DONT_CARE, WORD_EXT_DONT_CARE);
        end
    endtask
    
    task disable_narrow;
        begin
            _update_narrow(1'b0, BANK_DONT_CARE, OP_ADDR_DONT_CARE, WORD_EXT_DONT_CARE, WORD_EXT_DONT_CARE);
        end
    endtask
    
    always @(posedge clk)
        //
        if (rst)                       disable_wide;
        else begin
            //
            if      (ext_wide_xy_ena)  enable_wide(ext_wide_xy_bank,  ext_wide_xy_addr,  ext_wide_x_din,  ext_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                       disable_wide;
            //
        end
            
    always @(posedge clk)
        //
        if (rst)                         disable_narrow;
        else begin
            //
            if      (ext_narrow_xy_ena)  enable_narrow(ext_narrow_xy_bank,  ext_narrow_xy_addr,  ext_narrow_x_din,  ext_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                         disable_narrow;
            //
        end

    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_din   = wr_wide_x_din_reg;
    assign wr_wide_y_din   = 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_din   = wr_narrow_x_din_reg;
    assign wr_narrow_y_din   = wr_narrow_y_din_reg;
    
endmodule