// the "macro" to dump signals
`ifdef COCOTB_SIM
initial begin
$dumpfile ("multiplier.vcd");
$dumpvars (0, multiplier);
#1;
end
`endif
# test_multiplier.py
# 2022/09/13 by marsee
import random
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer, RisingEdge
@cocotb.test()
async def test_multiplier(dut):
dut.ap_rst = 1 # Reset
clock = Clock(dut.ap_clk, 10, units="ns") # Create a 10ns period clock on port clk
cocotb.start_soon(clock.start()) # Start the clock
await Timer(10, units='ns')
dut.ap_start = 1
dut.ap_rst = 0 # Normal Operation
for i in range(5):
dut.a.value = i
dut.b.value = i+1
for j in range(3):
await RisingEdge(dut.ap_clk)
await Timer(1, units='ns')
assert dut.c.value == i*(i+1), "Invalid value for multiplication {}".format(i*(i+1))
await Timer(9, units='ns')
# Makefile
# 2022/09/13 by marsee
SIM ?= icarus
VERILOG_SOURCES = $(shell pwd)/multiplier.v
VERILOG_SOURCES += $(shell pwd)/multiplier_mul_mul_16s_16s_32_4_1.v
TOPLEVEL = multiplier
MODULE = test_multiplier
include $(shell cocotb-config --makefiles)/Makefile.sim
(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/Cocotb/multiplier$ make
rm -f results.xml
make -f Makefile results.xml
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/Cocotb/multiplier' に入ります
rm -f results.xml
MODULE=test_multiplier TESTCASE= TOPLEVEL=multiplier TOPLEVEL_LANG=verilog \
/usr/bin/vvp -M /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb/libs -m libcocotbvpi_icarus sim_build/sim.vvp
-.--ns INFO gpi ..mbed/gpi_embed.cpp:76 in set_program_name_in_venv Did not detect Python virtual environment. Using system-wide Python interpreter
-.--ns INFO gpi ../gpi/GpiCommon.cpp:101 in gpi_print_registered_impl VPI registered
0.00ns INFO cocotb Running on Icarus Verilog version 10.1 (stable)
0.00ns INFO cocotb Running tests with cocotb v1.7.0 from /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb
0.00ns INFO cocotb Seeding Python random module with 1663099051
0.00ns INFO cocotb.regression Found test test_multiplier.test_multiplier
0.00ns INFO cocotb.regression running test_multiplier (1/1)
/media/masaaki/Ubuntu_Disk/Cocotb/multiplier/test_multiplier.py:11: DeprecationWarning: Setting values on handles using the ``dut.handle = value`` syntax is deprecated. Instead use the ``handle.value = value`` syntax
dut.ap_rst = 1 # Reset
VCD info: dumpfile multiplier.vcd opened for output.
/media/masaaki/Ubuntu_Disk/Cocotb/multiplier/test_multiplier.py:19: DeprecationWarning: Setting values on handles using the ``dut.handle = value`` syntax is deprecated. Instead use the ``handle.value = value`` syntax
dut.ap_start = 1
/media/masaaki/Ubuntu_Disk/Cocotb/multiplier/test_multiplier.py:20: DeprecationWarning: Setting values on handles using the ``dut.handle = value`` syntax is deprecated. Instead use the ``handle.value = value`` syntax
dut.ap_rst = 0 # Normal Operation
160.00ns INFO cocotb.regression test_multiplier passed
160.00ns INFO cocotb.regression *****************************************************************************************
** TEST STATUS SIM TIME (ns) REAL TIME (s) RATIO (ns/s) **
*****************************************************************************************
** test_multiplier.test_multiplier PASS 160.00 0.00 40576.39 **
*****************************************************************************************
** TESTS=1 PASS=1 FAIL=0 SKIP=0 160.00 0.21 754.96 **
*****************************************************************************************
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/Cocotb/multiplier' から出ます
// ==============================================================
// RTL generated by Vitis HLS - High-Level Synthesis from C, C++ and OpenCL v2022.1 (64-bit)
// Version: 2022.1
// Copyright (C) Copyright 1986-2022 Xilinx, Inc. All Rights Reserved.
//
// ===========================================================
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="multiplier_multiplier,hls_ip_2022_1,{HLS_INPUT_TYPE=cxx,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z020-clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=2.150000,HLS_SYN_LAT=3,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=0,HLS_SYN_FF=4,HLS_SYN_LUT=25,HLS_VERSION=2022_1}" *)
module multiplier (
ap_clk,
ap_rst,
ap_start,
ap_done,
ap_idle,
ap_ready,
a,
b,
c,
c_ap_vld,
ap_return
);
parameter ap_ST_fsm_state1 = 4'd1;
parameter ap_ST_fsm_state2 = 4'd2;
parameter ap_ST_fsm_state3 = 4'd4;
parameter ap_ST_fsm_state4 = 4'd8;
input ap_clk;
input ap_rst;
input ap_start;
output ap_done;
output ap_idle;
output ap_ready;
input [15:0] a;
input [15:0] b;
output [31:0] c;
output c_ap_vld;
output [31:0] ap_return;
reg ap_done;
reg ap_idle;
reg ap_ready;
reg c_ap_vld;
(* fsm_encoding = "none" *) reg [3:0] ap_CS_fsm;
wire ap_CS_fsm_state1;
wire signed [31:0] grp_fu_53_p2;
wire ap_CS_fsm_state4;
reg [3:0] ap_NS_fsm;
reg ap_ST_fsm_state1_blk;
wire ap_ST_fsm_state2_blk;
wire ap_ST_fsm_state3_blk;
wire ap_ST_fsm_state4_blk;
wire ap_ce_reg;
// power-on initialization
initial begin
#0 ap_CS_fsm = 4'd1;
end
multiplier_mul_mul_16s_16s_32_4_1 #(
.ID( 1 ),
.NUM_STAGE( 4 ),
.din0_WIDTH( 16 ),
.din1_WIDTH( 16 ),
.dout_WIDTH( 32 ))
mul_mul_16s_16s_32_4_1_U1(
.clk(ap_clk),
.reset(ap_rst),
.din0(b),
.din1(a),
.ce(1'b1),
.dout(grp_fu_53_p2)
);
always @ (posedge ap_clk) begin
if (ap_rst == 1'b1) begin
ap_CS_fsm <= ap_ST_fsm_state1;
end else begin
ap_CS_fsm <= ap_NS_fsm;
end
end
always @ (*) begin
if ((ap_start == 1'b0)) begin
ap_ST_fsm_state1_blk = 1'b1;
end else begin
ap_ST_fsm_state1_blk = 1'b0;
end
end
assign ap_ST_fsm_state2_blk = 1'b0;
assign ap_ST_fsm_state3_blk = 1'b0;
assign ap_ST_fsm_state4_blk = 1'b0;
always @ (*) begin
if ((1'b1 == ap_CS_fsm_state4)) begin
ap_done = 1'b1;
end else begin
ap_done = 1'b0;
end
end
always @ (*) begin
if (((ap_start == 1'b0) & (1'b1 == ap_CS_fsm_state1))) begin
ap_idle = 1'b1;
end else begin
ap_idle = 1'b0;
end
end
always @ (*) begin
if ((1'b1 == ap_CS_fsm_state4)) begin
ap_ready = 1'b1;
end else begin
ap_ready = 1'b0;
end
end
always @ (*) begin
if ((1'b1 == ap_CS_fsm_state4)) begin
c_ap_vld = 1'b1;
end else begin
c_ap_vld = 1'b0;
end
end
always @ (*) begin
case (ap_CS_fsm)
ap_ST_fsm_state1 : begin
if (((ap_start == 1'b1) & (1'b1 == ap_CS_fsm_state1))) begin
ap_NS_fsm = ap_ST_fsm_state2;
end else begin
ap_NS_fsm = ap_ST_fsm_state1;
end
end
ap_ST_fsm_state2 : begin
ap_NS_fsm = ap_ST_fsm_state3;
end
ap_ST_fsm_state3 : begin
ap_NS_fsm = ap_ST_fsm_state4;
end
ap_ST_fsm_state4 : begin
ap_NS_fsm = ap_ST_fsm_state1;
end
default : begin
ap_NS_fsm = 'bx;
end
endcase
end
assign ap_CS_fsm_state1 = ap_CS_fsm[32'd0];
assign ap_CS_fsm_state4 = ap_CS_fsm[32'd3];
assign ap_return = 32'd0;
assign c = grp_fu_53_p2;
endmodule //multiplier
`timescale 1 ns / 1 ps
module multiplier_mul_mul_16s_16s_32_4_1_DSP48_0(clk, rst, ce, a, b, p);
input clk;
input rst;
input ce;
input signed [16 - 1 : 0] a;
input signed [16 - 1 : 0] b;
output signed [32 - 1 : 0] p;
reg signed [32 - 1 : 0] p_reg;
reg signed [16 - 1 : 0] a_reg;
reg signed [16 - 1 : 0] b_reg;
reg signed [32 - 1 : 0] p_reg_tmp;
always @ (posedge clk) begin
if (ce) begin
a_reg <= a;
b_reg <= b;
p_reg_tmp <= a_reg * b_reg;
p_reg <= p_reg_tmp;
end
end
assign p = p_reg;
endmodule
`timescale 1 ns / 1 ps
module multiplier_mul_mul_16s_16s_32_4_1(
clk,
reset,
ce,
din0,
din1,
dout);
parameter ID = 32'd1;
parameter NUM_STAGE = 32'd1;
parameter din0_WIDTH = 32'd1;
parameter din1_WIDTH = 32'd1;
parameter dout_WIDTH = 32'd1;
input clk;
input reset;
input ce;
input[din0_WIDTH - 1:0] din0;
input[din1_WIDTH - 1:0] din1;
output[dout_WIDTH - 1:0] dout;
multiplier_mul_mul_16s_16s_32_4_1_DSP48_0 multiplier_mul_mul_16s_16s_32_4_1_DSP48_0_U(
.clk( clk ),
.rst( reset ),
.ce( ce ),
.a( din0 ),
.b( din1 ),
.p( dout ));
endmodule
// multiplier.cpp
// 2022/09/13 by marsee
//
#include <stdint.h>
int multiplier(int16_t a, int16_t b, int32_t *c){
*c = a * b;
return(0);
}
// multiplier_tb.cpp
// 2022/09/13 by marsee
//
#include <stdio.h>
#include <stdint.h>
int multiplier(int16_t a, int16_t b, int32_t *c);
int main(){
int16_t a, b;
int32_t c;
a = 3;
b = 4;
multiplier(a, b, &c);
printf("a = %d, b = %d, c = (a*b) = %d\n", a, b, c);
return(0);
}
のようだ。つまり、1 つのテストあたり 2 ns 時間が進むようだ。await Timer(2, units="ns")
(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/Cocotb/cocotb/examples/adder/tests$ make SIM=icarus
rm -f results.xml
make -f Makefile results.xml
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/Cocotb/cocotb/examples/adder/tests' に入ります
mkdir -p sim_build
/usr/bin/iverilog -o sim_build/sim.vvp -D COCOTB_SIM=1 -s adder -f sim_build/cmds.f -g2012 /media/masaaki/Ubuntu_Disk/Cocotb/cocotb/examples/adder/tests/../hdl/adder.sv
rm -f results.xml
MODULE=test_adder TESTCASE= TOPLEVEL=adder TOPLEVEL_LANG=verilog \
/usr/bin/vvp -M /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb/libs -m libcocotbvpi_icarus sim_build/sim.vvp
-.--ns INFO gpi ..mbed/gpi_embed.cpp:76 in set_program_name_in_venv Did not detect Python virtual environment. Using system-wide Python interpreter
-.--ns INFO gpi ../gpi/GpiCommon.cpp:101 in gpi_print_registered_impl VPI registered
0.00ns INFO cocotb Running on Icarus Verilog version 10.1 (stable)
0.00ns INFO cocotb Running tests with cocotb v1.7.0 from /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb
0.00ns INFO cocotb Seeding Python random module with 1662838789
0.00ns INFO cocotb.regression Found test test_adder.adder_basic_test
0.00ns INFO cocotb.regression Found test test_adder.adder_randomised_test
0.00ns INFO cocotb.regression running adder_basic_test (1/2)
Test for 5 + 10
VCD info: dumpfile dump.vcd opened for output.
2.00ns INFO cocotb.regression adder_basic_test passed
2.00ns INFO cocotb.regression running adder_randomised_test (2/2)
Test for adding 2 random numbers multiple times
22.00ns INFO cocotb.regression adder_randomised_test passed
22.00ns INFO cocotb.regression ******************************************************************************************
** TEST STATUS SIM TIME (ns) REAL TIME (s) RATIO (ns/s) **
******************************************************************************************
** test_adder.adder_basic_test PASS 2.00 0.00 2616.21 **
** test_adder.adder_randomised_test PASS 20.00 0.00 19518.44 **
******************************************************************************************
** TESTS=2 PASS=2 FAIL=0 SKIP=0 22.00 0.29 76.33 **
******************************************************************************************
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/Cocotb/cocotb/examples/adder/tests' から出ます
// the "macro" to dump signals
`ifdef COCOTB_SIM
initial begin
$dumpfile ("button_deb.vcd");
$dumpvars (0, button_deb);
#1;
end
`endif
// dff.sv
`timescale 1us/1ns
module dff (
output logic q,
input logic clk, d
);
always @(posedge clk) begin
q <= d;
end
`ifdef COCOTB_SIM
initial begin
$dumpfile ("dff.vcd");
$dumpvars (0, dff);
#1;
end
`endif
endmodule
SIM ?= icarus
# Makefile
SIM ?= icarus
TOPLEVEL_LANG = verilog
VERILOG_SOURCES = $(shell pwd)/dff.sv
TOPLEVEL = dff
MODULE = test_dff
include $(shell cocotb-config --makefiles)/Makefile.sim
cocotbは、Pythonを使用してVHDL および SystemVerilog RTLを検証するためのCOroutineベースのCOsimulation TestBench環境です。
(base) masaaki@masaaki-H110M4-M01:/media/masaaki/Ubuntu_Disk/Cocotb/dff_example$ make SIM=icarus
rm -f results.xml
make -f Makefile results.xml
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/Cocotb/dff_example' に入ります
mkdir -p sim_build
/usr/bin/iverilog -o sim_build/sim.vvp -D COCOTB_SIM=1 -s dff -f sim_build/cmds.f -g2012 /media/masaaki/Ubuntu_Disk/Cocotb/dff_example/dff.sv
rm -f results.xml
MODULE=test_dff TESTCASE= TOPLEVEL=dff TOPLEVEL_LANG=verilog \
/usr/bin/vvp -M /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb/libs -m libcocotbvpi_icarus sim_build/sim.vvp
-.--ns INFO gpi ..mbed/gpi_embed.cpp:76 in set_program_name_in_venv Did not detect Python virtual environment. Using system-wide Python interpreter
-.--ns INFO gpi ../gpi/GpiCommon.cpp:101 in gpi_print_registered_impl VPI registered
0.00ns INFO cocotb Running on Icarus Verilog version 10.1 (stable)
0.00ns INFO cocotb Running tests with cocotb v1.7.0 from /home/masaaki/anaconda3/lib/python3.8/site-packages/cocotb
0.00ns INFO cocotb Seeding Python random module with 1662639569
0.00ns INFO cocotb.regression Found test test_dff.test_dff_simple
0.00ns INFO cocotb.regression running test_dff_simple (1/1)
Test that d propagates to q
95001.00ns INFO cocotb.regression test_dff_simple passed
95001.00ns INFO cocotb.regression **************************************************************************************
** TEST STATUS SIM TIME (ns) REAL TIME (s) RATIO (ns/s) **
**************************************************************************************
** test_dff.test_dff_simple PASS 95001.00 0.00 33260690.68 **
**************************************************************************************
** TESTS=1 PASS=1 FAIL=0 SKIP=0 95001.00 2.71 35015.19 **
**************************************************************************************
make[1]: ディレクトリ '/media/masaaki/Ubuntu_Disk/Cocotb/dff_example' から出ます
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | 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 | - |