@@ -0,0 +1,3 @@ | |||
[submodule "7Segment_Lattice_ice40_UltraPlus"] | |||
path = 7Segment_Lattice_ice40_UltraPlus | |||
url = https://git.efi.th-nuernberg.de/gitea/schmidtsi76327/7Segment_Lattice_ice40_UltraPlus |
@@ -0,0 +1,3 @@ | |||
{ | |||
"python.pythonPath": "/usr/bin/python3" | |||
} |
@@ -0,0 +1,29 @@ | |||
////////////////////////////////////////////////////////////// | |||
// 4-bit loadable up-down counter ////// | |||
////////////////////////////////////////////////////////////// | |||
module counter(clk, rst, data, updown, load, data_out); | |||
input clk, rst, load; | |||
input updown; | |||
input [3:0] data; | |||
output reg [3:0] data_out; | |||
always @(posedge clk) | |||
begin | |||
if(rst) | |||
data_out <= 4'b0; | |||
else if(load) | |||
data_out <= data; | |||
else | |||
data_out <= ((updown)?(data_out + 1'b1):(data_out -1'b1)); | |||
end | |||
// Dump waves | |||
initial begin | |||
$dumpfile("dump.vcd"); | |||
$dumpvars(1, counter); | |||
end | |||
endmodule |
@@ -0,0 +1,49 @@ | |||
############################################################################### | |||
# Copyright (c) 2013 Potential Ventures Ltd | |||
# Copyright (c) 2013 SolarFlare Communications Inc | |||
# All rights reserved. | |||
# | |||
# Redistribution and use in source and binary forms, with or without | |||
# modification, are permitted provided that the following conditions are met: | |||
# * Redistributions of source code must retain the above copyright | |||
# notice, this list of conditions and the following disclaimer. | |||
# * Redistributions in binary form must reproduce the above copyright | |||
# notice, this list of conditions and the following disclaimer in the | |||
# documentation and/or other materials provided with the distribution. | |||
# * Neither the name of Potential Ventures Ltd, | |||
# SolarFlare Communications Inc nor the | |||
# names of its contributors may be used to endorse or promote products | |||
# derived from this software without specific prior written permission. | |||
# | |||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
# DISCLAIMED. IN NO EVENT SHALL POTENTIAL VENTURES LTD BE LIABLE FOR ANY | |||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
############################################################################### | |||
TOPLEVEL_LANG ?= verilog | |||
PWD=$(shell pwd) | |||
ifeq ($(TOPLEVEL_LANG),verilog) | |||
VERILOG_SOURCES = $(PWD)/../hdl/counter.sv | |||
else ifeq ($(TOPLEVEL_LANG),vhdl) | |||
VHDL_SOURCES = $(PWD)/../hdl/counter.vhdl | |||
else | |||
$(error "A valid value (verilog or vhdl) was not provided for TOPLEVEL_LANG=$(TOPLEVEL_LANG)") | |||
endif | |||
TOPLEVEL := counter | |||
MODULE := test_counter | |||
include $(shell cocotb-config --makefiles)/Makefile.sim | |||
clean:: | |||
rm -rf dump.vcd results.xml | |||
@@ -0,0 +1,183 @@ | |||
$date | |||
Tue Jun 8 18:10:07 2021 | |||
$end | |||
$version | |||
Icarus Verilog | |||
$end | |||
$timescale | |||
1ps | |||
$end | |||
$scope module counter $end | |||
$var wire 1 ! clk $end | |||
$var wire 4 " data [3:0] $end | |||
$var wire 1 # load $end | |||
$var wire 1 $ rst $end | |||
$var wire 1 % updown $end | |||
$var reg 4 & data_out [3:0] $end | |||
$upscope $end | |||
$enddefinitions $end | |||
#0 | |||
$dumpvars | |||
bx & | |||
z% | |||
z$ | |||
z# | |||
bz " | |||
1! | |||
$end | |||
#5000000 | |||
0! | |||
#10000000 | |||
1$ | |||
1! | |||
#15000000 | |||
0! | |||
#20000000 | |||
b0 & | |||
1! | |||
#25000000 | |||
0! | |||
#30000000 | |||
1! | |||
#35000000 | |||
0! | |||
#40000000 | |||
1! | |||
#40000001 | |||
0$ | |||
1# | |||
b1110 " | |||
#45000001 | |||
0! | |||
#50000001 | |||
b1110 & | |||
1! | |||
#55000001 | |||
0! | |||
#55000002 | |||
b0 & | |||
1$ | |||
0# | |||
1% | |||
b1100 " | |||
1! | |||
#60000002 | |||
0$ | |||
0! | |||
#65000002 | |||
b1 & | |||
1! | |||
#70000002 | |||
0! | |||
#75000002 | |||
b10 & | |||
1! | |||
#80000002 | |||
0! | |||
#85000002 | |||
b11 & | |||
1! | |||
#90000002 | |||
0! | |||
#95000002 | |||
b100 & | |||
1! | |||
#100000002 | |||
0! | |||
#105000002 | |||
b101 & | |||
1! | |||
#110000002 | |||
0! | |||
#115000002 | |||
b110 & | |||
1! | |||
#120000002 | |||
0! | |||
#125000002 | |||
b111 & | |||
1! | |||
#130000002 | |||
0! | |||
#135000002 | |||
b1000 & | |||
1! | |||
#140000002 | |||
0! | |||
#145000002 | |||
b1001 & | |||
1! | |||
#150000002 | |||
0! | |||
#155000002 | |||
b1010 & | |||
1! | |||
#160000002 | |||
0! | |||
#160000003 | |||
b0 & | |||
1$ | |||
0% | |||
b1110 " | |||
1! | |||
#165000003 | |||
0$ | |||
1# | |||
0! | |||
#170000003 | |||
b1110 & | |||
1! | |||
#175000003 | |||
0# | |||
0! | |||
#180000003 | |||
b1101 & | |||
1! | |||
#185000003 | |||
0! | |||
#190000003 | |||
b1100 & | |||
1! | |||
#195000003 | |||
0! | |||
#200000003 | |||
b1011 & | |||
1! | |||
#205000003 | |||
0! | |||
#210000003 | |||
b1010 & | |||
1! | |||
#215000003 | |||
0! | |||
#220000003 | |||
b1001 & | |||
1! | |||
#225000003 | |||
0! | |||
#230000003 | |||
b1000 & | |||
1! | |||
#235000003 | |||
0! | |||
#240000003 | |||
b111 & | |||
1! | |||
#245000003 | |||
0! | |||
#250000003 | |||
b110 & | |||
1! | |||
#255000003 | |||
0! | |||
#260000003 | |||
b101 & | |||
1! | |||
#265000003 | |||
0! | |||
#270000003 | |||
b100 & | |||
1! | |||
#275000003 | |||
0! | |||
#275000004 |
@@ -0,0 +1,9 @@ | |||
<testsuites name="results"> | |||
<testsuite name="all" package="all"> | |||
<property name="random_seed" value="1623168607" /> | |||
<testcase name="test_counter_reset" classname="test_counter" file="/home/sim/ice40/sta/4-bit-counter-cocotb/tests/test_counter.py" lineno="7" time="0.0012416839599609375" sim_time_ns="40000.001" ratio_time="32214317.241609827" /> | |||
<testcase name="test_counter_load" classname="test_counter" file="/home/sim/ice40/sta/4-bit-counter-cocotb/tests/test_counter.py" lineno="25" time="0.0005171298980712891" sim_time_ns="15000.001000000004" ratio_time="29006253.662657455" /> | |||
<testcase name="test_counter_inc" classname="test_counter" file="/home/sim/ice40/sta/4-bit-counter-cocotb/tests/test_counter.py" lineno="41" time="0.0017952919006347656" sim_time_ns="105000.00099999999" ratio_time="58486311.31398459" /> | |||
<testcase name="test_counter_dec" classname="test_counter" file="/home/sim/ice40/sta/4-bit-counter-cocotb/tests/test_counter.py" lineno="67" time="0.0019235610961914062" sim_time_ns="115000.00100000002" ratio_time="59784948.46235797" /> | |||
</testsuite> | |||
</testsuites> |
@@ -0,0 +1 @@ | |||
+timescale+1ns/1ps |
@@ -0,0 +1,79 @@ | |||
#! /usr/local/bin/vvp | |||
:ivl_version "12.0 (devel)" "(s20150603-1130-g1f8876be)"; | |||
:ivl_delay_selection "TYPICAL"; | |||
:vpi_time_precision - 12; | |||
:vpi_module "/usr/local/lib/ivl/system.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/vhdl_sys.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/vhdl_textio.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/v2005_math.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/va_math.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/v2009.vpi"; | |||
S_0x55fb04b57e00 .scope package, "$unit" "$unit" 2 1; | |||
.timescale -9 -12; | |||
S_0x55fb04b57f90 .scope module, "counter" "counter" 3 5; | |||
.timescale -9 -12; | |||
.port_info 0 /INPUT 1 "clk"; | |||
.port_info 1 /INPUT 1 "rst"; | |||
.port_info 2 /INPUT 4 "data"; | |||
.port_info 3 /INPUT 1 "updown"; | |||
.port_info 4 /INPUT 1 "load"; | |||
.port_info 5 /OUTPUT 4 "data_out"; | |||
o0x7f9f460c2018 .functor BUFZ 1, C4<z>; HiZ drive | |||
v0x55fb04b7dc80_0 .net "clk", 0 0, o0x7f9f460c2018; 0 drivers | |||
o0x7f9f460c2048 .functor BUFZ 4, C4<zzzz>; HiZ drive | |||
v0x55fb04ba0930_0 .net "data", 3 0, o0x7f9f460c2048; 0 drivers | |||
v0x55fb04ba0a10_0 .var "data_out", 3 0; | |||
o0x7f9f460c20a8 .functor BUFZ 1, C4<z>; HiZ drive | |||
v0x55fb04ba0ad0_0 .net "load", 0 0, o0x7f9f460c20a8; 0 drivers | |||
o0x7f9f460c20d8 .functor BUFZ 1, C4<z>; HiZ drive | |||
v0x55fb04ba0b90_0 .net "rst", 0 0, o0x7f9f460c20d8; 0 drivers | |||
o0x7f9f460c2108 .functor BUFZ 1, C4<z>; HiZ drive | |||
v0x55fb04ba0ca0_0 .net "updown", 0 0, o0x7f9f460c2108; 0 drivers | |||
E_0x55fb04b905c0 .event posedge, v0x55fb04b7dc80_0; | |||
.scope S_0x55fb04b57f90; | |||
T_0 ; | |||
%wait E_0x55fb04b905c0; | |||
%load/vec4 v0x55fb04ba0b90_0; | |||
%flag_set/vec4 8; | |||
%jmp/0xz T_0.0, 8; | |||
%pushi/vec4 0, 0, 4; | |||
%assign/vec4 v0x55fb04ba0a10_0, 0; | |||
%jmp T_0.1; | |||
T_0.0 ; | |||
%load/vec4 v0x55fb04ba0ad0_0; | |||
%flag_set/vec4 8; | |||
%jmp/0xz T_0.2, 8; | |||
%load/vec4 v0x55fb04ba0930_0; | |||
%assign/vec4 v0x55fb04ba0a10_0, 0; | |||
%jmp T_0.3; | |||
T_0.2 ; | |||
%load/vec4 v0x55fb04ba0ca0_0; | |||
%flag_set/vec4 8; | |||
%jmp/0 T_0.4, 8; | |||
%load/vec4 v0x55fb04ba0a10_0; | |||
%addi 1, 0, 4; | |||
%jmp/1 T_0.5, 8; | |||
T_0.4 ; End of true expr. | |||
%load/vec4 v0x55fb04ba0a10_0; | |||
%subi 1, 0, 4; | |||
%jmp/0 T_0.5, 8; | |||
; End of false expr. | |||
%blend; | |||
T_0.5; | |||
%assign/vec4 v0x55fb04ba0a10_0, 0; | |||
T_0.3 ; | |||
T_0.1 ; | |||
%jmp T_0; | |||
.thread T_0; | |||
.scope S_0x55fb04b57f90; | |||
T_1 ; | |||
%vpi_call/w 3 25 "$dumpfile", "dump.vcd" {0 0 0}; | |||
%vpi_call/w 3 26 "$dumpvars", 32'sb00000000000000000000000000000001, S_0x55fb04b57f90 {0 0 0}; | |||
%end; | |||
.thread T_1; | |||
# The file index is used to find the file name in the following table. | |||
:file_names 4; | |||
"N/A"; | |||
"<interactive>"; | |||
"-"; | |||
"/home/sim/ice40/cocotb/examples/4-bit-counter/tests/../hdl/counter.sv"; |
@@ -0,0 +1,98 @@ | |||
import cocotb | |||
from cocotb.clock import Clock | |||
from cocotb.triggers import Timer, RisingEdge, FallingEdge | |||
import random | |||
@cocotb.test() | |||
async def test_counter_reset(dut): | |||
clock = Clock(dut.clk, 10, units="us") # Create a 10us period clock on port clk | |||
cocotb.fork(clock.start()) # Start the clock | |||
await RisingEdge(dut.clk) | |||
await RisingEdge(dut.clk) | |||
dut.rst <= 1 | |||
await RisingEdge(dut.clk) | |||
await FallingEdge(dut.clk) | |||
cnt = dut.data_out.value.integer # assert counter ouput is 0 | |||
assert cnt == 0 | |||
await RisingEdge(dut.clk) | |||
await RisingEdge(dut.clk) | |||
@cocotb.test() | |||
async def test_counter_load(dut): | |||
clock = Clock(dut.clk, 10, units="us") # Create a 10us period clock on port clk | |||
cocotb.fork(clock.start()) # Start the clock | |||
dut.rst <= 0 | |||
dut.load <= 1 | |||
soll = random.randint(0,15) | |||
dut.data <= soll | |||
await RisingEdge(dut.clk) | |||
await FallingEdge(dut.clk) | |||
assert dut.data_out.value.integer == soll, f"counter value is incorrect: {dut.data_out.value.integer} != {soll}" | |||
@cocotb.test() | |||
async def test_counter_inc(dut): | |||
"""Test for count up""" | |||
dut.rst <= 0 | |||
dut.load <= 0 | |||
dut.updown <= 1 | |||
dut.data <= random.randint(0,15) | |||
clock = Clock(dut.clk, 10, units="us") # Create a 10us period clock on port clk | |||
cocotb.fork(clock.start()) # Start the clock | |||
dut.rst <= 1 | |||
await RisingEdge(dut.clk) | |||
await FallingEdge(dut.clk) | |||
dut.rst <= 0 | |||
soll = 0 | |||
for _ in range(10): | |||
assert dut.data_out.value.integer == soll, f"counter value is incorrect: {dut.data_out.value.integer} != {soll}" | |||
await RisingEdge(dut.clk) | |||
soll += 1 | |||
await FallingEdge(dut.clk) | |||
@cocotb.test() | |||
async def test_counter_dec(dut): | |||
"""Test for count down""" | |||
dut.rst <= 0 | |||
dut.load <= 0 | |||
dut.updown <= 0 | |||
dut.data <= 14 | |||
soll = 14 | |||
clock = Clock(dut.clk, 10, units="us") # Create a 10us period clock on port clk | |||
cocotb.fork(clock.start()) # Start the clock | |||
dut.rst <= 1 | |||
await RisingEdge(dut.clk) | |||
await FallingEdge(dut.clk) | |||
dut.rst <= 0 | |||
dut.load <= 1 | |||
await RisingEdge(dut.clk) | |||
await FallingEdge(dut.clk) | |||
dut.load <= 0 | |||
for _ in range(10): | |||
assert dut.data_out.value.integer == soll, f"counter value is incorrect: {dut.data_out.value.integer} != {soll}" | |||
await RisingEdge(dut.clk) | |||
soll -= 1 | |||
await FallingEdge(dut.clk) | |||
@@ -0,0 +1,3 @@ | |||
{ | |||
"python.pythonPath": "/usr/bin/python3" | |||
} |
@@ -0,0 +1,46 @@ | |||
// File: counter_4bit.v | |||
// Generated by MyHDL 0.11 | |||
// Date: Mon Jun 7 19:39:23 2021 | |||
`timescale 1ns/10ps | |||
module counter_4bit ( | |||
clk, | |||
rst, | |||
data, | |||
updown, | |||
load, | |||
data_out | |||
); | |||
input clk; | |||
input rst; | |||
input [3:0] data; | |||
input updown; | |||
input load; | |||
output [3:0] data_out; | |||
reg [3:0] data_out; | |||
always @(posedge clk) begin: COUNTER_4BIT_CYCLE | |||
if (rst) begin | |||
data_out <= 0; | |||
end | |||
else if (load) begin | |||
data_out <= data; | |||
end | |||
else begin | |||
if (updown) begin | |||
data_out <= (data_out + 1); | |||
end | |||
else begin | |||
data_out <= (data_out - 1); | |||
end | |||
end | |||
end | |||
endmodule |
@@ -0,0 +1,33 @@ | |||
import myhdl | |||
from myhdl import * | |||
@block | |||
def counter_4bit(clk, rst, data, updown, load, data_out): | |||
@always(clk.posedge) | |||
def cycle(): | |||
if rst: | |||
data_out.next = 0 | |||
elif load: | |||
data_out.next = data | |||
else: | |||
if updown: | |||
data_out.next = data_out + 1 | |||
else: | |||
data_out.next = data_out - 1 | |||
return cycle | |||
def convert(): | |||
clk = Signal(bool(0)) | |||
rst = Signal(bool(0)) # nur sync reset hier | |||
# reset = ResetSignal(0, active=0, isasync=True) | |||
updown = Signal(bool(0)) | |||
load = Signal(bool(0)) | |||
data = Signal(modbv(val=0, min=0, max=15)[4:]) | |||
data_out = Signal(modbv(val=0, min=0, max=15)[4:]) | |||
inst = counter_4bit(clk, rst, data, updown, load, data_out) | |||
inst.convert(hdl='Verilog') | |||
# inst.convert(hdl='VHDL') |
@@ -0,0 +1,133 @@ | |||
import os | |||
import myhdl | |||
from myhdl import * | |||
module = 'counter_4bit' | |||
testbench = 'tb_%s' % module | |||
build_cmd = "iverilog -o %s.vvp %s.v %s.v" % (testbench, module, testbench) | |||
def tb_counter_4bit(): | |||
clk = Signal(bool(0)) | |||
rst = Signal(bool(0)) | |||
updown = Signal(bool(0)) | |||
load = Signal(bool(0)) | |||
data = Signal(modbv(val=0, min=0, max=15)[4:]) | |||
data_out = Signal(modbv(val=0, min=0, max=15)[4:]) | |||
# DUT | |||
print(build_cmd) | |||
if os.system(build_cmd): | |||
raise Exception("Error running build command") | |||
dut = Cosimulation( | |||
"vvp -m myhdl %s.vvp -lxt2" % testbench, | |||
clk=clk, | |||
rst=rst, | |||
updown=updown, | |||
load=load, | |||
data=data, | |||
data_out=data_out | |||
) | |||
@always(delay(4)) | |||
def clkgen(): | |||
clk.next = not clk | |||
@instance | |||
def check(): | |||
print("initialize") | |||
clk.next = 0 | |||
rst.next = 0 | |||
load.next = 0 | |||
updown.next = 1 | |||
data.next = 0 | |||
yield clk.posedge | |||
yield clk.posedge | |||
print("... OK") | |||
print("test 1: reset") | |||
yield clk.negedge | |||
rst.next = 1 | |||
yield clk.posedge | |||
yield clk.negedge | |||
rst.next = 0 | |||
yield clk.posedge | |||
assert data_out == 0, f"assert failed with data_out {data_out} != 0" | |||
yield clk.posedge | |||
yield clk.posedge | |||
print("... OK") | |||
print("test 2: load") | |||
yield clk.posedge | |||
load.next = 1 | |||
data.next = Signal(modbv(13)[4:]) | |||
yield clk.negedge | |||
yield clk.posedge | |||
yield clk.negedge | |||
assert data_out == 13, f"assert failed with data_out {data_out} != {13}" | |||
load.next = 0 | |||
yield clk.posedge | |||
yield clk.negedge | |||
print("... OK") | |||
print("test 3: inc") | |||
yield clk.negedge | |||
rst.next = 1 | |||
yield clk.posedge | |||
yield clk.negedge | |||
rst.next = 0 | |||
soll = 0 | |||
for i in range(4): | |||
assert data_out == soll, f"assert failed with data_out {int(data_out)} != {i}" | |||
yield clk.posedge | |||
soll += 1 | |||
yield clk.negedge | |||
print("... OK") | |||
print("test 4: dec") | |||
soll = 13 | |||
yield clk.posedge | |||
updown.next = 0 | |||
load.next = 1 | |||
data.next = Signal(modbv(soll)[4:]) | |||
yield clk.negedge | |||
yield clk.posedge | |||
yield clk.negedge | |||
load.next = 0 | |||
for i in range(4): | |||
assert data_out == soll, f"assert failed with data_out {int(data_out)} != {soll}" | |||
yield clk.posedge | |||
soll -= 1 | |||
yield clk.negedge | |||
print("... OK") | |||
for _ in range(10): | |||
yield clk.posedge | |||
raise StopSimulation | |||
return instances() | |||
def simulate(): | |||
sim = Simulation(tb_counter_4bit()) | |||
sim.run() |
@@ -0,0 +1,23 @@ | |||
////////////////////////////////////////////////////////////// | |||
// 4-bit loadable up-down counter ////// | |||
////////////////////////////////////////////////////////////// | |||
module counter(clk, rst, data, updown, load, data_out); | |||
input clk, rst, load; | |||
input updown; | |||
input [3:0] data; | |||
output reg [3:0] data_out; | |||
always @(posedge clk) | |||
begin | |||
if(rst) | |||
data_out <= 4'b0; | |||
else if(load) | |||
data_out <= data; | |||
else | |||
data_out <= ((updown)?(data_out + 1'b1):(data_out -1'b1)); | |||
end | |||
endmodule |
@@ -0,0 +1,10 @@ | |||
import counter_4bit_conv, counter_4bit_tb | |||
import os | |||
# print("Konvertiere MyHDL Design in Verilog") | |||
# counter_4bit_conv.convert() | |||
print("Simuliere Verilog Design mit MyHDL") | |||
counter_4bit_tb.simulate() | |||
os.system("gtkwave.exe -S run.tcl *.lxt") |
@@ -0,0 +1,22 @@ | |||
### -------------------------------------------------------------------- | |||
### gtkwave.tcl | |||
### Author: Simon Schmidt | |||
### -------------------------------------------------------------------- | |||
# Resources: | |||
# Manual: http://gtkwave.sourceforge.net/gtkwave.pdf#Appendix-E-Tcl-Command-Syntax | |||
# Add all signals | |||
set nfacs [ gtkwave::getNumFacs ] | |||
set all_facs [list] | |||
for {set i 0} {$i < $nfacs } {incr i} { | |||
set facname [ gtkwave::getFacName $i ] | |||
lappend all_facs "$facname" | |||
} | |||
set num_added [ gtkwave::addSignalsFromList $all_facs ] | |||
puts "num signals added: $num_added" | |||
# zoom full | |||
gtkwave::/Time/Zoom/Zoom_Full |
@@ -0,0 +1,38 @@ | |||
module tb_counter_4bit; | |||
reg clk; | |||
reg rst; | |||
reg [3:0] data; | |||
reg updown; | |||
reg load; | |||
wire [3:0] data_out; | |||
initial begin | |||
$from_myhdl( | |||
clk, | |||
rst, | |||
data, | |||
updown, | |||
load | |||
); | |||
$to_myhdl( | |||
data_out | |||
); | |||
// dump file | |||
$dumpfile("tb_counter_4bit.lxt"); | |||
$dumpvars(0, tb_counter_4bit); | |||
end | |||
counter_4bit dut( | |||
clk, | |||
rst, | |||
data, | |||
updown, | |||
load, | |||
data_out | |||
); | |||
endmodule |
@@ -0,0 +1,88 @@ | |||
#! /usr/local/bin/vvp | |||
:ivl_version "12.0 (devel)" "(s20150603-1130-g1f8876be)"; | |||
:ivl_delay_selection "TYPICAL"; | |||
:vpi_time_precision - 11; | |||
:vpi_module "/usr/local/lib/ivl/system.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/vhdl_sys.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/vhdl_textio.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/v2005_math.vpi"; | |||
:vpi_module "/usr/local/lib/ivl/va_math.vpi"; | |||
S_0x556346c658c0 .scope module, "tb_counter_4bit" "tb_counter_4bit" 2 1; | |||
.timescale -9 -11; | |||
v0x556346c77d30_0 .var "clk", 0 0; | |||
v0x556346c77df0_0 .var "data", 3 0; | |||
v0x556346c77ec0_0 .net "data_out", 3 0, v0x556346c77920_0; 1 drivers | |||
v0x556346c77fc0_0 .var "load", 0 0; | |||
v0x556346c78090_0 .var "rst", 0 0; | |||
v0x556346c78180_0 .var "updown", 0 0; | |||
S_0x556346c65a50 .scope module, "dut" "counter_4bit" 2 29, 3 8 0, S_0x556346c658c0; | |||
.timescale -9 -11; | |||
.port_info 0 /INPUT 1 "clk"; | |||
.port_info 1 /INPUT 1 "rst"; | |||
.port_info 2 /INPUT 4 "data"; | |||
.port_info 3 /INPUT 1 "updown"; | |||
.port_info 4 /INPUT 1 "load"; | |||
.port_info 5 /OUTPUT 4 "data_out"; | |||
v0x556346c51a80_0 .net "clk", 0 0, v0x556346c77d30_0; 1 drivers | |||
v0x556346c77840_0 .net "data", 3 0, v0x556346c77df0_0; 1 drivers | |||
v0x556346c77920_0 .var "data_out", 3 0; | |||
v0x556346c779e0_0 .net "load", 0 0, v0x556346c77fc0_0; 1 drivers | |||
v0x556346c77aa0_0 .net "rst", 0 0, v0x556346c78090_0; 1 drivers | |||
v0x556346c77bb0_0 .net "updown", 0 0, v0x556346c78180_0; 1 drivers | |||
E_0x556346c631d0 .event posedge, v0x556346c51a80_0; | |||
S_0x556346c518a0 .scope begin, "COUNTER_4BIT_CYCLE" "COUNTER_4BIT_CYCLE" 3 29, 3 29 0, S_0x556346c65a50; | |||
.timescale -9 -11; | |||
.scope S_0x556346c65a50; | |||
T_0 ; | |||
%wait E_0x556346c631d0; | |||
%fork t_1, S_0x556346c518a0; | |||
%jmp t_0; | |||
.scope S_0x556346c518a0; | |||
t_1 ; | |||
%load/vec4 v0x556346c77aa0_0; | |||
%flag_set/vec4 8; | |||
%jmp/0xz T_0.0, 8; | |||
%pushi/vec4 0, 0, 4; | |||
%assign/vec4 v0x556346c77920_0, 0; | |||
%jmp T_0.1; | |||
T_0.0 ; | |||
%load/vec4 v0x556346c779e0_0; | |||
%flag_set/vec4 8; | |||
%jmp/0xz T_0.2, 8; | |||
%load/vec4 v0x556346c77840_0; | |||
%assign/vec4 v0x556346c77920_0, 0; | |||
%jmp T_0.3; | |||
T_0.2 ; | |||
%load/vec4 v0x556346c77bb0_0; | |||
%flag_set/vec4 8; | |||
%jmp/0xz T_0.4, 8; | |||
%load/vec4 v0x556346c77920_0; | |||
%addi 1, 0, 4; | |||
%assign/vec4 v0x556346c77920_0, 0; | |||
%jmp T_0.5; | |||
T_0.4 ; | |||
%load/vec4 v0x556346c77920_0; | |||
%subi 1, 0, 4; | |||
%assign/vec4 v0x556346c77920_0, 0; | |||
T_0.5 ; | |||
T_0.3 ; | |||
T_0.1 ; | |||
%end; | |||
.scope S_0x556346c65a50; | |||
t_0 %join; | |||
%jmp T_0; | |||
.thread T_0; | |||
.scope S_0x556346c658c0; | |||
T_1 ; | |||
%vpi_call 2 13 "$from_myhdl", v0x556346c77d30_0, v0x556346c78090_0, v0x556346c77df0_0, v0x556346c78180_0, v0x556346c77fc0_0 {0 0 0}; | |||
%vpi_call 2 20 "$to_myhdl", v0x556346c77ec0_0 {0 0 0}; | |||
%vpi_call 2 25 "$dumpfile", "tb_counter_4bit.lxt" {0 0 0}; | |||
%vpi_call 2 26 "$dumpvars", 32'sb00000000000000000000000000000000, S_0x556346c658c0 {0 0 0}; | |||
%end; | |||
.thread T_1; | |||
# The file index is used to find the file name in the following table. | |||
:file_names 4; | |||
"N/A"; | |||
"<interactive>"; | |||
"tb_counter_4bit.v"; | |||
"counter_4bit.v"; |
@@ -0,0 +1 @@ | |||
Subproject commit d567bd258c4e6cee6d2dc2866892824e890c5656 |
@@ -1,3 +1,3 @@ | |||
# ESY1B_SV_Python_Verifikation | |||
# ESY1B Verifikation mit SystemVerilog und Python | |||
Verwendeter Programmcode in Studienarbeit für ESY1B zum Thema "Verifikation mit SystemVerilog und Python" | |||
Verwendeter Programmcode in Studienarbeit für ESY1B zum Thema "Verifikation mit SystemVerilog und Python" |
@@ -0,0 +1,4 @@ | |||
*swp | |||
*vcd | |||
results.xml | |||
sim_build |
@@ -0,0 +1,12 @@ | |||
# cocotb setup | |||
MODULE = test | |||
TOPLEVEL = top | |||
VERILOG_SOURCES = top.v filter.v | |||
include $(shell cocotb-config --makefiles)/Makefile.sim | |||
# filters exported by pyfda always have module name set to top | |||
filter.v: | |||
sed -i 's/top/filter/' $@ | |||
.PHONY: filter.v |
@@ -0,0 +1,99 @@ | |||
/* Machine-generated using Migen */ | |||
module filter( | |||
input signed [15:0] i, | |||
output signed [15:0] o, | |||
input sys_clk, | |||
input sys_rst | |||
); | |||
reg signed [15:0] sreg0 = 16'sd0; | |||
reg signed [15:0] sreg1 = 16'sd0; | |||
reg signed [15:0] sreg2 = 16'sd0; | |||
reg signed [15:0] sreg3 = 16'sd0; | |||
reg signed [15:0] sreg4 = 16'sd0; | |||
reg signed [15:0] sreg5 = 16'sd0; | |||
reg signed [15:0] sreg6 = 16'sd0; | |||
reg signed [15:0] sreg7 = 16'sd0; | |||
reg signed [15:0] sreg8 = 16'sd0; | |||
reg signed [15:0] sreg9 = 16'sd0; | |||
reg signed [15:0] sreg10 = 16'sd0; | |||
reg signed [15:0] sreg11 = 16'sd0; | |||
reg signed [15:0] sreg12 = 16'sd0; | |||
reg signed [15:0] sreg13 = 16'sd0; | |||
reg signed [15:0] sreg14 = 16'sd0; | |||
reg signed [15:0] sreg15 = 16'sd0; | |||
reg signed [15:0] sreg16 = 16'sd0; | |||
reg signed [15:0] sreg17 = 16'sd0; | |||
reg signed [15:0] sreg18 = 16'sd0; | |||
reg signed [15:0] sreg19 = 16'sd0; | |||
reg signed [15:0] sreg20 = 16'sd0; | |||
reg signed [35:0] sum_full = 36'sd0; | |||
wire signed [31:0] sum_accu; | |||
wire signed [35:0] sig_i_q0; | |||
wire signed [31:0] sig_o0; | |||
wire signed [31:0] sig_i_q1; | |||
wire signed [15:0] sig_o1; | |||
// synthesis translate_off | |||
reg dummy_s; | |||
initial dummy_s <= 1'd0; | |||
// synthesis translate_on | |||
assign sig_i_q0 = (sum_full <<< 1'd0); | |||
assign sig_o0 = sig_i_q0; | |||
assign sum_accu = sig_o0; | |||
assign sig_i_q1 = (sum_accu >>> 4'd15); | |||
assign sig_o1 = sig_i_q1; | |||
assign o = sig_o1; | |||
always @(posedge sys_clk) begin | |||
sreg0 <= i; | |||
sreg1 <= sreg0; | |||
sreg2 <= sreg1; | |||
sreg3 <= sreg2; | |||
sreg4 <= sreg3; | |||
sreg5 <= sreg4; | |||
sreg6 <= sreg5; | |||
sreg7 <= sreg6; | |||
sreg8 <= sreg7; | |||
sreg9 <= sreg8; | |||
sreg10 <= sreg9; | |||
sreg11 <= sreg10; | |||
sreg12 <= sreg11; | |||
sreg13 <= sreg12; | |||
sreg14 <= sreg13; | |||
sreg15 <= sreg14; | |||
sreg16 <= sreg15; | |||
sreg17 <= sreg16; | |||
sreg18 <= sreg17; | |||
sreg19 <= sreg18; | |||
sreg20 <= sreg19; | |||
sum_full <= ((((((((((((((((((((($signed({1'd0, 11'd1135}) * sreg0) + ($signed({1'd0, 10'd512}) * sreg1)) + ($signed({1'd0, 9'd364}) * sreg2)) + (6'sd46 * sreg3)) + (11'sd1406 * sreg4)) + (12'sd2625 * sreg5)) + (13'sd5777 * sreg6)) + (13'sd4839 * sreg7)) + (14'sd12231 * sreg8)) + (14'sd11695 * sreg9)) + ($signed({1'd0, 15'd27889}) * sreg10)) + (14'sd11695 * sreg11)) + (14'sd12231 * sreg12)) + (13'sd4839 * sreg13)) + (13'sd5777 * sreg14)) + (12'sd2625 * sreg15)) + (11'sd1406 * sreg16)) + (6'sd46 * sreg17)) + ($signed({1'd0, 9'd364}) * sreg18)) + ($signed({1'd0, 10'd512}) * sreg19)) + ($signed({1'd0, 11'd1135}) * sreg20)); | |||
if (sys_rst) begin | |||
sreg0 <= 16'sd0; | |||
sreg1 <= 16'sd0; | |||
sreg2 <= 16'sd0; | |||
sreg3 <= 16'sd0; | |||
sreg4 <= 16'sd0; | |||
sreg5 <= 16'sd0; | |||
sreg6 <= 16'sd0; | |||
sreg7 <= 16'sd0; | |||
sreg8 <= 16'sd0; | |||
sreg9 <= 16'sd0; | |||
sreg10 <= 16'sd0; | |||
sreg11 <= 16'sd0; | |||
sreg12 <= 16'sd0; | |||
sreg13 <= 16'sd0; | |||
sreg14 <= 16'sd0; | |||
sreg15 <= 16'sd0; | |||
sreg16 <= 16'sd0; | |||
sreg17 <= 16'sd0; | |||
sreg18 <= 16'sd0; | |||
sreg19 <= 16'sd0; | |||
sreg20 <= 16'sd0; | |||
sum_full <= 36'sd0; | |||
end | |||
end | |||
endmodule | |||
@@ -0,0 +1,32 @@ | |||
import cocotb | |||
from cocotb.clock import Clock | |||
from cocotb.triggers import RisingEdge | |||
import wave | |||
import struct | |||
import numpy as np | |||
@cocotb.test() | |||
async def test(dut): | |||
clock = Clock(dut.clk, 10, units="us") | |||
cocotb.fork(clock.start()) | |||
# open audio files for read and write | |||
audio_in = wave.open('hello.wav') | |||
audio_out = wave.open('out.wav', 'wb') | |||
audio_out.setnchannels(audio_in.getnchannels()) | |||
audio_out.setsampwidth(audio_in.getsampwidth()) | |||
audio_out.setframerate(audio_in.getframerate()) | |||
nframes = audio_in.getnframes() | |||
print("sending %d frames" % nframes) | |||
# process the audio through the dut | |||
for i in range(nframes): | |||
frame = audio_in.readframes(1) | |||
val, = struct.unpack('h', frame) | |||
dut.data_in <= val | |||
await RisingEdge(dut.clk) | |||
raw_out = struct.pack('h', dut.data_out.value.signed_integer) | |||
audio_out.writeframes(raw_out) |
@@ -0,0 +1,4 @@ | |||
#!/bin/bash | |||
make | |||
cp hello.wav out.wav /mnt/c/Users/simon/Google_Drive/OHM_BEI6_Simon/ESY1_KUNTZSCH/000_Studienarbeit/verilog/fftplot | |||
py.exe "C:\Users\simon\Google_Drive\OHM_BEI6_Simon\ESY1_KUNTZSCH\000_Studienarbeit\verilog\fftplot\fftplot.py" |
@@ -0,0 +1,18 @@ | |||
`default_nettype none | |||
module top ( | |||
input wire clk, | |||
input wire signed [15:0] data_in, | |||
input wire signed [15:0] data_out | |||
); | |||
`ifdef COCOTB_SIM | |||
initial begin | |||
$dumpfile ("top.vcd"); | |||
$dumpvars (0, top); | |||
#1; | |||
end | |||
`endif | |||
filter filter (.i(data_in), .o(data_out), .sys_clk(clk), .sys_rst(1'b0)); | |||
endmodule |
@@ -0,0 +1,28 @@ | |||
[*] | |||
[*] GTKWave Analyzer v3.3.105 (w)1999-2020 BSI | |||
[*] Wed Sep 23 09:52:12 2020 | |||
[*] | |||
[dumpfile] "/home/matt/work/fpga/pyfda-cocotb-demo/top.vcd" | |||
[dumpfile_mtime] "Wed Sep 23 09:51:27 2020" | |||
[dumpfile_size] 24963113 | |||
[savefile] "/home/matt/work/fpga/pyfda-cocotb-demo/top_coco.gtkw" | |||
[timestart] 0 | |||
[size] 2353 1179 | |||
[pos] -1 -1 | |||
*-36.000000 2010000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 | |||
[sst_width] 272 | |||
[signals_width] 438 | |||
[sst_expanded] 1 | |||
[sst_vpaned_height] 349 | |||
@28 | |||
top.clk | |||
@8420 | |||
top.data_in[15:0] | |||
@20000 | |||
- | |||
@8420 | |||
top.data_out[15:0] | |||
@20000 | |||
- | |||
[pattern_trace] 1 | |||
[pattern_trace] 0 |