Verilog、SystemVerilog小项目模板

介绍

我自己在做一些小项目以及验证想法时经常就在windows下使用vscode、iverilog、gtkwave进行开发了。

最大的优势就是轻量与快,在我的环境下启动modelsim以及其他eda软件都比较慢,而使用这些工具搭建的开发流启动起来非常快(从打开工程到输出波形)。

整体体验还不错。

  • 使用vscode插件、makefile、vscode tasks等方式一键仿真。
  • ctags和vscode插件实现的文件内信号跳转、文件间模块例化跳转
  • 自己修改的插件实现的一键生成tb内容
  • 设置的GTKWave tcl文件,添加信号、自动file filter(如信号值转状态机、译码值转寄存器名等)

https://github.com/Bowen-0x00/verilog-project-template

详情

必要软件

  • iverilog
  • gtkwave

文件结构

.project-root
├── .vscode/
│ └── tasks.json
├── build/
│ └── (compiled outputs and intermediate files)
├── GTKWave/
│ ├── set_wave.tcl
| └—— file filters 
├── src/
│ ├── module1.sv
│ └── module2.sv
├── testbench/
│ ├── tb_module.sv
│ └── (other testbench files)
└── Makefile

仿真

  • 运行vscode tasks
  • 或在terminal中(项目根目录)运行make waveform

一键仿真结果

Makefile示例

TB_FILE := testbench/tb_cdc_4phase.sv
GTKWAVE_TCL_FILE := GTKWave/set_wave.tcl


TB_MODULE := $(basename $(notdir $(TB_FILE)))
VCD := $(TB_MODULE).vcd
VCD_PATH := build/$(VCD)


OUT := $(TB_MODULE).out
OUT_PATH := build/$(OUT)

# v_files := src/cdc_4phase.sv src/sync.sv 
sv_files := $(wildcard src/*.sv)
v_files := $(wildcard src/*.v)
all_files := $(sv_files) $(v_files)
$(info v_files=$(v_files))


all: $(TB_MODULE)
 
.PHONY: vvp waveform clean
 
$(TB_MODULE): $(TB_FILE) $(all_files)
	iverilog -g2012 -o $(OUT_PATH) $(TB_FILE) $(all_files)
 
$(VCD): $(TB_MODULE)
	cd build && vvp $(OUT)
	
 
vvp: $(VCD)
 
waveform: $(VCD)
	gtkwave $(VCD_PATH) -T $(GTKWAVE_TCL_FILE)
 
clean::
	cd build && del /Q $(OUT) $(VCD)

GTKWave tcl脚本示例

# Signals
set top [list u_cdc_4phase.src_clk_i u_cdc_4phase.dst_clk_i  u_cdc_4phase.src_rst_ni u_cdc_4phase.dst_rst_ni]
set signals_to_add {
    {"i_src.state_q" Yellow}
    {"i_src.valid_i" Blue}
    {"i_src.req_src_q" Indigo}
    {"i_src.ack_synced" Violet}
    {"i_dst.state_q" Yellow}
    {"i_dst.ready_i" Blue}
    {"i_dst.req_synced" Indigo}
    {"i_dst.async_ack_o" Violet}
}

# File filters
set state_map_dict {
    "i_src.state_q" "./GTKWave/FSM_src.txt"
    "i_dst.state_q" "./GTKWave/FSM_dst.txt"
}

# variables
set states [dict keys $state_map_dict]
set nsigs [ gtkwave::getNumFacs ]

# Customize view settings
gtkwave::nop
gtkwave::/Edit/Set_Trace_Max_Hier 2
# gtkwave::/View/Show_Filled_High_Values 1
gtkwave::/View/Show_Wave_Highlight 1
# gtkwave::/View/Show_Mouseover 1

gtkwave::/Edit/Insert_Comment "Clock & Reset"
gtkwave::addSignalsFromList $top
gtkwave::highlightSignalsFromList $top
# gtkwave::/Edit/Color_Format/Indigo
gtkwave::/Edit/UnHighlight_All
gtkwave::/Edit/Insert_Blank

proc translate {element_list element mapping_file} {
    set iselement 0

    foreach e $element_list {
        if {[ string first $e $element ] != -1} {
            set iselement 1
        }
    }
    if {$iselement == 1 } {
        gtkwave::highlightSignalsFromList "$element"
        gtkwave::installFileFilter $mapping_file
        gtkwave::/Edit/UnHighlight_All
    }
    # return $iselement
}

proc add_signals { filter color} {
    global nsigs
    global states
    global state_map_dict

    set filterKeyword $filter
    set filterCondition "_hi_"
    set monitorSignals [list]
    for {set i 0} {$i < $nsigs } {incr i} {
        set facname [ gtkwave::getFacName $i ]
        set index [ string first $filterKeyword $facname  ]
        set index2 [ string first $filterCondition $facname  ]

        if {$index != -1 && $index2 == -1} {
            lappend monitorSignals "$facname"
        }
    }
    # gtkwave::/Edit/Insert_Comment $filter
    gtkwave::addSignalsFromList $monitorSignals
    # gtkwave::/Edit/Insert_Blank
    foreach v $monitorSignals {
        set a [split $v .]
        set a [lindex $a end]
        gtkwave::highlightSignalsFromList $v
    }
    gtkwave::/Edit/Color_Format/$color
    gtkwave::/Edit/UnHighlight_All

    foreach v $monitorSignals {
        if {[info exists states]} {
            foreach state $states {
                if {[string first $state $v] != -1} {
                    set state_map [ gtkwave::setCurrentTranslateFile [dict get $state_map_dict $state] ]
                    translate $states $v $state_map
                }
            }
        }
    }
    ## This sets the register signal names to be aliased to the register name
    foreach v $monitorSignals {
        if {[string first regs_ $v] != -1} {
        set name [string range [lsearch -inline [split $v .] {regs_*}] 5 end]
        gtkwave::highlightSignalsFromList "$v"
        gtkwave::/Edit/Alias_Highlighted_Trace x$name
        gtkwave::/Edit/UnHighlight_All

        }
    }
}

# Zoom all
gtkwave::/Time/Zoom/Zoom_Full


# Add signals
gtkwave::/Edit/Insert_Comment "Signals"

foreach s $signals_to_add {
    puts $s
    add_signals [lindex $s 0] [lindex $s 1]
}

个人使用的vscode插件

https://marketplace.visualstudio.com/items?itemName=mshr-h.VerilogHDL
https://marketplace.visualstudio.com/items?itemName=leafvmaple.verilog
https://marketplace.visualstudio.com/items?itemName=Truecrab.verilog-testbench-instance
https://marketplace.visualstudio.com/items?itemName=theonekevin.icarusext
https://marketplace.visualstudio.com/items?itemName=czh.czh-verilog-snippet
https://marketplace.visualstudio.com/items?itemName=ericsonj.verilogformat
https://marketplace.visualstudio.com/items?itemName=sterben.fpga-support

posted @ 2024-06-01 02:21  一鸣惊人_001  阅读(162)  评论(0)    收藏  举报