소스 정보
- 저장소
- Ljj05170930/verilog-code-plugin
- 최근 소스 활동
- 2026년 4월 12일 11:49
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 0
- 포크
- 1
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/Ljj05170930/verilog-code-plugin --skill new-verilog-project명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
创建 SystemVerilog 测试平台文件。触发词包括:创建TB、写testbench、新建测试平台、生成TB、写TB、创建仿真测试文件
编写和审查可综合的 Verilog RTL 代码。当用户要求编写、设计、实现、修复或审查任何 Verilog/RTL 模块、 硬件模块或数字逻辑时自动触发。触发词包括:写Verilog、写RTL、实现模块、设计电路、review代码、 审查Verilog、FSM、状态机、FIFO、pipeline、流水线、arbiter、仲裁器、counter、计数器、 shift register、移位寄存器、handshake、握手协议、AXI、APB、SPI、I2C、UART、 clock divider、分频器、debounce、去抖、edge detector、边沿检测、synchronizer、同步器、 dual-port RAM、双端口RAM。即使用户只说"写一个模块"或"实现这个功能"而没有显式提到"Verilog", 也应使用此 skill。涵盖新代码生成和已有 Verilog 代码的 review/debug。
SOC 직업 분류 기준
SKILL.md 표시 중
| name | new-verilog-project |
| description | 新建 Verilog 仿真项目,搭建环境。触发词包括:新建项目、建立Verilog环境、初始化工程、搭建仿真环境、新建Verilog工程 |
在当前工作目录下创建完整的 Verilog 仿真项目结构。
./
├── RTL/ (仅在不存在时创建;已存在则保留原内容不动)
├── TB/
│ └── tb_top.sv (仅在 TB/ 内无仿真文件时由 tb-creator skill 生成)
├── .vscode/
│ └── tasks.json
├── .gitignore
├── gen_filelist.py
├── gen_dumpvars.py
├── clean.py
└── CLAUDE.md
{
"version": "2.0.0",
"tasks": [
{
"label": "Generate Filelist",
"type": "shell",
"command": "python",
"args": ["gen_filelist.py"],
"group": "build"
},
{
"label": "iverilog compile",
"type": "shell",
"command": "iverilog",
"args": [
"-o", "sim.vvp",
"-g2012",
"-f", "filelist.f"
],
"group": {
"kind": "build",
"isDefault": false
},
"problemMatcher": []
},
{
"label": "vvp run",
"type": "shell",
"command": "vvp sim.vvp -fst",
"group": {
"kind": "build",
"isDefault": false
},
"problemMatcher": []
},
{
"label": "Gen Dumpvars",
"type": "shell",
"command": "python",
"args": ["gen_dumpvars.py", "--patch"],
"group": "build",
"problemMatcher": []
},
{
"label": "clean",
"type": "shell",
"command": "python",
"args": ["clean.py"],
"group": "build",
"problemMatcher": []
},
{
"label": "compile and run",
"dependsOn": ["Generate Filelist","Gen Dumpvars","iverilog compile", "vvp run"],
"dependsOrder": "sequence",
"group": {
"kind": "build",
"isDefault": false
},
"problemMatcher": []
}
]
}
import os
extensions = ('.v', '.sv')
dirs = ['RTL', 'TB']
with open('filelist.f', 'w') as f:
for d in dirs:
if not os.path.exists(d):
continue
for root, _, files in os.walk(d):
for file in files:
if file.endswith(extensions):
path = os.path.join(root, file).replace('\\', '/')
f.write(path + '\n')
print("Generated filelist.f")
#!/usr/bin/env python3
"""
gen_dumpvars.py
自动扫描 RTL 文件中的非压缩数组,结合实例化层次,
生成 DUMP_ARRAY 宏调用,可选地直接更新 TB 的波形 initial 块。
用法:
python gen_dumpvars.py # 仅打印生成结果
python gen_dumpvars.py --patch # 同时更新 TB 文件
"""
import re, sys, argparse
from pathlib import Path
FILELIST = "filelist.f"
SV_KEYWORDS = {
'module','endmodule','input','output','inout','wire','reg','logic',
'integer','genvar','begin','end','if','else','for','always','initial',
'assign','parameter','localparam','generate','endgenerate','task',
'function','endtask','endfunction','case','casex','casez','endcase',
'posedge','negedge','repeat','while','fork','join','string','bit',
'byte','int','real','time','signed','unsigned','automatic',
'supply0',,,,,,,
}
():
src = re.sub(, , src)
src = re.sub(, , src, flags=re.S)
src
():
files = []
(path) f:
line f:
line = line.strip().replace(, )
line line.startswith():
files.append(line)
files
():
params = {}
m re.finditer(
,
body
):
name = m.group()
expr = m.group().strip()
:
val = (expr, {: {}}, (params))
params[name] = (val)
Exception:
params
():
:
((expr.strip(), {: {}}, params))
Exception:
():
params = extract_params(body)
arrays = []
a re.finditer(
,
body
):
name = a.group()
name SV_KEYWORDS:
hi = resolve(a.group(), params)
lo = resolve(a.group(), params)
hi lo :
arrays.append((name, (hi - lo) + ))
gen_insts = []
gen re.finditer(, body, re.S):
blk re.finditer(
,
gen.group(), re.S
):
label = blk.group()
blk_body = blk.group()
m re.finditer(
, blk_body
):
mtype, iname = m.group(), m.group()
mtype SV_KEYWORDS iname SV_KEYWORDS:
gen_insts.append((label, mtype, iname))
body_no_gen = re.sub(, , body, flags=re.S)
reg_insts = []
m re.finditer(
, body_no_gen
):
mtype, iname = m.group(), m.group()
mtype SV_KEYWORDS iname SV_KEYWORDS:
reg_insts.append((mtype, iname))
arrays, reg_insts, gen_insts
():
all_mods = {}
f files:
:
src = Path(f).read_text(encoding=, errors=)
clean = strip_comments(src)
m re.finditer(
, clean, re.S
):
name, body = m.group(), m.group()
all_mods[name] = parse_module(body)
Exception e:
(, file=sys.stderr)
all_mods
():
results = []
visited = ()
():
key = (mod_name, prefix)
key visited mod_name all_mods:
visited.add(key)
arrays, reg_insts, gen_insts = all_mods[mod_name]
arr_name, size arrays:
results.append((, size))
mtype, iname reg_insts:
mtype all_mods:
dfs(mtype, )
label, mtype, iname gen_insts:
mtype all_mods:
dfs(mtype, )
mtype, iname start_insts:
mtype all_mods:
dfs(mtype, iname)
results
():
lines = [
,
,
,
]
path, size entries:
lines.append()
lines.append()
.join(lines)
():
src = Path(tb_path).read_text(encoding=)
lines = src.split()
start_i = end_i =
i, line (lines):
re.search(, line):
window = .join(lines[i: i + ])
window:
start_i = i
depth =
j (i, (lines)):
depth += (re.findall(, lines[j]))
depth -= (re.findall(, lines[j]))
depth == j > i:
end_i = j
start_i end_i :
new_lines = (lines[:start_i]
+ new_block.split()
+ lines[end_i + :])
Path(tb_path).write_text(.join(new_lines), encoding=)
()
:
endmod_i =
i, line (lines):
re.search(, line):
endmod_i = i
endmod_i :
new_lines = (lines[:endmod_i]
+ []
+ new_block.split()
+ []
+ lines[endmod_i:])
Path(tb_path).write_text(.join(new_lines), encoding=)
()
:
(, file=sys.stderr)
():
ap = argparse.ArgumentParser(description=)
ap.add_argument(, action=,
=)
args = ap.parse_args()
files = read_filelist()
tb_files = [f f files Path(f).stem.startswith()]
all_mods = parse_all(files)
tb_mod =
start_insts = []
tf tb_files:
src = Path(tf).read_text(encoding=, errors=)
clean = strip_comments(src)
m = re.search(, clean, re.S)
m:
tb_mod = m.group()
_, reg_insts, _ = parse_module(m.group())
mtype, iname reg_insts:
mtype all_mods mtype != tb_mod:
start_insts.append((mtype, iname))
tb_mod:
(, file=sys.stderr)
sys.exit()
entries = collect(all_mods, start_insts)
seen, unique = (), []
path, size entries:
path seen:
seen.add(path)
unique.append((path, size))
block = gen_block(tb_mod, unique)
()
(block)
()
args.patch:
tf tb_files:
patch_tb(tf, block)
__name__ == :
main()
import os
import glob
import shutil
for fst in glob.glob("*.fst"):
base = os.path.splitext(fst)[0]
for ext in [".fst", ".vcd"]:
target = base + ext
if os.path.exists(target):
os.remove(target)
print(f"Deleted: {target}")
for f in ["filelist.f", "sim.vvp"]:
if os.path.exists(f):
os.remove(f)
print(f"Deleted: {f}")
for cache_dir in glob.glob("**/__pycache__", recursive=True):
shutil.rmtree(cache_dir, ignore_errors=True)
print(f"Deleted: {cache_dir}")
for pyc in glob.glob("**/*.pyc", recursive=True):
os.remove(pyc)
print(f"Deleted: {pyc}")
print("Clean done.")
# 仿真产物
*.fst
*.vvp
filelist.f
# Python 缓存
__pycache__/
*.pyc
## 回答规范
每次回答结束后,必须在末尾附上:
- 当前使用的模型名称
- 当前的effort 级别(如果有)
RTL 目录:使用 Glob 检查 RTL/ 下是否有任意文件:
RTL/.gitkeep(空文件,确保目录存在)RTL/ 做任何操作使用 Write 工具依次创建以下文件(直接覆盖,不询问):
.vscode/tasks.json.gitignoregen_filelist.pygen_dumpvars.pyclean.pyCLAUDE.md.claude/settings.local.json(内容如下,用于自动授权 iverilog 编译和仿真命令){
"permissions": {
"allow": [
"Bash(iverilog -o sim.vvp -g2012 -f filelist.f)",
"Bash(vvp sim.vvp -fst)"
]
}
}
TB 目录:使用 Glob 检查 TB/ 下是否存在 .v 或 .sv 文件:
tb-creator skill 生成 TB/tb_top.svTB/ 做任何操作tasks.json:创建或覆盖 .vscode/tasks.json,不询问用户任何问题
全部完成后,告知用户"Verilog 项目环境已就绪",并列出创建/跳过的文件清单。