New scan controller

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
diff --git a/configure.py b/configure.py
index ebb2106..637ca8f 100755
--- a/configure.py
+++ b/configure.py
@@ -290,13 +290,14 @@
             .slow_clk               (io_out[10]),
             .set_clk_div            (io_in[11]),
 
-            .scan_clk               (clk[0]),
+            .scan_clk_in            (clk[0]),
+            .scan_clk_out           (clk[NUM_MACROS]),
             .scan_data_out          (data[0]),
             .scan_data_in           (data[NUM_MACROS]),
             .scan_select            (scan[0]),
             .scan_latch_en          (latch[0]),
 
-            .la_scan_clk            (la_data_in[0]),
+            .la_scan_clk_in         (la_data_in[0]),
             .la_scan_data_in        (la_data_in[1]),
             .la_scan_data_out       (la_data_out[0]),
             .la_scan_select         (la_data_in[2]),
diff --git a/verilog/rtl/scan_controller/properties.v b/verilog/rtl/scan_controller/properties.v
index c104f6a..5825c57 100644
--- a/verilog/rtl/scan_controller/properties.v
+++ b/verilog/rtl/scan_controller/properties.v
@@ -1,22 +1,24 @@
 always @(*) begin
     if(driver_sel == 2'b00) begin // external driver
-        assert(outputs[0]    == scan_data_in);
-        assert(scan_clk      == ext_scan_clk);
+        assert(outputs[0]    == scan_clk_in);
+        assert(outputs[1]    == scan_data_in);
+        assert(scan_clk_out  == inputs[0]);
         assert(scan_data_out == inputs[1]);
         assert(scan_select   == inputs[2]);
         assert(scan_latch_en == inputs[3]);
     end else
     if(driver_sel == 2'b10) begin // external driver
         assert(la_scan_data_out == scan_data_in);
-        assert(scan_clk      == la_scan_clk);
+        assert(scan_clk_out  == la_scan_clk);
         assert(scan_data_out == la_scan_data_in);
         assert(scan_select   == la_scan_select);
         assert(scan_latch_en == la_scan_latch_en);
     end else
     if(driver_sel == 2'b01) begin // internal driver
         assert(int_scan_data_out == scan_data_out);
-        assert(scan_clk      == int_scan_clk);
+        assert(scan_clk__out == int_scan_clk_out);
         assert(scan_data_in  == int_scan_data_in);
+        assert(scan_clk_in   == int_scan_clk_in);
         assert(scan_select   == int_scan_select);
         assert(scan_latch_en == int_scan_latch_en);
     end
diff --git a/verilog/rtl/scan_controller/scan_controller.v b/verilog/rtl/scan_controller/scan_controller.v
index 1591991..1b37af3 100644
--- a/verilog/rtl/scan_controller/scan_controller.v
+++ b/verilog/rtl/scan_controller/scan_controller.v
@@ -1,226 +1,450 @@
+`timescale 1ns / 100ps
 `default_nettype none
 
-module scan_controller (
+module scan_controller #(
+    parameter integer NUM_DESIGNS = 8,
+    parameter integer NUM_IOS     = 8,
+
+    // auto-set
+    parameter integer PL = NUM_IOS - 1
+)(
     input  wire clk,
     input  wire reset,
 
     input  wire [8:0] active_select,    // which design is connected to the inputs and outputs
-    input  wire [7:0] inputs,           // inputs to the design (or external scan chain)
+    input  wire [PL:0] inputs,           // inputs to the design (or external scan chain)
     input  wire set_clk_div,            // set clock divider. See module below
-    output wire [7:0] outputs,          // outputs from the design (or external scan chain)
+    output wire [PL:0] outputs,          // outputs from the design (or external scan chain)
     output wire ready,                  // debug output that goes high once per refresh
     output wire slow_clk,               // debug clock divider output
 
-    output wire scan_clk,               // scan chain interface for the tiny designs, from perspective of this module
-    output wire scan_data_out,          // see diagrams below for how the scan chain works
+    output reg  scan_clk_out,           // scan chain interface for the tiny designs, from perspective of this module
+    output reg  scan_data_out,          // see diagrams below for how the scan chain works
+    input  wire scan_clk_in,            // feedback clock after having done the whole round
     input  wire scan_data_in,           // will be driven by internal driver, external gpio pins, or Caravel logic analyser
-    output wire scan_select,            // external scan chain driver muxes with ins/outs, eg microcontroller outside the ASIC
-    output wire scan_latch_en,
+    output reg  scan_select,            // external scan chain driver muxes with ins/outs, eg microcontroller outside the ASIC
+    output reg  scan_latch_en,
 
-    input  wire la_scan_clk,            // logic analyser scan chain driver, driven by firmware running on Caravel's VexRisc 
-    input  wire la_scan_data_in,        // signal names from perspective of this module
+    input  wire la_scan_clk_in,         // logic analyser scan chain driver, driven by firmware running on Caravel's VexRisc
+    input  wire la_scan_data_in,        // signal names from perspective of this module toward scan chain
     output wire la_scan_data_out,
     input  wire la_scan_select,
     input  wire la_scan_latch_en,
 
-    input  wire [1:0] driver_sel,       // 00 = external, 01 = internal, 10 = logic analyser
+    input  wire [1:0] driver_sel,       // 00 = external, 01 = logic analyzer, 1x = internal
 
     output wire [`MPRJ_IO_PADS-1:0] oeb // caravel harness needs output enable bar set low to enable outputs
-    );
+);
 
+    // Signals
+    // -------
+
+    // Reset
+    reg  [2:0]  rst_shift;
+    wire        rst_i;
+
+    // Muxing
+        // _in / _out are from the perspecitve of this module toward the scan
+        // chain. So all _in are FROM the scan chain (and either input to this
+        // module from there, or output from this module to LA / External)
+
+    wire        ext_scan_clk_in;
+    wire        ext_scan_data_in;
+    wire        ext_scan_clk_out;
+    wire        ext_scan_data_out;
+    wire        ext_scan_select;
+    wire        ext_scan_latch_en;
+
+    wire        int_scan_clk_in;
+    wire        int_scan_data_in;
+    reg         int_scan_clk_out;
+    reg         int_scan_data_out;
+    reg         int_scan_select;
+    reg         int_scan_latch_en;
+
+    // FSM
+    localparam [3:0]
+        ST_IDLE             = 0,    // Idle
+        ST_IN_LOAD          = 1,    // Capture input
+        ST_IN_SHIFT_LO      = 2,    // Shift input to design: lo-clk
+        ST_IN_SHIFT_HI      = 3,    // Shift input to design: hi-clk
+        ST_IN_LATCH_WAIT    = 4,    // Wait before latching
+        ST_IN_LATCH         = 5,    // Latch
+        ST_OUT_LOAD_PRE     = 6,    // Prepare load
+        ST_OUT_LOAD         = 7,    // Clock once to load
+        ST_OUT_LOAD_POST    = 8,    // Wait for load to be done
+        ST_OUT_LOAD_CLR     = 9,    // Restore chain to shift mode
+        ST_OUT_SHIFT_LO     = 10,   // Shift output to us: lo-clk
+        ST_OUT_SHIFT_HI     = 11,   // Shift output to us: hi-clk
+        ST_OUT_CAP_WAIT     = 12,   // Wait for capture
+        ST_OUT_CAP          = 13;   // Capture to out local register
+
+    reg       active;
+
+    reg [3:0] state;
+    reg [3:0] state_nxt;
+
+    // Scan progress
+    reg [$clog2(NUM_IOS)-1:0] bit_cnt;
+    wire                      bit_last;
+
+    reg   [8:0] proj_cnt;
+    wire        proj_sel;
+    wire        proj_done;
+
+    // Auto IO
+    reg  [PL:0] aio_input_sync;
+    reg  [PL:0] aio_input_reg;
+    reg  [PL:0] aio_input_shift;
+
+    reg  [PL:0] aio_output_shift;
+    reg  [PL:0] aio_output_reg;
+
+    wire        aio_input_sh;
+    wire        aio_input_ld;
+    wire        aio_output_cap;
+
+    // Wait state config
+    reg   [7:0] ws_cnt;
+    wire        ws_cnt_done;
+    wire        ws_cnt_run;
+
+    // Wait state config
+    reg  [2:0]  ws_set_sync;
+    reg         ws_set_now;
+    reg  [7:0]  ws_cfg;
+
+    // Clock divider
+    wire        slow_clk_ena;
+
+
+    // Misc
+    // ----
+
+    // Generate internal ties for the IO blocks
     assign oeb = {`MPRJ_IO_PADS{1'b0}};
 
-    parameter NUM_DESIGNS = 8; 
-    parameter NUM_IOS     = 8;
-
-    localparam START = 0;
-    localparam LOAD = 1;
-    localparam READ = 2;
-    localparam CAPTURE_STATE = 3;
-    localparam LATCH = 4;
-                    
-    // scan chain muxing
-    // signal names in perspective of this module
-    wire ext_scan_clk       = inputs[0];
-    wire ext_scan_data_in   = inputs[1];
-    wire ext_scan_data_out  = scan_data_in;
-    wire ext_scan_select    = inputs[2];   
-    wire ext_scan_latch_en  = inputs[3];
-
-    assign scan_clk         = driver_sel == 2'b00 ? ext_scan_clk      : driver_sel == 2'b01 ? int_scan_clk      : la_scan_clk;
-    assign scan_data_out    = driver_sel == 2'b00 ? ext_scan_data_in  : driver_sel == 2'b01 ? int_scan_data_out : la_scan_data_in;
-    assign scan_select      = driver_sel == 2'b00 ? ext_scan_select   : driver_sel == 2'b01 ? int_scan_select   : la_scan_select;
-    assign scan_latch_en    = driver_sel == 2'b00 ? ext_scan_latch_en : driver_sel == 2'b01 ? int_scan_latch_en : la_scan_latch_en;
-
-    wire int_scan_data_in   = scan_data_in;
-    assign la_scan_data_out = scan_data_in;
-    assign outputs          = driver_sel == 2'b01 ? outputs_r : {7'b0, ext_scan_data_out};
-
     `ifdef FORMAL
         `include "properties.v"
     `endif
 
-    // reg
-    reg [8:0] current_design;
-    reg [2:0] state;
-    reg [3:0] num_io;
-    reg scan_clk_r;
-    reg scan_select_out_r;
+    // Generate our own reset, with de-assertion
+    // synchronized to clock
+    always @(posedge clk or posedge reset)
+        if (reset)
+            rst_shift <= 3'b111;
+        else
+            rst_shift <= { rst_shift[1:0], 1'b0 };
 
-    reg [7:0] inputs_r;
-    reg [7:0] outputs_r;
-    reg [7:0] output_buf;
-
-    // wires
-    wire [8:0] active_select_rev = NUM_DESIGNS - 1 - active_select;
-    assign ready = state == START;
-    wire int_scan_latch_en = state == LATCH;
-    wire int_scan_clk = scan_clk_r;
-    wire int_scan_data_out = (state == LOAD && current_design == active_select_rev ) ? inputs_r[NUM_IOS-1-num_io] : 0;
-    wire int_scan_select = scan_select_out_r;
-
-    // clock divider
-    clk_divider clk_divider (
-        .clk            (clk),
-        .set            (set_clk_div),
-        .reset          (reset),
-        .divider        (inputs),
-        .slow_clk       (slow_clk)
-    );
-    wire [7:0] inputs_and_clk = set_clk_div ? { inputs[7:1], slow_clk } : inputs;
-
-    /*
-
-    LOAD
-
-             ┌──┐  ┌──┐  ┌──┐  ┌──┐              
-    clk    : ┘  └──┘  └──┘  └──┘  └──────────────
-             ┐                                   
-    scan en: └───────────────────────────────────
-             ┐                       ┌─────┐     
-    latch  : └───────────────────────┘     └─────
-             ┐     ┌─────┐     ┌─────┐           
-    data o : └─────┘     └─────┘     └───────────
-             xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-    data i : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+    assign rst_i = rst_shift[2];
 
 
-    READ
+    // Scan chain and IO muxing
+    // ------------------------
 
-             ┌──┐  ┌──┐  ┌──┐  ┌──┐  ┌──┐  ┌──┐  
-    clk    : ┘  └──┘  └──┘  └──┘  └──┘  └──┘  └──
-             ┐     ┌─────┐                       
-    scan en: └─────┘     └───────────────────────
-             ┐                                   
-    latch  : └───────────────────────────────────
-             xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-    data o : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-             ┐           ┌─────┐     ┌─────┐     
-    data i : └───────────┘     └─────┘     └─────
+        // To ensure we get something working, the scan chain can be driven
+        // three different ways. Automatic, from caravel LA and fully
+        // externally (see driver_sel input)
 
-    */
+    // External interface
+    assign ext_scan_clk_out   = inputs[0];
+    assign ext_scan_data_out  = inputs[1];
+    assign ext_scan_select    = inputs[2];
+    assign ext_scan_latch_en  = inputs[3];
 
-    // FSM, only run it if driver_sel is set to internal
-    always @(posedge clk) begin
-        if(reset) begin
-            current_design <= 0;
-            state <= START; 
-            inputs_r <= 0;
-            outputs_r <= 0;
-            scan_clk_r <= 0;
-            num_io <= 0;
-            output_buf <= 0;
-        end else if (driver_sel == 2'b01) begin
-            case(state)
-                START: begin
-                    state <= LOAD;
-                    inputs_r <= inputs_and_clk;
-                    outputs_r <= output_buf;
-                    current_design <= 0;
-                    scan_select_out_r <= 0;
-                end
+    assign ext_scan_clk_in    = scan_clk_in;
+    assign ext_scan_data_in   = scan_data_in;
 
-                LOAD: begin
-                    scan_clk_r <= ~scan_clk_r;
-                    if(scan_clk_r) begin
-                        num_io <= num_io + 1;
+    // Internal interface
+    assign int_scan_clk_in    = scan_clk_in;
+    assign int_scan_data_in   = scan_data_in;
 
-                        if(num_io == NUM_IOS - 1) begin
-                            num_io <= 0;
-                            current_design <= current_design + 1;
-                        
-                            if(current_design == NUM_DESIGNS - 1)
-                                state <= LATCH;
-                        end
+    // LA interface
+    assign la_scan_data_out   = scan_data_in;
 
-                    end
-
-                end
-                LATCH: begin
-                    state <= READ;
-                    current_design <= 0;
-                    scan_select_out_r <= 1;
-                end
-            
-                READ: begin
-                    scan_select_out_r <= 0;
-                    scan_clk_r <= ~scan_clk_r;
-                    if(scan_clk_r) begin
-                        num_io <= num_io + 1;
-                        if(current_design == active_select_rev)
-                            output_buf[NUM_IOS-1-num_io] <= int_scan_data_in;
-
-                        if(num_io == NUM_IOS - 1) begin
-                            num_io <= 0;
-                            current_design <= current_design + 1;
-
-
-                            if(current_design == NUM_DESIGNS - 1) begin
-                                state <= START;
-                            end
-                        end
-                    end
-                end
-            endcase
-        end
-    end
-
-endmodule
-
-module clk_divider (
-    input clk,
-    input reset,
-    input set,
-    input [DIV_WIDTH-1:0] divider,
-    output slow_clk
-    );
-    
-    // fastest useful clock period must be < max refresh rate: 750Hz
-    // 10M with 14bit divider (min) gives ~610Hz
-    // 10M with 22bit divider (max) gives ~2.4Hz
-    localparam MIN_WIDTH = 13;
-    localparam DIV_WIDTH = 8;
-
-    reg [MIN_WIDTH+8:0] counter;
-    reg [DIV_WIDTH-1:0] compare;
-    reg last_set;
-
-    assign slow_clk = counter[MIN_WIDTH + compare];
-
-    always @(posedge clk) begin
-        if(reset) begin
-            counter <= 0;
-            compare <= 0;
-            last_set <= 0;
-        end
-        else begin
-            // update divider on positive edge of set
-            if(set && !last_set) begin
-                compare <= divider;
+    // Mux toward scan-schain
+    always @(*)
+    begin
+        casez (driver_sel)
+            // External
+            2'b00: begin
+                scan_clk_out  = ext_scan_clk_out;
+                scan_data_out = ext_scan_data_out;
+                scan_select   = ext_scan_select;
+                scan_latch_en = ext_scan_latch_en;
             end
-            counter <= counter + 1'b1;
-            last_set <= set;
-        end
+
+            // Caravel LA
+            2'b01: begin
+                scan_clk_out  = la_scan_clk_in;
+                scan_data_out = la_scan_data_in;
+                scan_select   = la_scan_select;
+                scan_latch_en = la_scan_latch_en;
+            end
+
+            // Internal
+            2'b1z: begin
+                scan_clk_out  = int_scan_clk_out;
+                scan_data_out = int_scan_data_out;
+                scan_select   = int_scan_select;
+                scan_latch_en = int_scan_latch_en;
+            end
+        endcase
     end
 
-endmodule
+    // Synchronizer for inputs
+    always @(posedge clk)
+    begin
+        aio_input_sync <= inputs;
+        aio_input_reg  <= driver_sel[1] ? aio_input_sync : 0;
+    end
+
+    // Mux for outputs
+    assign outputs = driver_sel[1] ? aio_output_reg : {6'b0, ext_scan_data_in, ext_scan_clk_in};
+
+
+    // FSM & control
+    // -------------
+
+    // Check if we're active
+    always @(posedge clk or posedge rst_i)
+        if (rst_i)
+            active <= 1'b0;
+        else
+            active <= driver_sel[1];
+
+    // State register
+    always @(posedge clk or posedge rst_i)
+        if (rst_i)
+            state <= ST_IDLE;
+        else
+            state <= state_nxt;
+
+    // State transitions
+    always @(*)
+    begin
+        // Defaults
+        state_nxt = state;
+
+        // Transitions
+        case (state)
+            ST_IDLE:
+                if (active)
+                    state_nxt = ST_IN_LOAD;
+
+            ST_IN_LOAD:
+                state_nxt = ST_IN_SHIFT_LO;
+
+            ST_IN_SHIFT_LO:
+                state_nxt = ST_IN_SHIFT_HI;
+
+            ST_IN_SHIFT_HI:
+                state_nxt = (proj_sel & bit_last) ? ST_IN_LATCH_WAIT : ST_IN_SHIFT_LO;
+
+            ST_IN_LATCH_WAIT:
+                if (ws_cnt_done)
+                    state_nxt = ST_IN_LATCH;
+
+            ST_IN_LATCH:
+                state_nxt = ST_OUT_LOAD_PRE;
+
+            ST_OUT_LOAD_PRE:
+                if (ws_cnt_done)
+                    state_nxt = ST_OUT_LOAD;
+
+            ST_OUT_LOAD:
+                state_nxt = ST_OUT_LOAD_POST;
+
+            ST_OUT_LOAD_POST:
+                if (ws_cnt_done)
+                    state_nxt = ST_OUT_LOAD_CLR;
+
+            ST_OUT_LOAD_CLR:
+                if (ws_cnt_done)
+                    state_nxt = ST_OUT_SHIFT_LO;
+
+            ST_OUT_SHIFT_LO:
+                state_nxt = ST_OUT_SHIFT_HI;
+
+            ST_OUT_SHIFT_HI:
+                state_nxt = (proj_done & bit_last) ? ST_OUT_CAP_WAIT : ST_OUT_SHIFT_LO;
+
+            ST_OUT_CAP_WAIT:
+                if (ws_cnt_done)
+                    state_nxt = ST_OUT_CAP;
+
+            ST_OUT_CAP:
+                state_nxt = ST_IDLE;
+        endcase
+    end
+
+
+    // Scan progress tracking
+    // ----------------------
+
+    // Keep track of IO number
+    always @(posedge clk)
+        if (state == ST_IDLE)
+            bit_cnt <= 0;
+        else if ((state == ST_IN_SHIFT_HI) | (state == ST_OUT_SHIFT_HI))
+            bit_cnt <= bit_last ? 0 : (bit_cnt + 1);
+
+    assign bit_last = (bit_cnt == (NUM_IOS - 1));
+
+    // Keep track of project number
+    always @(posedge clk)
+        if (state == ST_IDLE)
+            proj_cnt <= 0;
+        else if (((state == ST_IN_SHIFT_HI) | (state == ST_OUT_SHIFT_HI)) & bit_last)
+            proj_cnt <= proj_cnt + 1;
+
+    assign proj_sel  = (proj_cnt == active_select);
+    assign proj_done = (proj_cnt == NUM_DESIGNS);
+
+
+    // Scan chain control
+    // ------------------
+
+    always @(posedge clk)
+    begin
+        int_scan_clk_out  <= (state == ST_IN_SHIFT_HI)  | (state == ST_OUT_LOAD) | (state == ST_OUT_SHIFT_HI);
+        int_scan_data_out <= aio_input_shift[PL];
+        int_scan_select   <= (state == ST_OUT_LOAD_PRE) | (state == ST_OUT_LOAD) | (state == ST_OUT_LOAD_POST);
+        int_scan_latch_en <= (state == ST_IN_LATCH);
+    end
+
+
+    // Shift registers
+    // ---------------
+
+    // Local control from FSM
+    assign aio_input_sh   = (state == ST_IN_SHIFT_HI);
+    assign aio_input_ld   = (state == ST_IN_LOAD);
+    assign aio_output_cap = (state == ST_OUT_CAP);
+
+    // Input
+    always @(posedge clk)
+        if (aio_input_ld)
+            aio_input_shift <= slow_clk_ena ? { aio_input_reg[PL-1:1], slow_clk } : aio_input_reg;
+        else if (aio_input_sh)
+            aio_input_shift <= { aio_input_shift[PL-1:0], 1'b0 };
+
+    // Output
+    always @(posedge int_scan_clk_in)
+        aio_output_shift <= { aio_output_shift[PL-1:0], int_scan_data_in };
+
+    always @(posedge clk)
+        if (aio_output_cap)
+            aio_output_reg <= aio_output_shift;
+
+
+    // Wait state counter
+    // ------------------
+
+    always @(posedge clk)
+        if (~ws_cnt_run | ws_cnt_done)
+            ws_cnt <= 0;
+        else
+            ws_cnt <= ws_cnt + 1;
+
+    assign ws_cnt_done = (ws_cnt == ws_cfg);
+
+    assign ws_cnt_run = (
+        (state == ST_IN_LATCH_WAIT) |
+        (state == ST_OUT_LOAD_PRE) |
+        (state == ST_OUT_LOAD_POST) |
+        (state == ST_OUT_LOAD_CLR)  |
+        (state == ST_OUT_CAP_WAIT)
+    );
+
+
+    // Wait state config
+    // -----------------
+
+        // This dictates how many wait cycle we insert in various state
+        // of the load process. We have a sane default, but also allow
+        // override externally.
+
+    always @(posedge clk or posedge rst_i)
+        if (rst_i)
+            ws_set_sync <= 3'b000;
+        else
+            ws_set_sync <= { ws_set_sync[1:0], (driver_sel == 2'b11) };
+
+    always @(posedge clk)
+        ws_set_now <= ~ws_set_sync[2] & ws_set_sync[1];
+
+    always @(posedge clk or posedge rst_i)
+        if (rst_i)
+            ws_cfg <= 8'd10;
+        else if (ws_set_now)
+            ws_cfg <= inputs;
+
+
+    // Clock Divider
+    // -------------
+
+    clk_divider clk_divider_I (
+        .clk      (clk),
+        .ce       (aio_input_ld),
+        .set      (set_clk_div),
+        .reset    (rst_i),
+        .divider  (inputs),
+        .active   (slow_clk_ena),
+        .slow_clk (slow_clk)
+    );
+
+endmodule // scan_controller
+
+
+module clk_divider #(
+    parameter integer DIV_WIDTH = 8
+)(
+    input  wire clk,
+    input  wire ce,
+    input  wire reset,
+    input  wire set,
+    input  wire [DIV_WIDTH-1:0] divider,
+    output wire active,
+    output reg  slow_clk
+);
+
+    reg [DIV_WIDTH-1:0] counter;
+    reg [DIV_WIDTH-1:0] compare;
+    wire                match;
+
+    reg [2:0] set_sync;
+    reg       set_now;
+
+    // Detect rising edge (with synchronizer)
+    always @(posedge clk)
+    begin
+        set_sync <= { set_sync[1:0], set };
+        set_now  <= ~set_sync[2] & set_sync[1];
+    end
+
+    assign active = set_sync[2];
+
+    // Latch divider
+    always @(posedge clk)
+        if (set_now)
+            compare <= divider;
+
+    // Compare
+    assign match = (counter == compare);
+
+    // Counter
+    always @(posedge clk or posedge reset)
+        if (reset)
+            counter <= 0;
+        else if (ce)
+            counter <= match ? 0 : (counter + 1);
+
+    // Clock gen
+    always @(posedge clk or posedge reset)
+        if (reset)
+            slow_clk <= 1'b0;
+        else if (ce)
+            slow_clk <= slow_clk ^ match;
+
+endmodule // clk_divider
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 7fcce1c..2674df0 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -96,13 +96,14 @@
             .slow_clk               (io_out[10]),
             .set_clk_div            (io_in[11]),
 
-            .scan_clk               (clk[0]),
+            .scan_clk_out           (clk[0]),
+            .scan_clk_in            (clk[NUM_MACROS]),
             .scan_data_out          (data[0]),
             .scan_data_in           (data[NUM_MACROS]),
             .scan_select            (scan[0]),
             .scan_latch_en          (latch[0]),
 
-            .la_scan_clk            (la_data_in[0]),
+            .la_scan_clk_in         (la_data_in[0]),
             .la_scan_data_in        (la_data_in[1]),
             .la_scan_data_out       (la_data_out[0]),
             .la_scan_select         (la_data_in[2]),