initial commit
This commit is contained in:
+3
@@ -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
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
Executable
+79
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user