소스 정보
- 저장소
- londey/claude-skill-verilog
- 최근 소스 활동
- 2026년 4월 21일 21:57
- 감지된 SKILL.md 언어
- 영어
- 스타
- 18
- 포크
- 2
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/londey/claude-skill-verilog --skill claude-skill-verilog명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | claude-skill-verilog |
| description | Verilog/SystemVerilog coding style and Verilator workflow guidance |
Apply when working with .v, .sv, .vh, .svh files or running Verilator.
All modules, wires, and registers require comments:
// Module: counter
// Purpose: Simple up-counter with synchronous reset
module counter #(
parameter WIDTH = 8 // Counter bit width
) (
input logic clk, // System clock
input logic rst_n, // Active-low reset
output logic [WIDTH-1:0] count // Current count value
);
Document all fixed-point values using TI-style Q notation:
Qm.n — signed: m integer bits (including sign bit), n fractional bits, total width = m + n bits.UQm.n — unsigned: m integer bits, n fractional bits, total width = m + n bits.Use Q notation in signal comments, localparam descriptions, and module-level documentation.
logic signed [15:0] scale_factor; // Scaling multiplier, Q4.12
logic [15:0] timer_count; // Free-running tick counter, UQ16.0
logic signed [15:0] delta; // Sample-to-sample difference, Q4.12
_n suffix (e.g., rst_n, chip_select_n)clk or clk_<domain>always_ff blocks must contain ONLY simple non-blocking assignments. No logic, no expressions — this ensures Verilator simulation matches synthesized behavior. (Exceptions: memory inference and async reset synchronizers require conditional logic — see those sections.)
// CORRECT - simple assignment
always_ff @(posedge clk) begin
count <= count_next;
state <= state_next;
end
// WRONG - logic in always_ff
always_ff @(posedge clk) begin
count <= count + 1; // Move to always_comb
state <= enable ? RUNNING : IDLE; // Move to always_comb
end
All combinational logic belongs in always_comb blocks:
always_comb begin
count_next = count + 8'd1;
state_next = enable ? RUNNING : IDLE;
end
`default_nettype nonebegin/end blocks for if, else, case items (prevents bugs when adding code later)`default_nettype none
module example (
input logic clk,
input logic rst_n,
input logic [7:0] data_in,
output logic [7:0] data_out
);
logic [7:0] data_reg; // Registered data
logic [7:0] data_next; // Next state value
logic valid; // Data valid flag
localparam logic [7:0] INIT_VAL = 8'd0;
endmodule
`default_nettype wire
Synthesizable RTL should work with both Verilator (lint/simulation) and Yosys (synthesis for open-source FPGA flows).
Yosys supports a subset of SystemVerilog via read_verilog -sv.
Code that passes Verilator may still fail Yosys synthesis.
Constructs to avoid in synthesizable RTL:
| Avoid | Use instead |
|---|---|
return <expr>; in functions | function_name = <expr>; (Verilog-2005 style) |
interface / modport | Explicit port lists |
unique case / priority case | Plain case with default |
| Multi-dimensional packed arrays in ports | Flatten to single vectors |
// CORRECT - Yosys-compatible function
function automatic logic [7:0] add_saturate(input logic [7:0] a, input logic [7:0] b);
logic [8:0] sum;
sum = {1'b0, a} + {1'b0, b};
add_saturate = sum[8] ? 8'hFF : sum[7:0];
endfunction
// WRONG - return statement (Yosys rejects this)
function automatic logic [7:0] add_saturate(input logic [7:0] a, input logic [7:0] b);
logic [8:0] sum;
sum = {1'b0, a} + {1'b0, b};
return sum[8] ? 8'hFF : sum[7:0];
endfunction
Always verify with the actual synthesis flow (e.g. yosys -p "synth_ecp5 ...", yosys -p "synth_ice40 ...", or the project's build target), not only verilator --lint-only, when using SystemVerilog features. Lint-clean does not imply synthesizable.
Every module requires a testbench. Build and run with Verilator:
# Build testbench
verilator --binary -Wall module_tb.sv module.sv
# Run simulation
./obj_dir/Vmodule_tb
Testbench structure:
module counter_tb;
logic clk = 1'b0; // System clock
logic rst_n; // Active-low reset
logic [7:0] count; // DUT output
counter dut (
.clk(clk),
.rst_n(rst_n),
.count(count)
);
always begin
#5 clk = ~clk;
end
initial begin
rst_n = 1'b0;
#20 rst_n = 1'b1;
#100;
$display("Test complete, count=%d", count);
$finish;
end
endmodule
Run linting on all files and fix all warnings:
verilator --lint-only -Wall module.sv
Recommended flags for simulation builds:
verilator --binary \
-Wall \
-Wno-fatal \
-j 0 \
--assert \
--timing \
--trace-fst \
--trace-structs \
--main-top-name "-" \
--x-assign unique \
--x-initial unique \
module_tb.sv module.sv
| Flag | Purpose |
|---|---|
-Wall | Enable all warnings |
-Wno-fatal | Don't exit on warnings (allows full report) |
-j 0 | Fully parallelized compilation |
--assert | Enable SystemVerilog assertions |
--timing | Enable timing constructs |
--trace-fst | Dump waveforms as FST (compressed) |
--trace-structs | Human-readable struct dumps |
--main-top-name "-" | Remove extra TOP module wrapper |
--x-assign unique | Replace X with random constant per-build |
--x-initial unique | Randomly initialize uninitialized variables |
// CORRECT - named connections
counter #(
.WIDTH(16)
) u_counter (
.clk (clk),
.rst_n (rst_n),
.count (count_value)
);
// WRONG - positional connections
counter u_counter (clk, rst_n, count_value);
Latches are inferred when signals aren't assigned in all paths. Prevent with:
always_combdefaultalways_comb begin
// Default assignments first
data_next = data_reg;
valid_next = 1'b0;
case (state)
IDLE: begin
data_next = 8'd0;
end
LOAD: begin
data_next = data_in;
end
default: begin
data_next = data_reg;
end
endcase
end
Use synchronous resets when possible. For external async resets, synchronize first.
Note: Async reset synchronizers require conditional logic in always_ff for the reset condition — this is a necessary exception similar to memory inference.
// Synchronous reset (preferred)
logic [7:0] count; // Counter register
logic [7:0] count_next; // Next counter value
always_comb begin
count_next = rst_n ? (count + 8'd1) : 8'd0;
end
always_ff @(posedge clk) begin
count <= count_next;
end
// Reset synchronizer for external async reset
logic [1:0] rst_sync; // Synchronizer flip-flops
logic [1:0] rst_sync_next; // Next synchronizer value
always_comb begin
rst_sync_next = {rst_sync[0], 1'b1};
end
always_ff @(posedge clk or negedge rst_async_n) begin
if (!rst_async_n) begin
rst_sync <= 2'b00;
end else begin
rst_sync <= rst_sync_next;
end
end
assign rst_n = rst_sync[1];
Separate state register from next-state logic. Use enums for state encoding.
typedef enum logic [1:0] {
IDLE,
RUN,
DONE
} state_t;
state_t state; // Current state register
state_t state_next; // Next state value
// Next-state logic (combinational)
always_comb begin
state_next = state;
case (state)
IDLE: begin
if (start) begin
state_next = RUN;
end
end
RUN: begin
if (finish) begin
state_next = DONE;
end
end
DONE: begin
state_next = IDLE;
end
default: begin
state_next = IDLE;
end
endcase
end
// State register (sequential)
always_ff @(posedge clk) begin
state <= state_next;
end
Single-bit signals: use 2-FF synchronizer. Multi-bit: use gray coding or handshake.
// 2-FF synchronizer for single-bit CDC
logic [1:0] sync_reg; // Synchronizer flip-flops
logic [1:0] sync_reg_next; // Next synchronizer value
logic signal_sync; // Synchronized output
always_comb begin
sync_reg_next = {sync_reg[0], signal_src};
end
always_ff @(posedge clk_dst) begin
sync_reg <= sync_reg_next;
end
assign signal_sync = sync_reg[1];
// Gray code for multi-bit counters crossing domains
function automatic logic [WIDTH-1:0] bin2gray(input logic [WIDTH-1:0] bin);
bin2gray = bin ^ (bin >> 1);
endfunction
Use standard patterns for RAM/ROM inference by synthesis tools.
Note: Memory patterns are an exception to the "simple assignments only" rule for always_ff. Synthesis tools require these specific patterns to correctly infer RAM/ROM primitives.
// Single-port RAM
logic [DATA_WIDTH-1:0] mem [0:DEPTH-1]; // Memory array
always_ff @(posedge clk) begin
if (we) begin
mem[addr] <= wdata;
end
rdata <= mem[addr];
end
// ROM (initialized memory)
logic [7:0] rom [0:255]; // ROM array
initial $readmemh("rom_data.hex", rom);
always_ff @(posedge clk) begin
rdata <= rom[addr];
end
Use assertions for verification. They're enabled with --assert in Verilator.
// Immediate assertion
always_comb begin
assert (count < MAX_COUNT) else $error("Count overflow");
end
// Concurrent assertions
property p_valid_handshake;
@(posedge clk) disable iff (!rst_n)
valid |-> ##[1:3] ready;
endproperty
assert property (p_valid_handshake)
else $error("Handshake timeout");
// Cover property (for functional coverage)
cover property (@(posedge clk) state == DONE);