cocotb ist ein HDL-Testframework, das Python verwendet. Ich habe eine Weile zugesehen, aber seit Version 1.0 veröffentlicht wurde, habe ich beschlossen, es auszuprobieren.
cocotb ist ein leichtes Testframework für HDL, das von Potential Ventures in Python entwickelt wurde. Es wird auf GitHub unter einer BSD-Lizenz veröffentlicht. https://github.com/potentialventures/cocotb
Das Dokument ist hier. http://cocotb.readthedocs.org/en/latest/index.html
Sie ist sich des schnellen Starts einer Verifizierungsumgebung in der FPGA-Entwicklung bewusst und ist viel leichter als UVM, das in System Verilog und in Python geschrieben wurde. Daher ist die Beschreibung einfach und leicht zu lesen.
Kompatible Simulatoren sind Icarus Verilog, VCS, Riviera-PRO, [Questa (ModelSim)](http://www.mentorg.co.jp/products/fv/ Es unterstützt questa /), Incisive. Besonders Ikarus und VCS scheinen eine gute Affinität zu haben.
Darüber hinaus verfügt es über eine Dateiausgabefunktion für xUnit, und es kann gesagt werden, dass die Verknüpfung mit dem CI-Tool Jenkins einfach ist.
Python-Generatoren, Collouts und Decorator-Technologie werden verwendet, um auf DUT (HDL) zuzugreifen. Es ist ein Mechanismus, um den Simulator im Collout anzuhalten, die Verarbeitung von Cocotb einzufügen und den Simulator neu zu starten. Es gibt einige Dinge, mit denen Leute, die Python verwenden, nicht vertraut sind, aber mit Cocotb müssen Sie sich dessen nicht sehr bewusst sein, wenn Sie wissen, wie man es verwendet.
Dieses Mal habe ich anhand des Beispiels und des Dokuments versucht, die Umgebung für die Überprüfung der sequentiellen Schaltung von Verilog mithilfe von cocotb zu beschreiben. Das Betriebssystem ist CentOS 6.6.
Von GitHub herunterladen.
git clone https://github.com/potentialventures/cocotb
Dieses Mal habe ich ein neues Arbeitsverzeichnis im Verzeichnis "example" erstellt, die Verzeichnisse "rtl" und "tests" darin erstellt und den Prüfling bzw. die Tests gespeichert.
Icarus Verilog wird für den Simulator verwendet. Fügen Sie "icarus" in den Simulatorauswahlteil von "Makefile.sim" im Verzeichnis "makefiles" ein.
# Default to Icarus if no simulator is defined
SIM ?= icarus
DUT Es ist eine 8-Bit-Sequenzschaltung. Im Inneren versuche ich, eine VCD-Datei für die Wellenformerfassung auszugeben.
dff.v
module dff(
input RST_N,
input CLK,
input [7:0] D,
output reg [7:0] Q
);
always @(negedge RST_N, posedge CLK)
if(~RST_N)
Q <= 8'h0;
else
Q <= D;
initial begin
$dumpfile("dump.vcd");
$dumpvars(1, dff);
end
endmodule
Ich habe eine Testbench-Umgebung (eine Instanz mit Prüfling) und eine einfache Treiberprüfung eingerichtet, da ich nur eine Datei benötige. Dies ist ein Szenario, in dem ein zufälliger Wert eingegeben und der Ausgabewert vom Prüfling nach einem Zyklus überprüft wird.
tests.py
import cocotb
from cocotb.triggers import Timer, RisingEdge
from cocotb.result import TestFailure
from cocotb.clock import Clock
import random
class DffTB(object):
def __init__(self, dut, dubug=True):
self.dut = dut
@cocotb.coroutine
def reset(self, duration=10000):
self.dut.log.info("Resetting DUT")
self.dut.RST_N <= 0
self.dut.D <= 0
yield Timer(duration)
yield RisingEdge(self.dut.CLK)
self.dut.RST_N <= 1
self.dut.log.info("Out of reset")
@cocotb.coroutine
def gen_and_check(self):
D = random.randint(0, 255)
self.dut.D = D;
yield RisingEdge(self.dut.CLK)
yield Timer(1)
if int(self.dut.Q) != D :
raise TestFailure(
"[NG] Compre error. D==%s Q==%s" % (D, int(self.dut.Q)))
else :
self.dut.log.info("[OK]")
@cocotb.coroutine
def clock_gen(signal):
while True:
signal <= 0
yield Timer(5000)
signal <= 1
yield Timer(5000)
@cocotb.test()
def basic_test(dut):
"""basic_test"""
tb = DffTB(dut)
cocotb.fork(clock_gen(dut.CLK))
yield RisingEdge(dut.CLK)
yield tb.reset()
for i in range(30):
yield tb.gen_and_check()
In cocotb ist "dut" das reservierte Wort, das der obersten Ebene des Prüflings entspricht. Der Einfachheit halber wird bisher nur eine Instanz von dut für den Klassenkonstruktor beschrieben, aber wir werden die Verarbeitung hinzufügen, z. B. das Initialisieren anderer Verifizierungsmodule und Dienstprogramme.
Das Testszenario wird geschrieben, indem cocotb.test () wie am Ende geschrieben dekoriert wird.
Bei der Durchführung der Simulation ist der Hauptverarbeitungsteil das Dekorieren von cocotb.coroutine. In der obigen Beschreibung handelt es sich um "clock_gen" und "gen_and_check".
Ich habe ein Makefile im Verzeichnis "tests" vorbereitet. Geben Sie die oberste Hierarchie des Prüflings in (TOPLEVEL) an und geben Sie den Namen des Python-Skripts in (MODULE) ein.
Makefile
TOPLEVEL := dff
TOPLEVEL_LANG ?= verilog
PWD=$(shell pwd)
COCOTB=$(PWD)/../../..
ifeq ($(OS),Msys)
WPWD=$(shell sh -c 'pwd -W')
PYTHONPATH := $(WPWD)/../model;$(PYTHONPATH)
else
WPWD=$(shell pwd)
PYTHONPATH := $(WPWD)/../model:$(PYTHONPATH)
endif
export PYTHONPATH
VERILOG_SOURCES = $(WPWD)/../rtl/dff.v
GPI_IMPL := vpi
export TOPLEVEL_LANG
MODULE ?= tests
include $(COCOTB)/makefiles/Makefile.inc
include $(COCOTB)/makefiles/Makefile.sim
Wie unten gezeigt, konnten wir von der Initialisierungsphase zum Zurücksetzen, Überprüfen des Ausgabewerts und Beenden der Simulation übergehen.
TESTCASE= TOPLEVEL=dff \
vvp -M /tmp/cocotb/build/libs/x86_64 -m gpivpi sim_build/sim.vvp
-.--ns INFO cocotb.gpi GpiCommon.cpp:47 in gpi_print_registered_impl VPI registered
0.00ns INFO cocotb.gpi gpi_embed.c:229 in embed_sim_init Running on Icarus Verilog version 0.9.6
0.00ns INFO cocotb.gpi gpi_embed.c:230 in embed_sim_init Python interpreter initialised and cocotb loaded!
0.00ns INFO cocotb.gpi __init__.py:103 in _initialise_testbench Running tests with Cocotb v1.0 from /tmp/cocotb
0.00ns INFO cocotb.gpi __init__.py:119 in _initialise_testbench Seeding Python random module with 1430897996
0.00ns INFO cocotb.regression regression.py:153 in initialise Found test tests.basic_test
0.00ns INFO cocotb.regression regression.py:254 in execute Running test 1/1: basic_test
0.00ns INFO ..routine.basic_test.0x7f2a3156ffd0 decorators.py:186 in send Starting test: "basic_test"
Description: basic_test
VCD info: dumpfile dump.vcd opened for output.
5.00ns INFO cocotb.dff tests.py:14 in reset Resetting DUT
15.00ns INFO cocotb.dff tests.py:20 in reset Out of reset
25.00ns INFO cocotb.dff tests.py:32 in gen_and_check [OK]
35.00ns INFO cocotb.dff tests.py:32 in gen_and_check [OK]
(Unterlassung)
315.00ns INFO cocotb.dff tests.py:32 in gen_and_check [OK]
315.00ns INFO cocotb.regression regression.py:201 in handle_result Test Passed: basic_test
315.00ns INFO cocotb.regression regression.py:162 in tear_down Passed 1 tests (0 skipped)
315.00ns INFO cocotb.regression regression.py:168 in tear_down Shutting down...
Die Wellenform ist wie folgt. Sie können sehen, dass es mit RST_N initialisiert wird und dann ein zufälliger Wert eingegeben wird.
Mit einigen Python-Kenntnissen habe ich den Eindruck, dass es relativ einfach ist, eine Verifizierungsumgebung zu erstellen. Obwohl ich es möglicherweise nicht verstehe, ist die Dokumentation nicht sehr vollständig. Außerdem hatte der Endian Swapper zu Beginn des Tutorials das Gefühl, dass die Schwelle zu hoch war. In SystemVerilog ist es jedoch leicht zu verstehen, ob der Testteil, der schwer zu debuggen ist, Python ist, und ich denke, dass die Verwendung einer Python-Bibliothek wie zufällig diesmal einen großen Vorteil in Bezug auf die Kosten und viele Benutzer hat. Ich werde. 1.0 ist gerade erschienen und ich habe hohe Erwartungen für die Zukunft.
Recommended Posts