Remove useless midcr.eivect feature. Make mlei left-shift its value by 2.

This commit is contained in:
Luke Wren 2021-12-04 01:17:57 +00:00
parent cd1b391714
commit 52ba930638
4 changed files with 4414 additions and 5534 deletions

File diff suppressed because it is too large Load Diff

View File

@ -175,8 +175,6 @@ Trap vector base address. Read-write. Exactly which bits of `mtvec` can be modif
NOTE: In the RISC-V specification, `mode` is a 2-bit write-any read-legal field in bits 1:0. Hazard3 implements this by hardwiring bit 1 to 0. NOTE: In the RISC-V specification, `mode` is a 2-bit write-any read-legal field in bits 1:0. Hazard3 implements this by hardwiring bit 1 to 0.
NOTE: Hazard3 has an additional nonstandard vectoring mode, where external interrupts are each separated into distinct vectors and `mcause` values. This is enabled through the implementation-defined control register, <<reg-midcr>>, since the RISC-V specification reserves `mtvec.mode == 2, 3` for future standard use.
==== mscratch ==== mscratch
Address: `0x340` Address: `0x340`
@ -211,8 +209,6 @@ The most significant bit of `mcause` is set to 1 to indicate an interrupt cause,
| 11 | External interrupt (`mip.meip`) | 11 | External interrupt (`mip.meip`)
|=== |===
Numbers >16 are used for to disambiguate between external IRQs when expanded vectoring is enabled -- see <<reg-midcr>>.
The following exception causes may be set by Hazard3 hardware: The following exception causes may be set by Hazard3 hardware:
[cols="10h,~", options="header"] [cols="10h,~", options="header"]
@ -413,20 +409,6 @@ The Debug Module uses this mapping to exchange data with the core by injecting `
This CSR address is given by the `dataaddress` field of the Debug Module's `hartinfo` register, and `hartinfo.dataaccess` is set to 0 to indicate this is a CSR mapping, not a memory mapping. This CSR address is given by the `dataaddress` field of the Debug Module's `hartinfo` register, and `hartinfo.dataaccess` is set to 0 to indicate this is a CSR mapping, not a memory mapping.
[[reg-midcr]]
==== midcr
Address: `0xbc0`
Implementation-defined control register. Miscellaneous nonstandard controls.
[cols="10h,20h,~", options="header"]
|===
| Bits | Name | Description
| 31:1 | - | RES0
| 0 | `eivect` | Modified external interrupt vectoring. If 0, use standard behaviour: all external interrupts set interrupt `mcause` of 11 and vector to `mtvec + 0x2c`. If 1, external interrupts use distinct interrupt `mcause` numbers 16 upward, and distinct vectors `mtvec + (irq + 16) * 4`. Resets to 0. Has no effect when `mtvec[0]` is 0.
|===
[[reg-meie0]] [[reg-meie0]]
==== meie0 ==== meie0
@ -464,24 +446,18 @@ When any bit is set in both `meip0` and `meie0`, the standard external interrupt
In this case, the processor jumps to either: In this case, the processor jumps to either:
* `mtvec` directly, if vectoring is disabled (`mtvec[0]` is 0) * `mtvec` directly, if vectoring is disabled (`mtvec[0]` is 0)
* `mtvec + 0x2c`, if vectoring is enabled (`mtvec[0]` is 1) and modified external IRQ vectoring is disabled (`midcr.eivect` is 0) * `mtvec + 0x2c`, if vectoring is enabled (`mtvec[0]` is 1)
* `mtvect + (mlei + 16) * 4`, if vectoring is enabled (`mtvec[0]` is 1) and modified external IRQ vectoring is enabled (`midcr.eivect` is 1). `
** `mlei` is a read-only CSR containing the lowest-numbered pending-and-enabled external interrupt.
==== mlei ==== mlei
Address: `0xfe4` Address: `0xfe4`
Lowest external interrupt. Contains the index of the lowest-numbered external interrupt which is both asserted in `meip0` and enabled in `meie0`. Can be used for faster software vectoring when modified external interrupt vectoring (`midcr.eivect = 1`) is not in use. Lowest external interrupt. Contains the index of the lowest-numbered external interrupt which is both asserted in `meip0` and enabled in `meie0`, left-shifted by 2 so that it can be used to index an array of 32-bit function pointers.
[cols="10h,20h,~", options="header"] [cols="10h,20h,~", options="header"]
|=== |===
| Bits | Name | Description | Bits | Name | Description
| 31:5 | - | RES0 | 31:7 | - | RES0
| 4:0 | - | Index of the lowest-numbered active external interrupt. A LSB-first priority encode of `meip0 & meie0`. Zero when no external interrupts are both pending and enabled. | 6:2 | - | Index of the lowest-numbered active external interrupt. A LSB-first priority encode of `meip0 & meie0`. Zero when no external interrupts are both pending and enabled.
| 1:0 | - | RES0
|=== |===
==== Maybe-adds
An option to clear a bit in `meie0` when that interrupt is taken, and set it when an `mret` has a matching `mcause` for that interrupt. Makes preemption support easier.

View File

@ -244,7 +244,6 @@ localparam MHPMEVENT30 = 12'h33e; // WARL (we tie to 0)
localparam MHPMEVENT31 = 12'h33f; // WARL (we tie to 0) localparam MHPMEVENT31 = 12'h33f; // WARL (we tie to 0)
// Custom M-mode CSRs: // Custom M-mode CSRs:
localparam MIDCR = 12'hbc0; // Implementation-defined control register (bag of bits)
localparam MEIE0 = 12'hbe0; // External interrupt enable register 0 localparam MEIE0 = 12'hbe0; // External interrupt enable register 0
localparam MEIP0 = 12'hfe0; // External interrupt pending register 0 localparam MEIP0 = 12'hfe0; // External interrupt pending register 0
localparam MLEI = 12'hfe4; // Lowest external interrupt number localparam MLEI = 12'hfe4; // Lowest external interrupt number
@ -300,25 +299,6 @@ always @ (posedge clk or negedge rst_n) begin
end end
end end
// ----------------------------------------------------------------------------
// Implementation-defined control register
localparam MIDCR_INIT = X0;
localparam MIDCR_WMASK = 32'h00000001;
reg [XLEN-1:0] midcr;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
midcr <= MIDCR_INIT;
end else if (wen && addr == MIDCR) begin
midcr <= update_nonconst(midcr, MIDCR_WMASK);
end
end
// Modified external interrupt vectoring
wire midcr_eivect = midcr[0];
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Trap-handling CSRs // Trap-handling CSRs
@ -872,11 +852,6 @@ always @ (*) begin
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Custom CSRs // Custom CSRs
MIDCR: if (CSR_M_TRAP) begin
decode_match = 1'b1;
rdata = midcr;
end
MEIE0: if (CSR_M_TRAP) begin MEIE0: if (CSR_M_TRAP) begin
decode_match = 1'b1; decode_match = 1'b1;
rdata = meie0; rdata = meie0;
@ -889,7 +864,7 @@ always @ (*) begin
MLEI: if (CSR_M_TRAP) begin MLEI: if (CSR_M_TRAP) begin
decode_match = !wen_soon; decode_match = !wen_soon;
rdata = {{XLEN-5{1'b0}}, mlei}; rdata = {{XLEN-7{1'b0}}, mlei, 2'b00};
end end
default: begin end default: begin end
@ -1023,11 +998,7 @@ assign mip = {
3'h0 // Reserved 3'h0 // Reserved
}; };
// When eivect = 1, mip.meip is masked from the standard IRQs, so that the wire irq_active = |(mip & mie) && mstatus_mie && !dcsr_step;
// platform-specific causes and vectors are used instead.
wire [31:0] mip_no_global = mip & ~(32'h800 & ~{XLEN{midcr_eivect}});
wire standard_irq_active = |(mip_no_global & mie) && mstatus_mie && !dcsr_step;
wire external_irq_active = external_irq_pending && mstatus_mie && !dcsr_step && mie_meie;
// WFI clear respects individual interrupt enables but ignores mstatus.mie. // WFI clear respects individual interrupt enables but ignores mstatus.mie.
// Additionally, wfi is treated as a nop during single-stepping and D-mode. // Additionally, wfi is treated as a nop during single-stepping and D-mode.
@ -1047,7 +1018,7 @@ hazard3_priority_encode #(
hazard3_priority_encode #( hazard3_priority_encode #(
.W_REQ (16) .W_REQ (16)
) irq_priority ( ) irq_priority (
.req (mip_no_global[15:0] & mie[15:0]), .req (mip[15:0] & mie[15:0]),
.gnt (standard_irq_num) .gnt (standard_irq_num)
); );
@ -1055,15 +1026,9 @@ hazard3_priority_encode #(
// depending on dcsr.ebreakm. // depending on dcsr.ebreakm.
assign exception_req_any = except != EXCEPT_NONE && !(except == EXCEPT_EBREAK && dcsr_ebreakm); assign exception_req_any = except != EXCEPT_NONE && !(except == EXCEPT_EBREAK && dcsr_ebreakm);
// Note when eivect=0 platform external interrupts also count as a standard wire [5:0] mcause_irq_num = irq_active ? {2'h0, standard_irq_num} : 6'd0;
// external interrupt, so the standard mapping (collapsed into a single
// vector) always takes priority.
wire [5:0] mcause_irq_num =
standard_irq_active ? {2'h0, standard_irq_num} :
external_irq_active ? {1'h0, external_irq_num} + 6'd16 : 6'd0;
wire [5:0] vector_sel = wire [5:0] vector_sel = !exception_req_any && irq_vector_enable ? mcause_irq_num : 6'd0;
!exception_req_any && irq_vector_enable ? mcause_irq_num : 6'd0;
assign trap_addr = assign trap_addr =
except == EXCEPT_MRET ? mepc : except == EXCEPT_MRET ? mepc :
@ -1077,7 +1042,7 @@ assign trap_is_irq = DEBUG_SUPPORT && (want_halt_except || want_halt_irq) ?
// delay_irq_entry also applies to IRQ-like debug entries. // delay_irq_entry also applies to IRQ-like debug entries.
assign trap_enter_vld = assign trap_enter_vld =
CSR_M_TRAP && (exception_req_any || CSR_M_TRAP && (exception_req_any ||
!delay_irq_entry && !debug_mode && (standard_irq_active || external_irq_active)) || !delay_irq_entry && !debug_mode && irq_active) ||
DEBUG_SUPPORT && ( DEBUG_SUPPORT && (
(!delay_irq_entry && want_halt_irq) || want_halt_except || pending_dbg_resume); (!delay_irq_entry && want_halt_irq) || want_halt_except || pending_dbg_resume);

View File

@ -8,7 +8,7 @@ cd embench-iot
# Make sure testbench is up to date # Make sure testbench is up to date
make -C ../../tb_cxxrtl tb make -C ../../tb_cxxrtl tb
./build_all.py --arch riscv32 --chip hazard3 --board hazard3tb ./build_all.py --arch riscv32 --chip hazard3 --board hazard3tb
./benchmark_speed --target-module run_hazard3tb ./benchmark_speed.py --target-module run_hazard3tb
``` ```
The compiler specified in `config/riscv32/chips/hazard3/chip.cfg` is `/opt/riscv/unstable/bin/riscv32-unknown-elf-gcc`, which is where I have an unstable GCC 12 build installed on my machine. You need to have a recent upstream master build to support the Zba/Zbb/Zbc/Zbs instructions. If you don't care about these, you can use whatever `riscv32-unknown-elf` compiler you have, and also edit `cflags` in that `.cfg` file to not include the bitmanip extensions in `march`. The compiler specified in `config/riscv32/chips/hazard3/chip.cfg` is `/opt/riscv/unstable/bin/riscv32-unknown-elf-gcc`, which is where I have an unstable GCC 12 build installed on my machine. You need to have a recent upstream master build to support the Zba/Zbb/Zbc/Zbs instructions. If you don't care about these, you can use whatever `riscv32-unknown-elf` compiler you have, and also edit `cflags` in that `.cfg` file to not include the bitmanip extensions in `march`.