test logic analyser control of scan chain works
diff --git a/verilog/dv/scan_controller_la/Makefile b/verilog/dv/scan_controller_la/Makefile
new file mode 100644
index 0000000..eb95226
--- /dev/null
+++ b/verilog/dv/scan_controller_la/Makefile
@@ -0,0 +1,31 @@
+PWDD := $(shell pwd)
+BLOCKS := $(shell basename $(PWDD))
+
+# ---- Include Partitioned Makefiles ----
+
+CONFIG = caravel_user_project
+
+export COCOTB_REDUCED_LOG_FMT=1
+# Change this line if you want to use existing cocotb test modules:
+#export PYTHONPATH := $(DESIGNS)/verilog/rtl/<your design python tests>
+export LIBPYTHON_LOC=$(shell cocotb-config --libpython)
+
+
+include $(MCW_ROOT)/verilog/dv/make/env.makefile
+include $(MCW_ROOT)/verilog/dv/make/var.makefile
+include $(MCW_ROOT)/verilog/dv/make/cpu.makefile
+include $(MCW_ROOT)/verilog/dv/make/sim.makefile
+
+# change the project.hex to your projects firmware file
+coco_test: scan_controller.hex
+	rm -rf sim_build/
+	mkdir sim_build/
+
+    # change project_tb.v to match your testbench name
+	iverilog -Ttyp -DFUNCTIONAL -DSIM -DUSE_POWER_PINS -DUNIT_DELAY=#1 \
+	-f$(VERILOG_PATH)/includes/includes.rtl.caravel \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) -o sim_build/sim.vvp scan_controller_tb.v
+
+    # change this line to choose the comma separated test cases and the name of your python test module
+	TESTCASE=test_start MODULE=test_scan_controller vvp -M $$(cocotb-config --prefix)/cocotb/libs -m libcocotbvpi_icarus sim_build/sim.vvp
+	! grep failure results.xml
diff --git a/verilog/dv/scan_controller_la/README.md b/verilog/dv/scan_controller_la/README.md
new file mode 100644
index 0000000..7934b26
--- /dev/null
+++ b/verilog/dv/scan_controller_la/README.md
@@ -0,0 +1,7 @@
+# logic analyser test
+
+run
+
+    ./configure.py --update-caravel --limit 1
+
+before starting test
diff --git a/verilog/dv/scan_controller_la/scan_controller.c b/verilog/dv/scan_controller_la/scan_controller.c
new file mode 100644
index 0000000..1547b92
--- /dev/null
+++ b/verilog/dv/scan_controller_la/scan_controller.c
@@ -0,0 +1,103 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Efabless Corporation
+ *
+ * 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.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <defs.h>
+#include <stub.c>
+
+#define SET(PIN,N) (PIN |=  (1<<N))
+#define CLR(PIN,N) (PIN &= ~(1<<N))
+#define GET(PIN,N) (PIN &   (1<<N))
+
+// names from our perspective
+#define CLK         0 
+#define LATCH       3
+#define SCAN        2
+#define DATA_IN     0
+#define DATA_OUT    1
+
+#define FW_READY    12
+#define FW_DONE     13
+#define DATA_RX     14
+
+void main()
+{
+	/* 
+	IO Control Registers
+	| DM     | VTRIP | SLOW  | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+	| 3-bits | 1-bit | 1-bit | 1-bit  | 1-bit  | 1-bit | 1-bit   | 1-bit   | 1-bit | 1-bit | 1-bit   |
+
+	Output: 0000_0110_0000_1110  (0x1808) = GPIO_MODE_USER_STD_OUTPUT
+	| DM     | VTRIP | SLOW  | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+	| 110    | 0     | 0     | 0      | 0      | 0     | 0       | 1       | 0     | 0     | 0       |
+	
+	 
+	Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL
+	| DM     | VTRIP | SLOW  | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+	| 001    | 0     | 0     | 0      | 0      | 0     | 0       | 0       | 0     | 1     | 0       |
+
+	*/
+
+    // 2 inputs for enable logic analyser control
+	reg_mprj_io_8 =   GPIO_MODE_USER_STD_INPUT_NOPULL;
+	reg_mprj_io_9 =   GPIO_MODE_USER_STD_INPUT_NOPULL;
+
+    // outputs for testbench control
+    reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT; // fw ready
+    reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT; // fw done
+    reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT; // data rx
+
+    /* Apply configuration */
+    reg_mprj_xfer = 1;
+    while (reg_mprj_xfer == 1);
+
+    reg_la0_iena = 0x0; // input enable on
+    reg_la0_oenb = 0xFFFFFFFF; // enable all of bank0 logic analyser outputs (ignore the name, 1 is on, 0 off)
+
+	reg_mprj_datal |= 1 << FW_READY;
+
+    // fill scan chain data with 11110000
+    SET(reg_la0_data, DATA_OUT);
+    CLR(reg_la0_data, SCAN);
+    int i;
+    for(i = 0; i < 8; i ++)
+    {
+        SET(reg_la0_data, CLK);
+        CLR(reg_la0_data, CLK);
+        if(i == 3)
+            CLR(reg_la0_data, DATA_OUT);
+    }
+    // latch it
+    SET(reg_la0_data, LATCH);
+    CLR(reg_la0_data, LATCH);
+
+    // clock the data out of the modules into the chain
+    SET(reg_la0_data, SCAN);
+    SET(reg_la0_data, CLK);
+    CLR(reg_la0_data, CLK);
+    CLR(reg_la0_data, SCAN);
+    // wait for some data to arrive
+    for(i = 0; i < 8; i ++)
+    {
+        SET(reg_la0_data, CLK);
+        CLR(reg_la0_data, CLK);
+        if(GET(reg_la0_data_in, DATA_IN))
+            reg_mprj_datal |= 1 << DATA_RX;
+    }
+
+	reg_mprj_datal |= 1 << FW_DONE;
+}
+
diff --git a/verilog/dv/scan_controller_la/scan_controller.hex b/verilog/dv/scan_controller_la/scan_controller.hex
new file mode 100755
index 0000000..eada8bf
--- /dev/null
+++ b/verilog/dv/scan_controller_la/scan_controller.hex
@@ -0,0 +1,91 @@
+@00000000

+6F 00 00 0B 13 00 00 00 13 00 00 00 13 00 00 00 

+13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00 

+23 2E 11 FE 23 2C 51 FE 23 2A 61 FE 23 28 71 FE 

+23 26 A1 FE 23 24 B1 FE 23 22 C1 FE 23 20 D1 FE 

+23 2E E1 FC 23 2C F1 FC 23 2A 01 FD 23 28 11 FD 

+23 26 C1 FD 23 24 D1 FD 23 22 E1 FD 23 20 F1 FD 

+13 01 01 FC EF 00 40 11 83 20 C1 03 83 22 81 03 

+03 23 41 03 83 23 01 03 03 25 C1 02 83 25 81 02 

+03 26 41 02 83 26 01 02 03 27 C1 01 83 27 81 01 

+03 28 41 01 83 28 01 01 03 2E C1 00 83 2E 81 00 

+03 2F 41 00 83 2F 01 00 13 01 01 04 73 00 20 30 

+17 01 00 F1 13 01 01 75 17 05 00 00 13 05 85 F6 

+73 10 55 30 13 05 00 00 93 05 00 00 17 06 00 00 

+13 06 46 4D 63 0C B5 00 83 26 06 00 23 20 D5 00 

+13 05 45 00 13 06 46 00 6F F0 DF FE 13 05 00 00 

+93 05 80 00 63 08 B5 00 23 20 05 00 13 05 45 00 

+6F F0 5F FF 37 15 00 00 13 05 05 88 73 10 45 30 

+EF 00 C0 1A 6F 00 00 00 13 01 01 FF 23 26 81 00 

+13 04 01 01 13 00 00 00 03 24 C1 00 13 01 01 01 

+67 80 00 00 13 01 01 FF 23 26 81 00 13 04 01 01 

+13 00 00 00 03 24 C1 00 13 01 01 01 67 80 00 00 

+13 01 01 FE 23 2E 81 00 13 04 01 02 23 26 A4 FE 

+83 27 C4 FE 73 90 07 BC 13 00 00 00 03 24 C1 01 

+13 01 01 02 67 80 00 00 13 01 01 FF 23 26 11 00 

+23 24 81 00 13 04 01 01 13 05 00 00 EF F0 5F FC 

+B7 37 00 F0 93 87 87 03 13 07 A0 00 23 A0 E7 00 

+B7 37 00 F0 93 87 C7 03 37 07 02 00 23 A0 E7 00 

+13 07 10 00 23 10 E0 00 13 00 00 00 83 20 C1 00 

+03 24 81 00 13 01 01 01 67 80 00 00 13 01 01 FF 

+23 26 81 00 13 04 01 01 13 00 00 00 03 24 C1 00 

+13 01 01 01 67 80 00 00 13 01 01 FF 23 26 81 00 

+13 04 01 01 13 00 00 00 03 24 C1 00 13 01 01 01 

+67 80 00 00 13 01 01 FE 23 2E 11 00 23 2C 81 00 

+13 04 01 02 93 07 05 00 A3 07 F4 FE 03 47 F4 FE 

+93 07 A0 00 63 16 F7 00 13 05 D0 00 EF F0 9F FD 

+13 00 00 00 B7 67 00 F0 93 87 47 80 03 A7 07 00 

+93 07 10 00 E3 08 F7 FE B7 67 00 F0 93 87 07 80 

+03 47 F4 FE 23 A0 E7 00 13 00 00 00 83 20 C1 01 

+03 24 81 01 13 01 01 02 67 80 00 00 13 01 01 FE 

+23 2E 11 00 23 2C 81 00 13 04 01 02 23 26 A4 FE 

+6F 00 C0 01 83 27 C4 FE 13 87 17 00 23 26 E4 FE 

+83 C7 07 00 13 85 07 00 EF F0 DF F6 83 27 C4 FE 

+83 C7 07 00 E3 90 07 FE 13 00 00 00 83 20 C1 01 

+03 24 81 01 13 01 01 02 67 80 00 00 13 01 01 FE 

+23 2E 81 00 13 04 01 02 B7 07 00 26 93 87 47 04 

+13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 87 04 

+13 07 20 40 23 A0 E7 00 B7 07 00 26 93 87 47 05 

+37 27 00 00 13 07 97 80 23 A0 E7 00 B7 07 00 26 

+93 87 87 05 37 27 00 00 13 07 97 80 23 A0 E7 00 

+B7 07 00 26 93 87 C7 05 37 27 00 00 13 07 97 80 

+23 A0 E7 00 B7 07 00 26 13 07 10 00 23 A0 E7 00 

+13 00 00 00 B7 07 00 26 03 A7 07 00 93 07 10 00 

+E3 0A F7 FE B7 37 00 F0 93 87 C7 00 23 A0 07 00 

+B7 37 00 F0 93 87 C7 01 13 07 F0 FF 23 A0 E7 00 

+B7 07 00 26 93 87 C7 00 83 A6 07 00 B7 07 00 26 

+93 87 C7 00 37 17 00 00 33 E7 E6 00 23 A0 E7 00 

+B7 37 00 F0 93 87 C7 03 03 A7 07 00 B7 37 00 F0 

+93 87 C7 03 13 67 27 00 23 A0 E7 00 B7 37 00 F0 

+93 87 C7 03 03 A7 07 00 B7 37 00 F0 93 87 C7 03 

+13 77 B7 FF 23 A0 E7 00 23 26 04 FE 6F 00 00 07 

+B7 37 00 F0 93 87 C7 03 03 A7 07 00 B7 37 00 F0 

+93 87 C7 03 13 67 17 00 23 A0 E7 00 B7 37 00 F0 

+93 87 C7 03 03 A7 07 00 B7 37 00 F0 93 87 C7 03 

+13 77 E7 FF 23 A0 E7 00 03 27 C4 FE 93 07 30 00 

+63 10 F7 02 B7 37 00 F0 93 87 C7 03 03 A7 07 00 

+B7 37 00 F0 93 87 C7 03 13 77 D7 FF 23 A0 E7 00 

+83 27 C4 FE 93 87 17 00 23 26 F4 FE 03 27 C4 FE 

+93 07 70 00 E3 D6 E7 F8 B7 37 00 F0 93 87 C7 03 

+03 A7 07 00 B7 37 00 F0 93 87 C7 03 13 67 87 00 

+23 A0 E7 00 B7 37 00 F0 93 87 C7 03 03 A7 07 00 

+B7 37 00 F0 93 87 C7 03 13 77 77 FF 23 A0 E7 00 

+B7 37 00 F0 93 87 C7 03 03 A7 07 00 B7 37 00 F0 

+93 87 C7 03 13 67 47 00 23 A0 E7 00 B7 37 00 F0 

+93 87 C7 03 03 A7 07 00 B7 37 00 F0 93 87 C7 03 

+13 67 17 00 23 A0 E7 00 B7 37 00 F0 93 87 C7 03 

+03 A7 07 00 B7 37 00 F0 93 87 C7 03 13 77 E7 FF 

+23 A0 E7 00 B7 37 00 F0 93 87 C7 03 03 A7 07 00 

+B7 37 00 F0 93 87 C7 03 13 77 B7 FF 23 A0 E7 00 

+23 26 04 FE 6F 00 C0 07 B7 37 00 F0 93 87 C7 03 

+03 A7 07 00 B7 37 00 F0 93 87 C7 03 13 67 17 00 

+23 A0 E7 00 B7 37 00 F0 93 87 C7 03 03 A7 07 00 

+B7 37 00 F0 93 87 C7 03 13 77 E7 FF 23 A0 E7 00 

+B7 37 00 F0 93 87 C7 02 83 A7 07 00 93 F7 17 00 

+63 82 07 02 B7 07 00 26 93 87 C7 00 83 A6 07 00 

+B7 07 00 26 93 87 C7 00 37 47 00 00 33 E7 E6 00 

+23 A0 E7 00 83 27 C4 FE 93 87 17 00 23 26 F4 FE 

+03 27 C4 FE 93 07 70 00 E3 D0 E7 F8 B7 07 00 26 

+93 87 C7 00 83 A6 07 00 B7 07 00 26 93 87 C7 00 

+37 27 00 00 33 E7 E6 00 23 A0 E7 00 13 00 00 00 

+03 24 C1 01 13 01 01 02 67 80 00 00 

diff --git a/verilog/dv/scan_controller_la/scan_controller_la.gtkw b/verilog/dv/scan_controller_la/scan_controller_la.gtkw
new file mode 100644
index 0000000..cf6ba1a
--- /dev/null
+++ b/verilog/dv/scan_controller_la/scan_controller_la.gtkw
@@ -0,0 +1,48 @@
+[*]
+[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
+[*] Sun Aug 28 03:36:21 2022
+[*]
+[dumpfile] "/home/matt/work/asic-workshop/shuttle7/tinytapeout-mpw7/verilog/dv/scan_controller_la/scan_controller_tb.vcd"
+[dumpfile_mtime] "Sun Aug 28 03:33:58 2022"
+[dumpfile_size] 1544765
+[savefile] "/home/matt/work/asic-workshop/shuttle7/tinytapeout-mpw7/verilog/dv/scan_controller_la/scan_controller_la.gtkw"
+[timestart] 0
+[size] 1795 917
+[pos] -1 -1
+*-29.000000 1829000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] scan_controller_tb.
+[treeopen] scan_controller_tb.uut.
+[treeopen] scan_controller_tb.uut.mprj.
+[sst_width] 423
+[signals_width] 261
+[sst_expanded] 1
+[sst_vpaned_height] 254
+@28
+scan_controller_tb.clk
+scan_controller_tb.driver_sel[1:0]
+scan_controller_tb.fw_done
+scan_controller_tb.fw_ready
+scan_controller_tb.data_rx
+scan_controller_tb.uut.mprj.scan_controller.driver_sel[1:0]
+@800200
+-la scan chain
+@28
+scan_controller_tb.uut.mprj.scan_controller.la_scan_clk
+scan_controller_tb.uut.mprj.scan_controller.la_scan_data_in
+scan_controller_tb.uut.mprj.scan_controller.la_scan_data_out
+scan_controller_tb.uut.mprj.scan_controller.la_scan_latch_en
+scan_controller_tb.uut.mprj.scan_controller.la_scan_select
+@1000200
+-la scan chain
+@800200
+-scan chain
+@28
+scan_controller_tb.uut.mprj.scan_controller.scan_clk
+scan_controller_tb.uut.mprj.scan_controller.scan_data_in
+scan_controller_tb.uut.mprj.scan_controller.scan_data_out
+scan_controller_tb.uut.mprj.scan_controller.scan_latch_en
+scan_controller_tb.uut.mprj.scan_controller.scan_select
+@1000200
+-scan chain
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/verilog/dv/scan_controller_la/scan_controller_tb.v b/verilog/dv/scan_controller_la/scan_controller_tb.v
new file mode 100644
index 0000000..72b5efa
--- /dev/null
+++ b/verilog/dv/scan_controller_la/scan_controller_tb.v
@@ -0,0 +1,97 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// 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.
+// SPDX-License-Identifier: Apache-2.0
+
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+// change module name to something that suits your project
+module scan_controller_tb;
+    initial begin
+        // change to suit your project
+        $dumpfile ("scan_controller_tb.vcd");
+        $dumpvars (0, scan_controller_tb);
+        #1;
+    end
+
+    reg clk;
+    reg RSTB;
+    reg power1, power2;
+    reg power3, power4;
+
+    wire gpio;
+    wire [37:0] mprj_io;
+
+    ///// convenience signals that match what the cocotb test modules are looking for
+    // change to suit your project. Here's how we can make some nicer named signals for inputs & outputs
+    wire fw_ready = mprj_io[12];
+    wire fw_done = mprj_io[13];
+    wire data_rx = mprj_io[14];
+
+    wire [1:0] driver_sel;
+    assign mprj_io[9:8] = driver_sel;
+    /////
+    
+
+    wire flash_csb;
+    wire flash_clk;
+    wire flash_io0;
+    wire flash_io1;
+
+    wire VDD3V3 = power1;
+    wire VDD1V8 = power2;
+    wire USER_VDD3V3 = power3;
+    wire USER_VDD1V8 = power4;
+    wire VSS = 1'b0;
+
+    caravel uut (
+        .vddio    (VDD3V3),
+        .vssio    (VSS),
+        .vdda     (VDD3V3),
+        .vssa     (VSS),
+        .vccd     (VDD1V8),
+        .vssd     (VSS),
+        .vdda1    (USER_VDD3V3),
+        .vdda2    (USER_VDD3V3),
+        .vssa1    (VSS),
+        .vssa2    (VSS),
+        .vccd1    (USER_VDD1V8),
+        .vccd2    (USER_VDD1V8),
+        .vssd1    (VSS),
+        .vssd2    (VSS),
+        .clock    (clk),
+        .gpio     (gpio),
+        .mprj_io  (mprj_io),
+        .flash_csb(flash_csb),
+        .flash_clk(flash_clk),
+        .flash_io0(flash_io0),
+        .flash_io1(flash_io1),
+        .resetb   (RSTB)
+    );
+
+    spiflash #(
+        // change the hex file to match your project
+        .FILENAME("scan_controller.hex")
+    ) spiflash (
+        .csb(flash_csb),
+        .clk(flash_clk),
+        .io0(flash_io0),
+        .io1(flash_io1),
+        .io2(),         // not used
+        .io3()          // not used
+    );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/scan_controller_la/test_scan_controller.py b/verilog/dv/scan_controller_la/test_scan_controller.py
new file mode 100644
index 0000000..9d7907e
--- /dev/null
+++ b/verilog/dv/scan_controller_la/test_scan_controller.py
@@ -0,0 +1,40 @@
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import RisingEdge, FallingEdge, ClockCycles, with_timeout
+
+@cocotb.test()
+async def test_start(dut):
+    clock = Clock(dut.clk, 25, units="ns") # 40M
+    cocotb.fork(clock.start())
+   
+    dut.driver_sel.value = 0b10 # logic analyser
+    dut.RSTB.value = 0
+    dut.power1.value = 0
+    dut.power2.value = 0
+    dut.power3.value = 0
+    dut.power4.value = 0
+
+    await ClockCycles(dut.clk, 8)
+    dut.power1.value = 1
+    await ClockCycles(dut.clk, 8)
+    dut.power2.value = 1
+    await ClockCycles(dut.clk, 8)
+    dut.power3.value = 1
+    await ClockCycles(dut.clk, 8)
+    dut.power4.value = 1
+
+    await ClockCycles(dut.clk, 80)
+    dut.RSTB.value = 1
+
+    # wait with a timeout for the project to become active
+    await with_timeout(RisingEdge(dut.fw_ready), 350, 'us')
+    print("firmware ready")
+
+    # wait
+    await with_timeout(RisingEdge(dut.fw_done), 2800, 'us')
+
+    assert(dut.fw_done == 1)
+    assert(dut.data_rx == 1)
+
+    await ClockCycles(dut.clk, 100)
+