diff --git a/src/csr_buffer.sv b/src/csr_buffer.sv index 15108f780054bef057b3b715d67df4a447113dc2..3937aa3b239f25d0650c4f8479832213890b8503 100644 --- a/src/csr_buffer.sv +++ b/src/csr_buffer.sv @@ -28,46 +28,37 @@ module csr_buffer import ariane_pkg::*; ( // to CSR file output logic [11:0] csr_addr_o // CSR address to commit stage ); - // this is a single entry store buffer for the address of the CSR + // This is a single entry store buffer for the address of the CSR // which we are going to need in the commit stage - struct packed { - logic [11:0] csr_address; - logic valid; - } csr_reg_n, csr_reg_q; + logic [11:0] csr_address_n, csr_address_q; + logic csr_valid_n, csr_valid_q; - // control logic, scoreboard signals - assign csr_result_o = fu_data_i.operand_a; - assign csr_addr_o = csr_reg_q.csr_address; + // Write logic + // Clear the buffer if we flushed or if there is a commit with no new valid instruction + assign csr_valid_n = (flush_i) ? 1'b0 : + (csr_commit_i && ~csr_valid_i) ? 1'b0 : + (csr_valid_i) ? 1'b1 : + csr_valid_q; - // write logic - always_comb begin : write - csr_reg_n = csr_reg_q; - // by default we are ready - csr_ready_o = 1'b1; - // if we have a valid uncomiited csr req or are just getting one WITHOUT a commit in, we are not ready - if ((csr_reg_q.valid || csr_valid_i) && ~csr_commit_i) - csr_ready_o = 1'b0; - // if we got a valid from the scoreboard - // store the CSR address - if (csr_valid_i) begin - csr_reg_n.csr_address = fu_data_i.operand_b[11:0]; - csr_reg_n.valid = 1'b1; - end - // if we get a commit and no new valid instruction -> clear the valid bit - if (csr_commit_i && ~csr_valid_i) begin - csr_reg_n.valid = 1'b0; - end - // clear the buffer if we flushed - if (flush_i) - csr_reg_n.valid = 1'b0; - end - // sequential process + // Store the CSR address if we got a valid from the scoreboard. + assign csr_address_n = (csr_valid_i) ? fu_data_i.operand_b[11:0] : csr_address_q; + + // If we have a valid uncomitted CSR req or are just getting one without a + // commit in, we are not ready. + assign csr_ready_o = ~((csr_valid_q || csr_valid_i) && ~csr_commit_i); + + // Control logic, scoreboard signals + assign csr_result_o = fu_data_i.operand_a; + assign csr_addr_o = csr_address_q; + + // Sequential process always_ff @(posedge clk_i or negedge rst_ni) begin - if(~rst_ni) begin - csr_reg_q <= '{default: 0}; + if (~rst_ni) begin + csr_valid_q <= 1'b0; + csr_address_q <= '0; end else begin - csr_reg_q <= csr_reg_n; + csr_valid_q <= csr_valid_n; + csr_address_q <= csr_address_n; end end - endmodule