module modexpng_reductor ( clk, rst, ena, rdy, //fsm_state_next, word_index_last, //dsp_xy_ce_p, //dsp_x_p, dsp_y_p, //col_index, col_index_last, rd_wide_xy_addr_aux, rd_wide_xy_bank_aux, rd_wide_x_dout_aux, rd_wide_y_dout_aux, //rcmb_wide_xy_bank, rcmb_wide_xy_addr, rcmb_wide_x_dout, rcmb_wide_y_dout, rcmb_wide_xy_valid, rcmb_final_xy_bank, rcmb_final_xy_addr, rcmb_final_x_dout, rcmb_final_y_dout, rcmb_final_xy_valid, rdct_final_xy_addr, rdct_final_x_dout, rdct_final_y_dout, rdct_final_xy_valid ); // // Headers // //`include "../rtl_1/modexpng_mmm_fsm.vh" `include "../rtl_1/modexpng_parameters_old.vh" //`include "../rtl_1/modexpng_parameters_x8.vh" input clk; input rst; input ena; output rdy; /* input [FSM_STATE_WIDTH-1:0] fsm_state_next;*/ input [7:0] word_index_last;/* input dsp_xy_ce_p; *//* input [9*47-1:0] dsp_x_p; input [9*47-1:0] dsp_y_p; input [ 4:0] col_index; input [ 4:0] col_index_last; *//* input [ 7:0] rd_narrow_xy_addr; input [ 1:0] rd_narrow_xy_bank; */ input [ 1:0] rd_wide_xy_bank_aux; input [ 7:0] rd_wide_xy_addr_aux; input [ 17:0] rd_wide_x_dout_aux; input [ 17:0] rd_wide_y_dout_aux; // input [ 1:0] rcmb_final_xy_bank; input [ 7:0] rcmb_final_xy_addr; input [ 17:0] rcmb_final_x_dout; input [ 17:0] rcmb_final_y_dout; input rcmb_final_xy_valid; output [ 7:0] rdct_final_xy_addr; output [ 17:0] rdct_final_x_dout; output [ 17:0] rdct_final_y_dout; output rdct_final_xy_valid; // // Ready // reg rdy_reg = 1'b1; reg busy_now = 1'b0; assign rdy = rdy_reg; always @(posedge clk) // if (rst) rdy_reg <= 1'b1; else begin if (rdy && ena) rdy_reg <= 1'b0; if (!rdy && !busy_now) rdy_reg <= 1'b1; end // // Pipeline (Delay Match) // reg rcmb_xy_valid_dly1 = 1'b0; reg rcmb_xy_valid_dly2 = 1'b0; reg rcmb_xy_valid_dly3 = 1'b0; reg [2:0] rcmb_xy_bank_dly1; reg [2:0] rcmb_xy_bank_dly2; reg [2:0] rcmb_xy_bank_dly3; reg [7:0] rcmb_xy_addr_dly1; reg [7:0] rcmb_xy_addr_dly2; reg [7:0] rcmb_xy_addr_dly3; reg [17:0] rcmb_x_dout_dly1; reg [17:0] rcmb_x_dout_dly2; reg [17:0] rcmb_x_dout_dly3; reg [17:0] rcmb_y_dout_dly1; reg [17:0] rcmb_y_dout_dly2; reg [17:0] rcmb_y_dout_dly3; always @(posedge clk) // if (rst) begin rcmb_xy_valid_dly1 <= 1'b0; rcmb_xy_valid_dly2 <= 1'b0; rcmb_xy_valid_dly3 <= 1'b0; end else begin rcmb_xy_valid_dly1 <= rcmb_final_xy_valid; rcmb_xy_valid_dly2 <= rcmb_xy_valid_dly1; rcmb_xy_valid_dly3 <= rcmb_xy_valid_dly2; end always @(posedge clk) begin // if (rcmb_final_xy_valid) begin rcmb_xy_bank_dly1 <= rcmb_final_xy_bank; rcmb_xy_addr_dly1 <= rcmb_final_xy_addr; rcmb_x_dout_dly1 <= rcmb_final_x_dout; rcmb_y_dout_dly1 <= rcmb_final_y_dout; end // if (rcmb_xy_valid_dly1) begin rcmb_xy_bank_dly2 <= rcmb_xy_bank_dly1; rcmb_xy_addr_dly2 <= rcmb_xy_addr_dly1; rcmb_x_dout_dly2 <= rcmb_x_dout_dly1; rcmb_y_dout_dly2 <= rcmb_y_dout_dly1; end // if (rcmb_xy_valid_dly2) begin rcmb_xy_bank_dly3 <= rcmb_xy_bank_dly2; rcmb_xy_addr_dly3 <= rcmb_xy_addr_dly2; rcmb_x_dout_dly3 <= rcmb_x_dout_dly2; rcmb_y_dout_dly3 <= rcmb_y_dout_dly2; end // end reg [ 1:0] rcmb_x_lsb_carry; reg [15:0] rcmb_x_lsb_dummy; reg [17:0] rcmb_x_lsb_dout; reg [ 1:0] rcmb_y_lsb_carry; reg [15:0] rcmb_y_lsb_dummy; reg [17:0] rcmb_y_lsb_dout; //reg [17:0] reductor_fat_bram_x_msb_dout; //reg reductor_fat_bram_x_msb_dout_valid = 1'b0; //reg [ 7:0] reductor_fat_bram_x_msb_addr; // // Carry Computation // always @(posedge clk) // if (ena) begin rcmb_x_lsb_carry <= 2'b00; rcmb_y_lsb_carry <= 2'b00; end else if (rcmb_xy_valid_dly3) // case (rcmb_xy_bank_dly3) BANK_RCMB_ML: begin {rcmb_x_lsb_carry, rcmb_x_lsb_dummy} <= rcmb_x_dout_dly3 + rd_wide_x_dout_aux + rcmb_x_lsb_carry; {rcmb_y_lsb_carry, rcmb_y_lsb_dummy} <= rcmb_y_dout_dly3 + rd_wide_y_dout_aux + rcmb_y_lsb_carry; end BANK_RCMB_MH: if (rcmb_xy_addr_dly3 == 8'd0) begin {rcmb_x_lsb_carry, rcmb_x_lsb_dummy} <= rcmb_x_dout_dly3 + rd_wide_x_dout_aux + rcmb_x_lsb_carry; {rcmb_y_lsb_carry, rcmb_y_lsb_dummy} <= rcmb_y_dout_dly3 + rd_wide_y_dout_aux + rcmb_y_lsb_carry; end endcase // // Reduction // reg [ 7:0] rdct_xy_addr; reg [ 17:0] rdct_x_dout; reg [ 17:0] rdct_y_dout; reg rdct_xy_valid = 1'b0; assign rdct_final_xy_addr = rdct_xy_addr; assign rdct_final_x_dout = rdct_x_dout; assign rdct_final_y_dout = rdct_y_dout; assign rdct_final_xy_valid = rdct_xy_valid; task _update_rdct; input [ 7:0] addr; input [17:0] dout_x; input [17:0] dout_y; input valid; begin rdct_xy_addr <= addr; rdct_x_dout <= dout_x; rdct_y_dout <= dout_y; rdct_xy_valid <= valid; end endtask task set_rdct; input [ 7:0] addr; input [17:0] dout_x; input [17:0] dout_y; begin _update_rdct(addr, dout_x, dout_y, 1'b1); end endtask task clear_rdct; begin _update_rdct(8'hXX, {18{1'bX}}, {18{1'bX}}, 1'b0); end endtask // // // wire [17:0] sum_rdct_x = rcmb_x_dout_dly3 + rd_wide_x_dout_aux; wire [17:0] sum_rdct_y = rcmb_y_dout_dly3 + rd_wide_y_dout_aux; wire [17:0] sum_rdct_x_carry = sum_rdct_x + {16'h0000, rcmb_x_lsb_carry}; wire [17:0] sum_rdct_y_carry = sum_rdct_y + {16'h0000, rcmb_y_lsb_carry}; // // // always @(posedge clk) // if (rst) clear_rdct; else begin // clear_rdct; // if (busy_now && rcmb_xy_valid_dly3) // case (rcmb_xy_bank_dly3) BANK_RCMB_MH: if (rcmb_xy_addr_dly3 == 8'd1) set_rdct(8'd0, sum_rdct_x_carry, sum_rdct_y_carry); else if (rcmb_xy_addr_dly3 > 8'd1) set_rdct(rcmb_xy_addr_dly3 - 1'b1, sum_rdct_x, sum_rdct_y); BANK_RCMB_EXT: set_rdct(word_index_last, rcmb_x_dout_dly3, rcmb_y_dout_dly3); endcase // end // // Busy // always @(posedge clk) // if (rst) busy_now <= 1'b0; else begin if (rdy && ena) busy_now <= 1'b1; //if (!rdy && !busy_now) rdy <= 1'b1; end endmodule