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