Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 90 additions & 32 deletions core/cache_subsystem/wt_axi_adapter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ module wt_axi_adapter
output axi_req_t axi_req_o,
input axi_rsp_t axi_resp_i,

// Endianness Control Signal from CSR
input logic mbe_i,

// Invalidations
input logic [63:0] inval_addr_i,
input logic inval_valid_i,
Expand Down Expand Up @@ -264,43 +267,98 @@ module wt_axi_adapter
end
// RISC-V atops have a load semantic
AMO_SWAP: axi_wr_atop = axi_pkg::ATOP_ATOMICSWAP;
AMO_ADD:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_ADD
};
AMO_ADD: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_ADD
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_ADD
};
end
end
AMO_AND: begin
// in this case we need to invert the data to get a "CLR"
axi_wr_data[0] = ~{(CVA6Cfg.AxiDataWidth / CVA6Cfg.XLEN) {dcache_data.data}};
axi_wr_user = ~{(CVA6Cfg.AxiDataWidth / CVA6Cfg.XLEN) {dcache_data.user}};
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_CLR
};
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_CLR
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_CLR
};
end
end
AMO_OR: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_SET
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SET
};
end
end
AMO_XOR: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_EOR
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_EOR
};
end
end
AMO_MAX: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_SMAX
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SMAX
};
end
end
AMO_MAXU: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_UMAX
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_UMAX
};
end
end
AMO_MIN: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_SMIN
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SMIN
};
end
end
AMO_MINU: begin
if (mbe_i) begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_BIG_END, axi_pkg::ATOP_UMIN
};
end else begin
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_UMIN
};
end
end
AMO_OR:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SET
};
AMO_XOR:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_EOR
};
AMO_MAX:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SMAX
};
AMO_MAXU:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_UMAX
};
AMO_MIN:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_SMIN
};
AMO_MINU:
axi_wr_atop = {
axi_pkg::ATOP_ATOMICLOAD, axi_pkg::ATOP_LITTLE_END, axi_pkg::ATOP_UMIN
};
default: ; // Do nothing
default: ; // Do nothing
endcase
end
end
Expand Down
3 changes: 3 additions & 0 deletions core/cache_subsystem/wt_cache_subsystem.sv
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module wt_cache_subsystem
// AMO interface
input amo_req_t dcache_amo_req_i,
output amo_resp_t dcache_amo_resp_o,
input logic mbe_i,
// Request ports
input dcache_req_i_t [NumPorts-1:0] dcache_req_ports_i, // to/from LSU
output dcache_req_o_t [NumPorts-1:0] dcache_req_ports_o, // to/from LSU
Expand Down Expand Up @@ -164,6 +165,7 @@ module wt_cache_subsystem
.wbuffer_not_ni_o(wbuffer_not_ni_o),
.amo_req_i (dcache_amo_req_i),
.amo_resp_o (dcache_amo_resp_o),
.mbe_i (mbe_i),
.req_ports_i (dcache_req_ports_i),
.req_ports_o (dcache_req_ports_o),
.miss_vld_bits_o (miss_vld_bits_o),
Expand Down Expand Up @@ -228,6 +230,7 @@ module wt_cache_subsystem
.dcache_rtrn_o (adapter_dcache),
.axi_req_o (noc_req_o),
.axi_resp_i (noc_resp_i),
.mbe_i (mbe_i),
.inval_addr_i (inval_addr_i),
.inval_valid_i (inval_valid_i),
.inval_ready_o (inval_ready_o)
Expand Down
2 changes: 2 additions & 0 deletions core/cache_subsystem/wt_dcache.sv
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module wt_dcache
// AMO interface
input amo_req_t amo_req_i,
output amo_resp_t amo_resp_o,
input logic mbe_i,

// Request ports
input dcache_req_i_t [NumPorts-1:0] req_ports_i,
Expand Down Expand Up @@ -148,6 +149,7 @@ module wt_dcache
// amo interface
.amo_req_i (amo_req_i),
.amo_resp_o (amo_resp_o),
.mbe_i (mbe_i),
// miss handling interface
.miss_req_i (miss_req),
.miss_ack_o (miss_ack),
Expand Down
30 changes: 27 additions & 3 deletions core/cache_subsystem/wt_dcache_missunit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module wt_dcache_missunit
// AMO interface
input amo_req_t amo_req_i,
output amo_resp_t amo_resp_o,
input logic mbe_i,
// miss handling interface (ld, ptw, wbuffer)
input logic [NumPorts-1:0] miss_req_i,
output logic [NumPorts-1:0] miss_ack_o,
Expand Down Expand Up @@ -288,9 +289,32 @@ module wt_dcache_missunit
assign amo_rtrn_mux = mem_rtrn_i.data[amo_req_i.operand_a[CVA6Cfg.DCACHE_OFFSET_WIDTH-1:3]*64+:64];
end

// always sign extend 32bit values
assign amo_resp_o.result = (amo_req_i.size==2'b10) ? {{32{amo_rtrn_mux[amo_req_i.operand_a[2]*32 + 31]}},amo_rtrn_mux[amo_req_i.operand_a[2]*32 +: 32]} :
amo_rtrn_mux ;
// BIG ENDIAN CAPABLE logic for amo return value from memory
logic [63:0] amoResult_LE;
logic [63:0] amoResult_BE;

// Little Endian Calculation of return value from memory (when 32bit, we need to sign extend)
logic [63:0] amoResult_32bitLE;
assign amoResult_32bitLE = {
{32{amo_rtrn_mux[amo_req_i.operand_a[2]*32+31]}}, amo_rtrn_mux[amo_req_i.operand_a[2]*32+:32]
};

// Big Endian Calculations of return value from memory with AMO operations (Bytes need swapping and sign extension is different)
logic [63:0] amoResult_64bitBE;
logic [31:0] amoResult_32bitBE_NoSign;
logic [63:0] amoResult_32bitBE;
assign amoResult_64bitBE = {<<8{amo_rtrn_mux}};
assign amoResult_32bitBE_NoSign = {<<8{amo_rtrn_mux[amo_req_i.operand_a[2]*32+:32]}};
assign amoResult_32bitBE = {
{32{amo_rtrn_mux[amo_req_i.operand_a[2]*32+7]}}, amoResult_32bitBE_NoSign
}; // +7 to the base address to find the sign bit, as in BE the Most Significant Byte is always at the lowest addressed byte.

assign amoResult_BE = (amo_req_i.size == 2'b10) ? amoResult_32bitBE : amoResult_64bitBE;
assign amoResult_LE = (amo_req_i.size == 2'b10) ? amoResult_32bitLE : amo_rtrn_mux;

assign amo_resp_o.result = mbe_i ? amoResult_BE : amoResult_LE;
// end BIG ENDIAN CAPABLE logic for amo return value from memory

assign amo_req_d = amo_req_i.req;
end

Expand Down
25 changes: 22 additions & 3 deletions core/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ module csr_regfile
output logic [CVA6Cfg.VLEN-1:0] trap_vector_base_o,
// Current privilege level the CPU is in - EX_STAGE
output riscv::priv_lvl_t priv_lvl_o,
// Data Endian mode
output logic mbe_o,
// Current virtualization mode state the CPU is in - EX_STAGE
output logic v_o,
// Imprecise FP exception from the accelerator (fcsr.fflags format) - ACC_DISPATCHER
Expand Down Expand Up @@ -215,6 +217,7 @@ module csr_regfile
riscv::hstatus_rv_t hstatus_q, hstatus_d;
riscv::mstatus_rv_t vsstatus_q, vsstatus_d;
logic [CVA6Cfg.XLEN-1:0] mstatus_extended;
logic [31:0] mstatush;
logic [CVA6Cfg.XLEN-1:0] vsstatus_extended;
satp_t satp_q, satp_d;
satp_t vsatp_q, vsatp_d;
Expand Down Expand Up @@ -314,6 +317,7 @@ module csr_regfile
// ----------------
assign mstatus_extended = CVA6Cfg.IS_XLEN64 ? mstatus_q[CVA6Cfg.XLEN-1:0] :
{mstatus_q.sd, mstatus_q.wpri3[7:0], mstatus_q[22:0]};
assign mstatush = {24'h0, mstatus_q.mpv, mstatus_q.gva, mstatus_q.mbe, mstatus_q.sbe, 4'h0};
if (CVA6Cfg.RVH) begin
if (CVA6Cfg.IS_XLEN64) begin : gen_vsstatus_64read
assign vsstatus_extended = vsstatus_q[CVA6Cfg.XLEN-1:0];
Expand Down Expand Up @@ -521,7 +525,7 @@ module csr_regfile
// machine mode registers
riscv::CSR_MSTATUS: csr_rdata = mstatus_extended;
riscv::CSR_MSTATUSH:
if (CVA6Cfg.XLEN == 32) csr_rdata = '0;
if (CVA6Cfg.XLEN == 32) csr_rdata = mstatush;
else read_access_exception = 1'b1;
riscv::CSR_MISA: csr_rdata = IsaCode;
riscv::CSR_MEDELEG:
Expand Down Expand Up @@ -1390,11 +1394,24 @@ module csr_regfile
mstatus_d.wpri1 = 1'b0;
mstatus_d.wpri2 = 1'b0;
mstatus_d.wpri0 = 1'b0;
mstatus_d.ube = 1'b0; // CVA6 is little-endian
// Mirror MBE
mstatus_d.sbe = mstatus_d.mbe;
mstatus_d.ube = mstatus_d.mbe;
// this register has side-effects on other registers, flush the pipeline
flush_o = 1'b1;
end
riscv::CSR_MSTATUSH: if (CVA6Cfg.XLEN != 32) update_access_exception = 1'b1;
riscv::CSR_MSTATUSH: begin
if (CVA6Cfg.XLEN == 32) begin
mstatus_d.mbe = ((csr_wdata & riscv::MSTATUSH_MBE) != 0);
// Mirror MBE
mstatus_d.sbe = mstatus_d.mbe;
mstatus_d.ube = mstatus_d.mbe;
// this register has side-effects on other registers, flush the pipeline
flush_o = 1'b1;
end else begin
update_access_exception = 1'b1;
end
end
// MISA is WARL (Write Any Value, Reads Legal Value)
riscv::CSR_MISA: ;
// machine exception delegation register
Expand Down Expand Up @@ -2535,6 +2552,8 @@ module csr_regfile
assign single_step_o = CVA6Cfg.DebugEn ? dcsr_q.step : 1'b0;
assign mcountinhibit_o = {{29 - MHPMCounterNum{1'b0}}, mcountinhibit_q};

assign mbe_o = mstatus_q.mbe;

// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
Expand Down
20 changes: 12 additions & 8 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,15 @@ module cva6
// Global Signals
// Signals connecting more than one module
// ------------------------------------------
riscv::priv_lvl_t priv_lvl;
logic v;
exception_t ex_commit; // exception from commit stage
bp_resolve_t resolved_branch;
logic [ CVA6Cfg.VLEN-1:0] pc_commit;
logic eret;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;
riscv::priv_lvl_t priv_lvl;
logic v;
exception_t ex_commit; // exception from commit stage
bp_resolve_t resolved_branch;
logic [CVA6Cfg.VLEN-1:0] pc_commit;
logic eret;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;
logic mbe; // determines the data endian-ness of the processor

localparam NumPorts = 4;

Expand Down Expand Up @@ -1047,6 +1048,7 @@ module cva6
.flush_tlb_vvma_i (flush_tlb_vvma_ctrl_ex),
.flush_tlb_gvma_i (flush_tlb_gvma_ctrl_ex),
.priv_lvl_i (priv_lvl), // from CSR
.mbe_i (mbe), // from CSR
.v_i (v), // from CSR
.ld_st_priv_lvl_i (ld_st_priv_lvl_csr_ex), // from CSR
.ld_st_v_i (ld_st_v_csr_ex), // from CSR
Expand Down Expand Up @@ -1161,6 +1163,7 @@ module cva6
.eret_o (eret),
.trap_vector_base_o (trap_vector_base_commit_pcgen),
.priv_lvl_o (priv_lvl),
.mbe_o (mbe),
.v_o (v),
.acc_fflags_ex_i (acc_resp_fflags),
.acc_fflags_ex_valid_i (acc_resp_fflags_valid),
Expand Down Expand Up @@ -1382,6 +1385,7 @@ module cva6
// to commit stage
.dcache_amo_req_i (amo_req),
.dcache_amo_resp_o (amo_resp),
.mbe_i (mbe),
// from PTW, Load Unit and Store Unit
.dcache_miss_o (dcache_miss_cache_perf),
.miss_vld_bits_o (miss_vld_bits),
Expand Down
5 changes: 3 additions & 2 deletions core/cva6_mmu/cva6_mmu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// Description: Memory Management Unit for CVA6, contains TLB and
// address translation unit. SV32 SV39 and SV39x4 as defined in RISC-V
// privilege specification 1.11-WIP.
// This module is an merge of the MMU Sv39 developed
// This module is a merge of the MMU Sv39 developed
// by Florian Zaruba, the MMU Sv32 developed by Sebastien Jacq and the MMU Sv39x4 developed by Bruno Sá.


Expand Down Expand Up @@ -72,6 +72,7 @@ module cva6_mmu
input logic vs_sum_i,
input logic mxr_i,
input logic vmxr_i,
input logic mbe_i,
input logic hlvx_inst_i,
input logic hs_ld_st_inst_i,
// input logic flag_mprv_i,
Expand Down Expand Up @@ -341,7 +342,7 @@ module cva6_mmu
.hgatp_ppn_i,
.mxr_i,
.vmxr_i,

.mbe_i(mbe_i),
// Performance counters
.shared_tlb_miss_o(shared_tlb_miss), //open for now

Expand Down
Loading