aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_reductor.v
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/modexpng_reductor.v')
-rw-r--r--rtl/modexpng_reductor.v270
1 files changed, 270 insertions, 0 deletions
diff --git a/rtl/modexpng_reductor.v b/rtl/modexpng_reductor.v
new file mode 100644
index 0000000..0f5e461
--- /dev/null
+++ b/rtl/modexpng_reductor.v
@@ -0,0 +1,270 @@
+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