:Fix: Misaligned page exceptions, add dirty test

This commit is contained in:
Florian Zaruba 2017-06-18 21:50:28 +02:00
parent 8352e83ed1
commit 1701a8a784
10 changed files with 193 additions and 136 deletions

View file

@ -42,7 +42,7 @@ riscv-tests = rv64ui-p-add rv64ui-p-addi rv64ui-p-slli rv64ui-p-addiw rv64ui-p-a
rv64ui-p-lw rv64ui-p-lwu \
rv64mi-p-csr rv64mi-p-mcsr rv64mi-p-illegal rv64mi-p-ma_addr rv64mi-p-ma_fetch rv64mi-p-sbreak rv64mi-p-scall \
rv64si-p-csr rv64si-p-ma_fetch rv64si-p-scall rv64si-p-wfi rv64si-p-sbreak \
rv64uc-p-rvc
rv64uc-p-rvc rv64si-p-dirty
riscv-test = rv64ui-p-add

View file

@ -82,7 +82,7 @@ Check out the [contribution guide](CONTRIBUTING.md)
| **Test Name** | **P/F/U** | **Test Name** | **P/F/U** | **Test Name** | **P/F/U** |
|---------------|--------------------|---------------|--------------------|---------------|--------------------|
| csr | :white_check_mark: | dirty | :x: | ma_fetch | :white_check_mark: |
| csr | :white_check_mark: | dirty | :white_check_mark: | ma_fetch | :white_check_mark: |
| sbreak | :white_check_mark: | scall | :white_check_mark: | wfi | :white_check_mark: |

View file

@ -1,17 +1,27 @@
/* Ariane ALU
* File: scoreboard.sv
* Author: Matthias Baer <baermatt@student.ethz.ch>
* Author: Igor Loi <igor.loi@unibo.it>
* Author: Andreas Traber <atraber@student.ethz.ch>
* Author: Lukas Mueller <lukasmue@student.ethz.ch>
* Author: Florian Zaruba <zaruabf@ethz.ch>
* Date: 19.3.2017
*
* Description: Minimal version of the ALU, 64-bit compatible
*
* Copyright (C) 2017 ETH Zurich, University of Bologna
* All rights reserved.
*/
// Author: Matthias Baer <baermatt@student.ethz.ch>
// Author: Igor Loi <igor.loi@unibo.it>
// Author: Andreas Traber <atraber@student.ethz.ch>
// Author: Lukas Mueller <lukasmue@student.ethz.ch>
// Author: Florian Zaruba <zaruabf@ethz.ch>
//
// Date: 19.03.2017
// Description: Ariane ALU
//
//
// Copyright (C) 2017 ETH Zurich, University of Bologna
// All rights reserved.
//
// This code is under development and not yet released to the public.
// Until it is released, the code is under the copyright of ETH Zurich and
// the University of Bologna, and may contain confidential and/or unpublished
// work. Any reuse/redistribution is strictly forbidden without written
// permission from ETH Zurich.
//
// Bug fixes and contributions will eventually be released under the
// SolderPad open hardware license in the context of the PULP platform
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
// University of Bologna.
//
import ariane_pkg::*;
module alu

View file

@ -193,6 +193,7 @@ module ariane
// CSR <-> *
// --------------
logic enable_translation_csr_ex;
logic en_ld_st_translation_csr_ex;
priv_lvl_t ld_st_priv_lvl_csr_ex;
logic sum_csr_ex;
logic mxr_csr_ex;
@ -328,68 +329,69 @@ module ariane
// EX
// ---------
ex_stage ex_stage_i (
.flush_i ( flush_ctrl_ex ),
.fu_i ( fu_id_ex ),
.operator_i ( operator_id_ex ),
.operand_a_i ( operand_a_id_ex ),
.operand_b_i ( operand_b_id_ex ),
.imm_i ( imm_id_ex ),
.trans_id_i ( trans_id_id_ex ),
.pc_i ( pc_id_ex ),
.is_compressed_instr_i ( is_compressed_instr_id_ex ),
.flush_i ( flush_ctrl_ex ),
.fu_i ( fu_id_ex ),
.operator_i ( operator_id_ex ),
.operand_a_i ( operand_a_id_ex ),
.operand_b_i ( operand_b_id_ex ),
.imm_i ( imm_id_ex ),
.trans_id_i ( trans_id_id_ex ),
.pc_i ( pc_id_ex ),
.is_compressed_instr_i ( is_compressed_instr_id_ex ),
// ALU
.alu_ready_o ( alu_ready_ex_id ),
.alu_valid_i ( alu_valid_id_ex ),
.alu_result_o ( alu_result_ex_id ),
.alu_trans_id_o ( alu_trans_id_ex_id ),
.alu_valid_o ( alu_valid_ex_id ),
.alu_exception_o ( ),
.alu_ready_o ( alu_ready_ex_id ),
.alu_valid_i ( alu_valid_id_ex ),
.alu_result_o ( alu_result_ex_id ),
.alu_trans_id_o ( alu_trans_id_ex_id ),
.alu_valid_o ( alu_valid_ex_id ),
.alu_exception_o ( ),
// Branches and Jumps
.branch_ready_o ( branch_ready_ex_id ),
.branch_valid_o ( branch_valid_ex_id ),
.branch_valid_i ( branch_valid_id_ex ),
.branch_trans_id_o ( branch_trans_id_ex_id ),
.branch_result_o ( branch_result_ex_id ),
.branch_exception_o ( branch_exception_ex_id ),
.branch_predict_i ( branch_predict_id_ex ), // branch predict to ex
.resolved_branch_o ( resolved_branch ),
.resolve_branch_o ( resolve_branch_ex_id ),
.branch_ready_o ( branch_ready_ex_id ),
.branch_valid_o ( branch_valid_ex_id ),
.branch_valid_i ( branch_valid_id_ex ),
.branch_trans_id_o ( branch_trans_id_ex_id ),
.branch_result_o ( branch_result_ex_id ),
.branch_exception_o ( branch_exception_ex_id ),
.branch_predict_i ( branch_predict_id_ex ), // branch predict to ex
.resolved_branch_o ( resolved_branch ),
.resolve_branch_o ( resolve_branch_ex_id ),
// LSU
.lsu_ready_o ( lsu_ready_ex_id ),
.lsu_valid_i ( lsu_valid_id_ex ),
.lsu_result_o ( lsu_result_ex_id ),
.lsu_trans_id_o ( lsu_trans_id_ex_id ),
.lsu_valid_o ( lsu_valid_ex_id ),
.lsu_commit_i ( lsu_commit_commit_ex ), // from commit
.lsu_exception_o ( lsu_exception_ex_id ),
.no_st_pending_o ( no_st_pending_ex_commit ),
.lsu_ready_o ( lsu_ready_ex_id ),
.lsu_valid_i ( lsu_valid_id_ex ),
.lsu_result_o ( lsu_result_ex_id ),
.lsu_trans_id_o ( lsu_trans_id_ex_id ),
.lsu_valid_o ( lsu_valid_ex_id ),
.lsu_commit_i ( lsu_commit_commit_ex ), // from commit
.lsu_exception_o ( lsu_exception_ex_id ),
.no_st_pending_o ( no_st_pending_ex_commit ),
// CSR
.csr_ready_o ( csr_ready_ex_id ),
.csr_valid_i ( csr_valid_id_ex ),
.csr_trans_id_o ( csr_trans_id_ex_id ),
.csr_result_o ( csr_result_ex_id ),
.csr_valid_o ( csr_valid_ex_id ),
.csr_addr_o ( csr_addr_ex_csr ),
.csr_commit_i ( csr_commit_commit_ex ), // from commit
.csr_ready_o ( csr_ready_ex_id ),
.csr_valid_i ( csr_valid_id_ex ),
.csr_trans_id_o ( csr_trans_id_ex_id ),
.csr_result_o ( csr_result_ex_id ),
.csr_valid_o ( csr_valid_ex_id ),
.csr_addr_o ( csr_addr_ex_csr ),
.csr_commit_i ( csr_commit_commit_ex ), // from commit
// Memory Management
.enable_translation_i ( enable_translation_csr_ex ), // from CSR
.flush_tlb_i ( flush_tlb_ctrl_ex ),
.fetch_req_i ( fetch_req_if_ex ),
.fetch_gnt_o ( fetch_gnt_ex_if ),
.fetch_valid_o ( fetch_valid_ex_if ),
.fetch_vaddr_i ( fetch_vaddr_if_ex ),
.fetch_rdata_o ( fetch_rdata_ex_if ),
.fetch_ex_o ( fetch_ex_ex_if ), // fetch exception to IF
.priv_lvl_i ( priv_lvl ), // from CSR
.ld_st_priv_lvl_i ( ld_st_priv_lvl_csr_ex ), // from CSR
.sum_i ( sum_csr_ex ), // from CSR
.mxr_i ( mxr_csr_ex ), // from CSR
.satp_ppn_i ( satp_ppn_csr_ex ), // from CSR
.asid_i ( asid_csr_ex ), // from CSR
.enable_translation_i ( enable_translation_csr_ex ), // from CSR
.en_ld_st_translation_i ( en_ld_st_translation_csr_ex ),
.flush_tlb_i ( flush_tlb_ctrl_ex ),
.fetch_req_i ( fetch_req_if_ex ),
.fetch_gnt_o ( fetch_gnt_ex_if ),
.fetch_valid_o ( fetch_valid_ex_if ),
.fetch_vaddr_i ( fetch_vaddr_if_ex ),
.fetch_rdata_o ( fetch_rdata_ex_if ),
.fetch_ex_o ( fetch_ex_ex_if ), // fetch exception to IF
.priv_lvl_i ( priv_lvl ), // from CSR
.ld_st_priv_lvl_i ( ld_st_priv_lvl_csr_ex ), // from CSR
.sum_i ( sum_csr_ex ), // from CSR
.mxr_i ( mxr_csr_ex ), // from CSR
.satp_ppn_i ( satp_ppn_csr_ex ), // from CSR
.asid_i ( asid_csr_ex ), // from CSR
.mult_ready_o ( mult_ready_ex_id ),
.mult_valid_i ( mult_valid_id_ex ),
.mult_ready_o ( mult_ready_ex_id ),
.mult_valid_i ( mult_valid_id_ex ),
.*
);
@ -436,7 +438,8 @@ module ariane
.trap_vector_base_o ( trap_vector_base_commit_pcgen ),
.priv_lvl_o ( priv_lvl ),
.ld_st_priv_lvl_o ( ld_st_priv_lvl_csr_ex ),
.enable_translation_o ( enable_translation_csr_ex ),
.en_translation_o ( enable_translation_csr_ex ),
.en_ld_st_translation_o ( en_ld_st_translation_csr_ex ),
.sum_o ( sum_csr_ex ),
.mxr_o ( mxr_csr_ex ),
.satp_ppn_o ( satp_ppn_csr_ex ),
@ -509,6 +512,10 @@ module ariane
initial begin
it.trace();
end
final begin
it.close();
end
endprogram
instr_tracer instr_tracer_i (tracer_if);

View file

@ -22,47 +22,47 @@ import ariane_pkg::*;
module csr_regfile #(
parameter int ASID_WIDTH = 1
)(
input logic clk_i, // Clock
input logic rtc_i, // Real Time clock in
input logic rst_ni, // Asynchronous reset active low
input logic clk_i, // Clock
input logic rtc_i, // Real Time clock in
input logic rst_ni, // Asynchronous reset active low
// send a flush request out if a CSR with a side effect has changed (e.g. written)
output logic flush_o,
// commit acknowledge
input logic commit_ack_i, // Commit acknowledged a instruction -> increase instret CSR
input logic commit_ack_i, // Commit acknowledged a instruction -> increase instret CSR
// Core and Cluster ID
input logic [3:0] core_id_i, // Core ID is considered static
input logic [5:0] cluster_id_i, // Cluster ID is considered static
input logic [63:0] boot_addr_i, // Address from which to start booting, mtvec is set to the same address
input logic [3:0] core_id_i, // Core ID is considered static
input logic [5:0] cluster_id_i, // Cluster ID is considered static
input logic [63:0] boot_addr_i, // Address from which to start booting, mtvec is set to the same address
// we are taking an exception
input exception ex_i, // We've got an exception from the commit stage, take its
input exception ex_i, // We've got an exception from the commit stage, take its
input fu_op csr_op_i, // Operation to perform on the CSR file
input logic [11:0] csr_addr_i, // Address of the register to read/write
input logic [63:0] csr_wdata_i, // Write data in
output logic [63:0] csr_rdata_o, // Read data out
input logic [63:0] pc_i, // PC of instruction accessing the CSR
output exception csr_exception_o, // attempts to access a CSR without appropriate privilege
// level or to write a read-only register also
// raises illegal instruction exceptions.
input fu_op csr_op_i, // Operation to perform on the CSR file
input logic [11:0] csr_addr_i, // Address of the register to read/write
input logic [63:0] csr_wdata_i, // Write data in
output logic [63:0] csr_rdata_o, // Read data out
input logic [63:0] pc_i, // PC of instruction accessing the CSR
output exception csr_exception_o, // attempts to access a CSR without appropriate privilege
// level or to write a read-only register also
// raises illegal instruction exceptions.
// Interrupts/Exceptions
output logic [63:0] epc_o, // Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly
output logic eret_o, // Return from exception, set the PC of epc_o
output logic [63:0] trap_vector_base_o, // Output base of exception vector, correct CSR is output (mtvec, stvec)
output priv_lvl_t priv_lvl_o, // Current privilege level the CPU is in
output logic [63:0] epc_o, // Output the exception PC to PC Gen, the correct CSR (mepc, sepc) is set accordingly
output logic eret_o, // Return from exception, set the PC of epc_o
output logic [63:0] trap_vector_base_o, // Output base of exception vector, correct CSR is output (mtvec, stvec)
output priv_lvl_t priv_lvl_o, // Current privilege level the CPU is in
// MMU
output logic enable_translation_o, // Enable VA translation
output priv_lvl_t ld_st_priv_lvl_o, // Privilege level at which load and stores should happen
output logic en_translation_o, // enable VA translation
output logic en_ld_st_translation_o, // enable VA translation for load and stores
output priv_lvl_t ld_st_priv_lvl_o, // Privilege level at which load and stores should happen
output logic sum_o,
output logic mxr_o,
// input logic flag_mprv_i,
output logic [43:0] satp_ppn_o,
output logic [ASID_WIDTH-1:0] asid_o,
// external interrupts
input logic [1:0] irq_i, // external interrupt in
input logic [1:0] irq_i, // external interrupt in
// Visualization Support
output logic tvm_o, // trap virtual memory
output logic tw_o, // timeout wait
output logic tsr_o // trap sret
output logic tvm_o, // trap virtual memory
output logic tw_o, // timeout wait
output logic tsr_o // trap sret
// Performance Counter
);
@ -76,13 +76,14 @@ module csr_regfile #(
logic read_access_exception, update_access_exception;
logic csr_we, csr_read;
logic [63:0] csr_wdata, csr_rdata;
priv_lvl_t trap_to_priv_lvl;
priv_lvl_t trap_to_priv_lvl;
// register for enabling load store address translation, this is critical, hence the register
logic en_ld_st_translation_n, en_ld_st_translation_q;
// ----------------------
// LD/ST Privilege Level
// ----------------------
assign ld_st_priv_lvl_o = (mstatus_q.mprv) ? mstatus_q.mpp : priv_lvl_o;
assign en_ld_st_translation_o = en_ld_st_translation_q;
// ----------------
// CSR Registers
// ----------------
@ -223,12 +224,13 @@ module csr_regfile #(
sscratch_n = sscratch_q;
stval_n = stval_q;
satp_n = satp_q;
en_ld_st_translation_n = en_ld_st_translation_q;
// check for correct access rights and that we are writing
if(csr_we) begin
case (csr_addr.address)
// sstatus is a subset of mstatus - mask it accordingly
CSR_SSTATUS: mstatus_n = csr_wdata & 64'h3fffe1fee;
CSR_SSTATUS: mstatus_n = csr_wdata & 64'h3fffe1fee;
// even machine mode interrupts can be visible and set-able to supervisor
// if the corresponding bit in mideleg is set
CSR_SIE: mie_n = csr_wdata & 64'hBBB & mideleg_q; // we only support supervisor and m-mode interrupts
@ -260,7 +262,7 @@ module csr_regfile #(
mstatus_n.fs = 2'b0;
mstatus_n.upie = 1'b0;
mstatus_n.uie = 1'b0;
// if the SIE was set also set the MIE as interrupts for
// if the SIE was set also set the MIE, as interrupts for
// higher privilege levels are always set, 1.10 p.20
if (csr_wdata[1])
mstatus_n.mie = 1'b1;
@ -270,13 +272,13 @@ module csr_regfile #(
mstatus_n.sie = 1'b0;
end
// machine exception delegation register
// 0 - 12 exceptions supported
// 0 - 15 exceptions supported
CSR_MEDELEG: medeleg_n = csr_wdata & 64'hF7FF;
// machine interrupt delegation register
// we do not support user interrupt delegation
CSR_MIDELEG: mideleg_n = csr_wdata & 64'hBBB;
// mask the register so that user interrupts can never be set
// mask the register so that unsupported interrupts can never be set
CSR_MIE: mie_n = csr_wdata & 64'hBBB; // we only support supervisor and m-mode interrupts
CSR_MIP: mip_n = csr_wdata & 64'h33; // only USIP, SSIP, UTIP, STIP are write-able
@ -287,7 +289,7 @@ module csr_regfile #(
CSR_MTVAL: mtval_n = csr_wdata;
default: update_access_exception = 1'b1;
endcase
// so we wrote something, TODO: this can be finer grained (e.g.: did it have side effects?)
// so we wrote something, TODO: this can be more fine grained (e.g.: did it have side effects?)
flush_o = 1'b1;
end
// ---------------------
@ -296,15 +298,15 @@ module csr_regfile #(
// Machine Mode External Interrupt Pending
mip_n[11] = mip_q[11] & irq_i[0];
// Supervisor Mode External Interrupt Pending
mip_n[9] = mip_q[9] & irq_i[0];
mip_n[9] = mip_q[9] & irq_i[1];
// -----------------------
// Manage Exception Stack
// -----------------------
// update exception CSRs
// we got an exception update cause, pc and stval register
// Exception is taken
trap_to_priv_lvl = PRIV_LVL_M;
// Exception is taken
if (ex_i.valid) begin
// do not flush, flush is reserved for CSR writes with side effects
flush_o = 1'b0;
@ -351,6 +353,15 @@ module csr_regfile #(
priv_lvl_n = trap_to_priv_lvl;
end
// ------------------------------
// MPRV - Modify Privilege Level
// ------------------------------
// Set the address translation at which the load and stores should occur
// we can use the previous values since changing the address translation will always involve a pipeline flush
if (mstatus_q.mprv && satp_q.mode == 4'h8 && (mstatus_q.mpp != PRIV_LVL_M))
en_ld_st_translation_n = 1'b1;
else // otherwise we go with the regular settings
en_ld_st_translation_n = en_translation_o;
// -----------------------
// Return from Exception
// -----------------------
@ -511,18 +522,18 @@ module csr_regfile #(
// -------------------
// Output Assignments
// -------------------
assign csr_rdata_o = csr_rdata;
assign priv_lvl_o = priv_lvl_q;
assign csr_rdata_o = csr_rdata;
assign priv_lvl_o = priv_lvl_q;
// MMU outputs
assign satp_ppn_o = satp_q.ppn;
assign asid_o = satp_q.asid[ASID_WIDTH-1:0];
assign sum_o = mstatus_q.sum;
assign satp_ppn_o = satp_q.ppn;
assign asid_o = satp_q.asid[ASID_WIDTH-1:0];
assign sum_o = mstatus_q.sum;
// we support bare memory addressing and SV39
assign enable_translation_o = (satp_q.mode == 4'h8 && priv_lvl_q != PRIV_LVL_M) ? 1'b1 : 1'b0;
assign mxr_o = mstatus_q.mxr;
assign tvm_o = mstatus_q.tvm;
assign tw_o = mstatus_q.tw;
assign tsr_o = mstatus_q.tsr;
assign en_translation_o = (satp_q.mode == 4'h8 && priv_lvl_q != PRIV_LVL_M) ? 1'b1 : 1'b0;
assign mxr_o = mstatus_q.mxr;
assign tvm_o = mstatus_q.tvm;
assign tw_o = mstatus_q.tw;
assign tsr_o = mstatus_q.tsr;
// output assignments dependent on privilege mode
always_comb begin : priv_output
@ -570,6 +581,8 @@ module csr_regfile #(
// timer and counters
cycle_q <= 64'b0;
instret_q <= 64'b0;
// aux registers
en_ld_st_translation_q <= 1'b0;
end else begin
priv_lvl_q <= priv_lvl_n;
// machine mode registers
@ -593,6 +606,8 @@ module csr_regfile #(
// timer and counters
cycle_q <= cycle_n;
instret_q <= instret_n;
// aux registers
en_ld_st_translation_q <= en_ld_st_translation_n;
end
end

View file

@ -73,6 +73,7 @@ module ex_stage #(
input logic csr_commit_i,
// memory management
input logic enable_translation_i,
input logic en_ld_st_translation_i,
input logic flush_tlb_i,
input logic fetch_req_i,
output logic fetch_gnt_o,

View file

@ -40,7 +40,7 @@ module lsu #(
input logic commit_i, // commit the pending store
input logic enable_translation_i, // enable virtual memory translation
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
input logic fetch_req_i, // Instruction fetch interface
output logic fetch_gnt_o, // Instruction fetch interface
output logic fetch_valid_o, // Instruction fetch interface

View file

@ -27,10 +27,12 @@ module mmu #(
parameter int ASID_WIDTH = 1
)
(
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic enable_translation_i,
input logic clk_i,
input logic rst_ni,
input logic flush_i,
input logic enable_translation_i,
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
// IF interface
input logic fetch_req_i,
output logic fetch_gnt_o,
@ -273,7 +275,7 @@ module mmu #(
daccess_err = (ld_st_priv_lvl_i == PRIV_LVL_S && !sum_i && dtlb_content.u) || // SUM is not set and we are trying to access a user page in supervisor mode
(ld_st_priv_lvl_i == PRIV_LVL_U && !dtlb_content.u); // this is not a user page but we are in user mode and trying to access it
// translation is enabled and no misaligned exception occurred
if (enable_translation_i && !misaligned_ex_i.valid) begin
if (en_ld_st_translation_i && !misaligned_ex_i.valid) begin
lsu_valid_o = 1'b0;
// 4K page
lsu_paddr_o = {dtlb_content.ppn, lsu_vaddr_i[11:0]};
@ -296,6 +298,10 @@ module mmu #(
if (!dtlb_content.w || daccess_err) begin
lsu_exception_o = {ST_ACCESS_FAULT, lsu_vaddr_i, 1'b1};
end
// check if the dirty flag is set
if (!dtlb_content.d) begin
lsu_exception_o = {STORE_PAGE_FAULT, lsu_vaddr_i, 1'b1};
end
// this is a load, check for sufficient access privileges
end else if (daccess_err) begin
lsu_exception_o = {LD_ACCESS_FAULT, lsu_vaddr_i, 1'b1};
@ -304,7 +310,7 @@ module mmu #(
// ---------
// DTLB Miss
// ---------
// watch out for exception
// watch out for exceptions
if (ptw_active && !walking_instr) begin
// page table walker threw an exception
if (ptw_error) begin

View file

@ -24,16 +24,18 @@ module ptw #(
parameter int ASID_WIDTH = 1
)
(
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic flush_i, // flush everything, we need to do this because
// actually everything we do is speculative at this stage
// e.g.: there could be a CSR instruction that changes everything
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic flush_i, // flush everything, we need to do this because
// actually everything we do is speculative at this stage
// e.g.: there could be a CSR instruction that changes everything
output logic ptw_active_o,
output logic walking_instr_o, // set when walking for TLB
output logic ptw_error_o, // set when an error occurred
input logic enable_translation_i, // CSRs indicate to enable SV39
input logic lsu_is_store_i, // this translation was triggered by a store
output logic walking_instr_o, // set when walking for TLB
output logic ptw_error_o, // set when an error occurred
input logic enable_translation_i, // CSRs indicate to enable SV39
input logic en_ld_st_translation_i, // enable virtual memory translation for load/stores
input logic lsu_is_store_i, // this translation was triggered by a store
// PTW Memory Port
output logic [11:0] address_index_o,
output logic [43:0] address_tag_o,
@ -177,7 +179,7 @@ module ptw #(
vaddr_n = itlb_vaddr_i;
NS = WAIT_GRANT;
// we got an DTLB miss
end else if (enable_translation_i & dtlb_access_i & dtlb_miss_i) begin
end else if (en_ld_st_translation_i & dtlb_access_i & dtlb_miss_i) begin
ptw_pptr_n = {satp_ppn_i, dtlb_vaddr_i[38:30], 3'b0};
tlb_update_asid_n = asid_i;
vaddr_n = dtlb_vaddr_i;
@ -253,6 +255,18 @@ module ptw #(
NS = PROPAGATE_ERROR;
end
end
// check if the ppn is correctly aligned:
// 6. If i > 0 and pa.ppn[i 1 : 0] != 0, this is a misaligned superpage; stop and raise a page-fault
// exception.
if (ptw_lvl_q == LVL1 && pte.ppn[17:0] != '0) begin
NS = PROPAGATE_ERROR;
dtlb_update_o = 1'b0;
itlb_update_o = 1'b0;
end else if (ptw_lvl_q == LVL2 && pte.ppn[8:0] != '0) begin
NS = PROPAGATE_ERROR;
dtlb_update_o = 1'b0;
itlb_update_o = 1'b0;
end
// this is a pointer to the next TLB level
end else begin
// pointer to next level of page table

View file

@ -180,4 +180,8 @@ class instruction_tracer;
$fwrite(this.f, {print_ex, "\n"});
endfunction
function void close();
$fclose(this.f);
endfunction
endclass : instruction_tracer