Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cocotb testbench runner #222

Draft
wants to merge 126 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
eade15f
First commit. Adding the cocotb test runner script to the project.
jacob720 Sep 20, 2024
1609d9b
Applied different approach to assignments and checks, creating dictio…
jacob720 Sep 20, 2024
9fea16f
Initialising carry_end to 0.
jacob720 Sep 20, 2024
93dcdd1
Script to run tests for all modules listed in a text file.
jacob720 Sep 24, 2024
7f64c07
Creates directories for each module containing waveforms.
jacob720 Sep 24, 2024
b28bc95
Ensuring signals of type 'read' are not initialised.
jacob720 Sep 27, 2024
fcad115
Can run multiple tests using 'all' in place of module name.
jacob720 Oct 7, 2024
a0b5d21
Removing 'loud' flag.
jacob720 Oct 7, 2024
3fb1648
Records time taken for tests.
jacob720 Oct 7, 2024
2ec4582
Run each module simulation in a different folder
jacob720 Oct 7, 2024
0cd2b34
Minor code style improvement
jacob720 Oct 7, 2024
03b7068
Ignore simulation build folder
jacob720 Oct 7, 2024
df7ae50
When running all tests, only run the ones that contains test_config
jacob720 Oct 7, 2024
9b8d626
Adding test_config files for modules to be tested.
jacob720 Oct 8, 2024
54f0f41
Get HDL modules needed for a module from its test_config file.
jacob720 Oct 8, 2024
057d3a8
Deal with signals of type 'time' by taking into account _H and _L sig…
jacob720 Oct 8, 2024
d74aa52
Codestyle improvements.
jacob720 Oct 8, 2024
d48e580
Removing script to run all tests. This is now done in cocotb_timing_t…
jacob720 Oct 8, 2024
345f213
Changing name of signals_dict to signals_info.
jacob720 Oct 8, 2024
c1e6d4a
'Dealing with case where test name is given but there are no tests wi…
jacob720 Oct 8, 2024
c01ef45
Deal with case where an incorrect module name is given.
jacob720 Oct 9, 2024
8a4a24a
Allows directories as well as files in test_config.
jacob720 Oct 9, 2024
80e14c0
Get additional build args from a module's test_config.
jacob720 Oct 10, 2024
37096ad
Test config files for seq and pcomp modules
jacob720 Oct 10, 2024
4fa2415
Deal with 'table short' data type
jacob720 Oct 10, 2024
f372e1f
Function to work out what IP is needed for each module. Use command '…
jacob720 Oct 10, 2024
2fdba52
Remove shared variable from synthesisable code
glennchid Oct 9, 2024
c406907
Removing unisim dependancy from posenc (it's unused)
jacob720 Oct 10, 2024
b71fb4b
Test config files for posenc, qdec & srgate
jacob720 Oct 10, 2024
b644330
Dealing with tests with a '/' in the name
jacob720 Oct 10, 2024
fd71cad
Using Michael's FIFO module to avoid pulse_queue IP.
jacob720 Oct 15, 2024
7354287
Debugging
jacob720 Oct 15, 2024
3a1f1aa
Test config files for pcap and pgen.
jacob720 Oct 16, 2024
93069ee
Allow for modules where the top level vhdl file doesn't match the dir…
jacob720 Oct 16, 2024
a53caac
Functions to check IP and timing INI for a module.
jacob720 Oct 16, 2024
e901677
See commit 0aa91f22
jacob720 Oct 16, 2024
bc79a1c
bugfix
jacob720 Oct 16, 2024
4e08029
DMA driver to simulate dma capability within pgen module.
jacob720 Oct 17, 2024
85c4d37
Supporting 'table' data type for signals.
jacob720 Oct 17, 2024
770d480
Changing pgen module to use Michael's fifo rather than IP.
jacob720 Oct 17, 2024
8ff4f46
Removing unisim dependancy from bitmux - it doesn't need it
jacob720 Oct 23, 2024
a0bd325
Changing from std_ulogic to std_logic
jacob720 Oct 23, 2024
22ece7d
Changing to std_logic from std_ulogic and removing function to avoid …
jacob720 Oct 23, 2024
035372a
Changing test config files to reflect changes in support.vhd. top_def…
jacob720 Oct 23, 2024
f677346
Adding output buffer for fifo to replicate behaviour of IP fifo
jacob720 Oct 23, 2024
1a2fb60
Changing timing INI to reflect behaviour with python DMA driver and n…
jacob720 Oct 23, 2024
130fc96
Improving pgen test files
jacob720 Oct 23, 2024
81a36c9
DMA monitor for pcap data output
jacob720 Oct 23, 2024
598a4e3
More information needed in test config for pcap, such as top level en…
jacob720 Oct 23, 2024
951b607
Some output signals contain '_out' but don't end in '_out'
jacob720 Oct 23, 2024
31d8534
Allowing the cocotb runner to work with the DMA monitor.
jacob720 Oct 23, 2024
0b84788
Allowing cocotb runner to deal with bus signals
jacob720 Oct 23, 2024
1a07a2b
Removing skip list
jacob720 Oct 23, 2024
5369ca9
Initialising signals in pcap module
jacob720 Oct 24, 2024
685f2cc
Don't check data condition for pcap_dat_o if pcap_dat_valid_o is low
jacob720 Oct 24, 2024
20faabf
Working dma_monitor
jacob720 Oct 25, 2024
99e4cdb
Only check signals of type 'data_valid' if ini file has an explicit c…
jacob720 Oct 25, 2024
c44c4a1
Allow negative numbers to be assigned to a part of a bus. Assumes 2s …
jacob720 Oct 25, 2024
8b7da67
Bugfix
jacob720 Oct 25, 2024
a0fc523
Adding signals to pcap's test config file so they are initialised. Pr…
jacob720 Oct 25, 2024
6a98e63
Adding bit bus info to pcap test config file
jacob720 Oct 28, 2024
d53322e
Reformatting
jacob720 Oct 28, 2024
cba75f5
Using 'clean' option. Getting xml_path directly from sim object.
jacob720 Oct 28, 2024
dd09952
Adding docstrings and reformatting.
jacob720 Oct 28, 2024
295f3ee
Formatting
jacob720 Oct 28, 2024
3587687
Reverting pgen table file name to 1000.txt
jacob720 Oct 28, 2024
600b7ef
Clean up
jacob720 Oct 29, 2024
6c7abcd
Including fmc lback autogen hdl files so pcap_std_dev is not disabled.
jacob720 Oct 29, 2024
9feaf6a
Allowing different simulator to be chosen
jacob720 Oct 31, 2024
63eaf5d
Adding options for NVC simulator, and ordering HDL files before build…
jacob720 Oct 31, 2024
88c7c86
Fixing ordering of HDL files
jacob720 Oct 31, 2024
7e2660e
Remove simulator-specific options from test config files
jacob720 Nov 1, 2024
39f5f37
Adjustments to get nvc simulator working. Need to investigate wavedro…
jacob720 Nov 1, 2024
d7d241a
Formatting changes
jacob720 Nov 1, 2024
9c65820
Trying to pass CI tests
jacob720 Nov 6, 2024
1ee925b
bugfix
jacob720 Nov 6, 2024
ae39b8e
Fix of issue caused by latest version of cocotb
jacob720 Nov 7, 2024
fb8f9c1
Removing wavedrom functionality
jacob720 Nov 7, 2024
1d7fb8c
Updates for latest cocotb version
jacob720 Nov 7, 2024
1782370
Adding option of 'elab_args' for elaboration stage. Needs latest coco…
jacob720 Nov 7, 2024
1770f5e
Report coverage data if nvc simulator is used.
jacob720 Nov 7, 2024
e100662
Vivado tests and CI
jacob720 Nov 11, 2024
bd01196
Updating pulse and pgen block INI as they no longer need IP
jacob720 Nov 13, 2024
193c623
Renaming PGEN_1000.txt to 1000.txt
jacob720 Nov 13, 2024
c215603
Changes needed from changing 1000.txt filename (from PGEN_1000.txt)
jacob720 Nov 13, 2024
966625e
Codestyle changes
jacob720 Nov 13, 2024
7ab4cdd
New argument 'skip' to skip some modules being tested
jacob720 Nov 14, 2024
1227885
Changing so that all modules use PandABox-fmc_lback-sfp_lback build
jacob720 Nov 15, 2024
5ebe80e
Adding cocotb tests to CI workflow
jacob720 Nov 18, 2024
728129d
Only build autogen for cocotb CI
jacob720 Nov 19, 2024
c84b19a
Using panda-coco container in CI
jacob720 Nov 19, 2024
eb05d9f
Using the latest panda-cocotb container
jacob720 Nov 19, 2024
86254fc
Spelling correction
jacob720 Nov 20, 2024
41f68a0
Simplifying cocotb CI run
jacob720 Nov 20, 2024
5780ce4
Removing deprecated module 'imp' in favour of 'importlib'
jacob720 Nov 20, 2024
73e62a4
Removing deprecated module 'imp' in favour of 'importlib'
jacob720 Nov 20, 2024
be6bc9a
Updating pcap simulation so it works with python 3.9+
jacob720 Nov 20, 2024
7ad31ad
cocotb CI improvement
jacob720 Nov 20, 2024
35b47e2
Using latest container
jacob720 Nov 21, 2024
42542df
No longer assumes autogen build directory. Adding cocotb tests to mak…
jacob720 Nov 22, 2024
27cd1b2
Setting default simulator to NVC, testing all modules by default in m…
jacob720 Nov 25, 2024
4367055
Using latest container in CI
jacob720 Nov 25, 2024
9c2a463
Check module timing ini rather than test config file, to check whethe…
jacob720 Nov 25, 2024
113dace
Continue test to end on failiure, and collect value data.
jacob720 Nov 26, 2024
3a076db
Give option to collect values
jacob720 Nov 26, 2024
86575ff
Adding collect arg
jacob720 Nov 26, 2024
9580b75
Changing some prints to logging
jacob720 Nov 26, 2024
d577726
Improving values collection
jacob720 Nov 26, 2024
2f5d658
Putting test called by cocotb in seperate file
jacob720 Nov 26, 2024
c8adc0f
Write errors to file if there are any
jacob720 Nov 27, 2024
efa2c88
Cleanup sim build directory by creating subfolders for each test.
jacob720 Nov 27, 2024
0746266
Print errors at the end of test run using new logging level 'TIMING_E…
jacob720 Nov 27, 2024
f9f0720
Using latest container in CI
jacob720 Nov 27, 2024
9beb25a
Allow multiple test names to be passed, seperated by ,,
jacob720 Nov 28, 2024
d245cef
Using -c when running cocotb tests in Makefile
jacob720 Nov 28, 2024
6ac0fc9
Adding cocotb docs
jacob720 Nov 28, 2024
6a26869
Allowing for multiple timing.ini files per module (such as with seq)
jacob720 Nov 29, 2024
cecabf2
auto format cocotb scripts
jsouter Dec 3, 2024
87b2c7c
add some typing to cocotb runner
jsouter Dec 3, 2024
c2b7707
separate log_timing_error from Logger class
jsouter Dec 3, 2024
c766f7b
Attempt to fix ip, info and ini commands in cocotb test runner
jsouter Dec 3, 2024
aa4634a
Add cobertura coverage to codecov for cocotb
jsouter Dec 6, 2024
bb61bc3
Move cocotb_tests to _cocotb_test.yml
jsouter Jan 16, 2025
9b4f4b8
Run cocotb workflows on ubuntu-latest
jsouter Jan 30, 2025
80ce3c8
use sed to make coverage paths relative
jsouter Jan 30, 2025
b381df1
rollback cocotb workflow to test coverage reports
jsouter Jan 30, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/_cocotb_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
on:
workflow_call:

jobs:
cocotb_test:
runs-on: ubuntu-latest
steps:
# Git repositories
- name: Checkout Source
uses: actions/checkout@v2
with:
path: PandABlocks-fpga
# require history to get back to last tag for version number of branches
fetch-depth: 0

# Login into ghcr
- name: login to ghcr
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run cocotb tests
run: |
docker pull ghcr.io/pandablocks/pandablocks-dev-container:4.0a7
docker run \
--net=host \
-v "${{ github.workspace }}:/repos" \
-v "${{ github.workspace }}/build:/build" \
ghcr.io/pandablocks/pandablocks-dev-container:4.0a7 \
/bin/bash -c \
"cd PandABlocks-fpga && ln -s CONFIG.example CONFIG && make cocotb_tests && sed -i 's/\/repos\/pandablocks-fpga\///i' cocotb_coverage.xml"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
name: nvc-coverage
files: cocotb_coverage.xml
# env:
# CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

10 changes: 7 additions & 3 deletions .github/workflows/code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ jobs:
make_zpkg:
uses: ./.github/workflows/_make_zpkg.yml

# Release on push to tag
# cocotb tests
cocotb_test:
uses: ./.github/workflows/_cocotb_test.yml

release:
needs: [ make_boot, make_zpkg, test_hdl, test_matrix, test_python_autogen ]
needs: [ make_boot, make_zpkg, test_hdl, test_matrix, test_python_autogen, cocotb_test ]
uses: ./.github/workflows/_release.yml

# Generate job matrix to evenly split tests
Expand All @@ -38,4 +41,5 @@ jobs:
needs: [test_matrix, test_python_autogen]
uses: ./.github/workflows/_test_hdl.yml
with:
matrix: ${{needs.test_matrix.outputs.matrix}}
matrix: ${{needs.test_matrix.outputs.matrix}}

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@

# For mac
*.DS_Store

# cocotb build dir
sim_build*
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,12 @@ single_hdl_test: $(TIMING_BUILD_DIRS) $(BUILD_DIR)/hdl_timing/pcap carrier_ip
hdl_timing: $(TIMING_BUILD_DIRS)
.PHONY: hdl_timing

MODULE = all
SIMULATOR = nvc
# e.g. make cocotb_tests MODULE=pulse TEST="No delay or stretch"
cocotb_tests: $(AUTOGEN_BUILD_DIR)
$(PYTHON) $(TOP)/common/python/cocotb_timing_test_runner.py -c --panda-build-dir $(BUILD_DIR) --sim $(SIMULATOR) $(MODULE) '$(TEST)'
.PHONY: cocotb_tests

# ------------------------------------------------------------------------------
# FPGA build
Expand Down
3 changes: 3 additions & 0 deletions common/hdl/defines/support.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ constant c_UNSIGNED_GRAY_ENCODING : std_logic_vector(1 downto 0) := "01";
constant c_SIGNED_BINARY_ENCODING : std_logic_vector(1 downto 0) := "10";
constant c_SIGNED_GRAY_ENCODING : std_logic_vector(1 downto 0) := "11";

type vector_array is array(natural range <>) of std_logic_vector;

--
-- Functions
--
Expand Down Expand Up @@ -96,4 +98,5 @@ begin
return index;
end function;


end support;
139 changes: 139 additions & 0 deletions common/hdl/fifo.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
-- FIFO with AXI style handshaking. The valid signal is asserted by the
-- producer when data is available to be transferred, and the ready signal is
-- asserted when the receiver is ready: transfer happens on the clock cycle when
-- ready and valid are asserted. Two further AXI rules are followed: when valid
-- is asserted it must remain asserted until ready is seen; and the assertion of
-- valid must be independent of the state of ready.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.support.all;
USE work.top_defines.all;

entity fifo is
generic (
FIFO_BITS : natural := 5; -- log2 FIFO depth
DATA_WIDTH : natural; -- Width of data path
MEM_STYLE : string := "" -- Can override tool default
);
port (
clk_i : in std_logic;

-- Write interface
write_valid_i : in std_logic;
write_ready_o : out std_logic := '0';
write_data_i : in std_logic_vector(DATA_WIDTH-1 downto 0);

-- Read interface
read_valid_o : out std_logic := '0';
read_ready_i : in std_logic;
read_data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);

-- Control and status
reset_fifo_i : in std_logic := '0';
fifo_depth_o : out unsigned(FIFO_BITS downto 0) := (others => '0')
);
end;

architecture arch of fifo is
subtype DATA_RANGE is natural range DATA_WIDTH-1 downto 0;
subtype ADDRESS_RANGE is natural range 0 to 2**FIFO_BITS-1;
subtype ADDRESS_RANGE_BITS is natural range FIFO_BITS downto 0;

signal fifo : vector_array(ADDRESS_RANGE)(DATA_RANGE);
attribute RAM_STYLE : string;
attribute RAM_STYLE of fifo : signal is MEM_STYLE;

-- This is just computing a mask with only the top bit set to be used for
-- detecting the FIFO full condition
function COMPARE_MASK return unsigned
is
variable result : unsigned(ADDRESS_RANGE_BITS) := (others => '0');
begin
result(FIFO_BITS) := '1';
return result;
end;

signal write_pointer : unsigned(ADDRESS_RANGE_BITS) := (others => '0');
signal read_pointer : unsigned(ADDRESS_RANGE_BITS) := (others => '0');
-- The read valid state is separated from read_valid_o to improve data flow
signal read_valid : std_logic := '0';

begin
process (clk_i)
variable read_enable : std_logic;
variable next_write_pointer : unsigned(ADDRESS_RANGE_BITS);
variable next_read_pointer : unsigned(ADDRESS_RANGE_BITS);
variable write_address : ADDRESS_RANGE;
variable read_address : ADDRESS_RANGE;
variable next_read_valid : std_logic;

begin
if rising_edge(clk_i) then
next_write_pointer := write_pointer;
next_read_pointer := read_pointer;
if reset_fifo_i then
next_write_pointer := (others => '0');
next_read_pointer := (others => '0');
-- Block writes during reset
write_ready_o <= '0';
read_valid <= '0';
read_enable := '0';
else
-- Advance write pointer if writing
if write_valid_i and write_ready_o then
next_write_pointer := write_pointer + 1;
end if;

-- Advance read pointer if reading. We keep read_data_o valid
-- at all times when possible
read_enable :=
read_valid and (read_ready_i or not read_valid_o);
if read_enable then
next_read_pointer := read_pointer + 1;
end if;

-- Compute full and empty conditions. Empty is simply equality
-- of pointers, full is when the write pointer is exactly one
-- FIFO depth ahead of the read pointer. This computation can
-- safely be done on the next_ pointers, which gives a small
-- flow optimisation.
write_ready_o <= to_std_logic(
next_write_pointer /= (next_read_pointer xor COMPARE_MASK));
read_valid <= to_std_logic(
next_write_pointer /= next_read_pointer);
end if;
write_pointer <= next_write_pointer;
read_pointer <= next_read_pointer;

-- Throw away the top bit of the read/write pointers for access, the
-- top bit is only used as a cycle counter to distinguish full and
-- empty states
write_address := to_integer(write_pointer(FIFO_BITS-1 downto 0));
read_address := to_integer(read_pointer(FIFO_BITS-1 downto 0));

-- Write
if write_valid_i and write_ready_o then
fifo(write_address) <= write_data_i;
end if;

-- Read
next_read_valid := read_valid_o;
if reset_fifo_i then
next_read_valid := '0';
elsif read_enable then
read_data_o <= fifo(read_address);
next_read_valid := '1';
elsif read_ready_i then
next_read_valid := '0';
end if;
read_valid_o <= next_read_valid;

-- Compute number of points in FIFO, also counting the output buffer
fifo_depth_o <=
next_write_pointer - next_read_pointer + next_read_valid;
end if;
end process;
end;
12 changes: 4 additions & 8 deletions common/hdl/spbram.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,18 @@ end spbram;
architecture rtl of spbram is

type mem_type is array (2**AW-1 downto 0) of std_logic_vector (DW-1 downto 0);
shared variable mem : mem_type := (others => (others => '0'));

begin

process (clka)
process (clka, clkb)
variable mem : mem_type := (others => (others => '0'));
begin
if (clka'event and clka = '1') then
if rising_edge(clka) then
if (wea = '1') then
mem(to_integer(unsigned(addra))) := dina;
end if;
end if;
end process;

process (clkb)
begin
if (clkb'event and clkb = '1') then
if rising_edge(clkb) then
doutb <= mem(to_integer(unsigned(addrb)));
end if;
end process;
Expand Down
Loading
Loading