Initial commit
This commit is contained in:
42
test/Makefile
Normal file
42
test/Makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
# Makefile
|
||||
# See https://docs.cocotb.org/en/stable/quickstart.html for more info
|
||||
|
||||
# defaults
|
||||
SIM ?= icarus
|
||||
TOPLEVEL_LANG ?= verilog
|
||||
SRC_DIR = $(PWD)/../src
|
||||
PROJECT_SOURCES = project.v
|
||||
|
||||
ifneq ($(GATES),yes)
|
||||
|
||||
# RTL simulation:
|
||||
SIM_BUILD = sim_build/rtl
|
||||
VERILOG_SOURCES += $(addprefix $(SRC_DIR)/,$(PROJECT_SOURCES))
|
||||
COMPILE_ARGS += -I$(SRC_DIR)
|
||||
|
||||
else
|
||||
|
||||
# Gate level simulation:
|
||||
SIM_BUILD = sim_build/gl
|
||||
COMPILE_ARGS += -DGL_TEST
|
||||
COMPILE_ARGS += -DFUNCTIONAL
|
||||
COMPILE_ARGS += -DUSE_POWER_PINS
|
||||
COMPILE_ARGS += -DSIM
|
||||
COMPILE_ARGS += -DUNIT_DELAY=\#1
|
||||
VERILOG_SOURCES += $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/verilog/primitives.v
|
||||
VERILOG_SOURCES += $(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v
|
||||
|
||||
# this gets copied in by the GDS action workflow
|
||||
VERILOG_SOURCES += $(PWD)/gate_level_netlist.v
|
||||
|
||||
endif
|
||||
|
||||
# Include the testbench sources:
|
||||
VERILOG_SOURCES += $(PWD)/tb.v
|
||||
TOPLEVEL = tb
|
||||
|
||||
# MODULE is the basename of the Python test file
|
||||
MODULE = test
|
||||
|
||||
# include cocotb's make rules to take care of the simulator setup
|
||||
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||
30
test/README.md
Normal file
30
test/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Sample testbench for a Tiny Tapeout project
|
||||
|
||||
This is a sample testbench for a Tiny Tapeout project. It uses [cocotb](https://docs.cocotb.org/en/stable/) to drive the DUT and check the outputs.
|
||||
|
||||
## Setting up
|
||||
|
||||
1. Edit [Makefile](Makefile) and modify `PROJECT_SOURCES` to point to your Verilog files.
|
||||
2. Edit [tb.v](tb.v) and replace `tt_um_example` with your module name.
|
||||
|
||||
## How to run
|
||||
|
||||
To run the RTL simulation:
|
||||
|
||||
```sh
|
||||
make
|
||||
```
|
||||
|
||||
To run gatelevel simulation, first harden your project and copy `../runs/wokwi/results/final/verilog/gl/{your_module_name}.v` to `gate_level_netlist.v`.
|
||||
|
||||
Then run:
|
||||
|
||||
```sh
|
||||
make GATES=yes
|
||||
```
|
||||
|
||||
## How to view the VCD file
|
||||
|
||||
```sh
|
||||
gtkwave tb.vcd tb.gtkw
|
||||
```
|
||||
39
test/tb.gtkw
Normal file
39
test/tb.gtkw
Normal file
@@ -0,0 +1,39 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
|
||||
[*] Mon Nov 20 16:00:28 2023
|
||||
[*]
|
||||
[dumpfile] "/home/uri/p/tt-new-template-proto/test/tb.vcd"
|
||||
[dumpfile_mtime] "Mon Nov 20 15:58:34 2023"
|
||||
[dumpfile_size] 1110
|
||||
[savefile] "/home/uri/p/tt-new-template-proto/test/tb.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1376 600
|
||||
[pos] -1 -1
|
||||
*-24.534533 -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 -1
|
||||
[treeopen] tb.
|
||||
[sst_width] 297
|
||||
[signals_width] 230
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 158
|
||||
@28
|
||||
tb.user_project.ena
|
||||
@29
|
||||
tb.user_project.clk
|
||||
@28
|
||||
tb.user_project.rst_n
|
||||
@200
|
||||
-Inputs
|
||||
@22
|
||||
tb.user_project.ui_in[7:0]
|
||||
@200
|
||||
-Bidirectional Pins
|
||||
@22
|
||||
tb.user_project.uio_in[7:0]
|
||||
tb.user_project.uio_oe[7:0]
|
||||
tb.user_project.uio_out[7:0]
|
||||
@200
|
||||
-Output Pins
|
||||
@22
|
||||
tb.user_project.uo_out[7:0]
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
||||
44
test/tb.v
Normal file
44
test/tb.v
Normal file
@@ -0,0 +1,44 @@
|
||||
`default_nettype none `timescale 1ns / 1ps
|
||||
|
||||
/* This testbench just instantiates the module and makes some convenient wires
|
||||
that can be driven / tested by the cocotb test.py.
|
||||
*/
|
||||
module tb ();
|
||||
|
||||
// Dump the signals to a VCD file. You can view it with gtkwave.
|
||||
initial begin
|
||||
$dumpfile("tb.vcd");
|
||||
$dumpvars(0, tb);
|
||||
#1;
|
||||
end
|
||||
|
||||
// Wire up the inputs and outputs:
|
||||
reg clk;
|
||||
reg rst_n;
|
||||
reg ena;
|
||||
reg [7:0] ui_in;
|
||||
reg [7:0] uio_in;
|
||||
wire [7:0] uo_out;
|
||||
wire [7:0] uio_out;
|
||||
wire [7:0] uio_oe;
|
||||
|
||||
// Replace tt_um_example with your module name:
|
||||
tt_um_example user_project (
|
||||
|
||||
// Include power ports for the Gate Level test:
|
||||
`ifdef GL_TEST
|
||||
.VPWR(1'b1),
|
||||
.VGND(1'b0),
|
||||
`endif
|
||||
|
||||
.ui_in (ui_in), // Dedicated inputs
|
||||
.uo_out (uo_out), // Dedicated outputs
|
||||
.uio_in (uio_in), // IOs: Input path
|
||||
.uio_out(uio_out), // IOs: Output path
|
||||
.uio_oe (uio_oe), // IOs: Enable path (active high: 0=input, 1=output)
|
||||
.ena (ena), // enable - goes high when design is selected
|
||||
.clk (clk), // clock
|
||||
.rst_n (rst_n) // not reset
|
||||
);
|
||||
|
||||
endmodule
|
||||
32
test/test.py
Normal file
32
test/test.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# SPDX-FileCopyrightText: © 2023 Uri Shaked <uri@tinytapeout.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import ClockCycles
|
||||
|
||||
@cocotb.test()
|
||||
async def test_adder(dut):
|
||||
dut._log.info("Start")
|
||||
|
||||
# Our example module doesn't use clock and reset, but we show how to use them here anyway.
|
||||
clock = Clock(dut.clk, 10, units="us")
|
||||
cocotb.start_soon(clock.start())
|
||||
|
||||
# Reset
|
||||
dut._log.info("Reset")
|
||||
dut.ena.value = 1
|
||||
dut.ui_in.value = 0
|
||||
dut.uio_in.value = 0
|
||||
dut.rst_n.value = 0
|
||||
await ClockCycles(dut.clk, 10)
|
||||
dut.rst_n.value = 1
|
||||
|
||||
# Set the input values, wait one clock cycle, and check the output
|
||||
dut._log.info("Test")
|
||||
dut.ui_in.value = 20
|
||||
dut.uio_in.value = 30
|
||||
|
||||
await ClockCycles(dut.clk, 1)
|
||||
|
||||
assert dut.uo_out.value == 50
|
||||
Reference in New Issue
Block a user