module modexpng_mmm_din_addr ( clk, rst_n, index_last, fsm_state_next, col_index_zero, col_index_next, din_addr, din_bank, din_ena, din_reg_ena, din_addr_cnt, din_addr_cnt_last, din_addr_cnt_lower_prev, din_addr_cnt_upper_prev ); // // 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_next; input [ INDEX_WIDTH-4:0] col_index_zero; input [ INDEX_WIDTH-4:0] col_index_next; output [ INDEX_WIDTH-4:0] din_addr; output [ 3-1:0] din_bank; output [ 1-1:0] din_ena; output [ 1-1:0] din_reg_ena; output [ INDEX_WIDTH-1:0] din_addr_cnt; output [ INDEX_WIDTH-1:0] din_addr_cnt_last; output [ 3-1:0] din_addr_cnt_lower_prev; output [ INDEX_WIDTH-4:0] din_addr_cnt_upper_prev; // // Address // reg [INDEX_WIDTH-1:0] din_addr_reg; wire [INDEX_WIDTH-1:0] din_addr_zero = {INDEX_WIDTH{1'b0}}; reg [INDEX_WIDTH-1:0] din_addr_last; wire [INDEX_WIDTH-1:0] din_addr_prev = (din_addr_reg == din_addr_zero) ? din_addr_last : din_addr_reg - 1'b1; reg [INDEX_WIDTH-1:0] din_addr_cnt_reg; wire [INDEX_WIDTH-1:0] din_addr_cnt_zero = {INDEX_WIDTH{1'b0}}; wire [INDEX_WIDTH-1:0] din_addr_cnt_next = din_addr_cnt_reg + 1'b1; reg [INDEX_WIDTH-1:0] din_addr_cnt_last_reg; wire [ 3-1:0] din_addr_cnt_lower = din_addr_cnt_reg[ 3-1:0]; wire [INDEX_WIDTH-4:0] din_addr_cnt_upper = din_addr_cnt_reg[INDEX_WIDTH-1:3]; reg [ 3-1:0] din_addr_cnt_lower_dly; reg [INDEX_WIDTH-4:0] din_addr_cnt_upper_dly; reg [ 3-1:0] din_bank_reg; // // Enables // reg din_ena_reg = 1'b0; reg din_reg_ena_reg = 1'b0; always @(posedge clk or negedge rst_n) // if (!rst_n) din_ena_reg <= 1'b0; else case (fsm_state_next) // FSM_STATE_MULT_SQUARE_COL_0_TRIG, FSM_STATE_MULT_SQUARE_COL_N_TRIG, FSM_STATE_MULT_SQUARE_COL_0_BUSY, FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_ena_reg <= 1'b1; // default: din_ena_reg <= 1'b0; // endcase always @(posedge clk or negedge rst_n) // if (!rst_n) din_reg_ena_reg <= 1'b0; else din_reg_ena_reg <= din_ena_reg; // // Address Mapping // assign din_addr = din_addr_reg[INDEX_WIDTH-1:3]; assign din_addr_cnt = din_addr_cnt_reg; assign din_addr_cnt_last = din_addr_cnt_last_reg; assign din_addr_cnt_lower_prev = din_addr_cnt_lower_dly; assign din_addr_cnt_upper_prev = din_addr_cnt_upper_dly; assign din_bank = din_bank_reg; // // Enable Mapping // assign din_ena = din_ena_reg; assign din_reg_ena = din_reg_ena_reg; // // Delay // always @(posedge clk) begin din_addr_cnt_lower_dly <= din_addr_cnt_lower; din_addr_cnt_upper_dly <= din_addr_cnt_upper; end always @(posedge clk) // case (fsm_state_next) // FSM_STATE_MULT_SQUARE_COL_0_TRIG: begin din_addr_reg <= {col_index_zero, {3{1'b0}}}; din_addr_last <= index_last; din_addr_cnt_reg <= din_addr_cnt_zero; din_addr_cnt_last_reg <= index_last; end // FSM_STATE_MULT_SQUARE_COL_N_TRIG: begin din_addr_reg <= {col_index_next, {3{1'b0}}}; din_addr_cnt_reg <= din_addr_cnt_zero; end // FSM_STATE_MULT_SQUARE_COL_0_BUSY, FSM_STATE_MULT_SQUARE_COL_N_BUSY: begin din_addr_reg <= din_addr_prev; din_addr_cnt_reg <= din_addr_cnt_next; end // //default: // endcase always @(posedge clk) // case (fsm_state_next) // FSM_STATE_MULT_SQUARE_COL_0_TRIG, FSM_STATE_MULT_SQUARE_COL_N_TRIG, FSM_STATE_MULT_SQUARE_COL_0_BUSY, FSM_STATE_MULT_SQUARE_COL_N_BUSY: din_bank_reg = BANK_XY_T1T2; // default: din_bank_reg = BANK_XY_ANY; // endcase endmodule