-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
scan_chain: Update with new 'invert-at-each-stage' scanchain
The scanchain.v module has less buffering stage in-to-out for reduced delay and outputs an inverted clock. The final FF stage is not pos-edge since the neg-edge trick is handled by outputing an inverted clock. The controller needs some update since you need more clock pulses to push things through now. Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
- Loading branch information
Showing
2 changed files
with
88 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,111 @@ | ||
`default_nettype none | ||
|
||
module scanchain ( | ||
input wire clk_in, | ||
input wire data_in, | ||
input wire scan_select_in, | ||
input wire latch_enable_in, | ||
module scanchain #( | ||
parameter NUM_IOS = 8 | ||
)( | ||
// Chain input | ||
input wire clk_in, | ||
input wire data_in, | ||
input wire scan_select_in, | ||
input wire latch_enable_in, | ||
|
||
// Chain output | ||
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 [NUM_IOS-1:0] module_data_out, | ||
// User module connections | ||
input wire [NUM_IOS-1:0] module_data_out, | ||
output wire [NUM_IOS-1:0] module_data_in | ||
); | ||
); | ||
|
||
// Signals | ||
// ------- | ||
|
||
// input buffers | ||
// Looking at results from multiple projects the buffering is a bit | ||
// inconsistent. So instead, we ensure at least clk buf | ||
// Internal clock | ||
wire clk; | ||
|
||
sky130_fd_sc_hd__clkbuf_2 input_buf_clk ( | ||
// Scan Flop chain | ||
wire [NUM_IOS-1:0] scan_data_out; | ||
wire [NUM_IOS-1:0] scan_data_in; | ||
|
||
|
||
// Clock distribution | ||
// ------------------ | ||
|
||
// Pass-through inverter | ||
sky130_fd_sc_hd__clkinv_4 buf_clk ( | ||
.A (clk_in), | ||
.X (clk), | ||
.Y (clk_out), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
|
||
// output buffers | ||
// Same as for input, to try and be more consistent, we make our own | ||
wire data_out_i; | ||
|
||
sky130_fd_sc_hd__buf_4 output_buffers[3:0] ( | ||
.A ({clk, data_out_i, scan_select_in, latch_enable_in }), | ||
.X ({clk_out, data_out, scan_select_out, latch_enable_out }), | ||
// Internal clock net inverter | ||
sky130_fd_sc_hd__clkinv_2 buf_clk_int ( | ||
.A (clk_out), | ||
.Y (clk), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
|
||
parameter NUM_IOS = 8; | ||
|
||
// wires needed | ||
wire [NUM_IOS-1:0] scan_data_out; // output of the each scan chain flop | ||
wire [NUM_IOS-1:0] scan_data_in; // input of each scan chain flop | ||
// wire [NUM_IOS-1:0] module_data_in; // the data that enters the user module | ||
// wire [NUM_IOS-1:0] module_data_out; // the data from the user module | ||
|
||
// scan chain - link all the flops, with data coming from data_in | ||
assign scan_data_in = {scan_data_out[NUM_IOS-2:0], data_in}; | ||
// Through buffers | ||
// --------------- | ||
|
||
// end of the chain is a negedge FF to increase hold margin between blocks | ||
sky130_fd_sc_hd__dfrtn_1 out_flop ( | ||
.RESET_B (1'b1), | ||
.CLK_N (clk), | ||
.D (scan_data_out[NUM_IOS-1]), | ||
.Q (data_out_i), | ||
sky130_fd_sc_hd__buf_4 through_buffers[1:0] ( | ||
.A ({ scan_select_in, latch_enable_in }), | ||
.X ({ scan_select_out, latch_enable_out }), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
|
||
|
||
// Scan Chain | ||
// ---------- | ||
|
||
// Link all the flops, with data coming from data_in | ||
assign scan_data_in = { scan_data_out[NUM_IOS-2:0], data_in }; | ||
|
||
// end of the chain output | ||
assign data_out_i = scan_data_out[NUM_IOS-1]; | ||
|
||
// 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 | ||
`ifndef FORMAL | ||
`ifndef FORMAL_COMPAT | ||
sky130_fd_sc_hd__sdfxtp_1 scan_flop [NUM_IOS-1:0] ( | ||
.CLK (clk), | ||
.D (scan_data_in), | ||
.SCD (module_data_out), | ||
.SCE (scan_select_in), | ||
.Q (scan_data_out), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
.CLK (clk), | ||
.D (scan_data_in), | ||
.SCD (module_data_out), | ||
.SCE (scan_select_in), | ||
.Q (scan_data_out), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
|
||
// end of the chain FF to compensate for clock inversion and lost cycle | ||
// between blocks | ||
sky130_fd_sc_hd__dfrtp_4 out_flop ( | ||
.RESET_B (1'b1), | ||
.CLK (clk), | ||
.D (scan_data_out[NUM_IOS-1]), | ||
.Q (data_out), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
|
||
// latch is used to latch the input data of the user module while the scan chain is used to capture the user module's outputs | ||
// https://antmicro-skywater-pdk-docs.readthedocs.io/en/test-submodules-in-rtd/contents/libraries/sky130_fd_sc_hd/cells/dlxtp/README.html | ||
sky130_fd_sc_hd__dlxtp_1 latch [NUM_IOS-1:0] ( | ||
.D (scan_data_out), | ||
.GATE (latch_enable_in), | ||
.Q (module_data_in), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
`endif | ||
`endif | ||
|
||
/* | ||
// instantiate the wokwi module | ||
user_module_USER_MODULE_ID user_module( | ||
.io_in (module_data_in), | ||
.io_out (module_data_out) | ||
.D (scan_data_out), | ||
.GATE (latch_enable_in), | ||
.Q (module_data_in), | ||
.VPWR (1'b1), | ||
.VGND (1'b0) | ||
); | ||
*/ | ||
`endif | ||
`endif | ||
|
||
endmodule | ||
endmodule // scanchain |