mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
This macro is not required and makes the file harder to parse. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: JeanRochCoulon <jean-roch.coulon@thalesgroup.com>
436 lines
15 KiB
Systemverilog
436 lines
15 KiB
Systemverilog
// Copyright 2024 Thales DIS France SAS
|
|
//
|
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
|
//
|
|
// Original Author: Yannick Casamatta - Thales
|
|
// Date: 09/01/2024
|
|
|
|
|
|
module cva6_rvfi
|
|
import ariane_pkg::*;
|
|
#(
|
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
|
parameter type rvfi_instr_t = logic,
|
|
parameter type rvfi_csr_t = logic,
|
|
parameter type rvfi_probes_instr_t = logic,
|
|
parameter type rvfi_probes_csr_t = logic,
|
|
parameter type rvfi_probes_t = logic
|
|
|
|
) (
|
|
|
|
input logic clk_i,
|
|
input logic rst_ni,
|
|
|
|
input rvfi_probes_t rvfi_probes_i,
|
|
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_instr_o,
|
|
output rvfi_csr_t rvfi_csr_o
|
|
|
|
);
|
|
|
|
localparam logic [CVA6Cfg.XLEN-1:0] IsaCode =
|
|
(CVA6Cfg.XLEN'(CVA6Cfg.RVA) << 0) // A - Atomic Instructions extension
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVB) << 1) // C - Bitmanip extension
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVC) << 2) // C - Compressed extension
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVD) << 3) // D - Double precision floating-point extension
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVF) << 5) // F - Single precision floating-point extension
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVH) << 7) // H - Hypervisor extension
|
|
| (CVA6Cfg.XLEN'(1) << 8) // I - RV32I/64I/128I base ISA
|
|
| (CVA6Cfg.XLEN'(1) << 12) // M - Integer Multiply/Divide extension
|
|
| (CVA6Cfg.XLEN'(0) << 13) // N - User level interrupts supported
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVS) << 18) // S - Supervisor mode implemented
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVU) << 20) // U - User mode implemented
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.RVV) << 21) // V - Vector extension
|
|
| (CVA6Cfg.XLEN'(CVA6Cfg.NSX) << 23) // X - Non-standard extensions present
|
|
| ((CVA6Cfg.XLEN == 64 ? 2 : 1) << CVA6Cfg.XLEN - 2); // MXL
|
|
|
|
localparam logic [CVA6Cfg.XLEN-1:0] hart_id_i = '0;
|
|
|
|
localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg);
|
|
|
|
logic flush;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0] issue_instr_ack;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0] fetch_entry_valid;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] truncated;
|
|
|
|
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] issue_pointer;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] commit_pointer;
|
|
|
|
logic flush_unissued_instr;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instr_valid;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0] decoded_instr_ack;
|
|
|
|
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1;
|
|
logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2;
|
|
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] rvfi_intr;
|
|
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.VLEN-1:0] commit_instr_pc;
|
|
fu_op [CVA6Cfg.NrCommitPorts-1:0] commit_instr_op;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rs1;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rs2;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][REG_ADDR_SIZE-1:0] commit_instr_rd;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] commit_instr_result;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0] commit_instr_valid;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0] commit_drop;
|
|
|
|
logic [CVA6Cfg.XLEN-1:0] ex_commit_cause;
|
|
logic ex_commit_valid;
|
|
|
|
riscv::priv_lvl_t priv_lvl;
|
|
|
|
logic [CVA6Cfg.VLEN-1:0] lsu_ctrl_vaddr;
|
|
fu_t lsu_ctrl_fu;
|
|
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_ctrl_be;
|
|
logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_ctrl_trans_id;
|
|
|
|
logic [((CVA6Cfg.CvxifEn || CVA6Cfg.RVV) ? 5 : 4)-1:0][CVA6Cfg.XLEN-1:0] wbdata;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack;
|
|
logic [CVA6Cfg.PLEN-1:0] mem_paddr;
|
|
logic debug_mode;
|
|
logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.XLEN-1:0] wdata;
|
|
|
|
logic [CVA6Cfg.VLEN-1:0] lsu_addr;
|
|
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_rmask;
|
|
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_wmask;
|
|
logic [CVA6Cfg.TRANS_ID_BITS-1:0] lsu_addr_trans_id;
|
|
|
|
riscv::pmpcfg_t [15:0] pmpcfg_q, pmpcfg_d;
|
|
|
|
rvfi_probes_csr_t csr;
|
|
rvfi_probes_instr_t instr;
|
|
|
|
always_comb begin
|
|
csr = '0;
|
|
instr = '0;
|
|
|
|
if ($bits(rvfi_probes_i.instr) == $bits(instr)) begin
|
|
instr = rvfi_probes_i.instr;
|
|
end
|
|
|
|
if ($bits(rvfi_probes_i.csr) == $bits(csr)) begin
|
|
csr = rvfi_probes_i.csr;
|
|
end
|
|
|
|
end
|
|
|
|
|
|
assign flush = instr.flush;
|
|
assign issue_instr_ack = instr.issue_instr_ack;
|
|
assign fetch_entry_valid = instr.fetch_entry_valid;
|
|
assign instruction = instr.instruction;
|
|
assign is_compressed = instr.is_compressed;
|
|
|
|
assign issue_pointer = instr.issue_pointer;
|
|
assign commit_pointer = instr.commit_pointer;
|
|
|
|
assign flush_unissued_instr = instr.flush_unissued_instr;
|
|
assign decoded_instr_valid = instr.decoded_instr_valid;
|
|
assign decoded_instr_ack = instr.decoded_instr_ack;
|
|
|
|
assign rs1 = instr.rs1;
|
|
assign rs2 = instr.rs2;
|
|
|
|
assign commit_instr_pc = instr.commit_instr_pc;
|
|
assign commit_instr_op = instr.commit_instr_op;
|
|
assign commit_instr_rs1 = instr.commit_instr_rs1;
|
|
assign commit_instr_rs2 = instr.commit_instr_rs2;
|
|
assign commit_instr_rd = instr.commit_instr_rd;
|
|
assign commit_instr_result = instr.commit_instr_result;
|
|
assign commit_instr_valid = instr.commit_instr_valid;
|
|
assign commit_drop = instr.commit_drop;
|
|
|
|
assign ex_commit_cause = instr.ex_commit_cause;
|
|
assign ex_commit_valid = instr.ex_commit_valid;
|
|
|
|
assign priv_lvl = instr.priv_lvl;
|
|
|
|
assign wbdata = instr.wbdata;
|
|
assign commit_ack = instr.commit_ack;
|
|
assign mem_paddr = instr.mem_paddr;
|
|
assign debug_mode = instr.debug_mode;
|
|
assign wdata = instr.wdata;
|
|
|
|
assign lsu_addr = instr.lsu_ctrl_vaddr;
|
|
assign lsu_rmask = instr.lsu_ctrl_fu == LOAD ? instr.lsu_ctrl_be : '0;
|
|
assign lsu_wmask = instr.lsu_ctrl_fu == STORE ? instr.lsu_ctrl_be : '0;
|
|
assign lsu_addr_trans_id = instr.lsu_ctrl_trans_id;
|
|
|
|
|
|
//ID STAGE
|
|
|
|
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
|
assign truncated[i] = (is_compressed[i]) ? {16'b0, instruction[i][15:0]} : instruction[i];
|
|
end
|
|
|
|
typedef struct packed {
|
|
logic valid;
|
|
logic [31:0] instr;
|
|
} issue_struct_t;
|
|
issue_struct_t [CVA6Cfg.NrIssuePorts-1:0] issue_n, issue_q;
|
|
logic took0;
|
|
|
|
always_comb begin
|
|
issue_n = issue_q;
|
|
took0 = 1'b0;
|
|
|
|
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
|
if (issue_instr_ack[i]) begin
|
|
issue_n[i].valid = 1'b0;
|
|
end
|
|
end
|
|
|
|
if (!issue_n[CVA6Cfg.NrIssuePorts-1].valid) begin
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].valid = fetch_entry_valid[0];
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].instr = truncated[0];
|
|
took0 = 1'b1;
|
|
end
|
|
|
|
if (!issue_n[0].valid) begin
|
|
issue_n[0] = issue_n[CVA6Cfg.NrIssuePorts-1];
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].valid = 1'b0;
|
|
end
|
|
|
|
if (!issue_n[CVA6Cfg.NrIssuePorts-1].valid) begin
|
|
if (took0) begin
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].valid = fetch_entry_valid[CVA6Cfg.NrIssuePorts-1];
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].instr = truncated[CVA6Cfg.NrIssuePorts-1];
|
|
end else begin
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].valid = fetch_entry_valid[0];
|
|
issue_n[CVA6Cfg.NrIssuePorts-1].instr = truncated[0];
|
|
end
|
|
end
|
|
|
|
if (flush) begin
|
|
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
|
issue_n[i].valid = 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
always_ff @(posedge clk_i or negedge rst_ni) begin
|
|
if (~rst_ni) begin
|
|
issue_q <= '0;
|
|
end else begin
|
|
issue_q <= issue_n;
|
|
end
|
|
end
|
|
|
|
//ISSUE STAGE
|
|
|
|
// this is the FIFO struct of the issue queue
|
|
typedef struct packed {
|
|
logic [CVA6Cfg.XLEN-1:0] rs1_rdata;
|
|
logic [CVA6Cfg.XLEN-1:0] rs2_rdata;
|
|
logic [CVA6Cfg.VLEN-1:0] lsu_addr;
|
|
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_rmask;
|
|
logic [(CVA6Cfg.XLEN/8)-1:0] lsu_wmask;
|
|
logic [CVA6Cfg.XLEN-1:0] lsu_wdata;
|
|
logic [31:0] instr;
|
|
} sb_mem_t;
|
|
sb_mem_t [CVA6Cfg.NR_SB_ENTRIES-1:0] mem_q, mem_n;
|
|
|
|
always_comb begin : issue_fifo
|
|
mem_n = mem_q;
|
|
|
|
for (int unsigned i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
|
if (decoded_instr_valid[i] && decoded_instr_ack[i] && !flush_unissued_instr) begin
|
|
mem_n[issue_pointer[i]] = '{
|
|
rs1_rdata: rs1[i],
|
|
rs2_rdata: rs2[i],
|
|
lsu_addr: '0,
|
|
lsu_rmask: '0,
|
|
lsu_wmask: '0,
|
|
lsu_wdata: '0,
|
|
instr: issue_q[i].instr
|
|
};
|
|
end
|
|
end
|
|
|
|
if (lsu_rmask != 0) begin
|
|
mem_n[lsu_addr_trans_id].lsu_addr = lsu_addr;
|
|
mem_n[lsu_addr_trans_id].lsu_rmask = lsu_rmask;
|
|
end else if (lsu_wmask != 0) begin
|
|
mem_n[lsu_addr_trans_id].lsu_addr = lsu_addr;
|
|
mem_n[lsu_addr_trans_id].lsu_wmask = lsu_wmask;
|
|
mem_n[lsu_addr_trans_id].lsu_wdata = wbdata[STORE_WB];
|
|
end
|
|
end
|
|
|
|
always_ff @(posedge clk_i or negedge rst_ni) begin : regs
|
|
if (!rst_ni) begin
|
|
mem_q <= '{default: sb_mem_t'(0)};
|
|
end else begin
|
|
mem_q <= mem_n;
|
|
end
|
|
end
|
|
|
|
//----------------------------------------------------------------------------------------------------------
|
|
// PACK
|
|
//----------------------------------------------------------------------------------------------------------
|
|
|
|
always_ff @(posedge clk_i) begin
|
|
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
|
|
logic exception;
|
|
logic valid;
|
|
exception = (i == 0) && commit_instr_valid[i] && ex_commit_valid && !commit_drop[i];
|
|
valid = (commit_ack[i] && !ex_commit_valid && !commit_drop[i]) ||
|
|
(exception && (ex_commit_cause == riscv::ENV_CALL_MMODE ||
|
|
ex_commit_cause == riscv::ENV_CALL_SMODE ||
|
|
ex_commit_cause == riscv::ENV_CALL_UMODE));
|
|
rvfi_instr_o[i].valid <= valid;
|
|
rvfi_instr_o[i].insn <= mem_q[commit_pointer[i]].instr;
|
|
// when synchronous trap, the instruction is not executed
|
|
rvfi_instr_o[i].trap <= exception && !ex_commit_cause[31];
|
|
|
|
if (exception && ex_commit_cause[31]) begin
|
|
rvfi_intr[i] <= 'b101;
|
|
end else if (exception) begin
|
|
rvfi_intr[i] <= 'b11;
|
|
end
|
|
if (valid) begin
|
|
rvfi_intr[i] <= 0;
|
|
end
|
|
|
|
rvfi_instr_o[i].intr <= rvfi_intr[i];
|
|
|
|
rvfi_instr_o[i].cause <= ex_commit_cause;
|
|
rvfi_instr_o[i].mode <= (CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl;
|
|
rvfi_instr_o[i].ixl <= CVA6Cfg.XLEN == 64 ? 2 : 1;
|
|
rvfi_instr_o[i].rs1_addr <= commit_instr_rs1[i];
|
|
rvfi_instr_o[i].rs2_addr <= commit_instr_rs2[i];
|
|
rvfi_instr_o[i].rd_addr <= commit_instr_rd[i];
|
|
rvfi_instr_o[i].rd_wdata <= (CVA6Cfg.FpPresent && is_rd_fpr(
|
|
commit_instr_op[i]
|
|
)) ? commit_instr_result[i] : wdata[i];
|
|
rvfi_instr_o[i].pc_rdata <= commit_instr_pc[i];
|
|
rvfi_instr_o[i].mem_addr <= mem_q[commit_pointer[i]].lsu_addr;
|
|
// So far, only write paddr is reported. TODO: read paddr
|
|
rvfi_instr_o[i].mem_paddr <= mem_paddr;
|
|
rvfi_instr_o[i].mem_wmask <= mem_q[commit_pointer[i]].lsu_wmask;
|
|
rvfi_instr_o[i].mem_wdata <= mem_q[commit_pointer[i]].lsu_wdata;
|
|
rvfi_instr_o[i].mem_rmask <= mem_q[commit_pointer[i]].lsu_rmask;
|
|
rvfi_instr_o[i].mem_rdata <= commit_instr_result[i];
|
|
rvfi_instr_o[i].rs1_rdata <= mem_q[commit_pointer[i]].rs1_rdata;
|
|
rvfi_instr_o[i].rs2_rdata <= mem_q[commit_pointer[i]].rs2_rdata;
|
|
end
|
|
end
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------
|
|
// CSR
|
|
//----------------------------------------------------------------------------------------------------------
|
|
|
|
`define CONNECT_RVFI_FULL(CSR_ENABLE_COND, CSR_NAME,
|
|
CSR_SOURCE_NAME) \
|
|
always_ff @(posedge clk_i) begin \
|
|
if (CSR_ENABLE_COND) begin \
|
|
rvfi_csr_o.``CSR_NAME``.rdata <= {{CVA6Cfg.XLEN - $bits(CSR_SOURCE_NAME)}, CSR_SOURCE_NAME}; \
|
|
end \
|
|
end \
|
|
assign rvfi_csr_o.``CSR_NAME``.wdata = CSR_ENABLE_COND ? { {{CVA6Cfg.XLEN-$bits(CSR_SOURCE_NAME)}, CSR_SOURCE_NAME} } : 0; \
|
|
assign rvfi_csr_o.``CSR_NAME``.rmask = CSR_ENABLE_COND ? 1 : 0; \
|
|
assign rvfi_csr_o.``CSR_NAME``.wmask = (rvfi_csr_o.``CSR_NAME``.rdata != {{CVA6Cfg.XLEN - $bits(CSR_SOURCE_NAME)}, CSR_SOURCE_NAME}) && CSR_ENABLE_COND;
|
|
|
|
`define CONNECT_RVFI_SAME(CSR_ENABLE_COND, CSR_NAME) \
|
|
`CONNECT_RVFI_FULL(CSR_ENABLE_COND, CSR_NAME, csr.``CSR_NAME``_q)
|
|
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fflags, csr.fcsr_q.fflags)
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, frm, csr.fcsr_q.frm)
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fcsr, {csr.fcsr_q.frm, csr.fcsr_q.fflags})
|
|
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, ftran, csr.fcsr_q.fprec)
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.FpPresent, dcsr)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.DebugEn, dpc)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.DebugEn, dscratch0)
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.DebugEn, dscratch1)
|
|
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.RVS, sstatus,
|
|
csr.mstatus_extended & SMODE_STATUS_READ_MASK[CVA6Cfg.XLEN-1:0])
|
|
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.RVS, sie, csr.mie_q & csr.mideleg_q)
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.RVS, sip, csr.mip_q & csr.mideleg_q)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, stvec)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, scounteren)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, sscratch)
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, sepc)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, scause)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, stval)
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, satp)
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, mstatus, csr.mstatus_extended)
|
|
|
|
bit [31:0] mstatush_q;
|
|
`CONNECT_RVFI_FULL(1'b1, mstatush, mstatush_q)
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, misa, IsaCode)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, medeleg)
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVS, mideleg)
|
|
|
|
`CONNECT_RVFI_SAME(1'b1, mie)
|
|
`CONNECT_RVFI_SAME(1'b1, mtvec)
|
|
`CONNECT_RVFI_SAME(1'b1, mcounteren)
|
|
|
|
`CONNECT_RVFI_SAME(1'b1, mscratch)
|
|
|
|
`CONNECT_RVFI_SAME(1'b1, mepc)
|
|
`CONNECT_RVFI_SAME(1'b1, mcause)
|
|
`CONNECT_RVFI_SAME(1'b1, mtval)
|
|
`CONNECT_RVFI_SAME(1'b1, mip)
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, menvcfg, csr.fiom_q)
|
|
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, menvcfgh, 32'h0)
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, mvendorid, OPENHWGROUP_MVENDORID)
|
|
`CONNECT_RVFI_FULL(1'b1, marchid, ARIANE_MARCHID)
|
|
`CONNECT_RVFI_FULL(1'b1, mhartid, hart_id_i)
|
|
|
|
`CONNECT_RVFI_SAME(1'b1, mcountinhibit)
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, mcycle, csr.cycle_q[CVA6Cfg.XLEN-1:0])
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, mcycleh, csr.cycle_q[63:32])
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, minstret, csr.instret_q[CVA6Cfg.XLEN-1:0])
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, minstreth, csr.instret_q[63:32])
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, cycle, csr.cycle_q[CVA6Cfg.XLEN-1:0])
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, cycleh, csr.cycle_q[63:32])
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, instret, csr.instret_q[CVA6Cfg.XLEN-1:0])
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, instreth, csr.instret_q[63:32])
|
|
|
|
`CONNECT_RVFI_SAME(1'b1, dcache)
|
|
`CONNECT_RVFI_SAME(1'b1, icache)
|
|
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.EnableAccelerator, acc_cons)
|
|
`CONNECT_RVFI_SAME(CVA6Cfg.RVZCMT, jvt)
|
|
`CONNECT_RVFI_FULL(1'b1, pmpcfg0, csr.pmpcfg_q[CVA6Cfg.XLEN/8-1:0])
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, pmpcfg1, csr.pmpcfg_q[7:4])
|
|
|
|
`CONNECT_RVFI_FULL(1'b1, pmpcfg2, csr.pmpcfg_q[8+:CVA6Cfg.XLEN/8])
|
|
`CONNECT_RVFI_FULL(CVA6Cfg.XLEN == 32, pmpcfg3, csr.pmpcfg_q[15:12])
|
|
|
|
bit [CVA6Cfg.XLEN-1:0] pmpaddr_q;
|
|
genvar i;
|
|
generate
|
|
for (i = 0; i < 16; i++) begin
|
|
`CONNECT_RVFI_FULL(1'b1, pmpaddr[i], {
|
|
csr.pmpaddr_q[i][CVA6Cfg.PLEN-3:1], pmpcfg_q[i].addr_mode[1]})
|
|
end
|
|
endgenerate
|
|
;
|
|
|
|
endmodule
|