Text Generation
PEFT
Safetensors
English
lora
qwen2.5-coder
verilog
eda
dft
test-point-insertion
reinforcement-learning
grpo
conversational
Instructions to use SKLP-EDA-LAB/Tesla-Pro-TPI with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use SKLP-EDA-LAB/Tesla-Pro-TPI with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-Coder-7B-Instruct") model = PeftModel.from_pretrained(base_model, "SKLP-EDA-LAB/Tesla-Pro-TPI") - Notebooks
- Google Colab
- Kaggle
| ===== SYSTEM ===== | |
| Respond in the following format: | |
| <think> | |
| ... | |
| </think> | |
| <total_design> | |
| ... | |
| </total_design> | |
| ===== USER ===== | |
| ## RULE #1: KEEP EVERY LINE OF THE ORIGINAL RTL | |
| This is the most important rule. The #RTL CODE# section below contains the complete RTL. | |
| You MUST output the FULL module -- every line stays exactly as it is, except for additions required by the chosen TPI mode: | |
| (a) CP or CP+OP: add `cp_en` using the same port declaration style as the original RTL. OP-only: do NOT add `cp_en`. | |
| (b) OP or CP+OP: add `tp_xxx` ports using the same port declaration style as the original RTL. CP-only: no `tp_*` port is required for that bit. | |
| (c) CP or CP+OP: add CP function definitions at the TOP of the module body. | |
| (d) CP or CP+OP: modify the target register assignment inside always blocks by wrapping the next value with the CP function call. | |
| (e) OP or CP+OP: add OP instantiations inside the module body (before `endmodule`). | |
| (f) OP or CP+OP: add only the required TestPointOBType_* module definitions AFTER the top module's `endmodule`. | |
| DO NOT remove, rewrite, reformat, or regenerate any original RTL code. | |
| DO NOT touch the module name, port list (except adding required cp_en/tp_* ports), parameters, reg/wire declarations, | |
| always blocks, assign statements, or any other original code. | |
| PORT STYLE: The original RTL uses ANSI-style ports. | |
| - Add new ports directly in the module port list with direction/type. | |
| - CP/CP+OP example: `input wire cp_en, output wire tp_sig1`. | |
| - OP-only example: `output wire tp_sig1`. | |
| - Do NOT add separate `input cp_en;` / `output tp_sig1;` declarations in the module body. | |
| ## ACTUAL TASK INPUT SUMMARY (READ THIS BEFORE ANY TESTABILITY SCORING) | |
| #Required TPI Count#: 3 | |
| #Forbidden Scan Cell Bits for THIS sample#: | |
| counter[0] | |
| Legality equation for this sample: | |
| chosen_tpi_bits ∩ forbidden_scan_bits MUST be empty. | |
| If even one chosen CP-only, OP-only, or CP+OP bit is in the forbidden list, the answer is invalid. | |
| CRITICAL LOW-BIT WARNING for this sample: | |
| The following attractive low-order bits are FORBIDDEN here: counter[0] | |
| Do not choose them even if they toggle frequently. Start scoring only after removing them. | |
| How to derive legal non-scan candidates from the RTL and scan-cell list: | |
| 1) Parse the ORIGINAL RTL declarations and sequential assignments to identify real register bits only. | |
| Legal targets must be declared as `reg`, `output reg`, or be assigned in a clocked always block. | |
| Do NOT choose plain `wire`, `input`, combinational temporary wires, or invented signal names. | |
| 2) Expand vectors bit-by-bit. Example: `reg [7:0] data_reg;` creates `data_reg[7]` ... `data_reg[0]`. | |
| Scalar registers keep their exact scalar name unless the RTL itself uses an indexed form. | |
| Unpacked register arrays are allowed only with exact static indices: `reg [31:0] stack [7:0];` creates | |
| bits such as `stack[7][8]`. Do NOT select dynamic elements such as `stack[write_ptr]`. | |
| 3) Normalize scan-cell names conservatively: remove a leading backslash, remove ONLY the final `_reg` suffix, | |
| keep every other part of the RTL name, and keep the bit index. | |
| Example: `\data_reg_reg[8]` -> `data_reg[8]`, NOT `data[8]`. | |
| Example: `\cc_reg[31]` -> `cc[31]`. | |
| 4) Compute: legal_non_scan_register_bits = RTL_declared_register_bits - normalized_forbidden_scan_bits. | |
| 5) Choose TPI bits only from legal_non_scan_register_bits. If a chosen name is not an exact RTL register bit, | |
| the answer is invalid even if the name looks semantically reasonable. | |
| Your first reasoning step must remove these exact forbidden bits from consideration. | |
| Never say the scan-cell list is empty unless the list above is literally empty. | |
| ## MANDATORY RULES | |
| 1. SCAN-CELL EXCLUSION CONSTRAINT (HIGHEST PRIORITY after Rule #1) | |
| #Scan Cell Bits# are scan cells selected by AutoPSS. | |
| These bits are already scan-controllable/observable and MUST NOT be selected for TPI. | |
| Treat #Scan Cell Bits# as an exact FORBIDDEN bit list, not as a recommendation. | |
| All test points MUST be inserted on non-scan register bits, i.e. register bits NOT listed in #Scan Cell Bits#. | |
| If a vector is partially scanned, legality is bit-specific: if cnt[0], cnt[1], cnt[2], cnt[3] are scan cells, then cnt[4] may be legal but cnt[0]..cnt[3] are forbidden. | |
| Low-order bits such as cnt[0], Q[0], state[0], filter[0], data[0] are often attractive because they toggle frequently, but they are STILL ILLEGAL if listed in #Scan Cell Bits#. | |
| Do not select a scan bit for CP-only, OP-only, or CP+OP under any circumstance. | |
| WRONG: Selecting a register bit that appears in #Scan Cell Bits#, even if it has high activity or strong testability. | |
| RIGHT: First remove every scan-cell bit from the candidate set, then choose TPI only from the remaining non-scan bits. | |
| 1b. RTL REGISTER-BIT GROUNDING CONSTRAINT | |
| Before selecting TPI, explicitly derive legal candidates as: | |
| RTL_declared_register_bits - normalized_forbidden_scan_bits. | |
| Use the exact RTL signal name. Do not shorten, singularize, or rename registers. | |
| WRONG: RTL declares `data_reg`; selecting `data`. | |
| WRONG: scan cell `\data_reg_reg[8]` is normalized to `data[8]`. | |
| RIGHT: scan cell `\data_reg_reg[8]` is normalized to `data_reg[8]` because only the final `_reg` is removed. | |
| If the RTL declares `state`, do not select `state_reg` unless that exact register exists in the RTL. | |
| Every selected bit must be visible in the original RTL declaration or clocked assignment. | |
| Register arrays/memories are legal only when the target is bit-precise and statically indexed. | |
| RIGHT: `stack[7][8]` if RTL declares `reg [31:0] stack [7:0];`. | |
| WRONG: `stack[write_ptr]`, `stack[7]` as a whole row when the budget is for single bits, or any dynamic index. | |
| 2. TPI Counting (IS = Intervention Site = 1 bit) | |
| - 1-bit CP-only = 1 IS | 1-bit OP-only = 1 IS | 1-bit CP+OP = 1 IS | |
| - N-bit OP = N IS (must use `TestPointOBType_Nbit`) | |
| - `output [7:0] tp_a;` = 8 IS. You CANNOT pack multiple IS into one vector. | |
| - Total IS MUST equal exactly 3. | |
| Counting EXAMPLES (CRITICAL -- same bit shared by CP+OP counts as 1 IS): | |
| Ex-A: cnt[3:0] OP (4 IS) + cnt[2] CP+OP (same bit, already counted) = 4 IS total (NOT 5!) | |
| Ex-B: result[15:0] OP (16 IS) + result[0] CP (same bit) = 16 IS total | |
| Ex-C: state[1] CP-only (1 IS) + state[0] OP-only (1 IS) = 2 IS total | |
| 3. Port Declaration: Match the original RTL style exactly | |
| Add `cp_en` only if at least one selected bit uses CP or CP+OP. | |
| OP-only designs must not add `cp_en`. | |
| ANSI-style original: add directed ports in the module header, e.g. `input wire cp_en, output wire tp_sig1`. | |
| Non-ANSI-style original: add bare names in the port list and add `input cp_en;` / `output tp_sig1;` declarations in the body. | |
| Never mix ANSI declarations into a non-ANSI port list. | |
| 4. CP Function: Use only for CP or CP+OP. Define at TOP of module body, call inside always-block with <= | |
| WRONG: CP on wire/assign. WRONG: function outside module. | |
| WRONG: `assign sig = sig_in & ~cp_en;` (never use assign for CP) | |
| WRONG: `sig = InsertCP_1bit(sig, cp_en);` (forgot <=) | |
| WRONG: `InsertCP_8bit = sig_in & {8{~cp_en}};` when only some bits are selected (this zeroes ALL bits!) | |
| CORRECT: `reg <= InsertCP_1bit(sig_next, cp_en);` (inside always block) | |
| CP Semantics: cp_en=0 means NORMAL (pass-through), cp_en=1 means FORCE-0. | |
| Partial mask (RECOMMENDED): `InsertCP_8bit = {sig_in[7:1], sig_in[0] & ~cp_en};` | |
| Full-vector mask is allowed only when EVERY bit of that vector is selected for CP. | |
| 5. OP Instantiation: Use only for OP or CP+OP. Inside module body (before endmodule). NEVER use assign. | |
| CORRECT: `TestPointOBType_1bit op_sig1 (.funcin(signal1[0]), .tp_out(tp_sig1));` | |
| CORRECT: `TestPointOBType_8bit op_sig8 (.funcin(signal[7:0]), .tp_out(tp_sig8));` | |
| Width MUST match: N-bit signal -> `TestPointOBType_Nbit` | |
| 6. Module Definition Order: | |
| (a) Original ports + required new ports (`cp_en` only for CP/CP+OP, `tp_*` only for OP/CP+OP) | |
| (b) CP function definitions only if CP/CP+OP exists (at TOP, before always blocks) | |
| (c) OP instantiations only if OP/CP+OP exists (before endmodule) | |
| (d) Original always/assign blocks (UNCHANGED except CP wrapping) | |
| (e) endmodule | |
| (f) `module TestPointOBType_* ... endmodule` definitions only for used OP widths | |
| 7. Comments: Do not add new comments. Preserve comments that already exist in the original RTL. | |
| 8. Directives: Do not add new `timescale or `include directives. Preserve directives that already exist in the original RTL. | |
| 9. Chain-of-Thought (inside <think>): | |
| Step 1: Circuit Analysis + Scan-Cell Exclusion Filtering | |
| - Explicitly identify the scan-cell bits as FORBIDDEN. | |
| - List the real RTL register bits or register-bit groups that can be considered. | |
| - Normalize the scan-cell list using the rule above. | |
| - Build the legal candidate set by computing RTL_declared_register_bits - normalized_forbidden_scan_bits before scoring testability. | |
| - Never justify choosing a forbidden scan bit because it toggles often or looks useful. | |
| Step 2: Testability Scoring for non-scan register bits | |
| Step 3: Budget Allocation and mode choice (CP-only, OP-only, or CP+OP; prove sum of bits = 3) | |
| - Include a compact allocation table: bit | mode | count contribution | implementation line. | |
| - The table must use the exact RTL bit names that will appear in <total_design>. | |
| Step 4: Syntax Pre-simulation | |
| Step 5: Final Engineering Check | |
| - Every bit listed in your allocation table MUST be physically implemented in <total_design>. | |
| - Do not claim a bit such as filter[2] in <think> and then omit its CP/OP construct in RTL. | |
| - Recount physical RTL bits from actual InsertCP/TestPointOBType constructs, not from the prose table. | |
| - Write this exact legality check in words: `chosen_tpi_bits ∩ forbidden_scan_bits = empty`. | |
| - If the intersection is non-empty, you MUST replace the offending bit before writing <total_design>. | |
| - This is especially important for state[0], cnt[0], Q[0], filter[0], received[2], and other attractive low bits. | |
| Inside <total_design>: ONLY modified RTL. No markdown fences, no text. | |
| Stop immediately after </total_design>. Nothing after it. | |
| ## STYLE EXAMPLE (follow the syntax style; choose CP/OP/CP+OP according to the actual design) | |
| Example input RTL -- simple state machine with 2 test points: | |
| `timescale 1ns/1ps | |
| module fsm_example #(parameter WIDTH=8) ( | |
| input wire clk, rst_n, | |
| input wire [WIDTH-1:0] data_in, | |
| output reg [WIDTH-1:0] data_out, | |
| output wire ready | |
| ); | |
| localparam IDLE=2'b00, WORK=2'b01, DONE=2'b10; | |
| reg [1:0] state, next_state; | |
| reg [WIDTH-1:0] buffer; | |
| assign ready = (state == DONE); | |
| always @(posedge clk or negedge rst_n) | |
| if (!rst_n) state <= IDLE; | |
| else state <= next_state; | |
| always @* begin | |
| next_state = state; | |
| case (state) | |
| IDLE: if (data_in[0]) next_state = WORK; | |
| WORK: next_state = DONE; | |
| DONE: next_state = IDLE; | |
| endcase | |
| end | |
| always @(posedge clk or negedge rst_n) | |
| if (!rst_n) buffer <= {WIDTH{1'b0}}; | |
| else if (state == WORK) buffer <= data_in; | |
| always @(posedge clk or negedge rst_n) | |
| if (!rst_n) data_out <= {WIDTH{1'b0}}; | |
| else data_out <= buffer; | |
| endmodule | |
| CORRECT output -- original RTL fully preserved, CP+OP example added: | |
| `timescale 1ns/1ps | |
| module fsm_example #(parameter WIDTH=8) ( | |
| input wire clk, rst_n, | |
| input wire [WIDTH-1:0] data_in, | |
| output reg [WIDTH-1:0] data_out, | |
| output wire ready, | |
| input wire cp_en, | |
| output wire tp_state_1, | |
| output wire tp_buffer_7 | |
| ); | |
| localparam IDLE=2'b00, WORK=2'b01, DONE=2'b10; | |
| reg [1:0] state, next_state; | |
| reg [WIDTH-1:0] buffer; | |
| assign ready = (state == DONE); | |
| function [1:0] InsertCP_2bit_state; | |
| input [1:0] sig_in; | |
| input cp_en; | |
| begin | |
| InsertCP_2bit_state = {sig_in[1] & ~cp_en, sig_in[0]}; | |
| end | |
| endfunction | |
| function [WIDTH-1:0] InsertCP_Wbit_buffer; | |
| input [WIDTH-1:0] sig_in; | |
| input cp_en; | |
| begin | |
| InsertCP_Wbit_buffer = {sig_in[WIDTH-1:8], sig_in[7] & ~cp_en, sig_in[6:0]}; | |
| end | |
| endfunction | |
| TestPointOBType_1bit op_state_1 (.funcin(state[1]), .tp_out(tp_state_1)); | |
| TestPointOBType_1bit op_buffer_7 (.funcin(buffer[7]), .tp_out(tp_buffer_7)); | |
| always @(posedge clk or negedge rst_n) | |
| if (!rst_n) state <= IDLE; | |
| else state <= InsertCP_2bit_state(next_state, cp_en); | |
| always @* begin | |
| next_state = state; | |
| case (state) | |
| IDLE: if (data_in[0]) next_state = WORK; | |
| WORK: next_state = DONE; | |
| DONE: next_state = IDLE; | |
| endcase | |
| end | |
| always @(posedge clk or negedge rst_n) | |
| if (!rst_n) buffer <= {WIDTH{1'b0}}; | |
| else if (state == WORK) buffer <= InsertCP_Wbit_buffer(data_in, cp_en); | |
| always @(posedge clk or negedge rst_n) | |
| if (!rst_n) data_out <= {WIDTH{1'b0}}; | |
| else data_out <= buffer; | |
| endmodule | |
| module TestPointOBType_1bit (input funcin, output tp_out); | |
| assign tp_out = funcin; | |
| endmodule | |
| module TestPointOBType_2bit (input [1:0] funcin, output [1:0] tp_out); | |
| assign tp_out = funcin; | |
| endmodule | |
| ## CP/OP SYNTAX REFERENCE | |
| Use only the syntax needed by your selected modes. OP-only samples do not need `cp_en` or CP functions. | |
| ### CP Function (ONLY for CP or CP+OP; AND-type: cp_en=0=normal/pass-through, cp_en=1=force target bit to 0) | |
| The key principle: only the masked bits are forced to 0; ALL other bits PASS THROUGH unchanged. | |
| Mode A -- Single bit CP (most common): | |
| function InsertCP_1bit; | |
| input sig_in; input cp_en; | |
| begin InsertCP_1bit = sig_in & ~cp_en; end | |
| endfunction | |
| Mode B -- Multi-bit, only bit[0] controlled, rest PASS THROUGH: | |
| function [7:0] InsertCP_8bit_bit0; | |
| input [7:0] sig_in; input cp_en; | |
| begin | |
| InsertCP_8bit_bit0 = {sig_in[7:1], sig_in[0] & ~cp_en}; | |
| end | |
| endfunction | |
| Mode C -- Multi-bit, specific bits controlled (bit[7] + bit[3]), rest PASS THROUGH: | |
| function [7:0] InsertCP_8bit_bit73; | |
| input [7:0] sig_in; input cp_en; | |
| begin | |
| InsertCP_8bit_bit73 = { | |
| sig_in[7] & ~cp_en, sig_in[6:4], | |
| sig_in[3] & ~cp_en, sig_in[2:0] | |
| }; | |
| end | |
| endfunction | |
| Mode D -- Full-vector mask is usually wrong: | |
| Do NOT write `sig_in & {N{~cp_en}}` unless all N bits are selected for CP. | |
| ### CP Usage (inside always block, use <= non-blocking) | |
| reg <= InsertCP_1bit(reg_next, cp_en); | |
| reg <= InsertCP_8bit_bit0(reg_next, cp_en); | |
| reg <= InsertCP_8bit_bit73(reg_next, cp_en); | |
| Full-vector mask is rarely correct -- it zeroes every bit of the vector! | |
| ### OP Instantiation | |
| TestPointOBType_1bit op_sig1 (.funcin(signal1), .tp_out(tp_sig1)); | |
| TestPointOBType_8bit op_sig8 (.funcin(signal[7:0]), .tp_out(tp_sig8)); | |
| For unpacked register arrays, use exact static bit indices: | |
| TestPointOBType_1bit op_stack_7_8 (.funcin(stack[7][8]), .tp_out(tp_stack_7_8)); | |
| Do not use dynamic array indices for TPI targets. | |
| ### Port Declaration | |
| Preserve the original port declaration style. | |
| ANSI original: add directed ports in the header. | |
| Non-ANSI original: add bare names in the header and declarations in the body. | |
| `cp_en` is only for CP or CP+OP. `tp_*` is only for OP or CP+OP. | |
| ### Module Definition Order | |
| 1) Original ports + required added ports | |
| 2) CP function definitions, only if CP/CP+OP exists (at TOP of module body) | |
| 3) OP instantiations, only if OP/CP+OP exists (before endmodule) | |
| 4) Original logic (unchanged) | |
| 5) endmodule | |
| 6) TestPointOBType_* module definitions, only for used OP widths | |
| #RTL CODE#: | |
| module gen_sync ( input clock,input reset,input enable,input [7:0] rate,output wire sync ); | |
| reg [7:0] counter; | |
| assign sync = |(((rate+1)>>1)& counter); | |
| always @(posedge clock) | |
| if(reset || ~enable) | |
| counter <= #1 0; | |
| else if(counter == rate) | |
| counter <= #1 0; | |
| else | |
| counter <= #1 counter + 8'd1; | |
| endmodule | |
| #Scan Cell Bits (DO NOT select): | |
| counter[0] | |
| #Required TPI Count: 3 | |