mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
83 lines
2.9 KiB
Systemverilog
83 lines
2.9 KiB
Systemverilog
// Copyright 2018 ETH Zurich and University of Bologna.
|
|
// Copyright and related rights are licensed under the Solderpad Hardware
|
|
// License, Version 0.51 (the "License"); you may not use this file except in
|
|
// compliance with the License. You may obtain a copy of the License at
|
|
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
|
// or agreed to in writing, software, hardware and materials distributed under
|
|
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations under the License.
|
|
//
|
|
// Author: Florian Zaruba, ETH Zurich
|
|
// Date: 05.05.2017
|
|
// Description: Buffer to hold CSR address, this acts like a functional unit
|
|
// to the scoreboard.
|
|
|
|
|
|
module csr_buffer
|
|
import ariane_pkg::*;
|
|
#(
|
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
|
parameter type fu_data_t = logic
|
|
) (
|
|
// Subsystem Clock - SUBSYSTEM
|
|
input logic clk_i,
|
|
// Asynchronous reset active low - SUBSYSTEM
|
|
input logic rst_ni,
|
|
// Flush CSR - CONTROLLER
|
|
input logic flush_i,
|
|
// FU data needed to execute instruction - ISSUE_STAGE
|
|
input fu_data_t fu_data_i,
|
|
// CSR FU is ready - ISSUE_STAGE
|
|
output logic csr_ready_o,
|
|
// CSR instruction is valid - ISSUE_STAGE
|
|
input logic csr_valid_i,
|
|
// CSR buffer result - ISSUE_STAGE
|
|
output logic [CVA6Cfg.XLEN-1:0] csr_result_o,
|
|
// commit the pending CSR OP - TO_BE_COMPLETED
|
|
input logic csr_commit_i,
|
|
// CSR address to write - COMMIT_STAGE
|
|
output logic [11:0] csr_addr_o
|
|
);
|
|
// 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;
|
|
|
|
// control logic, scoreboard signals
|
|
assign csr_result_o = fu_data_i.operand_a;
|
|
assign csr_addr_o = csr_reg_q.csr_address;
|
|
|
|
// 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
|
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
|
if (~rst_ni) begin
|
|
csr_reg_q <= '{default: 0};
|
|
end else begin
|
|
csr_reg_q <= csr_reg_n;
|
|
end
|
|
end
|
|
|
|
endmodule
|