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: 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
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`)
|===
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:
[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.
[[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]]
==== 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:
* `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)
* `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.
* `mtvec + 0x2c`, if vectoring is enabled (`mtvec[0]` is 1)
==== mlei
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"]
|===
| Bits | Name | Description
| 31:5 | - | 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.
| 31:7 | - | RES0
| 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)
// 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 MEIP0 = 12'hfe0; // External interrupt pending register 0
localparam MLEI = 12'hfe4; // Lowest external interrupt number
@ -300,25 +299,6 @@ always @ (posedge clk or negedge rst_n) begin
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
@ -872,11 +852,6 @@ always @ (*) begin
// ------------------------------------------------------------------------
// Custom CSRs
MIDCR: if (CSR_M_TRAP) begin
decode_match = 1'b1;
rdata = midcr;
end
MEIE0: if (CSR_M_TRAP) begin
decode_match = 1'b1;
rdata = meie0;
@ -889,7 +864,7 @@ always @ (*) begin
MLEI: if (CSR_M_TRAP) begin
decode_match = !wen_soon;
rdata = {{XLEN-5{1'b0}}, mlei};
rdata = {{XLEN-7{1'b0}}, mlei, 2'b00};
end
default: begin end
@ -1023,11 +998,7 @@ assign mip = {
3'h0 // Reserved
};
// When eivect = 1, mip.meip is masked from the standard IRQs, so that the
// 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;
wire irq_active = |(mip & mie) && mstatus_mie && !dcsr_step;
// WFI clear respects individual interrupt enables but ignores mstatus.mie.
// Additionally, wfi is treated as a nop during single-stepping and D-mode.
@ -1047,7 +1018,7 @@ hazard3_priority_encode #(
hazard3_priority_encode #(
.W_REQ (16)
) irq_priority (
.req (mip_no_global[15:0] & mie[15:0]),
.req (mip[15:0] & mie[15:0]),
.gnt (standard_irq_num)
);
@ -1055,15 +1026,9 @@ hazard3_priority_encode #(
// depending on 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
// 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] mcause_irq_num = irq_active ? {2'h0, standard_irq_num} : 6'd0;
wire [5:0] vector_sel =
!exception_req_any && irq_vector_enable ? mcause_irq_num : 6'd0;
wire [5:0] vector_sel = !exception_req_any && irq_vector_enable ? mcause_irq_num : 6'd0;
assign trap_addr =
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.
assign trap_enter_vld =
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 && (
(!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 -C ../../tb_cxxrtl tb
./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`.