Generic test bench for loads/stores.

Change-Id: I1193581f8240826da99592c6193e58ece7edfb04
diff --git a/hdl/chisel/src/bus/BUILD b/hdl/chisel/src/bus/BUILD
index 9a6f1e3..0a257c2 100644
--- a/hdl/chisel/src/bus/BUILD
+++ b/hdl/chisel/src/bus/BUILD
@@ -100,6 +100,7 @@
 AXI2TLUL_TESTCASES = [
     "test_write_request",
     "test_read_request",
+    "test_read_error",
 ]
 # END_TESTCASES_FOR_axi2tlul_cocotb_test
 
diff --git a/tests/cocotb/BUILD b/tests/cocotb/BUILD
index 206b156..5259869 100644
--- a/tests/cocotb/BUILD
+++ b/tests/cocotb/BUILD
@@ -182,6 +182,7 @@
     "load16_segment2_stride6_m1",
     "load8_indexed_m1",
     "store8_indexed_m1",
+    "load_store8_test",
 ]
 # END_TESTCASES_FOR_rvv_load_store_test
 
@@ -189,6 +190,7 @@
 RVV_ARITHMETIC_TESTCASES = [
     "arithmetic_m1_vanilla_ops",
     "reduction_m1_vanilla_ops",
+    "widen_math_ops_test_impl",
 ]
 # END_TESTCASES_FOR_rvv_arithmetic_cocotb_test
 
diff --git a/tests/cocotb/rvv/load_store/BUILD b/tests/cocotb/rvv/load_store/BUILD
index aa9dd02..167cd30 100644
--- a/tests/cocotb/rvv/load_store/BUILD
+++ b/tests/cocotb/rvv/load_store/BUILD
@@ -56,6 +56,9 @@
         "load8_stride2_mf4": {
             "srcs": ["load8_stride2_mf4.cc"],
         },
+        "load_store8_test": {
+            "srcs": ["load_store8_test.cc"],
+        },
         "load_store8_unit_m2": {
             "srcs": ["load_store8_unit_m2.cc"],
         },
@@ -101,6 +104,7 @@
         ":load8_stride2_m1.elf",
         ":load8_stride2_m1_partial.elf",
         ":load8_stride2_mf4.elf",
+        ":load_store8_test.elf",
         ":load_store8_unit_m2.elf",
         ":load_store16_unit_m2.elf",
         ":load_store32_unit_m2.elf",
diff --git a/tests/cocotb/rvv/load_store/load_store8_test.cc b/tests/cocotb/rvv/load_store/load_store8_test.cc
new file mode 100644
index 0000000..7b0f3cd
--- /dev/null
+++ b/tests/cocotb/rvv/load_store/load_store8_test.cc
@@ -0,0 +1,32 @@
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// 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.
+
+#include <riscv_vector.h>
+#include <stdint.h>
+
+// A fully parameterized test that executes a m1 unit load/store pair. Addresses
+// can be overridden with the `in_ptr` and `out_ptr` variables and data size
+// can be overridden via the `vl` parameter.
+
+uint8_t buffer[4096] __attribute__((section(".data")));
+uint8_t* in_ptr __attribute__((section(".data"))) = &(buffer[0]);
+uint8_t* out_ptr __attribute__((section(".data"))) = &(buffer[0]);
+size_t vl __attribute__((section(".data"))) = 16 ;
+
+int main() {
+  vuint8m1_t v = __riscv_vle8_v_u8m1(in_ptr, vl);
+  __riscv_vse8_v_u8m1(out_ptr, v, vl);
+
+  return 0;
+}
diff --git a/tests/cocotb/rvv_load_store_test.py b/tests/cocotb/rvv_load_store_test.py
index 5fcdd5d..78da0b4 100644
--- a/tests/cocotb/rvv_load_store_test.py
+++ b/tests/cocotb/rvv_load_store_test.py
@@ -382,3 +382,29 @@
         elf_name = 'store8_indexed_m1.elf',
         dtype = np.uint8,
     )
+
+@cocotb.test()
+async def load_store8_test(dut):
+    """Testbench to test RVV load."""
+    fixture = await Fixture.Create(dut)
+    r = runfiles.Create()
+    await fixture.load_elf_and_lookup_symbols(
+        r.Rlocation('kelvin_hw/tests/cocotb/rvv/load_store/load_store8_test.elf'),
+        ['buffer', 'in_ptr', 'out_ptr', 'vl'],
+    )
+
+    vl = 16
+    input_data = np.random.randint(0, 255, vl, dtype=np.uint8)
+    target_in_addr = fixture.symbols['buffer'] + 16
+    target_out_addr = fixture.symbols['buffer'] + 64
+
+    await fixture.core_mini_axi.write(target_in_addr, input_data)
+    await fixture.write('in_ptr', np.array([target_in_addr], dtype=np.uint32))
+    await fixture.write('out_ptr', np.array([target_out_addr], dtype=np.uint32))
+    await fixture.write('vl', np.array([vl], dtype=np.uint32))
+
+    await fixture.run_to_halt()
+
+    routputs = (await fixture.core_mini_axi.read(target_out_addr, vl)).view(
+        np.uint8)
+    assert (input_data == routputs).all()