本文最后更新于 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")
def async_bubblesort_verilog_test(parameters): 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()))) run( python_search = [test_path], verilog_sources = verilog_sources, toplevel = "add_wrapper", module = "async_add_tb", waves = True, sim_build = sim_build )
if __name__ == '__main__': async_bubblesort_verilog_test(parameters)
|
程序运行默认的verilog仿真器是iverilog,要更改需要在.bashrc上增加环境变量SIM=icarus,然后运行程序
对于PyCharm的终端,用户的环境变量无法被读出,因此我们要创建一个配置去执行我们的程序。
运行之后会发现波形文件被生成在sim_build目录中。