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,