第 0 节 – 环境搭建
基础环境:
– Windows Subsystem for Linux (WSL) with Ubuntu 26.04 LTS
– git version 2.53.0
– just 1.45.0
– cmake version 4.2.3
– uv 0.9.17如上述环境有缺失的,自行网络搜寻安装方法。
本节是为了搭建一个适合 FPGA 开发的环境,主要包括安装 Verilator、Verible、GTKWave 等工具,并创建一个简单的计数器项目以验证环境是否配置成功。对于初学而言其并不能获得较大收益,但是作者认为开发需要良好的开发习惯。
安装 Verilator
Verilator 是一个开源的 Verilog HDL 模拟器和综合工具。它将 Verilog 代码转换为 C++ 或 SystemC 代码,从而实现高性能的仿真。
sudo apt install verilator
使用以下命令检查 Verilator 是否安装成功:
verilator --version
安装 Verible
Verible 是一套 SystemVerilog 开发工具,包含解析器、代码风格检查器、格式化工具和语言服务器。
从 GitHub 拉取 Release 版本:
wget https://github.com/chipsalliance/verible/releases/download/v0.0-4296-g0f262651/verible-v0.0-4296-g0f262651-linux-static-x86_64.tar.gz
tar -xzf verible-v0.0-4296-g0f262651-linux-static-x86_64.tar.gz
mv verible-v0.0-4296-g0f262651/bin/* ~/.local/bin/
检查是否可用:
verible-verilog-format --version
verible-verilog-lint --version
verible-verilog-syntax --version
安装 GTKWave
GTKWave 是一个开源的波形查看器,用于查看数字电路仿真结果。它支持多种波形文件格式,如 VCD、LXT、FST 等。
sudo apt install gtkwave
安装后应当可直接打开:
gtkwave
出现图形界面:
创建一个项目
mkdir counter
cd counter
uv init
uv add cocotb
此举通过 cocotb 就绪一个易于测试的项目。
用 Visual Studio Code 打开项目:
code .
注意:此处建议建立一个新的 Visual Studio Code 配置文件用于 FPGA 项目,以避免与其他项目的配置冲突。
具体建立方法不多赘述,参考 Visual Studio Code 的基础使用方法。
安装插件:
以及 Python 相关支持。
然后开始建立目录结构:
counter/
├── src/
│ └── counter.sv
├── tests/
│ ├── run.py
│ └── test_counter.py
├── build/
├── pyproject.toml
├── uv.lock
└── justfile
写 src/counter.sv:
module counter (
input logic clk,
input logic rst,
output logic [3:0] count
);
always_ff @(posedge clk) begin
if (rst)
count <= 4'd0;
else
count <= count + 4'd1;
end
endmodule
其中,module 定义了一个计数器模块,包含时钟输入 clk、复位输入 rst 和 4 位输出 count。
[3:0] 表示 count 是一个 4 位宽的逻辑向量。
always_ff 块在时钟上升沿(posedge clk)触发,如果复位信号为高电平(rst),则计数器清零,否则计数器加一。
4'd0 和 4'd1 分别表示 4 位二进制的 0 和 1。
然后,写一个测试,在 tests/test_counter.py 中:
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, ReadOnly
@cocotb.test()
async def test_counter(dut):
cocotb.start_soon(
Clock(dut.clk, 10, unit="ns").start()
)
dut.rst.value = 1
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
dut.rst.value = 0
for expected in range(1, 6):
await RisingEdge(dut.clk)
await ReadOnly()
assert dut.count.value == expected
其中,@cocotb.test() 装饰器将 test_counter 函数标记为一个 cocotb 测试。async def 定义了一个异步函数,允许在测试中使用 await 关键字等待事件。dut 参数表示被测试的设计单元(Device Under Test)。
start_soon 方法启动一个时钟生成器,创建一个周期为 10 纳秒的时钟信号 clk。
dut.rst.value = 1 将复位信号设置为高电平,表示进入复位状态。随后,使用 await RisingEdge(dut.clk) 等待两个时钟上升沿,以确保复位信号被正确应用。
将复位信号释放(dut.rst.value = 0),并在接下来的时钟周期中检查计数器的输出值是否按预期递增。
设置 ReadOnly() 触发器检查输出,确保在读取 dut.count.value 时不会被其他信号修改。
随后,每个时钟上升沿都会增加一个计数,于是 expected 变量从 1 到 5,检查计数器的输出是否与预期值一致。
写一个运行脚本,在 tests/run.py 中:
from pathlib import Path
from cocotb_tools.runner import get_runner
ROOT = Path(__file__).resolve().parent.parent
def test_counter():
runner = get_runner("verilator")
runner.build(
sources=[ROOT / "src" / "counter.sv"],
hdl_toplevel="counter",
build_dir=ROOT / "build",
waves=True,
build_args=["--trace-fst"],
)
runner.test(
hdl_toplevel="counter",
test_module="test_counter",
waves=True,
)
if __name__ == "__main__":
test_counter()
这个脚本能使 uv 找到 cocotb 的测试模块,并使用 verilator 进行仿真。
其中 --trace-fst 参数启用 FST 波形输出,便于后续使用 GTKWave 查看波形。
编写 justfile:
default:
@just --list
test:
uv run python tests/run.py
lint:
verible-verilog-lint src/*.sv
format:
verible-verilog-format --inplace --indentation_spaces=4 src/*.sv
wave:
gtkwave build/dump.fst
测试一下:
just test
just wave
应当能够看到测试已经通过了:
同时打开 GTKWave 波形并缩放到合适大小,打开 count[3:0]:
可看到数值变化,同时也可以双击展开 count[3:0],查看每一位的变化情况。
just format格式化默认缩进为 2 个空格,使用--indentation_spaces=4修改其为 4,just lint检查代码风格。
至此,环境准备工作已经结束。准备学习 Verilog 基础语法。




