formal mux proof
diff --git a/verilog/rtl/scan_controller/Makefile b/verilog/rtl/scan_controller/Makefile
new file mode 100644
index 0000000..408fcf6
--- /dev/null
+++ b/verilog/rtl/scan_controller/Makefile
@@ -0,0 +1,2 @@
+prove_mux:
+ sby -f scan_mux.sby
diff --git a/verilog/rtl/scan_controller/properties.v b/verilog/rtl/scan_controller/properties.v
new file mode 100644
index 0000000..c104f6a
--- /dev/null
+++ b/verilog/rtl/scan_controller/properties.v
@@ -0,0 +1,23 @@
+always @(*) begin
+ if(driver_sel == 2'b00) begin // external driver
+ assert(outputs[0] == scan_data_in);
+ assert(scan_clk == ext_scan_clk);
+ 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_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_data_in == int_scan_data_in);
+ assert(scan_select == int_scan_select);
+ assert(scan_latch_en == int_scan_latch_en);
+ end
+end
diff --git a/verilog/rtl/scan_controller/scan_controller.v b/verilog/rtl/scan_controller/scan_controller.v
index 60b366b..d9f8f96 100644
--- a/verilog/rtl/scan_controller/scan_controller.v
+++ b/verilog/rtl/scan_controller/scan_controller.v
@@ -11,14 +11,14 @@
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
+ 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
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,
input wire la_scan_clk, // logic analyser scan chain driver, driven by firmware running on Caravel's VexRisc
- input wire la_scan_data_in,
+ input wire la_scan_data_in, // signal names from perspective of this module
output wire la_scan_data_out,
input wire la_scan_select,
input wire la_scan_latch_en,
@@ -40,18 +40,25 @@
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;
+ // 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_out : driver_sel == 2'b01 ? int_scan_data_out : la_scan_data_out;
+ 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;
+ wire int_scan_data_in = scan_data_in;
+ wire 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;
@@ -65,7 +72,6 @@
reg [7:0] output_buf;
// wires
- assign outputs = outputs_r;
wire [8:0] active_select_rev = NUM_DESIGNS - 1 - active_select;
assign ready = state == START;
wire int_scan_latch_en = state == LATCH;
@@ -114,7 +120,7 @@
*/
- // FSM
+ // FSM, only run it if driver_sel is set to internal
always @(posedge clk) begin
if(reset) begin
current_design <= 0;
@@ -124,7 +130,7 @@
scan_clk_r <= 0;
num_io <= 0;
output_buf <= 0;
- end else begin
+ end else if (driver_sel == 2'b01) begin
case(state)
START: begin
state <= LOAD;
diff --git a/verilog/rtl/scan_controller/scan_mux.sby b/verilog/rtl/scan_controller/scan_mux.sby
new file mode 100644
index 0000000..57fe264
--- /dev/null
+++ b/verilog/rtl/scan_controller/scan_mux.sby
@@ -0,0 +1,13 @@
+[options]
+mode prove
+
+[engines]
+smtbmc
+
+[script]
+read -formal -DMPRJ_IO_PADS=38 scan_controller.v
+prep -top scan_controller
+
+[files]
+scan_controller.v
+properties.v