diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5d1e0dc --- /dev/null +++ b/.gitmodules @@ -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 diff --git a/4-bit-counter-cocotb/.vscode/settings.json b/4-bit-counter-cocotb/.vscode/settings.json new file mode 100644 index 0000000..615aafb --- /dev/null +++ b/4-bit-counter-cocotb/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/4-bit-counter-cocotb/hdl/counter.sv b/4-bit-counter-cocotb/hdl/counter.sv new file mode 100644 index 0000000..8c6ea9b --- /dev/null +++ b/4-bit-counter-cocotb/hdl/counter.sv @@ -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 diff --git a/4-bit-counter-cocotb/tests/Makefile b/4-bit-counter-cocotb/tests/Makefile new file mode 100644 index 0000000..8359ad6 --- /dev/null +++ b/4-bit-counter-cocotb/tests/Makefile @@ -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 + diff --git a/4-bit-counter-cocotb/tests/__pycache__/test_counter.cpython-38-pytest-6.2.4.pyc b/4-bit-counter-cocotb/tests/__pycache__/test_counter.cpython-38-pytest-6.2.4.pyc new file mode 100644 index 0000000..c2e81f5 Binary files /dev/null and b/4-bit-counter-cocotb/tests/__pycache__/test_counter.cpython-38-pytest-6.2.4.pyc differ diff --git a/4-bit-counter-cocotb/tests/dump.vcd b/4-bit-counter-cocotb/tests/dump.vcd new file mode 100644 index 0000000..2db6176 --- /dev/null +++ b/4-bit-counter-cocotb/tests/dump.vcd @@ -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 diff --git a/4-bit-counter-cocotb/tests/results.xml b/4-bit-counter-cocotb/tests/results.xml new file mode 100644 index 0000000..aa66b42 --- /dev/null +++ b/4-bit-counter-cocotb/tests/results.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/4-bit-counter-cocotb/tests/sim_build/cmds.f b/4-bit-counter-cocotb/tests/sim_build/cmds.f new file mode 100644 index 0000000..3e26e00 --- /dev/null +++ b/4-bit-counter-cocotb/tests/sim_build/cmds.f @@ -0,0 +1 @@ ++timescale+1ns/1ps diff --git a/4-bit-counter-cocotb/tests/sim_build/sim.vvp b/4-bit-counter-cocotb/tests/sim_build/sim.vvp new file mode 100755 index 0000000..a751c79 --- /dev/null +++ b/4-bit-counter-cocotb/tests/sim_build/sim.vvp @@ -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; HiZ drive +v0x55fb04b7dc80_0 .net "clk", 0 0, o0x7f9f460c2018; 0 drivers +o0x7f9f460c2048 .functor BUFZ 4, C4; HiZ drive +v0x55fb04ba0930_0 .net "data", 3 0, o0x7f9f460c2048; 0 drivers +v0x55fb04ba0a10_0 .var "data_out", 3 0; +o0x7f9f460c20a8 .functor BUFZ 1, C4; HiZ drive +v0x55fb04ba0ad0_0 .net "load", 0 0, o0x7f9f460c20a8; 0 drivers +o0x7f9f460c20d8 .functor BUFZ 1, C4; HiZ drive +v0x55fb04ba0b90_0 .net "rst", 0 0, o0x7f9f460c20d8; 0 drivers +o0x7f9f460c2108 .functor BUFZ 1, C4; 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"; + ""; + "-"; + "/home/sim/ice40/cocotb/examples/4-bit-counter/tests/../hdl/counter.sv"; diff --git a/4-bit-counter-cocotb/tests/test_counter.py b/4-bit-counter-cocotb/tests/test_counter.py new file mode 100644 index 0000000..0c5c475 --- /dev/null +++ b/4-bit-counter-cocotb/tests/test_counter.py @@ -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) + + + diff --git a/4-bit-counter-myhdl/.vscode/settings.json b/4-bit-counter-myhdl/.vscode/settings.json new file mode 100644 index 0000000..615aafb --- /dev/null +++ b/4-bit-counter-myhdl/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/4-bit-counter-myhdl/__pycache__/counter_4bit_conv.cpython-38.pyc b/4-bit-counter-myhdl/__pycache__/counter_4bit_conv.cpython-38.pyc new file mode 100644 index 0000000..755e98b Binary files /dev/null and b/4-bit-counter-myhdl/__pycache__/counter_4bit_conv.cpython-38.pyc differ diff --git a/4-bit-counter-myhdl/__pycache__/counter_4bit_tb.cpython-38.pyc b/4-bit-counter-myhdl/__pycache__/counter_4bit_tb.cpython-38.pyc new file mode 100644 index 0000000..c0d85a0 Binary files /dev/null and b/4-bit-counter-myhdl/__pycache__/counter_4bit_tb.cpython-38.pyc differ diff --git a/4-bit-counter-myhdl/counter_4bit.v b/4-bit-counter-myhdl/counter_4bit.v new file mode 100644 index 0000000..1318498 --- /dev/null +++ b/4-bit-counter-myhdl/counter_4bit.v @@ -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 diff --git a/4-bit-counter-myhdl/counter_4bit_conv.py b/4-bit-counter-myhdl/counter_4bit_conv.py new file mode 100644 index 0000000..79f1aa2 --- /dev/null +++ b/4-bit-counter-myhdl/counter_4bit_conv.py @@ -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') diff --git a/4-bit-counter-myhdl/counter_4bit_tb.py b/4-bit-counter-myhdl/counter_4bit_tb.py new file mode 100644 index 0000000..d8b5827 --- /dev/null +++ b/4-bit-counter-myhdl/counter_4bit_tb.py @@ -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() diff --git a/4-bit-counter-myhdl/counter_reference.v b/4-bit-counter-myhdl/counter_reference.v new file mode 100644 index 0000000..f380ba4 --- /dev/null +++ b/4-bit-counter-myhdl/counter_reference.v @@ -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 \ No newline at end of file diff --git a/4-bit-counter-myhdl/main.py b/4-bit-counter-myhdl/main.py new file mode 100644 index 0000000..fcb1ef1 --- /dev/null +++ b/4-bit-counter-myhdl/main.py @@ -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") \ No newline at end of file diff --git a/4-bit-counter-myhdl/run.tcl b/4-bit-counter-myhdl/run.tcl new file mode 100644 index 0000000..c57509f --- /dev/null +++ b/4-bit-counter-myhdl/run.tcl @@ -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 \ No newline at end of file diff --git a/4-bit-counter-myhdl/tb_counter_4bit.lxt b/4-bit-counter-myhdl/tb_counter_4bit.lxt new file mode 100644 index 0000000..24fbffc Binary files /dev/null and b/4-bit-counter-myhdl/tb_counter_4bit.lxt differ diff --git a/4-bit-counter-myhdl/tb_counter_4bit.v b/4-bit-counter-myhdl/tb_counter_4bit.v new file mode 100644 index 0000000..bb1b977 --- /dev/null +++ b/4-bit-counter-myhdl/tb_counter_4bit.v @@ -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 diff --git a/4-bit-counter-myhdl/tb_counter_4bit.vvp b/4-bit-counter-myhdl/tb_counter_4bit.vvp new file mode 100755 index 0000000..261ef9c --- /dev/null +++ b/4-bit-counter-myhdl/tb_counter_4bit.vvp @@ -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"; + ""; + "tb_counter_4bit.v"; + "counter_4bit.v"; diff --git a/7Segment_Lattice_ice40_UltraPlus b/7Segment_Lattice_ice40_UltraPlus new file mode 160000 index 0000000..d567bd2 --- /dev/null +++ b/7Segment_Lattice_ice40_UltraPlus @@ -0,0 +1 @@ +Subproject commit d567bd258c4e6cee6d2dc2866892824e890c5656 diff --git a/README.md b/README.md index b221e37..0892b29 100644 --- a/README.md +++ b/README.md @@ -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" \ No newline at end of file +Verwendeter Programmcode in Studienarbeit für ESY1B zum Thema "Verifikation mit SystemVerilog und Python" diff --git a/digitaler-filter-cocotb/.gitignore b/digitaler-filter-cocotb/.gitignore new file mode 100644 index 0000000..180c0d1 --- /dev/null +++ b/digitaler-filter-cocotb/.gitignore @@ -0,0 +1,4 @@ +*swp +*vcd +results.xml +sim_build diff --git a/digitaler-filter-cocotb/Makefile b/digitaler-filter-cocotb/Makefile new file mode 100644 index 0000000..02b8131 --- /dev/null +++ b/digitaler-filter-cocotb/Makefile @@ -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 diff --git a/digitaler-filter-cocotb/__pycache__/test.cpython-38.pyc b/digitaler-filter-cocotb/__pycache__/test.cpython-38.pyc new file mode 100644 index 0000000..b4eab7c Binary files /dev/null and b/digitaler-filter-cocotb/__pycache__/test.cpython-38.pyc differ diff --git a/digitaler-filter-cocotb/filter.v b/digitaler-filter-cocotb/filter.v new file mode 100644 index 0000000..f05e6ec --- /dev/null +++ b/digitaler-filter-cocotb/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 + diff --git a/digitaler-filter-cocotb/hello.wav b/digitaler-filter-cocotb/hello.wav new file mode 100644 index 0000000..b30ad06 Binary files /dev/null and b/digitaler-filter-cocotb/hello.wav differ diff --git a/digitaler-filter-cocotb/out.wav b/digitaler-filter-cocotb/out.wav new file mode 100644 index 0000000..41cdb0a Binary files /dev/null and b/digitaler-filter-cocotb/out.wav differ diff --git a/digitaler-filter-cocotb/test.py b/digitaler-filter-cocotb/test.py new file mode 100644 index 0000000..bd90472 --- /dev/null +++ b/digitaler-filter-cocotb/test.py @@ -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) diff --git a/digitaler-filter-cocotb/test.sh b/digitaler-filter-cocotb/test.sh new file mode 100755 index 0000000..2fec8f8 --- /dev/null +++ b/digitaler-filter-cocotb/test.sh @@ -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" diff --git a/digitaler-filter-cocotb/top.v b/digitaler-filter-cocotb/top.v new file mode 100644 index 0000000..9748c43 --- /dev/null +++ b/digitaler-filter-cocotb/top.v @@ -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 diff --git a/digitaler-filter-cocotb/top_coco.gtkw b/digitaler-filter-cocotb/top_coco.gtkw new file mode 100644 index 0000000..e60a15f --- /dev/null +++ b/digitaler-filter-cocotb/top_coco.gtkw @@ -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