使用PyCharm部署verilog一键仿真环境

本文最后更新于 2024年9月19日 凌晨

选择verliog的仿真器

网上有很多仿真器供我们选择,像verilator,icarus等。 这里我使用的是icarus,其他仿真器配置类似。

环境搭建

这里只进行linux环境搭建的介绍,windows的一键下载应该没有人不会用吧。

icarus安装

1
sudo apt install verilog

python环境

我使用的是python3.10.x版本,其他版本的使用不做保证

1
2
pip install cocotb-test
pip install pytest

这里构建主要依赖于cocotb-test包,如果想要详细了解,这里是它的文档

PyCharm设置

推荐的插件

编程的高亮对于程序员来说直接影响编程的体验,推荐使用免费插件verilog support,当然有钱购买官方的systemverilog可以获得更好的体验。

文件结构

正常创建项目以后,我们先确定文件的存放路径。

我将用于module都放置于项目目录下的src文件夹中,顶层modlule文件放置于wrapper文件夹中。使用python来写testbench,放在test文件中,我们最后生成的结果记录和vcd波形文件都会生成在test文件夹中。

注意:这里的顶层文件其实只是将moudule相应的接口引出

示例

这里提供一个加法器的verilog程序作为例子

add.v

1
2
3
4
5
6
7
8
// 四位全加器
module adder4(cout,sum,ina,inb,cin);
output[3:0] sum;
output cout;
input[3:0] ina,inb;
input cin;
assign {cout,sum}=ina+inb;
endmodule

add_wrapper.v

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
`timescale 1ns/1ns

module add_wrapper #(
parameter digit4 = 4
)(
output [digit4-1:0] res,
output cout,
input [digit4-1:0] a,b,
input cin
);

adder4 adder (
.sum(res),
.cout(cout),
.ina(a),
.inb(b),
.cin(cin)
);
initial begin
$dumpfile("vcd/async_add.vcd"); // 把当前和子模块的所有数据波形保存到该文件中
$dumpvars();
end
endmodule

async_add_wrapper.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import logging
import os

import pytest
import cocotb_test.simulator

import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotb.utils import get_sim_steps

class async_add:
def __init__(self,dut):
self.dut=dut
self.log=logging.getLogger("cocotb.tb")
self.log.setLevel(logging.INFO)
self.dut.a.setimmediatevalue(0)
self.dut.b.setimmediatevalue(0)
self.dut.cin.setimmediatevalue(0)
self.log.info("Starting asynchronous add test...")
cocotb.start_soon(Clock(dut.cin,2,units="ns").start())

async def ichange(self):
self.log.info("Running ichange...")
for i in range(16):
await RisingEdge(self.dut.cin)
self.dut.a.setimmediatevalue(i)

async def jchange(self):
self.log.info("Running jchange...")
for j in range(16):
await RisingEdge(self.dut.cin)
self.dut.b.setimmediatevalue(j)
@cocotb.test()
async def run_test(dut):
async_add_tb= async_add(dut)
await async_add_tb.ichange()
await async_add_tb.jchange()

build.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from cocotb_test.simulator import run
import pytest
import os

project_dir = os.path.abspath(".")
test_path = os.path.join(project_dir, "test")
src_path = os.path.join(project_dir, "src")
wrapper_path = os.path.join(project_dir, "wrapper")
parameters = {}


@pytest.mark.skipif(os.getenv("SIM") == "ghdl", reason="Verilog not suported")
# @pytest.mark.parametrize("parameters", [
# {"DATA_WIDTH":"8", "ADDR_WIDTH":"8"}
# ])
def async_bubblesort_verilog_test(parameters):
# 参与编译的所有文件路径要写入verilog_source
verilog_sources = [
os.path.join(wrapper_path, "add_wrapper.v"),
os.path.join(src_path, "add.v")
]

sim_build = os.path.join(test_path, "sim_build", "_".join(("{}={}".format(*i) for i in parameters.items())))
# toplevel和module根据项目修改
run(
python_search = [test_path],
verilog_sources = verilog_sources,
toplevel = "add_wrapper",
module = "async_add_tb",
# parameters = parameters,
# extra_env = parameters,
waves = True,
sim_build = sim_build
) # sources # top level HDL # name of cocotb test module


# @pytest.mark.skipif(os.getenv("SIM") == "verilator", reason="VHDL not suported")
# @pytest.mark.skipif(os.getenv("SIM") == "icarus", reason="VHDL not suported")
# def test_dff_vhdl():
# run(vhdl_sources=[os.path.join(tests_dir, "dff.vhdl")], toplevel="dff_test_vhdl", module="dff_cocotb", toplevel_lang="vhdl")
if __name__ == '__main__':
async_bubblesort_verilog_test(parameters)

程序运行默认的verilog仿真器是iverilog,要更改需要在.bashrc上增加环境变量SIM=icarus,然后运行程序

1
python3 build.py

对于PyCharm的终端,用户的环境变量无法被读出,因此我们要创建一个配置去执行我们的程序。

运行之后会发现波形文件被生成在sim_build目录中。


使用PyCharm部署verilog一键仿真环境
http://example.com/posts/35126/
作者
晓寒
发布于
2024年9月18日
许可协议