aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_mmm_dout_addr.v
blob: 3749d824db01bd527e02c52bff41fe4002e58c3f (plain) (tree)






































































































































































                                                                                                                                                              
module modexpng_mmm_dout_addr
(
    clk, rst_n,
    //index_last,
    fsm_state,
    load_xy_addr,
    load_addr_zero,
    load_nn_coeff_addr_done,
    /*
    
    col_index_zero, col_index_next,*/
    x_dout_addr, y_dout_addr,
    x_dout_ena,  y_dout_ena,
    x_dout_bank, y_dout_bank

);


    //
    // Includes
    //
    `include "modexpng_parameters.vh"
    `include "modexpng_parameters_x8.vh"
    `include "modexpng_mmm_fsm.vh"


    //
    // Parameters
    //
    parameter INDEX_WIDTH = 6;
    
    
    //
    // Ports
    //
    input                        clk;
    input                        rst_n;
    //input  [    INDEX_WIDTH-1:0] index_last;
    input  [FSM_STATE_WIDTH-1:0] fsm_state;
    input  [INDEX_WIDTH:0] load_xy_addr;       // address
    input                  load_addr_zero;
    input                  load_nn_coeff_addr_done;
    //input  [    INDEX_WIDTH-4:0] col_index_zero;
    //input  [    INDEX_WIDTH-4:0] col_index_next;
    output [INDEX_WIDTH-4:0] x_dout_addr;
    output [INDEX_WIDTH-4:0] y_dout_addr;
    
    output [NUM_MULTS-1:0] x_dout_ena;
    output [NUM_MULTS-1:0] y_dout_ena;
    
    output [3-1:0] x_dout_bank;
    output [3-1:0] y_dout_bank;
    
 
    //
    // Registers
    //
    reg [INDEX_WIDTH-4:0] x_dout_addr_reg; //clog2
    reg [INDEX_WIDTH-4:0] y_dout_addr_reg; //clog2
    
    reg [NUM_MULTS-1:0] x_dout_ena_reg = {NUM_MULTS{1'b0}};
    reg [NUM_MULTS-1:0] y_dout_ena_reg = {NUM_MULTS{1'b0}};

    reg [NUM_MULTS-1:0] x_dout_ena_int;
    reg [NUM_MULTS-1:0] y_dout_ena_int;
    
    reg [3-1:0] x_dout_bank_reg;
    reg [3-1:0] y_dout_bank_reg;

    
    //
    // Mapping
    //
    assign x_dout_addr = x_dout_addr_reg;
    assign y_dout_addr = y_dout_addr_reg;
    
    assign x_dout_ena  = x_dout_ena_reg;
    assign y_dout_ena  = y_dout_ena_reg;
    
    assign x_dout_bank = x_dout_bank_reg;
    assign y_dout_bank = y_dout_bank_reg;

    
    always @(posedge clk)
        //
        case (fsm_state)
            //
            FSM_STATE_LOAD_T1T2_3: begin
                x_dout_addr_reg <= load_xy_addr[INDEX_WIDTH-1:3];
                y_dout_addr_reg <= load_xy_addr[INDEX_WIDTH-1:3];
            end
            //
            FSM_STATE_LOAD_NN_COEFF_3: begin
                x_dout_addr_reg <= !load_nn_coeff_addr_done ? load_xy_addr[INDEX_WIDTH-1:3] : BANK_XY_AUX_ADDR_N_COEFF[INDEX_WIDTH-4:0];
                y_dout_addr_reg <= !load_nn_coeff_addr_done ? load_xy_addr[INDEX_WIDTH-1:3] : BANK_XY_AUX_ADDR_N_COEFF[INDEX_WIDTH-4:0];
            end
            //
            default: begin
                x_dout_addr_reg <= {INDEX_WIDTH-3{1'bX}};
                y_dout_addr_reg <= {INDEX_WIDTH-3{1'bX}};
            end
            //
        endcase

    wire [NUM_MULTS-1:0] load_xy_ena_init = {{NUM_MULTS-1{1'b0}}, 1'b1};        
    
    always @(posedge clk)
        //
        case (fsm_state)
            //
            FSM_STATE_LOAD_T1T2_2: begin
                x_dout_ena_int <= load_addr_zero ? load_xy_ena_init : {x_dout_ena_int[NUM_MULTS-2:0], x_dout_ena_int[NUM_MULTS-1]};
                y_dout_ena_int <= load_addr_zero ? load_xy_ena_init : {y_dout_ena_int[NUM_MULTS-2:0], y_dout_ena_int[NUM_MULTS-1]};
            end
            //
            FSM_STATE_LOAD_NN_COEFF_2: begin
                x_dout_ena_int <= load_addr_zero ? load_xy_ena_init : {x_dout_ena_int[NUM_MULTS-2:0], x_dout_ena_int[NUM_MULTS-1] & ~load_nn_coeff_addr_done};
                y_dout_ena_int <= load_addr_zero ? load_xy_ena_init : {y_dout_ena_int[NUM_MULTS-2:0], y_dout_ena_int[NUM_MULTS-1]};
            end
            //
        endcase


    always @(posedge clk or negedge rst_n)
        //
        if (!rst_n) begin
            x_dout_ena_reg <= {NUM_MULTS{1'b0}};
            y_dout_ena_reg <= {NUM_MULTS{1'b0}};        
        end else case (fsm_state)
            //
            FSM_STATE_LOAD_T1T2_3,
            FSM_STATE_LOAD_NN_COEFF_3: begin
                x_dout_ena_reg <= x_dout_ena_int;
                y_dout_ena_reg <= y_dout_ena_int;
            end
            //
            default: begin
                x_dout_ena_reg <= {NUM_MULTS{1'b0}};
                y_dout_ena_reg <= {NUM_MULTS{1'b0}};
            end
            //
        endcase

        
    always @(posedge clk)
        //
        case (fsm_state)
            //
            FSM_STATE_LOAD_T1T2_3: begin
                x_dout_bank_reg <= BANK_X_T1;
                y_dout_bank_reg <= BANK_Y_T2;
            end
            //
            FSM_STATE_LOAD_NN_COEFF_3: begin
                x_dout_bank_reg <= !load_nn_coeff_addr_done ? BANK_X_N       : BANK_XY_AUX;
                y_dout_bank_reg <= !load_nn_coeff_addr_done ? BANK_Y_N_COEFF : BANK_XY_AUX;
            end
            //
            default: begin
                x_dout_bank_reg <= BANK_XY_ANY;
                y_dout_bank_reg <= BANK_XY_ANY;
            end
            //
        endcase

        
endmodule