diff --git a/errata.md b/errata.md new file mode 100644 index 000000000..35236eab5 --- /dev/null +++ b/errata.md @@ -0,0 +1,11 @@ +# Textbook Errata + +This document contains errata for [RISC-V System-on-Chip Design](https://www.amazon.com/RISC-V-Microprocessor-System-Chip-Design/dp/0323994989) published by Elsevier. + +Please contribute by making a pull request to modify this document on GitHub. Sort the errata by page number. Keep the correction as succinct as possible. + +Sample Errata + +| Page | Location | Error | Correction | Contributor | +| ---- | -------- | ----- | ----------- | ----------- | +| 42 | Fig 1.42 | foobar | FooBar | Ben Bitdiddle, Claremont, CA | \ No newline at end of file diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index 0689cef10..114f3a029 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -31,7 +31,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, input logic StallW, FlushW, - input logic [31:15] InstrM, // privileged instruction function field + input logic [31:7 ] InstrM, // privileged instruction function field input logic PrivilegedM, // is this a privileged instruction (from IEU controller) input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction input logic IllegalCSRAccessM, // Not a legal CSR access @@ -43,26 +43,31 @@ module privdec import cvw::*; #(parameter cvw_t P) ( output logic wfiM, wfiW, sfencevmaM // wfi / sfence.vma / sinval.vma instructions ); - logic rs1zeroM; // rs1 field = 0 + logic rs1zeroM, rdzeroM; // rs1 / rd field = 0 logic IllegalPrivilegedInstrM; // privileged instruction isn't a legal one or in legal mode logic WFITimeoutM; // WFI reaches timeout threshold logic ebreakM, ecallM; // ebreak / ecall instructions logic sinvalvmaM; // sinval.vma + logic presfencevmaM; // sfence.vma before checking privilege mode logic sfencewinvalM, sfenceinvalirM; // sfence.w.inval, sfence.inval.ir - logic invalM; // any of the svinval instructions + logic vmaM; // sfence.vma or sinval.vma + logic fenceinvalM; // sfence.w.inval or sfence.inval.ir /////////////////////////////////////////// // Decode privileged instructions /////////////////////////////////////////// assign rs1zeroM = InstrM[19:15] == 5'b0; + assign rdzeroM = InstrM[11:7] == 5'b0; // svinval instructions // any svinval instruction is treated as sfence.vma on Wally - assign sinvalvmaM = (InstrM[31:25] == 7'b0001011); - assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM; - assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM; - assign invalM = P.SVINVAL_SUPPORTED & (sinvalvmaM | sfencewinvalM | sfenceinvalirM); + assign sinvalvmaM = (InstrM[31:25] == 7'b0001011) & rdzeroM; + assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM & rdzeroM; + assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM & rdzeroM; + assign presfencevmaM = (InstrM[31:25] == 7'b0001001) & rdzeroM; + assign vmaM = presfencevmaM | (sinvalvmaM & P.SVINVAL_SUPPORTED); // sfence.vma or sinval.vma + assign fenceinvalM = (sfencewinvalM | sfenceinvalirM) & P.SVINVAL_SUPPORTED; // sfence.w.inval or sfence.inval.ir assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & rs1zeroM & P.S_SUPPORTED & (PrivilegeModeW == P.M_MODE | PrivilegeModeW == P.S_MODE & ~STATUS_TSR); @@ -71,8 +76,11 @@ module privdec import cvw::*; #(parameter cvw_t P) ( assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000) & rs1zeroM; assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001) & rs1zeroM; assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101) & rs1zeroM; - assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001 | invalM) & - (PrivilegeModeW == P.M_MODE | (PrivilegeModeW == P.S_MODE & ~STATUS_TVM)) & P.VIRTMEM_SUPPORTED; + + // all of sinval.vma, sfence.w.inval, sfence.inval.ir are treated as sfence.vma + assign sfencevmaM = PrivilegedM & P.VIRTMEM_SUPPORTED & + ((PrivilegeModeW == P.M_MODE & (vmaM | fenceinvalM)) | + (PrivilegeModeW == P.S_MODE & (vmaM & ~STATUS_TVM | fenceinvalM))); // sfence.w.inval & sfence.inval.ir not affected by TVM /////////////////////////////////////////// // WFI timeout Privileged Spec 3.1.6.5 diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 11968b93e..878e7e710 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -127,7 +127,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); // decode privileged instructions - privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:15]), + privdec #(P) pmd(.clk, .reset, .StallW, .FlushW, .InstrM(InstrM[31:7]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .RetM, .wfiM, .wfiW, .sfencevmaM);