diff --git a/src/ex_stage.sv b/src/ex_stage.sv index 6d4fa1fa654c60e0000c9238323f838512774fb3..ff6aa832c24861ddcd5adf57c689f68888dbcbbe 100644 --- a/src/ex_stage.sv +++ b/src/ex_stage.sv @@ -108,6 +108,11 @@ module ex_stage import ariane_pkg::*; #( input logic[15:0][53:0] pmpaddr_i ); + typedef struct packed { + riscv::xlen_t result; + logic [TRANS_ID_BITS-1:0] trans_id; + } flu_res_t; + // ------------------------- // Fixed Latency Units // ------------------------- @@ -143,6 +148,10 @@ module ex_stage import ariane_pkg::*; #( logic [TRANS_ID_BITS-1:0] mult_trans_id; logic mult_valid; + // FLU arbitrer + flu_res_t alu_res_in, alu_res_out; + logic push_alu_res, pop_alu_res, alu_empty; + // 1. ALU (combinatorial) // data silence operation fu_data_t alu_data; @@ -190,28 +199,50 @@ module ex_stage import ariane_pkg::*; #( .csr_addr_o ); - assign flu_valid_o = alu_valid_i | branch_valid_i | csr_valid_i | mult_valid; + // ready flags for FLU + always_comb begin + flu_ready_o = csr_ready & mult_ready; + end // result MUX always_comb begin - // Branch result as default case - flu_result_o = {{riscv::XLEN-riscv::VLEN{1'b0}}, branch_result}; + pop_alu_res = 1'b0; + push_alu_res = 1'b0; + + flu_result_o = branch_valid_i ? {{riscv::XLEN-riscv::VLEN{1'b0}}, branch_result} : alu_result; flu_trans_id_o = fu_data_i.trans_id; - // ALU result - if (alu_valid_i) begin - flu_result_o = alu_result; - // CSR result - end else if (csr_valid_i) begin + flu_valid_o = 1'b0; + + alu_res_in.result = branch_valid_i ? {{riscv::XLEN-riscv::VLEN{1'b0}}, branch_result} : alu_result; + alu_res_in.trans_id = fu_data_i.trans_id; + + if (csr_valid_i) begin flu_result_o = csr_result; + flu_valid_o = 1'b1; + + if (mult_valid) begin + alu_res_in.result = mult_result; + alu_res_in.trans_id = mult_trans_id; + end + + push_alu_res = mult_valid | alu_valid_i | branch_valid_i; end else if (mult_valid) begin flu_result_o = mult_result; flu_trans_id_o = mult_trans_id; - end - end + flu_valid_o = 1'b1; - // ready flags for FLU - always_comb begin - flu_ready_o = csr_ready & mult_ready; + push_alu_res = alu_valid_i | branch_valid_i; + end else if (~alu_empty) begin + flu_result_o = alu_res_out.result; + flu_trans_id_o = alu_res_out.trans_id; + + flu_valid_o = 1'b1; + pop_alu_res = 1'b1; + + push_alu_res = alu_valid_i | branch_valid_i; + end else if (alu_valid_i | branch_valid_i) begin + flu_valid_o = 1'b1; + end end // 4. Multiplication (Sequential) @@ -231,6 +262,21 @@ module ex_stage import ariane_pkg::*; #( .mult_trans_id_o ( mult_trans_id ) ); + fifo_v3 #( + .DEPTH ( ariane_pkg::NR_SB_ENTRIES ), + .dtype ( flu_res_t ) + ) i_fifo_alu_res ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .flush_i ( flush_i ), + .testmode_i ( 1'b0 ), + .empty_o ( alu_empty ), + .data_i ( alu_res_in ), + .push_i ( push_alu_res ), + .data_o ( alu_res_out ), + .pop_i ( pop_alu_res ) + ); + // ---------------- // FPU // ----------------