From f8ad1b3db864e0a7d2868839b76913934b1fd99d Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 Mar 2023 14:24:41 -0700 Subject: [PATCH 01/13] Improved IEU and bitmanip test coverage --- src/generic/lzc.sv | 2 +- src/ieu/bmu/bmuctrl.sv | 77 +++++++++++++++------------- testbench/tests.vh | 2 +- tests/coverage/Makefile | 2 +- tests/coverage/{badinstr.S => ieu.S} | 27 ++++++++-- 5 files changed, 69 insertions(+), 41 deletions(-) rename tests/coverage/{badinstr.S => ieu.S} (66%) diff --git a/src/generic/lzc.sv b/src/generic/lzc.sv index ecfd6796..9b7c841b 100644 --- a/src/generic/lzc.sv +++ b/src/generic/lzc.sv @@ -32,7 +32,7 @@ module lzc #(parameter WIDTH = 1) ( always_comb begin i = 0; - while (~num[WIDTH-1-i] & (i < WIDTH)) i = i+1; // search for leading one + while ((i < WIDTH) & ~num[WIDTH-1-i]) i = i+1; // search for leading one ZeroCnt = i[$clog2(WIDTH+1)-1:0]; end endmodule diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 645e711c..24dd22ce 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -78,21 +78,22 @@ module bmuctrl( always_comb begin // ALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD BMUControlsD = {Funct3D, `BMUCTRLWSUB3'b00_000_0_0_0_0_0_0_0_0_1}; // default: Illegal instruction - if (`ZBA_SUPPORTED) + if (`ZBA_SUPPORTED) begin casez({OpD, Funct7D, Funct3D}) 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add 17'b0110011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh2add 17'b0110011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh3add endcase - if (`ZBA_SUPPORTED & `XLEN==64) - casez({OpD, Funct7D, Funct3D}) - 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw - 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw - 17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh3add.uw - 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_0_0; // add.uw - 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw - endcase - if (`ZBB_SUPPORTED) + if (`XLEN==64) + casez({OpD, Funct7D, Funct3D}) + 17'b0111011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh1add.uw + 17'b0111011_0010000_100: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh2add.uw + 17'b0111011_0010000_110: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_1_0; // sh3add.uw + 17'b0111011_0000100_000: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_1_1_0_0_0_0_0; // add.uw + 17'b0011011_000010?_001: BMUControlsD = `BMUCTRLW'b001_01_000_1_1_1_1_0_0_0_0_0; // slli.uw + endcase + end + if (`ZBB_SUPPORTED) begin casez({OpD, Funct7D, Funct3D}) 17'b0110011_0110000_001: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // rol 17'b0110011_0110000_101: BMUControlsD = `BMUCTRLW'b001_01_111_1_0_0_1_0_1_0_0_0; // ror @@ -100,8 +101,6 @@ 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) 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 @@ -114,38 +113,47 @@ module bmuctrl( 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 endcase - if (`ZBB_SUPPORTED & `XLEN==64) - casez({OpD, Funct7D, Funct3D}) - 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw - 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rorw - 17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv64) - 17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_1_0_1_0_0_0; // roriw - 17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) - BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction - 17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64) - endcase + if (`XLEN==32) + casez({OpD, Funct7D, Funct3D}) + 17'b0110011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_1_0_1_0_0_0_0_0; // zexth (rv32) + endcase + else if (`XLEN==64) + casez({OpD, Funct7D, Funct3D}) + 17'b0111011_0000100_100: BMUControlsD = `BMUCTRLW'b000_10_001_1_0_0_1_0_0_0_0_0; // zexth (rv64) + 17'b0111011_0110000_001: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rolw + 17'b0111011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_0_1_1_0_1_0_0_0; // rorw + 17'b0010011_011000?_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_0_1_0_1_0_0_0; // rori (rv64) + 17'b0011011_0110000_101: BMUControlsD = `BMUCTRLW'b001_00_111_1_1_1_1_0_1_0_0_0; // roriw + 17'b0011011_0110000_001: if ((Rs2D[4:2]==3'b000) & ~(Rs2D[1] & Rs2D[0])) + BMUControlsD = `BMUCTRLW'b000_10_000_1_1_1_1_0_0_0_0_0; // count word instruction + endcase + end if (`ZBC_SUPPORTED) casez({OpD, Funct7D, Funct3D}) 17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_11_000_1_0_0_1_0_0_0_0_0; // ZBC instruction endcase - if (`ZBS_SUPPORTED) // ZBS + if (`ZBS_SUPPORTED) begin // ZBS casez({OpD, Funct7D, Funct3D}) - 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri - 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti - 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi - 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti 17'b0110011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_0_0_1_1_0_1_0_0; // bclr 17'b0110011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_0_0_1_1_0_1_0_0; // bext 17'b0110011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_0_0_1_0_0_1_0_0; // binv 17'b0110011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_0_0_1_0_0_1_0_0; // bset endcase - if (`ZBS_SUPPORTED & `XLEN==64) // ZBS 64-bit - casez({OpD, Funct7D, Funct3D}) - 17'b0010011_0100101_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64) - 17'b0010011_0100101_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64) - 17'b0010011_0110101_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi (rv64) - 17'b0010011_0010101_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64) - endcase + if (`XLEN==32) // ZBS 64-bit + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_0100100_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri + 17'b0010011_0100100_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti + 17'b0010011_0110100_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi + 17'b0010011_0010100_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti + endcase + else if (`XLEN==64) // ZBS 64-bit + casez({OpD, Funct7D, Funct3D}) + 17'b0010011_010010?_001: BMUControlsD = `BMUCTRLW'b111_01_000_1_1_0_1_1_0_1_0_0; // bclri (rv64) + 17'b0010011_010010?_101: BMUControlsD = `BMUCTRLW'b101_01_000_1_1_0_1_1_0_1_0_0; // bexti (rv64) + 17'b0010011_011010?_001: BMUControlsD = `BMUCTRLW'b100_01_000_1_1_0_1_0_0_1_0_0; // binvi (rv64) + 17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64) + endcase + end if (`ZBB_SUPPORTED | `ZBS_SUPPORTED) // rv32i/64i shift instructions need certain BMU shifter control when BMU shifter is used casez({OpD, Funct7D, Funct3D}) 17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll @@ -153,7 +161,6 @@ module bmuctrl( 17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_1_1_0_0_0_0_0; // sraw, srlw, sllw 17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_1_1_0_0_0_0_0; // sraiw, srliw, slliw endcase - // ZBC end // Unpack Control Signals diff --git a/testbench/tests.vh b/testbench/tests.vh index 83729f96..f5e02290 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -44,7 +44,7 @@ string tvpaths[] = '{ string coverage64gc[] = '{ `COVERAGE, - "badinstr", + "ieu", "csrwrites" }; diff --git a/tests/coverage/Makefile b/tests/coverage/Makefile index d3686f8e..7d4552af 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 -mabi=lp64 -mcmodel=medany \ + riscv64-unknown-elf-gcc -g -o $@ -march=rv64gc_zba_zbb_zbc_zbs -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/badinstr.S b/tests/coverage/ieu.S similarity index 66% rename from tests/coverage/badinstr.S rename to tests/coverage/ieu.S index 174ea0ae..8467f2d4 100644 --- a/tests/coverage/badinstr.S +++ b/tests/coverage/ieu.S @@ -1,9 +1,9 @@ /////////////////////////////////////////// -// badinstr.S +// ieu.S // // Written: David_Harris@hmc.edu 21 March 2023 // -// Purpose: Test illegal instruction opcodes +// Purpose: Test coverage for IEU // // A component of the CORE-V-WALLY configurable RISC-V project. // @@ -27,7 +27,19 @@ #include "WALLY-init-lib.h" main: - .word 0x00000033 // legal R-type instruction + + # Test clz with all bits being 0 + li t0, 0 + clz t1, t0 + li t0, -1 + clz t1, t0 + + # Test forwarding from store conditional + lr.w t0, 0(a0) + sc.w t0, a1, 0(a0) + addi t0, t0, 1 + + # Test illegal instructions are detected .word 0x80000033 // illegal R-type instruction .word 0x00007003 // illegal Load instruction .word 0x80005013 // illegal I-type instruction: srli: op = 0010011, funct3 = 101, funct7 = 1000000 @@ -37,6 +49,15 @@ main: .word 0x0400003B // Illegal RW or MulDivW instruction .word 0x00007067 // Illegal JALR instruction .word 0x00002063 // Illegal branch instruction + .word 0x60F01013 // Illegal BMU sign extend / count instruction + .word 0x60801013 // Illegal BMU sign extend / count instruction + .word 0x60301013 // Illegal BMU sign extend / count instruction + .word 0x6BF05013 // Illegal BMU similar to rev8 + .word 0x69805013 // Illegal BMU similar to rev8 + .word 0x28F05013 // Illegal BMU similar to or.c + .word 0x60F0101B // Illegal BMU similar to count word + .word 0x6080101B // Illegal BMU similar to count word + .word 0x6030101B // Illegal BMU similar to count word j done From b0620db374ef289b67190c850ac9b366e1b723be Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 Mar 2023 17:24:58 -0700 Subject: [PATCH 02/13] Tool change docs --- bin/wally-tool-chain-install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 798fe51b..ef98aed7 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -35,8 +35,8 @@ set -e # break on error # Modify accordingly for your machine # Increasing NUM_THREADS will speed up parallel compilation of the tools -NUM_THREADS=2 # for low memory machines > 16GiB -#NUM_THREADS=8 # for >= 32GiB +#NUM_THREADS=2 # for low memory machines > 16GiB +NUM_THREADS=8 # for >= 32GiB #NUM_THREADS=16 # for >= 64GiB sudo mkdir -p $RISCV From 83e13cef46d087174a508c396cee0a638ee9dffd Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 Mar 2023 17:25:27 -0700 Subject: [PATCH 03/13] 100% IEU coverage --- sim/coverage-exclusions-rv64gc.do | 19 +++++++++++++++---- tests/coverage/ieu.S | 2 ++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index 8f79b7d5..9905c897 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -24,11 +24,22 @@ #// and limitations under the License. #//////////////////////////////////////////////////////////////////////////////////////////////// +# LZA (i<64) statement confuses coverage tool +# This is ugly to exlcude the whole file - is there a better option +coverage exclude -srcfile lzc.sv + + +###################### +# Toggle exclusions +# Not used because toggle coverage isn't measured +###################### + # Exclude DivBusyE from all design units because rv64gc uses the fdivsqrt unit for integer division -coverage exclude -togglenode DivBusyE -du * +#coverage exclude -togglenode DivBusyE -du * # Exclude QuotM and RemM from MDU because rv64gc uses the fdivsqrt rather tha div unit for integer division -coverage exclude -togglenode /dut/core/mdu/mdu/QuotM -coverage exclude -togglenode /dut/core/mdu/mdu/RemM +#coverage exclude -togglenode /dut/core/mdu/mdu/QuotM +#coverage exclude -togglenode /dut/core/mdu/mdu/RemM # StallFCause is hardwired to 0 -coverage exclude -togglenode /dut/core/hzu/StallFCause +#coverage exclude -togglenode /dut/core/hzu/StallFCause + diff --git a/tests/coverage/ieu.S b/tests/coverage/ieu.S index 8467f2d4..e1b23937 100644 --- a/tests/coverage/ieu.S +++ b/tests/coverage/ieu.S @@ -33,6 +33,8 @@ main: clz t1, t0 li t0, -1 clz t1, t0 + li t0, 1 + clz t1, t0 # Test forwarding from store conditional lr.w t0, 0(a0) From dc156cc09cbb8cbd9bcfe2ca793e25238d6525a6 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 23 Mar 2023 17:25:59 -0700 Subject: [PATCH 04/13] Removed unnecessary XZero from fdivsqrt --- src/fpu/fdivsqrt/fdivsqrtexpcalc.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv b/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv index b5b2ba33..482fed84 100644 --- a/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv +++ b/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv @@ -69,6 +69,6 @@ module fdivsqrtexpcalc( assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias}; // correct exponent for subnormal input's normalization shifts - assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; // *** why Xzero? Is this a hack for postprocessor? + assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}); assign Qe = Sqrt ? SExp : DExp; endmodule From c6561fffd4a42422c345abeeafb1d4832b2b3003 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 06:18:06 -0700 Subject: [PATCH 05/13] BMU simplifications --- src/ieu/alu.sv | 12 ++---------- src/ieu/bmu/bmuctrl.sv | 2 +- src/ieu/controller.sv | 4 +--- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 2f1bd9d8..a0370f2b 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -55,22 +55,14 @@ module alu #(parameter WIDTH=32) ( logic Asign, Bsign; // Sign bits of A, B logic shSignA; logic [WIDTH-1:0] rotA; // XLEN bit input source to shifter - logic [1:0] shASelect; // select signal for shifter source generation mux - logic Rotate; // Indicates if it is Rotate instruction // Extract control signals from ALUControl. assign {W64, SubArith, ALUOp} = ALUControl; - // Extract rotate signal from BALUControl. - assign Rotate = BALUControl[2]; - - // Pack control signals into shifter select signal. - assign shASelect = {W64, SubArith}; - // A, A sign bit muxes if (WIDTH == 64) begin mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA); - mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A,{~W64, SubArith}, CondExtA); + mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux end else begin mux2 #(1) signmux(1'b0, A[31], SubArith, shSignA); assign CondExtA = A; @@ -81,7 +73,7 @@ module alu #(parameter WIDTH=32) ( assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts (configurable for rotation) - shifter sh(.shA(CondExtA), .Sign(shSignA), .rotA, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate); + shifter sh(.shA(CondExtA), .Sign(shSignA), .rotA, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2])); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 46222cf7..4769c63d 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -34,7 +34,6 @@ module bmuctrl( // Decode stage control signals input logic StallD, FlushD, // Stall, flush Decode stage input logic [31:0] InstrD, // Instruction in Decode stage - output logic [2:0] ALUSelectD, // ALU Mux select signal in Decode Stage output logic [1:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage output logic [2:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode? output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage @@ -62,6 +61,7 @@ module bmuctrl( logic MaskD; // Indicates if zbs instruction in Decode Stage logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage logic [2:0] BALUControlD; // ALU Control signals for B instructions + logic [2:0] ALUSelectD; // ALU Mux select signal in Decode Stage `define BMUCTRLW 17 `define BMUCTRLWSUB3 14 diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 5c397d15..2cb45311 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -98,7 +98,6 @@ module controller( logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu logic BaseALUSrcBD; // Base instruction ALU B source select signal logic [2:0] ALUControlD; // Determines ALU operation - logic [2:0] ALUSelectD; // ALU mux select signal logic ALUSrcAD, ALUSrcBD; // ALU inputs logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR @@ -260,7 +259,7 @@ module controller( // bit manipulation Configuration Block if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags - bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUSelectD, .BSelectD, .ZBBSelectD, + bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .BSelectD, .ZBBSelectD, .BRegWriteD, .BALUSrcBD, .BW64D, .BALUOpD, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE); if (`ZBA_SUPPORTED) begin @@ -269,7 +268,6 @@ module controller( end else assign sltD = (Funct3D == 3'b010); end else begin: bitmanipi - assign ALUSelectD = Funct3D; assign ALUSelectE = Funct3E; assign BSelectE = 2'b00; assign BSelectD = 2'b00; From 9ffac8315b5b9ce35492e054ccb843c8cbc7e887 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 06:49:26 -0700 Subject: [PATCH 06/13] Simplified rotate source to shifter --- src/ieu/alu.sv | 8 +++----- src/ieu/bmu/bitmanipalu.sv | 10 ++-------- src/ieu/shifter.sv | 30 ++++++++++++++++-------------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index a0370f2b..71453573 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -54,7 +54,6 @@ module alu #(parameter WIDTH=32) ( logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops logic Asign, Bsign; // Sign bits of A, B logic shSignA; - logic [WIDTH-1:0] rotA; // XLEN bit input source to shifter // Extract control signals from ALUControl. assign {W64, SubArith, ALUOp} = ALUControl; @@ -73,7 +72,7 @@ module alu #(parameter WIDTH=32) ( assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts (configurable for rotation) - shifter sh(.shA(CondExtA), .Sign(shSignA), .rotA, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2])); + shifter sh(.A(CondExtA), .Sign(shSignA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2])); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign @@ -106,13 +105,12 @@ 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, .ALUControl, .ALUSelect, .BSelect, .ZBBSelect, + bitmanipalu #(WIDTH) balu(.A, .B, .ALUControl, .BSelect, .ZBBSelect, .Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult, - .CondMaskB, .CondShiftA, .rotA, .Result); + .CondMaskB, .CondShiftA, .Result); end else begin assign Result = ALUResult; assign CondMaskB = B; assign CondShiftA = A; - assign rotA = A; end endmodule \ No newline at end of file diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index 83638ce2..a8439b76 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -32,17 +32,15 @@ module bitmanipalu #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, // Operands input logic [2:0] ALUControl, // With Funct3, indicates operation to perform - input logic [2:0] ALUSelect, // ALU mux select signal 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, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect + input logic [2:0] Funct3, // Funct3 field of opcode indicates operation to perform input logic [1:0] CompFlags, // Comparator flags input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [WIDTH-1:0] CondExtA, // A Conditional Extend Intermediary Signal input logic [WIDTH-1:0] ALUResult, FullResult, // ALUResult, 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] rotA, // Rotate source signal output logic [WIDTH-1:0] Result); // Result logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result @@ -68,12 +66,8 @@ module bitmanipalu #(parameter WIDTH=32) ( mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); end else assign CondMaskB = B; - // shifter rotate source select mux - if (`ZBB_SUPPORTED & WIDTH == 64) begin - mux2 #(WIDTH) rotmux(A, {A[31:0], A[31:0]}, W64, rotA); - end else assign rotA = A; - // Pre-Shift Mux + // 0-3 bit Pre-Shift Mux if (`ZBA_SUPPORTED) begin: zbapreshift assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; assign CondShiftA = CondExtA << (PreShiftAmt); diff --git a/src/ieu/shifter.sv b/src/ieu/shifter.sv index 594ef3dd..d0a6471c 100644 --- a/src/ieu/shifter.sv +++ b/src/ieu/shifter.sv @@ -30,8 +30,7 @@ `include "wally-config.vh" module shifter ( - input logic [`XLEN-1:0] shA, // shift Source - input logic [`XLEN-1:0] rotA, // rotate source + input logic [`XLEN-1:0] A, // shift Source input logic [`LOG_XLEN-1:0] Amt, // Shift amount input logic Right, Rotate, W64, Sign, // Shift right, rotate signals output logic [`XLEN-1:0] Y); // Shifted result @@ -43,32 +42,35 @@ module shifter ( if (`XLEN==32) begin // rv32 with rotates always_comb // funnel mux case({Right, Rotate}) - 2'b00: z = {shA[31:0], 31'b0}; - 2'b01: z = {rotA,rotA[31:1]}; - 2'b10: z = {{31{Sign}}, shA[31:0]}; - 2'b11: z = {rotA[30:0],rotA}; + 2'b00: z = {A[31:0], 31'b0}; + 2'b01: z = {A[31:0], A[31:1]}; + 2'b10: z = {{31{Sign}}, A[31:0]}; + 2'b11: z = {A[30:0], A}; endcase assign amttrunc = Amt; // shift amount end else begin // rv64 with rotates + // shifter rotate source select mux + logic [`XLEN-1:0] RotA; // rotate source + mux2 #(`XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons always_comb // funnel mux case ({Right, Rotate}) - 2'b00: z = {shA[63:0],{63'b0}}; - 2'b01: z = {rotA, rotA[63:1]}; - 2'b10: z = {{63{Sign}},shA[63:0]}; - 2'b11: z = {rotA[62:0],rotA[63:0]}; + 2'b00: z = {A[63:0],{63'b0}}; + 2'b01: z = {RotA, RotA[63:1]}; + 2'b10: z = {{63{Sign}}, A[63:0]}; + 2'b11: z = {RotA[62:0], RotA}; endcase assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift end end else begin: norotfunnel if (`XLEN==32) begin:shifter // RV32 always_comb // funnel mux - if (Right) z = {{31{Sign}}, shA[31:0]}; - else z = {shA[31:0], 31'b0}; + if (Right) z = {{31{Sign}}, A[31:0]}; + else z = {A[31:0], 31'b0}; assign amttrunc = Amt; // shift amount end else begin:shifter // RV64 always_comb // funnel mux - if (Right) z = {{63{Sign}},shA[63:0]}; - else z = {shA[63:0],{63'b0}}; + if (Right) z = {{63{Sign}}, A[63:0]}; + else z = {A[63:0], {63'b0}}; assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift end end From ac0b669518c56dc26701d730ec4ba4370930d813 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 07:28:42 -0700 Subject: [PATCH 07/13] Merged ALUOp into ALUControl to simplify ALU mux --- src/ieu/alu.sv | 5 ++--- src/ieu/bmu/bitmanipalu.sv | 3 +-- src/ieu/bmu/bmuctrl.sv | 17 ++++++++++------- src/ieu/controller.sv | 9 +++------ 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 71453573..82e3c097 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -86,9 +86,8 @@ module alu #(parameter WIDTH=32) ( // Select appropriate ALU Result always_comb begin - if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation) - else casez (ALUSelect) // Otherwise check Funct3 NOTE: change signal name to ALUSelect - 3'b000: FullResult = Sum; // add or sub + case (ALUSelect) + 3'b000: FullResult = Sum; // add or sub (including address generation) 3'b001: FullResult = Shift; // sll, sra, or srl 3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt 3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu diff --git a/src/ieu/bmu/bitmanipalu.sv b/src/ieu/bmu/bitmanipalu.sv index a8439b76..6a63d20a 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -62,11 +62,10 @@ module bitmanipalu #(parameter WIDTH=32) ( // Mask Generation Mux if (`ZBS_SUPPORTED) begin: zbsdec - decoder #($clog2(WIDTH)) maskgen (B[$clog2(WIDTH)-1:0], MaskB); + decoder #($clog2(WIDTH)) maskgen(B[$clog2(WIDTH)-1:0], MaskB); mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); end else assign CondMaskB = B; - // 0-3 bit Pre-Shift Mux if (`ZBA_SUPPORTED) begin: zbapreshift assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index 4769c63d..ad599c8f 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -34,12 +34,12 @@ module bmuctrl( // Decode stage control signals input logic StallD, FlushD, // Stall, flush Decode stage input logic [31:0] InstrD, // Instruction in Decode stage + input logic ALUOpD, // Regular ALU Operation output logic [1:0] BSelectD, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding in Decode stage output logic [2:0] ZBBSelectD, // ZBB mux select signal in Decode stage NOTE: do we need this in decode? output logic BRegWriteD, // Indicates if it is a R type B instruction in Decode Stage output logic BALUSrcBD, // Indicates if it is an I/IW (non auipc) type B instruction in Decode Stage output logic BW64D, // Indiciates if it is a W type B instruction in Decode Stage - output logic BALUOpD, // Indicates if it is an ALU B instruction in Decode Stage output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage // Execute stage control signals @@ -61,10 +61,10 @@ module bmuctrl( logic MaskD; // Indicates if zbs instruction in Decode Stage logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage logic [2:0] BALUControlD; // ALU Control signals for B instructions - logic [2:0] ALUSelectD; // ALU Mux select signal in Decode Stage + logic [2:0] BALUSelectD, ALUSelectD; // ALU Mux select signal in Decode Stage + logic BALUOpD; // Indicates if it is an ALU B instruction in Decode Stage `define BMUCTRLW 17 - `define BMUCTRLWSUB3 14 logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals @@ -76,8 +76,8 @@ module bmuctrl( // Main Instruction Decoder always_comb begin - // ALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD - BMUControlsD = {Funct3D, `BMUCTRLWSUB3'b00_000_0_0_0_0_0_0_0_0_1}; // default: Illegal instruction + // BALUSelect_BSelect_ZBBSelect_BRegWrite_BALUSrcB_BW64_BALUOp_BSubArithD_RotateD_MaskD_PreShiftD_IllegalBitmanipInstrD + BMUControlsD = `BMUCTRLW'b000_00_000_0_0_0_0_0_0_0_0_1; // default: Illegal bmu instruction; if (`ZBA_SUPPORTED) begin casez({OpD, Funct7D, Funct3D}) 17'b0110011_0010000_010: BMUControlsD = `BMUCTRLW'b000_01_000_1_0_0_1_0_0_0_1_0; // sh1add @@ -157,7 +157,7 @@ module bmuctrl( 17'b0010011_001010?_001: BMUControlsD = `BMUCTRLW'b110_01_000_1_1_0_1_0_0_1_0_0; // bseti (rv64) endcase end - if (`ZBB_SUPPORTED | `ZBS_SUPPORTED) // rv32i/64i shift instructions need certain BMU shifter control when BMU shifter is used + if (`ZBB_SUPPORTED | `ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used casez({OpD, Funct7D, Funct3D}) 17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_0_0_1_0_0_0_0_0; // sra, srl, sll 17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_00_000_1_1_0_1_0_0_0_0_0; // srai, srli, slli @@ -167,7 +167,7 @@ module bmuctrl( end // Unpack Control Signals - assign {ALUSelectD,BSelectD,ZBBSelectD, BRegWriteD,BALUSrcBD, BW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD; + assign {BALUSelectD, BSelectD, ZBBSelectD, BRegWriteD,BALUSrcBD, BW64D, BALUOpD, BSubArithD, RotateD, MaskD, PreShiftD, IllegalBitmanipInstrD} = BMUControlsD; // Pack BALUControl Signals assign BALUControlD = {RotateD, MaskD, PreShiftD}; @@ -175,6 +175,9 @@ module bmuctrl( // 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#(13) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {ALUSelectE, BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE}); endmodule \ No newline at end of file diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 2cb45311..8bc68353 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -127,7 +127,6 @@ module controller( logic [2:0] ZBBSelectD; // ZBB Mux Select Signal logic BRegWriteD; // Indicates if it is a R type B instruction in decode stage logic BW64D; // Indicates if it is a W type B instruction in decode stage - logic BALUOpD; // Indicates if it is an ALU B instruction in decode stage logic BSubArithD; // TRUE for B-type ext, clr, andn, orn, xnor logic BALUSrcBD; // B-type alu src select signal logic BComparatorSignedE; // Indicates if max, min (signed comarison) instruction in Execute Stage @@ -235,11 +234,10 @@ module controller( assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; //NOTE: Do we want to segregate the IllegalBitmanipInstrD into its own output signal //assign IllegalBaseInstrD = 1'b0; assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD, - ResultSrcD, BranchD, BaseALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, + ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD; // If either bitmanip signal or base instruction signal - assign ALUOpD = BaseALUOpD | BALUOpD; assign RegWriteD = BaseRegWriteD | BRegWriteD; assign W64D = BaseW64D | BW64D; assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD; @@ -259,8 +257,8 @@ module controller( // bit manipulation Configuration Block if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags - bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .BSelectD, .ZBBSelectD, - .BRegWriteD, .BALUSrcBD, .BW64D, .BALUOpD, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, + bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD, + .BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, .ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE); if (`ZBA_SUPPORTED) begin // ALU Decoding is more comprehensive when ZBA is supported. slt and slti conflicts with sh1add, sh1add.uw @@ -274,7 +272,6 @@ module controller( assign ZBBSelectE = 3'b000; assign BRegWriteD = 1'b0; assign BW64D = 1'b0; - assign BALUOpD = 1'b0; assign BRegWriteE = 1'b0; assign BSubArithD = 1'b0; assign BComparatorSignedE = 1'b0; From d04f4cedf613343ecdb390fad6788f3a53f7b260 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 08:10:48 -0700 Subject: [PATCH 08/13] ALUControl Elimination --- src/ieu/alu.sv | 25 +++++++--------- src/ieu/bmu/bitmanipalu.sv | 8 +----- src/ieu/bmu/bmuctrl.sv | 6 ++-- src/ieu/controller.sv | 59 +++++++++++++++++++------------------- src/ieu/datapath.sv | 5 ++-- src/ieu/ieu.sv | 10 +++---- 6 files changed, 52 insertions(+), 61 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 82e3c097..11759b1d 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -31,11 +31,12 @@ module alu #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, // Operands - input logic [2:0] ALUControl, // With Funct3, indicates operation to perform + input logic W64, // W64-type instruction + input logic SubArith, // Subtraction or arithmetic shift input logic [2:0] ALUSelect, // ALU mux select signal 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, // With ALUControl, indicates operation to perform NOTE: Change signal name to ALUSelect + input logic [2:0] Funct3, // For BMU decoding input logic [1:0] CompFlags, // Comparator flags input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage output logic [WIDTH-1:0] Result, // ALU result @@ -49,21 +50,15 @@ module alu #(parameter WIDTH=32) ( logic [WIDTH-1:0] CondExtA; // Result of Zero Extend A select mux logic Carry, Neg; // Flags: carry out, negative logic LT, LTU; // Less than, Less than unsigned - logic W64; // RV64 W-type instruction - logic SubArith; // Performing subtraction or arithmetic right shift - logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops logic Asign, Bsign; // Sign bits of A, B - logic shSignA; - - // Extract control signals from ALUControl. - assign {W64, SubArith, ALUOp} = ALUControl; + logic ShiftSignA; // A, A sign bit muxes if (WIDTH == 64) begin - mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, shSignA); + mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, ShiftSignA); mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux end else begin - mux2 #(1) signmux(1'b0, A[31], SubArith, shSignA); + mux2 #(1) signmux(1'b0, A[31], SubArith, ShiftSignA); assign CondExtA = A; end @@ -72,7 +67,7 @@ module alu #(parameter WIDTH=32) ( assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts (configurable for rotation) - shifter sh(.A(CondExtA), .Sign(shSignA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2])); + shifter sh(.A(CondExtA), .Sign(ShiftSignA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2])); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign @@ -92,7 +87,7 @@ module alu #(parameter WIDTH=32) ( 3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt 3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu 3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv - 3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift;// bext + 3'b101: FullResult = (`ZBS_SUPPORTED | `ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported) 3'b110: FullResult = A | CondMaskInvB; // or, orn, bset 3'b111: FullResult = A & CondMaskInvB; // and, bclr endcase @@ -104,8 +99,8 @@ 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, .ALUControl, .BSelect, .ZBBSelect, - .Funct3, .CompFlags, .BALUControl, .CondExtA, .ALUResult, .FullResult, + bitmanipalu #(WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, + .Funct3, .CompFlags, .BALUControl, .CondExtA, .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 6a63d20a..1cf1cd08 100644 --- a/src/ieu/bmu/bitmanipalu.sv +++ b/src/ieu/bmu/bitmanipalu.sv @@ -31,7 +31,7 @@ module bitmanipalu #(parameter WIDTH=32) ( input logic [WIDTH-1:0] A, B, // Operands - input logic [2:0] ALUControl, // With Funct3, indicates operation to perform + input logic W64, // W64-type instruction 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 @@ -46,17 +46,11 @@ module bitmanipalu #(parameter WIDTH=32) ( logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result logic [WIDTH-1:0] MaskB; // BitMask of B logic [WIDTH-1:0] RevA; // Bit-reversed A - logic W64; // RV64 W-type instruction - logic SubArith; // Performing subtraction or arithmetic right shift - logic ALUOp; // 0 for address generation addition or 1 for regular ALU ops logic Rotate; // Indicates if it is Rotate instruction logic Mask; // Indicates if it is ZBS instruction logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction logic [1:0] PreShiftAmt; // Amount to Pre-Shift A - // Extract control signals from ALUControl. - assign {W64, SubArith, ALUOp} = ALUControl; - // Extract control signals from bitmanip ALUControl. assign {Mask, PreShift} = BALUControl[1:0]; diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index ad599c8f..b436fda4 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -44,7 +44,7 @@ module bmuctrl( output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage // Execute stage control signals input logic StallE, FlushE, // Stall, flush Execute stage - output logic [2:0] ALUSelectE, + output logic [2:0] ALUSelectD, // ALU select 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 @@ -61,7 +61,7 @@ module bmuctrl( logic MaskD; // Indicates if zbs instruction in Decode Stage logic PreShiftD; // Indicates if sh1add, sh2add, sh3add instruction in Decode Stage logic [2:0] BALUControlD; // ALU Control signals for B instructions - logic [2:0] BALUSelectD, ALUSelectD; // ALU Mux select signal in Decode Stage + logic [2:0] BALUSelectD; // ALU Mux select signal in Decode Stage for BMU operations logic BALUOpD; // Indicates if it is an ALU B instruction in Decode Stage `define BMUCTRLW 17 @@ -179,5 +179,5 @@ module bmuctrl( assign ALUSelectD = BALUOpD ? BALUSelectD : (ALUOpD ? Funct3D : 3'b000); // BMU Execute stage pipieline control register - flopenrc#(13) controlregBMU(clk, reset, FlushE, ~StallE, {ALUSelectD, BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {ALUSelectE, BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE}); + flopenrc#(10) controlregBMU(clk, reset, FlushE, ~StallE, {BSelectD, ZBBSelectD, BRegWriteD, BComparatorSignedD, BALUControlD}, {BSelectE, ZBBSelectE, BRegWriteE, BComparatorSignedE, BALUControlE}); endmodule \ No newline at end of file diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 8bc68353..21811b49 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -45,7 +45,6 @@ module controller( input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) input logic FWriteIntE, // Write integer register, coming from FPU controller output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit) - output logic [2:0] ALUControlE, // ALU operation to perform output logic ALUSrcAE, ALUSrcBE, // ALU operands output logic ALUResultSrcE, // Selects result to pass on to Memory stage output logic [2:0] ALUSelectE, // ALU mux select signal @@ -54,6 +53,7 @@ module controller( output logic IntDivE, // Integer divide output logic MDUE, // MDU (multiply/divide) operatio output logic W64E, // RV64 W-type operation + output logic SubArithE, // Subtraction or arithmetic shift output logic JumpE, // jump instruction output logic BranchE, // Branch instruction output logic SCE, // Store Conditional instruction @@ -93,7 +93,7 @@ module controller( logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file logic [1:0] MemRWD, MemRWE; // Store (write to memory) logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3) - logic BaseALUOpD, BaseW64D; // ALU operation and W64 for Base instructions specifically + logic BaseW64D; // W64 for Base instructions specifically logic BaseRegWriteD; // Indicates if Base instruction register write instruction logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu logic BaseALUSrcBD; // Base instruction ALU B source select signal @@ -111,6 +111,7 @@ module controller( logic [`CTRLW-1:0] ControlsD; // Main Instruction Decoder control signals logic SubArithD; // TRUE for R-type subtracts and sra, slt, sltu or B-type ext clr, andn, orn, xnor logic subD, sraD, sltD, sltuD; // Indicates if is one of these instructions + logic ALUOpE; // 0 for address generationm 1 for ALU operations logic BranchTakenE; // Branch is taken logic eqE, ltE; // Comparator outputs logic unused; @@ -118,22 +119,18 @@ module controller( logic IEURegWriteE; // Register write logic BRegWriteE; // Register write from BMU controller in Execute Stage logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers - logic IllegalBitmanipInstrD; // Unrecognized B instruction logic [1:0] AtomicE; // Atomic instruction logic FenceD, FenceE; // Fence instruction logic SFenceVmaD; // sfence.vma instruction 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 BRegWriteD; // Indicates if it is a R type B instruction in decode stage - logic BW64D; // Indicates if it is a W type B instruction in decode stage - logic BSubArithD; // TRUE for B-type ext, clr, andn, orn, xnor - logic BALUSrcBD; // B-type alu src 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 logic FenceM; // Fence.I or sfence.VMA instruction in memory stage + logic [2:0] ALUSelectD; // ALU Output selection mux control // Extract fields assign OpD = InstrD[6:0]; @@ -231,17 +228,10 @@ module controller( // Squash control signals if coming from an illegal compressed instruction // On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them. assign IllegalERegAdrD = `E_SUPPORTED & `ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11]; - assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; //NOTE: Do we want to segregate the IllegalBitmanipInstrD into its own output signal //assign IllegalBaseInstrD = 1'b0; assign {BaseRegWriteD, ImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD, ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, PrivilegedD, FenceXD, MDUD, AtomicD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD; - - // If either bitmanip signal or base instruction signal - assign RegWriteD = BaseRegWriteD | BRegWriteD; - assign W64D = BaseW64D | BW64D; - assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD; - assign SubArithD = BaseSubArithD | BSubArithD; // TRUE If B-type or R-type instruction involves inverted operand assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? assign CSRWriteD = CSRReadD & !(CSRZeroSrcD & InstrD[13]); // Don't write if setting or clearing zeros @@ -253,34 +243,45 @@ module controller( assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi assign sraD = (Funct3D == 3'b101 & Funct7D[5]); assign BaseSubArithD = ALUOpD & (subD | sraD | sltD | sltuD); - assign ALUControlD = {W64D, SubArithD, ALUOpD}; // bit manipulation Configuration Block if (`ZBS_SUPPORTED | `ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED) begin: bitmanipi //change the conditional expression to OR any Z supported flags + logic IllegalBitmanipInstrD; // Unrecognized B instruction + logic BRegWriteD; // Indicates if it is a R type BMU instruction in decode stage + logic BW64D; // Indicates if it is a W type BMU instruction in decode stage + logic BSubArithD; // TRUE for BMU ext, clr, andn, orn, xnor + logic BALUSrcBD; // BMU alu src select signal + bmuctrl bmuctrl(.clk, .reset, .StallD, .FlushD, .InstrD, .ALUOpD, .BSelectD, .ZBBSelectD, .BRegWriteD, .BALUSrcBD, .BW64D, .BSubArithD, .IllegalBitmanipInstrD, .StallE, .FlushE, - .ALUSelectE, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .BALUControlE); + .ALUSelectD, .BSelectE, .ZBBSelectE, .BRegWriteE, .BComparatorSignedE, .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])) ; end else assign sltD = (Funct3D == 3'b010); + // Combine base and bit manipulation signals + assign IllegalBaseInstrD = (ControlsD[0] & IllegalBitmanipInstrD) | IllegalERegAdrD ; + assign RegWriteD = BaseRegWriteD | BRegWriteD; + assign W64D = BaseW64D | BW64D; + assign ALUSrcBD = BaseALUSrcBD | BALUSrcBD; + assign SubArithD = BaseSubArithD | BSubArithD; // TRUE If BMU or R-type instruction involves inverted operand + end else begin: bitmanipi - assign ALUSelectE = Funct3E; + assign ALUSelectD = ALUOpD ? Funct3D : 3'b000; // add for address generation when not doing ALU operation + assign sltD = (Funct3D == 3'b010); + assign IllegalBaseInstrD = ControlsD[0] | IllegalERegAdrD ; + assign RegWriteD = BaseRegWriteD; + assign W64D = BaseW64D; + assign ALUSrcBD = BaseALUSrcBD; + assign SubArithD = BaseSubArithD; // TRUE If B-type or R-type instruction involves inverted operand + + // tie off unused bit manipulation signals assign BSelectE = 2'b00; assign BSelectD = 2'b00; assign ZBBSelectE = 3'b000; - assign BRegWriteD = 1'b0; - assign BW64D = 1'b0; - assign BRegWriteE = 1'b0; - assign BSubArithD = 1'b0; assign BComparatorSignedE = 1'b0; assign BALUControlE = 3'b0; - assign BALUSrcBD = 1'b0; - - assign sltD = (Funct3D == 3'b010); - - assign IllegalBitmanipInstrD = 1'b1; end // Fences @@ -300,9 +301,9 @@ module controller( flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); // Execute stage pipeline control register and logic - flopenrc #(28) controlregE(clk, reset, FlushE, ~StallE, - {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD}, - {IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE}); + flopenrc #(29) controlregE(clk, reset, FlushE, ~StallE, + {ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, InstrValidD}, + {ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE}); // Branch Logic // The comparator handles both signed and unsigned branches using BranchSignedE diff --git a/src/ieu/datapath.sv b/src/ieu/datapath.sv index dc9a0289..a6fb1fdc 100644 --- a/src/ieu/datapath.sv +++ b/src/ieu/datapath.sv @@ -40,7 +40,8 @@ module datapath ( input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage input logic StallE, FlushE, // Stall, flush Execute stage input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages - input logic [2:0] ALUControlE, // Indicate operation ALU performs + input logic W64E, // W64-type instruction + input logic SubArithE, // Subtraction or arithmetic shift input logic ALUSrcAE, ALUSrcBE, // ALU operands input logic ALUResultSrcE, // Selects result to pass on to Memory stage input logic [2:0] ALUSelectE, // ALU mux select signal @@ -113,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, ALUControlE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE); + alu #(`XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, FlagsE, BALUControlE, ALUResultE, IEUAdrE); mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); diff --git a/src/ieu/ieu.sv b/src/ieu/ieu.sv index c436a96d..0fdba9e8 100644 --- a/src/ieu/ieu.sv +++ b/src/ieu/ieu.sv @@ -76,7 +76,6 @@ module ieu ( logic [2:0] ImmSrcD; // Select type of immediate extension logic [1:0] FlagsE; // Comparison flags ({eq, lt}) - logic [2:0] ALUControlE; // ALU control indicates function to perform logic ALUSrcAE, ALUSrcBE; // ALU source operands logic [2:0] ResultSrcW; // Selects result in Writeback stage logic ALUResultSrcE; // Selects ALU result to pass on to Memory stage @@ -87,6 +86,7 @@ module ieu ( logic [1:0] BSelectE; // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding logic [2:0] ZBBSelectE; // ZBB Result Select Signal in Execute Stage logic [2:0] BALUControlE; // ALU Control signals for B instructions in Execute Stage + logic SubArithE; // Subtraction or arithmetic shift // Forwarding signals logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers @@ -99,15 +99,15 @@ module ieu ( controller c( .clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD, .IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, - .PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, - .Funct3E, .IntDivE, .MDUE, .W64E, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM, + .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, + .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); datapath dp( - .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, - .ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, + .clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, + .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, From 5dfaf931e3e291733d6158b9febf1c832bea43f8 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 08:11:15 -0700 Subject: [PATCH 09/13] Avoid printing junk when running regression --- sim/regression-wally | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/regression-wally b/sim/regression-wally index 122b04b5..7a509c89 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -162,7 +162,7 @@ def run_test_case(config): """Run the given test case, and return 0 if the test suceeds and 1 if it fails""" logname = "logs/"+config.variant+"_"+config.name+".log" cmd = config.cmd.format(logname) - print(cmd) +# print(cmd) os.chdir(regressionDir) os.system(cmd) if search_log_for_text(config.grepstr, logname): From 59f948d47cdb0d9da186e6eb94bcf3ceecde3e29 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 08:12:02 -0700 Subject: [PATCH 10/13] Start of EBU coverage tests --- src/ebu/ebufsmarb.sv | 27 +++++++++++++++----------- testbench/tests.vh | 1 + tests/coverage/ebu.S | 45 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 tests/coverage/ebu.S diff --git a/src/ebu/ebufsmarb.sv b/src/ebu/ebufsmarb.sv index bd5cfb89..11d3eb2b 100644 --- a/src/ebu/ebufsmarb.sv +++ b/src/ebu/ebufsmarb.sv @@ -56,7 +56,7 @@ module ebufsmarb ( logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst logic BeatCntEn; - logic [4-1:0] NextBeatCount, BeatCount; // Position within a burst transfer + logic [3:0] BeatCount; // Position within a burst transfer logic CntReset; logic [3:0] Threshold; // Number of beats derived from HBURST @@ -91,31 +91,36 @@ module ebufsmarb ( // This is necessary because the pipeline is stalled for the entire duration of both transactions, // and the LSU memory request will stil be active. flopr #(1) ifureqreg(HCLK, ~HRESETn, IFUReq, IFUReqD); - assign LSUDisable = CurrState == ARBITRATE ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD)); - assign LSUSelect = NextState == ARBITRATE ? 1'b1: LSUReq; + assign LSUDisable = (CurrState == ARBITRATE) ? 1'b0 : (IFUReqD & ~(HREADY & FinalBeatD)); + assign LSUSelect = (NextState == ARBITRATE) ? 1'b1: LSUReq; //////////////////////////////////////////////////////////////////////////////////////////////////// // Burst mode logic //////////////////////////////////////////////////////////////////////////////////////////////////// - flopenr #(4) BeatCountReg(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, NextBeatCount, BeatCount); - assign NextBeatCount = BeatCount + 1'b1; - assign CntReset = NextState == IDLE; assign FinalBeat = (BeatCount == Threshold); // Detect when we are waiting on the final access. - assign BeatCntEn = (NextState == ARBITRATE & HREADY); - + assign BeatCntEn = (NextState == ARBITRATE) & HREADY; + counter #(4) BeatCounter(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, BeatCount); + // Used to store data from data phase of AHB. flopenr #(1) FinalBeatReg(HCLK, ~HRESETn | CntReset, BeatCntEn, FinalBeat, FinalBeatD); // unlike the bus fsm in lsu/ifu, we need to derive the number of beats from HBURST. - always_comb begin - case(HBURST) + // HBURST[2:1] Beats + // 00 1 + // 01 4 + // 10 8 + // 11 16 + always_comb + if (HBURST[2:1] == 2'b00) Threshold = 4'b0000; + else Threshold = (2 << HBURST[2:1]) - 1; +/* case(HBURST) 0: Threshold = 4'b0000; 3: Threshold = 4'b0011; // INCR4 5: Threshold = 4'b0111; // INCR8 7: Threshold = 4'b1111; // INCR16 default: Threshold = 4'b0000; // INCR without end. endcase - end + end */ endmodule diff --git a/testbench/tests.vh b/testbench/tests.vh index f5e02290..64b5ca59 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -45,6 +45,7 @@ string tvpaths[] = '{ string coverage64gc[] = '{ `COVERAGE, "ieu", + "ebu", "csrwrites" }; diff --git a/tests/coverage/ebu.S b/tests/coverage/ebu.S new file mode 100644 index 00000000..8c69f9d1 --- /dev/null +++ b/tests/coverage/ebu.S @@ -0,0 +1,45 @@ +/////////////////////////////////////////// +// ebu.S +// +// Written: David_Harris@hmc.edu 23 March 2023 +// +// Purpose: Test coverage for EBU +// +// 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 clz with all bits being 0 + li t0, 0 + clz t1, t0 + li t0, -1 + clz t1, t0 + li t0, 1 + clz t1, t0 + + # Test forwarding from store conditional + lr.w t0, 0(a0) + sc.w t0, a1, 0(a0) + addi t0, t0, 1 + + j done + From 25a1ea7d230b0b6be96d7dbcde7cd65e95ad0f3e Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 08:12:32 -0700 Subject: [PATCH 11/13] FPU detect illegal instructions --- src/fpu/fctrl.sv | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index e787d10b..5700e1b6 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -123,7 +123,7 @@ module fctrl ( 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??: ControlsD = `FCTRLW'b1_0_01_01_xx1_1_0_0; // fsqrt + 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 @@ -141,7 +141,8 @@ module fctrl ( 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) ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass + 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 From 34e0b3bc61c81ccee377fb2ea2570ffcfa2cacd4 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 08:27:30 -0700 Subject: [PATCH 12/13] Shifter sign simplification and capitalization --- src/ieu/alu.sv | 5 +---- src/ieu/shifter.sv | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 11759b1d..47af5f4d 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -51,14 +51,11 @@ module alu #(parameter WIDTH=32) ( logic Carry, Neg; // Flags: carry out, negative logic LT, LTU; // Less than, Less than unsigned logic Asign, Bsign; // Sign bits of A, B - logic ShiftSignA; // A, A sign bit muxes if (WIDTH == 64) begin - mux3 #(1) signmux(A[63], A[31], 1'b0, {~SubArith, W64}, ShiftSignA); mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux end else begin - mux2 #(1) signmux(1'b0, A[31], SubArith, ShiftSignA); assign CondExtA = A; end @@ -67,7 +64,7 @@ module alu #(parameter WIDTH=32) ( assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; // Shifts (configurable for rotation) - shifter sh(.A(CondExtA), .Sign(ShiftSignA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .Y(Shift), .Rotate(BALUControl[2])); + shifter sh(.A(CondExtA), .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2])); // Condition code flags are based on subtraction output Sum = A-B. // Overflow occurs when the numbers being subtracted have the opposite sign diff --git a/src/ieu/shifter.sv b/src/ieu/shifter.sv index d0a6471c..8dbdf88e 100644 --- a/src/ieu/shifter.sv +++ b/src/ieu/shifter.sv @@ -30,13 +30,16 @@ `include "wally-config.vh" module shifter ( - input logic [`XLEN-1:0] A, // shift Source - input logic [`LOG_XLEN-1:0] Amt, // Shift amount - input logic Right, Rotate, W64, Sign, // Shift right, rotate signals - output logic [`XLEN-1:0] Y); // Shifted result + input logic [`XLEN-1:0] A, // shift Source + input logic [`LOG_XLEN-1:0] Amt, // Shift amount + input logic Right, Rotate, W64, SubArith, // Shift right, rotate, W64-type operation, arithmetic shift + output logic [`XLEN-1:0] Y); // Shifted result - logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits - logic [`LOG_XLEN-1:0] amttrunc, offset; // Shift amount adjusted for RV64, right-shift amount + logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits + logic [`LOG_XLEN-1:0] amttrunc, Offset; // Shift amount adjusted for RV64, right-shift amount + logic Sign; // Sign bit for sign extension + + assign Sign = A[`XLEN-1] & SubArith; // sign bit for sign extension if (`ZBB_SUPPORTED) begin: rotfunnel if (`XLEN==32) begin // rv32 with rotates @@ -76,10 +79,10 @@ module shifter ( end // Opposite offset for right shifts - assign offset = Right ? amttrunc : ~amttrunc; + assign Offset = Right ? amttrunc : ~amttrunc; // Funnel operation - assign zshift = z >> offset; + assign zshift = z >> Offset; assign Y = zshift[`XLEN-1:0]; endmodule From 9f1c1958a60402f098d2dc413f1e8d3ddea01bd0 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 24 Mar 2023 08:35:33 -0700 Subject: [PATCH 13/13] Query about CondExtA --- src/ieu/alu.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index 47af5f4d..15328bb2 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -52,9 +52,9 @@ module alu #(parameter WIDTH=32) ( logic LT, LTU; // Less than, Less than unsigned logic Asign, Bsign; // Sign bits of A, B - // A, A sign bit muxes + // *** explain this part better; possibly move into shifter and BMU? if (WIDTH == 64) begin - mux3 #(64) extendmux({{32{1'b0}}, A[31:0]},{{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux + mux3 #(64) extendmux({{32{1'b0}}, A[31:0]}, {{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, CondExtA); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux end else begin assign CondExtA = A; end