From b4d6021b3bfaac835692cbcfd231db7cb4a070ea Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Sun, 26 Mar 2023 19:39:49 -0700 Subject: [PATCH 01/56] removed unneccesary input signal from zbb --- src/ieu/bmu/bitmanipalu.sv | 2 +- src/ieu/bmu/zbb.sv | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 07c7e5343..4841f7dd1 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -84,7 +84,7 @@ module bitmanipalu #(parameter WIDTH=32) ( // ZBB Unit if (`ZBB_SUPPORTED) begin: zbb - zbb #(WIDTH) ZBB(.A, .RevA, .B, .ALUResult, .W64, .lt(CompFlags[0]), .ZBBSelect, .ZBBResult); + zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .lt(CompFlags[0]), .ZBBSelect, .ZBBResult); end else assign ZBBResult = 0; // Result Select Mux diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv index 5d1c52f1d..1dff2fd0a 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -32,7 +32,6 @@ module zbb #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, RevA, B, // Operands - input logic [WIDTH-1:0] ALUResult, // ALU Result input logic W64, // Indicates word operation input logic lt, // lt flag input logic [2:0] ZBBSelect, // Indicates word operation From f3edbcea150234e7402530b9616dec7df2a5b8a9 Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Sun, 26 Mar 2023 20:06:55 -0700 Subject: [PATCH 02/56] removed unnecessary signal indices --- src/ieu/bmu/cnt.sv | 2 +- src/ieu/bmu/zbb.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ieu/bmu/cnt.sv b/src/ieu/bmu/cnt.sv index 13ff1e15f..75ace3ac7 100644 --- a/src/ieu/bmu/cnt.sv +++ b/src/ieu/bmu/cnt.sv @@ -32,7 +32,7 @@ module cnt #(parameter WIDTH = 32) ( input logic [WIDTH-1:0] A, RevA, // Operands - input logic [4:0] B, // Last 5 bits of immediate + input logic [1:0] B, // Last 2 bits of immediate input logic W64, // Indicates word operation output logic [WIDTH-1:0] CntResult // count result ); diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv index 1dff2fd0a..fef8579b5 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -42,7 +42,7 @@ module zbb #(parameter WIDTH=32) ( logic [WIDTH-1:0] ByteResult; // byte results logic [WIDTH-1:0] ExtResult; // sign/zero extend results - cnt #(WIDTH) cnt(.A, .RevA, .B(B[4:0]), .W64, .CntResult); + cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult); byteUnit #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult); ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult); From fd2d08f50187e61f12624353cdcc797c25d4ec8e Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 10:21:33 -0700 Subject: [PATCH 03/56] Fixed fmv decoder --- src/fpu/fctrl.sv | 67 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index be10e8007..8428b8c75 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -75,16 +75,19 @@ module fctrl ( logic [1:0] FResSelD; // Select one of the results that finish in the memory stage logic [2:0] FrmD, FrmE; // FP rounding mode logic [`FMTBITS-1:0] FmtD; // FP format - logic [1:0] Fmt; // format - before possible reduction + logic [1:0] Fmt, Fmt2; // format - before possible reduction logic SupportedFmt; // is the format supported + logic SupportedFmt2; // is the source format supported for fp -> fp logic FCvtIntD, FCvtIntM; // convert to integer opperation // FPU Instruction Decoder assign Fmt = Funct7D[1:0]; + assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp - // Note: only Fmt is checked; fcvt does not check destination format assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & `D_SUPPORTED) | (Fmt == 2'b10 & `ZFH_SUPPORTED) | (Fmt == 2'b11 & `Q_SUPPORTED)); + assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & `D_SUPPORTED) | + (Fmt2 == 2'b10 & `ZFH_SUPPORTED) | (Fmt2 == 2'b11 & `Q_SUPPORTED)); // decode the instruction always_comb @@ -142,38 +145,42 @@ module fctrl ( default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction endcase 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass - else if (Funct3D[1:0] == 2'b00) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w to int reg - else if (Funct3D[1:0] == 2'b01) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.d to int reg - else ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction - 7'b1101000: case(Rs2D[1:0]) - 2'b00: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s - 2'b01: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s - 2'b10: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s - 2'b11: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s + ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass + else if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register + 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg + 7'b0100000: if (Rs2D[4:2] == 3'b000) + ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d + 7'b0100001: if (Rs2D[4:2] == 3'b000) + ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s + // *** other formats here + /* verilator lint_off CASEINCOMPLETE */ + 7'b1101000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s endcase - 7'b1100000: case(Rs2D[1:0]) - 2'b00: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w - 2'b01: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu - 2'b10: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l - 2'b11: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu + 7'b1100000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu endcase - 7'b1111000: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x to fp reg - 7'b0100000: ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d - 7'b1101001: case(Rs2D[1:0]) - 2'b00: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d - 2'b01: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d - 2'b10: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d - 2'b11: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d + 7'b1101001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d endcase - 7'b1100001: case(Rs2D[1:0]) - 2'b00: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w - 2'b01: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu - 2'b10: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l - 2'b11: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu + 7'b1100001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase - 7'b1111001: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.d.x to fp reg - 7'b0100001: ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s + /* verilator lint_off CASEINCOMPLETE */ default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction From e5955c5dd8d36cf98a6ea7345699e691fced6621 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 10:28:01 -0700 Subject: [PATCH 04/56] support more fp -> fp conversions --- src/fpu/fctrl.sv | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 8428b8c75..5e7dd1aed 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -150,10 +150,14 @@ module fctrl ( ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg - 7'b0100000: if (Rs2D[4:2] == 3'b000) - ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d - 7'b0100001: if (Rs2D[4:2] == 3'b000) - ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s + 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) + ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) + 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) + ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) + ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.h.(s/d//h) + 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) + ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.q.(s/h/d) // *** other formats here /* verilator lint_off CASEINCOMPLETE */ 7'b1101000: case(Rs2D) From 40311c4f62b96edee2a9559911b8b7a3a7b0b435 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 10:35:41 -0700 Subject: [PATCH 05/56] fixed fp->fp conversions --- src/fpu/fctrl.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 5e7dd1aed..5a52b0484 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -155,9 +155,9 @@ module fctrl ( 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) - ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.h.(s/d//h) + ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) - ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.q.(s/h/d) + ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) // *** other formats here /* verilator lint_off CASEINCOMPLETE */ 7'b1101000: case(Rs2D) From f0cab709f28c4adbccaaf55f806f9defd9833d44 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 10:53:06 -0700 Subject: [PATCH 06/56] Added support (untested) for half and quad conversions --- src/fpu/fctrl.sv | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 5a52b0484..a3e93ad7a 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -184,6 +184,31 @@ module fctrl ( 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase + 7'b1101010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h + endcase + 7'b1100010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu + endcase + 7'b1101011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q + endcase + 7'b1100011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu + endcase + /* verilator lint_off CASEINCOMPLETE */ default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase From adabb7c2363cfbd84c6a1808c7c3a2f9bcd3dc4a Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Tue, 28 Mar 2023 11:40:19 -0700 Subject: [PATCH 07/56] comment formatting --- src/ieu/bmu/zbb.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv index fef8579b5..a85114b55 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -34,11 +34,11 @@ module zbb #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, RevA, B, // Operands input logic W64, // Indicates word operation input logic lt, // lt flag - input logic [2:0] ZBBSelect, // Indicates word operation + input logic [2:0] ZBBSelect, // ZBB Result select signal output logic [WIDTH-1:0] ZBBResult); // ZBB result logic [WIDTH-1:0] CntResult; // count result - logic [WIDTH-1:0] MinMaxResult; // min,max result + logic [WIDTH-1:0] MinMaxResult; // min, max result logic [WIDTH-1:0] ByteResult; // byte results logic [WIDTH-1:0] ExtResult; // sign/zero extend results From 69f6b291c6385fa6d4a2b39b4a26f662881e04d2 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Mar 2023 14:47:08 -0500 Subject: [PATCH 08/56] Possible fix for issue 148. I found the problem. We use a Committed(F/M) signal to indicate the IFU or LSU has an ongoing cache or bus transaction and should not be interrupted. At the time of the mret, the IFU is fetching uncacheable invalid instructions asserting CommittedF. As the IFU finishes the request it unstalls the pipeline but continues to assert CommittedF. (This is not necessary for the IFU). In the same cycle the LSU d cache misses. Because CommittedF is blocking the interrupt the d cache submits a cache line fetch to the EBU. I am thinking out loud here. At it's core the Committed(F/M) ensure memory operations are atomic and caches don't get into inconsistent states. Once the memory operation is completed the LSU/IFU removes the stall but continues to hold Committed(F/M) because the memory operation has completed and it would be wrong to allow an interrupt to occur with a completed load/store. However this is not true of the IFU. If we lower CommittedF once the operation is complete then this problem is solved. The interrupt won't be masked and the LSU will flush the d cache miss. This requires a minor change in the cachebusfsm and cachefsm. I will report back after I've confirmed this works. --- src/cache/cachefsm.sv | 2 +- src/ebu/ahbcacheinterface.sv | 5 +++-- src/ebu/buscachefsm.sv | 5 +++-- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index c51257be7..cd1d43c55 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -135,7 +135,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) ( end // com back to CPU - assign CacheCommitted = CurrState != STATE_READY; + assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & CurrState == STATE_READ_HOLD); assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) | (CurrState == STATE_FETCH) | (CurrState == STATE_WRITEBACK) | diff --git a/src/ebu/ahbcacheinterface.sv b/src/ebu/ahbcacheinterface.sv index b30a15096..e2e7d3696 100644 --- a/src/ebu/ahbcacheinterface.sv +++ b/src/ebu/ahbcacheinterface.sv @@ -33,7 +33,8 @@ module ahbcacheinterface #( parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline parameter AHBWLOGBWPL, // Log2 of ^ parameter LINELEN, // Number of bits in cacheline - parameter LLENPOVERAHBW // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) + parameter LLENPOVERAHBW, // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) + parameter READ_ONLY_CACHE )( input logic HCLK, HRESETn, // bus interface controls @@ -115,7 +116,7 @@ module ahbcacheinterface #( flopen #(`AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[`AHBW/8-1:0], HWSTRB); - buscachefsm #(BeatCountThreshold, AHBWLOGBWPL) AHBBuscachefsm( + buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm( .HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat, .CacheBusRW, .CacheBusAck, .BeatCount, .BeatCountDelayed, .HREADY, .HTRANS, .HWRITE, .HBURST); diff --git a/src/ebu/buscachefsm.sv b/src/ebu/buscachefsm.sv index c619c9135..e0efcf3a3 100644 --- a/src/ebu/buscachefsm.sv +++ b/src/ebu/buscachefsm.sv @@ -33,7 +33,8 @@ // HCLK and clk must be the same clock! module buscachefsm #( parameter BeatCountThreshold, // Largest beat index - parameter AHBWLOGBWPL // Log2 of BEATSPERLINE + parameter AHBWLOGBWPL, // Log2 of BEATSPERLINE + parameter READ_ONLY_CACHE )( input logic HCLK, input logic HRESETn, @@ -121,7 +122,7 @@ module buscachefsm #( (CurrState == DATA_PHASE) | (CurrState == CACHE_FETCH & ~HREADY) | (CurrState == CACHE_WRITEBACK & ~HREADY); - assign BusCommitted = CurrState != ADR_PHASE; + assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY_CACHE & CurrState == MEM3); // AHB bus interface assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW)) & ~Flush) | diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 2a411a737..c1556daeb 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -251,7 +251,7 @@ module ifu ( .NextSet(PCSpillNextF[11:0]), .PAdr(PCPF), .CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM)); - ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW) + ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1) ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), .HRDATA, .Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index e3adc00f5..0b0bc81e3 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -275,7 +275,7 @@ module lsu ( .FetchBuffer, .CacheBusRW, .CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0)); - ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW)) ahbcacheinterface( + ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface( .HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB), .HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY), From 7cc8d4f20cf670561b0422ad5316a6d580e33d0c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Mar 2023 16:09:54 -0500 Subject: [PATCH 09/56] Now have logging of i/d cache addresses, but the performance counter reports are x's. --- testbench/testbench.sv | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index f07cfef12..0afb4310b 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -474,7 +474,7 @@ logic [3:0] dummy; // default start condiction is reset // default end condiction is end of test (DCacheFlushDone) assign StartSampleFirst = InReset; - flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + flop #(1) StartSampleReg(clk, StartSampleFirst, StartSampleDelayed); assign StartSample = StartSampleFirst & ~ StartSampleDelayed; assign EndSample = DCacheFlushStart & ~DCacheFlushDone; @@ -555,16 +555,19 @@ end int file; string LogFile; logic resetD, resetEdge; + logic Enable; + assign Enable = ~dut.core.StallD & ~dut.core.FlushD & dut.core.ifu.bus.icache.CacheRWF[1] & ~reset; flop #(1) ResetDReg(clk, reset, resetD); assign resetEdge = ~reset & resetD; initial begin LogFile = $psprintf("ICache.log"); file = $fopen(LogFile, "w"); + $fwrite(file, "BEGIN %s\n", memfilename); end always @(posedge clk) begin if(resetEdge) $fwrite(file, "TRAIN\n"); if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); - if(~dut.core.StallD & ~dut.core.FlushD) begin + if(Enable) begin // only log i cache reads $fwrite(file, "%h R\n", dut.core.ifu.PCPF); end if(EndSample) $fwrite(file, "END %s\n", memfilename); @@ -580,6 +583,7 @@ end initial begin LogFile = $psprintf("DCache.log"); file = $fopen(LogFile, "w"); + $fwrite(file, "BEGIN %s\n", memfilename); end always @(posedge clk) begin if(resetEdge) $fwrite(file, "TRAIN\n"); From a48049f6fe9832f297fa28f4e3769c054097c4e0 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Mar 2023 16:15:05 -0500 Subject: [PATCH 10/56] Restored performance counter reports. --- testbench/testbench.sv | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 0afb4310b..1af6f2b13 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -169,7 +169,8 @@ logic [3:0] dummy; logic InitializingMemories; integer ResetCount, ResetThreshold; logic InReset; - + logic Begin; + // instantiate device to be tested assign GPIOIN = 0; assign UARTSin = 1; @@ -417,7 +418,7 @@ logic [3:0] dummy; if(`PrintHPMCounters & `ZICOUNTERS_SUPPORTED) begin : HPMCSample integer HPMCindex; logic StartSampleFirst; - logic StartSampleDelayed; + logic StartSampleDelayed, BeginDelayed; logic EndSampleFirst, EndSampleDelayed; logic [`XLEN-1:0] InitialHPMCOUNTERH[`COUNTERS-1:0]; @@ -474,10 +475,13 @@ logic [3:0] dummy; // default start condiction is reset // default end condiction is end of test (DCacheFlushDone) assign StartSampleFirst = InReset; - flop #(1) StartSampleReg(clk, StartSampleFirst, StartSampleDelayed); + flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); assign StartSample = StartSampleFirst & ~ StartSampleDelayed; - assign EndSample = DCacheFlushStart & ~DCacheFlushDone; + + flop #(1) BeginReg(clk, StartSampleFirst, BeginDelayed); + assign Begin = StartSampleFirst & ~ BeginDelayed; + end always @(negedge clk) begin @@ -566,7 +570,7 @@ end end always @(posedge clk) begin if(resetEdge) $fwrite(file, "TRAIN\n"); - if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); + if(Begin) $fwrite(file, "BEGIN %s\n", memfilename); if(Enable) begin // only log i cache reads $fwrite(file, "%h R\n", dut.core.ifu.PCPF); end @@ -587,7 +591,7 @@ end end always @(posedge clk) begin if(resetEdge) $fwrite(file, "TRAIN\n"); - if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); + if(Begin) $fwrite(file, "BEGIN %s\n", memfilename); if(~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin if(dut.core.lsu.bus.dcache.CacheRWM == 2'b10) begin $fwrite(file, "%h R\n", dut.core.lsu.PAdrM); From cef75cfe06caaf63878698d6c5168c07745c0c45 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Mar 2023 16:20:14 -0500 Subject: [PATCH 11/56] Now reports if there is a hit or miss. --- testbench/testbench.sv | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 1af6f2b13..aa11d377c 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -568,11 +568,13 @@ end file = $fopen(LogFile, "w"); $fwrite(file, "BEGIN %s\n", memfilename); end + string HitMissString; + assign HitMissString = dut.core.ifu.bus.icache.icache.CacheHit ? "H" : "M"; always @(posedge clk) begin if(resetEdge) $fwrite(file, "TRAIN\n"); if(Begin) $fwrite(file, "BEGIN %s\n", memfilename); if(Enable) begin // only log i cache reads - $fwrite(file, "%h R\n", dut.core.ifu.PCPF); + $fwrite(file, "%h R %s\n", dut.core.ifu.PCPF, HitMissString); end if(EndSample) $fwrite(file, "END %s\n", memfilename); end @@ -582,8 +584,10 @@ end int file; string LogFile; logic resetD, resetEdge; + string HitMissString; flop #(1) ResetDReg(clk, reset, resetD); assign resetEdge = ~reset & resetD; + assign HitMissString = dut.core.lsu.bus.dcache.dcache.CacheHit ? "H" : "M"; initial begin LogFile = $psprintf("DCache.log"); file = $fopen(LogFile, "w"); @@ -594,13 +598,13 @@ end if(Begin) $fwrite(file, "BEGIN %s\n", memfilename); if(~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin if(dut.core.lsu.bus.dcache.CacheRWM == 2'b10) begin - $fwrite(file, "%h R\n", dut.core.lsu.PAdrM); + $fwrite(file, "%h R %s\n", dut.core.lsu.PAdrM, HitMissString); end else if (dut.core.lsu.bus.dcache.CacheRWM == 2'b01) begin - $fwrite(file, "%h W\n", dut.core.lsu.PAdrM); + $fwrite(file, "%h W %s\n", dut.core.lsu.PAdrM, HitMissString); end else if (dut.core.lsu.bus.dcache.CacheAtomicM[1] == 1'b1) begin // *** This may change - $fwrite(file, "%h A\n", dut.core.lsu.PAdrM); + $fwrite(file, "%h A %s\n", dut.core.lsu.PAdrM, HitMissString); end else if (dut.core.lsu.bus.dcache.FlushDCache) begin - $fwrite(file, "%h F\n", dut.core.lsu.PAdrM); + $fwrite(file, "%h F %s\n", dut.core.lsu.PAdrM, HitMissString); end end if(EndSample) $fwrite(file, "END %s\n", memfilename); From 34dd2850e09d4fb04d52c9483532ecf1070326ee Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Mar 2023 16:20:45 -0500 Subject: [PATCH 12/56] Disable loggers by default. --- testbench/testbench.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index aa11d377c..cc0f0a241 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -29,9 +29,9 @@ `include "tests.vh" `define PrintHPMCounters 1 -`define BPRED_LOGGER 1 -`define I_CACHE_ADDR_LOGGER 1 -`define D_CACHE_ADDR_LOGGER 1 +`define BPRED_LOGGER 0 +`define I_CACHE_ADDR_LOGGER 0 +`define D_CACHE_ADDR_LOGGER 0 module testbench; parameter DEBUG=0; From b4338a5a50126af83c583652a678be3c6d71dda9 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 28 Mar 2023 16:27:54 -0500 Subject: [PATCH 13/56] Modified the testbench to not use the loggers for unsupported configurations. --- testbench/testbench.sv | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index cc0f0a241..4372fd4e5 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -532,7 +532,7 @@ logic [3:0] dummy; // initialize the branch predictor - if (`BPRED_SUPPORTED == 1) begin + if (`BPRED_SUPPORTED) begin integer adrindex; always @(*) begin @@ -555,7 +555,7 @@ logic [3:0] dummy; end - if (`I_CACHE_ADDR_LOGGER == 1) begin + if (`ICACHE_SUPPORTED && `I_CACHE_ADDR_LOGGER) begin int file; string LogFile; logic resetD, resetEdge; @@ -580,7 +580,7 @@ end end end - if (`D_CACHE_ADDR_LOGGER == 1) begin + if (`DCACHE_SUPPORTED && `D_CACHE_ADDR_LOGGER) begin int file; string LogFile; logic resetD, resetEdge; @@ -611,7 +611,7 @@ end end end - if (`BPRED_SUPPORTED == 1) begin + if (`BPRED_SUPPORTED) begin if (`BPRED_LOGGER) begin string direction; int file; From bfb4f0d6eba72cdee8c209b3f13123028651df26 Mon Sep 17 00:00:00 2001 From: Alec Vercruysse Date: Thu, 23 Mar 2023 21:39:42 +0000 Subject: [PATCH 14/56] add check for legal funct3 for IW instructions --- src/ieu/controller.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index da99a48f6..5d0b78457 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -131,6 +131,7 @@ module controller( logic JFunctD; // detect jalr instruction logic FenceM; // Fence.I or sfence.VMA instruction in memory stage logic [2:0] ALUSelectD; // ALU Output selection mux control + logic IWValidFunct3D; // Detects if Funct3 is valid for IW instructions // Extract fields assign OpD = InstrD[6:0]; @@ -161,6 +162,7 @@ module controller( ((`XLEN == 64) & (Funct3D == 3'b011)); assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches assign JFunctD = (Funct3D == 3'b000); + assign IWValidFunct3D = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101; end else begin:legalcheck2 assign IFunctD = 1; // Don't bother to separate out shift decoding assign RFunctD = ~Funct7D[0]; // Not a multiply @@ -168,7 +170,8 @@ module controller( assign LFunctD = 1; // don't bother to check Funct3 for loads assign SFunctD = 1; // don't bother to check Funct3 for stores assign BFunctD = 1; // don't bother to check Funct3 for branches - assign JFunctD = 1; // don't bother to check Funct3 for jumps + assign JFunctD = 1; // don't bother to check Funct3 for jumps + assign IWValidFunct3D = 1; end // Main Instruction Decoder @@ -187,7 +190,7 @@ module controller( 7'b0010011: if (IFunctD) ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc - 7'b0011011: if (IFunctD & `XLEN == 64) + 7'b0011011: if (IFunctD & IWValidFunct3D & `XLEN == 64) ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i 7'b0100011: if (SFunctD) ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores From 7132271a83f0349e44128fe2b88057ebfa1c249f Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 21:13:25 -0700 Subject: [PATCH 15/56] Started adding fpu fctrl tests --- testbench/tests.vh | 1 + tests/coverage/Makefile | 2 +- tests/coverage/fpu.S | 69 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tests/coverage/fpu.S diff --git a/testbench/tests.vh b/testbench/tests.vh index 79f100d4f..fab26208a 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -47,6 +47,7 @@ string tvpaths[] = '{ "ieu", "ebu", "csrwrites", + "fpu", "priv" }; diff --git a/tests/coverage/Makefile b/tests/coverage/Makefile index 7d4552af2..b2a2544d3 100644 --- a/tests/coverage/Makefile +++ b/tests/coverage/Makefile @@ -17,7 +17,7 @@ all: $(OBJECTS) # Change many things if bit width isn't 64 %.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile - riscv64-unknown-elf-gcc -g -o $@ -march=rv64gc_zba_zbb_zbc_zbs -mabi=lp64 -mcmodel=medany \ + riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh -mabi=lp64 -mcmodel=medany \ -nostartfiles -T../../examples/link/link.ld $< riscv64-unknown-elf-objdump -S $@ > $@.objdump riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S new file mode 100644 index 000000000..34924a40a --- /dev/null +++ b/tests/coverage/fpu.S @@ -0,0 +1,69 @@ +/////////////////////////////////////////// +// fpu.S +// +// Written: David_Harris@hmc.edu 28 March 2023 +// +// Purpose: Test coverage for FPU +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// load code to initalize stack, handle interrupts, terminate +#include "WALLY-init-lib.h" + +main: + + # Test legal instructions not covered elsewhere + flq ft0, 0(a0) + flh ft0, 8(a0) + fsq ft0, 0(a0) + fsh ft0, 8(a0) + fcvt.h.s ft1, ft0 + fcvt.q.s ft2, ft0 + fcvt.h.w ft3, a0 + fcvt.h.wu ft3, a0 + fcvt.h.l ft3, a0 + fcvt.h.lu ft3, a0 + fcvt.w.h a0, ft3 + fcvt.wu.h a0, ft3 + fcvt.l.h a0, ft3 + fcvt.lu.h a0, ft3 + fcvt.q.w ft3, a0 + fcvt.q.wu ft3, a0 + fcvt.q.l ft3, a0 + fcvt.q.lu ft3, a0 + fcvt.w.q a0, ft3 + fcvt.wu.q a0, ft3 + fcvt.l.q a0, ft3 + fcvt.lu.q a0, ft3 + + + # Test illegal instructions are detected + .word 0x00000007 // illegal floating-point load (bad Funct3) + .word 0x00000027 // illegal floating-point store (bad Funct3) + .word 0x58F00053 // illegal fsqrt (bad Rs2D) + .word 0x20007053 // illegal fsgnj (bad Funct3) + .word 0x28007053 // illegal fmin/max (bad Funct3) + .word 0xA0007053 // illegal fcmp (bad Funct3) + .word 0xE0007053 // illegal fclass/fmv (bad Funct3) + .word 0xF0007053 // illegal fmv (bad Funct3) + .word 0x43007053 // illegal fcvt.d.* (bad Rs2D) + .word 0x42207053 // illegal fcvt.d.* (bad Rs2D[1]) + + j done + From 043e4fe5f4bc4e272e22b44fba61ebb2f8721000 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 21:13:48 -0700 Subject: [PATCH 16/56] Simplified fctrl --- src/fpu/fctrl.sv | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index a3e93ad7a..ad9007014 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -90,32 +90,27 @@ module fctrl ( (Fmt2 == 2'b10 & `ZFH_SUPPORTED) | (Fmt2 == 2'b11 & `Q_SUPPORTED)); // decode the instruction - always_comb + // ControlsD: FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt + always_comb if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt) ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // for anything other than loads and stores, check for supported format - else case(OpD) - // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt + else begin + ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // default: illegal FPU instruction + /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed + case(OpD) 7'b0000111: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fld not supported 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flq not supported 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flh not supported - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b0100111: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsd not supported 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsq not supported 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsh not supported - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub @@ -131,18 +126,15 @@ module fctrl ( 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction - endcase + endcase 7'b00101??: case(Funct3D) 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b10100??: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle - default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction endcase 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass @@ -158,9 +150,7 @@ module fctrl ( ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) - // *** other formats here - /* verilator lint_off CASEINCOMPLETE */ - 7'b1101000: case(Rs2D) + 7'b1101000: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s @@ -207,13 +197,11 @@ module fctrl ( 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase - - /* verilator lint_off CASEINCOMPLETE */ - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + endcase endcase - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction - endcase + endcase + /* verilator lint_off CASEINCOMPLETE */ + end // unswizzle control bits assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD} = ControlsD; From 4c41589329ef2161c15fcfbb4275dd3f8c50ff22 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 28 Mar 2023 21:28:56 -0700 Subject: [PATCH 17/56] Turned off hpm counters --- testbench/testbench.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 4372fd4e5..2bc3622c1 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -28,7 +28,7 @@ `include "wally-config.vh" `include "tests.vh" -`define PrintHPMCounters 1 +`define PrintHPMCounters 0 `define BPRED_LOGGER 0 `define I_CACHE_ADDR_LOGGER 0 `define D_CACHE_ADDR_LOGGER 0 From 4fa2959e566780fa31544c6d77145174d127f84c Mon Sep 17 00:00:00 2001 From: Diego Herrera Vicioso Date: Tue, 28 Mar 2023 22:48:17 -0700 Subject: [PATCH 18/56] Added test coverage cases for writing to STVAL, SCAUSE, SEPC, and STIMECMP CSRs. --- tests/coverage/priv.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 3aa3aea5c..8cd18925b 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -36,4 +36,11 @@ main: addi t0, zero, 0 csrr t0, stimecmp + # Test write to STVAL, SCAUSE, SEPC, and STIMECMP CSRs + li t0, 0 + csrw stval, t0 + csrw scause, t0 + csrw sepc, t0 + csrw stimecmp, t0 + j done From 0e0237853275eceebadb55d55816db3c4aa071ef Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 29 Mar 2023 06:10:05 -0700 Subject: [PATCH 19/56] Turned on FS bit in fpu.S coverage test --- tests/coverage/fpu.S | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 34924a40a..1a2d5ce7b 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -28,6 +28,9 @@ main: + bseti t0, zero, 14 # turn on FPU + csrs mstatus, t0 + # Test legal instructions not covered elsewhere flq ft0, 0(a0) flh ft0, 8(a0) From de2a0da9e93b903b1cfc95733b26cb3b5286d574 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 29 Mar 2023 07:02:09 -0700 Subject: [PATCH 20/56] Reduced number of bits in mcause and medeleg registers --- src/privileged/csr.sv | 11 ++++++----- src/privileged/csrm.sv | 21 +++++++++++---------- src/privileged/csrs.sv | 9 +++++---- src/privileged/privileged.sv | 4 ++-- src/privileged/trap.sv | 8 ++++---- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 1478b5fc0..f44785287 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -55,7 +55,7 @@ module csr #(parameter input logic [4:0] SetFflagsM, // Set floating point flag bits in FCSR input logic [1:0] NextPrivilegeModeM, // STATUS bits updated based on next privilege mode input logic [1:0] PrivilegeModeW, // current privilege mode - input logic [`LOG_XLEN-1:0] CauseM, // Trap cause + input logic [3:0] CauseM, // Trap cause input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode // inputs for performance counters input logic LoadStallD, @@ -79,7 +79,7 @@ module csr #(parameter // outputs from CSRs output logic [1:0] STATUS_MPP, output logic STATUS_SPP, STATUS_TSR, STATUS_TVM, - output logic [`XLEN-1:0] MEDELEG_REGW, + output logic [15:0] MEDELEG_REGW, output logic [`XLEN-1:0] SATP_REGW, output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, output logic STATUS_MIE, STATUS_SIE, @@ -107,7 +107,8 @@ module csr #(parameter logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic WriteFRMM, WriteFFLAGSM; - logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM; + logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; + logic [4:0] NextCauseM; logic [11:0] CSRAdrM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM; logic InsufficientCSRPrivilegeM; @@ -153,7 +154,7 @@ module csr #(parameter logic VectoredM; logic [`XLEN-1:0] TVecPlusCauseM; assign VectoredM = InterruptM & (TVecM[1:0] == 2'b01); - assign TVecPlusCauseM = {TVecAlignedM[`XLEN-1:6], CauseM[3:0], 2'b00}; // 64-byte alignment allows concatenation rather than addition + assign TVecPlusCauseM = {TVecAlignedM[`XLEN-1:6], CauseM, 2'b00}; // 64-byte alignment allows concatenation rather than addition mux2 #(`XLEN) trapvecmux(TVecAlignedM, TVecPlusCauseM, VectoredM, TrapVectorM); end else assign TrapVectorM = TVecAlignedM; @@ -196,7 +197,7 @@ module csr #(parameter assign CSRAdrM = InstrM[31:20]; assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+4 : PCM) : CSRWriteValM; assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment - assign NextCauseM = TrapM ? {InterruptM, {(`XLEN-`LOG_XLEN-1){1'b0}}, CauseM}: CSRWriteValM; + assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[`XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; assign CSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE); assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW); diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index daf7e1012..9f00f3a68 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -69,20 +69,21 @@ module csrm #(parameter DSCRATCH1 = 12'h7B3, // Constants ZERO = {(`XLEN){1'b0}}, - MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), + MEDELEG_MASK = 16'hB3FF, MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable ) ( input logic clk, reset, input logic InstrValidNotFlushedM, input logic CSRMWriteM, MTrapM, input logic [11:0] CSRAdrM, - input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW, + input logic [`XLEN-1:0] NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW, + input logic [4:0] NextCauseM, input logic [`XLEN-1:0] CSRWriteValM, input logic [11:0] MIP_REGW, MIE_REGW, output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW, output logic [`XLEN-1:0] MEPC_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, - output logic [`XLEN-1:0] MEDELEG_REGW, + output logic [15:0] MEDELEG_REGW, output logic [11:0] MIDELEG_REGW, output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], @@ -91,8 +92,8 @@ module csrm #(parameter ); logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW; - logic [`XLEN-1:0] MSCRATCH_REGW; - logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW; + logic [`XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW; + logic [4:0] MCAUSE_REGW; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; @@ -150,13 +151,13 @@ module csrm #(parameter // CSRs flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); if (`S_SUPPORTED) begin:deleg // DELEG registers should exist - flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, MEDELEG_REGW); - flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW); + flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW); + flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW); end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0; flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW); - flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); + flopenr #(5) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); if(`QEMU) assign MTVAL_REGW = `XLEN'b0; // MTVAL tied to 0 in QEMU configuration else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW); @@ -192,13 +193,13 @@ module csrm #(parameter MSTATUS: CSRMReadValM = MSTATUS_REGW; MSTATUSH: CSRMReadValM = MSTATUSH_REGW; MTVEC: CSRMReadValM = MTVEC_REGW; - MEDELEG: CSRMReadValM = MEDELEG_REGW; + MEDELEG: CSRMReadValM = {{(`XLEN-16){1'b0}}, MEDELEG_REGW}; MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW}; MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; MSCRATCH: CSRMReadValM = MSCRATCH_REGW; MEPC: CSRMReadValM = MEPC_REGW; - MCAUSE: CSRMReadValM = MCAUSE_REGW; + MCAUSE: CSRMReadValM = {MCAUSE_REGW[4], {(`XLEN-5){1'b0}}, MCAUSE_REGW[3:0]}; MTVAL: CSRMReadValM = MTVAL_REGW; MTINST: CSRMReadValM = 0; // implemented as trivial zero MCOUNTEREN:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTEREN_REGW}; diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index 3d75ef73e..598eed155 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -48,7 +48,8 @@ module csrs #(parameter input logic InstrValidNotFlushedM, input logic CSRSWriteM, STrapM, input logic [11:0] CSRAdrM, - input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, + input logic [`XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW, + input logic [4:0] NextCauseM, input logic STATUS_TVM, input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear input logic [`XLEN-1:0] CSRWriteValM, @@ -73,7 +74,7 @@ module csrs #(parameter logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSTIMECMPM, WriteSTIMECMPHM; logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW; - logic [`XLEN-1:0] SCAUSE_REGW; + logic [4:0] SCAUSE_REGW; logic [63:0] STIMECMP_REGW; // write enables @@ -93,7 +94,7 @@ module csrs #(parameter flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); - flopenr #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, SCAUSE_REGW); + flopenr #(5) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, SCAUSE_REGW); flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); if (`VIRTMEM_SUPPORTED) flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW); @@ -126,7 +127,7 @@ module csrs #(parameter SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW & 12'h222 & MIDELEG_REGW}; // only read supervisor fields SSCRATCH: CSRSReadValM = SSCRATCH_REGW; SEPC: CSRSReadValM = SEPC_REGW; - SCAUSE: CSRSReadValM = SCAUSE_REGW; + SCAUSE: CSRSReadValM = {SCAUSE_REGW[4], {(`XLEN-5){1'b0}}, SCAUSE_REGW[3:0]}; STVAL: CSRSReadValM = STVAL_REGW; SATP: if (`VIRTMEM_SUPPORTED & (PrivilegeModeW == `M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW; else begin diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 1975db10e..6fa8dcf98 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -96,8 +96,8 @@ module privileged ( output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout ); - logic [`LOG_XLEN-1:0] CauseM; // trap cause - logic [`XLEN-1:0] MEDELEG_REGW; // exception delegation CSR + logic [3:0] CauseM; // trap cause + logic [15:0] MEDELEG_REGW; // exception delegation CSR logic [11:0] MIDELEG_REGW; // interrupt delegation CSR logic sretM, mretM; // supervisor / machine return instruction logic IllegalCSRAccessM; // Illegal access to CSR diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index d50b5fb48..ace63b48b 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -38,7 +38,7 @@ module trap ( input logic wfiM, // wait for interrupt instruction input logic [1:0] PrivilegeModeW, // current privilege mode input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs - input logic [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR + input logic [15:0] MEDELEG_REGW, // exception delegation SR input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables input logic InstrValidM, // current instruction is valid, not flushed input logic CommittedM, CommittedF, // LSU/IFU has committed to a bus operation that can't be interrupted @@ -49,7 +49,7 @@ module trap ( output logic IntPendingM, // Interrupt is pending, might occur if enabled output logic DelegateM, // Delegate trap to supervisor handler output logic WFIStallM, // Stall due to WFI instruction - output logic [`LOG_XLEN-1:0] CauseM // trap cause + output logic [3:0] CauseM // trap cause ); logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables @@ -72,7 +72,7 @@ module trap ( assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); assign ValidIntsM = {12{~Committed}} & EnabledIntsM; assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. - assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]) & + assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE); assign WFIStallM = wfiM & ~IntPendingM; @@ -109,7 +109,7 @@ module trap ( else if (IllegalInstrFaultM) CauseM = 2; else if (InstrMisalignedFaultM) CauseM = 0; else if (BreakpointFaultM) CauseM = 3; - else if (EcallFaultM) CauseM = {{(`LOG_XLEN-4){1'b0}}, {2'b10}, PrivilegeModeW}; + else if (EcallFaultM) CauseM = {2'b10, PrivilegeModeW}; else if (LoadMisalignedFaultM) CauseM = 4; else if (StoreAmoMisalignedFaultM) CauseM = 6; else if (LoadPageFaultM) CauseM = 13; From dac011c1d2fd5eb635dafa8235e250a96d3a6030 Mon Sep 17 00:00:00 2001 From: Alec Vercruysse Date: Wed, 29 Mar 2023 13:04:00 -0700 Subject: [PATCH 21/56] icache coverage improvements by simplifying logic --- src/cache/cache.sv | 19 +++++++++++++------ src/cache/cacheLRU.sv | 8 +++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index da7f83276..3dac0c562 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -168,14 +168,21 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE assign DemuxedByteMask[(index+1)*(WORDLEN/8)-1:index*(WORDLEN/8)] = MemPAdrDecoded[index] ? ByteMask : '0; end assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1. - assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; - // Merge write data into fetched cache line for store miss - for(index = 0; index < LINELEN/8; index++) begin - mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), - .d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index]), .y(LineWriteData[8*index+7:8*index])); + if(!READ_ONLY_CACHE) begin:WriteSelLogic + // Merge write data into fetched cache line for store miss + for(index = 0; index < LINELEN/8; index++) begin + mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), + .d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index]), .y(LineWriteData[8*index+7:8*index])); + end + assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; end - + else + begin:WriteSelLogic + // No need for this mux if the cache does not handle writes. + assign LineWriteData = FetchBuffer; + assign LineByteMask = '1; + end ///////////////////////////////////////////////////////////////////////////////////////////// // Flush logic ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/cache/cacheLRU.sv b/src/cache/cacheLRU.sv index 05e26f4bf..780807943 100644 --- a/src/cache/cacheLRU.sv +++ b/src/cache/cacheLRU.sv @@ -98,7 +98,9 @@ module cacheLRU assign LRUUpdate[t1] = LRUUpdate[s] & WayEncoded[r]; end - mux2 #(1) LRUMuxes[NUMWAYS-2:0](CurrLRU, ~WayExpanded, LRUUpdate, NextLRU); + // The root node of the LRU tree will always be selected in LRUUpdate. No mux needed. + assign NextLRU[NUMWAYS-2] = ~WayExpanded[NUMWAYS-2]; + mux2 #(1) LRUMuxes[NUMWAYS-3:0](CurrLRU[NUMWAYS-3:0], ~WayExpanded[NUMWAYS-3:0], LRUUpdate[NUMWAYS-3:0], NextLRU[NUMWAYS-3:0]); // Compute next victim way. for(s = NUMWAYS-2; s >= NUMWAYS/2; s--) begin @@ -128,8 +130,8 @@ module cacheLRU always_ff @(posedge clk) begin if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; if(CacheEn) begin - if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; - else if (LRUWriteEn & ~FlushStage) begin + // if((InvalidateCache | FlushCache) & ~FlushStage) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; + if (LRUWriteEn & ~FlushStage) begin LRUMemory[PAdr] <= NextLRU; end if(LRUWriteEn & ~FlushStage & (PAdr == CacheSet)) From da905b4eb97cfe5989a18721cd8ffe9e8149566a Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Wed, 29 Mar 2023 15:04:56 -0700 Subject: [PATCH 22/56] Resolved ImperasDV receiving incorrect cause values --- src/privileged/csrm.sv | 8 ++++---- src/privileged/csrs.sv | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index 9f00f3a68..1511732f7 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -92,8 +92,8 @@ module csrm #(parameter ); logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW; - logic [`XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW; - logic [4:0] MCAUSE_REGW; + logic [`XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; + // logic [4:0] ; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; @@ -157,7 +157,7 @@ module csrm #(parameter flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW); - flopenr #(5) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); + flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, {NextCauseM[4], {(`XLEN-5){1'b0}}, NextCauseM[3:0]}, MCAUSE_REGW); if(`QEMU) assign MTVAL_REGW = `XLEN'b0; // MTVAL tied to 0 in QEMU configuration else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW); @@ -199,7 +199,7 @@ module csrm #(parameter MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; MSCRATCH: CSRMReadValM = MSCRATCH_REGW; MEPC: CSRMReadValM = MEPC_REGW; - MCAUSE: CSRMReadValM = {MCAUSE_REGW[4], {(`XLEN-5){1'b0}}, MCAUSE_REGW[3:0]}; + MCAUSE: CSRMReadValM = MCAUSE_REGW; MTVAL: CSRMReadValM = MTVAL_REGW; MTINST: CSRMReadValM = 0; // implemented as trivial zero MCOUNTEREN:CSRMReadValM = {{(`XLEN-32){1'b0}}, MCOUNTEREN_REGW}; diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index 598eed155..f14cc30ff 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -73,8 +73,8 @@ module csrs #(parameter logic WriteSSCRATCHM, WriteSEPCM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSTIMECMPM, WriteSTIMECMPHM; - logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW; - logic [4:0] SCAUSE_REGW; + logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW; + // logic [4:0] ; logic [63:0] STIMECMP_REGW; // write enables @@ -94,7 +94,7 @@ module csrs #(parameter flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW); flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW); - flopenr #(5) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, SCAUSE_REGW); + flopenr #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, {NextCauseM[4], {(`XLEN-5){1'b0}}, NextCauseM[3:0]}, SCAUSE_REGW); flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW); if (`VIRTMEM_SUPPORTED) flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW); @@ -127,7 +127,7 @@ module csrs #(parameter SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW & 12'h222 & MIDELEG_REGW}; // only read supervisor fields SSCRATCH: CSRSReadValM = SSCRATCH_REGW; SEPC: CSRSReadValM = SEPC_REGW; - SCAUSE: CSRSReadValM = {SCAUSE_REGW[4], {(`XLEN-5){1'b0}}, SCAUSE_REGW[3:0]}; + SCAUSE: CSRSReadValM = SCAUSE_REGW; STVAL: CSRSReadValM = STVAL_REGW; SATP: if (`VIRTMEM_SUPPORTED & (PrivilegeModeW == `M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW; else begin From ede13491efc65d10109117e67bde45ac5ecc1bb9 Mon Sep 17 00:00:00 2001 From: Sydney Riley Date: Wed, 29 Mar 2023 15:15:47 -0700 Subject: [PATCH 23/56] Starting IFU tests including c.fld compressed instruction --- testbench/tests.vh | 3 ++- tests/coverage/ifu.S | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/coverage/ifu.S diff --git a/testbench/tests.vh b/testbench/tests.vh index 79f100d4f..e03d50e30 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -47,7 +47,8 @@ string tvpaths[] = '{ "ieu", "ebu", "csrwrites", - "priv" + "priv", + "ifu" }; string coremark[] = '{ diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S new file mode 100644 index 000000000..a3a5e7d29 --- /dev/null +++ b/tests/coverage/ifu.S @@ -0,0 +1,40 @@ +/////////////////////////////////////////// +// ifu.S +// +// Written: David_Harris@hmc.edu 28 March 2023 +// +// Purpose: Test coverage for IFU +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// load code to initalize stack, handle interrupts, terminate +#include "WALLY-init-lib.h" + +main: + # turn floating point on + li t0, 0x2000 + csrs mstatus, t0 + + # calling compressed floating point load double instruction + //.halfword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op + // binary version 0000 0000 0000 0000 0010 0000 0000 0000 + mv s0, sp + c.fld fs0, 0(s0) + + j done From 287df517b9c363e6c15c798f48bae837a68aebb7 Mon Sep 17 00:00:00 2001 From: Sydney Riley Date: Wed, 29 Mar 2023 15:20:46 -0700 Subject: [PATCH 24/56] Corrected authorship for IFU.S tests file --- tests/coverage/ifu.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index a3a5e7d29..3ceeeac12 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -1,7 +1,7 @@ /////////////////////////////////////////// // ifu.S // -// Written: David_Harris@hmc.edu 28 March 2023 +// Written: sriley@g.hmc.edu 28 March 2023 // // Purpose: Test coverage for IFU // From 414cd26a9df6afe11b2565dbec0276a8cc98792a Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Wed, 29 Mar 2023 15:24:00 -0700 Subject: [PATCH 25/56] updated tests to reflect non-writeable bits of deleg --- .../privilege/references/WALLY-trap-01.reference_output | 4 ++-- .../privilege/references/WALLY-trap-s-01.reference_output | 4 ++-- .../privilege/references/WALLY-trap-u-01.reference_output | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output index 78e096cee..39ec3ad42 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output @@ -108,8 +108,8 @@ 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 -fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable) -ffffffff +0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +00000000 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled 00000001 # mcause from an instruction access fault diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output index dc5acb4d6..4c3031eb2 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output @@ -98,8 +98,8 @@ 00000000 00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0 00000000 -fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable) -ffffffff +0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +00000000 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 00000000 0000000b # scause from M mode ecall diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output index 7afec5268..2d1d16d27 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output @@ -92,8 +92,8 @@ 00000000 00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0 00000000 -fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable) -ffffffff +0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +00000000 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 00000000 0000000b # scause from M mode ecall From 7881c245a22e02142c38e8988e764522e7566d10 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Wed, 29 Mar 2023 16:31:28 -0700 Subject: [PATCH 26/56] ported medelg fixes to 32 bit tests. Requires a make allclean --- .../rv32i_m/privilege/references/WALLY-trap-01.reference_output | 2 +- .../privilege/references/WALLY-trap-s-01.reference_output | 2 +- .../privilege/references/WALLY-trap-u-01.reference_output | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output index a9c3da2c0..fb24280ad 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output @@ -53,7 +53,7 @@ 8000000b # mcause value from m ext interrupt 00000000 # mtval for mext interrupt (0x0) 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 -fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) # skipping instruction address fault since they're impossible with compressed instrs enabled 00000001 # mcause from an instruction access fault 00000000 # mtval of faulting instruction address (0x0) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output index e57184719..9dbdd8337 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output @@ -48,7 +48,7 @@ 00000009 # scause from S mode ecall 00000000 # stval of ecall (*** defined to be zero for now) 00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0 -fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 0000000b # scause from M mode ecall 00000000 # stval of ecall (*** defined to be zero for now) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output index 5c6d8378d..b19a0c21e 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output @@ -45,7 +45,7 @@ 00000008 # scause from U mode ecall 00000000 # stval of ecall (*** defined to be zero for now) 00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0 -fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 0000000b # scause from M mode ecall 00000000 # stval of ecall (*** defined to be zero for now) From 94f03b0d785f70e763205ba4928a49a21d241319 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Wed, 29 Mar 2023 19:32:57 -0700 Subject: [PATCH 27/56] unnecessary comments cleanup --- src/privileged/csrm.sv | 1 - src/privileged/csrs.sv | 1 - 2 files changed, 2 deletions(-) diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index 1511732f7..e8a42773d 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -93,7 +93,6 @@ module csrm #(parameter logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [`XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; - // logic [4:0] ; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index f14cc30ff..f6d02fe14 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -74,7 +74,6 @@ module csrs #(parameter logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSTIMECMPM, WriteSTIMECMPHM; logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW; - // logic [4:0] ; logic [63:0] STIMECMP_REGW; // write enables From 3990417d704209eac501755de21bf6a0df354487 Mon Sep 17 00:00:00 2001 From: Alessandro Maiuolo Date: Wed, 29 Mar 2023 20:57:26 -0700 Subject: [PATCH 28/56] integrated tv generation for IFdivsqrt --- .../fp/combined_IF_vectors/IF_vectors/README | 4 + .../combined_IF_vectors/create_IF_vectors.sh | 8 + .../extract_arch_vectors.py | 251 ++++++++++++++++++ .../extract_testfloat_vectors.py | 79 ++++++ tests/fp/create_all_vectors.sh | 3 + 5 files changed, 345 insertions(+) create mode 100644 tests/fp/combined_IF_vectors/IF_vectors/README create mode 100755 tests/fp/combined_IF_vectors/create_IF_vectors.sh create mode 100755 tests/fp/combined_IF_vectors/extract_arch_vectors.py create mode 100755 tests/fp/combined_IF_vectors/extract_testfloat_vectors.py diff --git a/tests/fp/combined_IF_vectors/IF_vectors/README b/tests/fp/combined_IF_vectors/IF_vectors/README new file mode 100644 index 000000000..bfbf368dd --- /dev/null +++ b/tests/fp/combined_IF_vectors/IF_vectors/README @@ -0,0 +1,4 @@ +This folder holds the archtest and testfloat vectors necessary fo evaluating performance +of standalone intdiv vs combined IFdivsqrt + +to generate vectors, uncomment line 8 in create_all_vectors.sh \ No newline at end of file diff --git a/tests/fp/combined_IF_vectors/create_IF_vectors.sh b/tests/fp/combined_IF_vectors/create_IF_vectors.sh new file mode 100755 index 000000000..d6b83f599 --- /dev/null +++ b/tests/fp/combined_IF_vectors/create_IF_vectors.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# create test vectors for stand alone int + +./extract_testfloat_vectors.py +./extract_arch_vectors.py + +# to create tvs for evaluation of combined IFdivsqrt +#./combined_IF_vectors/create_IF_vectors.sh \ No newline at end of file diff --git a/tests/fp/combined_IF_vectors/extract_arch_vectors.py b/tests/fp/combined_IF_vectors/extract_arch_vectors.py new file mode 100755 index 000000000..c80c7a843 --- /dev/null +++ b/tests/fp/combined_IF_vectors/extract_arch_vectors.py @@ -0,0 +1,251 @@ +#! /usr/bin/python3 + +# author: Alessandro Maiuolo +# contact: amaiuolo@g.hmc.edu +# date created: 3-29-2023 + +# extract all arch test vectors +import os +wally = os.popen('echo $WALLY').read().strip() + +def ext_bits(my_string): + target_len = 32 # we want 128 bits, div by 4 bc hex notation + zeroes_to_add = target_len - len(my_string) + return zeroes_to_add*"0" + my_string + +def twos_comp(b, x): + if b == 32: + return hex(0x100000000 - int(x,16))[2:] + elif b == 64: + return hex(0x10000000000000000 - int(x,16))[2:] + else: + return "UNEXPECTED_BITSIZE" + +def unpack_rf(packed): + bin_u = bin(int(packed, 16))[2:].zfill(8) # translate to binary + flags = hex(int(bin_u[3:],2))[2:].zfill(2) + rounding_mode = hex(int(bin_u[:3],2))[2:] + return flags, rounding_mode + +# rounding mode dictionary +round_dict = { + "rne":"0", + "rnm":"4", + "ru":"3", + "rz":"1", + "rd":"2", + "dyn":"7" +} + +# fcsr dictionary +fcsr_dict = { + "0":"rne", + "128":"rnm", + "96":"ru", + "32":"rz", + "64":"rd", + "224":"dyn" +} + +print("creating arch test vectors") + +class Config: + def __init__(self, bits, letter, op, filt, op_code): + self.bits = bits + self.letter = letter + self.op = op + self.filt = filt + self.op_code = op_code + +def create_vectors(my_config): + suite_folder_num = my_config.bits + if my_config.bits == 64 and my_config.letter == "F": suite_folder_num = 32 + source_dir1 = "{}/addins/riscv-arch-test/riscv-test-suite/rv{}i_m/{}/src/".format(wally, suite_folder_num, my_config.letter) + source_dir2 = "{}/tests/riscof/work/riscv-arch-test/rv{}i_m/{}/src/".format(wally, my_config.bits, my_config.letter) + dest_dir = "{}/tests/fp/combined_IF_vectors/IF_vectors/".format(wally) + all_vectors1 = os.listdir(source_dir1) + + filt_vectors1 = [v for v in all_vectors1 if my_config.filt in v] + # print(filt_vectors1) + filt_vectors2 = [v + "/ref/Reference-sail_c_simulator.signature" for v in all_vectors1 if my_config.filt in v] + + # iterate through all vectors + for i in range(len(filt_vectors1)): + vector1 = filt_vectors1[i] + vector2 = filt_vectors2[i] + operation = my_config.op_code + rounding_mode = "X" + flags = "XX" + # use name to create our new tv + dest_file = open("{}cvw_{}_{}.tv".format(dest_dir, my_config.bits, vector1[:-2]), 'a') + # open vectors + src_file1 = open(source_dir1 + vector1,'r') + src_file2 = open(source_dir2 + vector2,'r') + # for each test in the vector + reading = True + src_file2.readline() #skip first bc junk + # print(my_config.bits, my_config.letter) + if my_config.letter == "F" and my_config.bits == 64: + reading = True + # print("trigger 64F") + #skip first 2 lines bc junk + src_file2.readline() + while reading: + # get answer and flags from Ref...signature + # answers are before deadbeef (first line of 4) + # flags are after deadbeef (third line of 4) + answer = src_file2.readline().strip() + deadbeef = src_file2.readline().strip() + # print(answer) + if not (answer == "e7d4b281" and deadbeef == "6f5ca309"): # if there is still stuff to read + # get flags + packed = src_file2.readline().strip()[6:] + flags, rounding_mode = unpack_rf(packed) + # skip 00000000 buffer + src_file2.readline() + + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if my_config.op != "fsqrt": # sqrt doesn't have two input vals + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + else: + op2val = 32*"X" + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # put it all together + if not done: + translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip()), flags, rounding_mode) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + elif my_config.letter == "M" and my_config.bits == 64: + reading = True + #skip first 2 lines bc junk + src_file2.readline() + while reading: + # print("trigger 64M") + # get answer from Ref...signature + # answers span two lines and are reversed + answer2 = src_file2.readline().strip() + answer1 = src_file2.readline().strip() + answer = answer1 + answer2 + # print(answer1,answer2) + if not (answer2 == "e7d4b281" and answer1 == "6f5ca309"): # if there is still stuff to read + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling + op1val = twos_comp(my_config.bits, op1val) + if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling + op2val = twos_comp(my_config.bits, op2val) + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # ints don't have flags + flags = "XX" + # put it all together + if not done: + translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip()), flags.strip(), rounding_mode) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + else: + while reading: + # get answer and flags from Ref...signature + answer = src_file2.readline() + # print(answer) + packed = src_file2.readline()[6:] + # print(packed) + if len(packed.strip())>0: # if there is still stuff to read + # print("packed") + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling + op1val = twos_comp(my_config.bits, op1val) + if my_config.op != "fsqrt": # sqrt doesn't have two input vals + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling + op2val = twos_comp(my_config.bits, op2val) + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # rounding mode for float + if not done and (my_config.op == "fsqrt" or my_config.op == "fdiv"): + flags, rounding_mode = unpack_rf(packed) + + # put it all together + if not done: + translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip()), flags, rounding_mode) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + print("out") + dest_file.close() + src_file1.close() + src_file2.close() + +config_list = [ +Config(32, "M", "div", "div_", 0), +Config(32, "F", "fdiv", "fdiv", 1), +Config(32, "F", "fsqrt", "fsqrt", 2), +Config(32, "M", "rem", "rem-", 3), +Config(32, "M", "divu", "divu-", 4), +Config(32, "M", "remu", "remu-", 5), +Config(64, "M", "div", "div-", 0), +Config(64, "F", "fdiv", "fdiv", 1), +Config(64, "F", "fsqrt", "fsqrt", 2), +Config(64, "M", "rem", "rem-", 3), +Config(64, "M", "divu", "divu-", 4), +Config(64, "M", "remu", "remu-", 5), +Config(64, "M", "divw", "divw-", 6), +Config(64, "M", "divuw", "divuw-", 7), +Config(64, "M", "remw", "remw-", 8), +Config(64, "M", "remuw", "remuw-", 9) +] + +for c in config_list: + create_vectors(c) \ No newline at end of file diff --git a/tests/fp/combined_IF_vectors/extract_testfloat_vectors.py b/tests/fp/combined_IF_vectors/extract_testfloat_vectors.py new file mode 100755 index 000000000..07047be25 --- /dev/null +++ b/tests/fp/combined_IF_vectors/extract_testfloat_vectors.py @@ -0,0 +1,79 @@ +#! /usr/bin/python3 +# extract sqrt and float div testfloat vectors + +# author: Alessandro Maiuolo +# contact: amaiuolo@g.hmc.edu +# date created: 3-29-2023 + +import os +wally = os.popen('echo $WALLY').read().strip() +# print(wally) + +def ext_bits(my_string): + target_len = 32 # we want 128 bits, div by 4 bc hex notation + zeroes_to_add = target_len - len(my_string) + return zeroes_to_add*"0" + my_string + +# rounding mode dictionary +round_dict = { + "rne":"0", + "rnm":"4", + "ru":"3", + "rz":"1", + "rd":"2", + "dyn":"7" +} + + +print("creating testfloat div test vectors") + +source_dir = "{}/tests/fp/vectors/".format(wally) +dest_dir = "{}/tests/fp/combined_IF_vectors/IF_vectors/".format(wally) +all_vectors = os.listdir(source_dir) + +div_vectors = [v for v in all_vectors if "div" in v] + +# iterate through all float div vectors +for vector in div_vectors: + # use name to determine configs + config_list = vector.split(".")[0].split("_") + operation = "1" #float div + rounding_mode = round_dict[str(config_list[2])] + # use name to create our new tv + dest_file = open(dest_dir + "cvw_" + vector, 'a') + # open vector + src_file = open(source_dir + vector,'r') + # for each test in the vector + for i in src_file.readlines(): + translation = "" # this stores the test that we are currently working on + [input_1, input_2, answer, flags] = i.split("_") # separate inputs, answer, and flags + # put it all together, strip nec for removing \n on the end of the flags + translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(input_1), ext_bits(input_2), ext_bits(answer), flags.strip(), rounding_mode) + dest_file.write(translation + "\n") + dest_file.close() + src_file.close() + + +print("creating testfloat sqrt test vectors") + +sqrt_vectors = [v for v in all_vectors if "sqrt" in v] + +# iterate through all float div vectors +for vector in sqrt_vectors: + # use name to determine configs + config_list = vector.split(".")[0].split("_") + operation = "2" #sqrt + rounding_mode = round_dict[str(config_list[2])] + # use name to create our new tv + dest_file = open(dest_dir + "cvw_" + vector, 'a') + # open vector + src_file = open(source_dir + vector,'r') + # for each test in the vector + for i in src_file.readlines(): + translation = "" # this stores the test that we are currently working on + [input_1, answer, flags] = i.split("_") # separate inputs, answer, and flags + # put it all together, strip nec for removing \n on the end of the flags + translation = "{}_{}_{}_{}_{}_{}".format(operation, ext_bits(input_1), "X"*32, ext_bits(answer), flags.strip(), rounding_mode) + dest_file.write(translation + "\n") + dest_file.close() + src_file.close() \ No newline at end of file diff --git a/tests/fp/create_all_vectors.sh b/tests/fp/create_all_vectors.sh index f1ba3625c..38cfd555a 100755 --- a/tests/fp/create_all_vectors.sh +++ b/tests/fp/create_all_vectors.sh @@ -3,3 +3,6 @@ mkdir -p vectors ./create_vectors.sh ./remove_spaces.sh + +# to create tvs for evaluation of combined IFdivsqrt +#./combined_IF_vectors/create_IF_vectors.sh \ No newline at end of file From 132074523faa7ea5e5eafe5a22060f320911c3f9 Mon Sep 17 00:00:00 2001 From: Alec Vercruysse Date: Thu, 30 Mar 2023 10:32:40 -0700 Subject: [PATCH 29/56] Make entire cache write path conditional on READ_ONLY_CACHE --- src/cache/cache.sv | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 3dac0c562..56044384b 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -96,8 +96,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache; logic SelFetchBuffer; logic CacheEn; - logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded; - logic [LINELEN/8-1:0] LineByteMask, DemuxedByteMask, FetchBufferByteSel; + logic [LINELEN/8-1:0] LineByteMask; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; genvar index; @@ -161,15 +160,17 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE ///////////////////////////////////////////////////////////////////////////////////////////// // Write Path ///////////////////////////////////////////////////////////////////////////////////////////// - - // Adjust byte mask from word to cache line - onehotdecoder #(LOGCWPL) adrdec(.bin(PAdr[LOGCWPL+LOGLLENBYTES-1:LOGLLENBYTES]), .decoded(MemPAdrDecoded)); - for(index = 0; index < 2**LOGCWPL; index++) begin - assign DemuxedByteMask[(index+1)*(WORDLEN/8)-1:index*(WORDLEN/8)] = MemPAdrDecoded[index] ? ByteMask : '0; - end - assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1. - if(!READ_ONLY_CACHE) begin:WriteSelLogic + logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded; + logic [LINELEN/8-1:0] DemuxedByteMask, FetchBufferByteSel; + + // Adjust byte mask from word to cache line + onehotdecoder #(LOGCWPL) adrdec(.bin(PAdr[LOGCWPL+LOGLLENBYTES-1:LOGLLENBYTES]), .decoded(MemPAdrDecoded)); + for(index = 0; index < 2**LOGCWPL; index++) begin + assign DemuxedByteMask[(index+1)*(WORDLEN/8)-1:index*(WORDLEN/8)] = MemPAdrDecoded[index] ? ByteMask : '0; + end + assign FetchBufferByteSel = SetValid & ~SetDirty ? '1 : ~DemuxedByteMask; // If load miss set all muxes to 1. + // Merge write data into fetched cache line for store miss for(index = 0; index < LINELEN/8; index++) begin mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), From b07c71ea41cbf280a885c492bc3deee8f3fa0c61 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 30 Mar 2023 12:57:14 -0700 Subject: [PATCH 30/56] Started to clean up fctrl --- src/fpu/fctrl.sv | 226 +++++++++++++++++++++++++---------------------- 1 file changed, 121 insertions(+), 105 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index ad9007014..67c601d35 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -90,118 +90,134 @@ module fctrl ( (Fmt2 == 2'b10 & `ZFH_SUPPORTED) | (Fmt2 == 2'b11 & `Q_SUPPORTED)); // decode the instruction - // ControlsD: FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt - always_comb + // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt + always_comb if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt) ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // for anything other than loads and stores, check for supported format - else begin - ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // default: illegal FPU instruction + else begin + ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // default: non-implemented instruction /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed case(OpD) - 7'b0000111: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw - 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld - 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq - 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh - endcase - 7'b0100111: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw - 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd - 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq - 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh - endcase - 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd - 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub - 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub - 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd - 7'b1010011: casez(Funct7D) - 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd - 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub - 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul - 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv - 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt - 7'b00100??: case(Funct3D) - 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj - 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn - 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx - endcase - 7'b00101??: case(Funct3D) - 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin - 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax - endcase - 7'b10100??: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq - 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt - 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle - endcase - 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass - else if (Funct3D == 3'b000 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register - 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg - 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) - ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) - 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) - ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) - 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) - ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) - 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) - ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) - 7'b1101000: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s - endcase - 7'b1100000: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu - endcase - 7'b1101001: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d - endcase - 7'b1100001: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu - endcase - 7'b1101010: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h - endcase - 7'b1100010: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu - endcase - 7'b1101011: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q - endcase - 7'b1100011: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase - endcase + 7'b0000111: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw + 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld + else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fld not supported + 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq + else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flq not supported + 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh + else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flh not supported + default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + endcase + 7'b0100111: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw + 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd + else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsd not supported + 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq + else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsq not supported + 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh + else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsh not supported + default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + endcase + 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd + 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub + 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub + 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd + 7'b1010011: casez(Funct7D) + 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd + 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub + 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul + 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv + 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt + 7'b00100??: case(Funct3D) + 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj + 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn + 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx + default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + endcase + 7'b00101??: case(Funct3D) + 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin + 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax + default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + endcase + 7'b10100??: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq + 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt + 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle + default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction + endcase + 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass + else if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register + 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg + 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) + ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) + 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) + ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) + ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) + 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) + ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) + // *** other formats here + /* verilator lint_off CASEINCOMPLETE */ + 7'b1101000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s + endcase + 7'b1100000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu + endcase + 7'b1101001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d + endcase + 7'b1100001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu + endcase + 7'b1101010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h + endcase + 7'b1100010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu + endcase + 7'b1101011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q + endcase + 7'b1100011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu + endcase + + default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + endcase +// default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase - /* verilator lint_off CASEINCOMPLETE */ end + /* verilator lint_off CASEINCOMPLETE */ // unswizzle control bits assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD} = ControlsD; @@ -330,4 +346,4 @@ module fctrl ( //assign FCvtIntW = (FResSelW == 2'b01); -endmodule +endmodule \ No newline at end of file From e68e473da94fb8f4d72c903d630264986368307f Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 30 Mar 2023 13:05:56 -0700 Subject: [PATCH 31/56] fctrl continued cleanup --- src/fpu/fctrl.sv | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 67c601d35..337e00354 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -103,22 +103,14 @@ module fctrl ( 7'b0000111: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fld not supported 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flq not supported 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flh not supported - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b0100111: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsd not supported 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsq not supported 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh - else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsh not supported - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub From fc01f45c8036e15710bd677b7de7db291412d5cd Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 30 Mar 2023 13:07:39 -0700 Subject: [PATCH 32/56] fctrl continued cleanup --- src/fpu/fctrl.sv | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 337e00354..6e4166b16 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -126,18 +126,18 @@ module fctrl ( 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction +// default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b00101??: case(Funct3D) 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction + // default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b10100??: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle - default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction + // default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction endcase 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass @@ -153,8 +153,6 @@ module fctrl ( ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) - // *** other formats here - /* verilator lint_off CASEINCOMPLETE */ 7'b1101000: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s @@ -204,12 +202,12 @@ module fctrl ( 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu endcase - default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction +// default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase // default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase end - /* verilator lint_off CASEINCOMPLETE */ + /* verilator lint_on CASEINCOMPLETE */ // unswizzle control bits assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD} = ControlsD; From a4ae1b9cbb5364d70ef1919a03a9aaea2b1e5619 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 30 Mar 2023 13:17:15 -0700 Subject: [PATCH 33/56] fctrl updated and buildroot working again --- src/fpu/fctrl.sv | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 6e4166b16..ad58f44fd 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -126,18 +126,15 @@ module fctrl ( 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx -// default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b00101??: case(Funct3D) 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax - // default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase 7'b10100??: case(Funct3D) 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle - // default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction endcase 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass @@ -202,9 +199,7 @@ module fctrl ( 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu endcase -// default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase -// default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction endcase end /* verilator lint_on CASEINCOMPLETE */ @@ -333,7 +328,5 @@ module fctrl ( flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW, {FRegWriteM, FResSelM, FCvtIntM}, {FRegWriteW, FResSelW, FCvtIntW}); - - //assign FCvtIntW = (FResSelW == 2'b01); - + endmodule \ No newline at end of file From 25cd1cc432f0af788ed94c1638d2cab0e1e61b4f Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 30 Mar 2023 14:56:19 -0700 Subject: [PATCH 34/56] Started factoring out InstrValidNotFlushed from CSRs --- src/privileged/csr.sv | 8 ++++++-- src/privileged/csrs.sv | 1 - src/privileged/csru.sv | 5 ++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index f44785287..605c4fb24 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -106,6 +106,7 @@ module csr #(parameter logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM; + logic GatedCSRMWriteM, GatedCSRSWriteM, GatedCSRUWriteM; logic WriteFRMM, WriteFFLAGSM; logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; logic [4:0] NextCauseM; @@ -200,8 +201,11 @@ module csr #(parameter assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[`XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; assign CSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE); - assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW); - assign CSRUWriteM = CSRWriteM; + assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; + assign CSRUWriteM = CSRWriteM & InstrValidNotFlushedM; + assign GatedCSRMWriteM = CSRMWriteM & InstrValidNotFlushedM; +// assign GatedCSRSWriteM = CSRSWriteM & InstrValidNotFlushedM; +// assign GatedCSRUWriteM = CSRUWriteM & InstrValidNotFlushedM; assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index f6d02fe14..c94abf6fe 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -77,7 +77,6 @@ module csrs #(parameter logic [63:0] STIMECMP_REGW; // write enables - // *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM? assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM; assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM; assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM; diff --git a/src/privileged/csru.sv b/src/privileged/csru.sv index d8c405cb5..e474e5967 100644 --- a/src/privileged/csru.sv +++ b/src/privileged/csru.sv @@ -51,9 +51,8 @@ module csru #(parameter logic SetOrWriteFFLAGSM; // Write enables - //assign WriteFCSRM = CSRUWriteM & (CSRAdrM == FCSR) & InstrValidNotFlushedM; - assign WriteFRMM = (CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FRM | CSRAdrM == FCSR)) & InstrValidNotFlushedM; - assign WriteFFLAGSM = (CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FFLAGS | CSRAdrM == FCSR)) & InstrValidNotFlushedM; + assign WriteFRMM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FRM | CSRAdrM == FCSR); + assign WriteFFLAGSM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FFLAGS | CSRAdrM == FCSR); // Write Values assign NextFRMM = (CSRAdrM == FCSR) ? CSRWriteValM[7:5] : CSRWriteValM[2:0]; From 77d5f1c81b7374ee5d589b089cf3d35f345e9838 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 30 Mar 2023 17:06:09 -0700 Subject: [PATCH 35/56] Refactored InstrValidNotFlushed into CSR Write signals --- src/privileged/csr.sv | 16 +++++++--------- src/privileged/csri.sv | 9 ++++----- src/privileged/csrm.sv | 33 ++++++++++++++++----------------- src/privileged/csrs.sv | 21 ++++++++++----------- 4 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 605c4fb24..688218b7b 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -106,7 +106,7 @@ module csr #(parameter logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM; - logic GatedCSRMWriteM, GatedCSRSWriteM, GatedCSRUWriteM; + logic UngatedCSRMWriteM; logic WriteFRMM, WriteFFLAGSM; logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; logic [4:0] NextCauseM; @@ -200,12 +200,10 @@ module csr #(parameter assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[`XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; - assign CSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE); + assign UngatedCSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE); + assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM; assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; assign CSRUWriteM = CSRWriteM & InstrValidNotFlushedM; - assign GatedCSRMWriteM = CSRMWriteM & InstrValidNotFlushedM; -// assign GatedCSRSWriteM = CSRSWriteM & InstrValidNotFlushedM; -// assign GatedCSRUWriteM = CSRUWriteM & InstrValidNotFlushedM; assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; @@ -213,7 +211,7 @@ module csr #(parameter // CSRs /////////////////////////////////////////// - csri csri(.clk, .reset, .InstrValidNotFlushedM, + csri csri(.clk, .reset, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, .MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); @@ -227,8 +225,8 @@ module csr #(parameter .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM, .STATUS_FS, .BigEndianM); - csrm csrm(.clk, .reset, .InstrValidNotFlushedM, - .CSRMWriteM, .MTrapM, .CSRAdrM, + csrm csrm(.clk, .reset, + .UngatedCSRMWriteM, .CSRMWriteM, .MTrapM, .CSRAdrM, .NextEPCM, .NextCauseM, .NextMtvalM, .MSTATUS_REGW, .MSTATUSH_REGW, .CSRWriteValM, .CSRMReadValM, .MTVEC_REGW, .MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW, @@ -238,7 +236,7 @@ module csr #(parameter if (`S_SUPPORTED) begin:csrs - csrs csrs(.clk, .reset, .InstrValidNotFlushedM, + csrs csrs(.clk, .reset, .CSRSWriteM, .STrapM, .CSRAdrM, .NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW, .STATUS_TVM, .MCOUNTEREN_TM(MCOUNTEREN_REGW[1]), diff --git a/src/privileged/csri.sv b/src/privileged/csri.sv index a6fddbd0e..0a62b2174 100644 --- a/src/privileged/csri.sv +++ b/src/privileged/csri.sv @@ -35,7 +35,6 @@ module csri #(parameter SIE = 12'h104, SIP = 12'h144) ( input logic clk, reset, - input logic InstrValidNotFlushedM, input logic CSRMWriteM, CSRSWriteM, input logic [`XLEN-1:0] CSRWriteValM, input logic [11:0] CSRAdrM, @@ -50,10 +49,10 @@ module csri #(parameter logic STIP; // Interrupt Write Enables - assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM; - assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE) & InstrValidNotFlushedM; - assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & InstrValidNotFlushedM; - assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & InstrValidNotFlushedM; + assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP); + assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE); + assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP); + assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE); // Interrupt Pending and Enable Registers // MEIP, MTIP, MSIP are read-only diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index e8a42773d..f0e5f00db 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -73,8 +73,7 @@ module csrm #(parameter MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable ) ( input logic clk, reset, - input logic InstrValidNotFlushedM, - input logic CSRMWriteM, MTrapM, + input logic UngatedCSRMWriteM, CSRMWriteM, MTrapM, input logic [11:0] CSRAdrM, input logic [`XLEN-1:0] NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW, input logic [4:0] NextCauseM, @@ -112,13 +111,13 @@ module csrm #(parameter else assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01); - assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & InstrValidNotFlushedM & ~ADDRLocked[i]; + assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~ADDRLocked[i]; flopenr #(`PA_BITS-2) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM[`PA_BITS-3:0], PMPADDR_ARRAY_REGW[i]); if (`XLEN==64) begin - assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & InstrValidNotFlushedM & ~CFGLocked[i]; + assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~CFGLocked[i]; flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%8)*8+7:(i%8)*8], PMPCFG_ARRAY_REGW[i]); end else begin - assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & InstrValidNotFlushedM & ~CFGLocked[i]; + assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~CFGLocked[i]; flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%4)*8+7:(i%4)*8], PMPCFG_ARRAY_REGW[i]); end end @@ -133,19 +132,19 @@ module csrm #(parameter assign MHARTID_REGW = 0; // Write machine Mode CSRs - assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS) & InstrValidNotFlushedM; - assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH) & InstrValidNotFlushedM & (`XLEN==32); - assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC) & InstrValidNotFlushedM; - assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG) & InstrValidNotFlushedM; - assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG) & InstrValidNotFlushedM; - assign WriteMSCRATCHM = CSRMWriteM & (CSRAdrM == MSCRATCH) & InstrValidNotFlushedM; - assign WriteMEPCM = MTrapM | (CSRMWriteM & (CSRAdrM == MEPC)) & InstrValidNotFlushedM; - assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE)) & InstrValidNotFlushedM; - assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)) & InstrValidNotFlushedM; - assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN) & InstrValidNotFlushedM; - assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT) & InstrValidNotFlushedM; + assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS); + assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH)& (`XLEN==32); + assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC); + assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG); + assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG); + assign WriteMSCRATCHM = CSRMWriteM & (CSRAdrM == MSCRATCH); + assign WriteMEPCM = MTrapM | (CSRMWriteM & (CSRAdrM == MEPC)); + assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE)); + assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); + assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); + assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT); - assign IllegalCSRMWriteReadonlyM = CSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID); + assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID); // CSRs flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index c94abf6fe..e085232a6 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -45,7 +45,6 @@ module csrs #(parameter STIMECMPH = 12'h15D, SATP = 12'h180) ( input logic clk, reset, - input logic InstrValidNotFlushedM, input logic CSRSWriteM, STrapM, input logic [11:0] CSRAdrM, input logic [`XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW, @@ -77,16 +76,16 @@ module csrs #(parameter logic [63:0] STIMECMP_REGW; // write enables - assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM; - assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC) & InstrValidNotFlushedM; - assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH) & InstrValidNotFlushedM; - assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC)) & InstrValidNotFlushedM; - assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE)) & InstrValidNotFlushedM; - assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)) & InstrValidNotFlushedM; - assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM) & InstrValidNotFlushedM; - assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN) & InstrValidNotFlushedM; - assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & InstrValidNotFlushedM; - assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & (`XLEN == 32) & InstrValidNotFlushedM; + assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS); + assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC); + assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH); + assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC)); + assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE)); + assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)); + assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == `M_MODE | ~STATUS_TVM); + assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN); + assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM); + assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM) & (`XLEN == 32); // CSRs flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); From 64f15d48de1e04cf0de335299a8b2582cb3c99d0 Mon Sep 17 00:00:00 2001 From: Marcus Mellor Date: Thu, 30 Mar 2023 19:44:55 -0500 Subject: [PATCH 36/56] Disable coverage for branches tested in fpu.s --- src/fpu/fctrl.sv | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index ad9007014..feb2034ef 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -146,11 +146,13 @@ module fctrl ( ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + // coverage off 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) - 7'b1101000: case(Rs2D) + // coverage on + 7'b1101000: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s @@ -174,6 +176,7 @@ module fctrl ( 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase + // coverage off 7'b1101010: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h @@ -197,7 +200,8 @@ module fctrl ( 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase + endcase + // coverage on endcase endcase /* verilator lint_off CASEINCOMPLETE */ From d8bbb4286e64cba857ccef9e9d9a29931d9ebe9c Mon Sep 17 00:00:00 2001 From: Marcus Mellor Date: Thu, 30 Mar 2023 20:01:11 -0500 Subject: [PATCH 37/56] Add comments to fpu.S indicating which lines of src/fpu/fctrl.sv are covered --- tests/coverage/fpu.S | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 1a2d5ce7b..b93b75056 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -28,7 +28,7 @@ main: - bseti t0, zero, 14 # turn on FPU + #bseti t0, zero, 14 # turn on FPU csrs mstatus, t0 # Test legal instructions not covered elsewhere @@ -36,8 +36,12 @@ main: flh ft0, 8(a0) fsq ft0, 0(a0) fsh ft0, 8(a0) + + # Tests for fpu/fctrl.sv + ## The following cover lines 149 to 154 fcvt.h.s ft1, ft0 fcvt.q.s ft2, ft0 + ## The following cover lines 179 to 204 fcvt.h.w ft3, a0 fcvt.h.wu ft3, a0 fcvt.h.l ft3, a0 @@ -55,7 +59,6 @@ main: fcvt.l.q a0, ft3 fcvt.lu.q a0, ft3 - # Test illegal instructions are detected .word 0x00000007 // illegal floating-point load (bad Funct3) .word 0x00000027 // illegal floating-point store (bad Funct3) From 97181e063b85107d0a3ed20b2496a4f3544f8a86 Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Thu, 30 Mar 2023 19:15:33 -0700 Subject: [PATCH 38/56] only pass in relevant comparator flag to ALU --- src/ieu/alu.sv | 4 ++-- src/ieu/bmu/bitmanipalu.sv | 4 ++-- src/ieu/datapath.sv | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index c4e0f3906..4db187e54 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -37,7 +37,7 @@ module alu #(parameter WIDTH=32) ( input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] Funct3, // For BMU decoding - input logic [1:0] CompFlags, // Comparator flags + input logic CompLT, // Less-Than flag from comparator input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage output logic [WIDTH-1:0] Result, // ALU result output logic [WIDTH-1:0] Sum); // Sum of operands @@ -90,7 +90,7 @@ module alu #(parameter WIDTH=32) ( // Final Result B instruction select mux if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, - .Funct3, .CompFlags, .BALUControl, .ALUResult, .FullResult, + .Funct3, .CompLT, .BALUControl, .ALUResult, .FullResult, .CondMaskB, .CondShiftA, .Result); end else begin assign Result = ALUResult; diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 4841f7dd1..ae71db7b9 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -35,7 +35,7 @@ module bitmanipalu #(parameter WIDTH=32) ( input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform - input logic [1:0] CompFlags, // Comparator flags + input logic CompLT, // Less-Than flag from comparator input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [WIDTH-1:0] ALUResult, FullResult, // ALUResult, FullResult signals output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions @@ -84,7 +84,7 @@ module bitmanipalu #(parameter WIDTH=32) ( // ZBB Unit if (`ZBB_SUPPORTED) begin: zbb - zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .lt(CompFlags[0]), .ZBBSelect, .ZBBResult); + zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .lt(CompLT), .ZBBSelect, .ZBBResult); end else assign ZBBResult = 0; // Result Select Mux diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index a48b39402..19d1264a9 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -114,7 +114,7 @@ module datapath ( comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); - alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE); + alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE[0], BALUControlE, ALUResultE, IEUAdrE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); From 913cdecb65d5bb97fb5516e66e2eec428fc4b74d Mon Sep 17 00:00:00 2001 From: Marcus Mellor Date: Fri, 31 Mar 2023 09:51:33 -0500 Subject: [PATCH 39/56] Address comments in openhwgroup/cvw#180 --- src/fpu/fctrl.sv | 2 ++ tests/coverage/fpu.S | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index feb2034ef..9db3d670e 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -147,6 +147,7 @@ module fctrl ( 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) // coverage off + // Not covered in testing because rv64gc does not support half or quad precision 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) @@ -177,6 +178,7 @@ module fctrl ( 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase // coverage off + // Not covered in testing because rv64gc does not support half or quad precision 7'b1101010: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index b93b75056..3fdca6e84 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -38,10 +38,8 @@ main: fsh ft0, 8(a0) # Tests for fpu/fctrl.sv - ## The following cover lines 149 to 154 fcvt.h.s ft1, ft0 fcvt.q.s ft2, ft0 - ## The following cover lines 179 to 204 fcvt.h.w ft3, a0 fcvt.h.wu ft3, a0 fcvt.h.l ft3, a0 From 820e3513c7a0d77060751b6b9ee4fc066869265c Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 08:32:02 -0700 Subject: [PATCH 40/56] Privilege test improvements --- tests/coverage/priv.S | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 3aa3aea5c..008d06be6 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -36,4 +36,30 @@ main: addi t0, zero, 0 csrr t0, stimecmp + # CSR coverage + csrw scause, zero + csrw stval, zero + csrw scounteren, zero + csrw satp, zero + + # satp write with mstatus.TVM = 1 + bseti t0, zero, 20 + csrs mstatus, t0 + csrw satp, zero + + # STIMECMP from S mode + li t0, 1 + ecall # enter S-mode + csrw stimecmp, zero + li t0, 3 + ecall # return to M-mode + csrsi mcounteren, 2 # mcounteren_tm = 1 + li t0, 1 + ecall # supervisor mode again + csrw stimecmp, zero + li t0, 3 + ecall # machine mode again + + + j done From b95730e3a16f18faa9958774e88d4d51a9cb2ccf Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 08:33:46 -0700 Subject: [PATCH 41/56] Coverage improvements in ieu, hazard units --- sim/coverage-exclusions-rv64gc.do | 6 +++++- src/hazard/hazard.sv | 2 ++ src/ieu/bmu/bmuctrl.sv | 6 ++++-- src/ieu/controller.sv | 2 ++ src/lsu/lsu.sv | 2 +- src/privileged/csr.sv | 2 +- 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index 9905c897b..d58e4c514 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -24,8 +24,12 @@ #// and limitations under the License. #//////////////////////////////////////////////////////////////////////////////////////////////// +# This file should be a last resort. It's preferable to put +# // coverage off +# statements inline with the code whenever possible. + # LZA (i<64) statement confuses coverage tool -# This is ugly to exlcude the whole file - is there a better option +# This is ugly to exlcude the whole file - is there a better option? // coverage off isn't working coverage exclude -srcfile lzc.sv diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index cf3a22c1f..bc9f7baa0 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -88,7 +88,9 @@ module hazard ( assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled + // coverage off: StallFCause is always 0 assign #1 StallF = StallFCause | StallD; + // coverage on assign #1 StallD = StallDCause | StallE; assign #1 StallE = StallECause | StallM; assign #1 StallM = StallMCause | StallW; diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 90d031a14..0bfbfeb49 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -101,8 +101,10 @@ module bmuctrl( BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // sign extend instruction else if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) BMUControlsD = `BMUCTRLW'b000_10_000_1_1_0_1_0_0_0_0_0; // count instruction - 17'b0110011_0000100_100: if (`XLEN == 32) - BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) +// // coverage off: This case can't occur in RV64 +// 17'b0110011_0000100_100: if (`XLEN == 32) +// BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) +// // coverage on 17'b0110011_0100000_111: BMUControlsD = `BMUCTRLW'b111_01_111_1_0_0_1_1_0_0_0_0; // andn 17'b0110011_0100000_110: BMUControlsD = `BMUCTRLW'b110_01_111_1_0_0_1_1_0_0_0_0; // orn 17'b0110011_0100000_100: BMUControlsD = `BMUCTRLW'b100_01_111_1_0_0_1_1_0_0_0_0; // xnor diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 5d0b78457..2174b96c3 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -264,7 +264,9 @@ module controller( end else assign sltD = (Funct3D == 3'b010); // Combine base and bit manipulation signals + // coverage off: IllegalERegAdr can't occur in rv64gc; only applicable to E mode assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; + // coverage on assign RegWriteD = BaseRegWriteD | BRegWriteD; assign W64D = BaseW64D | BW64D; assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD; diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 0b0bc81e3..f2e147f00 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -149,7 +149,7 @@ module lsu ( // MMU include PMP and is needed if any privileged supported ///////////////////////////////////////////////////////////////////////////////////////////// - if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED + if(`VIRTMEM_SUPPORTED) begin : hptw hptw hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF, .DTLBMissM, .DTLBWriteM, .InstrUpdateDAF, .DataUpdateDAM, .FlushW, .DCacheStallM, .SATP_REGW, .PCSpillF, diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 688218b7b..db142de5f 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -202,7 +202,7 @@ module csr #(parameter assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; assign UngatedCSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE); assign CSRMWriteM = UngatedCSRMWriteM & InstrValidNotFlushedM; - assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; + assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW) & InstrValidNotFlushedM; assign CSRUWriteM = CSRWriteM & InstrValidNotFlushedM; assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; From e5653ff3515ff2b6ab6c36fc09d57606a5355619 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 08:37:16 -0700 Subject: [PATCH 42/56] Merged privileged test --- tests/coverage/priv.S | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 0d59a2555..008d06be6 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -36,7 +36,6 @@ main: addi t0, zero, 0 csrr t0, stimecmp -<<<<<<< HEAD # CSR coverage csrw scause, zero csrw stval, zero @@ -63,13 +62,4 @@ main: -======= - # Test write to STVAL, SCAUSE, SEPC, and STIMECMP CSRs - li t0, 0 - csrw stval, t0 - csrw scause, t0 - csrw sepc, t0 - csrw stimecmp, t0 - ->>>>>>> 37d289cf44530c3e3a6f53e54b06e6eda7f0c3c1 j done From 0ccfdde30e21218550688a4af807f2e1e2d40b2d Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 09:15:15 -0700 Subject: [PATCH 43/56] Regression update --- sim/regression-wally | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sim/regression-wally b/sim/regression-wally index 7a509c890..045d7b947 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -49,6 +49,7 @@ configs = [ ] def getBuildrootTC(boot): INSTR_LIMIT = 4000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM +# INSTR_LIMIT = 8000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM MAX_EXPECTED = 246000000 # *** TODO: replace this with a search for the login prompt. if boot: name="buildrootboot" @@ -56,7 +57,12 @@ def getBuildrootTC(boot): BRgrepstr="WallyHostname login:" else: name="buildroot" - BRcmd="vsim > {} -c < {} -c < {} -c < Date: Fri, 31 Mar 2023 09:59:38 -0700 Subject: [PATCH 44/56] regression cleanup; unable to run buildroot coverage because of different config file --- sim/Makefile | 3 ++- sim/imperas.ic | 4 ++-- sim/regression-wally | 17 +++++------------ sim/wally-batch.do | 13 ++++++++++--- tests/coverage/ieu.S | 6 ++++++ 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/sim/Makefile b/sim/Makefile index 540c9418f..9cf3f0034 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -18,7 +18,8 @@ all: riscoftests memfiles coveragetests coverage: #make -C ../tests/coverage --jobs #iter-elf.bash --cover --search ../tests/coverage - vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb riscv.ucdb -logfile cov/log + vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb cov/buildroot_buildroot.ucdb riscv.ucdb -logfile cov/log +# vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb riscv.ucdb /home/rthompson/buildroot_buildroot-no-trace.ucdb -logfile cov/log vcover report -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt vcover report cov/cov.ucdb -details -instance=/core/ebu. > cov/rv64gc_coverage_ebu.rpt vcover report cov/cov.ucdb -details -instance=/core/priv. > cov/rv64gc_coverage_priv.rpt diff --git a/sim/imperas.ic b/sim/imperas.ic index 167c0cc44..fe8220399 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -6,7 +6,7 @@ # Core settings --override cpu/unaligned=F --override cpu/ignore_non_leaf_DAU=1 ---override cpu/wfi_is_nop=T +#--override cpu/wfi_is_nop=T --override cpu/mimpid=0x100 --override cpu/misa_Extensions_mask=0x0 @@ -49,7 +49,7 @@ # Add Imperas simulator application instruction tracing --override cpu/show_c_prefix=T ---trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 10500000 +--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 800000 # Exceptions and pagetables debug --override cpu/debugflags=6 diff --git a/sim/regression-wally b/sim/regression-wally index 045d7b947..c70177206 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -49,7 +49,6 @@ configs = [ ] def getBuildrootTC(boot): INSTR_LIMIT = 4000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM -# INSTR_LIMIT = 8000000 # multiple of 100000; 4M is interesting because it gets into the kernel and enabling VM MAX_EXPECTED = 246000000 # *** TODO: replace this with a search for the login prompt. if boot: name="buildrootboot" @@ -182,8 +181,6 @@ def main(): try: os.chdir(regressionDir) os.mkdir("logs") - #print(os.getcwd()) - #print(regressionDir) except: pass try: @@ -204,9 +201,11 @@ def main(): TIMEOUT_DUR = 30*7200 # seconds configs=[getBuildrootTC(boot=True)] elif '-coverage' in sys.argv: - TIMEOUT_DUR = 20*60 # seconds - configs.append(getBuildrootTC(boot=False)) - os.system('rm cov/*.ucdb') + TIMEOUT_DUR = 20*60 # seconds + # Presently don't run buildroot because it has a different config and can't be merged with the rv64gc coverage. + # Also it is slow to run. + # configs.append(getBuildrootTC(boot=False)) + os.system('rm -f cov/*.ucdb') else: TIMEOUT_DUR = 10*60 # seconds configs.append(getBuildrootTC(boot=False)) @@ -228,12 +227,6 @@ def main(): # Coverage report if coverage: os.system('make coverage') - #print('Generating coverage report') - #os.system('vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log') - #os.system('vcover report -details cov/cov.ucdb > cov/rv64gc_coverage_details.rpt') - #os.system('vcover report -below 100 cov/cov.ucdb > cov/rv64gc_coverage.rpt') - #os.system('vcover report -recursive cov/cov.ucdb > cov/rv64gc_recursive.rpt') - #os.system('vcover report -details -threshH 100 -html cov/cov.ucdb') # Count the number of failures if num_fail: print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 7815e94fc..df49518c1 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -46,7 +46,7 @@ mkdir -p cov # Check if measuring coverage set coverage 0 if {$argc >= 3} { - if {$3 eq "-coverage"} { + if {$3 eq "-coverage" || ($argc >= 7 && $7 eq "-coverage")} { set coverage 1 } } @@ -61,8 +61,14 @@ if {$argc >= 3} { if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 # start and run simulation - vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt - vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 + if { $coverage } { + echo "wally-batch buildroot coverage" + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt +cover=sbecf + vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 -cover + } else { + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -o testbenchopt + vsim -lib wkdir/work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3691,13286 -fatal 7 + } run -all run -all @@ -139,6 +145,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { } if {$coverage} { + echo "Saving coverage to ${1}_${2}.ucdb" do coverage-exclusions-rv64gc.do # beware: this assumes testing the rv64gc configuration coverage save -instance /testbench/dut/core cov/${1}_${2}.ucdb } diff --git a/tests/coverage/ieu.S b/tests/coverage/ieu.S index e1b239371..3fd56686f 100644 --- a/tests/coverage/ieu.S +++ b/tests/coverage/ieu.S @@ -28,6 +28,11 @@ main: + # Division test (having trouble with buildroot) + li x11, 0x384000 + li x12, 0x1c2000 + divuw x9, x11, x12 + # Test clz with all bits being 0 li t0, 0 clz t1, t0 @@ -61,5 +66,6 @@ main: .word 0x6080101B // Illegal BMU similar to count word .word 0x6030101B // Illegal BMU similar to count word + j done From 800fdeb7ad6156651d5f3a5a5415dd2df7970826 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 31 Mar 2023 10:54:03 -0700 Subject: [PATCH 45/56] Added SSTC support to imperas.ic and wallyTracer. Fixes many of the privileged tests --- sim/imperas.ic | 10 +++++++++- testbench/common/wallyTracer.sv | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index fe8220399..beadba6fa 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -10,10 +10,15 @@ --override cpu/mimpid=0x100 --override cpu/misa_Extensions_mask=0x0 -# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=16 --override cpu/PMP_undefined=T +# Wally-specific non-default configuraiton +--override refRoot/cpu/Sstc=T +# Zba doesn't seem to exist - Lee is finding the name +#--override refRoot/cpu/Zba=T + + # Illegal instruction should not contain the bit pattern # illegal pmp read contained this # --override cpu/tval_ii_code=F @@ -47,8 +52,11 @@ #-override refRoot/cpu/cv/cover=basic #-override refRoot/cpu/cv/extensions=RV32I + + # Add Imperas simulator application instruction tracing --override cpu/show_c_prefix=T + --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 800000 # Exceptions and pagetables debug diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index 4df1956ad..221c8d7f8 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -162,6 +162,7 @@ module wallyTracer(rvviTrace rvvi); CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; + CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // user CSRs CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW; @@ -211,6 +212,7 @@ module wallyTracer(rvviTrace rvvi); CSRArray[12'h143] = CSRArrayOld[12'h143]; CSRArray[12'h142] = CSRArrayOld[12'h142]; CSRArray[12'h144] = CSRArrayOld[12'h144]; + CSRArray[12'h14D] = CSRArrayOld[12'h14D]; // user CSRs CSRArray[12'h001] = CSRArrayOld[12'h001]; CSRArray[12'h002] = CSRArrayOld[12'h002]; @@ -329,6 +331,7 @@ module wallyTracer(rvviTrace rvvi); CSRArrayOld[12'h143] = CSRArray[12'h143]; CSRArrayOld[12'h142] = CSRArray[12'h142]; CSRArrayOld[12'h144] = CSRArray[12'h144]; + CSRArrayOld[12'h14D] = CSRArray[12'h14D]; // user CSRs CSRArrayOld[12'h001] = CSRArray[12'h001]; CSRArrayOld[12'h002] = CSRArray[12'h002]; @@ -376,6 +379,7 @@ module wallyTracer(rvviTrace rvvi); assign #2 CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0; assign #2 CSR_W[12'h142] = (CSRArrayOld[12'h142] != CSRArray[12'h142]) ? 1 : 0; assign #2 CSR_W[12'h144] = (CSRArrayOld[12'h144] != CSRArray[12'h144]) ? 1 : 0; + assign #2 CSR_W[12'h14D] = (CSRArrayOld[12'h14D] != CSRArray[12'h14D]) ? 1 : 0; assign #2 CSR_W[12'h001] = (CSRArrayOld[12'h001] != CSRArray[12'h001]) ? 1 : 0; assign #2 CSR_W[12'h002] = (CSRArrayOld[12'h002] != CSRArray[12'h002]) ? 1 : 0; assign #2 CSR_W[12'h003] = (CSRArrayOld[12'h003] != CSRArray[12'h003]) ? 1 : 0; @@ -412,6 +416,7 @@ module wallyTracer(rvviTrace rvvi); assign rvvi.csr_wb[0][0][12'h143] = CSR_W[12'h143]; assign rvvi.csr_wb[0][0][12'h142] = CSR_W[12'h142]; assign rvvi.csr_wb[0][0][12'h144] = CSR_W[12'h144]; + assign rvvi.csr_wb[0][0][12'h14D] = CSR_W[12'h14D]; assign rvvi.csr_wb[0][0][12'h001] = CSR_W[12'h001]; assign rvvi.csr_wb[0][0][12'h002] = CSR_W[12'h002]; assign rvvi.csr_wb[0][0][12'h003] = CSR_W[12'h003]; @@ -448,6 +453,7 @@ module wallyTracer(rvviTrace rvvi); assign rvvi.csr[0][0][12'h143] = CSRArray[12'h143]; assign rvvi.csr[0][0][12'h142] = CSRArray[12'h142]; assign rvvi.csr[0][0][12'h144] = CSRArray[12'h144]; + assign rvvi.csr[0][0][12'h14D] = CSRArray[12'h14D]; assign rvvi.csr[0][0][12'h001] = CSRArray[12'h001]; assign rvvi.csr[0][0][12'h002] = CSRArray[12'h002]; assign rvvi.csr[0][0][12'h003] = CSRArray[12'h003]; From 3815b7117b03502ef5a43a15208d5e1732cd4c7f Mon Sep 17 00:00:00 2001 From: Alexa Wright Date: Sat, 1 Apr 2023 16:02:23 -0700 Subject: [PATCH 46/56] Added tests for writing and reading to HPMCOUNTERM csrs --- tests/coverage/priv.S | 46 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/coverage/priv.S b/tests/coverage/priv.S index 8cd18925b..7382d331c 100644 --- a/tests/coverage/priv.S +++ b/tests/coverage/priv.S @@ -42,5 +42,49 @@ main: csrw scause, t0 csrw sepc, t0 csrw stimecmp, t0 - + + # Switch to machine mode + li a0, 3 + ecall + # Testing the HPMCOUNTERM performance counter: writing + # Base address is 2816 (MHPMCOUNTERBASE) + # There are 32 HPMCOUNTER registers + csrw 2816, t0 + csrw 2817, t0 + csrw 2818, t0 + csrw 2819, t0 + csrw 2820, t0 + csrw 2821, t0 + csrw 2822, t0 + csrw 2823, t0 + csrw 2824, t0 + csrw 2825, t0 + csrw 2826, t0 + csrw 2827, t0 + csrw 2828, t0 + csrw 2829, t0 + csrw 2830, t0 + csrw 2831, t0 + csrw 2832, t0 + csrw 2833, t0 + csrw 2834, t0 + csrw 2835, t0 + csrw 2836, t0 + csrw 2837, t0 + csrw 2838, t0 + csrw 2839, t0 + csrw 2840, t0 + csrw 2841, t0 + csrw 2842, t0 + csrw 2843, t0 + csrw 2844, t0 + csrw 2845, t0 + csrw 2846, t0 + csrw 2847, t0 + + # Testing the HPMCOUNTERM performance counter: reading + csrr t0, 2817 j done + + + From e3f3f1421673a7c0016ad81f936df7f61620ac58 Mon Sep 17 00:00:00 2001 From: James Stine Date: Sun, 2 Apr 2023 18:16:23 -0500 Subject: [PATCH 47/56] Update one bug in testfloat - still have to fix fpdiv but others should now all work --- testbench/testbench-fp.sv | 309 +++++++++++++++++++------------------- 1 file changed, 155 insertions(+), 154 deletions(-) diff --git a/testbench/testbench-fp.sv b/testbench/testbench-fp.sv index d1f6f9b63..f250e8035 100644 --- a/testbench/testbench-fp.sv +++ b/testbench/testbench-fp.sv @@ -1,7 +1,8 @@ -/////////////////////////////////////////// + 64 bit conversions to the to-be-tested list @@ -270,27 +270,27 @@ module testbenchfp; end if (`D_SUPPORTED) begin // if double precision is supported if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested - Tests = {Tests, f64rv32cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b01}; - end - if (`XLEN == 64) begin // if 64-bit integers are being supported - Tests = {Tests, f64rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - end + Tests = {Tests, f64rv32cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b01}; + end + if (`XLEN == 64) begin // if 64-bit integers are being supported + Tests = {Tests, f64rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + end if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested if(`F_SUPPORTED) begin // if single precision is supported // add the 64 <-> 32 bit conversions to the to-be-tested list @@ -397,27 +397,27 @@ module testbenchfp; end if (`F_SUPPORTED) begin // if single precision being supported if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested - Tests = {Tests, f32rv32cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b00}; - end - if (`XLEN == 64) begin // if 64-bit integers are supported - Tests = {Tests, f32rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - end + Tests = {Tests, f32rv32cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b00}; + end + if (`XLEN == 64) begin // if 64-bit integers are supported + Tests = {Tests, f32rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + end if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested if(`ZFH_SUPPORTED) begin // add the 32 <-> 16 bit conversions to the to-be-tested list @@ -508,27 +508,27 @@ module testbenchfp; end if (`ZFH_SUPPORTED) begin // if half precision supported if (TEST === "cvtint"| TEST === "all") begin // if in conversions are being tested - Tests = {Tests, f16rv32cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b10}; - end - if (`XLEN == 64) begin // if 64-bit integers are supported - Tests = {Tests, f16rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; - // add what unit is used and the fmt to their lists (one for each test) - for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - end + Tests = {Tests, f16rv32cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b10}; + end + if (`XLEN == 64) begin // if 64-bit integers are supported + Tests = {Tests, f16rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; + // add what unit is used and the fmt to their lists (one for each test) + for(int i = 0; i<20; i++) begin + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + end if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16cmp}; @@ -656,7 +656,8 @@ module testbenchfp; end // extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector - readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, + readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), + .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, .Xs, .Ys, .Zs, .Unit(UnitVal), .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), .Xm, .Ym, .Zm, .DivStart, @@ -680,7 +681,7 @@ module testbenchfp; /////////////////////////////////////////////////////////////////////////////////////////////// // instantiate devices under test - if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "all") begin : fma + if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma fma fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), .Xe(Xe), .Ye(Ye), .Ze(Ze), .Xm(Xm), .Ym(Ym), .Zm(Zm), @@ -1331,4 +1332,4 @@ module readvectors ( .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, .XEn, .YEn, .ZEn, .XExpMax); -endmodule \ No newline at end of file +endmodule From 9a4fa6ce96b5410ebbea2202f73557457f054372 Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Sun, 2 Apr 2023 18:28:09 -0700 Subject: [PATCH 48/56] changed signal names on clmul and zbc to match book --- src/ieu/bmu/clmul.sv | 10 +++++----- src/ieu/bmu/zbc.sv | 15 ++++++--------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/ieu/bmu/clmul.sv b/src/ieu/bmu/clmul.sv index 904c64238..cf3e1c6b1 100644 --- a/src/ieu/bmu/clmul.sv +++ b/src/ieu/bmu/clmul.sv @@ -30,20 +30,20 @@ `include "wally-config.vh" module clmul #(parameter WIDTH=32) ( - input logic [WIDTH-1:0] A, B, // Operands + input logic [WIDTH-1:0] X, Y, // Operands output logic [WIDTH-1:0] ClmulResult); // ZBS result - logic [(WIDTH*WIDTH)-1:0] s; // intermediary signals for carry-less multiply + logic [(WIDTH*WIDTH)-1:0] S; // intermediary signals for carry-less multiply integer i,j; always_comb begin for (i=0;i Date: Sun, 2 Apr 2023 18:42:41 -0700 Subject: [PATCH 49/56] signal renaming on bitmanip alu and alu --- src/ieu/alu.sv | 14 +++++++------- src/ieu/bmu/bitmanipalu.sv | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 4db187e54..9dfb6ae65 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -39,12 +39,12 @@ module alu #(parameter WIDTH=32) ( input logic [2:0] Funct3, // For BMU decoding input logic CompLT, // Less-Than flag from comparator input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage - output logic [WIDTH-1:0] Result, // ALU result + output logic [WIDTH-1:0] ALUResult, // ALU result output logic [WIDTH-1:0] Sum); // Sum of operands // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction. - logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, ALUResult; // Intermediate Signals + logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, PreALUResult; // Intermediate Signals logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux @@ -84,16 +84,16 @@ module alu #(parameter WIDTH=32) ( end // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits - if (WIDTH == 64) assign ALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; - else assign ALUResult = FullResult; + if (WIDTH == 64) assign PreALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; + else assign PreALUResult = FullResult; // Final Result B instruction select mux if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, - .Funct3, .CompLT, .BALUControl, .ALUResult, .FullResult, - .CondMaskB, .CondShiftA, .Result); + .Funct3, .CompLT, .BALUControl, .PreALUResult, .FullResult, + .CondMaskB, .CondShiftA, .ALUResult); end else begin - assign Result = ALUResult; + assign ALUResult = PreALUResult; assign CondMaskB = B; assign CondShiftA = A; end diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index ae71db7b9..7bc9055cf 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -37,10 +37,10 @@ module bitmanipalu #(parameter WIDTH=32) ( input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform input logic CompLT, // Less-Than flag from comparator input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage - input logic [WIDTH-1:0] ALUResult, FullResult, // ALUResult, FullResult signals + input logic [WIDTH-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions - output logic [WIDTH-1:0] Result); // Result + output logic [WIDTH-1:0] ALUResult); // Result logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result logic [WIDTH-1:0] MaskB; // BitMask of B @@ -91,9 +91,9 @@ module bitmanipalu #(parameter WIDTH=32) ( always_comb case (BSelect) // 00: ALU, 01: ZBA/ZBS, 10: ZBB, 11: ZBC - 2'b00: Result = ALUResult; - 2'b01: Result = FullResult; // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word. - 2'b10: Result = ZBBResult; - 2'b11: Result = ZBCResult; + 2'b00: ALUResult = PreALUResult; + 2'b01: ALUResult = FullResult; // NOTE: We don't use ALUResult because ZBA/ZBS instructions don't sign extend the MSB of the right-hand word. + 2'b10: ALUResult = ZBBResult; + 2'b11: ALUResult = ZBCResult; endcase endmodule From 5e7bbeddd1f49ec0093ec543a9f4385bf4d32b7e Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Sun, 2 Apr 2023 21:14:31 -0700 Subject: [PATCH 50/56] removed comparator flag to ALU --- src/ieu/alu.sv | 3 +-- src/ieu/bmu/bitmanipalu.sv | 5 +++-- src/ieu/bmu/bmuctrl.sv | 15 +++++---------- src/ieu/bmu/zbb.sv | 10 +++++++--- src/ieu/controller.sv | 7 ++----- src/ieu/datapath.sv | 2 +- 6 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 9dfb6ae65..43df83b60 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -37,7 +37,6 @@ module alu #(parameter WIDTH=32) ( input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] Funct3, // For BMU decoding - input logic CompLT, // Less-Than flag from comparator input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage output logic [WIDTH-1:0] ALUResult, // ALU result output logic [WIDTH-1:0] Sum); // Sum of operands @@ -90,7 +89,7 @@ module alu #(parameter WIDTH=32) ( // Final Result B instruction select mux if (`ZBC_SUPPORTED | `ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED) begin : bitmanipalu bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, - .Funct3, .CompLT, .BALUControl, .PreALUResult, .FullResult, + .Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult, .CondMaskB, .CondShiftA, .ALUResult); end else begin assign ALUResult = PreALUResult; diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 7bc9055cf..228b23132 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -35,7 +35,8 @@ module bitmanipalu #(parameter WIDTH=32) ( input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform - input logic CompLT, // Less-Than flag from comparator + input logic LT, // less than flag + input logic LTU, // less than unsigned flag input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [WIDTH-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions @@ -84,7 +85,7 @@ module bitmanipalu #(parameter WIDTH=32) ( // ZBB Unit if (`ZBB_SUPPORTED) begin: zbb - zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .lt(CompLT), .ZBBSelect, .ZBBResult); + zbb #(WIDTH) ZBB(.A, .RevA, .B, .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult); end else assign ZBBResult = 0; // Result Select Mux diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 90d031a14..3ddc32319 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -48,7 +48,6 @@ module bmuctrl( output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding output logic [2:0] ZBBSelectE, // ZBB mux select signal output logic BRegWriteE, // Indicates if it is a R type B instruction in Execute - output logic BComparatorSignedE, // Indicates if comparator signed in Execute Stage output logic [2:0] BALUControlE // ALU Control signals for B instructions in Execute Stage ); @@ -56,7 +55,6 @@ module bmuctrl( logic [2:0] Funct3D; // Funct3 field in Decode stage logic [6:0] Funct7D; // Funct7 field in Decode stage logic [4:0] Rs2D; // Rs2 source register in Decode stage - logic BComparatorSignedD; // Indicates if comparator signed (max, min instruction) in Decode Stage logic RotateD; // Indicates if rotate instruction in Decode Stage logic MaskD; // Indicates if zbs instruction in Decode Stage logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage @@ -110,10 +108,10 @@ module bmuctrl( BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // rev8 17'b0010011_0010100_101: if (Rs2D[4:0] == 5'b00111) BMUControlsD = `BMUCTRLW'b000_10_010_1_1_0_1_0_0_0_0_0; // orc.b - 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_0_0_0_0_0; // max - 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_0_0_0_0_0; // maxu - 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // min - 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_0_0_0_0_0; // minu + 17'b0110011_0000101_110: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_1_0_0_0_0; // max + 17'b0110011_0000101_111: BMUControlsD = `BMUCTRLW'b000_10_111_1_0_0_1_1_0_0_0_0; // maxu + 17'b0110011_0000101_100: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // min + 17'b0110011_0000101_101: BMUControlsD = `BMUCTRLW'b000_10_011_1_0_0_1_1_0_0_0_0; // minu endcase if (`XLEN==32) casez({OpD, Funct7D, Funct3D}) @@ -172,12 +170,9 @@ module bmuctrl( // Pack BALUControl Signals assign BALUControlD = {RotateD, MaskD, PreShiftD}; - // Comparator should perform signed comparison when min/max instruction. We have overlap in funct3 with some branch instructions so we use opcode to differentiate betwen min/max and branches - assign BComparatorSignedD = (Funct3D[2]^Funct3D[0]) & ~OpD[6]; - // Choose ALUSelect brom BMU for BMU operations, Funct3 for IEU operations, or 0 for addition assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); // BMU Execute stage pipieline control register - flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE}); + flopenrc#(9) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BALUControlE}); endmodule diff --git a/src/ieu/bmu/zbb.sv b/src/ieu/bmu/zbb.sv index a85114b55..1a1b9de24 100644 --- a/src/ieu/bmu/zbb.sv +++ b/src/ieu/bmu/zbb.sv @@ -33,21 +33,25 @@ module zbb #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, RevA, B, // Operands input logic W64, // Indicates word operation - input logic lt, // lt flag + input logic LT, // lt flag + input logic LTU, // ltu flag + input logic BUnsigned, // max/min (signed) flag input logic [2:0] ZBBSelect, // ZBB Result select signal output logic [WIDTH-1:0] ZBBResult); // ZBB result - + + logic lt; // lt given signed/unsigned logic [WIDTH-1:0] CntResult; // count result logic [WIDTH-1:0] MinMaxResult; // min, max result logic [WIDTH-1:0] ByteResult; // byte results logic [WIDTH-1:0] ExtResult; // sign/zero extend results + mux2 #(1) ltmux(LT, LTU, BUnsigned , lt); cnt #(WIDTH) cnt(.A, .RevA, .B(B[1:0]), .W64, .CntResult); byteUnit #(WIDTH) bu(.A, .ByteSelect(B[0]), .ByteResult); ext #(WIDTH) ext(.A, .ExtSelect({~B[2], {B[2] & B[0]}}), .ExtResult); // ZBBSelect[2] differentiates between min(u) vs max(u) instruction - mux2 #(WIDTH) minmaxmux(B, A, lt^ZBBSelect[2], MinMaxResult); + mux2 #(WIDTH) minmaxmux(B, A, ZBBSelect[2]^lt, MinMaxResult); // ZBB Result select mux mux4 #(WIDTH) zbbresultmux(CntResult, ExtResult, ByteResult, MinMaxResult, ZBBSelect[1:0], ZBBResult); diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 5d0b78457..780316175 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -125,7 +125,6 @@ module controller( logic IntDivM; // Integer divide instruction logic [1:0] BSelectD; // One-Hot encoding if it's ZBA_ZBB_ZBC_ZBS instruction in decode stage logic [2:0] ZBBSelectD; // ZBB Mux Select Signal - logic BComparatorSignedE; // Indicates if max, min (signed comarison) instruction in Execute Stage logic IFunctD, RFunctD, MFunctD; // Detect I, R, and M-type RV32IM/Rv64IM instructions logic LFunctD, SFunctD, BFunctD; // Detect load, store, branch instructions logic JFunctD; // detect jalr instruction @@ -257,7 +256,7 @@ module controller( bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD, .BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, - .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE); + .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BALUControlE); if (`ZBA_SUPPORTED) begin // ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw assign sltD = (Funct3D == 3'b010 & (~(Funct7D[4]) | ~OpD[5])) ; @@ -283,7 +282,6 @@ module controller( assign BSelectE = 2'b00; assign BSelectD = 2'b00; assign ZBBSelectE = 3'b000; - assign BComparatorSignedE = 1'b0; assign BALUControlE = 3'b0; end @@ -311,8 +309,7 @@ module controller( // Branch Logic // The comparator handles both signed and unsigned branches using BranchSignedE // Hence, only eq and lt flags are needed - // We also want comparator to handle signed comparison on a max/min bitmanip instruction - assign BranchSignedE = (~(Funct3E[2:1] == 2'b11) & BranchE) | BComparatorSignedE; + assign BranchSignedE = (~(Funct3E[2:1] == 2'b11) & BranchE); assign {eqE, ltE} = FlagsE; mux2 #(1) branchflagmux(eqE, ltE, Funct3E[2], BranchFlagE); assign BranchTakenE = BranchFlagE ^ Funct3E[0]; diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index 19d1264a9..d6fe92a2a 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -114,7 +114,7 @@ module datapath ( comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); - alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE[0], BALUControlE, ALUResultE, IEUAdrE); + alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, ALUResultE, IEUAdrE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); From 440e41bb3e32cebeec411cdaa92fab2671bc66f0 Mon Sep 17 00:00:00 2001 From: Sydney Riley Date: Sun, 2 Apr 2023 23:51:34 -0700 Subject: [PATCH 51/56] expanded ifu coverage including 4 added directed tests and 1 exclusion, expanded fpu coverage including 6 directed tests and 2 multiline exclusions. --- src/fpu/fctrl.sv | 9 ++++++++- src/ifu/decompress.sv | 6 ++++++ tests/coverage/fpu.S | 18 +++++++++++++++++- tests/coverage/ifu.S | 19 ++++++++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index ad9007014..23279bd17 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -146,10 +146,13 @@ module fctrl ( ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + // coverage off + // We are turning off coverage because rv64gc configuration doesn't support quad or half 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) + // coverage on 7'b1101000: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s @@ -174,6 +177,9 @@ module fctrl ( 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu endcase + //coverage off + // turning coverage off here because rv64gc configuration does not support floating point halfs and quads + // verified that these branches will not ever be taken in rv64gc configuration. 7'b1101010: case(Rs2D) 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h @@ -197,7 +203,8 @@ module fctrl ( 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase + endcase + // coverage on endcase endcase /* verilator lint_off CASEINCOMPLETE */ diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 0ab0e706a..b28a9e7be 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -135,10 +135,16 @@ module decompress ( IllegalCompInstrD = 1; InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap end + // coverage off + // are excluding this branch from coverage because in rv64gc XLEN is always 64 and thus greater than 32 bits + // This branch will only be taken if instr16[12:10] == 3'b111 and 'XLEN !> 32, because all other + // possible values for instr16[12:10] are covered by branches above. XLEN !> 32 + // will never occur in rv64gc so this branch can not be covered else begin // illegal instruction IllegalCompInstrD = 1; InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap end + // coverage on 5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j 5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz 5'b01111: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 1a2d5ce7b..527547bb3 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -55,7 +55,23 @@ main: fcvt.l.q a0, ft3 fcvt.lu.q a0, ft3 - + + // Tests verfying that half and quad floating point convertion instructions are not supported by rv64gc + # fcvt.h.d ft3, ft0 // Somehow this instruction is taking the route on line 124 + // idea: enable the Q extension for this to work properly? A: Q and halfs not supported in rv64gc + # fcvt.h.w ft3, a0 + # fcvt.w.h a0, ft0 + # fcvt.q.w ft3, a0 + # fcvt.w.q a0, ft0 + # fcvt.q.d ft3, ft0 + + .word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011 + .word 0x40000053 // Line 145 All False Test case - illegal instruction? + .word 0xd0400053 // Line 156 All False Test case - illegal instruction? + .word 0xc0400053 // Line 162 All False Test case - illegal instruction? + .word 0xd2400053 // Line 168 All False Test case - illegal instruction? + .word 0xc2400053 // Line 174 All False Test case - illegal instruction? + # Test illegal instructions are detected .word 0x00000007 // illegal floating-point load (bad Funct3) .word 0x00000027 // illegal floating-point store (bad Funct3) diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index 3ceeeac12..68db3d087 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -32,9 +32,26 @@ main: csrs mstatus, t0 # calling compressed floating point load double instruction - //.halfword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op + //.hword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op // binary version 0000 0000 0000 0000 0010 0000 0000 0000 mv s0, sp c.fld fs0, 0(s0) + c.fsd fs0, 0(s0) + + // c.fldsp fs0, 0 + .hword 0x2002 + + // c.fsdsp fs0, 0 + .hword 0xA002 + + # set XLEN to 64 + li t0, 0x200000000 + csrs mstatus, t0 + + //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else + //.hword 0x9C01 + + # Illegal compressed instruction + .hword 0x9C41 j done From 7e5e9d928e2b94ae39b5b86e766b123fad624e0b Mon Sep 17 00:00:00 2001 From: Sydeny Date: Mon, 3 Apr 2023 01:55:23 -0700 Subject: [PATCH 52/56] Manual merge for fctrl.sv, fpu.S, and ifu.S files --- src/fpu/fctrl.sv | 204 ++++++++++++++++++++++--------------------- tests/coverage/fpu.S | 3 - tests/coverage/ifu.S | 7 +- 3 files changed, 107 insertions(+), 107 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 0c345a495..b34001077 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -100,105 +100,111 @@ module fctrl ( ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // default: non-implemented instruction /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed case(OpD) - 7'b0000111: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw - 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld - 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq - 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh - endcase - 7'b0100111: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw - 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd - 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq - 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh - endcase - 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd - 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub - 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub - 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd - 7'b1010011: casez(Funct7D) - 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd - 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub - 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul - 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv - 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt - 7'b00100??: case(Funct3D) - 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj - 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn - 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx - endcase - 7'b00101??: case(Funct3D) - 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin - 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax - endcase - 7'b10100??: case(Funct3D) - 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq - 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt - 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle - endcase - 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass - else if (Funct3D == 3'b000 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register - 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) - ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg - 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) - ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) - 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) - ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) - 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) - ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) - 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) - ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) - 7'b1101000: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s - endcase - 7'b1100000: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu - endcase - 7'b1101001: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d - endcase - 7'b1100001: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu - endcase - 7'b1101010: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h - endcase - 7'b1100010: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu - endcase - 7'b1101011: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q - 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q - 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q - 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q - endcase - 7'b1100011: case(Rs2D) - 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w - 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu - 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l - 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu - endcase - endcase + 7'b0000111: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw + 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld + 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq + 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh + endcase + 7'b0100111: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw + 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd + 3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq + 3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh + endcase + 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd + 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub + 7'b1001011: ControlsD = `FCTRLW'b1_0_01_10_010_0_0_0; // fnmsub + 7'b1001111: ControlsD = `FCTRLW'b1_0_01_10_011_0_0_0; // fnmadd + 7'b1010011: casez(Funct7D) + 7'b00000??: ControlsD = `FCTRLW'b1_0_01_10_110_0_0_0; // fadd + 7'b00001??: ControlsD = `FCTRLW'b1_0_01_10_111_0_0_0; // fsub + 7'b00010??: ControlsD = `FCTRLW'b1_0_01_10_100_0_0_0; // fmul + 7'b00011??: ControlsD = `FCTRLW'b1_0_01_01_xx0_1_0_0; // fdiv + 7'b01011??: if (Rs2D == 5'b0000) ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt + 7'b00100??: case(Funct3D) + 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj + 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn + 3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx + endcase + 7'b00101??: case(Funct3D) + 3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin + 3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax + endcase + 7'b10100??: case(Funct3D) + 3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq + 3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt + 3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle + endcase + 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass + else if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register + 7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000) + ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg + 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) + ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h) + 7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01) + ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q) + // coverage off + // Not covered in testing because rv64gc does not support half or quad precision + 7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10) + ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q) + 7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11) + ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d) + // coverage on + 7'b1101000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s + endcase + 7'b1100000: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu + endcase + 7'b1101001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d + endcase + 7'b1100001: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu + endcase + // coverage off + // Not covered in testing because rv64gc does not support half or quad precision + 7'b1101010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h + endcase + 7'b1100010: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu + endcase + 7'b1101011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q + 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q + 5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q + 5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q + endcase + 7'b1100011: case(Rs2D) + 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w + 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu + 5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l + 5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu + endcase + // coverage on + endcase endcase end /* verilator lint_on CASEINCOMPLETE */ diff --git a/tests/coverage/fpu.S b/tests/coverage/fpu.S index 17fed79b3..a349ac606 100644 --- a/tests/coverage/fpu.S +++ b/tests/coverage/fpu.S @@ -57,7 +57,6 @@ main: fcvt.l.q a0, ft3 fcvt.lu.q a0, ft3 -<<<<<<< HEAD // Tests verfying that half and quad floating point convertion instructions are not supported by rv64gc # fcvt.h.d ft3, ft0 // Somehow this instruction is taking the route on line 124 @@ -75,8 +74,6 @@ main: .word 0xd2400053 // Line 168 All False Test case - illegal instruction? .word 0xc2400053 // Line 174 All False Test case - illegal instruction? -======= ->>>>>>> d4b7da34dee55ec8394ab391ecd6514c887a9790 # Test illegal instructions are detected .word 0x00000007 // illegal floating-point load (bad Funct3) .word 0x00000027 // illegal floating-point store (bad Funct3) diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index 68db3d087..9cde14ce2 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -36,6 +36,7 @@ main: // binary version 0000 0000 0000 0000 0010 0000 0000 0000 mv s0, sp c.fld fs0, 0(s0) + c.fsd fs0, 0(s0) // c.fldsp fs0, 0 @@ -44,14 +45,10 @@ main: // c.fsdsp fs0, 0 .hword 0xA002 - # set XLEN to 64 - li t0, 0x200000000 - csrs mstatus, t0 - //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else //.hword 0x9C01 - # Illegal compressed instruction + # Line Illegal compressed instruction .hword 0x9C41 j done From 77f071dc147433d9be62cc639f516e0709a4dc7c Mon Sep 17 00:00:00 2001 From: David Harris Date: Mon, 3 Apr 2023 17:55:30 -0700 Subject: [PATCH 53/56] Updated imperas.ic to enable B extension --- sim/imperas.ic | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index beadba6fa..2295c9d45 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -15,9 +15,8 @@ # Wally-specific non-default configuraiton --override refRoot/cpu/Sstc=T -# Zba doesn't seem to exist - Lee is finding the name -#--override refRoot/cpu/Zba=T - +--override cpu/add_implicit_Extensions=B +--override cpu/bitmanip_version=1.0.0 # Illegal instruction should not contain the bit pattern # illegal pmp read contained this From ce8a401a841e0472889d7902e5749fce50e6002b Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Mon, 3 Apr 2023 22:53:46 -0700 Subject: [PATCH 54/56] reduced mux3 to mux2 for input signal to clmul --- src/ieu/bmu/zbc.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ieu/bmu/zbc.sv b/src/ieu/bmu/zbc.sv index 1fb41193f..b173a5f63 100644 --- a/src/ieu/bmu/zbc.sv +++ b/src/ieu/bmu/zbc.sv @@ -41,7 +41,7 @@ module zbc #(parameter WIDTH=32) ( bitreverse #(WIDTH) brB(B, RevB); mux3 #(WIDTH) xmux({RevA[WIDTH-2:0], {1'b0}}, RevA, A, ~Funct3[1:0], X); - mux3 #(WIDTH) ymux({{1'b0}, RevB[WIDTH-2:0]}, RevB, B, ~Funct3[1:0], Y); + mux2 #(WIDTH) ymux(RevB, B, ~Funct3[1], Y); clmul #(WIDTH) clm(.X, .Y, .ClmulResult); From b9ef99530acc18a3e34b0fbcf6efca7d83b4b94e Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Tue, 4 Apr 2023 17:20:00 +0100 Subject: [PATCH 55/56] add support for Sstc --- sim/imperas.ic | 48 +++++++++++++++------------- testbench/testbench-linux-imperas.sv | 9 +++--- testbench/testbench_imperas.sv | 10 +++--- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index 2295c9d45..4c221f2af 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -4,24 +4,36 @@ --showcommands # Core settings +--override cpu/priv_version=1.12 +--override cpu/user_version=20191213 +# arch +--override cpu/mimpid=0x100 +--override refRoot/cpu/tvec_align=64 + +# clarify +#--override refRoot/cpu/mtvec_sext=F + +--override cpu/tval_ii_code=T + +#--override cpu/time_undefined=T +#--override cpu/cycle_undefined=T +#--override cpu/instret_undefined=T +#--override cpu/hpmcounter_undefined=T + +--override cpu/reset_address=0x80000000 + --override cpu/unaligned=F --override cpu/ignore_non_leaf_DAU=1 -#--override cpu/wfi_is_nop=T ---override cpu/mimpid=0x100 +--override cpu/wfi_is_nop=T --override cpu/misa_Extensions_mask=0x0 +#--override cpu/updatePTEA=T +#--override cpu/updatePTED=T +--override cpu/Sstc=T +# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=16 --override cpu/PMP_undefined=T -# Wally-specific non-default configuraiton ---override refRoot/cpu/Sstc=T ---override cpu/add_implicit_Extensions=B ---override cpu/bitmanip_version=1.0.0 - -# Illegal instruction should not contain the bit pattern -# illegal pmp read contained this -# --override cpu/tval_ii_code=F - # PMA Settings # 'r': read access allowed # 'w': write access allowed @@ -51,19 +63,11 @@ #-override refRoot/cpu/cv/cover=basic #-override refRoot/cpu/cv/extensions=RV32I - - # Add Imperas simulator application instruction tracing ---override cpu/show_c_prefix=T - ---trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 800000 - -# Exceptions and pagetables debug ---override cpu/debugflags=6 - -# Turn on verbose output for Imperas simulator and Model --verbose ---override cpu/verbose=1 +--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 0 +--override cpu/debugflags=6 --override cpu/verbose=1 +--override cpu/show_c_prefix=T # Store simulator output to logfile --output imperas.log diff --git a/testbench/testbench-linux-imperas.sv b/testbench/testbench-linux-imperas.sv index 00167e5fd..d3d71626f 100644 --- a/testbench/testbench-linux-imperas.sv +++ b/testbench/testbench-linux-imperas.sv @@ -413,10 +413,11 @@ module testbench; end end - always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); - always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); - always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); - always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); + always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); + always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); + always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); final begin void'(rvviRefShutdown()); diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index f63c640d7..56ca763af 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -198,10 +198,12 @@ module testbench; end - always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); - always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); - always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); - always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); + always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); + always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); + always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); + always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); + final begin void'(rvviRefShutdown()); From b7b1f2443f54d0f94f6bebfd2dcc857f8772c0c9 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 4 Apr 2023 09:32:26 -0700 Subject: [PATCH 56/56] Fixed WFI to commit when an interrupt occurs --- src/hazard/hazard.sv | 10 ++++++++-- src/privileged/privileged.sv | 6 ++---- src/privileged/trap.sv | 2 -- src/wally/wallypipelinedcore.sv | 12 +++++++----- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index bc9f7baa0..11efacffa 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -36,7 +36,7 @@ module hazard ( input logic FCvtIntStallD, FPUStallD, input logic DivBusyE, FDivBusyE, input logic EcallFaultM, BreakpointFaultM, - input logic WFIStallM, + input logic wfiM, IntPendingM, // Stall & flush outputs output logic StallF, StallD, StallE, StallM, StallW, output logic FlushD, FlushE, FlushM, FlushW @@ -45,6 +45,12 @@ module hazard ( logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic LatestUnstalledD, LatestUnstalledE, LatestUnstalledM, LatestUnstalledW; logic FlushDCause, FlushECause, FlushMCause, FlushWCause; + + logic WFIStallM, WFIInterruptedM; + + // WFI logic + assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout + assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -68,7 +74,7 @@ module hazard ( assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; - assign FlushWCause = TrapM; + assign FlushWCause = TrapM & ~WFIInterruptedM; // Stall causes // Most data depenency stalls are identified in the decode stage diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index 6fa8dcf98..ca3d35717 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -93,7 +93,7 @@ module privileged ( output logic BigEndianM, // Use big endian in current privilege mode // Fault outputs output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire - output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout + output logic wfiM, IntPendingM // Stall in Memory stage for WFI until interrupt pending or timeout ); logic [3:0] CauseM; // trap cause @@ -110,8 +110,6 @@ module privileged ( logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return logic DelegateM; // trap should be delegated - logic wfiM; // wait for interrupt instruction - logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi logic InterruptM; // interrupt occuring logic ExceptionM; // Memory stage instruction caused a fault @@ -156,7 +154,7 @@ module privileged ( .mretM, .sretM, .PrivilegeModeW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .InstrValidM, .CommittedM, .CommittedF, - .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .WFIStallM, .CauseM); + .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); endmodule diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index ace63b48b..b6e99f2e0 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -48,7 +48,6 @@ module trap ( output logic ExceptionM, // exception is occurring output logic IntPendingM, // Interrupt is pending, might occur if enabled output logic DelegateM, // Delegate trap to supervisor handler - output logic WFIStallM, // Stall due to WFI instruction output logic [3:0] CauseM // trap cause ); @@ -74,7 +73,6 @@ module trap ( assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE); - assign WFIStallM = wfiM & ~IntPendingM; /////////////////////////////////////////// // Trigger Traps and RET diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 343cf1fdb..81f1997af 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -106,7 +106,7 @@ module wallypipelinedcore ( logic [1:0] PrivilegeModeW; logic [`XLEN-1:0] PTE; logic [1:0] PageType; - logic sfencevmaM, WFIStallM; + logic sfencevmaM; logic SelHPTW; // PMA checker signals @@ -162,7 +162,8 @@ module wallypipelinedcore ( logic CommittedF; logic BranchD, BranchE, JumpD, JumpE; logic DCacheStallM, ICacheStallF; - + logic wfiM, IntPendingM; + // instruction fetch unit: PC, branch prediction, instruction cache ifu ifu(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, @@ -265,7 +266,7 @@ module wallypipelinedcore ( .FCvtIntStallD, .FPUStallD, .DivBusyE, .FDivBusyE, .EcallFaultM, .BreakpointFaultM, - .WFIStallM, + .wfiM, .IntPendingM, // Stall & flush outputs .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW); @@ -292,13 +293,14 @@ module wallypipelinedcore ( .PrivilegeModeW, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, - .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .WFIStallM, .BigEndianM); + .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); end else begin assign CSRReadValW = 0; assign UnalignedPCNextF = PC2NextF; assign RetM = 0; assign TrapM = 0; - assign WFIStallM = 0; + assign wfiM = 0; + assign IntPendingM = 0; assign sfencevmaM = 0; assign BigEndianM = 0; end