rtl: Add custom scanchain
diff --git a/verilog/rtl/scanchain_gf180.v b/verilog/rtl/scanchain_gf180.v new file mode 100644 index 0000000..d1c8173 --- /dev/null +++ b/verilog/rtl/scanchain_gf180.v
@@ -0,0 +1,78 @@ +`default_nettype none + +module scanchain_local #( + parameter SCAN_LENGTH = 2) + ( + input wire clk_in, + input wire data_in, + input wire scan_select_in, + input wire latch_enable_in, + output wire clk_out, + output wire data_out, + output wire scan_select_out, + output wire latch_enable_out, + + // io, names from point of view of the user module + input wire [SCAN_LENGTH-1:0] module_data_out, + output wire [SCAN_LENGTH-1:0] module_data_in + ); + + // input buffers + // Looking at results from multiple projects the buffering is a bit + // inconsistent. So instead, we ensure at least clk buf + wire clk; + + gf180mcu_fd_sc_mcu7t5v0__buf_2 input_buf_clk ( + .I (clk_in), + .Z (clk), + .VDD (1'b1), + .VSS (1'b0) + ); + + // output buffers + // Same as for input, to try and be more consistent, we make our own + wire data_out_i; + + gf180mcu_fd_sc_mcu7t5v0__buf_4 output_buffers[3:0] ( + .I ({clk, data_out_i, scan_select_in, latch_enable_in }), + .Z ({clk_out, data_out, scan_select_out, latch_enable_out }), + .VDD (1'b1), + .VSS (1'b0) + ); + + // wires needed + wire [SCAN_LENGTH-1:0] scan_data_out; // output of the each scan chain flop + wire [SCAN_LENGTH-1:0] scan_data_in; // input of each scan chain flop + + // scan chain - link all the flops, with data coming from data_in + assign scan_data_in = {scan_data_out[SCAN_LENGTH-2:0], data_in}; + + // end of the chain is a negedge FF to increase hold margin between blocks + gf180mcu_fd_sc_mcu7t5v0__dffnq_1 out_flop ( + .CLKN (clk), + .D (scan_data_out[SCAN_LENGTH-1]), + .Q (data_out_i), + .VDD (1'b1), + .VSS (1'b0) + ); + + // scan flops have a mux on their inputs to choose either data from the user module or the previous flop's output + // https://antmicro-skywater-pdk-docs.readthedocs.io/en/test-submodules-in-rtd/contents/libraries/sky130_fd_sc_ls/cells/sdfxtp/README.html +`ifndef FORMAL +`ifndef FORMAL_COMPAT + gf180mcu_fd_sc_mcu7t5v0__sdffq_1 scan_flop [SCAN_LENGTH-1:0] ( + .CLK (clk), + .D (scan_data_in), + .SI (module_data_out), + .SE (scan_select_in), + .Q (scan_data_out), + .VDD (1'b1), + .VSS (1'b0) + ); + + /* Because we control the clock into serv, we can avoid the extra latches here */ + assign module_data_in = scan_data_out; +`endif + `endif + +endmodule