aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_mmm_transporter.v
blob: a8f309ab5803ca5373bcb0d1007c79a9e9cc3ccd (plain) (tree)




























































































































































                                                                                                                                            
module modexpng_mmm_transporter
(
    clk,
    ena,
    index_last,
    fsm_state,
    fsm_state_next,
    load_phase,
    load_xy_addr,
    load_xy_addr_vld,
    load_xy_req,
    load_addr_zero,
    load_t1t2_addr_done,
    load_nn_coeff_addr_done
);


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


    //
    // Parameters
    //
    parameter INDEX_WIDTH = 6;


    //
    // Ports
    //
    input                        clk;
    input                        ena;
    input  [    INDEX_WIDTH-1:0] index_last;
    input  [FSM_STATE_WIDTH-1:0] fsm_state;
    input  [FSM_STATE_WIDTH-1:0] fsm_state_next;
    output                       load_phase;
    output [      INDEX_WIDTH:0] load_xy_addr;
    output                       load_xy_addr_vld;
    output                       load_xy_req;
    output                       load_addr_zero;
    output                       load_t1t2_addr_done;
    output                       load_nn_coeff_addr_done;
    

    //
    // Load Address Generator
    //
    reg                 load_phase_reg;
    reg [INDEX_WIDTH:0] load_xy_addr_reg;
    reg                 load_xy_addr_vld_reg;
    reg                 load_xy_req_reg;

    
    //
    // Mapping
    //
    assign load_phase       = load_phase_reg;
    assign load_xy_addr     = load_xy_addr_reg;
    assign load_xy_addr_vld = load_xy_addr_vld_reg;
    assign load_xy_req      = load_xy_req_reg;

    
    //
    // Handy Quantities
    //
    wire [INDEX_WIDTH:0] load_xy_addr_zero = {{INDEX_WIDTH{1'b0}}, 1'b0};
    wire [INDEX_WIDTH:0] load_xy_addr_next = load_xy_addr_reg + 1'b1;
    wire [INDEX_WIDTH:0] load_xy_addr_xxx = {{INDEX_WIDTH{1'bX}}, 1'bX};
    
    
    //
    // More Handy Quantities
    //
    reg [INDEX_WIDTH:0] load_t1t2_addr_last;
    reg [INDEX_WIDTH:0] load_nn_coeff_addr_last;

    
    //
    // Flags
    //
    assign load_addr_zero          = load_xy_addr_reg == load_xy_addr_zero;
    assign load_t1t2_addr_done     = load_xy_addr_reg == load_t1t2_addr_last;
    assign load_nn_coeff_addr_done = load_xy_addr_reg == load_nn_coeff_addr_last;
    
    
    //
    // Last Index Latch
    //
    always @(posedge clk)
        //
        if (ena && (fsm_state == FSM_STATE_IDLE)) begin
            load_t1t2_addr_last     <= {1'b0, index_last};
            load_nn_coeff_addr_last <= {1'b0, index_last} + 1'b1;
        end
    

    //
    // Update Load Phase
    //
    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_LOAD_T1T2_1,
            FSM_STATE_LOAD_T1T2_2,
            FSM_STATE_LOAD_T1T2_3:      load_phase_reg <= 1'b0;
            FSM_STATE_LOAD_NN_COEFF_1,
            FSM_STATE_LOAD_NN_COEFF_2,
            FSM_STATE_LOAD_NN_COEFF_3:  load_phase_reg <= 1'b1;
            default:                    load_phase_reg <= 1'bX;
        endcase
    
    
    //
    // Update Load Address
    //
    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_LOAD_T1T2_1:     load_xy_addr_reg <= (fsm_state == FSM_STATE_LOAD_T1T2_3) ? load_xy_addr_next : load_xy_addr_zero;
            FSM_STATE_LOAD_T1T2_2,
            FSM_STATE_LOAD_T1T2_3:     load_xy_addr_reg <= load_xy_addr_reg;
            FSM_STATE_LOAD_NN_COEFF_1: load_xy_addr_reg <= (fsm_state == FSM_STATE_LOAD_NN_COEFF_3) ? load_xy_addr_next : load_xy_addr_zero;
            FSM_STATE_LOAD_NN_COEFF_2,
            FSM_STATE_LOAD_NN_COEFF_3: load_xy_addr_reg <= load_xy_addr_reg;
            default                    load_xy_addr_reg <= load_xy_addr_xxx;
        endcase

    
    //
    // Update Address Valid Flag
    //
    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_LOAD_T1T2_1,
            FSM_STATE_LOAD_NN_COEFF_1: load_xy_addr_vld_reg <= 1'b1;
            default                    load_xy_addr_vld_reg <= 1'b0;
        endcase

        
    //
    // Update Load Request Flag
    //
    always @(posedge clk)
        //
        case (fsm_state_next)
            FSM_STATE_LOAD_T1T2_2,
            FSM_STATE_LOAD_NN_COEFF_2: load_xy_req_reg <= 1'b1;
            default                    load_xy_req_reg <= 1'b0;
        endcase

 
endmodule