wip: internal working as normal
diff --git a/configure.py b/configure.py index b5c5865..3d35a39 100755 --- a/configure.py +++ b/configure.py
@@ -263,32 +263,34 @@ assigns = """ localparam NUM_MACROS = {}; wire [NUM_MACROS:0] data, scan, latch, clk; - wire ready, slow_clk; - wire [8:0] active_select = io_in[20:12]; - wire [7:0] inputs = io_in[28:21]; - wire set_clk_div = io_in[11]; - wire [7:0] outputs; - assign io_out[36:29] = outputs; - assign io_out[37] = ready; - assign io_out[10] = slow_clk; """ scan_controller_template = """ scan_controller #(.NUM_DESIGNS(NUM_MACROS)) scan_controller( - .clk (wb_clk_i), - .reset (wb_rst_i), - .active_select (active_select), - .inputs (inputs), - .outputs (outputs), - .ready (ready), - .slow_clk (slow_clk), - .set_clk_div (set_clk_div), - .scan_clk (clk[0]), - .scan_data_out (data[0]), - .scan_data_in (data[NUM_MACROS]), - .scan_select (scan[0]), - .scan_latch_enable(latch[0]), - .oeb (io_oeb[37:29]) + .clk (wb_clk_i), + .reset (wb_rst_i), + .active_select (io_in[20:12]), + .inputs (io_in[28:21]), + .outputs (io_out[36:29]), + .ready (io_out[37]), + .slow_clk (io_out[10]), + .set_clk_div (io_in[11]), + + .scan_clk (clk[0]), + .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_data_in (la_data_in[1]), + .la_scan_data_out (la_data_out[0]), + .la_scan_select (la_data_in[2]), + .la_scan_latch_en (la_data_in[3]), + + .driver_sel (io_in[9:8]), + + .oeb (io_oeb) ); """
diff --git a/verilog/dv/scan_controller/test_scan_controller.py b/verilog/dv/scan_controller/test_scan_controller.py index 9c5616d..fd64c35 100644 --- a/verilog/dv/scan_controller/test_scan_controller.py +++ b/verilog/dv/scan_controller/test_scan_controller.py
@@ -33,12 +33,13 @@ return '?' @cocotb.test() -async def test(dut): +async def internal_controller(dut): clock = Clock(dut.clk, 100, units="ns") # 10 MHz cocotb.fork(clock.start()) dut.reset.value = 1 dut.set_clk_div.value = 0 + dut.driver_sel.value = 0b01 # internal controller dut.active_select.value = 12 # 7 seg seconds await ClockCycles(dut.clk, 10) dut.reset.value = 0 @@ -62,3 +63,4 @@ #assert decode_seg(dut.seven_seg.value) == i #await single_cycle(dut) await FallingEdge(dut.slow_clk) +
diff --git a/verilog/dv/scan_controller/test_scan_controller_tb.v b/verilog/dv/scan_controller/test_scan_controller_tb.v index c8cea33..15e5082 100644 --- a/verilog/dv/scan_controller/test_scan_controller_tb.v +++ b/verilog/dv/scan_controller/test_scan_controller_tb.v
@@ -8,6 +8,7 @@ input wire clk, input wire reset, + input wire [1:0] driver_sel, input wire [8:0] active_select, input wire [7:0] inputs, input wire set_clk_div, @@ -25,6 +26,7 @@ assign io_in[20:12] = active_select; assign io_in[28:21] = inputs; assign io_in[11] = set_clk_div; + assign io_in[9:8] = driver_sel; assign outputs = io_out[36:29]; assign ready = io_out[37]; assign slow_clk = io_out[10];
diff --git a/verilog/rtl/scan_controller/scan_controller.v b/verilog/rtl/scan_controller/scan_controller.v index 8883c35..60b366b 100644 --- a/verilog/rtl/scan_controller/scan_controller.v +++ b/verilog/rtl/scan_controller/scan_controller.v
@@ -5,22 +5,30 @@ 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 + input wire [7: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 + output wire [7: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, // see diagrams below for how the scan chain works - output wire scan_data_out, - input wire scan_data_in, - output wire scan_select, - output wire scan_latch_enable, + output wire scan_clk, // scan chain interface for the tiny designs + output wire scan_data_out, // see diagrams below for how the scan chain works + 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 wire [8:0] oeb // caravel harness needs output enable bar set low to enable outputs + input wire la_scan_clk, // logic analyser scan chain driver, driven by firmware running on Caravel's VexRisc + input wire la_scan_data_in, + 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 + + output wire [`MPRJ_IO_PADS-1:0] oeb // caravel harness needs output enable bar set low to enable outputs ); - assign oeb = 8'b0; + assign oeb = {`MPRJ_IO_PADS{1'b0}}; parameter NUM_DESIGNS = 8; parameter NUM_IOS = 8; @@ -31,6 +39,19 @@ localparam CAPTURE_STATE = 3; localparam LATCH = 4; + // scan chain muxing + wire ext_scan_clk; + wire ext_scan_data_out; + wire ext_scan_data_in; + wire ext_scan_select; + wire ext_scan_latch_en; + + 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_out : driver_sel == 2'b01 ? int_scan_data_out : la_scan_data_out; + 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; // reg reg [8:0] current_design; @@ -47,10 +68,10 @@ assign outputs = outputs_r; wire [8:0] active_select_rev = NUM_DESIGNS - 1 - active_select; assign ready = state == START; - assign scan_latch_enable = state == LATCH; - assign scan_clk = scan_clk_r; - assign scan_data_out = (state == LOAD && current_design == active_select_rev ) ? inputs_r[NUM_IOS-1-num_io] : 0; - assign scan_select = scan_select_out_r; + 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 ( @@ -141,7 +162,7 @@ if(scan_clk_r) begin num_io <= num_io + 1; if(current_design == active_select_rev) - output_buf[NUM_IOS-1-num_io] <= scan_data_in; + output_buf[NUM_IOS-1-num_io] <= int_scan_data_in; if(num_io == NUM_IOS - 1) begin num_io <= 0;