Fix index>data indexed load >m1 Add a new counter alongside lmul to determine which section of index vectors to use. Bad test cases are fixed. Change-Id: I07fa4cfa6d60f2a2fe745912f6e0e1f889522441
diff --git a/hdl/chisel/src/kelvin/scalar/Lsu.scala b/hdl/chisel/src/kelvin/scalar/Lsu.scala index a20845e..49e656d 100644 --- a/hdl/chisel/src/kelvin/scalar/Lsu.scala +++ b/hdl/chisel/src/kelvin/scalar/Lsu.scala
@@ -291,6 +291,7 @@ // Additional internal states to help drive derived outputs. val rdStart = UInt(5.W) val rd = UInt(5.W) + val indexParition = new LoopingCounter(2.W) def subvectorDone(): Bool = subvector.isFull() def segmentDone(): Bool = subvectorDone() && segment.isFull() @@ -308,7 +309,8 @@ segmentDone() -> (rdStart + lmul.next().curr), // Jump all lmuls to next seg. subvectorDone() -> (rd + lmul.max + 1.U), - )) + )), + _.indexParition -> Mux(segmentDone(), indexParition.next(), indexParition), ) override def toPrintable: Printable = { @@ -390,6 +392,17 @@ result.vectorLoop := vectorLoop val segmentBaseAddr = baseAddr + (segmentStride * vectorLoop.segment.curr) + val bitsPerSlot = bytesPerSlot * 8 + val indices = MuxCase(rvv2lsu.idx.bits.data, Seq( + // 2 of 2 + ((vectorLoop.indexParition.curr === 1.U) && (vectorLoop.indexParition.max === 1.U)) -> (rvv2lsu.idx.bits.data(bitsPerSlot - 1, bitsPerSlot / 2)), + // 2 of 4 + ((vectorLoop.indexParition.curr === 1.U) && (vectorLoop.indexParition.max === 3.U)) -> (rvv2lsu.idx.bits.data(bitsPerSlot / 2 - 1, bitsPerSlot / 4)), + // 3 of 4 + ((vectorLoop.indexParition.curr === 2.U) && (vectorLoop.indexParition.max === 3.U)) -> (rvv2lsu.idx.bits.data(bitsPerSlot * 3 / 4 - 1, bitsPerSlot / 2)), + // 4 of 4 + ((vectorLoop.indexParition.curr === 3.U) && (vectorLoop.indexParition.max === 3.U)) -> (rvv2lsu.idx.bits.data(bitsPerSlot - 1, bitsPerSlot * 3 / 4)), + )) result.addrs := MuxCase(addrs, Seq( op.isOneOf(LsuOp.VLOAD_UNIT, LsuOp.VSTORE_UNIT) -> ComputeStridedAddrs(bytesPerSlot, segmentBaseAddr, elemStride, elemWidth), @@ -397,7 +410,7 @@ ComputeStridedAddrs(bytesPerSlot, segmentBaseAddr, elemStride, elemWidth), op.isOneOf(LsuOp.VLOAD_OINDEXED, LsuOp.VLOAD_UINDEXED, LsuOp.VSTORE_OINDEXED, LsuOp.VSTORE_UINDEXED) -> - ComputeIndexedAddrs(bytesPerSlot, baseAddr, rvv2lsu.idx.bits.data, + ComputeIndexedAddrs(bytesPerSlot, baseAddr, indices, elemWidth, sew), )) result.elemWidth := elemWidth @@ -595,6 +608,15 @@ ((elemMultiplier === 4.U) && (uop.lmul.get.asSInt >= 0.S)) -> 3.U, ((elemMultiplier === 4.U) && (uop.lmul.get.asSInt === -1.S)) -> 1.U, )) + // [0..x] data vecs we can operate on with one index vec + val indexParitions = MuxCase(0.U, Seq( + // 16-bit data, 8-bit indices + ((elemWidth === "b000".U) && (uop.sew.get === 1.U)) -> 1.U, + // 32-bit data, 8-bit indices + ((elemWidth === "b000".U) && (uop.sew.get === 2.U)) -> 3.U, + // 32-bit data, 16-bit indices + ((elemWidth === "b101".U) && (uop.sew.get === 2.U)) -> 1.U, + )) result.vectorLoop := MakeWireBundle[LsuVectorLoop]( new LsuVectorLoop, _.isActive -> LsuOp.isVector(uop.op), @@ -604,6 +626,7 @@ _.lmul -> LoopingCounter((1.U(4.W) << effectiveLmul) - 1.U), _.rdStart -> uop.rd, _.rd -> uop.rd, + _.indexParition -> LoopingCounter(indexParitions), ) }
diff --git a/tests/cocotb/rvv_load_store_test.py b/tests/cocotb/rvv_load_store_test.py index f7c6aa6..1e0d7e6 100644 --- a/tests/cocotb/rvv_load_store_test.py +++ b/tests/cocotb/rvv_load_store_test.py
@@ -658,23 +658,23 @@ make_test_case('vluxei8_v_u16mf2', vl = 3), make_test_case('vluxei8_v_u16m1', vl = 8), make_test_case('vluxei8_v_u16m1', vl = 7), - # make_test_case('vluxei8_v_u16m2', vl = 16), - # make_test_case('vluxei8_v_u16m2', vl = 15), - # make_test_case('vluxei8_v_u16m4', vl = 32), - # make_test_case('vluxei8_v_u16m4', vl = 31), - # make_test_case('vluxei8_v_u16m8', vl = 64), - # make_test_case('vluxei8_v_u16m8', vl = 63), + make_test_case('vluxei8_v_u16m2', vl = 16), + make_test_case('vluxei8_v_u16m2', vl = 15), + make_test_case('vluxei8_v_u16m4', vl = 32), + make_test_case('vluxei8_v_u16m4', vl = 31), + make_test_case('vluxei8_v_u16m8', vl = 64), + make_test_case('vluxei8_v_u16m8', vl = 63), # Ordered make_test_case('vloxei8_v_u16mf2', vl = 4), make_test_case('vloxei8_v_u16mf2', vl = 3), make_test_case('vloxei8_v_u16m1', vl = 8), make_test_case('vloxei8_v_u16m1', vl = 7), - # make_test_case('vloxei8_v_u16m1', vl = 16), - # make_test_case('vloxei8_v_u16m1', vl = 15), - # make_test_case('vloxei8_v_u16m4', vl = 32), - # make_test_case('vloxei8_v_u16m4', vl = 31), - # make_test_case('vloxei8_v_u16m8', vl = 64), - # make_test_case('vloxei8_v_u16m8', vl = 63), + make_test_case('vloxei8_v_u16m2', vl = 16), + make_test_case('vloxei8_v_u16m2', vl = 15), + make_test_case('vloxei8_v_u16m4', vl = 32), + make_test_case('vloxei8_v_u16m4', vl = 31), + make_test_case('vloxei8_v_u16m8', vl = 64), + make_test_case('vloxei8_v_u16m8', vl = 63), ], dtype = np.uint16, index_dtype = np.uint8, @@ -765,21 +765,21 @@ # Unordered make_test_case('vluxei8_v_u32m1', vl = 4), make_test_case('vluxei8_v_u32m1', vl = 3), - # make_test_case('vluxei8_v_u32m2', vl = 8), - # make_test_case('vluxei8_v_u32m2', vl = 7), - # make_test_case('vluxei8_v_u32m4', vl = 16), - # make_test_case('vluxei8_v_u32m4', vl = 15), - # make_test_case('vluxei8_v_u32m8', vl = 32), - # make_test_case('vluxei8_v_u32m8', vl = 31), + make_test_case('vluxei8_v_u32m2', vl = 8), + make_test_case('vluxei8_v_u32m2', vl = 7), + make_test_case('vluxei8_v_u32m4', vl = 16), + make_test_case('vluxei8_v_u32m4', vl = 15), + make_test_case('vluxei8_v_u32m8', vl = 32), + make_test_case('vluxei8_v_u32m8', vl = 31), # Ordered make_test_case('vloxei8_v_u32m1', vl = 4), make_test_case('vloxei8_v_u32m1', vl = 3), - # make_test_case('vloxei8_v_u32m1', vl = 16), - # make_test_case('vloxei8_v_u32m1', vl = 15), - # make_test_case('vloxei8_v_u32m4', vl = 32), - # make_test_case('vloxei8_v_u32m4', vl = 31), - # make_test_case('vloxei8_v_u32m8', vl = 64), - # make_test_case('vloxei8_v_u32m8', vl = 63), + make_test_case('vloxei8_v_u32m2', vl = 8), + make_test_case('vloxei8_v_u32m2', vl = 7), + make_test_case('vloxei8_v_u32m4', vl = 16), + make_test_case('vloxei8_v_u32m4', vl = 15), + make_test_case('vloxei8_v_u32m8', vl = 32), + make_test_case('vloxei8_v_u32m8', vl = 31), ], dtype = np.uint32, index_dtype = np.uint8,