diff --git a/fpga/common/tb/Makefile b/fpga/common/tb/Makefile new file mode 100644 index 000000000..c7c16d7c6 --- /dev/null +++ b/fpga/common/tb/Makefile @@ -0,0 +1,39 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPTARGETS := all clean + +SUBDIRS := $(wildcard */.) + +$(TOPTARGETS): $(SUBDIRS) +$(SUBDIRS): + $(MAKE) -C $@ $(MAKECMDGOALS) + +.PHONY: $(TOPTARGETS) $(SUBDIRS) + diff --git a/fpga/common/tb/axi.py b/fpga/common/tb/axi.py deleted file mode 120000 index af4c666a6..000000000 --- a/fpga/common/tb/axi.py +++ /dev/null @@ -1 +0,0 @@ -../lib/axi/tb/axi.py \ No newline at end of file diff --git a/fpga/common/tb/axil.py b/fpga/common/tb/axil.py deleted file mode 120000 index 9abd07cc6..000000000 --- a/fpga/common/tb/axil.py +++ /dev/null @@ -1 +0,0 @@ -../lib/axi/tb/axil.py \ No newline at end of file diff --git a/fpga/common/tb/axis_ep.py b/fpga/common/tb/axis_ep.py deleted file mode 120000 index f4ce98383..000000000 --- a/fpga/common/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/axis/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/common/tb/cpl_queue_manager/Makefile b/fpga/common/tb/cpl_queue_manager/Makefile new file mode 100644 index 000000000..17a0aec66 --- /dev/null +++ b/fpga/common/tb/cpl_queue_manager/Makefile @@ -0,0 +1,117 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = cpl_queue_manager +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v + +# module parameters +export PARAM_ADDR_WIDTH = 64 +export PARAM_REQ_TAG_WIDTH = 8 +export PARAM_OP_TABLE_SIZE = 16 +export PARAM_OP_TAG_WIDTH = 8 +export PARAM_QUEUE_INDEX_WIDTH = 8 +export PARAM_EVENT_WIDTH = 8 +export PARAM_QUEUE_PTR_WIDTH = 16 +export PARAM_LOG_QUEUE_SIZE_WIDTH = 4 +export PARAM_CPL_SIZE = 16 +export PARAM_PIPELINE = 2 +export PARAM_AXIL_DATA_WIDTH = 32 +export PARAM_AXIL_ADDR_WIDTH = 16 +export PARAM_AXIL_STRB_WIDTH = $(shell expr $(PARAM_AXIL_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).ADDR_WIDTH=$(PARAM_ADDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).REQ_TAG_WIDTH=$(PARAM_REQ_TAG_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).OP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).OP_TAG_WIDTH=$(PARAM_OP_TAG_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).QUEUE_INDEX_WIDTH=$(PARAM_QUEUE_INDEX_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).EVENT_WIDTH=$(PARAM_EVENT_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).QUEUE_PTR_WIDTH=$(PARAM_QUEUE_PTR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).LOG_QUEUE_SIZE_WIDTH=$(PARAM_LOG_QUEUE_SIZE_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).CPL_SIZE=$(PARAM_CPL_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).PIPELINE=$(PARAM_PIPELINE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GADDR_WIDTH=$(PARAM_ADDR_WIDTH) + COMPILE_ARGS += -GREQ_TAG_WIDTH=$(PARAM_REQ_TAG_WIDTH) + COMPILE_ARGS += -GOP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE) + COMPILE_ARGS += -GOP_TAG_WIDTH=$(PARAM_OP_TAG_WIDTH) + COMPILE_ARGS += -GQUEUE_INDEX_WIDTH=$(PARAM_QUEUE_INDEX_WIDTH) + COMPILE_ARGS += -GEVENT_WIDTH=$(PARAM_EVENT_WIDTH) + COMPILE_ARGS += -GQUEUE_PTR_WIDTH=$(PARAM_QUEUE_PTR_WIDTH) + COMPILE_ARGS += -GLOG_QUEUE_SIZE_WIDTH=$(PARAM_LOG_QUEUE_SIZE_WIDTH) + COMPILE_ARGS += -GCPL_SIZE=$(PARAM_CPL_SIZE) + COMPILE_ARGS += -GPIPELINE=$(PARAM_PIPELINE) + COMPILE_ARGS += -GAXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -GAXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -GAXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/cpl_queue_manager/test_cpl_queue_manager.py b/fpga/common/tb/cpl_queue_manager/test_cpl_queue_manager.py new file mode 100644 index 000000000..d33c231fc --- /dev/null +++ b/fpga/common/tb/cpl_queue_manager/test_cpl_queue_manager.py @@ -0,0 +1,337 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import random + +import cocotb_test.simulator + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiLiteMaster +from cocotbext.axi.stream import define_stream + + +EnqueueReqTransaction, EnqueueReqSource, EnqueueReqSink, EnqueueReqMonitor = define_stream("EnqueueReq", + signals=["queue", "tag", "valid"], + optional_signals=["ready"] +) + +EnqueueRespTransaction, EnqueueRespSource, EnqueueRespSink, EnqueueRespMonitor = define_stream("EnqueueResp", + signals=["queue", "ptr", "addr", "event", "tag", "op_tag", "full", "error", "valid"], + optional_signals=["ready"] +) + +EnqueueCommitTransaction, EnqueueCommitSource, EnqueueCommitSink, EnqueueCommitMonitor = define_stream("EnqueueCommit", + signals=["op_tag", "valid"], + optional_signals=["ready"] +) + +EventTransaction, EventSource, EventSink, EventMonitor = define_stream("Event", + signals=["event", "event_source", "event_valid"], + optional_signals=["event_ready"] +) + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + self.axil_master = AxiLiteMaster(dut, "s_axil", dut.clk, dut.rst) + + self.enqueue_req_source = EnqueueReqSource(dut, "s_axis_enqueue_req", dut.clk, dut.rst) + self.enqueue_resp_sink = EnqueueRespSink(dut, "m_axis_enqueue_resp", dut.clk, dut.rst) + self.enqueue_commit_source = EnqueueCommitSource(dut, "s_axis_enqueue_commit", dut.clk, dut.rst) + self.event_sink = EventSink(dut, "m_axis", dut.clk, dut.rst) + + dut.enable.setimmediatevalue(0) + + def set_idle_generator(self, generator=None): + if generator: + self.source.set_pause_generator(generator()) + + def set_backpressure_generator(self, generator=None): + if generator: + self.sink.set_pause_generator(generator()) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut): + + OP_TABLE_SIZE = int(os.getenv("PARAM_OP_TABLE_SIZE")) + + tb = TB(dut) + + await tb.reset() + + dut.enable <= 1 + + tb.log.info("Test read and write queue configuration registers") + + await tb.axil_master.write_qword(0*32+0, 0x8877665544332211) # address + await tb.axil_master.write_dword(0*32+8, 0x00000004) # active, log size + await tb.axil_master.write_dword(0*32+12, 0x80000001) # armed, continuous, event + await tb.axil_master.write_dword(0*32+16, 0x00000000) # head pointer + await tb.axil_master.write_dword(0*32+24, 0x00000000) # tail pointer + await tb.axil_master.write_dword(0*32+8, 0x80000004) # active, log size + + assert await tb.axil_master.read_qword(0*32+0) == 0x8877665544332211 + assert await tb.axil_master.read_dword(0*32+8) == 0x80000004 + assert await tb.axil_master.read_dword(0*32+12) == 0x80000001 + + tb.log.info("Test enqueue and dequeue") + + # read head pointer + head_ptr = await tb.axil_master.read_dword(0*32+16) # head pointer + tb.log.info("Head pointer: %d", head_ptr) + + # enqueue request + tb.enqueue_req_source.send(EnqueueReqTransaction(queue=0, tag=1)) + + await tb.enqueue_resp_sink.wait() + resp = tb.enqueue_resp_sink.recv() + + tb.log.info("Enqueue response: %s", resp) + + assert resp.queue == 0 + assert resp.ptr == head_ptr + assert resp.addr == 0x8877665544332211 + assert resp.event == 1 + assert resp.tag == 1 + assert not resp.full + assert not resp.error + + # enqueue commit + tb.enqueue_commit_source.send(EnqueueCommitTransaction(op_tag=resp.op_tag)) + + await Timer(100, 'ns') + + # check for event + await tb.event_sink.wait() + event = tb.event_sink.recv() + tb.log.info("Event: %s", event) + + assert event.event == 1 + assert event.event_source == 0 + + # read head pointer + new_head_ptr = await tb.axil_master.read_dword(0*32+16) # head pointer + tb.log.info("Head pointer: %d", new_head_ptr) + + assert new_head_ptr - head_ptr == 1 + + # increment tail pointer + tail_ptr = await tb.axil_master.read_dword(0*32+24) # tail pointer + tail_ptr += 1 + tb.log.info("Tail pointer: %d", tail_ptr) + await tb.axil_master.write_dword(0*32+24, tail_ptr) # head pointer + + tb.log.info("Test multiple enqueue and dequeue") + + for k in range(4): + await tb.axil_master.write_dword(k*32+8, 0x00000004) # active, log size + await tb.axil_master.write_qword(k*32+0, 0x5555555555000000 + 0x10000*k) # address + await tb.axil_master.write_dword(k*32+8, 0x00000004) # active, log size + await tb.axil_master.write_dword(k*32+12, 0xC0000000 + k) # armed, continuous, event + await tb.axil_master.write_dword(k*32+16, 0x0000fff0) # head pointer + await tb.axil_master.write_dword(k*32+24, 0x0000fff0) # tail pointer + await tb.axil_master.write_dword(k*32+8, 0x80000004) # active, log size + + current_tag = 1 + + queue_head_ptr = [0xfff0]*4 + queue_tail_ptr = [0xfff0]*4 + queue_depth = [0]*4 + queue_uncommit_depth = [0]*4 + + commit_list = [] + + random.seed(123456) + + for i in range(50): + # enqueue + for k in range(random.randrange(8)): + q = random.randrange(4) + + if len(commit_list) < OP_TABLE_SIZE: + tb.log.info("Try enqueue into queue %d", q) + + # enqueue request + tb.enqueue_req_source.send(EnqueueReqTransaction(queue=q, tag=current_tag)) + + await tb.enqueue_resp_sink.wait() + resp = tb.enqueue_resp_sink.recv() + + tb.log.info("Enqueue response: %s", resp) + + assert resp.queue == q + assert resp.ptr == queue_head_ptr[q] + assert (resp.addr >> 16) & 0xf == q + assert (resp.addr >> 4) & 0xf == queue_head_ptr[q] & 0xf + assert resp.event == q + assert resp.tag == current_tag + assert not resp.error + + if queue_uncommit_depth[q] < 16: + commit_list.append((q, resp.op_tag)) + queue_head_ptr[q] = (queue_head_ptr[q] + 1) & 0xffff + queue_uncommit_depth[q] += 1 + assert not resp.full + else: + tb.log.info("Queue was full") + assert resp.full + + current_tag = (current_tag + 1) % 256 + + # commit + #random.shuffle(commit_list) + for k in range(random.randrange(8)): + if commit_list: + q, t = commit_list.pop(0) + + tb.log.info("Commit enqueue into queue %d", q) + + # enqueue commit + tb.enqueue_commit_source.send(EnqueueCommitTransaction(op_tag=t)) + + queue_depth[q] += 1 + + # check event + await tb.event_sink.wait() + event = tb.event_sink.recv() + tb.log.info("Event: %s", event) + + assert event.event == q + assert event.event_source == q + + # dequeue + for k in range(random.randrange(8)): + q = random.randrange(4) + + if queue_depth[q] > 0: + tb.log.info("Dequeue from queue %d", q) + + # increment tail pointer + tail_ptr = await tb.axil_master.read_dword(q*32+24) # tail pointer + + assert tail_ptr == queue_tail_ptr[q] + + tail_ptr = (tail_ptr + 1) & 0xffff + + queue_tail_ptr[q] = tail_ptr + queue_depth[q] -= 1 + queue_uncommit_depth[q] -= 1 + + tb.log.info("Tail pointer: %d", tail_ptr) + await tb.axil_master.write_dword(q*32+24, tail_ptr) # tail pointer + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_cpl_queue_manager(request): + dut = "cpl_queue_manager" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + ] + + parameters = {} + + parameters['ADDR_WIDTH'] = 64 + parameters['REQ_TAG_WIDTH'] = 8 + parameters['OP_TABLE_SIZE'] = 16 + parameters['OP_TAG_WIDTH'] = 8 + parameters['QUEUE_INDEX_WIDTH'] = 8 + parameters['EVENT_WIDTH'] = 8 + parameters['QUEUE_PTR_WIDTH'] = 16 + parameters['LOG_QUEUE_SIZE_WIDTH'] = 4 + parameters['CPL_SIZE'] = 16 + parameters['PIPELINE'] = 2 + parameters['AXIL_DATA_WIDTH'] = 32 + parameters['AXIL_ADDR_WIDTH'] = 16 + parameters['AXIL_STRB_WIDTH'] = parameters['AXIL_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/eth_ep.py b/fpga/common/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/common/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/common/tb/ip_ep.py b/fpga/common/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/common/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/common/tb/mqnic.py b/fpga/common/tb/mqnic.py index 91fed935a..35e425de5 100644 --- a/fpga/common/tb/mqnic.py +++ b/fpga/common/tb/mqnic.py @@ -31,9 +31,10 @@ either expressed or implied, of The Regents of the University of California. """ -from myhdl import * +from collections import deque -import pcie +from cocotb.log import SimLog +from cocotb.triggers import Event import struct @@ -232,19 +233,26 @@ class Packet(object): def __repr__(self): return ( - ('Packet(data=%s, ' % repr(self.data)) + - ('timestamp_s=%d, ' % self.timestamp_s) + - ('timestamp_ns=%d, ' % self.timestamp_ns) + - ('rx_checksum=0x%x)' % self.rx_checksum) - ) + f'{type(self).__name__}(data={self.data}, ' + f'timestamp_s={self.timestamp_s}, ' + f'timestamp_ns={self.timestamp_ns}, ' + f'rx_checksum={self.rx_checksum:#06x})' + ) def __iter__(self): return self.data.__iter__() + def __len__(self): + return len(self.data) + + def __bytes__(self): + return bytes(self.data) + class EqRing(object): def __init__(self, interface, size, stride, index, hw_addr): self.interface = interface + self.log = interface.log self.driver = interface.driver self.rc = interface.driver.rc self.log_size = size.bit_length() - 1 @@ -262,32 +270,34 @@ class EqRing(object): self.hw_head_ptr = hw_addr+MQNIC_EVENT_QUEUE_HEAD_PTR_REG self.hw_tail_ptr = hw_addr+MQNIC_EVENT_QUEUE_TAIL_PTR_REG - def init(self): + async def init(self): + self.log.info("Init EqRing %d (interface %d)", self.index, self.interface.index) + self.buf_size = self.size*self.stride self.buf_dma, self.buf = self.rc.alloc_region(self.buf_size) - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, 0) # interrupt index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, 0) # interrupt index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size + + async def activate(self, int_index): + self.log.info("Activate EqRing %d (interface %d)", self.index, self.interface.index) - def activate(self, int_index): self.interrupt_index = int_index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, int_index) # interrupt index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_EVENT_QUEUE_ACTIVE_MASK) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, int_index) # interrupt index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_EVENT_QUEUE_ACTIVE_MASK) # active, log size - def deactivate(self): - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index) # interrupt index + async def deactivate(self): + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index) # interrupt index def empty(self): return self.head_ptr == self.tail_ptr @@ -295,55 +305,56 @@ class EqRing(object): def full(self): return self.head_ptr - self.tail_ptr >= self.size - def read_head_ptr(self): - val = yield from self.rc.mem_read_dword(self.hw_head_ptr) + async def read_head_ptr(self): + val = await self.rc.mem_read_dword(self.hw_head_ptr) self.head_ptr += (val - self.head_ptr) & self.hw_ptr_mask - def write_tail_ptr(self): - yield from self.rc.mem_write_dword(self.hw_tail_ptr, self.tail_ptr & self.hw_ptr_mask) + async def write_tail_ptr(self): + await self.rc.mem_write_dword(self.hw_tail_ptr, self.tail_ptr & self.hw_ptr_mask) - def arm(self): - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index | MQNIC_EVENT_QUEUE_ARM_MASK) # interrupt index + async def arm(self): + await self.rc.mem_write_dword(self.hw_addr+MQNIC_EVENT_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index | MQNIC_EVENT_QUEUE_ARM_MASK) # interrupt index - def process(self): + async def process(self): if not self.interface.port_up: return - print("Process event queue") + self.log.info("Process event queue") - yield from self.read_head_ptr() + await self.read_head_ptr() eq_tail_ptr = self.tail_ptr eq_index = eq_tail_ptr & self.size_mask - print("%d events in queue" % (self.head_ptr - eq_tail_ptr)) + self.log.info("%d events in queue", self.head_ptr - eq_tail_ptr) while (self.head_ptr != eq_tail_ptr): event_data = struct.unpack_from("> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, 0) # event index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, 0) # event index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size + + async def activate(self, int_index): + self.log.info("Activate CqRing %d (interface %d)", self.index, self.interface.index) - def activate(self, int_index): self.interrupt_index = int_index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, int_index) # event index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_CPL_QUEUE_ACTIVE_MASK) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, int_index) # event index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size | MQNIC_CPL_QUEUE_ACTIVE_MASK) # active, log size - def deactivate(self): - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_CPL_QUEUE_INDEX_REG, int_index) # event index + async def deactivate(self): + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_size) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index) # event index def empty(self): return self.head_ptr == self.tail_ptr @@ -395,20 +408,21 @@ class CqRing(object): def full(self): return self.head_ptr - self.tail_ptr >= self.size - def read_head_ptr(self): - val = yield from self.rc.mem_read_dword(self.hw_head_ptr) + async def read_head_ptr(self): + val = await self.rc.mem_read_dword(self.hw_head_ptr) self.head_ptr += (val - self.head_ptr) & self.hw_ptr_mask - def write_tail_ptr(self): - yield from self.rc.mem_write_dword(self.hw_tail_ptr, self.tail_ptr & self.hw_ptr_mask) + async def write_tail_ptr(self): + await self.rc.mem_write_dword(self.hw_tail_ptr, self.tail_ptr & self.hw_ptr_mask) - def arm(self): - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index | MQNIC_CPL_QUEUE_ARM_MASK) # event index + async def arm(self): + await self.rc.mem_write_dword(self.hw_addr+MQNIC_CPL_QUEUE_INTERRUPT_INDEX_REG, self.interrupt_index | MQNIC_CPL_QUEUE_ARM_MASK) # event index class TxRing(object): def __init__(self, interface, size, stride, index, hw_addr): self.interface = interface + self.log = interface.log self.driver = interface.driver self.rc = interface.driver.rc self.log_queue_size = size.bit_length() - 1 @@ -427,39 +441,41 @@ class TxRing(object): self.packets = 0 self.bytes = 0 - + self.hw_ptr_mask = 0xffff self.hw_addr = hw_addr self.hw_head_ptr = hw_addr+MQNIC_QUEUE_HEAD_PTR_REG self.hw_tail_ptr = hw_addr+MQNIC_QUEUE_TAIL_PTR_REG - def init(self): + async def init(self): + self.log.info("Init TxRing %d (interface %d)", self.index, self.interface.index) + self.tx_info = [None]*self.size self.buf_size = self.size*self.stride self.buf_dma, self.buf = self.rc.alloc_region(self.buf_size) - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, 0) # completion queue index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, 0) # completion queue index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size + + async def activate(self, cpl_index): + self.log.info("Activate TxRing %d (interface %d)", self.index, self.interface.index) - def activate(self, cpl_index): self.cpl_index = cpl_index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cpl_index) # completion queue index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cpl_index) # completion queue index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size - def deactivate(self): - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size + async def deactivate(self): + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size def empty(self): return self.head_ptr == self.clean_tail_ptr @@ -467,12 +483,12 @@ class TxRing(object): def full(self): return self.head_ptr - self.clean_tail_ptr >= self.full_size - def read_tail_ptr(self): - val = yield from self.rc.mem_read_dword(self.hw_tail_ptr) + async def read_tail_ptr(self): + val = await self.rc.mem_read_dword(self.hw_tail_ptr) self.tail_ptr += (val - self.tail_ptr) & self.hw_ptr_mask - def write_head_ptr(self): - yield from self.rc.mem_write_dword(self.hw_head_ptr, self.head_ptr & self.hw_ptr_mask) + async def write_head_ptr(self): + await self.rc.mem_write_dword(self.hw_head_ptr, self.head_ptr & self.hw_ptr_mask) def free_desc(self, index): pkt = self.tx_info[index] @@ -489,6 +505,7 @@ class TxRing(object): class RxRing(object): def __init__(self, interface, size, stride, index, hw_addr): self.interface = interface + self.log = interface.log self.driver = interface.driver self.rc = interface.driver.rc self.log_queue_size = size.bit_length() - 1 @@ -507,41 +524,43 @@ class RxRing(object): self.packets = 0 self.bytes = 0 - + self.hw_ptr_mask = 0xffff self.hw_addr = hw_addr self.hw_head_ptr = hw_addr+MQNIC_QUEUE_HEAD_PTR_REG self.hw_tail_ptr = hw_addr+MQNIC_QUEUE_TAIL_PTR_REG - def init(self): + async def init(self): + self.log.info("Init RxRing %d (interface %d)", self.index, self.interface.index) + self.rx_info = [None]*self.size self.buf_size = self.size*self.stride self.buf_dma, self.buf = self.rc.alloc_region(self.buf_size) - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, 0) # completion queue index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, 0) # completion queue index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size + + async def activate(self, cpl_index): + self.log.info("Activate RxRing %d (interface %d)", self.index, self.interface.index) - def activate(self, cpl_index): self.cpl_index = cpl_index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG, self.buf_dma & 0xffffffff) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_BASE_ADDR_REG+4, self.buf_dma >> 32) # base address - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cpl_index) # completion queue index - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, 0) # active, log size + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_CPL_QUEUE_INDEX_REG, cpl_index) # completion queue index + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_HEAD_PTR_REG, self.head_ptr & self.hw_ptr_mask) # head pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_TAIL_PTR_REG, self.tail_ptr & self.hw_ptr_mask) # tail pointer + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8) | MQNIC_QUEUE_ACTIVE_MASK) # active, log desc block size, log queue size - yield from self.refill_buffers() + await self.refill_buffers() - def deactivate(self): - yield from self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size + async def deactivate(self): + await self.rc.mem_write_dword(self.hw_addr+MQNIC_QUEUE_ACTIVE_LOG_SIZE_REG, self.log_queue_size | (self.log_desc_block_size << 8)) # active, log desc block size, log queue size def empty(self): return self.head_ptr == self.clean_tail_ptr @@ -549,12 +568,12 @@ class RxRing(object): def full(self): return self.head_ptr - self.clean_tail_ptr >= self.full_size - def read_tail_ptr(self): - val = yield from self.rc.mem_read_dword(self.hw_tail_ptr) + async def read_tail_ptr(self): + val = await self.rc.mem_read_dword(self.hw_tail_ptr) self.tail_ptr += (val - self.tail_ptr) & self.hw_ptr_mask - def write_head_ptr(self): - yield from self.rc.mem_write_dword(self.hw_head_ptr, self.head_ptr & self.hw_ptr_mask) + async def write_head_ptr(self): + await self.rc.mem_write_dword(self.hw_head_ptr, self.head_ptr & self.hw_ptr_mask) def free_desc(self, index): pkt = self.rx_info[index] @@ -577,11 +596,11 @@ class RxRing(object): # write descriptors for k in range(0, self.desc_block_size): - l = min(length-offset, 4096) if k < self.desc_block_size-1 else length-offset - struct.pack_into(" 1 else length-offset - struct.pack_into(" 1 else length-offset + struct.pack_into("> 16, self.fw_ver & 0xffff)) - self.board_id = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_BOARD_ID) - print("Board ID: {:#010x}".format(self.board_id)) - self.board_ver = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_BOARD_VER) - print("Board version: {}.{}".format(self.board_ver >> 16, self.board_ver & 0xffff)) + self.fw_id = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_FW_ID) + self.log.info("FW ID: 0x%08x", self.fw_id) + self.fw_ver = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_FW_VER) + self.log.info("FW version: %d.%d", self.fw_ver >> 16, self.fw_ver & 0xffff) + self.board_id = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_BOARD_ID) + self.log.info("Board ID: 0x%08x", self.board_id) + self.board_ver = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_BOARD_VER) + self.log.info("Board version: %d.%d", self.board_ver >> 16, self.board_ver & 0xffff) - self.phc_count = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_PHC_COUNT) - print("PHC count: {}".format(self.phc_count)) - self.phc_offset = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_PHC_OFFSET) - print("PHC offset: {:#010x}".format(self.phc_offset)) + self.phc_count = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_PHC_COUNT) + self.log.info("PHC count: %d", self.phc_count) + self.phc_offset = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_PHC_OFFSET) + self.log.info("PHC offset: 0x%08x", self.phc_offset) - self.if_count = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_IF_COUNT) - print("IF count: {}".format(self.if_count)) - self.if_stride = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_IF_STRIDE) - print("IF stride: {:#010x}".format(self.if_stride)) - self.if_csr_offset = yield from self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_IF_CSR_OFFSET) - print("IF CSR offset: {:#010x}".format(self.if_csr_offset)) - - # enable bus mastering - val = yield from self.rc.config_read_word(self.dev_id, 0x04) - yield from self.rc.config_write_word(self.dev_id, 0x04, val | 4) - - # configure MSI - yield from self.rc.configure_msi(self.dev_id) + self.if_count = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_IF_COUNT) + self.log.info("IF count: %d", self.if_count) + self.if_stride = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_IF_STRIDE) + self.log.info("IF stride: 0x%08x", self.if_stride) + self.if_csr_offset = await self.rc.mem_read_dword(self.hw_addr+MQNIC_REG_IF_CSR_OFFSET) + self.log.info("IF CSR offset: 0x%08x", self.if_csr_offset) self.interfaces = [] for k in range(self.if_count): i = Interface(self, k, self.hw_addr+k*self.if_stride) - yield from i.init() + await i.init() self.interfaces.append(i) def alloc_pkt(self): if self.free_packets: - return self.free_packets.pop() + return self.free_packets.popleft() pkt = self.rc.alloc_region(self.pkt_buf_size) self.allocated_packets.append(pkt) @@ -1078,5 +1109,3 @@ class Driver(object): assert pkt is not None assert pkt in self.allocated_packets self.free_packets.append(pkt) - - diff --git a/fpga/common/tb/pcie.py b/fpga/common/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/common/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/common/tb/pcie_us.py b/fpga/common/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/common/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/common/tb/pcie_usp.py b/fpga/common/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/common/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/common/tb/ptp.py b/fpga/common/tb/ptp.py deleted file mode 120000 index 20da32c54..000000000 --- a/fpga/common/tb/ptp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ptp.py \ No newline at end of file diff --git a/fpga/common/tb/queue_manager/Makefile b/fpga/common/tb/queue_manager/Makefile new file mode 100644 index 000000000..4ddecf51a --- /dev/null +++ b/fpga/common/tb/queue_manager/Makefile @@ -0,0 +1,120 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = queue_manager +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v + +# module parameters +export PARAM_ADDR_WIDTH = 64 +export PARAM_REQ_TAG_WIDTH = 8 +export PARAM_OP_TABLE_SIZE = 16 +export PARAM_OP_TAG_WIDTH = 8 +export PARAM_QUEUE_INDEX_WIDTH = 8 +export PARAM_CPL_INDEX_WIDTH = 8 +export PARAM_QUEUE_PTR_WIDTH = 16 +export PARAM_LOG_QUEUE_SIZE_WIDTH = 4 +export PARAM_DESC_SIZE = 16 +export PARAM_LOG_BLOCK_SIZE_WIDTH = 2 +export PARAM_PIPELINE = 2 +export PARAM_AXIL_DATA_WIDTH = 32 +export PARAM_AXIL_ADDR_WIDTH = 16 +export PARAM_AXIL_STRB_WIDTH = $(shell expr $(PARAM_AXIL_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).ADDR_WIDTH=$(PARAM_ADDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).REQ_TAG_WIDTH=$(PARAM_REQ_TAG_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).OP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).OP_TAG_WIDTH=$(PARAM_OP_TAG_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).QUEUE_INDEX_WIDTH=$(PARAM_QUEUE_INDEX_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).CPL_INDEX_WIDTH=$(PARAM_CPL_INDEX_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).QUEUE_PTR_WIDTH=$(PARAM_QUEUE_PTR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).LOG_QUEUE_SIZE_WIDTH=$(PARAM_LOG_QUEUE_SIZE_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).DESC_SIZE=$(PARAM_DESC_SIZE) + COMPILE_ARGS += -P $(TOPLEVEL).LOG_BLOCK_SIZE_WIDTH=$(PARAM_LOG_BLOCK_SIZE_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).PIPELINE=$(PARAM_PIPELINE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GADDR_WIDTH=$(PARAM_ADDR_WIDTH) + COMPILE_ARGS += -GREQ_TAG_WIDTH=$(PARAM_REQ_TAG_WIDTH) + COMPILE_ARGS += -GOP_TABLE_SIZE=$(PARAM_OP_TABLE_SIZE) + COMPILE_ARGS += -GOP_TAG_WIDTH=$(PARAM_OP_TAG_WIDTH) + COMPILE_ARGS += -GQUEUE_INDEX_WIDTH=$(PARAM_QUEUE_INDEX_WIDTH) + COMPILE_ARGS += -GCPL_INDEX_WIDTH=$(PARAM_CPL_INDEX_WIDTH) + COMPILE_ARGS += -GQUEUE_PTR_WIDTH=$(PARAM_QUEUE_PTR_WIDTH) + COMPILE_ARGS += -GLOG_QUEUE_SIZE_WIDTH=$(PARAM_LOG_QUEUE_SIZE_WIDTH) + COMPILE_ARGS += -GDESC_SIZE=$(PARAM_DESC_SIZE) + COMPILE_ARGS += -GLOG_BLOCK_SIZE_WIDTH=$(PARAM_LOG_BLOCK_SIZE_WIDTH) + COMPILE_ARGS += -GPIPELINE=$(PARAM_PIPELINE) + COMPILE_ARGS += -GAXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -GAXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -GAXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/queue_manager/test_queue_manager.py b/fpga/common/tb/queue_manager/test_queue_manager.py new file mode 100644 index 000000000..3f6654239 --- /dev/null +++ b/fpga/common/tb/queue_manager/test_queue_manager.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import random + +import cocotb_test.simulator + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiLiteMaster +from cocotbext.axi.stream import define_stream + + +DequeueReqTransaction, DequeueReqSource, DequeueReqSink, DequeueReqMonitor = define_stream("DequeueReq", + signals=["queue", "tag", "valid"], + optional_signals=["ready"] +) + +DequeueRespTransaction, DequeueRespSource, DequeueRespSink, DequeueRespMonitor = define_stream("DequeueResp", + signals=["queue", "ptr", "addr", "block_size", "cpl", "tag", "op_tag", "empty", "error", "valid"], + optional_signals=["ready"] +) + +DequeueCommitTransaction, DequeueCommitSource, DequeueCommitSink, DequeueCommitMonitor = define_stream("DequeueCommit", + signals=["op_tag", "valid"], + optional_signals=["ready"] +) + +DoorbellTransaction, DoorbellSource, DoorbellSink, DoorbellMonitor = define_stream("Doorbell", + signals=["queue", "valid"], + optional_signals=["ready"] +) + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + self.axil_master = AxiLiteMaster(dut, "s_axil", dut.clk, dut.rst) + + self.dequeue_req_source = DequeueReqSource(dut, "s_axis_dequeue_req", dut.clk, dut.rst) + self.dequeue_resp_sink = DequeueRespSink(dut, "m_axis_dequeue_resp", dut.clk, dut.rst) + self.dequeue_commit_source = DequeueCommitSource(dut, "s_axis_dequeue_commit", dut.clk, dut.rst) + self.doorbell_sink = DoorbellSink(dut, "m_axis_doorbell", dut.clk, dut.rst) + + dut.enable.setimmediatevalue(0) + + def set_idle_generator(self, generator=None): + if generator: + self.source.set_pause_generator(generator()) + + def set_backpressure_generator(self, generator=None): + if generator: + self.sink.set_pause_generator(generator()) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut): + + OP_TABLE_SIZE = int(os.getenv("PARAM_OP_TABLE_SIZE")) + + tb = TB(dut) + + await tb.reset() + + dut.enable <= 1 + + tb.log.info("Test read and write queue configuration registers") + + await tb.axil_master.write_qword(0*32+0, 0x8877665544332211) # address + await tb.axil_master.write_dword(0*32+8, 0x00000004) # active, log size + await tb.axil_master.write_dword(0*32+12, 0x00000001) # completion queue index + await tb.axil_master.write_dword(0*32+16, 0x00000000) # head pointer + await tb.axil_master.write_dword(0*32+24, 0x00000000) # tail pointer + await tb.axil_master.write_dword(0*32+8, 0x80000004) # active, log size + + assert await tb.axil_master.read_qword(0*32+0) == 0x8877665544332211 + assert await tb.axil_master.read_dword(0*32+8) == 0x80000004 + assert await tb.axil_master.read_dword(0*32+12) == 0x00000001 + + tb.log.info("Test enqueue and dequeue") + + # increment head pointer + head_ptr = await tb.axil_master.read_dword(0*32+16) # head pointer + head_ptr += 1 + tb.log.info("Head pointer: %d", head_ptr) + await tb.axil_master.write_dword(0*32+16, head_ptr) # head pointer + + # check for doorbell + await tb.doorbell_sink.wait() + db = tb.doorbell_sink.recv() + tb.log.info("Doorbell: %s", db) + + assert db.queue == 0 + + # read tail pointer + tail_ptr = await tb.axil_master.read_dword(0*32+24) # tail pointer + tb.log.info("Tail pointer: %d", tail_ptr) + + # dequeue request + tb.dequeue_req_source.send(DequeueReqTransaction(queue=0, tag=1)) + + await tb.dequeue_resp_sink.wait() + resp = tb.dequeue_resp_sink.recv() + + tb.log.info("Dequeue response: %s", resp) + + assert resp.queue == 0 + assert resp.ptr == tail_ptr + assert resp.addr == 0x8877665544332211 + assert resp.block_size == 0 + assert resp.cpl == 1 + assert resp.tag == 1 + assert not resp.empty + assert not resp.error + + # dequeue commit + tb.dequeue_commit_source.send(DequeueCommitTransaction(op_tag=resp.op_tag)) + + await Timer(100, 'ns') + + # read tail pointer + new_tail_ptr = await tb.axil_master.read_dword(0*32+24) # tail pointer + tb.log.info("Tail pointer: %d", new_tail_ptr) + + assert new_tail_ptr - tail_ptr == 1 + + tb.log.info("Test multiple enqueue and dequeue") + + for k in range(4): + await tb.axil_master.write_dword(k*32+8, 0x00000004) # active, log size + await tb.axil_master.write_qword(k*32+0, 0x5555555555000000 + 0x10000*k) # address + await tb.axil_master.write_dword(k*32+8, 0x00000004) # active, log size + await tb.axil_master.write_dword(k*32+12, 0x00000000 + k) # completion queue index + await tb.axil_master.write_dword(k*32+16, 0x0000fff0) # head pointer + await tb.axil_master.write_dword(k*32+24, 0x0000fff0) # tail pointer + await tb.axil_master.write_dword(k*32+8, 0x80000004) # active, log size + + current_tag = 1 + + queue_head_ptr = [0xfff0]*4 + queue_tail_ptr = [0xfff0]*4 + queue_depth = [0]*4 + queue_uncommit_depth = [0]*4 + + commit_list = [] + + random.seed(123456) + + for i in range(50): + # enqueue + for k in range(random.randrange(8)): + q = random.randrange(4) + + if queue_depth[q] < 16: + tb.log.info("Enqueue into queue %d", q) + + # increment head pointer + head_ptr = await tb.axil_master.read_dword(q*32+16) # head pointer + + assert head_ptr == queue_head_ptr[q] + + head_ptr = (head_ptr + 1) & 0xffff + + queue_head_ptr[q] = head_ptr + queue_depth[q] += 1 + queue_uncommit_depth[q] += 1 + + tb.log.info("Head pointer: %d", head_ptr) + await tb.axil_master.write_dword(q*32+16, head_ptr) # head pointer + + # check doorbell event + await tb.doorbell_sink.wait() + db = tb.doorbell_sink.recv() + tb.log.info("Doorbell: %s", db) + + assert db.queue == q + + # dequeue + for k in range(random.randrange(8)): + q = random.randrange(4) + + if len(commit_list) < OP_TABLE_SIZE: + tb.log.info("Try dequeue from queue %d", q) + + # dequeue request + tb.dequeue_req_source.send(DequeueReqTransaction(queue=q, tag=current_tag)) + + await tb.dequeue_resp_sink.wait() + resp = tb.dequeue_resp_sink.recv() + + tb.log.info("Dequeue response: %s", resp) + + assert resp.queue == q + assert resp.ptr == queue_tail_ptr[q] + assert (resp.addr >> 16) & 0xf == q + assert (resp.addr >> 4) & 0xf == queue_tail_ptr[q] & 0xf + assert resp.block_size == 0 + assert resp.cpl == q + assert resp.tag == current_tag + assert not resp.error + + if queue_uncommit_depth[q]: + commit_list.append((q, resp.op_tag)) + queue_tail_ptr[q] = (queue_tail_ptr[q] + 1) & 0xffff + queue_uncommit_depth[q] -= 1 + assert not resp.empty + else: + tb.log.info("Queue was empty") + assert resp.empty + + current_tag = (current_tag + 1) % 256 + + # commit + #random.shuffle(commit_list) + for k in range(random.randrange(8)): + if commit_list: + q, t = commit_list.pop(0) + + tb.log.info("Commit dequeue from queue %d", q) + + # dequeue commit + tb.dequeue_commit_source.send(DequeueCommitTransaction(op_tag=t)) + + queue_depth[q] -= 1 + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_queue_manager(request): + dut = "queue_manager" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + ] + + parameters = {} + + parameters['ADDR_WIDTH'] = 64 + parameters['REQ_TAG_WIDTH'] = 8 + parameters['OP_TABLE_SIZE'] = 16 + parameters['OP_TAG_WIDTH'] = 8 + parameters['QUEUE_INDEX_WIDTH'] = 8 + parameters['CPL_INDEX_WIDTH'] = 8 + parameters['QUEUE_PTR_WIDTH'] = 16 + parameters['LOG_QUEUE_SIZE_WIDTH'] = 4 + parameters['DESC_SIZE'] = 16 + parameters['LOG_BLOCK_SIZE_WIDTH'] = 2 + parameters['PIPELINE'] = 2 + parameters['AXIL_DATA_WIDTH'] = 32 + parameters['AXIL_ADDR_WIDTH'] = 16 + parameters['AXIL_STRB_WIDTH'] = parameters['AXIL_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/rx_checksum/Makefile b/fpga/common/tb/rx_checksum/Makefile new file mode 100644 index 000000000..7b9e53d0d --- /dev/null +++ b/fpga/common/tb/rx_checksum/Makefile @@ -0,0 +1,84 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = rx_checksum +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v + +# module parameters +export PARAM_DATA_WIDTH ?= 64 +export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE)-$(PARAM_DATA_WIDTH) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).DATA_WIDTH=$(PARAM_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GDATA_WIDTH=$(PARAM_DATA_WIDTH) + COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/rx_checksum/test_rx_checksum.py b/fpga/common/tb/rx_checksum/test_rx_checksum.py new file mode 100644 index 000000000..c7b2346f3 --- /dev/null +++ b/fpga/common/tb/rx_checksum/test_rx_checksum.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import itertools +import logging +import os + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP, TCP + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiStreamFrame, AxiStreamSource +from cocotbext.axi.stream import define_stream + + +CsumTransaction, CsumSource, CsumSink, CsumMonitor = define_stream("Csum", + signals=["csum", "csum_valid"] +) + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + self.source = AxiStreamSource(dut, "s_axis", dut.clk, dut.rst) + self.sink = CsumSink(dut, "m_axis", dut.clk, dut.rst) + + def set_idle_generator(self, generator=None): + if generator: + self.source.set_pause_generator(generator()) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=None, pkt_type=Ether): + + tb = TB(dut) + + await tb.reset() + + tb.set_idle_generator(idle_inserter) + + test_pkts = [] + test_frames = [] + + ip_id = 0 + + for payload in [payload_data(x) for x in payload_lengths()]: + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + if pkt_type == Ether: + test_pkt = eth / payload + else: + ip = IP(src=f'10.1.0.{ip_id}', dst=f'10.2.0.{ip_id}', id=ip_id) + if pkt_type == IP: + test_pkt = eth / ip / payload + elif pkt_type == UDP: + udp = UDP(sport=ip_id, dport=0x1000+ip_id) + test_pkt = eth / ip / udp / payload + elif pkt_type == TCP: + tcp = TCP(sport=ip_id, dport=0x1000+ip_id) + test_pkt = eth / ip / tcp / payload + + test_pkts.append(test_pkt) + + test_frame = AxiStreamFrame(test_pkt.build()) + test_frames.append(test_frame) + tb.source.send(test_frame) + + ip_id = (ip_id + 1) & 0xffff + + for test_pkt, test_frame in zip(test_pkts, test_frames): + await tb.sink.wait() + rx_csum = tb.sink.recv() + + csum = ~scapy.utils.checksum(bytes(test_pkt.payload)) & 0xffff + + tb.log.info("Output checksum: 0x%04x (expected 0x%04x)", rx_csum.csum.integer, csum) + + assert rx_csum.csum == csum + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +def cycle_pause(): + return itertools.cycle([1, 1, 1, 0]) + + +def size_list(): + return list(range(1, 128)) + [512, 1500, 9200] + [46]*10 + + +def incrementing_payload(length): + return bytes(itertools.islice(itertools.cycle(range(256)), length)) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.add_option("pkt_type", [Ether, IP, UDP, TCP]) + factory.add_option("payload_lengths", [size_list]) + factory.add_option("payload_data", [incrementing_payload]) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +@pytest.mark.parametrize("data_width", [64, 256]) +def test_rx_checksum(request, data_width): + dut = "rx_checksum" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + ] + + parameters = {} + + parameters['DATA_WIDTH'] = data_width + parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/rx_hash/Makefile b/fpga/common/tb/rx_hash/Makefile new file mode 100644 index 000000000..cc902834e --- /dev/null +++ b/fpga/common/tb/rx_hash/Makefile @@ -0,0 +1,84 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = rx_hash +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v + +# module parameters +export PARAM_DATA_WIDTH ?= 64 +export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE)-$(PARAM_DATA_WIDTH) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).DATA_WIDTH=$(PARAM_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GDATA_WIDTH=$(PARAM_DATA_WIDTH) + COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/rx_hash/test_rx_hash.py b/fpga/common/tb/rx_hash/test_rx_hash.py new file mode 100644 index 000000000..a4ed39f63 --- /dev/null +++ b/fpga/common/tb/rx_hash/test_rx_hash.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import enum +import ipaddress +import itertools +import logging +import os + +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP, TCP + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiStreamFrame, AxiStreamSource +from cocotbext.axi.stream import define_stream + + +HashTransaction, HashSource, HashSink, HashMonitor = define_stream("Hash", + signals=["hash", "hash_type", "hash_valid"] +) + + +class HashType(enum.IntFlag): + IPV4 = 1 + IPV6 = 2 + TCP = 4 + UDP = 8 + + +def hash_toep(data, key): + k = len(key)*8-32 + key = int.from_bytes(key, 'big') + + h = 0 + + for b in data: + for i in range(8): + if b & 0x80 >> i: + h ^= (key >> k) & 0xffffffff + k -= 1 + + return h + + +def tuple_pack(src_ip, dest_ip, src_port=None, dest_port=None): + src_ip = ipaddress.ip_address(src_ip) + dest_ip = ipaddress.ip_address(dest_ip) + data = b'' + if src_ip.version == 6 or dest_ip.version == 6: + data += src_ip.packed + data += dest_ip.packed + else: + data += src_ip.packed + data += dest_ip.packed + if src_port is not None and dest_port is not None: + data += src_port.to_bytes(2, 'big') + dest_port.to_bytes(2, 'big') + return data + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + self.source = AxiStreamSource(dut, "s_axis", dut.clk, dut.rst) + self.sink = HashSink(dut, "m_axis", dut.clk, dut.rst) + + hash_key = [ + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa + ] + + self.set_hash_key(hash_key) + + def set_idle_generator(self, generator=None): + if generator: + self.source.set_pause_generator(generator()) + + def set_hash_key(self, key): + self.hash_key = key + self.dut.hash_key <= int.from_bytes(key, 'big') + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=None, pkt_type=Ether): + + tb = TB(dut) + + await tb.reset() + + tb.set_idle_generator(idle_inserter) + + test_pkts = [] + hash_info = [] + test_frames = [] + + ip_id = 1 + + for payload in [payload_data(x) for x in payload_lengths()]: + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + if pkt_type == Ether: + test_pkt = eth / payload + hash_type = HashType(0) + hash_val = 0 + else: + ip = IP(src=f'10.1.0.{ip_id}', dst=f'10.2.0.{ip_id}', id=ip_id) + if pkt_type == IP: + test_pkt = eth / ip / payload + hash_type = HashType.IPV4 + hash_val = hash_toep(tuple_pack(ip.src, ip.dst), tb.hash_key) + elif pkt_type == UDP: + udp = UDP(sport=ip_id, dport=0x1000+ip_id) + test_pkt = eth / ip / udp / payload + hash_type = HashType.IPV4 | HashType.UDP + hash_val = hash_toep(tuple_pack(ip.src, ip.dst, udp.sport, udp.dport), tb.hash_key) + elif pkt_type == TCP: + tcp = TCP(sport=ip_id, dport=0x1000+ip_id) + test_pkt = eth / ip / tcp / payload + hash_type = HashType.IPV4 | HashType.TCP + hash_val = hash_toep(tuple_pack(ip.src, ip.dst, tcp.sport, tcp.dport), tb.hash_key) + + test_pkts.append(test_pkt) + hash_info.append((hash_type, hash_val)) + + test_frame = AxiStreamFrame(test_pkt.build()) + test_frames.append(test_frame) + tb.source.send(test_frame) + + ip_id = (ip_id + 1) & 0xffff + + for test_pkt, info, test_frame in zip(test_pkts, hash_info, test_frames): + hash_type, hash_val = info + + await tb.sink.wait() + rx_hash = tb.sink.recv() + + tb.log.info("RX hash: 0x%08x (expected: 0x%08x) type: %s (expected: %s)", + rx_hash.hash, hash_val, HashType(rx_hash.hash_type.integer), hash_type) + + assert rx_hash.hash_type == hash_type + assert rx_hash.hash == hash_val + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +def cycle_pause(): + return itertools.cycle([1, 1, 1, 0]) + + +def size_list(): + return list(range(1, 128)) + [512, 1500, 9200] + [46]*10 + + +def incrementing_payload(length): + return bytes(itertools.islice(itertools.cycle(range(256)), length)) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.add_option("pkt_type", [Ether, IP, UDP, TCP]) + factory.add_option("payload_lengths", [size_list]) + factory.add_option("payload_data", [incrementing_payload]) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +@pytest.mark.parametrize("data_width", [64, 256]) +def test_rx_hash(request, data_width): + dut = "rx_hash" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + ] + + parameters = {} + + parameters['DATA_WIDTH'] = data_width + parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/tdma_ber/Makefile b/fpga/common/tb/tdma_ber/Makefile new file mode 100644 index 000000000..518d208cb --- /dev/null +++ b/fpga/common/tb/tdma_ber/Makefile @@ -0,0 +1,125 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = tdma_ber +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/tdma_ber_ch.v +VERILOG_SOURCES += ../../rtl/tdma_scheduler.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v + +# module parameters +export PARAM_COUNT = 2 +export PARAM_INDEX_WIDTH = 6 +export PARAM_SLICE_WIDTH = 5 +export PARAM_AXIL_DATA_WIDTH = 32 +export PARAM_AXIL_ADDR_WIDTH = $(shell python -c "print($(PARAM_INDEX_WIDTH)+4+1+($(PARAM_COUNT)-1).bit_length())") +export PARAM_AXIL_STRB_WIDTH = $(shell expr $(PARAM_AXIL_DATA_WIDTH) / 8 ) +export PARAM_SCHEDULE_START_S = 0 +export PARAM_SCHEDULE_START_NS = 0 +export PARAM_SCHEDULE_PERIOD_S = 0 +export PARAM_SCHEDULE_PERIOD_NS = 1000000 +export PARAM_TIMESLOT_PERIOD_S = 0 +export PARAM_TIMESLOT_PERIOD_NS = 100000 +export PARAM_ACTIVE_PERIOD_S = 0 +export PARAM_ACTIVE_PERIOD_NS = 100000 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).COUNT=$(PARAM_COUNT) + COMPILE_ARGS += -P $(TOPLEVEL).INDEX_WIDTH=$(PARAM_INDEX_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SLICE_WIDTH=$(PARAM_SLICE_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_START_S=$(PARAM_SCHEDULE_START_S) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_START_NS=$(PARAM_SCHEDULE_START_NS) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_PERIOD_S=$(PARAM_SCHEDULE_PERIOD_S) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_PERIOD_NS=$(PARAM_SCHEDULE_PERIOD_NS) + COMPILE_ARGS += -P $(TOPLEVEL).TIMESLOT_PERIOD_S=$(PARAM_TIMESLOT_PERIOD_S) + COMPILE_ARGS += -P $(TOPLEVEL).TIMESLOT_PERIOD_NS=$(PARAM_TIMESLOT_PERIOD_NS) + COMPILE_ARGS += -P $(TOPLEVEL).ACTIVE_PERIOD_S=$(PARAM_ACTIVE_PERIOD_S) + COMPILE_ARGS += -P $(TOPLEVEL).ACTIVE_PERIOD_NS=$(PARAM_ACTIVE_PERIOD_NS) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GCOUNT=$(PARAM_COUNT) + COMPILE_ARGS += -GINDEX_WIDTH=$(PARAM_INDEX_WIDTH) + COMPILE_ARGS += -GSLICE_WIDTH=$(PARAM_SLICE_WIDTH) + COMPILE_ARGS += -GAXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -GAXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -GAXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + COMPILE_ARGS += -GSCHEDULE_START_S=$(PARAM_SCHEDULE_START_S) + COMPILE_ARGS += -GSCHEDULE_START_NS=$(PARAM_SCHEDULE_START_NS) + COMPILE_ARGS += -GSCHEDULE_PERIOD_S=$(PARAM_SCHEDULE_PERIOD_S) + COMPILE_ARGS += -GSCHEDULE_PERIOD_NS=$(PARAM_SCHEDULE_PERIOD_NS) + COMPILE_ARGS += -GTIMESLOT_PERIOD_S=$(PARAM_TIMESLOT_PERIOD_S) + COMPILE_ARGS += -GTIMESLOT_PERIOD_NS=$(PARAM_TIMESLOT_PERIOD_NS) + COMPILE_ARGS += -GACTIVE_PERIOD_S=$(PARAM_ACTIVE_PERIOD_S) + COMPILE_ARGS += -GACTIVE_PERIOD_NS=$(PARAM_ACTIVE_PERIOD_NS) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/tdma_ber/test_tdma_ber.py b/fpga/common/tb/tdma_ber/test_tdma_ber.py new file mode 100644 index 000000000..ba129eb61 --- /dev/null +++ b/fpga/common/tb/tdma_ber/test_tdma_ber.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiLiteMaster +from cocotbext.eth import PtpClock + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + cocotb.fork(Clock(dut.phy_tx_clk, 6.4, units="ns").start()) + cocotb.fork(Clock(dut.phy_rx_clk, 6.4, units="ns").start()) + + self.axil_master = AxiLiteMaster(dut, "s_axil", dut.clk, dut.rst) + + self.ptp_clock = PtpClock( + ts_96=dut.ptp_ts_96, + ts_step=dut.ptp_ts_step, + clock=dut.clk, + reset=dut.rst, + period_ns=6.4 + ) + + dut.phy_rx_error_count.setimmediatevalue(0) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut): + + tb = TB(dut) + + await tb.reset() + + tb.log.info("Test scheduler") + + await tb.axil_master.write_dwords(0x0110, [0, 500, 0, 0]) + await tb.axil_master.write_dwords(0x0120, [0, 2000, 0, 0]) + await tb.axil_master.write_dwords(0x0130, [0, 400, 0, 0]) + await tb.axil_master.write_dwords(0x0140, [0, 300, 0, 0]) + await tb.axil_master.write_dword(0x0100, 0x00000001) + + await Timer(10000, 'ns') + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_tdma_ber(request): + dut = "tdma_ber" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, f"{dut}_ch.v"), + os.path.join(rtl_dir, "tdma_scheduler.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + ] + + parameters = {} + + parameters['COUNT'] = 2 + parameters['INDEX_WIDTH'] = 6 + parameters['SLICE_WIDTH'] = 5 + parameters['AXIL_DATA_WIDTH'] = 32 + parameters['AXIL_ADDR_WIDTH'] = parameters['INDEX_WIDTH']+4+1+(parameters['COUNT']-1).bit_length() + parameters['AXIL_STRB_WIDTH'] = parameters['AXIL_DATA_WIDTH'] // 8 + parameters['SCHEDULE_START_S'] = 0 + parameters['SCHEDULE_START_NS'] = 0 + parameters['SCHEDULE_PERIOD_S'] = 0 + parameters['SCHEDULE_PERIOD_NS'] = 1000000 + parameters['TIMESLOT_PERIOD_S'] = 0 + parameters['TIMESLOT_PERIOD_NS'] = 100000 + parameters['ACTIVE_PERIOD_S'] = 0 + parameters['ACTIVE_PERIOD_NS'] = 100000 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/tdma_ber_ch/Makefile b/fpga/common/tb/tdma_ber_ch/Makefile new file mode 100644 index 000000000..c360383db --- /dev/null +++ b/fpga/common/tb/tdma_ber_ch/Makefile @@ -0,0 +1,93 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = tdma_ber_ch +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v + +# module parameters +export PARAM_INDEX_WIDTH = 6 +export PARAM_SLICE_WIDTH = 5 +export PARAM_AXIL_DATA_WIDTH = 32 +export PARAM_AXIL_ADDR_WIDTH = $(shell expr $(PARAM_INDEX_WIDTH) + 4 ) +export PARAM_AXIL_STRB_WIDTH = $(shell expr $(PARAM_AXIL_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).INDEX_WIDTH=$(PARAM_INDEX_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SLICE_WIDTH=$(PARAM_SLICE_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GINDEX_WIDTH=$(PARAM_INDEX_WIDTH) + COMPILE_ARGS += -GSLICE_WIDTH=$(PARAM_SLICE_WIDTH) + COMPILE_ARGS += -GAXIL_DATA_WIDTH=$(PARAM_AXIL_DATA_WIDTH) + COMPILE_ARGS += -GAXIL_ADDR_WIDTH=$(PARAM_AXIL_ADDR_WIDTH) + COMPILE_ARGS += -GAXIL_STRB_WIDTH=$(PARAM_AXIL_STRB_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/tdma_ber_ch/test_tdma_ber_ch.py b/fpga/common/tb/tdma_ber_ch/test_tdma_ber_ch.py new file mode 100644 index 000000000..47b32d05a --- /dev/null +++ b/fpga/common/tb/tdma_ber_ch/test_tdma_ber_ch.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiLiteMaster + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + cocotb.fork(Clock(dut.phy_tx_clk, 6.4, units="ns").start()) + cocotb.fork(Clock(dut.phy_rx_clk, 6.4, units="ns").start()) + + self.axil_master = AxiLiteMaster(dut, "s_axil", dut.clk, dut.rst) + + dut.phy_rx_error_count.setimmediatevalue(0) + + dut.tdma_timeslot_index.setimmediatevalue(0) + dut.tdma_timeslot_start.setimmediatevalue(0) + dut.tdma_timeslot_active.setimmediatevalue(0) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + async def run_scheduler(self, period=50, active_period=None, slots=4, cycles=5): + if active_period is None: + active_period = period + active_period = min(active_period, period) + + await RisingEdge(self.dut.clk) + for i in range(cycles): + for k in range(slots): + self.dut.tdma_timeslot_index <= k + self.dut.tdma_timeslot_start <= 1 + self.dut.tdma_timeslot_active <= 1 + await RisingEdge(self.dut.clk) + self.dut.tdma_timeslot_start <= 0 + for k in range(active_period-1): + await RisingEdge(self.dut.clk) + self.dut.tdma_timeslot_active <= 0 + for k in range(period-active_period): + await RisingEdge(self.dut.clk) + + async def dump_counters(self): + cycles, updates, errors = await self.axil_master.read_dwords(0x0014, 3) + self.log.info("Cycles: %d", cycles) + self.log.info("Updates: %d", updates) + self.log.info("Errors: %d", errors) + + async def dump_timeslot_counters(self, slice_index=0): + await self.axil_master.write_dword(0x0030, slice_index) + counters = await self.axil_master.read_dwords(0x0200, 8) + for k in range(4): + self.log.info("Timeslot %d slice %d updates: %s", k, slice_index, counters[k*2]) + self.log.info("Timeslot %d slice %d errors: %s", k, slice_index, counters[k*2+1]) + + async def clear_timeslot_counters(self, slice_index=0): + await self.axil_master.write_dword(0x0030, slice_index) + await self.axil_master.write_dwords(0x0200, [0]*8) + + +async def run_test(dut): + + tb = TB(dut) + + await tb.reset() + + tb.log.info("Test error counts") + + await tb.axil_master.write_dword(0x0000, 0x00000003) + await tb.axil_master.write_dword(0x0020, 0x00000001) + + await tb.dump_counters() + await tb.dump_timeslot_counters() + await tb.clear_timeslot_counters() + + await tb.run_scheduler(period=50, active_period=None, slots=4, cycles=5) + + await tb.dump_counters() + await tb.dump_timeslot_counters() + await tb.clear_timeslot_counters() + + await RisingEdge(dut.clk) + dut.phy_rx_error_count <= 1 + + await tb.run_scheduler(period=50, active_period=None, slots=4, cycles=5) + + await RisingEdge(dut.clk) + dut.phy_rx_error_count <= 0 + + await tb.dump_counters() + await tb.dump_timeslot_counters() + await tb.clear_timeslot_counters() + + tb.log.info("Change duty cycle") + + await tb.axil_master.write_dword(0x0000, 0x00000003) + await tb.axil_master.write_dword(0x0020, 0x00000001) + + await tb.dump_counters() + await tb.dump_timeslot_counters() + await tb.clear_timeslot_counters() + + await tb.run_scheduler(period=50, active_period=40, slots=4, cycles=5) + + await tb.dump_counters() + await tb.dump_timeslot_counters() + await tb.clear_timeslot_counters() + + await RisingEdge(dut.clk) + dut.phy_rx_error_count <= 1 + + await tb.run_scheduler(period=50, active_period=40, slots=4, cycles=5) + + await RisingEdge(dut.clk) + dut.phy_rx_error_count <= 0 + + await tb.dump_counters() + await tb.dump_timeslot_counters() + await tb.clear_timeslot_counters() + + tb.log.info("Test slices") + + await tb.axil_master.write_dword(0x0000, 0x00000003) + await tb.axil_master.write_dword(0x0020, 0x00000003) + await tb.axil_master.write_dword(0x0024, 0x00000010) + await tb.axil_master.write_dword(0x0028, 0x00000020) + + await tb.dump_counters() + for k in range(3): + await tb.dump_timeslot_counters(k) + for k in range(3): + await tb.clear_timeslot_counters(k) + + await tb.run_scheduler(period=500, active_period=400, slots=4, cycles=5) + + await tb.dump_counters() + for k in range(3): + await tb.dump_timeslot_counters(k) + for k in range(3): + await tb.clear_timeslot_counters(k) + + await RisingEdge(dut.clk) + dut.phy_rx_error_count <= 1 + + await tb.run_scheduler(period=500, active_period=400, slots=4, cycles=5) + + await RisingEdge(dut.clk) + dut.phy_rx_error_count <= 0 + + await tb.dump_counters() + for k in range(3): + await tb.dump_timeslot_counters(k) + for k in range(3): + await tb.clear_timeslot_counters(k) + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_tdma_ber_ch(request): + dut = "tdma_ber_ch" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + ] + + parameters = {} + + parameters['INDEX_WIDTH'] = 6 + parameters['SLICE_WIDTH'] = 5 + parameters['AXIL_DATA_WIDTH'] = 32 + parameters['AXIL_ADDR_WIDTH'] = parameters['INDEX_WIDTH']+4 + parameters['AXIL_STRB_WIDTH'] = parameters['AXIL_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/tdma_scheduler/Makefile b/fpga/common/tb/tdma_scheduler/Makefile new file mode 100644 index 000000000..91c3f0d3b --- /dev/null +++ b/fpga/common/tb/tdma_scheduler/Makefile @@ -0,0 +1,99 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = tdma_scheduler +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v + +# module parameters +export PARAM_INDEX_WIDTH = 8 +export PARAM_SCHEDULE_START_S = 0 +export PARAM_SCHEDULE_START_NS = 0 +export PARAM_SCHEDULE_PERIOD_S = 0 +export PARAM_SCHEDULE_PERIOD_NS = 1000000 +export PARAM_TIMESLOT_PERIOD_S = 0 +export PARAM_TIMESLOT_PERIOD_NS = 100000 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).INDEX_WIDTH=$(PARAM_INDEX_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_START_S=$(PARAM_SCHEDULE_START_S) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_START_NS=$(PARAM_SCHEDULE_START_NS) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_PERIOD_S=$(PARAM_SCHEDULE_PERIOD_S) + COMPILE_ARGS += -P $(TOPLEVEL).SCHEDULE_PERIOD_NS=$(PARAM_SCHEDULE_PERIOD_NS) + COMPILE_ARGS += -P $(TOPLEVEL).TIMESLOT_PERIOD_S=$(PARAM_TIMESLOT_PERIOD_S) + COMPILE_ARGS += -P $(TOPLEVEL).TIMESLOT_PERIOD_NS=$(PARAM_TIMESLOT_PERIOD_NS) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GINDEX_WIDTH=$(PARAM_INDEX_WIDTH) + COMPILE_ARGS += -GSCHEDULE_START_S=$(PARAM_SCHEDULE_START_S) + COMPILE_ARGS += -GSCHEDULE_START_NS=$(PARAM_SCHEDULE_START_NS) + COMPILE_ARGS += -GSCHEDULE_PERIOD_S=$(PARAM_SCHEDULE_PERIOD_S) + COMPILE_ARGS += -GSCHEDULE_PERIOD_NS=$(PARAM_SCHEDULE_PERIOD_NS) + COMPILE_ARGS += -GTIMESLOT_PERIOD_S=$(PARAM_TIMESLOT_PERIOD_S) + COMPILE_ARGS += -GTIMESLOT_PERIOD_NS=$(PARAM_TIMESLOT_PERIOD_NS) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/tdma_scheduler/test_tdma_scheduler.py b/fpga/common/tb/tdma_scheduler/test_tdma_scheduler.py new file mode 100644 index 000000000..f81709f4e --- /dev/null +++ b/fpga/common/tb/tdma_scheduler/test_tdma_scheduler.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os + +import cocotb_test.simulator + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer +from cocotb.regression import TestFactory + +from cocotbext.eth import PtpClock + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + self.ptp_clock = PtpClock( + ts_96=dut.input_ts_96, + ts_step=dut.input_ts_step, + clock=dut.clk, + reset=dut.rst, + period_ns=6.4 + ) + + dut.enable.setimmediatevalue(0) + dut.input_schedule_start.setimmediatevalue(0) + dut.input_schedule_start_valid.setimmediatevalue(0) + dut.input_schedule_period.setimmediatevalue(0) + dut.input_schedule_period_valid.setimmediatevalue(0) + dut.input_timeslot_period.setimmediatevalue(0) + dut.input_timeslot_period_valid.setimmediatevalue(0) + dut.input_active_period.setimmediatevalue(0) + dut.input_active_period_valid.setimmediatevalue(0) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut): + + tb = TB(dut) + + await tb.reset() + + dut.enable <= 1 + + tb.log.info("Test pulse out") + + await RisingEdge(dut.clk) + + dut.input_schedule_start <= 1000 + dut.input_schedule_start_valid <= 1 + dut.input_schedule_period <= 2000 + dut.input_schedule_period_valid <= 1 + dut.input_timeslot_period <= 400 + dut.input_timeslot_period_valid <= 1 + dut.input_active_period <= 300 + dut.input_active_period_valid <= 1 + + await RisingEdge(dut.clk) + + dut.input_schedule_start_valid <= 0 + dut.input_schedule_period_valid <= 0 + dut.input_timeslot_period_valid <= 0 + dut.input_active_period_valid <= 0 + + await Timer(10000, 'ns') + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +if cocotb.SIM_NAME: + + factory = TestFactory(run_test) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_tdma_scheduler(request): + dut = "tdma_scheduler" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + ] + + parameters = {} + + parameters['INDEX_WIDTH'] = 8 + parameters['SCHEDULE_START_S'] = 0 + parameters['SCHEDULE_START_NS'] = 0 + parameters['SCHEDULE_PERIOD_S'] = 0 + parameters['SCHEDULE_PERIOD_NS'] = 1000000 + parameters['TIMESLOT_PERIOD_S'] = 0 + parameters['TIMESLOT_PERIOD_NS'] = 100000 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/test_cpl_queue_manager.py b/fpga/common/tb/test_cpl_queue_manager.py deleted file mode 100755 index b6b1ad15d..000000000 --- a/fpga/common/tb/test_cpl_queue_manager.py +++ /dev/null @@ -1,495 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import axil -import axis_ep - -import random -import struct - -module = 'cpl_queue_manager' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - ADDR_WIDTH = 64 - REQ_TAG_WIDTH = 8 - OP_TABLE_SIZE = 16 - OP_TAG_WIDTH = 8 - QUEUE_INDEX_WIDTH = 8 - EVENT_WIDTH = 8 - QUEUE_PTR_WIDTH = 16 - LOG_QUEUE_SIZE_WIDTH = 4 - CPL_SIZE = 16 - PIPELINE = 2 - AXIL_DATA_WIDTH = 32 - AXIL_ADDR_WIDTH = 16 - AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH/8) - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_enqueue_req_queue = Signal(intbv(0)[QUEUE_INDEX_WIDTH:]) - s_axis_enqueue_req_tag = Signal(intbv(0)[REQ_TAG_WIDTH:]) - s_axis_enqueue_req_valid = Signal(bool(0)) - m_axis_enqueue_resp_ready = Signal(bool(0)) - s_axis_enqueue_commit_op_tag = Signal(intbv(0)[OP_TAG_WIDTH:]) - s_axis_enqueue_commit_valid = Signal(bool(0)) - s_axil_awaddr = Signal(intbv(0)[AXIL_ADDR_WIDTH:]) - s_axil_awprot = Signal(intbv(0)[3:]) - s_axil_awvalid = Signal(bool(0)) - s_axil_wdata = Signal(intbv(0)[AXIL_DATA_WIDTH:]) - s_axil_wstrb = Signal(intbv(0)[AXIL_STRB_WIDTH:]) - s_axil_wvalid = Signal(bool(0)) - s_axil_bready = Signal(bool(0)) - s_axil_araddr = Signal(intbv(0)[AXIL_ADDR_WIDTH:]) - s_axil_arprot = Signal(intbv(0)[3:]) - s_axil_arvalid = Signal(bool(0)) - s_axil_rready = Signal(bool(0)) - enable = Signal(bool(0)) - - # Outputs - s_axis_enqueue_req_ready = Signal(bool(0)) - m_axis_enqueue_resp_queue = Signal(intbv(0)[QUEUE_INDEX_WIDTH:]) - m_axis_enqueue_resp_ptr = Signal(intbv(0)[QUEUE_PTR_WIDTH:]) - m_axis_enqueue_resp_addr = Signal(intbv(0)[ADDR_WIDTH:]) - m_axis_enqueue_resp_event = Signal(intbv(0)[EVENT_WIDTH:]) - m_axis_enqueue_resp_tag = Signal(intbv(0)[REQ_TAG_WIDTH:]) - m_axis_enqueue_resp_op_tag = Signal(intbv(0)[OP_TAG_WIDTH:]) - m_axis_enqueue_resp_full = Signal(bool(0)) - m_axis_enqueue_resp_error = Signal(bool(0)) - m_axis_enqueue_resp_valid = Signal(bool(0)) - s_axis_enqueue_commit_ready = Signal(bool(0)) - m_axis_event = Signal(intbv(0)[EVENT_WIDTH:]) - m_axis_event_source = Signal(intbv(0)[QUEUE_INDEX_WIDTH:]) - m_axis_event_valid = Signal(bool(0)) - s_axil_awready = Signal(bool(0)) - s_axil_wready = Signal(bool(0)) - s_axil_bresp = Signal(intbv(0)[2:]) - s_axil_bvalid = Signal(bool(0)) - s_axil_arready = Signal(bool(0)) - s_axil_rdata = Signal(intbv(0)[AXIL_DATA_WIDTH:]) - s_axil_rresp = Signal(intbv(0)[2:]) - s_axil_rvalid = Signal(bool(0)) - - # sources and sinks - enqueue_req_source = axis_ep.AXIStreamSource() - - enqueue_req_source_logic = enqueue_req_source.create_logic( - clk, - rst, - tdata=(s_axis_enqueue_req_queue, s_axis_enqueue_req_tag), - tvalid=s_axis_enqueue_req_valid, - tready=s_axis_enqueue_req_ready, - name='enqueue_req_source' - ) - - enqueue_resp_sink = axis_ep.AXIStreamSink() - - enqueue_resp_sink_logic = enqueue_resp_sink.create_logic( - clk, - rst, - tdata=(m_axis_enqueue_resp_queue, m_axis_enqueue_resp_ptr, m_axis_enqueue_resp_addr, m_axis_enqueue_resp_event, m_axis_enqueue_resp_tag, m_axis_enqueue_resp_op_tag, m_axis_enqueue_resp_full, m_axis_enqueue_resp_error), - tvalid=m_axis_enqueue_resp_valid, - tready=m_axis_enqueue_resp_ready, - name='enqueue_resp_sink' - ) - - enqueue_commit_source = axis_ep.AXIStreamSource() - - enqueue_commit_source_logic = enqueue_commit_source.create_logic( - clk, - rst, - tdata=(s_axis_enqueue_commit_op_tag,), - tvalid=s_axis_enqueue_commit_valid, - tready=s_axis_enqueue_commit_ready, - name='enqueue_commit_source' - ) - - event_sink = axis_ep.AXIStreamSink() - - event_sink_logic = event_sink.create_logic( - clk, - rst, - tdata=(m_axis_event, m_axis_event_source), - tvalid=m_axis_event_valid, - name='event_sink' - ) - - # AXI4-Lite master - axil_master_inst = axil.AXILiteMaster() - axil_master_pause = Signal(bool(False)) - - axil_master_logic = axil_master_inst.create_logic( - clk, - rst, - m_axil_awaddr=s_axil_awaddr, - m_axil_awprot=s_axil_awprot, - m_axil_awvalid=s_axil_awvalid, - m_axil_awready=s_axil_awready, - m_axil_wdata=s_axil_wdata, - m_axil_wstrb=s_axil_wstrb, - m_axil_wvalid=s_axil_wvalid, - m_axil_wready=s_axil_wready, - m_axil_bresp=s_axil_bresp, - m_axil_bvalid=s_axil_bvalid, - m_axil_bready=s_axil_bready, - m_axil_araddr=s_axil_araddr, - m_axil_arprot=s_axil_arprot, - m_axil_arvalid=s_axil_arvalid, - m_axil_arready=s_axil_arready, - m_axil_rdata=s_axil_rdata, - m_axil_rresp=s_axil_rresp, - m_axil_rvalid=s_axil_rvalid, - m_axil_rready=s_axil_rready, - pause=axil_master_pause, - name='master' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_enqueue_req_queue=s_axis_enqueue_req_queue, - s_axis_enqueue_req_tag=s_axis_enqueue_req_tag, - s_axis_enqueue_req_valid=s_axis_enqueue_req_valid, - s_axis_enqueue_req_ready=s_axis_enqueue_req_ready, - m_axis_enqueue_resp_queue=m_axis_enqueue_resp_queue, - m_axis_enqueue_resp_ptr=m_axis_enqueue_resp_ptr, - m_axis_enqueue_resp_addr=m_axis_enqueue_resp_addr, - m_axis_enqueue_resp_event=m_axis_enqueue_resp_event, - m_axis_enqueue_resp_tag=m_axis_enqueue_resp_tag, - m_axis_enqueue_resp_op_tag=m_axis_enqueue_resp_op_tag, - m_axis_enqueue_resp_full=m_axis_enqueue_resp_full, - m_axis_enqueue_resp_error=m_axis_enqueue_resp_error, - m_axis_enqueue_resp_valid=m_axis_enqueue_resp_valid, - m_axis_enqueue_resp_ready=m_axis_enqueue_resp_ready, - s_axis_enqueue_commit_op_tag=s_axis_enqueue_commit_op_tag, - s_axis_enqueue_commit_valid=s_axis_enqueue_commit_valid, - s_axis_enqueue_commit_ready=s_axis_enqueue_commit_ready, - m_axis_event=m_axis_event, - m_axis_event_source=m_axis_event_source, - m_axis_event_valid=m_axis_event_valid, - s_axil_awaddr=s_axil_awaddr, - s_axil_awprot=s_axil_awprot, - s_axil_awvalid=s_axil_awvalid, - s_axil_awready=s_axil_awready, - s_axil_wdata=s_axil_wdata, - s_axil_wstrb=s_axil_wstrb, - s_axil_wvalid=s_axil_wvalid, - s_axil_wready=s_axil_wready, - s_axil_bresp=s_axil_bresp, - s_axil_bvalid=s_axil_bvalid, - s_axil_bready=s_axil_bready, - s_axil_araddr=s_axil_araddr, - s_axil_arprot=s_axil_arprot, - s_axil_arvalid=s_axil_arvalid, - s_axil_arready=s_axil_arready, - s_axil_rdata=s_axil_rdata, - s_axil_rresp=s_axil_rresp, - s_axil_rvalid=s_axil_rvalid, - s_axil_rready=s_axil_rready, - enable=enable - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - enable.next = 1 - - yield clk.posedge - print("test 1: read and write queue configuration registers") - current_test.next = 1 - - axil_master_inst.init_write(0*32+0, struct.pack('> 16) & 0xf == q - assert (resp.data[0][2] >> 4) & 0xf == queue_head_ptr[q] & 0xf - assert resp.data[0][3] == q - - assert resp.data[0][4] == current_tag # tag - assert not resp.data[0][7] # error - - if queue_uncommit_depth[q] < 16: - commit_list.append((q, resp.data[0][5])) - queue_head_ptr[q] = (queue_head_ptr[q] + 1) & 0xffff - queue_uncommit_depth[q] += 1 - else: - print("Queue was full") - assert resp.data[0][6] # full - - current_tag = (current_tag + 1) % 256 - - # commit - #random.shuffle(commit_list) - for k in range(random.randrange(8)): - if commit_list: - q, t = commit_list.pop(0) - - print("Commit enqueue into queue %d" % q) - - # enqueue commit - enqueue_commit_source.send([(t,)]) - - queue_depth[q] += 1 - - # check event - yield event_sink.wait() - event = event_sink.recv() - assert event.data[0][0] == q # event - assert event.data[0][1] == q # source (queue) - - # dequeue - for k in range(random.randrange(8)): - q = random.randrange(4) - - if queue_depth[q] > 0: - print("Dequeue from queue %d" % q) - - # increment tail pointer - axil_master_inst.init_read(q*32+24, 4) # tail pointer - yield axil_master_inst.wait() - - data = axil_master_inst.get_read_data() - tail_ptr = struct.unpack('> 16) & 0xf == q - assert (resp.data[0][2] >> 4) & 0xf == queue_tail_ptr[q] & 0xf - assert resp.data[0][4] == q - - assert resp.data[0][5] == current_tag # tag - assert not resp.data[0][8] # error - - if queue_uncommit_depth[q]: - commit_list.append((q, resp.data[0][6])) - queue_tail_ptr[q] = (queue_tail_ptr[q] + 1) & 0xffff - queue_uncommit_depth[q] -= 1 - else: - print("Queue was empty") - assert resp.data[0][7] # empty - - current_tag = (current_tag + 1) % 256 - - # commit - #random.shuffle(commit_list) - for k in range(random.randrange(8)): - if commit_list: - q, t = commit_list.pop(0) - - print("Commit dequeue from queue %d" % q) - - # dequeue commit - dequeue_commit_source.send([(t,)]) - - queue_depth[q] -= 1 - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_queue_manager.v b/fpga/common/tb/test_queue_manager.v deleted file mode 100644 index e0a30113b..000000000 --- a/fpga/common/tb/test_queue_manager.v +++ /dev/null @@ -1,223 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for queue_manager - */ -module test_queue_manager; - -// Parameters -parameter ADDR_WIDTH = 64; -parameter REQ_TAG_WIDTH = 8; -parameter OP_TABLE_SIZE = 16; -parameter OP_TAG_WIDTH = 8; -parameter QUEUE_INDEX_WIDTH = 8; -parameter CPL_INDEX_WIDTH = 8; -parameter QUEUE_PTR_WIDTH = 16; -parameter LOG_QUEUE_SIZE_WIDTH = 4; -parameter DESC_SIZE = 16; -parameter LOG_BLOCK_SIZE_WIDTH = 2; -parameter PIPELINE = 2; -parameter AXIL_DATA_WIDTH = 32; -parameter AXIL_ADDR_WIDTH = 16; -parameter AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [QUEUE_INDEX_WIDTH-1:0] s_axis_dequeue_req_queue = 0; -reg [REQ_TAG_WIDTH-1:0] s_axis_dequeue_req_tag = 0; -reg s_axis_dequeue_req_valid = 0; -reg m_axis_dequeue_resp_ready = 0; -reg [OP_TAG_WIDTH-1:0] s_axis_dequeue_commit_op_tag = 0; -reg s_axis_dequeue_commit_valid = 0; -reg [AXIL_ADDR_WIDTH-1:0] s_axil_awaddr = 0; -reg [2:0] s_axil_awprot = 0; -reg s_axil_awvalid = 0; -reg [AXIL_DATA_WIDTH-1:0] s_axil_wdata = 0; -reg [AXIL_STRB_WIDTH-1:0] s_axil_wstrb = 0; -reg s_axil_wvalid = 0; -reg s_axil_bready = 0; -reg [AXIL_ADDR_WIDTH-1:0] s_axil_araddr = 0; -reg [2:0] s_axil_arprot = 0; -reg s_axil_arvalid = 0; -reg s_axil_rready = 0; -reg enable = 0; - -// Outputs -wire s_axis_dequeue_req_ready; -wire [QUEUE_INDEX_WIDTH-1:0] m_axis_dequeue_resp_queue; -wire [QUEUE_PTR_WIDTH-1:0] m_axis_dequeue_resp_ptr; -wire [ADDR_WIDTH-1:0] m_axis_dequeue_resp_addr; -wire [LOG_BLOCK_SIZE_WIDTH-1:0] m_axis_dequeue_resp_block_size; -wire [CPL_INDEX_WIDTH-1:0] m_axis_dequeue_resp_cpl; -wire [REQ_TAG_WIDTH-1:0] m_axis_dequeue_resp_tag; -wire [OP_TAG_WIDTH-1:0] m_axis_dequeue_resp_op_tag; -wire m_axis_dequeue_resp_empty; -wire m_axis_dequeue_resp_error; -wire m_axis_dequeue_resp_valid; -wire s_axis_dequeue_commit_ready; -wire [QUEUE_INDEX_WIDTH-1:0] m_axis_doorbell_queue; -wire m_axis_doorbell_valid; -wire s_axil_awready; -wire s_axil_wready; -wire [1:0] s_axil_bresp; -wire s_axil_bvalid; -wire s_axil_arready; -wire [AXIL_DATA_WIDTH-1:0] s_axil_rdata; -wire [1:0] s_axil_rresp; -wire s_axil_rvalid; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_dequeue_req_queue, - s_axis_dequeue_req_tag, - s_axis_dequeue_req_valid, - m_axis_dequeue_resp_ready, - s_axis_dequeue_commit_op_tag, - s_axis_dequeue_commit_valid, - s_axil_awaddr, - s_axil_awprot, - s_axil_awvalid, - s_axil_wdata, - s_axil_wstrb, - s_axil_wvalid, - s_axil_bready, - s_axil_araddr, - s_axil_arprot, - s_axil_arvalid, - s_axil_rready, - enable - ); - $to_myhdl( - s_axis_dequeue_req_ready, - m_axis_dequeue_resp_queue, - m_axis_dequeue_resp_ptr, - m_axis_dequeue_resp_addr, - m_axis_dequeue_resp_block_size, - m_axis_dequeue_resp_cpl, - m_axis_dequeue_resp_tag, - m_axis_dequeue_resp_op_tag, - m_axis_dequeue_resp_empty, - m_axis_dequeue_resp_error, - m_axis_dequeue_resp_valid, - s_axis_dequeue_commit_ready, - m_axis_doorbell_queue, - m_axis_doorbell_valid, - s_axil_awready, - s_axil_wready, - s_axil_bresp, - s_axil_bvalid, - s_axil_arready, - s_axil_rdata, - s_axil_rresp, - s_axil_rvalid - ); - - // dump file - $dumpfile("test_queue_manager.lxt"); - $dumpvars(0, test_queue_manager); -end - -queue_manager #( - .ADDR_WIDTH(ADDR_WIDTH), - .REQ_TAG_WIDTH(REQ_TAG_WIDTH), - .OP_TABLE_SIZE(OP_TABLE_SIZE), - .OP_TAG_WIDTH(OP_TAG_WIDTH), - .QUEUE_INDEX_WIDTH(QUEUE_INDEX_WIDTH), - .CPL_INDEX_WIDTH(CPL_INDEX_WIDTH), - .QUEUE_PTR_WIDTH(QUEUE_PTR_WIDTH), - .LOG_QUEUE_SIZE_WIDTH(LOG_QUEUE_SIZE_WIDTH), - .DESC_SIZE(DESC_SIZE), - .LOG_BLOCK_SIZE_WIDTH(LOG_BLOCK_SIZE_WIDTH), - .PIPELINE(PIPELINE), - .AXIL_DATA_WIDTH(AXIL_DATA_WIDTH), - .AXIL_ADDR_WIDTH(AXIL_ADDR_WIDTH), - .AXIL_STRB_WIDTH(AXIL_STRB_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_dequeue_req_queue(s_axis_dequeue_req_queue), - .s_axis_dequeue_req_tag(s_axis_dequeue_req_tag), - .s_axis_dequeue_req_valid(s_axis_dequeue_req_valid), - .s_axis_dequeue_req_ready(s_axis_dequeue_req_ready), - .m_axis_dequeue_resp_queue(m_axis_dequeue_resp_queue), - .m_axis_dequeue_resp_ptr(m_axis_dequeue_resp_ptr), - .m_axis_dequeue_resp_addr(m_axis_dequeue_resp_addr), - .m_axis_dequeue_resp_block_size(m_axis_dequeue_resp_block_size), - .m_axis_dequeue_resp_cpl(m_axis_dequeue_resp_cpl), - .m_axis_dequeue_resp_tag(m_axis_dequeue_resp_tag), - .m_axis_dequeue_resp_op_tag(m_axis_dequeue_resp_op_tag), - .m_axis_dequeue_resp_empty(m_axis_dequeue_resp_empty), - .m_axis_dequeue_resp_error(m_axis_dequeue_resp_error), - .m_axis_dequeue_resp_valid(m_axis_dequeue_resp_valid), - .m_axis_dequeue_resp_ready(m_axis_dequeue_resp_ready), - .s_axis_dequeue_commit_op_tag(s_axis_dequeue_commit_op_tag), - .s_axis_dequeue_commit_valid(s_axis_dequeue_commit_valid), - .s_axis_dequeue_commit_ready(s_axis_dequeue_commit_ready), - .m_axis_doorbell_queue(m_axis_doorbell_queue), - .m_axis_doorbell_valid(m_axis_doorbell_valid), - .s_axil_awaddr(s_axil_awaddr), - .s_axil_awprot(s_axil_awprot), - .s_axil_awvalid(s_axil_awvalid), - .s_axil_awready(s_axil_awready), - .s_axil_wdata(s_axil_wdata), - .s_axil_wstrb(s_axil_wstrb), - .s_axil_wvalid(s_axil_wvalid), - .s_axil_wready(s_axil_wready), - .s_axil_bresp(s_axil_bresp), - .s_axil_bvalid(s_axil_bvalid), - .s_axil_bready(s_axil_bready), - .s_axil_araddr(s_axil_araddr), - .s_axil_arprot(s_axil_arprot), - .s_axil_arvalid(s_axil_arvalid), - .s_axil_arready(s_axil_arready), - .s_axil_rdata(s_axil_rdata), - .s_axil_rresp(s_axil_rresp), - .s_axil_rvalid(s_axil_rvalid), - .s_axil_rready(s_axil_rready), - .enable(enable) -); - -endmodule diff --git a/fpga/common/tb/test_rx_checksum_256.py b/fpga/common/tb/test_rx_checksum_256.py deleted file mode 100755 index 948d87b48..000000000 --- a/fpga/common/tb/test_rx_checksum_256.py +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import axis_ep -import eth_ep - -module = 'rx_checksum' -testbench = 'test_%s_256' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = bytearray() - if isinstance(frame, eth_ep.EthFrame): - data = frame.payload.data - elif isinstance(frame, axis_ep.AXIStreamFrame): - data = frame.data[14:] - else: - return None - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - DATA_WIDTH = 256 - KEEP_WIDTH = (DATA_WIDTH/8) - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - s_axis_tvalid = Signal(bool(0)) - s_axis_tlast = Signal(bool(0)) - - # Outputs - m_axis_csum = Signal(intbv(0)[16:]) - m_axis_csum_valid = Signal(bool(0)) - - # sources and sinks - source_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=s_axis_tdata, - tkeep=s_axis_tkeep, - tvalid=s_axis_tvalid, - tlast=s_axis_tlast, - pause=source_pause, - name='source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=(m_axis_csum,), - tvalid=m_axis_csum_valid, - name='sink' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_tdata=s_axis_tdata, - s_axis_tkeep=s_axis_tkeep, - s_axis_tvalid=s_axis_tvalid, - s_axis_tlast=s_axis_tlast, - m_axis_csum=m_axis_csum, - m_axis_csum_valid=m_axis_csum_valid - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while s_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while s_axis_tvalid: - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - source_pause.next = True - yield clk.posedge - - source_pause.next = False - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - for payload_len in list(range(1, 128)) + list([1024, 1500, 9000, 9214]): - yield clk.posedge - print("test 1: test packet, length %d" % payload_len) - current_test.next = 1 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame) - print(hex(csum)) - - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: back-to-back packets, length %d" % payload_len) - current_test.next = 2 - - test_frame1 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray((x%256 for x in range(payload_len))) - test_frame2 = eth_ep.EthFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x8000 - test_frame2.payload = bytearray((~x%256 for x in range(payload_len))) - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame1) - source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame1) - print(hex(csum)) - - assert rx_csum == csum - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame2) - print(hex(csum)) - - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: overflow test") - current_test.next = 3 - - axis_frame = axis_ep.AXIStreamFrame(bytearray([0xff]*10240)) - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(axis_frame) - print(hex(csum)) - - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: checksum test") - current_test.next = 4 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDA0203040506 - test_frame.eth_src_mac = 0xCA0203040506 - test_frame.eth_type = 0x005a - test_frame.payload = b'\xab\xcd'+bytearray(range(20, 108)) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame) - print(hex(csum)) - - assert csum == 0x8ad8 - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_rx_checksum_256.v b/fpga/common/tb/test_rx_checksum_256.v deleted file mode 100644 index 0b757f614..000000000 --- a/fpga/common/tb/test_rx_checksum_256.v +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for rx_checksum - */ -module test_rx_checksum_256; - -// Parameters -parameter DATA_WIDTH = 256; -parameter KEEP_WIDTH = (DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [DATA_WIDTH-1:0] s_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; -reg s_axis_tvalid = 0; -reg s_axis_tlast = 0; - -// Outputs -wire [15:0] m_axis_csum; -wire m_axis_csum_valid; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_tdata, - s_axis_tkeep, - s_axis_tvalid, - s_axis_tlast - ); - $to_myhdl( - m_axis_csum, - m_axis_csum_valid - ); - - // dump file - $dumpfile("test_rx_checksum_256.lxt"); - $dumpvars(0, test_rx_checksum_256); -end - -rx_checksum #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tlast(s_axis_tlast), - .m_axis_csum(m_axis_csum), - .m_axis_csum_valid(m_axis_csum_valid) -); - -endmodule diff --git a/fpga/common/tb/test_rx_checksum_64.py b/fpga/common/tb/test_rx_checksum_64.py deleted file mode 100755 index 1f0e04cbe..000000000 --- a/fpga/common/tb/test_rx_checksum_64.py +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import axis_ep -import eth_ep - -module = 'rx_checksum' -testbench = 'test_%s_64' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = bytearray() - if isinstance(frame, eth_ep.EthFrame): - data = frame.payload.data - elif isinstance(frame, axis_ep.AXIStreamFrame): - data = frame.data[14:] - else: - return None - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - DATA_WIDTH = 64 - KEEP_WIDTH = (DATA_WIDTH/8) - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - s_axis_tvalid = Signal(bool(0)) - s_axis_tlast = Signal(bool(0)) - - # Outputs - m_axis_csum = Signal(intbv(0)[16:]) - m_axis_csum_valid = Signal(bool(0)) - - # sources and sinks - source_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=s_axis_tdata, - tkeep=s_axis_tkeep, - tvalid=s_axis_tvalid, - tlast=s_axis_tlast, - pause=source_pause, - name='source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=(m_axis_csum,), - tvalid=m_axis_csum_valid, - name='sink' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_tdata=s_axis_tdata, - s_axis_tkeep=s_axis_tkeep, - s_axis_tvalid=s_axis_tvalid, - s_axis_tlast=s_axis_tlast, - m_axis_csum=m_axis_csum, - m_axis_csum_valid=m_axis_csum_valid - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while s_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while s_axis_tvalid: - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - source_pause.next = True - yield clk.posedge - - source_pause.next = False - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - for payload_len in list(range(1, 128)) + list([1024, 1500, 9000, 9214]): - yield clk.posedge - print("test 1: test packet, length %d" % payload_len) - current_test.next = 1 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame) - print(hex(csum)) - - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: back-to-back packets, length %d" % payload_len) - current_test.next = 2 - - test_frame1 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray((x%256 for x in range(payload_len))) - test_frame2 = eth_ep.EthFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x8000 - test_frame2.payload = bytearray((~x%256 for x in range(payload_len))) - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame1) - source.send(axis_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame1) - print(hex(csum)) - - assert rx_csum == csum - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame2) - print(hex(csum)) - - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: overflow test") - current_test.next = 3 - - axis_frame = axis_ep.AXIStreamFrame(bytearray([0xff]*10240)) - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(axis_frame) - print(hex(csum)) - - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: checksum test") - current_test.next = 4 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDA0203040506 - test_frame.eth_src_mac = 0xCA0203040506 - test_frame.eth_type = 0x005a - test_frame.payload = b'\xab\xcd'+bytearray(range(20, 108)) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_csum = sink.recv().data[0][0] - print(hex(rx_csum)) - - csum = frame_checksum(test_frame) - print(hex(csum)) - - assert csum == 0x8ad8 - assert rx_csum == csum - - assert sink.empty() - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_rx_checksum_64.v b/fpga/common/tb/test_rx_checksum_64.v deleted file mode 100644 index e3f255e43..000000000 --- a/fpga/common/tb/test_rx_checksum_64.v +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for rx_checksum - */ -module test_rx_checksum_64; - -// Parameters -parameter DATA_WIDTH = 64; -parameter KEEP_WIDTH = (DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [DATA_WIDTH-1:0] s_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; -reg s_axis_tvalid = 0; -reg s_axis_tlast = 0; - -// Outputs -wire [15:0] m_axis_csum; -wire m_axis_csum_valid; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_tdata, - s_axis_tkeep, - s_axis_tvalid, - s_axis_tlast - ); - $to_myhdl( - m_axis_csum, - m_axis_csum_valid - ); - - // dump file - $dumpfile("test_rx_checksum_64.lxt"); - $dumpvars(0, test_rx_checksum_64); -end - -rx_checksum #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tlast(s_axis_tlast), - .m_axis_csum(m_axis_csum), - .m_axis_csum_valid(m_axis_csum_valid) -); - -endmodule diff --git a/fpga/common/tb/test_rx_hash_256.py b/fpga/common/tb/test_rx_hash_256.py deleted file mode 100755 index f4b91c463..000000000 --- a/fpga/common/tb/test_rx_hash_256.py +++ /dev/null @@ -1,536 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os -import ipaddress - -import axis_ep -import eth_ep -import ip_ep -import udp_ep - -module = 'rx_hash' -testbench = 'test_%s_256' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def hash_toep(data, key): - k = len(key)*8-32 - key = int.from_bytes(key, 'big') - - h = 0 - - for b in data: - for i in range(8): - if b & 0x80 >> i: - h ^= (key >> k) & 0xffffffff - k -= 1 - - return h - -def tuple_pack(src_ip, dest_ip, src_port=None, dest_port=None): - src_ip = ipaddress.ip_address(src_ip) - dest_ip = ipaddress.ip_address(dest_ip) - if src_ip.version == 6 or dest_ip.version == 6: - src_ip = int(src_ip).to_bytes(16, 'big') - dest_ip = int(dest_ip).to_bytes(16, 'big') - else: - src_ip = int(src_ip).to_bytes(4, 'big') - dest_ip = int(dest_ip).to_bytes(4, 'big') - data = src_ip+dest_ip - if src_port is not None and dest_port is not None: - data += src_port.to_bytes(2, 'big') + dest_port.to_bytes(2, 'big') - return data - -def bench(): - - # Parameters - DATA_WIDTH = 256 - KEEP_WIDTH = (DATA_WIDTH/8) - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - s_axis_tvalid = Signal(bool(0)) - s_axis_tlast = Signal(bool(0)) - hash_key = Signal(intbv(0)[40*8:]) - - # Outputs - m_axis_hash = Signal(intbv(0)[32:]) - m_axis_hash_type = Signal(intbv(0)[4:]) - m_axis_hash_valid = Signal(bool(0)) - - # sources and sinks - source_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=s_axis_tdata, - tkeep=s_axis_tkeep, - tvalid=s_axis_tvalid, - tlast=s_axis_tlast, - pause=source_pause, - name='source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=(m_axis_hash, m_axis_hash_type), - tvalid=m_axis_hash_valid, - name='sink' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_tdata=s_axis_tdata, - s_axis_tkeep=s_axis_tkeep, - s_axis_tvalid=s_axis_tvalid, - s_axis_tlast=s_axis_tlast, - hash_key=hash_key, - m_axis_hash=m_axis_hash, - m_axis_hash_type=m_axis_hash_type, - m_axis_hash_valid=m_axis_hash_valid - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while s_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while s_axis_tvalid: - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - source_pause.next = True - yield clk.posedge - - source_pause.next = False - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - key = [0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, - 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, - 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, - 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, - 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa] - - hash_key.next = int.from_bytes(key, 'big') - - for payload_len in list(range(1, 128)) + list([1024, 1500, 9000, 9214]): - yield clk.posedge - print("test 1: test raw ethernet frame, length %d" % payload_len) - current_test.next = 1 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - assert rx_hash[1] == 0b0000 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: test raw IP frame, length %d" % payload_len) - current_test.next = 2 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x1 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0001 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: test UDP frame, length %d" % payload_len) - current_test.next = 3 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip, test_frame.udp_source_port, test_frame.udp_dest_port), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b1001 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: test TCP frame, length %d" % payload_len) - current_test.next = 4 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x6 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = b'\x12\x34\x43\x21'+bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip, 0x1234, 0x4321), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0101 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 5: back-to-back frames, length %d" % payload_len) - current_test.next = 5 - - test_frame1 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x1 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame3 = udp_ep.UDPFrame() - test_frame3.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame3.eth_src_mac = 0x5A5152535455 - test_frame3.eth_type = 0x0800 - test_frame3.ip_version = 4 - test_frame3.ip_ihl = 5 - test_frame3.ip_length = None - test_frame3.ip_identification = 0 - test_frame3.ip_flags = 2 - test_frame3.ip_fragment_offset = 0 - test_frame3.ip_ttl = 64 - test_frame3.ip_protocol = 0x11 - test_frame3.ip_header_checksum = None - test_frame3.ip_source_ip = 0xc0a80164 - test_frame3.ip_dest_ip = 0xc0a80165 - test_frame3.udp_source_port = 1 - test_frame3.udp_dest_port = 2 - test_frame3.udp_length = None - test_frame3.udp_checksum = None - test_frame3.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame4 = ip_ep.IPFrame() - test_frame4.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame4.eth_src_mac = 0x5A5152535455 - test_frame4.eth_type = 0x0800 - test_frame4.ip_version = 4 - test_frame4.ip_ihl = 5 - test_frame4.ip_length = None - test_frame4.ip_identification = 0 - test_frame4.ip_flags = 2 - test_frame4.ip_fragment_offset = 0 - test_frame4.ip_ttl = 64 - test_frame4.ip_protocol = 0x6 - test_frame4.ip_header_checksum = None - test_frame4.ip_source_ip = 0xc0a80164 - test_frame4.ip_dest_ip = 0xc0a80165 - test_frame4.payload = b'\x12\x34\x43\x21'+bytearray((x%256 for x in range(payload_len))) - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - axis_frame3 = test_frame3.build_axis() - axis_frame4 = test_frame4.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame1) - source.send(axis_frame2) - source.send(axis_frame3) - source.send(axis_frame4) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - assert rx_hash[1] == 0b0000 - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame2.ip_source_ip, test_frame2.ip_dest_ip), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0001 - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame3.ip_source_ip, test_frame3.ip_dest_ip, test_frame3.udp_source_port, test_frame3.udp_dest_port), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b1001 - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame4.ip_source_ip, test_frame4.ip_dest_ip, 0x1234, 0x4321), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0101 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 6: hash test") - current_test.next = 6 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0x420995bb - test_frame.ip_dest_ip = 0xa18e6450 - test_frame.udp_source_port = 2794 - test_frame.udp_dest_port = 1766 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(128))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip, test_frame.udp_source_port, test_frame.udp_dest_port), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b1001 - assert h == 0x51ccc178 - - assert sink.empty() - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_rx_hash_256.v b/fpga/common/tb/test_rx_hash_256.v deleted file mode 100644 index b7e2d1325..000000000 --- a/fpga/common/tb/test_rx_hash_256.v +++ /dev/null @@ -1,103 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for rx_hash - */ -module test_rx_hash_256; - -// Parameters -parameter DATA_WIDTH = 256; -parameter KEEP_WIDTH = (DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [DATA_WIDTH-1:0] s_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; -reg s_axis_tvalid = 0; -reg s_axis_tlast = 0; -reg [40*8-1:0] hash_key = 0; - -// Outputs -wire [31:0] m_axis_hash; -wire [3:0] m_axis_hash_type; -wire m_axis_hash_valid; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_tdata, - s_axis_tkeep, - s_axis_tvalid, - s_axis_tlast, - hash_key - ); - $to_myhdl( - m_axis_hash, - m_axis_hash_type, - m_axis_hash_valid - ); - - // dump file - $dumpfile("test_rx_hash_256.lxt"); - $dumpvars(0, test_rx_hash_256); -end - -rx_hash #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tlast(s_axis_tlast), - .hash_key(hash_key), - .m_axis_hash(m_axis_hash), - .m_axis_hash_type(m_axis_hash_type), - .m_axis_hash_valid(m_axis_hash_valid) -); - -endmodule diff --git a/fpga/common/tb/test_rx_hash_64.py b/fpga/common/tb/test_rx_hash_64.py deleted file mode 100755 index 4ab38dc04..000000000 --- a/fpga/common/tb/test_rx_hash_64.py +++ /dev/null @@ -1,536 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os -import ipaddress - -import axis_ep -import eth_ep -import ip_ep -import udp_ep - -module = 'rx_hash' -testbench = 'test_%s_64' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def hash_toep(data, key): - k = len(key)*8-32 - key = int.from_bytes(key, 'big') - - h = 0 - - for b in data: - for i in range(8): - if b & 0x80 >> i: - h ^= (key >> k) & 0xffffffff - k -= 1 - - return h - -def tuple_pack(src_ip, dest_ip, src_port=None, dest_port=None): - src_ip = ipaddress.ip_address(src_ip) - dest_ip = ipaddress.ip_address(dest_ip) - if src_ip.version == 6 or dest_ip.version == 6: - src_ip = int(src_ip).to_bytes(16, 'big') - dest_ip = int(dest_ip).to_bytes(16, 'big') - else: - src_ip = int(src_ip).to_bytes(4, 'big') - dest_ip = int(dest_ip).to_bytes(4, 'big') - data = src_ip+dest_ip - if src_port is not None and dest_port is not None: - data += src_port.to_bytes(2, 'big') + dest_port.to_bytes(2, 'big') - return data - -def bench(): - - # Parameters - DATA_WIDTH = 64 - KEEP_WIDTH = (DATA_WIDTH/8) - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - s_axis_tvalid = Signal(bool(0)) - s_axis_tlast = Signal(bool(0)) - hash_key = Signal(intbv(0)[40*8:]) - - # Outputs - m_axis_hash = Signal(intbv(0)[32:]) - m_axis_hash_type = Signal(intbv(0)[4:]) - m_axis_hash_valid = Signal(bool(0)) - - # sources and sinks - source_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=s_axis_tdata, - tkeep=s_axis_tkeep, - tvalid=s_axis_tvalid, - tlast=s_axis_tlast, - pause=source_pause, - name='source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=(m_axis_hash, m_axis_hash_type), - tvalid=m_axis_hash_valid, - name='sink' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_tdata=s_axis_tdata, - s_axis_tkeep=s_axis_tkeep, - s_axis_tvalid=s_axis_tvalid, - s_axis_tlast=s_axis_tlast, - hash_key=hash_key, - m_axis_hash=m_axis_hash, - m_axis_hash_type=m_axis_hash_type, - m_axis_hash_valid=m_axis_hash_valid - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while s_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while s_axis_tvalid: - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - source_pause.next = True - yield clk.posedge - - source_pause.next = False - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - key = [0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, - 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, - 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, - 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, - 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa] - - hash_key.next = int.from_bytes(key, 'big') - - for payload_len in list(range(1, 128)) + list([1024, 1500, 9000, 9214]): - yield clk.posedge - print("test 1: test raw ethernet frame, length %d" % payload_len) - current_test.next = 1 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - assert rx_hash[1] == 0b0000 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: test raw IP frame, length %d" % payload_len) - current_test.next = 2 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x1 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0001 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: test UDP frame, length %d" % payload_len) - current_test.next = 3 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip, test_frame.udp_source_port, test_frame.udp_dest_port), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b1001 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: test TCP frame, length %d" % payload_len) - current_test.next = 4 - - test_frame = ip_ep.IPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x6 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.payload = b'\x12\x34\x43\x21'+bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip, 0x1234, 0x4321), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0101 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 5: back-to-back frames, length %d" % payload_len) - current_test.next = 5 - - test_frame1 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame2 = ip_ep.IPFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x0800 - test_frame2.ip_version = 4 - test_frame2.ip_ihl = 5 - test_frame2.ip_length = None - test_frame2.ip_identification = 0 - test_frame2.ip_flags = 2 - test_frame2.ip_fragment_offset = 0 - test_frame2.ip_ttl = 64 - test_frame2.ip_protocol = 0x1 - test_frame2.ip_header_checksum = None - test_frame2.ip_source_ip = 0xc0a80164 - test_frame2.ip_dest_ip = 0xc0a80165 - test_frame2.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame3 = udp_ep.UDPFrame() - test_frame3.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame3.eth_src_mac = 0x5A5152535455 - test_frame3.eth_type = 0x0800 - test_frame3.ip_version = 4 - test_frame3.ip_ihl = 5 - test_frame3.ip_length = None - test_frame3.ip_identification = 0 - test_frame3.ip_flags = 2 - test_frame3.ip_fragment_offset = 0 - test_frame3.ip_ttl = 64 - test_frame3.ip_protocol = 0x11 - test_frame3.ip_header_checksum = None - test_frame3.ip_source_ip = 0xc0a80164 - test_frame3.ip_dest_ip = 0xc0a80165 - test_frame3.udp_source_port = 1 - test_frame3.udp_dest_port = 2 - test_frame3.udp_length = None - test_frame3.udp_checksum = None - test_frame3.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame4 = ip_ep.IPFrame() - test_frame4.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame4.eth_src_mac = 0x5A5152535455 - test_frame4.eth_type = 0x0800 - test_frame4.ip_version = 4 - test_frame4.ip_ihl = 5 - test_frame4.ip_length = None - test_frame4.ip_identification = 0 - test_frame4.ip_flags = 2 - test_frame4.ip_fragment_offset = 0 - test_frame4.ip_ttl = 64 - test_frame4.ip_protocol = 0x6 - test_frame4.ip_header_checksum = None - test_frame4.ip_source_ip = 0xc0a80164 - test_frame4.ip_dest_ip = 0xc0a80165 - test_frame4.payload = b'\x12\x34\x43\x21'+bytearray((x%256 for x in range(payload_len))) - - axis_frame1 = test_frame1.build_axis() - axis_frame2 = test_frame2.build_axis() - axis_frame3 = test_frame3.build_axis() - axis_frame4 = test_frame4.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame1) - source.send(axis_frame2) - source.send(axis_frame3) - source.send(axis_frame4) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - assert rx_hash[1] == 0b0000 - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame2.ip_source_ip, test_frame2.ip_dest_ip), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0001 - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame3.ip_source_ip, test_frame3.ip_dest_ip, test_frame3.udp_source_port, test_frame3.udp_dest_port), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b1001 - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame4.ip_source_ip, test_frame4.ip_dest_ip, 0x1234, 0x4321), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b0101 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 6: hash test") - current_test.next = 6 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0x420995bb - test_frame.ip_dest_ip = 0xa18e6450 - test_frame.udp_source_port = 2794 - test_frame.udp_dest_port = 1766 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(128))) - - axis_frame = test_frame.build_axis() - - for wait in wait_normal, wait_pause_source: - source.send(axis_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_hash = sink.recv().data[0] - print(rx_hash) - - h = hash_toep(tuple_pack(test_frame.ip_source_ip, test_frame.ip_dest_ip, test_frame.udp_source_port, test_frame.udp_dest_port), key) - print(hex(h)) - - assert rx_hash[0] == h - assert rx_hash[1] == 0b1001 - assert h == 0x51ccc178 - - assert sink.empty() - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_rx_hash_64.v b/fpga/common/tb/test_rx_hash_64.v deleted file mode 100644 index 66e527d75..000000000 --- a/fpga/common/tb/test_rx_hash_64.v +++ /dev/null @@ -1,103 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for rx_hash - */ -module test_rx_hash_64; - -// Parameters -parameter DATA_WIDTH = 64; -parameter KEEP_WIDTH = (DATA_WIDTH/8); - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [DATA_WIDTH-1:0] s_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; -reg s_axis_tvalid = 0; -reg s_axis_tlast = 0; -reg [40*8-1:0] hash_key = 0; - -// Outputs -wire [31:0] m_axis_hash; -wire [3:0] m_axis_hash_type; -wire m_axis_hash_valid; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_tdata, - s_axis_tkeep, - s_axis_tvalid, - s_axis_tlast, - hash_key - ); - $to_myhdl( - m_axis_hash, - m_axis_hash_type, - m_axis_hash_valid - ); - - // dump file - $dumpfile("test_rx_hash_64.lxt"); - $dumpvars(0, test_rx_hash_64); -end - -rx_hash #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tlast(s_axis_tlast), - .hash_key(hash_key), - .m_axis_hash(m_axis_hash), - .m_axis_hash_type(m_axis_hash_type), - .m_axis_hash_valid(m_axis_hash_valid) -); - -endmodule diff --git a/fpga/common/tb/test_tdma_ber.py b/fpga/common/tb/test_tdma_ber.py deleted file mode 100755 index afb621a9e..000000000 --- a/fpga/common/tb/test_tdma_ber.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os -import struct - -import axil -import ptp - -module = 'tdma_ber' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/tdma_ber_ch.v") -srcs.append("../rtl/tdma_scheduler.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def bench(): - - # Parameters - COUNT = 2 - INDEX_WIDTH = 6 - SLICE_WIDTH = 5 - AXIL_DATA_WIDTH = 32 - AXIL_ADDR_WIDTH = INDEX_WIDTH+4+1+(COUNT-1).bit_length() - AXIL_STRB_WIDTH = (AXIL_DATA_WIDTH/8) - SCHEDULE_START_S = 0x0 - SCHEDULE_START_NS = 0x0 - SCHEDULE_PERIOD_S = 0 - SCHEDULE_PERIOD_NS = 1000000 - TIMESLOT_PERIOD_S = 0 - TIMESLOT_PERIOD_NS = 100000 - ACTIVE_PERIOD_S = 0 - ACTIVE_PERIOD_NS = 100000 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - phy_tx_clk = Signal(intbv(0)[COUNT:]) - phy_rx_clk = Signal(intbv(0)[COUNT:]) - phy_rx_error_count = Signal(intbv(0)[COUNT*7:]) - s_axil_awaddr = Signal(intbv(0)[AXIL_ADDR_WIDTH:]) - s_axil_awprot = Signal(intbv(0)[3:]) - s_axil_awvalid = Signal(bool(0)) - s_axil_wdata = Signal(intbv(0)[AXIL_DATA_WIDTH:]) - s_axil_wstrb = Signal(intbv(0)[AXIL_STRB_WIDTH:]) - s_axil_wvalid = Signal(bool(0)) - s_axil_bready = Signal(bool(0)) - s_axil_araddr = Signal(intbv(0)[AXIL_ADDR_WIDTH:]) - s_axil_arprot = Signal(intbv(0)[3:]) - s_axil_arvalid = Signal(bool(0)) - s_axil_rready = Signal(bool(0)) - ptp_ts_96 = Signal(intbv(0)[96:]) - ptp_ts_step = Signal(bool(0)) - - # Outputs - phy_tx_prbs31_enable = Signal(intbv(0)[COUNT:]) - phy_rx_prbs31_enable = Signal(intbv(0)[COUNT:]) - s_axil_awready = Signal(bool(0)) - s_axil_wready = Signal(bool(0)) - s_axil_bresp = Signal(intbv(0)[2:]) - s_axil_bvalid = Signal(bool(0)) - s_axil_arready = Signal(bool(0)) - s_axil_rdata = Signal(intbv(0)[AXIL_DATA_WIDTH:]) - s_axil_rresp = Signal(intbv(0)[2:]) - s_axil_rvalid = Signal(bool(0)) - - # AXI4-Lite master - axil_master_inst = axil.AXILiteMaster() - axil_master_pause = Signal(bool(False)) - - axil_master_logic = axil_master_inst.create_logic( - clk, - rst, - m_axil_awaddr=s_axil_awaddr, - m_axil_awprot=s_axil_awprot, - m_axil_awvalid=s_axil_awvalid, - m_axil_awready=s_axil_awready, - m_axil_wdata=s_axil_wdata, - m_axil_wstrb=s_axil_wstrb, - m_axil_wvalid=s_axil_wvalid, - m_axil_wready=s_axil_wready, - m_axil_bresp=s_axil_bresp, - m_axil_bvalid=s_axil_bvalid, - m_axil_bready=s_axil_bready, - m_axil_araddr=s_axil_araddr, - m_axil_arprot=s_axil_arprot, - m_axil_arvalid=s_axil_arvalid, - m_axil_arready=s_axil_arready, - m_axil_rdata=s_axil_rdata, - m_axil_rresp=s_axil_rresp, - m_axil_rvalid=s_axil_rvalid, - m_axil_rready=s_axil_rready, - pause=axil_master_pause, - name='master' - ) - - # PTP clock - ptp_clock = ptp.PtpClock() - - ptp_logic = ptp_clock.create_logic( - clk, - rst, - ts_96=ptp_ts_96 - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - phy_tx_clk=phy_tx_clk, - phy_rx_clk=phy_rx_clk, - phy_rx_error_count=phy_rx_error_count, - phy_tx_prbs31_enable=phy_tx_prbs31_enable, - phy_rx_prbs31_enable=phy_rx_prbs31_enable, - s_axil_awaddr=s_axil_awaddr, - s_axil_awprot=s_axil_awprot, - s_axil_awvalid=s_axil_awvalid, - s_axil_awready=s_axil_awready, - s_axil_wdata=s_axil_wdata, - s_axil_wstrb=s_axil_wstrb, - s_axil_wvalid=s_axil_wvalid, - s_axil_wready=s_axil_wready, - s_axil_bresp=s_axil_bresp, - s_axil_bvalid=s_axil_bvalid, - s_axil_bready=s_axil_bready, - s_axil_araddr=s_axil_araddr, - s_axil_arprot=s_axil_arprot, - s_axil_arvalid=s_axil_arvalid, - s_axil_arready=s_axil_arready, - s_axil_rdata=s_axil_rdata, - s_axil_rresp=s_axil_rresp, - s_axil_rvalid=s_axil_rvalid, - s_axil_rready=s_axil_rready, - ptp_ts_96=ptp_ts_96, - ptp_ts_step=ptp_ts_step - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def clkgen2(): - phy_tx_clk.next = ~phy_tx_clk - phy_rx_clk.next = ~phy_rx_clk - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - yield clk.posedge - print("test 1: Test pulse out") - current_test.next = 1 - - axil_master_inst.init_write(0x0110, struct.pack('> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - DATA_WIDTH = 256 - KEEP_WIDTH = (DATA_WIDTH/8) - ID_ENABLE = 0 - ID_WIDTH = 8 - DEST_ENABLE = 0 - DEST_WIDTH = 8 - USER_ENABLE = 1 - USER_WIDTH = 1 - USE_INIT_VALUE = 1 - DATA_FIFO_DEPTH = 4096 - CHECKSUM_FIFO_DEPTH = 4 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - s_axis_tvalid = Signal(bool(0)) - s_axis_tlast = Signal(bool(0)) - s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - m_axis_tready = Signal(bool(0)) - s_axis_cmd_csum_enable = Signal(bool(0)) - s_axis_cmd_csum_start = Signal(intbv(0)[8:]) - s_axis_cmd_csum_offset = Signal(intbv(0)[8:]) - s_axis_cmd_csum_init = Signal(intbv(0)[16:]) - s_axis_cmd_valid = Signal(bool(0)) - - # Outputs - s_axis_tready = Signal(bool(0)) - m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - m_axis_tvalid = Signal(bool(0)) - m_axis_tlast = Signal(bool(0)) - m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - s_axis_cmd_ready = Signal(bool(1)) - - # sources and sinks - source_pause = Signal(bool(0)) - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=s_axis_tdata, - tkeep=s_axis_tkeep, - tvalid=s_axis_tvalid, - tready=s_axis_tready, - tlast=s_axis_tlast, - tuser=s_axis_tuser, - pause=source_pause, - name='source' - ) - - cmd_source = axis_ep.AXIStreamSource() - - cmd_source_logic = cmd_source.create_logic( - clk, - rst, - tdata=(s_axis_cmd_csum_enable, s_axis_cmd_csum_start, s_axis_cmd_csum_offset, s_axis_cmd_csum_init), - tvalid=s_axis_cmd_valid, - tready=s_axis_cmd_ready, - name='cmd_source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=m_axis_tdata, - tkeep=m_axis_tkeep, - tvalid=m_axis_tvalid, - tready=m_axis_tready, - tlast=m_axis_tlast, - tuser=m_axis_tuser, - pause=sink_pause, - name='sink' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_tdata=s_axis_tdata, - s_axis_tkeep=s_axis_tkeep, - s_axis_tvalid=s_axis_tvalid, - s_axis_tready=s_axis_tready, - s_axis_tlast=s_axis_tlast, - s_axis_tid=s_axis_tid, - s_axis_tdest=s_axis_tdest, - s_axis_tuser=s_axis_tuser, - m_axis_tdata=m_axis_tdata, - m_axis_tkeep=m_axis_tkeep, - m_axis_tvalid=m_axis_tvalid, - m_axis_tready=m_axis_tready, - m_axis_tlast=m_axis_tlast, - m_axis_tid=m_axis_tid, - m_axis_tdest=m_axis_tdest, - m_axis_tuser=m_axis_tuser, - s_axis_cmd_csum_enable=s_axis_cmd_csum_enable, - s_axis_cmd_csum_start=s_axis_cmd_csum_start, - s_axis_cmd_csum_offset=s_axis_cmd_csum_offset, - s_axis_cmd_csum_init=s_axis_cmd_csum_init, - s_axis_cmd_valid=s_axis_cmd_valid, - s_axis_cmd_ready=s_axis_cmd_ready - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while s_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while s_axis_tvalid or m_axis_tvalid: - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - source_pause.next = True - yield clk.posedge - - source_pause.next = False - - def wait_pause_sink(): - while s_axis_tvalid or m_axis_tvalid: - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - sink_pause.next = True - yield clk.posedge - - sink_pause.next = False - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - for payload_len in list(range(1, 128)) + list([1024, 1500]): - yield clk.posedge - print("test 1: test packet, length %d" % payload_len) - current_test.next = 1 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(False, 0, 0, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: back-to-back packets, length %d" % payload_len) - current_test.next = 2 - - test_frame1 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray((x%256 for x in range(payload_len))) - test_frame2 = eth_ep.EthFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x8000 - test_frame2.payload = bytearray((~x%256 for x in range(payload_len))) - - axis_frame1 = test_frame1.build_axis() - cmd_frame1 = [(False, 0, 0, 0)] - axis_frame2 = test_frame2.build_axis() - cmd_frame2 = [(False, 0, 0, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame1) - cmd_source.send(cmd_frame1) - source.send(axis_frame2) - cmd_source.send(cmd_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: test UDP packet with zero checksum, length %d" % payload_len) - current_test.next = 3 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame.update_udp_length() - test_frame.udp_checksum = 0 - pseudo_header_checksum = test_frame.calc_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, 34, 40, pseudo_header_checksum)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(rx_frame) - - print(hex(check_frame.udp_checksum)) - print(hex(check_frame.calc_udp_checksum())) - - assert check_frame.verify_checksums() - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: test UDP packet with inline pseudo header checksum, length %d" % payload_len) - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, 34, 40, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(rx_frame) - - print(hex(check_frame.udp_checksum)) - print(hex(check_frame.calc_udp_checksum())) - - assert check_frame.verify_checksums() - - assert sink.empty() - - yield delay(100) - - for start in list(range(0, min(payload_len+14, 64))): - offset = 0 - yield clk.posedge - print("test 5: test various offsets, length %d, start %d, offset %d" % (payload_len, start, offset)) - current_test.next = 5 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, start, offset, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - csum = ~frame_checksum(axis_frame, start) & 0xffff - print(hex(csum)) - - check_data = axis_frame.data - struct.pack_into('>H', check_data, offset, csum) - - print(check_data) - print(rx_frame.data) - - yield delay(100) - - assert check_data == rx_frame.data - - assert sink.empty() - - yield delay(100) - - for offset in list(range(0, min(payload_len+14, 64)-1)): - start = 0 - yield clk.posedge - print("test 6: test various offsets, length %d, start %d, offset %d" % (payload_len, start, offset)) - current_test.next = 6 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, start, offset, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - csum = ~frame_checksum(axis_frame, start) & 0xffff - print(hex(csum)) - - check_data = axis_frame.data - struct.pack_into('>H', check_data, offset, csum) - - print(check_data) - print(rx_frame.data) - - assert check_data == rx_frame.data - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 7: backpressure test") - current_test.next = 7 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(64))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(False, 0, 0, 0)] - - sink_pause.next = 1 - - for k in range(10): - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield delay(1000) - - sink_pause.next = 0 - - for k in range(10): - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - assert sink.empty() - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_tx_checksum_256.v b/fpga/common/tb/test_tx_checksum_256.v deleted file mode 100644 index 835f21823..000000000 --- a/fpga/common/tb/test_tx_checksum_256.v +++ /dev/null @@ -1,163 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for tx_checksum - */ -module test_tx_checksum_256; - -// Parameters -parameter DATA_WIDTH = 256; -parameter KEEP_WIDTH = (DATA_WIDTH/8); -parameter ID_ENABLE = 0; -parameter ID_WIDTH = 8; -parameter DEST_ENABLE = 0; -parameter DEST_WIDTH = 8; -parameter USER_ENABLE = 1; -parameter USER_WIDTH = 1; -parameter USE_INIT_VALUE = 1; -parameter DATA_FIFO_DEPTH = 4096; -parameter CHECKSUM_FIFO_DEPTH = 4; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [DATA_WIDTH-1:0] s_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; -reg s_axis_tvalid = 0; -reg s_axis_tlast = 0; -reg [ID_WIDTH-1:0] s_axis_tid = 0; -reg [DEST_WIDTH-1:0] s_axis_tdest = 0; -reg [USER_WIDTH-1:0] s_axis_tuser = 0; -reg m_axis_tready = 0; -reg s_axis_cmd_csum_enable = 0; -reg [7:0] s_axis_cmd_csum_start = 0; -reg [7:0] s_axis_cmd_csum_offset = 0; -reg [15:0] s_axis_cmd_csum_init = 0; -reg s_axis_cmd_valid = 0; - -// Outputs -wire s_axis_tready; -wire [DATA_WIDTH-1:0] m_axis_tdata; -wire [KEEP_WIDTH-1:0] m_axis_tkeep; -wire m_axis_tvalid; -wire m_axis_tlast; -wire [ID_WIDTH-1:0] m_axis_tid; -wire [DEST_WIDTH-1:0] m_axis_tdest; -wire [USER_WIDTH-1:0] m_axis_tuser; -wire s_axis_cmd_ready; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_tdata, - s_axis_tkeep, - s_axis_tvalid, - s_axis_tlast, - s_axis_tid, - s_axis_tdest, - s_axis_tuser, - m_axis_tready, - s_axis_cmd_csum_enable, - s_axis_cmd_csum_start, - s_axis_cmd_csum_offset, - s_axis_cmd_csum_init, - s_axis_cmd_valid - ); - $to_myhdl( - s_axis_tready, - m_axis_tdata, - m_axis_tkeep, - m_axis_tvalid, - m_axis_tlast, - m_axis_tid, - m_axis_tdest, - m_axis_tuser, - s_axis_cmd_ready - ); - - // dump file - $dumpfile("test_tx_checksum_256.lxt"); - $dumpvars(0, test_tx_checksum_256); -end - -tx_checksum #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH), - .USE_INIT_VALUE(USE_INIT_VALUE), - .DATA_FIFO_DEPTH(DATA_FIFO_DEPTH), - .CHECKSUM_FIFO_DEPTH(CHECKSUM_FIFO_DEPTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tready(s_axis_tready), - .s_axis_tlast(s_axis_tlast), - .s_axis_tid(s_axis_tid), - .s_axis_tdest(s_axis_tdest), - .s_axis_tuser(s_axis_tuser), - .m_axis_tdata(m_axis_tdata), - .m_axis_tkeep(m_axis_tkeep), - .m_axis_tvalid(m_axis_tvalid), - .m_axis_tready(m_axis_tready), - .m_axis_tlast(m_axis_tlast), - .m_axis_tid(m_axis_tid), - .m_axis_tdest(m_axis_tdest), - .m_axis_tuser(m_axis_tuser), - .s_axis_cmd_csum_enable(s_axis_cmd_csum_enable), - .s_axis_cmd_csum_start(s_axis_cmd_csum_start), - .s_axis_cmd_csum_offset(s_axis_cmd_csum_offset), - .s_axis_cmd_csum_init(s_axis_cmd_csum_init), - .s_axis_cmd_valid(s_axis_cmd_valid), - .s_axis_cmd_ready(s_axis_cmd_ready) -); - -endmodule diff --git a/fpga/common/tb/test_tx_checksum_64.py b/fpga/common/tb/test_tx_checksum_64.py deleted file mode 100755 index 1f3aa94f4..000000000 --- a/fpga/common/tb/test_tx_checksum_64.py +++ /dev/null @@ -1,571 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import struct - -import axis_ep -import eth_ep -import udp_ep - -module = 'tx_checksum' -testbench = 'test_%s_64' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame, offset=14): - data = bytearray() - if isinstance(frame, eth_ep.EthFrame): - data = frame.payload.data[offset-14:] - elif isinstance(frame, axis_ep.AXIStreamFrame): - data = frame.data[offset:] - else: - return None - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - DATA_WIDTH = 64 - KEEP_WIDTH = (DATA_WIDTH/8) - ID_ENABLE = 0 - ID_WIDTH = 8 - DEST_ENABLE = 0 - DEST_WIDTH = 8 - USER_ENABLE = 1 - USER_WIDTH = 1 - USE_INIT_VALUE = 1 - DATA_FIFO_DEPTH = 4096 - CHECKSUM_FIFO_DEPTH = 4 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - s_axis_tvalid = Signal(bool(0)) - s_axis_tlast = Signal(bool(0)) - s_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - s_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - s_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - m_axis_tready = Signal(bool(0)) - s_axis_cmd_csum_enable = Signal(bool(0)) - s_axis_cmd_csum_start = Signal(intbv(0)[8:]) - s_axis_cmd_csum_offset = Signal(intbv(0)[8:]) - s_axis_cmd_csum_init = Signal(intbv(0)[16:]) - s_axis_cmd_valid = Signal(bool(0)) - - # Outputs - s_axis_tready = Signal(bool(0)) - m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) - m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) - m_axis_tvalid = Signal(bool(0)) - m_axis_tlast = Signal(bool(0)) - m_axis_tid = Signal(intbv(0)[ID_WIDTH:]) - m_axis_tdest = Signal(intbv(0)[DEST_WIDTH:]) - m_axis_tuser = Signal(intbv(0)[USER_WIDTH:]) - s_axis_cmd_ready = Signal(bool(1)) - - # sources and sinks - source_pause = Signal(bool(0)) - sink_pause = Signal(bool(0)) - - source = axis_ep.AXIStreamSource() - - source_logic = source.create_logic( - clk, - rst, - tdata=s_axis_tdata, - tkeep=s_axis_tkeep, - tvalid=s_axis_tvalid, - tready=s_axis_tready, - tlast=s_axis_tlast, - tuser=s_axis_tuser, - pause=source_pause, - name='source' - ) - - cmd_source = axis_ep.AXIStreamSource() - - cmd_source_logic = cmd_source.create_logic( - clk, - rst, - tdata=(s_axis_cmd_csum_enable, s_axis_cmd_csum_start, s_axis_cmd_csum_offset, s_axis_cmd_csum_init), - tvalid=s_axis_cmd_valid, - tready=s_axis_cmd_ready, - name='cmd_source' - ) - - sink = axis_ep.AXIStreamSink() - - sink_logic = sink.create_logic( - clk, - rst, - tdata=m_axis_tdata, - tkeep=m_axis_tkeep, - tvalid=m_axis_tvalid, - tready=m_axis_tready, - tlast=m_axis_tlast, - tuser=m_axis_tuser, - pause=sink_pause, - name='sink' - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - s_axis_tdata=s_axis_tdata, - s_axis_tkeep=s_axis_tkeep, - s_axis_tvalid=s_axis_tvalid, - s_axis_tready=s_axis_tready, - s_axis_tlast=s_axis_tlast, - s_axis_tid=s_axis_tid, - s_axis_tdest=s_axis_tdest, - s_axis_tuser=s_axis_tuser, - m_axis_tdata=m_axis_tdata, - m_axis_tkeep=m_axis_tkeep, - m_axis_tvalid=m_axis_tvalid, - m_axis_tready=m_axis_tready, - m_axis_tlast=m_axis_tlast, - m_axis_tid=m_axis_tid, - m_axis_tdest=m_axis_tdest, - m_axis_tuser=m_axis_tuser, - s_axis_cmd_csum_enable=s_axis_cmd_csum_enable, - s_axis_cmd_csum_start=s_axis_cmd_csum_start, - s_axis_cmd_csum_offset=s_axis_cmd_csum_offset, - s_axis_cmd_csum_init=s_axis_cmd_csum_init, - s_axis_cmd_valid=s_axis_cmd_valid, - s_axis_cmd_ready=s_axis_cmd_ready - ) - - @always(delay(4)) - def clkgen(): - clk.next = not clk - - def wait_normal(): - while s_axis_tvalid: - yield clk.posedge - - def wait_pause_source(): - while s_axis_tvalid or m_axis_tvalid: - yield clk.posedge - yield clk.posedge - source_pause.next = False - yield clk.posedge - source_pause.next = True - yield clk.posedge - - source_pause.next = False - - def wait_pause_sink(): - while s_axis_tvalid or m_axis_tvalid: - yield clk.posedge - yield clk.posedge - sink_pause.next = False - yield clk.posedge - sink_pause.next = True - yield clk.posedge - - sink_pause.next = False - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - for payload_len in list(range(1, 128)) + list([1024, 1500]): - yield clk.posedge - print("test 1: test packet, length %d" % payload_len) - current_test.next = 1 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(False, 0, 0, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 2: back-to-back packets, length %d" % payload_len) - current_test.next = 2 - - test_frame1 = eth_ep.EthFrame() - test_frame1.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame1.eth_src_mac = 0x5A5152535455 - test_frame1.eth_type = 0x8000 - test_frame1.payload = bytearray((x%256 for x in range(payload_len))) - test_frame2 = eth_ep.EthFrame() - test_frame2.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame2.eth_src_mac = 0x5A5152535455 - test_frame2.eth_type = 0x8000 - test_frame2.payload = bytearray((~x%256 for x in range(payload_len))) - - axis_frame1 = test_frame1.build_axis() - cmd_frame1 = [(False, 0, 0, 0)] - axis_frame2 = test_frame2.build_axis() - cmd_frame2 = [(False, 0, 0, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame1) - cmd_source.send(cmd_frame1) - source.send(axis_frame2) - cmd_source.send(cmd_frame2) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame1 - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame2 - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 3: test UDP packet with zero checksum, length %d" % payload_len) - current_test.next = 3 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame.update_udp_length() - test_frame.udp_checksum = 0 - pseudo_header_checksum = test_frame.calc_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, 34, 40, pseudo_header_checksum)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(rx_frame) - - print(hex(check_frame.udp_checksum)) - print(hex(check_frame.calc_udp_checksum())) - - assert check_frame.verify_checksums() - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 4: test UDP packet with inline pseudo header checksum, length %d" % payload_len) - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, 34, 40, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(rx_frame) - - print(hex(check_frame.udp_checksum)) - print(hex(check_frame.calc_udp_checksum())) - - assert check_frame.verify_checksums() - - assert sink.empty() - - yield delay(100) - - for start in list(range(0, min(payload_len+14, 64))): - offset = 0 - yield clk.posedge - print("test 5: test various offsets, length %d, start %d, offset %d" % (payload_len, start, offset)) - current_test.next = 5 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, start, offset, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - csum = ~frame_checksum(axis_frame, start) & 0xffff - print(hex(csum)) - - check_data = axis_frame.data - struct.pack_into('>H', check_data, offset, csum) - - print(check_data) - print(rx_frame.data) - - yield delay(100) - - assert check_data == rx_frame.data - - assert sink.empty() - - yield delay(100) - - for offset in list(range(0, min(payload_len+14, 64)-1)): - start = 0 - yield clk.posedge - print("test 6: test various offsets, length %d, start %d, offset %d" % (payload_len, start, offset)) - current_test.next = 6 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(payload_len))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(True, start, offset, 0)] - - for wait in wait_normal, wait_pause_source, wait_pause_sink: - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield wait() - - yield sink.wait() - rx_frame = sink.recv() - - csum = ~frame_checksum(axis_frame, start) & 0xffff - print(hex(csum)) - - check_data = axis_frame.data - struct.pack_into('>H', check_data, offset, csum) - - print(check_data) - print(rx_frame.data) - - assert check_data == rx_frame.data - - assert sink.empty() - - yield delay(100) - - yield clk.posedge - print("test 7: backpressure test") - current_test.next = 7 - - test_frame = eth_ep.EthFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x8000 - test_frame.payload = bytearray((x%256 for x in range(64))) - - axis_frame = test_frame.build_axis() - cmd_frame = [(False, 0, 0, 0)] - - sink_pause.next = 1 - - for k in range(10): - source.send(axis_frame) - cmd_source.send(cmd_frame) - yield clk.posedge - yield clk.posedge - - yield delay(1000) - - sink_pause.next = 0 - - for k in range(10): - yield sink.wait() - rx_frame = sink.recv() - - check_frame = eth_ep.EthFrame() - check_frame.parse_axis(rx_frame) - - assert check_frame == test_frame - - assert sink.empty() - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/common/tb/test_tx_checksum_64.v b/fpga/common/tb/test_tx_checksum_64.v deleted file mode 100644 index 8cf2e960c..000000000 --- a/fpga/common/tb/test_tx_checksum_64.v +++ /dev/null @@ -1,163 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for tx_checksum - */ -module test_tx_checksum_64; - -// Parameters -parameter DATA_WIDTH = 64; -parameter KEEP_WIDTH = (DATA_WIDTH/8); -parameter ID_ENABLE = 0; -parameter ID_WIDTH = 8; -parameter DEST_ENABLE = 0; -parameter DEST_WIDTH = 8; -parameter USER_ENABLE = 1; -parameter USER_WIDTH = 1; -parameter USE_INIT_VALUE = 1; -parameter DATA_FIFO_DEPTH = 4096; -parameter CHECKSUM_FIFO_DEPTH = 4; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg [DATA_WIDTH-1:0] s_axis_tdata = 0; -reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; -reg s_axis_tvalid = 0; -reg s_axis_tlast = 0; -reg [ID_WIDTH-1:0] s_axis_tid = 0; -reg [DEST_WIDTH-1:0] s_axis_tdest = 0; -reg [USER_WIDTH-1:0] s_axis_tuser = 0; -reg m_axis_tready = 0; -reg s_axis_cmd_csum_enable = 0; -reg [7:0] s_axis_cmd_csum_start = 0; -reg [7:0] s_axis_cmd_csum_offset = 0; -reg [15:0] s_axis_cmd_csum_init = 0; -reg s_axis_cmd_valid = 0; - -// Outputs -wire s_axis_tready; -wire [DATA_WIDTH-1:0] m_axis_tdata; -wire [KEEP_WIDTH-1:0] m_axis_tkeep; -wire m_axis_tvalid; -wire m_axis_tlast; -wire [ID_WIDTH-1:0] m_axis_tid; -wire [DEST_WIDTH-1:0] m_axis_tdest; -wire [USER_WIDTH-1:0] m_axis_tuser; -wire s_axis_cmd_ready; - -initial begin - // myhdl integration - $from_myhdl( - clk, - rst, - current_test, - s_axis_tdata, - s_axis_tkeep, - s_axis_tvalid, - s_axis_tlast, - s_axis_tid, - s_axis_tdest, - s_axis_tuser, - m_axis_tready, - s_axis_cmd_csum_enable, - s_axis_cmd_csum_start, - s_axis_cmd_csum_offset, - s_axis_cmd_csum_init, - s_axis_cmd_valid - ); - $to_myhdl( - s_axis_tready, - m_axis_tdata, - m_axis_tkeep, - m_axis_tvalid, - m_axis_tlast, - m_axis_tid, - m_axis_tdest, - m_axis_tuser, - s_axis_cmd_ready - ); - - // dump file - $dumpfile("test_tx_checksum_64.lxt"); - $dumpvars(0, test_tx_checksum_64); -end - -tx_checksum #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_WIDTH(KEEP_WIDTH), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH), - .USE_INIT_VALUE(USE_INIT_VALUE), - .DATA_FIFO_DEPTH(DATA_FIFO_DEPTH), - .CHECKSUM_FIFO_DEPTH(CHECKSUM_FIFO_DEPTH) -) -UUT ( - .clk(clk), - .rst(rst), - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tready(s_axis_tready), - .s_axis_tlast(s_axis_tlast), - .s_axis_tid(s_axis_tid), - .s_axis_tdest(s_axis_tdest), - .s_axis_tuser(s_axis_tuser), - .m_axis_tdata(m_axis_tdata), - .m_axis_tkeep(m_axis_tkeep), - .m_axis_tvalid(m_axis_tvalid), - .m_axis_tready(m_axis_tready), - .m_axis_tlast(m_axis_tlast), - .m_axis_tid(m_axis_tid), - .m_axis_tdest(m_axis_tdest), - .m_axis_tuser(m_axis_tuser), - .s_axis_cmd_csum_enable(s_axis_cmd_csum_enable), - .s_axis_cmd_csum_start(s_axis_cmd_csum_start), - .s_axis_cmd_csum_offset(s_axis_cmd_csum_offset), - .s_axis_cmd_csum_init(s_axis_cmd_csum_init), - .s_axis_cmd_valid(s_axis_cmd_valid), - .s_axis_cmd_ready(s_axis_cmd_ready) -); - -endmodule diff --git a/fpga/common/tb/tx_checksum/Makefile b/fpga/common/tb/tx_checksum/Makefile new file mode 100644 index 000000000..6a61c96e8 --- /dev/null +++ b/fpga/common/tb/tx_checksum/Makefile @@ -0,0 +1,112 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = tx_checksum +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v + +# module parameters +export PARAM_DATA_WIDTH ?= 64 +export PARAM_KEEP_WIDTH ?= $(shell expr $(PARAM_DATA_WIDTH) / 8 ) +export PARAM_ID_ENABLE = 0 +export PARAM_ID_WIDTH = 8 +export PARAM_DEST_ENABLE = 0 +export PARAM_DEST_WIDTH = 8 +export PARAM_USER_ENABLE = 1 +export PARAM_USER_WIDTH = 1 +export PARAM_USE_INIT_VALUE = 1 +export PARAM_DATA_FIFO_DEPTH = 16384 +export PARAM_CHECKSUM_FIFO_DEPTH = 4 + +SIM_BUILD ?= sim_build_$(MODULE)-$(PARAM_DATA_WIDTH) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).DATA_WIDTH=$(PARAM_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).KEEP_WIDTH=$(PARAM_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).ID_ENABLE=$(PARAM_ID_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).ID_WIDTH=$(PARAM_ID_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).DEST_ENABLE=$(PARAM_DEST_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).DEST_WIDTH=$(PARAM_DEST_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).USER_ENABLE=$(PARAM_USER_ENABLE) + COMPILE_ARGS += -P $(TOPLEVEL).USER_WIDTH=$(PARAM_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).USE_INIT_VALUE=$(PARAM_USE_INIT_VALUE) + COMPILE_ARGS += -P $(TOPLEVEL).DATA_FIFO_DEPTH=$(PARAM_DATA_FIFO_DEPTH) + COMPILE_ARGS += -P $(TOPLEVEL).CHECKSUM_FIFO_DEPTH=$(PARAM_CHECKSUM_FIFO_DEPTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GDATA_WIDTH=$(PARAM_DATA_WIDTH) + COMPILE_ARGS += -GKEEP_WIDTH=$(PARAM_KEEP_WIDTH) + COMPILE_ARGS += -GID_ENABLE=$(PARAM_ID_ENABLE) + COMPILE_ARGS += -GID_WIDTH=$(PARAM_ID_WIDTH) + COMPILE_ARGS += -GDEST_ENABLE=$(PARAM_DEST_ENABLE) + COMPILE_ARGS += -GDEST_WIDTH=$(PARAM_DEST_WIDTH) + COMPILE_ARGS += -GUSER_ENABLE=$(PARAM_USER_ENABLE) + COMPILE_ARGS += -GUSER_WIDTH=$(PARAM_USER_WIDTH) + COMPILE_ARGS += -GUSE_INIT_VALUE=$(PARAM_USE_INIT_VALUE) + COMPILE_ARGS += -GDATA_FIFO_DEPTH=$(PARAM_DATA_FIFO_DEPTH) + COMPILE_ARGS += -GCHECKSUM_FIFO_DEPTH=$(PARAM_CHECKSUM_FIFO_DEPTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/common/tb/tx_checksum/test_tx_checksum.py b/fpga/common/tb/tx_checksum/test_tx_checksum.py new file mode 100644 index 000000000..793d95bfa --- /dev/null +++ b/fpga/common/tb/tx_checksum/test_tx_checksum.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import itertools +import logging +import os +import struct + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator +import pytest + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiStreamFrame, AxiStreamSource, AxiStreamSink +from cocotbext.axi.stream import define_stream + + +CsumCmdTransaction, CsumCmdSource, CsumCmdSink, CsumCmdMonitor = define_stream("CsumCmd", + signals=["csum_enable", "csum_start", "csum_offset", "csum_init", "valid"], + optional_signals=["ready"] +) + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.fork(Clock(dut.clk, 4, units="ns").start()) + + self.source = AxiStreamSource(dut, "s_axis", dut.clk, dut.rst) + self.sink = AxiStreamSink(dut, "m_axis", dut.clk, dut.rst) + + self.cmd_source = CsumCmdSource(dut, "s_axis_cmd", dut.clk, dut.rst) + + def set_idle_generator(self, generator=None): + if generator: + self.source.set_pause_generator(generator()) + + def set_backpressure_generator(self, generator=None): + if generator: + self.sink.set_pause_generator(generator()) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst <= 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test(dut, payload_lengths=None, payload_data=None, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + await tb.reset() + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + test_pkts = [] + test_frames = [] + + ip_id = 1 + + for payload in [payload_data(x) for x in payload_lengths()]: + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101', id=ip_id) + udp = UDP(sport=1234, dport=4321) + test_pkt = eth / ip / udp / payload + + ip_id = (ip_id + 1) & 0xffff + + # don't compute checksum + test_pkts.append(test_pkt.copy()) + test_frame = AxiStreamFrame(test_pkt.build()) + test_frames.append(test_frame) + + tb.source.send(test_frame) + tb.cmd_source.send(CsumCmdTransaction(csum_enable=0, csum_start=34, csum_offset=40, csum_init=0)) + + # inline partial checksum + test_pkts.append(test_pkt.copy()) + + pkt = test_pkt.copy() + partial_csum = scapy.utils.checksum(bytes(pkt[UDP])) + pkt[UDP].chksum = partial_csum + + test_frame = AxiStreamFrame(pkt.build()) + test_frames.append(test_frame) + + tb.source.send(test_frame) + tb.cmd_source.send(CsumCmdTransaction(csum_enable=1, csum_start=34, csum_offset=40, csum_init=0)) + + # partial checksum in command + test_pkts.append(test_pkt.copy()) + + pkt = test_pkt.copy() + partial_csum = scapy.utils.checksum(bytes(pkt[UDP])) + pkt[UDP].chksum = 0 + + test_frame = AxiStreamFrame(pkt.build()) + test_frames.append(test_frame) + + tb.source.send(test_frame) + tb.cmd_source.send(CsumCmdTransaction(csum_enable=1, csum_start=34, csum_offset=40, csum_init=partial_csum)) + + for test_pkt, test_frame in zip(test_pkts, test_frames): + await tb.sink.wait() + rx_frame = tb.sink.recv() + + rx_pkt = Ether(bytes(rx_frame)) + + tb.log.info("RX packet: %s", repr(rx_pkt)) + + check_pkt = Ether(test_pkt.build()) + + tb.log.info("RX packet UDP checksum: 0x%04x (expected 0x%04x)", rx_pkt[UDP].chksum, check_pkt[UDP].chksum) + + assert check_pkt == rx_pkt + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_offsets(dut, payload_lengths=None, payload_data=None, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + await tb.reset() + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + test_pkts = [] + test_frames = [] + check_frames = [] + + ip_id = 1 + + for payload in [payload_data(x) for x in payload_lengths()]: + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + test_pkt = eth / payload + + ip_id = (ip_id + 1) & 0xffff + + for start in range(0, min(len(payload)+14, 32)): + offset = 0 + test_pkts.append(test_pkt.copy()) + test_frame = AxiStreamFrame(test_pkt.build()) + test_frames.append(test_frame) + + tb.source.send(test_frame) + tb.cmd_source.send(CsumCmdTransaction(csum_enable=1, csum_start=start, csum_offset=offset, csum_init=0)) + + csum = scapy.utils.checksum(bytes(test_pkt)[start:]) + + check_frame = bytearray(test_frame.tdata) + struct.pack_into('>H', check_frame, offset, csum) + + check_frames.append(check_frame) + + for offset in range(0, min(len(payload)+14, 32)-1): + start = 0 + test_pkts.append(test_pkt.copy()) + test_frame = AxiStreamFrame(test_pkt.build()) + test_frames.append(test_frame) + + tb.source.send(test_frame) + tb.cmd_source.send(CsumCmdTransaction(csum_enable=1, csum_start=start, csum_offset=offset, csum_init=0)) + + csum = scapy.utils.checksum(bytes(test_pkt)[start:]) + + check_frame = bytearray(test_frame.tdata) + struct.pack_into('>H', check_frame, offset, csum) + + check_frames.append(check_frame) + + for test_pkt, test_frame, check_frame in zip(test_pkts, test_frames, check_frames): + await tb.sink.wait() + rx_frame = tb.sink.recv() + + rx_pkt = Ether(bytes(rx_frame)) + + tb.log.info("RX packet: %s", repr(rx_pkt)) + + assert rx_frame.tdata == check_frame + + assert tb.sink.empty() + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +def cycle_pause(): + return itertools.cycle([1, 1, 1, 0]) + + +def size_list(): + return list(range(1, 128)) + [512, 1472, 9172] + [18]*10 + + +def size_list2(): + return list(range(1, 64)) + + +def incrementing_payload(length): + return bytes(itertools.islice(itertools.cycle(range(256)), length)) + + +if cocotb.SIM_NAME: + + # for test in [run_test, run_test_offsets]: + + # factory = TestFactory(run_test) + # factory.add_option("payload_lengths", [size_list]) + # factory.add_option("payload_data", [incrementing_payload]) + # factory.add_option("idle_inserter", [None, cycle_pause]) + # factory.add_option("backpressure_inserter", [None, cycle_pause]) + # factory.generate_tests() + + factory = TestFactory(run_test) + factory.add_option("payload_lengths", [size_list]) + factory.add_option("payload_data", [incrementing_payload]) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.add_option("backpressure_inserter", [None, cycle_pause]) + factory.generate_tests() + + factory = TestFactory(run_test_offsets) + factory.add_option("payload_lengths", [size_list2]) + factory.add_option("payload_data", [incrementing_payload]) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.add_option("backpressure_inserter", [None, cycle_pause]) + factory.generate_tests() + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +@pytest.mark.parametrize("data_width", [64, 256]) +def test_tx_checksum(request, data_width): + dut = "tx_checksum" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + ] + + parameters = {} + + parameters['DATA_WIDTH'] = data_width + parameters['KEEP_WIDTH'] = parameters['DATA_WIDTH'] // 8 + parameters['ID_ENABLE'] = 0 + parameters['ID_WIDTH'] = 8 + parameters['DEST_ENABLE'] = 0 + parameters['DEST_WIDTH'] = 8 + parameters['USER_ENABLE'] = 1 + parameters['USER_WIDTH'] = 1 + parameters['USE_INIT_VALUE'] = 1 + parameters['DATA_FIFO_DEPTH'] = 16384 + parameters['CHECKSUM_FIFO_DEPTH'] = 4 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/common/tb/udp_ep.py b/fpga/common/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/common/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/common/tb/xgmii_ep.py b/fpga/common/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/common/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/axis_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/eth_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..1b6b1b200 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..30b89c1c5 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,587 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk, 3.102, units="ns").start()) + self.qsfp_0_source = AxiStreamSource(dut, "qsfp_0_rx_axis", dut.qsfp_0_rx_clk, dut.qsfp_0_rx_rst) + cocotb.fork(Clock(dut.qsfp_0_tx_clk, 3.102, units="ns").start()) + self.qsfp_0_sink = AxiStreamSink(dut, "qsfp_0_tx_axis", dut.qsfp_0_tx_clk, dut.qsfp_0_tx_rst) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk, 3.102, units="ns").start()) + self.qsfp_1_source = AxiStreamSource(dut, "qsfp_1_rx_axis", dut.qsfp_1_rx_clk, dut.qsfp_1_rx_rst) + cocotb.fork(Clock(dut.qsfp_1_tx_clk, 3.102, units="ns").start()) + self.qsfp_1_sink = AxiStreamSink(dut, "qsfp_1_tx_axis", dut.qsfp_1_tx_clk, dut.qsfp_1_tx_rst) + + dut.user_sw.setimmediatevalue(0) + + dut.qsfp_0_modprs_l.setimmediatevalue(0) + dut.qsfp_1_modprs_l.setimmediatevalue(0) + + dut.qsfp_int_l.setimmediatevalue(1) + dut.qsfp_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_sink.empty(): + self.qsfp_0_source.send(self.qsfp_0_sink.recv()) + if not self.qsfp_1_sink.empty(): + self.qsfp_1_source.send(self.qsfp_1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_sink.wait() + + pkt = tb.qsfp_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_sink.wait() + + pkt = tb.qsfp_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = int(parameters['AXIS_PCIE_DATA_WIDTH']/32) + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/ip_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/mqnic.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie_us.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index a9cb5ef45..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,957 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - user_sw = Signal(intbv(0)[2:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk = Signal(bool(0)) - qsfp_0_tx_rst = Signal(bool(0)) - qsfp_0_rx_clk = Signal(bool(0)) - qsfp_0_rx_rst = Signal(bool(0)) - qsfp_0_tx_axis_tready = Signal(bool(0)) - qsfp_0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_0_rx_axis_tvalid = Signal(bool(0)) - qsfp_0_rx_axis_tlast = Signal(bool(0)) - qsfp_0_rx_axis_tuser = Signal(bool(0)) - qsfp_0_modprs_l = Signal(bool(0)) - qsfp_1_tx_clk = Signal(bool(0)) - qsfp_1_tx_rst = Signal(bool(0)) - qsfp_1_rx_clk = Signal(bool(0)) - qsfp_1_rx_rst = Signal(bool(0)) - qsfp_1_tx_axis_tready = Signal(bool(0)) - qsfp_1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_1_rx_axis_tvalid = Signal(bool(0)) - qsfp_1_rx_axis_tlast = Signal(bool(0)) - qsfp_1_rx_axis_tuser = Signal(bool(0)) - qsfp_1_modprs_l = Signal(bool(0)) - qsfp_int_l = Signal(bool(0)) - qsfp_i2c_scl_i = Signal(bool(1)) - qsfp_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - user_led_g = Signal(intbv(0)[2:]) - user_led_r = Signal(bool(0)) - front_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_0_tx_axis_tvalid = Signal(bool(0)) - qsfp_0_tx_axis_tlast = Signal(bool(0)) - qsfp_0_tx_axis_tuser = Signal(bool(0)) - qsfp_0_sel_l = Signal(bool(1)) - qsfp_1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_1_tx_axis_tvalid = Signal(bool(0)) - qsfp_1_tx_axis_tlast = Signal(bool(0)) - qsfp_1_tx_axis_tuser = Signal(bool(0)) - qsfp_1_sel_l = Signal(bool(1)) - qsfp_reset_l = Signal(bool(1)) - qsfp_i2c_scl_o = Signal(bool(1)) - qsfp_i2c_scl_t = Signal(bool(1)) - qsfp_i2c_sda_o = Signal(bool(1)) - qsfp_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - eeprom_wp = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp_0_source = axis_ep.AXIStreamSource() - qsfp_0_source_pause = Signal(bool(False)) - - qsfp_0_source_logic = qsfp_0_source.create_logic( - qsfp_0_rx_clk, - qsfp_0_rx_rst, - tdata=qsfp_0_rx_axis_tdata, - tkeep=qsfp_0_rx_axis_tkeep, - tvalid=qsfp_0_rx_axis_tvalid, - tlast=qsfp_0_rx_axis_tlast, - tuser=qsfp_0_rx_axis_tuser, - pause=qsfp_0_source_pause, - name='qsfp_0_source' - ) - - qsfp_0_sink = axis_ep.AXIStreamSink() - qsfp_0_sink_pause = Signal(bool(False)) - - qsfp_0_sink_logic = qsfp_0_sink.create_logic( - qsfp_0_tx_clk, - qsfp_0_tx_rst, - tdata=qsfp_0_tx_axis_tdata, - tkeep=qsfp_0_tx_axis_tkeep, - tvalid=qsfp_0_tx_axis_tvalid, - tready=qsfp_0_tx_axis_tready, - tlast=qsfp_0_tx_axis_tlast, - tuser=qsfp_0_tx_axis_tuser, - pause=qsfp_0_sink_pause, - name='qsfp_0_sink' - ) - - qsfp_1_source = axis_ep.AXIStreamSource() - qsfp_1_source_pause = Signal(bool(False)) - - qsfp_1_source_logic = qsfp_1_source.create_logic( - qsfp_1_rx_clk, - qsfp_1_rx_rst, - tdata=qsfp_1_rx_axis_tdata, - tkeep=qsfp_1_rx_axis_tkeep, - tvalid=qsfp_1_rx_axis_tvalid, - tlast=qsfp_1_rx_axis_tlast, - tuser=qsfp_1_rx_axis_tuser, - pause=qsfp_1_source_pause, - name='qsfp_1_source' - ) - - qsfp_1_sink = axis_ep.AXIStreamSink() - qsfp_1_sink_pause = Signal(bool(False)) - - qsfp_1_sink_logic = qsfp_1_sink.create_logic( - qsfp_1_tx_clk, - qsfp_1_tx_rst, - tdata=qsfp_1_tx_axis_tdata, - tkeep=qsfp_1_tx_axis_tkeep, - tvalid=qsfp_1_tx_axis_tvalid, - tready=qsfp_1_tx_axis_tready, - tlast=qsfp_1_tx_axis_tlast, - tuser=qsfp_1_tx_axis_tuser, - pause=qsfp_1_sink_pause, - name='qsfp_1_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - user_led_g=user_led_g, - user_led_r=user_led_r, - front_led=front_led, - user_sw=user_sw, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk=qsfp_0_tx_clk, - qsfp_0_tx_rst=qsfp_0_tx_rst, - qsfp_0_tx_axis_tdata=qsfp_0_tx_axis_tdata, - qsfp_0_tx_axis_tkeep=qsfp_0_tx_axis_tkeep, - qsfp_0_tx_axis_tvalid=qsfp_0_tx_axis_tvalid, - qsfp_0_tx_axis_tready=qsfp_0_tx_axis_tready, - qsfp_0_tx_axis_tlast=qsfp_0_tx_axis_tlast, - qsfp_0_tx_axis_tuser=qsfp_0_tx_axis_tuser, - qsfp_0_rx_clk=qsfp_0_rx_clk, - qsfp_0_rx_rst=qsfp_0_rx_rst, - qsfp_0_rx_axis_tdata=qsfp_0_rx_axis_tdata, - qsfp_0_rx_axis_tkeep=qsfp_0_rx_axis_tkeep, - qsfp_0_rx_axis_tvalid=qsfp_0_rx_axis_tvalid, - qsfp_0_rx_axis_tlast=qsfp_0_rx_axis_tlast, - qsfp_0_rx_axis_tuser=qsfp_0_rx_axis_tuser, - qsfp_0_modprs_l=qsfp_0_modprs_l, - qsfp_0_sel_l=qsfp_0_sel_l, - qsfp_1_tx_clk=qsfp_1_tx_clk, - qsfp_1_tx_rst=qsfp_1_tx_rst, - qsfp_1_tx_axis_tdata=qsfp_1_tx_axis_tdata, - qsfp_1_tx_axis_tkeep=qsfp_1_tx_axis_tkeep, - qsfp_1_tx_axis_tvalid=qsfp_1_tx_axis_tvalid, - qsfp_1_tx_axis_tready=qsfp_1_tx_axis_tready, - qsfp_1_tx_axis_tlast=qsfp_1_tx_axis_tlast, - qsfp_1_tx_axis_tuser=qsfp_1_tx_axis_tuser, - qsfp_1_rx_clk=qsfp_1_rx_clk, - qsfp_1_rx_rst=qsfp_1_rx_rst, - qsfp_1_rx_axis_tdata=qsfp_1_rx_axis_tdata, - qsfp_1_rx_axis_tkeep=qsfp_1_rx_axis_tkeep, - qsfp_1_rx_axis_tvalid=qsfp_1_rx_axis_tvalid, - qsfp_1_rx_axis_tlast=qsfp_1_rx_axis_tlast, - qsfp_1_rx_axis_tuser=qsfp_1_rx_axis_tuser, - qsfp_1_modprs_l=qsfp_1_modprs_l, - qsfp_1_sel_l=qsfp_1_sel_l, - qsfp_reset_l=qsfp_reset_l, - qsfp_int_l=qsfp_int_l, - qsfp_i2c_scl_i=qsfp_i2c_scl_i, - qsfp_i2c_scl_o=qsfp_i2c_scl_o, - qsfp_i2c_scl_t=qsfp_i2c_scl_t, - qsfp_i2c_sda_i=qsfp_i2c_sda_i, - qsfp_i2c_sda_o=qsfp_i2c_sda_o, - qsfp_i2c_sda_t=qsfp_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - eeprom_wp=eeprom_wp, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp_0_tx_clk.next = not qsfp_0_tx_clk - qsfp_0_rx_clk.next = not qsfp_0_rx_clk - qsfp_1_tx_clk.next = not qsfp_1_tx_clk - qsfp_1_rx_clk.next = not qsfp_1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_sink.empty(): - pkt = qsfp_0_sink.recv() - qsfp_0_source.send(pkt) - if not qsfp_1_sink.empty(): - pkt = qsfp_1_sink.recv() - qsfp_1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst.next = 1 - qsfp_0_rx_rst.next = 1 - qsfp_1_tx_rst.next = 1 - qsfp_1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst.next = 0 - qsfp_0_rx_rst.next = 0 - qsfp_1_tx_rst.next = 0 - qsfp_1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_sink.wait() - - pkt = qsfp_0_sink.recv() - print(pkt) - - qsfp_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_sink.wait() - - # pkt = qsfp_1_sink.recv() - # print(pkt) - - # qsfp_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_sink.wait() - - pkt = qsfp_0_sink.recv() - print(pkt) - - qsfp_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index 114917fa3..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,481 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [1:0] user_sw = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk = 0; -reg qsfp_0_tx_rst = 0; -reg qsfp_0_tx_axis_tready = 0; -reg qsfp_0_rx_clk = 0; -reg qsfp_0_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp_0_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_0_rx_axis_tkeep = 0; -reg qsfp_0_rx_axis_tvalid = 0; -reg qsfp_0_rx_axis_tlast = 0; -reg qsfp_0_rx_axis_tuser = 0; -reg qsfp_0_modprs_l = 0; -reg qsfp_1_tx_clk = 0; -reg qsfp_1_tx_rst = 0; -reg qsfp_1_tx_axis_tready = 0; -reg qsfp_1_rx_clk = 0; -reg qsfp_1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp_1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_1_rx_axis_tkeep = 0; -reg qsfp_1_rx_axis_tvalid = 0; -reg qsfp_1_rx_axis_tlast = 0; -reg qsfp_1_rx_axis_tuser = 0; -reg qsfp_1_modprs_l = 0; -reg qsfp_int_l = 0; -reg qsfp_i2c_scl_i = 1; -reg qsfp_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [1:0] user_led_g; -wire user_led_r; -wire [1:0] front_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp_0_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_0_tx_axis_tkeep; -wire qsfp_0_tx_axis_tvalid; -wire qsfp_0_tx_axis_tlast; -wire qsfp_0_tx_axis_tuser; -wire qsfp_0_sel_l; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp_1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_1_tx_axis_tkeep; -wire qsfp_1_tx_axis_tvalid; -wire qsfp_1_tx_axis_tlast; -wire qsfp_1_tx_axis_tuser; -wire qsfp_1_sel_l; -wire qsfp_reset_l; -wire qsfp_i2c_scl_o; -wire qsfp_i2c_scl_t; -wire qsfp_i2c_sda_o; -wire qsfp_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire eeprom_wp; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - user_sw, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk, - qsfp_0_tx_rst, - qsfp_0_tx_axis_tready, - qsfp_0_rx_clk, - qsfp_0_rx_rst, - qsfp_0_rx_axis_tdata, - qsfp_0_rx_axis_tkeep, - qsfp_0_rx_axis_tvalid, - qsfp_0_rx_axis_tlast, - qsfp_0_rx_axis_tuser, - qsfp_0_modprs_l, - qsfp_1_tx_clk, - qsfp_1_tx_rst, - qsfp_1_tx_axis_tready, - qsfp_1_rx_clk, - qsfp_1_rx_rst, - qsfp_1_rx_axis_tdata, - qsfp_1_rx_axis_tkeep, - qsfp_1_rx_axis_tvalid, - qsfp_1_rx_axis_tlast, - qsfp_1_rx_axis_tuser, - qsfp_1_modprs_l, - qsfp_int_l, - qsfp_i2c_scl_i, - qsfp_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - user_led_g, - user_led_r, - front_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_tx_axis_tdata, - qsfp_0_tx_axis_tkeep, - qsfp_0_tx_axis_tvalid, - qsfp_0_tx_axis_tlast, - qsfp_0_tx_axis_tuser, - qsfp_0_sel_l, - qsfp_1_tx_axis_tdata, - qsfp_1_tx_axis_tkeep, - qsfp_1_tx_axis_tvalid, - qsfp_1_tx_axis_tlast, - qsfp_1_tx_axis_tuser, - qsfp_1_sel_l, - qsfp_reset_l, - qsfp_i2c_scl_o, - qsfp_i2c_scl_t, - qsfp_i2c_sda_o, - qsfp_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - eeprom_wp, - fpga_boot, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .user_led_g(user_led_g), - .user_led_r(user_led_r), - .front_led(front_led), - .user_sw(user_sw), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk(qsfp_0_tx_clk), - .qsfp_0_tx_rst(qsfp_0_tx_rst), - .qsfp_0_tx_axis_tdata(qsfp_0_tx_axis_tdata), - .qsfp_0_tx_axis_tkeep(qsfp_0_tx_axis_tkeep), - .qsfp_0_tx_axis_tvalid(qsfp_0_tx_axis_tvalid), - .qsfp_0_tx_axis_tready(qsfp_0_tx_axis_tready), - .qsfp_0_tx_axis_tlast(qsfp_0_tx_axis_tlast), - .qsfp_0_tx_axis_tuser(qsfp_0_tx_axis_tuser), - .qsfp_0_rx_clk(qsfp_0_rx_clk), - .qsfp_0_rx_rst(qsfp_0_rx_rst), - .qsfp_0_rx_axis_tdata(qsfp_0_rx_axis_tdata), - .qsfp_0_rx_axis_tkeep(qsfp_0_rx_axis_tkeep), - .qsfp_0_rx_axis_tvalid(qsfp_0_rx_axis_tvalid), - .qsfp_0_rx_axis_tlast(qsfp_0_rx_axis_tlast), - .qsfp_0_rx_axis_tuser(qsfp_0_rx_axis_tuser), - .qsfp_0_modprs_l(qsfp_0_modprs_l), - .qsfp_0_sel_l(qsfp_0_sel_l), - .qsfp_1_tx_clk(qsfp_1_tx_clk), - .qsfp_1_tx_rst(qsfp_1_tx_rst), - .qsfp_1_tx_axis_tdata(qsfp_1_tx_axis_tdata), - .qsfp_1_tx_axis_tkeep(qsfp_1_tx_axis_tkeep), - .qsfp_1_tx_axis_tvalid(qsfp_1_tx_axis_tvalid), - .qsfp_1_tx_axis_tready(qsfp_1_tx_axis_tready), - .qsfp_1_tx_axis_tlast(qsfp_1_tx_axis_tlast), - .qsfp_1_tx_axis_tuser(qsfp_1_tx_axis_tuser), - .qsfp_1_rx_clk(qsfp_1_rx_clk), - .qsfp_1_rx_rst(qsfp_1_rx_rst), - .qsfp_1_rx_axis_tdata(qsfp_1_rx_axis_tdata), - .qsfp_1_rx_axis_tkeep(qsfp_1_rx_axis_tkeep), - .qsfp_1_rx_axis_tvalid(qsfp_1_rx_axis_tvalid), - .qsfp_1_rx_axis_tlast(qsfp_1_rx_axis_tlast), - .qsfp_1_rx_axis_tuser(qsfp_1_rx_axis_tuser), - .qsfp_1_modprs_l(qsfp_1_modprs_l), - .qsfp_1_sel_l(qsfp_1_sel_l), - .qsfp_reset_l(qsfp_reset_l), - .qsfp_int_l(qsfp_int_l), - .qsfp_i2c_scl_i(qsfp_i2c_scl_i), - .qsfp_i2c_scl_o(qsfp_i2c_scl_o), - .qsfp_i2c_scl_t(qsfp_i2c_scl_t), - .qsfp_i2c_sda_i(qsfp_i2c_sda_i), - .qsfp_i2c_sda_o(qsfp_i2c_sda_o), - .qsfp_i2c_sda_t(qsfp_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .eeprom_wp(eeprom_wp), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/udp_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..1f33a22f2 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,657 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk_0, 6.4, units="ns").start()) + self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_0, 6.4, units="ns").start()) + self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_0, 6.4, units="ns").start()) + self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_0, 6.4, units="ns").start()) + self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3) + + dut.user_sw.setimmediatevalue(0) + + dut.qsfp_0_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_1_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_0_modprs_l.setimmediatevalue(0) + dut.qsfp_1_modprs_l.setimmediatevalue(0) + + dut.qsfp_int_l.setimmediatevalue(1) + dut.qsfp_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_0_sink.empty(): + self.qsfp_0_0_source.send(self.qsfp_0_0_sink.recv()) + if not self.qsfp_0_1_sink.empty(): + self.qsfp_0_1_source.send(self.qsfp_0_1_sink.recv()) + if not self.qsfp_0_2_sink.empty(): + self.qsfp_0_2_source.send(self.qsfp_0_2_sink.recv()) + if not self.qsfp_0_3_sink.empty(): + self.qsfp_0_3_source.send(self.qsfp_0_3_sink.recv()) + if not self.qsfp_1_0_sink.empty(): + self.qsfp_1_0_source.send(self.qsfp_1_0_sink.recv()) + if not self.qsfp_1_1_sink.empty(): + self.qsfp_1_1_source.send(self.qsfp_1_1_sink.recv()) + if not self.qsfp_1_2_sink.empty(): + self.qsfp_1_2_source.send(self.qsfp_1_2_sink.recv()) + if not self.qsfp_1_3_sink.empty(): + self.qsfp_1_3_source.send(self.qsfp_1_3_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = int(parameters['AXIS_PCIE_DATA_WIDTH']/32) + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/mqnic.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie_us.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 09e3c125b..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1047 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - user_sw = Signal(intbv(0)[2:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk_0 = Signal(bool(0)) - qsfp_0_tx_rst_0 = Signal(bool(0)) - qsfp_0_rx_clk_0 = Signal(bool(0)) - qsfp_0_rx_rst_0 = Signal(bool(0)) - qsfp_0_rxd_0 = Signal(intbv(0)[64:]) - qsfp_0_rxc_0 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_1 = Signal(bool(0)) - qsfp_0_tx_rst_1 = Signal(bool(0)) - qsfp_0_rx_clk_1 = Signal(bool(0)) - qsfp_0_rx_rst_1 = Signal(bool(0)) - qsfp_0_rxd_1 = Signal(intbv(0)[64:]) - qsfp_0_rxc_1 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_2 = Signal(bool(0)) - qsfp_0_tx_rst_2 = Signal(bool(0)) - qsfp_0_rx_clk_2 = Signal(bool(0)) - qsfp_0_rx_rst_2 = Signal(bool(0)) - qsfp_0_rxd_2 = Signal(intbv(0)[64:]) - qsfp_0_rxc_2 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_3 = Signal(bool(0)) - qsfp_0_tx_rst_3 = Signal(bool(0)) - qsfp_0_rx_clk_3 = Signal(bool(0)) - qsfp_0_rx_rst_3 = Signal(bool(0)) - qsfp_0_rxd_3 = Signal(intbv(0)[64:]) - qsfp_0_rxc_3 = Signal(intbv(0)[8:]) - qsfp_0_modprs_l = Signal(bool(0)) - qsfp_1_tx_clk_0 = Signal(bool(0)) - qsfp_1_tx_rst_0 = Signal(bool(0)) - qsfp_1_rx_clk_0 = Signal(bool(0)) - qsfp_1_rx_rst_0 = Signal(bool(0)) - qsfp_1_rxd_0 = Signal(intbv(0)[64:]) - qsfp_1_rxc_0 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_1 = Signal(bool(0)) - qsfp_1_tx_rst_1 = Signal(bool(0)) - qsfp_1_rx_clk_1 = Signal(bool(0)) - qsfp_1_rx_rst_1 = Signal(bool(0)) - qsfp_1_rxd_1 = Signal(intbv(0)[64:]) - qsfp_1_rxc_1 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_2 = Signal(bool(0)) - qsfp_1_tx_rst_2 = Signal(bool(0)) - qsfp_1_rx_clk_2 = Signal(bool(0)) - qsfp_1_rx_rst_2 = Signal(bool(0)) - qsfp_1_rxd_2 = Signal(intbv(0)[64:]) - qsfp_1_rxc_2 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_3 = Signal(bool(0)) - qsfp_1_tx_rst_3 = Signal(bool(0)) - qsfp_1_rx_clk_3 = Signal(bool(0)) - qsfp_1_rx_rst_3 = Signal(bool(0)) - qsfp_1_rxd_3 = Signal(intbv(0)[64:]) - qsfp_1_rxc_3 = Signal(intbv(0)[8:]) - qsfp_1_modprs_l = Signal(bool(0)) - qsfp_int_l = Signal(bool(0)) - qsfp_i2c_scl_i = Signal(bool(1)) - qsfp_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - user_led_g = Signal(intbv(0)[2:]) - user_led_r = Signal(bool(0)) - front_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_txd_0 = Signal(intbv(0)[64:]) - qsfp_0_txc_0 = Signal(intbv(0)[8:]) - qsfp_0_txd_1 = Signal(intbv(0)[64:]) - qsfp_0_txc_1 = Signal(intbv(0)[8:]) - qsfp_0_txd_2 = Signal(intbv(0)[64:]) - qsfp_0_txc_2 = Signal(intbv(0)[8:]) - qsfp_0_txd_3 = Signal(intbv(0)[64:]) - qsfp_0_txc_3 = Signal(intbv(0)[8:]) - qsfp_0_sel_l = Signal(bool(1)) - qsfp_1_txd_0 = Signal(intbv(0)[64:]) - qsfp_1_txc_0 = Signal(intbv(0)[8:]) - qsfp_1_txd_1 = Signal(intbv(0)[64:]) - qsfp_1_txc_1 = Signal(intbv(0)[8:]) - qsfp_1_txd_2 = Signal(intbv(0)[64:]) - qsfp_1_txc_2 = Signal(intbv(0)[8:]) - qsfp_1_txd_3 = Signal(intbv(0)[64:]) - qsfp_1_txc_3 = Signal(intbv(0)[8:]) - qsfp_1_sel_l = Signal(bool(1)) - qsfp_reset_l = Signal(bool(1)) - qsfp_i2c_scl_o = Signal(bool(1)) - qsfp_i2c_scl_t = Signal(bool(1)) - qsfp_i2c_sda_o = Signal(bool(1)) - qsfp_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - eeprom_wp = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp_0_0_source = xgmii_ep.XGMIISource() - qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') - - qsfp_0_0_sink = xgmii_ep.XGMIISink() - qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') - - qsfp_0_1_source = xgmii_ep.XGMIISource() - qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') - - qsfp_0_1_sink = xgmii_ep.XGMIISink() - qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') - - qsfp_0_2_source = xgmii_ep.XGMIISource() - qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') - - qsfp_0_2_sink = xgmii_ep.XGMIISink() - qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') - - qsfp_0_3_source = xgmii_ep.XGMIISource() - qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') - - qsfp_0_3_sink = xgmii_ep.XGMIISink() - qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') - - qsfp_1_0_source = xgmii_ep.XGMIISource() - qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') - - qsfp_1_0_sink = xgmii_ep.XGMIISink() - qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') - - qsfp_1_1_source = xgmii_ep.XGMIISource() - qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') - - qsfp_1_1_sink = xgmii_ep.XGMIISink() - qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') - - qsfp_1_2_source = xgmii_ep.XGMIISource() - qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') - - qsfp_1_2_sink = xgmii_ep.XGMIISink() - qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') - - qsfp_1_3_source = xgmii_ep.XGMIISource() - qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') - - qsfp_1_3_sink = xgmii_ep.XGMIISink() - qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - user_led_g=user_led_g, - user_led_r=user_led_r, - front_led=front_led, - user_sw=user_sw, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, - qsfp_0_txd_0=qsfp_0_txd_0, - qsfp_0_txc_0=qsfp_0_txc_0, - qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, - qsfp_0_rxd_0=qsfp_0_rxd_0, - qsfp_0_rxc_0=qsfp_0_rxc_0, - qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, - qsfp_0_txd_1=qsfp_0_txd_1, - qsfp_0_txc_1=qsfp_0_txc_1, - qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, - qsfp_0_rxd_1=qsfp_0_rxd_1, - qsfp_0_rxc_1=qsfp_0_rxc_1, - qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, - qsfp_0_txd_2=qsfp_0_txd_2, - qsfp_0_txc_2=qsfp_0_txc_2, - qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, - qsfp_0_rxd_2=qsfp_0_rxd_2, - qsfp_0_rxc_2=qsfp_0_rxc_2, - qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, - qsfp_0_txd_3=qsfp_0_txd_3, - qsfp_0_txc_3=qsfp_0_txc_3, - qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, - qsfp_0_rxd_3=qsfp_0_rxd_3, - qsfp_0_rxc_3=qsfp_0_rxc_3, - qsfp_0_modprs_l=qsfp_0_modprs_l, - qsfp_0_sel_l=qsfp_0_sel_l, - qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, - qsfp_1_txd_0=qsfp_1_txd_0, - qsfp_1_txc_0=qsfp_1_txc_0, - qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, - qsfp_1_rxd_0=qsfp_1_rxd_0, - qsfp_1_rxc_0=qsfp_1_rxc_0, - qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, - qsfp_1_txd_1=qsfp_1_txd_1, - qsfp_1_txc_1=qsfp_1_txc_1, - qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, - qsfp_1_rxd_1=qsfp_1_rxd_1, - qsfp_1_rxc_1=qsfp_1_rxc_1, - qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, - qsfp_1_txd_2=qsfp_1_txd_2, - qsfp_1_txc_2=qsfp_1_txc_2, - qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, - qsfp_1_rxd_2=qsfp_1_rxd_2, - qsfp_1_rxc_2=qsfp_1_rxc_2, - qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, - qsfp_1_txd_3=qsfp_1_txd_3, - qsfp_1_txc_3=qsfp_1_txc_3, - qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, - qsfp_1_rxd_3=qsfp_1_rxd_3, - qsfp_1_rxc_3=qsfp_1_rxc_3, - qsfp_1_modprs_l=qsfp_1_modprs_l, - qsfp_1_sel_l=qsfp_1_sel_l, - qsfp_reset_l=qsfp_reset_l, - qsfp_int_l=qsfp_int_l, - qsfp_i2c_scl_i=qsfp_i2c_scl_i, - qsfp_i2c_scl_o=qsfp_i2c_scl_o, - qsfp_i2c_scl_t=qsfp_i2c_scl_t, - qsfp_i2c_sda_i=qsfp_i2c_sda_i, - qsfp_i2c_sda_o=qsfp_i2c_sda_o, - qsfp_i2c_sda_t=qsfp_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - eeprom_wp=eeprom_wp, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 - qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 - qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 - qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 - qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 - qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 - qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 - qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 - qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 - qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 - qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 - qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 - qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 - qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 - qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 - qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_0_sink.empty(): - pkt = qsfp_0_0_sink.recv() - qsfp_0_0_source.send(pkt) - if not qsfp_0_1_sink.empty(): - pkt = qsfp_0_1_sink.recv() - qsfp_0_1_source.send(pkt) - if not qsfp_0_2_sink.empty(): - pkt = qsfp_0_2_sink.recv() - qsfp_0_2_source.send(pkt) - if not qsfp_0_3_sink.empty(): - pkt = qsfp_0_3_sink.recv() - qsfp_0_3_source.send(pkt) - if not qsfp_1_0_sink.empty(): - pkt = qsfp_1_0_sink.recv() - qsfp_1_0_source.send(pkt) - if not qsfp_1_1_sink.empty(): - pkt = qsfp_1_1_sink.recv() - qsfp_1_1_source.send(pkt) - if not qsfp_1_2_sink.empty(): - pkt = qsfp_1_2_sink.recv() - qsfp_1_2_source.send(pkt) - if not qsfp_1_3_sink.empty(): - pkt = qsfp_1_3_sink.recv() - qsfp_1_3_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst_0.next = 1 - qsfp_0_rx_rst_0.next = 1 - qsfp_0_tx_rst_1.next = 1 - qsfp_0_rx_rst_1.next = 1 - qsfp_0_tx_rst_2.next = 1 - qsfp_0_rx_rst_2.next = 1 - qsfp_0_tx_rst_3.next = 1 - qsfp_0_rx_rst_3.next = 1 - qsfp_1_tx_rst_0.next = 1 - qsfp_1_rx_rst_0.next = 1 - qsfp_1_tx_rst_1.next = 1 - qsfp_1_rx_rst_1.next = 1 - qsfp_1_tx_rst_2.next = 1 - qsfp_1_rx_rst_2.next = 1 - qsfp_1_tx_rst_3.next = 1 - qsfp_1_rx_rst_3.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst_0.next = 0 - qsfp_0_rx_rst_0.next = 0 - qsfp_0_tx_rst_1.next = 0 - qsfp_0_rx_rst_1.next = 0 - qsfp_0_tx_rst_2.next = 0 - qsfp_0_rx_rst_2.next = 0 - qsfp_0_tx_rst_3.next = 0 - qsfp_0_rx_rst_3.next = 0 - qsfp_1_tx_rst_0.next = 0 - qsfp_1_rx_rst_0.next = 0 - qsfp_1_tx_rst_1.next = 0 - qsfp_1_rx_rst_1.next = 0 - qsfp_1_tx_rst_2.next = 0 - qsfp_1_rx_rst_2.next = 0 - qsfp_1_tx_rst_3.next = 0 - qsfp_1_rx_rst_3.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_0_sink.wait() - - # pkt = qsfp_1_0_sink.recv() - # print(pkt) - - # qsfp_1_0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 521928431..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [1:0] user_sw = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk_0 = 0; -reg qsfp_0_tx_rst_0 = 0; -reg qsfp_0_rx_clk_0 = 0; -reg qsfp_0_rx_rst_0 = 0; -reg [63:0] qsfp_0_rxd_0 = 0; -reg [7:0] qsfp_0_rxc_0 = 0; -reg qsfp_0_tx_clk_1 = 0; -reg qsfp_0_tx_rst_1 = 0; -reg qsfp_0_rx_clk_1 = 0; -reg qsfp_0_rx_rst_1 = 0; -reg [63:0] qsfp_0_rxd_1 = 0; -reg [7:0] qsfp_0_rxc_1 = 0; -reg qsfp_0_tx_clk_2 = 0; -reg qsfp_0_tx_rst_2 = 0; -reg qsfp_0_rx_clk_2 = 0; -reg qsfp_0_rx_rst_2 = 0; -reg [63:0] qsfp_0_rxd_2 = 0; -reg [7:0] qsfp_0_rxc_2 = 0; -reg qsfp_0_tx_clk_3 = 0; -reg qsfp_0_tx_rst_3 = 0; -reg qsfp_0_rx_clk_3 = 0; -reg qsfp_0_rx_rst_3 = 0; -reg [63:0] qsfp_0_rxd_3 = 0; -reg [7:0] qsfp_0_rxc_3 = 0; -reg qsfp_0_modprs_l = 0; -reg qsfp_1_tx_clk_0 = 0; -reg qsfp_1_tx_rst_0 = 0; -reg qsfp_1_rx_clk_0 = 0; -reg qsfp_1_rx_rst_0 = 0; -reg [63:0] qsfp_1_rxd_0 = 0; -reg [7:0] qsfp_1_rxc_0 = 0; -reg qsfp_1_tx_clk_1 = 0; -reg qsfp_1_tx_rst_1 = 0; -reg qsfp_1_rx_clk_1 = 0; -reg qsfp_1_rx_rst_1 = 0; -reg [63:0] qsfp_1_rxd_1 = 0; -reg [7:0] qsfp_1_rxc_1 = 0; -reg qsfp_1_tx_clk_2 = 0; -reg qsfp_1_tx_rst_2 = 0; -reg qsfp_1_rx_clk_2 = 0; -reg qsfp_1_rx_rst_2 = 0; -reg [63:0] qsfp_1_rxd_2 = 0; -reg [7:0] qsfp_1_rxc_2 = 0; -reg qsfp_1_tx_clk_3 = 0; -reg qsfp_1_tx_rst_3 = 0; -reg qsfp_1_rx_clk_3 = 0; -reg qsfp_1_rx_rst_3 = 0; -reg [63:0] qsfp_1_rxd_3 = 0; -reg [7:0] qsfp_1_rxc_3 = 0; -reg qsfp_1_modprs_l = 0; -reg qsfp_int_l = 0; -reg qsfp_i2c_scl_i = 1; -reg qsfp_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [1:0] user_led_g; -wire user_led_r; -wire [1:0] front_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_0_txd_0; -wire [7:0] qsfp_0_txc_0; -wire [63:0] qsfp_0_txd_1; -wire [7:0] qsfp_0_txc_1; -wire [63:0] qsfp_0_txd_2; -wire [7:0] qsfp_0_txc_2; -wire [63:0] qsfp_0_txd_3; -wire [7:0] qsfp_0_txc_3; -wire qsfp_0_sel_l; -wire [63:0] qsfp_1_txd_0; -wire [7:0] qsfp_1_txc_0; -wire [63:0] qsfp_1_txd_1; -wire [7:0] qsfp_1_txc_1; -wire [63:0] qsfp_1_txd_2; -wire [7:0] qsfp_1_txc_2; -wire [63:0] qsfp_1_txd_3; -wire [7:0] qsfp_1_txc_3; -wire qsfp_1_sel_l; -wire qsfp_reset_l; -wire qsfp_i2c_scl_o; -wire qsfp_i2c_scl_t; -wire qsfp_i2c_sda_o; -wire qsfp_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire eeprom_wp; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - user_sw, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0, - qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0, - qsfp_0_rxd_0, - qsfp_0_rxc_0, - qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1, - qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1, - qsfp_0_rxd_1, - qsfp_0_rxc_1, - qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2, - qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2, - qsfp_0_rxd_2, - qsfp_0_rxc_2, - qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3, - qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3, - qsfp_0_rxd_3, - qsfp_0_rxc_3, - qsfp_0_modprs_l, - qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0, - qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0, - qsfp_1_rxd_0, - qsfp_1_rxc_0, - qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1, - qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1, - qsfp_1_rxd_1, - qsfp_1_rxc_1, - qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2, - qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2, - qsfp_1_rxd_2, - qsfp_1_rxc_2, - qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3, - qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3, - qsfp_1_rxd_3, - qsfp_1_rxc_3, - qsfp_1_modprs_l, - qsfp_int_l, - qsfp_i2c_scl_i, - qsfp_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - user_led_g, - user_led_r, - front_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_txd_0, - qsfp_0_txc_0, - qsfp_0_txd_1, - qsfp_0_txc_1, - qsfp_0_txd_2, - qsfp_0_txc_2, - qsfp_0_txd_3, - qsfp_0_txc_3, - qsfp_0_sel_l, - qsfp_1_txd_0, - qsfp_1_txc_0, - qsfp_1_txd_1, - qsfp_1_txc_1, - qsfp_1_txd_2, - qsfp_1_txc_2, - qsfp_1_txd_3, - qsfp_1_txc_3, - qsfp_1_sel_l, - qsfp_reset_l, - qsfp_i2c_scl_o, - qsfp_i2c_scl_t, - qsfp_i2c_sda_o, - qsfp_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - eeprom_wp, - fpga_boot, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .user_led_g(user_led_g), - .user_led_r(user_led_r), - .front_led(front_led), - .user_sw(user_sw), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), - .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), - .qsfp_0_txd_0(qsfp_0_txd_0), - .qsfp_0_txc_0(qsfp_0_txc_0), - .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), - .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), - .qsfp_0_rxd_0(qsfp_0_rxd_0), - .qsfp_0_rxc_0(qsfp_0_rxc_0), - .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), - .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), - .qsfp_0_txd_1(qsfp_0_txd_1), - .qsfp_0_txc_1(qsfp_0_txc_1), - .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), - .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), - .qsfp_0_rxd_1(qsfp_0_rxd_1), - .qsfp_0_rxc_1(qsfp_0_rxc_1), - .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), - .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), - .qsfp_0_txd_2(qsfp_0_txd_2), - .qsfp_0_txc_2(qsfp_0_txc_2), - .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), - .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), - .qsfp_0_rxd_2(qsfp_0_rxd_2), - .qsfp_0_rxc_2(qsfp_0_rxc_2), - .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), - .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), - .qsfp_0_txd_3(qsfp_0_txd_3), - .qsfp_0_txc_3(qsfp_0_txc_3), - .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), - .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), - .qsfp_0_rxd_3(qsfp_0_rxd_3), - .qsfp_0_rxc_3(qsfp_0_rxc_3), - .qsfp_0_modprs_l(qsfp_0_modprs_l), - .qsfp_0_sel_l(qsfp_0_sel_l), - .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), - .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), - .qsfp_1_txd_0(qsfp_1_txd_0), - .qsfp_1_txc_0(qsfp_1_txc_0), - .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), - .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), - .qsfp_1_rxd_0(qsfp_1_rxd_0), - .qsfp_1_rxc_0(qsfp_1_rxc_0), - .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), - .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), - .qsfp_1_txd_1(qsfp_1_txd_1), - .qsfp_1_txc_1(qsfp_1_txc_1), - .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), - .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), - .qsfp_1_rxd_1(qsfp_1_rxd_1), - .qsfp_1_rxc_1(qsfp_1_rxc_1), - .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), - .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), - .qsfp_1_txd_2(qsfp_1_txd_2), - .qsfp_1_txc_2(qsfp_1_txc_2), - .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), - .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), - .qsfp_1_rxd_2(qsfp_1_rxd_2), - .qsfp_1_rxc_2(qsfp_1_rxc_2), - .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), - .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), - .qsfp_1_txd_3(qsfp_1_txd_3), - .qsfp_1_txc_3(qsfp_1_txc_3), - .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), - .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), - .qsfp_1_rxd_3(qsfp_1_rxd_3), - .qsfp_1_rxc_3(qsfp_1_rxc_3), - .qsfp_1_modprs_l(qsfp_1_modprs_l), - .qsfp_1_sel_l(qsfp_1_sel_l), - .qsfp_reset_l(qsfp_reset_l), - .qsfp_int_l(qsfp_int_l), - .qsfp_i2c_scl_i(qsfp_i2c_scl_i), - .qsfp_i2c_scl_o(qsfp_i2c_scl_o), - .qsfp_i2c_scl_t(qsfp_i2c_scl_t), - .qsfp_i2c_sda_i(qsfp_i2c_sda_i), - .qsfp_i2c_sda_o(qsfp_i2c_sda_o), - .qsfp_i2c_sda_t(qsfp_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .eeprom_wp(eeprom_wp), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/mqnic.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..5087f24c6 --- /dev/null +++ b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,657 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk_0, 2.56, units="ns").start()) + self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_0, 2.56, units="ns").start()) + self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_1, 2.56, units="ns").start()) + self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_1, 2.56, units="ns").start()) + self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_2, 2.56, units="ns").start()) + self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_2, 2.56, units="ns").start()) + self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_3, 2.56, units="ns").start()) + self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_3, 2.56, units="ns").start()) + self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_0, 2.56, units="ns").start()) + self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_0, 2.56, units="ns").start()) + self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_1, 2.56, units="ns").start()) + self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_1, 2.56, units="ns").start()) + self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_2, 2.56, units="ns").start()) + self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_2, 2.56, units="ns").start()) + self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_3, 2.56, units="ns").start()) + self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_3, 2.56, units="ns").start()) + self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3) + + dut.user_sw.setimmediatevalue(0) + + dut.qsfp_0_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_1_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_0_modprs_l.setimmediatevalue(0) + dut.qsfp_1_modprs_l.setimmediatevalue(0) + + dut.qsfp_int_l.setimmediatevalue(1) + dut.qsfp_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_0_sink.empty(): + self.qsfp_0_0_source.send(self.qsfp_0_0_sink.recv()) + if not self.qsfp_0_1_sink.empty(): + self.qsfp_0_1_source.send(self.qsfp_0_1_sink.recv()) + if not self.qsfp_0_2_sink.empty(): + self.qsfp_0_2_source.send(self.qsfp_0_2_sink.recv()) + if not self.qsfp_0_3_sink.empty(): + self.qsfp_0_3_source.send(self.qsfp_0_3_sink.recv()) + if not self.qsfp_1_0_sink.empty(): + self.qsfp_1_0_source.send(self.qsfp_1_0_sink.recv()) + if not self.qsfp_1_1_sink.empty(): + self.qsfp_1_1_source.send(self.qsfp_1_1_sink.recv()) + if not self.qsfp_1_2_sink.empty(): + self.qsfp_1_2_source.send(self.qsfp_1_2_sink.recv()) + if not self.qsfp_1_3_sink.empty(): + self.qsfp_1_3_source.send(self.qsfp_1_3_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = int(parameters['AXIS_PCIE_DATA_WIDTH']/32) + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/mqnic.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie_us.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie_usp.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py deleted file mode 100755 index 57552f3e1..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.py +++ /dev/null @@ -1,1075 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - user_sw = Signal(intbv(0)[2:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk_0 = Signal(bool(0)) - qsfp_0_tx_rst_0 = Signal(bool(0)) - qsfp_0_rx_clk_0 = Signal(bool(0)) - qsfp_0_rx_rst_0 = Signal(bool(0)) - qsfp_0_rxd_0 = Signal(intbv(0)[64:]) - qsfp_0_rxc_0 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_1 = Signal(bool(0)) - qsfp_0_tx_rst_1 = Signal(bool(0)) - qsfp_0_rx_clk_1 = Signal(bool(0)) - qsfp_0_rx_rst_1 = Signal(bool(0)) - qsfp_0_rxd_1 = Signal(intbv(0)[64:]) - qsfp_0_rxc_1 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_2 = Signal(bool(0)) - qsfp_0_tx_rst_2 = Signal(bool(0)) - qsfp_0_rx_clk_2 = Signal(bool(0)) - qsfp_0_rx_rst_2 = Signal(bool(0)) - qsfp_0_rxd_2 = Signal(intbv(0)[64:]) - qsfp_0_rxc_2 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_3 = Signal(bool(0)) - qsfp_0_tx_rst_3 = Signal(bool(0)) - qsfp_0_rx_clk_3 = Signal(bool(0)) - qsfp_0_rx_rst_3 = Signal(bool(0)) - qsfp_0_rxd_3 = Signal(intbv(0)[64:]) - qsfp_0_rxc_3 = Signal(intbv(0)[8:]) - qsfp_0_modprs_l = Signal(bool(0)) - qsfp_1_tx_clk_0 = Signal(bool(0)) - qsfp_1_tx_rst_0 = Signal(bool(0)) - qsfp_1_rx_clk_0 = Signal(bool(0)) - qsfp_1_rx_rst_0 = Signal(bool(0)) - qsfp_1_rxd_0 = Signal(intbv(0)[64:]) - qsfp_1_rxc_0 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_1 = Signal(bool(0)) - qsfp_1_tx_rst_1 = Signal(bool(0)) - qsfp_1_rx_clk_1 = Signal(bool(0)) - qsfp_1_rx_rst_1 = Signal(bool(0)) - qsfp_1_rxd_1 = Signal(intbv(0)[64:]) - qsfp_1_rxc_1 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_2 = Signal(bool(0)) - qsfp_1_tx_rst_2 = Signal(bool(0)) - qsfp_1_rx_clk_2 = Signal(bool(0)) - qsfp_1_rx_rst_2 = Signal(bool(0)) - qsfp_1_rxd_2 = Signal(intbv(0)[64:]) - qsfp_1_rxc_2 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_3 = Signal(bool(0)) - qsfp_1_tx_rst_3 = Signal(bool(0)) - qsfp_1_rx_clk_3 = Signal(bool(0)) - qsfp_1_rx_rst_3 = Signal(bool(0)) - qsfp_1_rxd_3 = Signal(intbv(0)[64:]) - qsfp_1_rxc_3 = Signal(intbv(0)[8:]) - qsfp_1_modprs_l = Signal(bool(0)) - qsfp_int_l = Signal(bool(0)) - qsfp_i2c_scl_i = Signal(bool(1)) - qsfp_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - user_led_g = Signal(intbv(0)[2:]) - user_led_r = Signal(bool(0)) - front_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_txd_0 = Signal(intbv(0)[64:]) - qsfp_0_txc_0 = Signal(intbv(0)[8:]) - qsfp_0_txd_1 = Signal(intbv(0)[64:]) - qsfp_0_txc_1 = Signal(intbv(0)[8:]) - qsfp_0_txd_2 = Signal(intbv(0)[64:]) - qsfp_0_txc_2 = Signal(intbv(0)[8:]) - qsfp_0_txd_3 = Signal(intbv(0)[64:]) - qsfp_0_txc_3 = Signal(intbv(0)[8:]) - qsfp_0_sel_l = Signal(bool(1)) - qsfp_1_txd_0 = Signal(intbv(0)[64:]) - qsfp_1_txc_0 = Signal(intbv(0)[8:]) - qsfp_1_txd_1 = Signal(intbv(0)[64:]) - qsfp_1_txc_1 = Signal(intbv(0)[8:]) - qsfp_1_txd_2 = Signal(intbv(0)[64:]) - qsfp_1_txc_2 = Signal(intbv(0)[8:]) - qsfp_1_txd_3 = Signal(intbv(0)[64:]) - qsfp_1_txc_3 = Signal(intbv(0)[8:]) - qsfp_1_sel_l = Signal(bool(1)) - qsfp_reset_l = Signal(bool(1)) - qsfp_i2c_scl_o = Signal(bool(1)) - qsfp_i2c_scl_t = Signal(bool(1)) - qsfp_i2c_sda_o = Signal(bool(1)) - qsfp_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - eeprom_wp = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp_0_0_source = xgmii_ep.XGMIISource() - qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') - - qsfp_0_0_sink = xgmii_ep.XGMIISink() - qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') - - qsfp_0_1_source = xgmii_ep.XGMIISource() - qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') - - qsfp_0_1_sink = xgmii_ep.XGMIISink() - qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') - - qsfp_0_2_source = xgmii_ep.XGMIISource() - qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') - - qsfp_0_2_sink = xgmii_ep.XGMIISink() - qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') - - qsfp_0_3_source = xgmii_ep.XGMIISource() - qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') - - qsfp_0_3_sink = xgmii_ep.XGMIISink() - qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') - - qsfp_1_0_source = xgmii_ep.XGMIISource() - qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') - - qsfp_1_0_sink = xgmii_ep.XGMIISink() - qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') - - qsfp_1_1_source = xgmii_ep.XGMIISource() - qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') - - qsfp_1_1_sink = xgmii_ep.XGMIISink() - qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') - - qsfp_1_2_source = xgmii_ep.XGMIISource() - qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') - - qsfp_1_2_sink = xgmii_ep.XGMIISink() - qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') - - qsfp_1_3_source = xgmii_ep.XGMIISource() - qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') - - qsfp_1_3_sink = xgmii_ep.XGMIISink() - qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - user_led_g=user_led_g, - user_led_r=user_led_r, - front_led=front_led, - user_sw=user_sw, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, - qsfp_0_txd_0=qsfp_0_txd_0, - qsfp_0_txc_0=qsfp_0_txc_0, - qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, - qsfp_0_rxd_0=qsfp_0_rxd_0, - qsfp_0_rxc_0=qsfp_0_rxc_0, - qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, - qsfp_0_txd_1=qsfp_0_txd_1, - qsfp_0_txc_1=qsfp_0_txc_1, - qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, - qsfp_0_rxd_1=qsfp_0_rxd_1, - qsfp_0_rxc_1=qsfp_0_rxc_1, - qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, - qsfp_0_txd_2=qsfp_0_txd_2, - qsfp_0_txc_2=qsfp_0_txc_2, - qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, - qsfp_0_rxd_2=qsfp_0_rxd_2, - qsfp_0_rxc_2=qsfp_0_rxc_2, - qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, - qsfp_0_txd_3=qsfp_0_txd_3, - qsfp_0_txc_3=qsfp_0_txc_3, - qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, - qsfp_0_rxd_3=qsfp_0_rxd_3, - qsfp_0_rxc_3=qsfp_0_rxc_3, - qsfp_0_modprs_l=qsfp_0_modprs_l, - qsfp_0_sel_l=qsfp_0_sel_l, - qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, - qsfp_1_txd_0=qsfp_1_txd_0, - qsfp_1_txc_0=qsfp_1_txc_0, - qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, - qsfp_1_rxd_0=qsfp_1_rxd_0, - qsfp_1_rxc_0=qsfp_1_rxc_0, - qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, - qsfp_1_txd_1=qsfp_1_txd_1, - qsfp_1_txc_1=qsfp_1_txc_1, - qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, - qsfp_1_rxd_1=qsfp_1_rxd_1, - qsfp_1_rxc_1=qsfp_1_rxc_1, - qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, - qsfp_1_txd_2=qsfp_1_txd_2, - qsfp_1_txc_2=qsfp_1_txc_2, - qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, - qsfp_1_rxd_2=qsfp_1_rxd_2, - qsfp_1_rxc_2=qsfp_1_rxc_2, - qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, - qsfp_1_txd_3=qsfp_1_txd_3, - qsfp_1_txc_3=qsfp_1_txc_3, - qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, - qsfp_1_rxd_3=qsfp_1_rxd_3, - qsfp_1_rxc_3=qsfp_1_rxc_3, - qsfp_1_modprs_l=qsfp_1_modprs_l, - qsfp_1_sel_l=qsfp_1_sel_l, - qsfp_reset_l=qsfp_reset_l, - qsfp_int_l=qsfp_int_l, - qsfp_i2c_scl_i=qsfp_i2c_scl_i, - qsfp_i2c_scl_o=qsfp_i2c_scl_o, - qsfp_i2c_scl_t=qsfp_i2c_scl_t, - qsfp_i2c_sda_i=qsfp_i2c_sda_i, - qsfp_i2c_sda_o=qsfp_i2c_sda_o, - qsfp_i2c_sda_t=qsfp_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - eeprom_wp=eeprom_wp, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(1)) - def qsfp_clkgen(): - qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 - qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 - qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 - qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 - qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 - qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 - qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 - qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 - qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 - qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 - qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 - qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 - qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 - qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 - qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 - qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_0_sink.empty(): - pkt = qsfp_0_0_sink.recv() - qsfp_0_0_source.send(pkt) - if not qsfp_0_1_sink.empty(): - pkt = qsfp_0_1_sink.recv() - qsfp_0_1_source.send(pkt) - if not qsfp_0_2_sink.empty(): - pkt = qsfp_0_2_sink.recv() - qsfp_0_2_source.send(pkt) - if not qsfp_0_3_sink.empty(): - pkt = qsfp_0_3_sink.recv() - qsfp_0_3_source.send(pkt) - if not qsfp_1_0_sink.empty(): - pkt = qsfp_1_0_sink.recv() - qsfp_1_0_source.send(pkt) - if not qsfp_1_1_sink.empty(): - pkt = qsfp_1_1_sink.recv() - qsfp_1_1_source.send(pkt) - if not qsfp_1_2_sink.empty(): - pkt = qsfp_1_2_sink.recv() - qsfp_1_2_source.send(pkt) - if not qsfp_1_3_sink.empty(): - pkt = qsfp_1_3_sink.recv() - qsfp_1_3_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst_0.next = 1 - qsfp_0_rx_rst_0.next = 1 - qsfp_0_tx_rst_1.next = 1 - qsfp_0_rx_rst_1.next = 1 - qsfp_0_tx_rst_2.next = 1 - qsfp_0_rx_rst_2.next = 1 - qsfp_0_tx_rst_3.next = 1 - qsfp_0_rx_rst_3.next = 1 - qsfp_1_tx_rst_0.next = 1 - qsfp_1_rx_rst_0.next = 1 - qsfp_1_tx_rst_1.next = 1 - qsfp_1_rx_rst_1.next = 1 - qsfp_1_tx_rst_2.next = 1 - qsfp_1_rx_rst_2.next = 1 - qsfp_1_tx_rst_3.next = 1 - qsfp_1_rx_rst_3.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst_0.next = 0 - qsfp_0_rx_rst_0.next = 0 - qsfp_0_tx_rst_1.next = 0 - qsfp_0_rx_rst_1.next = 0 - qsfp_0_tx_rst_2.next = 0 - qsfp_0_rx_rst_2.next = 0 - qsfp_0_tx_rst_3.next = 0 - qsfp_0_rx_rst_3.next = 0 - qsfp_1_tx_rst_0.next = 0 - qsfp_1_rx_rst_0.next = 0 - qsfp_1_tx_rst_1.next = 0 - qsfp_1_rx_rst_1.next = 0 - qsfp_1_tx_rst_2.next = 0 - qsfp_1_rx_rst_2.next = 0 - qsfp_1_tx_rst_3.next = 0 - qsfp_1_rx_rst_3.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_0_sink.wait() - - # pkt = qsfp_1_0_sink.recv() - # print(pkt) - - # qsfp_1_0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - # yield clk.posedge - # print("test 7: send from multiple queues") - # current_test.next = 7 - - # count = 64 - - # pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - # loopback_enable.next = True - - # for k in range(count): - # yield from driver.interfaces[0].start_xmit(pkts[k], k%4) - - # for k in range(count): - # pkt = driver.interfaces[0].recv() - - # if not pkt: - # yield driver.interfaces[0].wait() - # pkt = driver.interfaces[0].recv() - - # print(pkt) - # #assert pkt.data == pkts[k] - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - # loopback_enable.next = False - - # yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v deleted file mode 100644 index 521928431..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/test_fpga_core.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [1:0] user_sw = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk_0 = 0; -reg qsfp_0_tx_rst_0 = 0; -reg qsfp_0_rx_clk_0 = 0; -reg qsfp_0_rx_rst_0 = 0; -reg [63:0] qsfp_0_rxd_0 = 0; -reg [7:0] qsfp_0_rxc_0 = 0; -reg qsfp_0_tx_clk_1 = 0; -reg qsfp_0_tx_rst_1 = 0; -reg qsfp_0_rx_clk_1 = 0; -reg qsfp_0_rx_rst_1 = 0; -reg [63:0] qsfp_0_rxd_1 = 0; -reg [7:0] qsfp_0_rxc_1 = 0; -reg qsfp_0_tx_clk_2 = 0; -reg qsfp_0_tx_rst_2 = 0; -reg qsfp_0_rx_clk_2 = 0; -reg qsfp_0_rx_rst_2 = 0; -reg [63:0] qsfp_0_rxd_2 = 0; -reg [7:0] qsfp_0_rxc_2 = 0; -reg qsfp_0_tx_clk_3 = 0; -reg qsfp_0_tx_rst_3 = 0; -reg qsfp_0_rx_clk_3 = 0; -reg qsfp_0_rx_rst_3 = 0; -reg [63:0] qsfp_0_rxd_3 = 0; -reg [7:0] qsfp_0_rxc_3 = 0; -reg qsfp_0_modprs_l = 0; -reg qsfp_1_tx_clk_0 = 0; -reg qsfp_1_tx_rst_0 = 0; -reg qsfp_1_rx_clk_0 = 0; -reg qsfp_1_rx_rst_0 = 0; -reg [63:0] qsfp_1_rxd_0 = 0; -reg [7:0] qsfp_1_rxc_0 = 0; -reg qsfp_1_tx_clk_1 = 0; -reg qsfp_1_tx_rst_1 = 0; -reg qsfp_1_rx_clk_1 = 0; -reg qsfp_1_rx_rst_1 = 0; -reg [63:0] qsfp_1_rxd_1 = 0; -reg [7:0] qsfp_1_rxc_1 = 0; -reg qsfp_1_tx_clk_2 = 0; -reg qsfp_1_tx_rst_2 = 0; -reg qsfp_1_rx_clk_2 = 0; -reg qsfp_1_rx_rst_2 = 0; -reg [63:0] qsfp_1_rxd_2 = 0; -reg [7:0] qsfp_1_rxc_2 = 0; -reg qsfp_1_tx_clk_3 = 0; -reg qsfp_1_tx_rst_3 = 0; -reg qsfp_1_rx_clk_3 = 0; -reg qsfp_1_rx_rst_3 = 0; -reg [63:0] qsfp_1_rxd_3 = 0; -reg [7:0] qsfp_1_rxc_3 = 0; -reg qsfp_1_modprs_l = 0; -reg qsfp_int_l = 0; -reg qsfp_i2c_scl_i = 1; -reg qsfp_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [1:0] user_led_g; -wire user_led_r; -wire [1:0] front_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_0_txd_0; -wire [7:0] qsfp_0_txc_0; -wire [63:0] qsfp_0_txd_1; -wire [7:0] qsfp_0_txc_1; -wire [63:0] qsfp_0_txd_2; -wire [7:0] qsfp_0_txc_2; -wire [63:0] qsfp_0_txd_3; -wire [7:0] qsfp_0_txc_3; -wire qsfp_0_sel_l; -wire [63:0] qsfp_1_txd_0; -wire [7:0] qsfp_1_txc_0; -wire [63:0] qsfp_1_txd_1; -wire [7:0] qsfp_1_txc_1; -wire [63:0] qsfp_1_txd_2; -wire [7:0] qsfp_1_txc_2; -wire [63:0] qsfp_1_txd_3; -wire [7:0] qsfp_1_txc_3; -wire qsfp_1_sel_l; -wire qsfp_reset_l; -wire qsfp_i2c_scl_o; -wire qsfp_i2c_scl_t; -wire qsfp_i2c_sda_o; -wire qsfp_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire eeprom_wp; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - user_sw, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0, - qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0, - qsfp_0_rxd_0, - qsfp_0_rxc_0, - qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1, - qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1, - qsfp_0_rxd_1, - qsfp_0_rxc_1, - qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2, - qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2, - qsfp_0_rxd_2, - qsfp_0_rxc_2, - qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3, - qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3, - qsfp_0_rxd_3, - qsfp_0_rxc_3, - qsfp_0_modprs_l, - qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0, - qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0, - qsfp_1_rxd_0, - qsfp_1_rxc_0, - qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1, - qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1, - qsfp_1_rxd_1, - qsfp_1_rxc_1, - qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2, - qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2, - qsfp_1_rxd_2, - qsfp_1_rxc_2, - qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3, - qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3, - qsfp_1_rxd_3, - qsfp_1_rxc_3, - qsfp_1_modprs_l, - qsfp_int_l, - qsfp_i2c_scl_i, - qsfp_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - user_led_g, - user_led_r, - front_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_txd_0, - qsfp_0_txc_0, - qsfp_0_txd_1, - qsfp_0_txc_1, - qsfp_0_txd_2, - qsfp_0_txc_2, - qsfp_0_txd_3, - qsfp_0_txc_3, - qsfp_0_sel_l, - qsfp_1_txd_0, - qsfp_1_txc_0, - qsfp_1_txd_1, - qsfp_1_txc_1, - qsfp_1_txd_2, - qsfp_1_txc_2, - qsfp_1_txd_3, - qsfp_1_txc_3, - qsfp_1_sel_l, - qsfp_reset_l, - qsfp_i2c_scl_o, - qsfp_i2c_scl_t, - qsfp_i2c_sda_o, - qsfp_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - eeprom_wp, - fpga_boot, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .user_led_g(user_led_g), - .user_led_r(user_led_r), - .front_led(front_led), - .user_sw(user_sw), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), - .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), - .qsfp_0_txd_0(qsfp_0_txd_0), - .qsfp_0_txc_0(qsfp_0_txc_0), - .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), - .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), - .qsfp_0_rxd_0(qsfp_0_rxd_0), - .qsfp_0_rxc_0(qsfp_0_rxc_0), - .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), - .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), - .qsfp_0_txd_1(qsfp_0_txd_1), - .qsfp_0_txc_1(qsfp_0_txc_1), - .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), - .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), - .qsfp_0_rxd_1(qsfp_0_rxd_1), - .qsfp_0_rxc_1(qsfp_0_rxc_1), - .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), - .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), - .qsfp_0_txd_2(qsfp_0_txd_2), - .qsfp_0_txc_2(qsfp_0_txc_2), - .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), - .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), - .qsfp_0_rxd_2(qsfp_0_rxd_2), - .qsfp_0_rxc_2(qsfp_0_rxc_2), - .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), - .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), - .qsfp_0_txd_3(qsfp_0_txd_3), - .qsfp_0_txc_3(qsfp_0_txc_3), - .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), - .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), - .qsfp_0_rxd_3(qsfp_0_rxd_3), - .qsfp_0_rxc_3(qsfp_0_rxc_3), - .qsfp_0_modprs_l(qsfp_0_modprs_l), - .qsfp_0_sel_l(qsfp_0_sel_l), - .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), - .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), - .qsfp_1_txd_0(qsfp_1_txd_0), - .qsfp_1_txc_0(qsfp_1_txc_0), - .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), - .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), - .qsfp_1_rxd_0(qsfp_1_rxd_0), - .qsfp_1_rxc_0(qsfp_1_rxc_0), - .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), - .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), - .qsfp_1_txd_1(qsfp_1_txd_1), - .qsfp_1_txc_1(qsfp_1_txc_1), - .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), - .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), - .qsfp_1_rxd_1(qsfp_1_rxd_1), - .qsfp_1_rxc_1(qsfp_1_rxc_1), - .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), - .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), - .qsfp_1_txd_2(qsfp_1_txd_2), - .qsfp_1_txc_2(qsfp_1_txc_2), - .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), - .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), - .qsfp_1_rxd_2(qsfp_1_rxd_2), - .qsfp_1_rxc_2(qsfp_1_rxc_2), - .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), - .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), - .qsfp_1_txd_3(qsfp_1_txd_3), - .qsfp_1_txc_3(qsfp_1_txc_3), - .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), - .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), - .qsfp_1_rxd_3(qsfp_1_rxd_3), - .qsfp_1_rxc_3(qsfp_1_rxc_3), - .qsfp_1_modprs_l(qsfp_1_modprs_l), - .qsfp_1_sel_l(qsfp_1_sel_l), - .qsfp_reset_l(qsfp_reset_l), - .qsfp_int_l(qsfp_int_l), - .qsfp_i2c_scl_i(qsfp_i2c_scl_i), - .qsfp_i2c_scl_o(qsfp_i2c_scl_o), - .qsfp_i2c_scl_t(qsfp_i2c_scl_t), - .qsfp_i2c_sda_i(qsfp_i2c_sda_i), - .qsfp_i2c_sda_o(qsfp_i2c_sda_o), - .qsfp_i2c_sda_t(qsfp_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .eeprom_wp(eeprom_wp), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py b/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/ADM_PCIE_9V3/fpga_25g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/axis_ep.py b/fpga/mqnic/AU200/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/eth_ep.py b/fpga/mqnic/AU200/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..1b6b1b200 --- /dev/null +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..e241e3779 --- /dev/null +++ b/fpga/mqnic/AU200/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,585 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk, 3.102, units="ns").start()) + self.qsfp0_source = AxiStreamSource(dut, "qsfp0_rx_axis", dut.qsfp0_rx_clk, dut.qsfp0_rx_rst) + cocotb.fork(Clock(dut.qsfp0_tx_clk, 3.102, units="ns").start()) + self.qsfp0_sink = AxiStreamSink(dut, "qsfp0_tx_axis", dut.qsfp0_tx_clk, dut.qsfp0_tx_rst) + + cocotb.fork(Clock(dut.qsfp1_rx_clk, 3.102, units="ns").start()) + self.qsfp1_source = AxiStreamSource(dut, "qsfp1_rx_axis", dut.qsfp1_rx_clk, dut.qsfp1_rx_rst) + cocotb.fork(Clock(dut.qsfp1_tx_clk, 3.102, units="ns").start()) + self.qsfp1_sink = AxiStreamSink(dut, "qsfp1_tx_axis", dut.qsfp1_tx_clk, dut.qsfp1_tx_rst) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(1) + self.dut.qsfp0_tx_rst.setimmediatevalue(1) + self.dut.qsfp1_rx_rst.setimmediatevalue(1) + self.dut.qsfp1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_sink.empty(): + self.qsfp0_source.send(self.qsfp0_sink.recv()) + if not self.qsfp1_sink.empty(): + self.qsfp1_source.send(self.qsfp1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_0_sink.wait() + + # pkt = tb.qsfp1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU200/fpga_100g/tb/ip_ep.py b/fpga/mqnic/AU200/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/mqnic.py b/fpga/mqnic/AU200/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/pcie.py b/fpga/mqnic/AU200/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/pcie_us.py b/fpga/mqnic/AU200/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/AU200/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/AU200/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index bd17d57c1..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,940 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk = Signal(bool(0)) - qsfp0_tx_rst = Signal(bool(0)) - qsfp0_rx_clk = Signal(bool(0)) - qsfp0_rx_rst = Signal(bool(0)) - qsfp0_tx_axis_tready = Signal(bool(0)) - qsfp0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_rx_axis_tvalid = Signal(bool(0)) - qsfp0_rx_axis_tlast = Signal(bool(0)) - qsfp0_rx_axis_tuser = Signal(bool(0)) - qsfp0_modprsl = Signal(bool(1)) - qsfp0_intl = Signal(bool(1)) - qsfp1_tx_clk = Signal(bool(0)) - qsfp1_tx_rst = Signal(bool(0)) - qsfp1_rx_clk = Signal(bool(0)) - qsfp1_rx_rst = Signal(bool(0)) - qsfp1_tx_axis_tready = Signal(bool(0)) - qsfp1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_rx_axis_tvalid = Signal(bool(0)) - qsfp1_rx_axis_tlast = Signal(bool(0)) - qsfp1_rx_axis_tuser = Signal(bool(0)) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[3:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_tx_axis_tvalid = Signal(bool(0)) - qsfp0_tx_axis_tlast = Signal(bool(0)) - qsfp0_tx_axis_tuser = Signal(bool(0)) - qsfp0_modsell = Signal(bool(0)) - qsfp0_resetl = Signal(bool(0)) - qsfp0_lpmode = Signal(bool(0)) - qsfp1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_tx_axis_tvalid = Signal(bool(0)) - qsfp1_tx_axis_tlast = Signal(bool(0)) - qsfp1_tx_axis_tuser = Signal(bool(0)) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_source = axis_ep.AXIStreamSource() - qsfp0_source_pause = Signal(bool(False)) - - qsfp0_source_logic = qsfp0_source.create_logic( - qsfp0_rx_clk, - qsfp0_rx_rst, - tdata=qsfp0_rx_axis_tdata, - tkeep=qsfp0_rx_axis_tkeep, - tvalid=qsfp0_rx_axis_tvalid, - tlast=qsfp0_rx_axis_tlast, - tuser=qsfp0_rx_axis_tuser, - pause=qsfp0_source_pause, - name='qsfp0_source' - ) - - qsfp0_sink = axis_ep.AXIStreamSink() - qsfp0_sink_pause = Signal(bool(False)) - - qsfp0_sink_logic = qsfp0_sink.create_logic( - qsfp0_tx_clk, - qsfp0_tx_rst, - tdata=qsfp0_tx_axis_tdata, - tkeep=qsfp0_tx_axis_tkeep, - tvalid=qsfp0_tx_axis_tvalid, - tready=qsfp0_tx_axis_tready, - tlast=qsfp0_tx_axis_tlast, - tuser=qsfp0_tx_axis_tuser, - pause=qsfp0_sink_pause, - name='qsfp0_sink' - ) - - qsfp1_source = axis_ep.AXIStreamSource() - qsfp1_source_pause = Signal(bool(False)) - - qsfp1_source_logic = qsfp1_source.create_logic( - qsfp1_rx_clk, - qsfp1_rx_rst, - tdata=qsfp1_rx_axis_tdata, - tkeep=qsfp1_rx_axis_tkeep, - tvalid=qsfp1_rx_axis_tvalid, - tlast=qsfp1_rx_axis_tlast, - tuser=qsfp1_rx_axis_tuser, - pause=qsfp1_source_pause, - name='qsfp1_source' - ) - - qsfp1_sink = axis_ep.AXIStreamSink() - qsfp1_sink_pause = Signal(bool(False)) - - qsfp1_sink_logic = qsfp1_sink.create_logic( - qsfp1_tx_clk, - qsfp1_tx_rst, - tdata=qsfp1_tx_axis_tdata, - tkeep=qsfp1_tx_axis_tkeep, - tvalid=qsfp1_tx_axis_tvalid, - tready=qsfp1_tx_axis_tready, - tlast=qsfp1_tx_axis_tlast, - tuser=qsfp1_tx_axis_tuser, - pause=qsfp1_sink_pause, - name='qsfp1_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk=qsfp0_tx_clk, - qsfp0_tx_rst=qsfp0_tx_rst, - qsfp0_tx_axis_tdata=qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep=qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid=qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tready=qsfp0_tx_axis_tready, - qsfp0_tx_axis_tlast=qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser=qsfp0_tx_axis_tuser, - qsfp0_rx_clk=qsfp0_rx_clk, - qsfp0_rx_rst=qsfp0_rx_rst, - qsfp0_rx_axis_tdata=qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep=qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid=qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast=qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser=qsfp0_rx_axis_tuser, - qsfp0_modprsl=qsfp0_modprsl, - qsfp0_modsell=qsfp0_modsell, - qsfp0_resetl=qsfp0_resetl, - qsfp0_intl=qsfp0_intl, - qsfp0_lpmode=qsfp0_lpmode, - qsfp1_tx_clk=qsfp1_tx_clk, - qsfp1_tx_rst=qsfp1_tx_rst, - qsfp1_tx_axis_tdata=qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep=qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid=qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tready=qsfp1_tx_axis_tready, - qsfp1_tx_axis_tlast=qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser=qsfp1_tx_axis_tuser, - qsfp1_rx_clk=qsfp1_rx_clk, - qsfp1_rx_rst=qsfp1_rx_rst, - qsfp1_rx_axis_tdata=qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep=qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid=qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast=qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser=qsfp1_rx_axis_tuser, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp0_tx_clk.next = not qsfp0_tx_clk - qsfp0_rx_clk.next = not qsfp0_rx_clk - qsfp1_tx_clk.next = not qsfp1_tx_clk - qsfp1_rx_clk.next = not qsfp1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_sink.empty(): - pkt = qsfp0_sink.recv() - qsfp0_source.send(pkt) - if not qsfp1_sink.empty(): - pkt = qsfp1_sink.recv() - qsfp1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst.next = 1 - qsfp0_rx_rst.next = 1 - qsfp1_tx_rst.next = 1 - qsfp1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst.next = 0 - qsfp0_rx_rst.next = 0 - qsfp1_tx_rst.next = 0 - qsfp1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_sink.wait() - - # pkt = qsfp0_sink.recv() - # print(pkt) - - # qsfp0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU200/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/AU200/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index 9050d9955..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,454 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk = 0; -reg qsfp0_tx_rst = 0; -reg qsfp0_tx_axis_tready = 0; -reg qsfp0_rx_clk = 0; -reg qsfp0_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_rx_axis_tkeep = 0; -reg qsfp0_rx_axis_tvalid = 0; -reg qsfp0_rx_axis_tlast = 0; -reg qsfp0_rx_axis_tuser = 0; -reg qsfp0_modprsl = 1; -reg qsfp0_intl = 1; -reg qsfp1_tx_clk = 0; -reg qsfp1_tx_rst = 0; -reg qsfp1_tx_axis_tready = 0; -reg qsfp1_rx_clk = 0; -reg qsfp1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep = 0; -reg qsfp1_rx_axis_tvalid = 0; -reg qsfp1_rx_axis_tlast = 0; -reg qsfp1_rx_axis_tuser = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [2:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_tx_axis_tkeep; -wire qsfp0_tx_axis_tvalid; -wire qsfp0_tx_axis_tlast; -wire qsfp0_tx_axis_tuser; -wire qsfp0_modsell; -wire qsfp0_resetl; -wire qsfp0_lpmode; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep; -wire qsfp1_tx_axis_tvalid; -wire qsfp1_tx_axis_tlast; -wire qsfp1_tx_axis_tuser; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk, - qsfp0_tx_rst, - qsfp0_tx_axis_tready, - qsfp0_rx_clk, - qsfp0_rx_rst, - qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser, - qsfp0_modprsl, - qsfp0_intl, - qsfp1_tx_clk, - qsfp1_tx_rst, - qsfp1_tx_axis_tready, - qsfp1_rx_clk, - qsfp1_rx_rst, - qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser, - qsfp1_modprsl, - qsfp1_intl, - qspi_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser, - qsfp0_modsell, - qsfp0_resetl, - qsfp0_lpmode, - qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk(qsfp0_tx_clk), - .qsfp0_tx_rst(qsfp0_tx_rst), - .qsfp0_tx_axis_tdata(qsfp0_tx_axis_tdata), - .qsfp0_tx_axis_tkeep(qsfp0_tx_axis_tkeep), - .qsfp0_tx_axis_tvalid(qsfp0_tx_axis_tvalid), - .qsfp0_tx_axis_tready(qsfp0_tx_axis_tready), - .qsfp0_tx_axis_tlast(qsfp0_tx_axis_tlast), - .qsfp0_tx_axis_tuser(qsfp0_tx_axis_tuser), - .qsfp0_rx_clk(qsfp0_rx_clk), - .qsfp0_rx_rst(qsfp0_rx_rst), - .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata), - .qsfp0_rx_axis_tkeep(qsfp0_rx_axis_tkeep), - .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid), - .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast), - .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser), - .qsfp0_modprsl(qsfp0_modprsl_int), - .qsfp0_modsell(qsfp0_modsell), - .qsfp0_resetl(qsfp0_resetl), - .qsfp0_intl(qsfp0_intl_int), - .qsfp0_lpmode(qsfp0_lpmode_int), - .qsfp1_tx_clk(qsfp1_tx_clk), - .qsfp1_tx_rst(qsfp1_tx_rst), - .qsfp1_tx_axis_tdata(qsfp1_tx_axis_tdata), - .qsfp1_tx_axis_tkeep(qsfp1_tx_axis_tkeep), - .qsfp1_tx_axis_tvalid(qsfp1_tx_axis_tvalid), - .qsfp1_tx_axis_tready(qsfp1_tx_axis_tready), - .qsfp1_tx_axis_tlast(qsfp1_tx_axis_tlast), - .qsfp1_tx_axis_tuser(qsfp1_tx_axis_tuser), - .qsfp1_rx_clk(qsfp1_rx_clk), - .qsfp1_rx_rst(qsfp1_rx_rst), - .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata), - .qsfp1_rx_axis_tkeep(qsfp1_rx_axis_tkeep), - .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid), - .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast), - .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU200/fpga_100g/tb/udp_ep.py b/fpga/mqnic/AU200/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_100g/tb/xgmii_ep.py b/fpga/mqnic/AU200/fpga_100g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU200/fpga_100g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/axis_ep.py b/fpga/mqnic/AU200/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/eth_ep.py b/fpga/mqnic/AU200/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..73e65ecb4 --- /dev/null +++ b/fpga/mqnic/AU200/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,655 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) + cocotb.fork(Clock(dut.qsfp0_tx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp0_rx_error_count_3.setimmediatevalue(0) + dut.qsfp0_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_1_sink.empty(): + self.qsfp0_1_source.send(self.qsfp0_1_sink.recv()) + if not self.qsfp0_2_sink.empty(): + self.qsfp0_2_source.send(self.qsfp0_2_sink.recv()) + if not self.qsfp0_3_sink.empty(): + self.qsfp0_3_source.send(self.qsfp0_3_sink.recv()) + if not self.qsfp0_4_sink.empty(): + self.qsfp0_4_source.send(self.qsfp0_4_sink.recv()) + if not self.qsfp1_1_sink.empty(): + self.qsfp1_1_source.send(self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + self.qsfp1_2_source.send(self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + self.qsfp1_3_source.send(self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + self.qsfp1_4_source.send(self.qsfp1_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_1_sink.wait() + + # pkt = tb.qsfp1_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU200/fpga_10g/tb/ip_ep.py b/fpga/mqnic/AU200/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/mqnic.py b/fpga/mqnic/AU200/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/pcie.py b/fpga/mqnic/AU200/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/pcie_us.py b/fpga/mqnic/AU200/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/AU200/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/AU200/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 3afc41b44..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1028 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk_1 = Signal(bool(0)) - qsfp0_tx_rst_1 = Signal(bool(0)) - qsfp0_rx_clk_1 = Signal(bool(0)) - qsfp0_rx_rst_1 = Signal(bool(0)) - qsfp0_rxd_1 = Signal(intbv(0)[64:]) - qsfp0_rxc_1 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_2 = Signal(bool(0)) - qsfp0_tx_rst_2 = Signal(bool(0)) - qsfp0_rx_clk_2 = Signal(bool(0)) - qsfp0_rx_rst_2 = Signal(bool(0)) - qsfp0_rxd_2 = Signal(intbv(0)[64:]) - qsfp0_rxc_2 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_3 = Signal(bool(0)) - qsfp0_tx_rst_3 = Signal(bool(0)) - qsfp0_rx_clk_3 = Signal(bool(0)) - qsfp0_rx_rst_3 = Signal(bool(0)) - qsfp0_rxd_3 = Signal(intbv(0)[64:]) - qsfp0_rxc_3 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_4 = Signal(bool(0)) - qsfp0_tx_rst_4 = Signal(bool(0)) - qsfp0_rx_clk_4 = Signal(bool(0)) - qsfp0_rx_rst_4 = Signal(bool(0)) - qsfp0_rxd_4 = Signal(intbv(0)[64:]) - qsfp0_rxc_4 = Signal(intbv(0)[8:]) - qsfp0_modprsl = Signal(bool(1)) - qsfp0_intl = Signal(bool(1)) - qsfp1_tx_clk_1 = Signal(bool(0)) - qsfp1_tx_rst_1 = Signal(bool(0)) - qsfp1_rx_clk_1 = Signal(bool(0)) - qsfp1_rx_rst_1 = Signal(bool(0)) - qsfp1_rxd_1 = Signal(intbv(0)[64:]) - qsfp1_rxc_1 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_2 = Signal(bool(0)) - qsfp1_tx_rst_2 = Signal(bool(0)) - qsfp1_rx_clk_2 = Signal(bool(0)) - qsfp1_rx_rst_2 = Signal(bool(0)) - qsfp1_rxd_2 = Signal(intbv(0)[64:]) - qsfp1_rxc_2 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_3 = Signal(bool(0)) - qsfp1_tx_rst_3 = Signal(bool(0)) - qsfp1_rx_clk_3 = Signal(bool(0)) - qsfp1_rx_rst_3 = Signal(bool(0)) - qsfp1_rxd_3 = Signal(intbv(0)[64:]) - qsfp1_rxc_3 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_4 = Signal(bool(0)) - qsfp1_tx_rst_4 = Signal(bool(0)) - qsfp1_rx_clk_4 = Signal(bool(0)) - qsfp1_rx_rst_4 = Signal(bool(0)) - qsfp1_rxd_4 = Signal(intbv(0)[64:]) - qsfp1_rxc_4 = Signal(intbv(0)[8:]) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[3:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_txd_1 = Signal(intbv(0)[64:]) - qsfp0_txc_1 = Signal(intbv(0)[8:]) - qsfp0_txd_2 = Signal(intbv(0)[64:]) - qsfp0_txc_2 = Signal(intbv(0)[8:]) - qsfp0_txd_3 = Signal(intbv(0)[64:]) - qsfp0_txc_3 = Signal(intbv(0)[8:]) - qsfp0_txd_4 = Signal(intbv(0)[64:]) - qsfp0_txc_4 = Signal(intbv(0)[8:]) - qsfp0_modsell = Signal(bool(0)) - qsfp0_resetl = Signal(bool(0)) - qsfp0_lpmode = Signal(bool(0)) - qsfp1_txd_1 = Signal(intbv(0)[64:]) - qsfp1_txc_1 = Signal(intbv(0)[8:]) - qsfp1_txd_2 = Signal(intbv(0)[64:]) - qsfp1_txc_2 = Signal(intbv(0)[8:]) - qsfp1_txd_3 = Signal(intbv(0)[64:]) - qsfp1_txc_3 = Signal(intbv(0)[8:]) - qsfp1_txd_4 = Signal(intbv(0)[64:]) - qsfp1_txc_4 = Signal(intbv(0)[8:]) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_1_source = xgmii_ep.XGMIISource() - qsfp0_1_source_logic = qsfp0_1_source.create_logic(qsfp0_rx_clk_1, qsfp0_rx_rst_1, txd=qsfp0_rxd_1, txc=qsfp0_rxc_1, name='qsfp0_1_source') - - qsfp0_1_sink = xgmii_ep.XGMIISink() - qsfp0_1_sink_logic = qsfp0_1_sink.create_logic(qsfp0_tx_clk_1, qsfp0_tx_rst_1, rxd=qsfp0_txd_1, rxc=qsfp0_txc_1, name='qsfp0_1_sink') - - qsfp0_2_source = xgmii_ep.XGMIISource() - qsfp0_2_source_logic = qsfp0_2_source.create_logic(qsfp0_rx_clk_2, qsfp0_rx_rst_2, txd=qsfp0_rxd_2, txc=qsfp0_rxc_2, name='qsfp0_2_source') - - qsfp0_2_sink = xgmii_ep.XGMIISink() - qsfp0_2_sink_logic = qsfp0_2_sink.create_logic(qsfp0_tx_clk_2, qsfp0_tx_rst_2, rxd=qsfp0_txd_2, rxc=qsfp0_txc_2, name='qsfp0_2_sink') - - qsfp0_3_source = xgmii_ep.XGMIISource() - qsfp0_3_source_logic = qsfp0_3_source.create_logic(qsfp0_rx_clk_3, qsfp0_rx_rst_3, txd=qsfp0_rxd_3, txc=qsfp0_rxc_3, name='qsfp0_3_source') - - qsfp0_3_sink = xgmii_ep.XGMIISink() - qsfp0_3_sink_logic = qsfp0_3_sink.create_logic(qsfp0_tx_clk_3, qsfp0_tx_rst_3, rxd=qsfp0_txd_3, rxc=qsfp0_txc_3, name='qsfp0_3_sink') - - qsfp0_4_source = xgmii_ep.XGMIISource() - qsfp0_4_source_logic = qsfp0_4_source.create_logic(qsfp0_rx_clk_4, qsfp0_rx_rst_4, txd=qsfp0_rxd_4, txc=qsfp0_rxc_4, name='qsfp0_4_source') - - qsfp0_4_sink = xgmii_ep.XGMIISink() - qsfp0_4_sink_logic = qsfp0_4_sink.create_logic(qsfp0_tx_clk_4, qsfp0_tx_rst_4, rxd=qsfp0_txd_4, rxc=qsfp0_txc_4, name='qsfp0_4_sink') - - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') - - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') - - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') - - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') - - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') - - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') - - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') - - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk_1=qsfp0_tx_clk_1, - qsfp0_tx_rst_1=qsfp0_tx_rst_1, - qsfp0_txd_1=qsfp0_txd_1, - qsfp0_txc_1=qsfp0_txc_1, - qsfp0_rx_clk_1=qsfp0_rx_clk_1, - qsfp0_rx_rst_1=qsfp0_rx_rst_1, - qsfp0_rxd_1=qsfp0_rxd_1, - qsfp0_rxc_1=qsfp0_rxc_1, - qsfp0_tx_clk_2=qsfp0_tx_clk_2, - qsfp0_tx_rst_2=qsfp0_tx_rst_2, - qsfp0_txd_2=qsfp0_txd_2, - qsfp0_txc_2=qsfp0_txc_2, - qsfp0_rx_clk_2=qsfp0_rx_clk_2, - qsfp0_rx_rst_2=qsfp0_rx_rst_2, - qsfp0_rxd_2=qsfp0_rxd_2, - qsfp0_rxc_2=qsfp0_rxc_2, - qsfp0_tx_clk_3=qsfp0_tx_clk_3, - qsfp0_tx_rst_3=qsfp0_tx_rst_3, - qsfp0_txd_3=qsfp0_txd_3, - qsfp0_txc_3=qsfp0_txc_3, - qsfp0_rx_clk_3=qsfp0_rx_clk_3, - qsfp0_rx_rst_3=qsfp0_rx_rst_3, - qsfp0_rxd_3=qsfp0_rxd_3, - qsfp0_rxc_3=qsfp0_rxc_3, - qsfp0_tx_clk_4=qsfp0_tx_clk_4, - qsfp0_tx_rst_4=qsfp0_tx_rst_4, - qsfp0_txd_4=qsfp0_txd_4, - qsfp0_txc_4=qsfp0_txc_4, - qsfp0_rx_clk_4=qsfp0_rx_clk_4, - qsfp0_rx_rst_4=qsfp0_rx_rst_4, - qsfp0_rxd_4=qsfp0_rxd_4, - qsfp0_rxc_4=qsfp0_rxc_4, - qsfp0_modprsl=qsfp0_modprsl, - qsfp0_modsell=qsfp0_modsell, - qsfp0_resetl=qsfp0_resetl, - qsfp0_intl=qsfp0_intl, - qsfp0_lpmode=qsfp0_lpmode, - qsfp1_tx_clk_1=qsfp1_tx_clk_1, - qsfp1_tx_rst_1=qsfp1_tx_rst_1, - qsfp1_txd_1=qsfp1_txd_1, - qsfp1_txc_1=qsfp1_txc_1, - qsfp1_rx_clk_1=qsfp1_rx_clk_1, - qsfp1_rx_rst_1=qsfp1_rx_rst_1, - qsfp1_rxd_1=qsfp1_rxd_1, - qsfp1_rxc_1=qsfp1_rxc_1, - qsfp1_tx_clk_2=qsfp1_tx_clk_2, - qsfp1_tx_rst_2=qsfp1_tx_rst_2, - qsfp1_txd_2=qsfp1_txd_2, - qsfp1_txc_2=qsfp1_txc_2, - qsfp1_rx_clk_2=qsfp1_rx_clk_2, - qsfp1_rx_rst_2=qsfp1_rx_rst_2, - qsfp1_rxd_2=qsfp1_rxd_2, - qsfp1_rxc_2=qsfp1_rxc_2, - qsfp1_tx_clk_3=qsfp1_tx_clk_3, - qsfp1_tx_rst_3=qsfp1_tx_rst_3, - qsfp1_txd_3=qsfp1_txd_3, - qsfp1_txc_3=qsfp1_txc_3, - qsfp1_rx_clk_3=qsfp1_rx_clk_3, - qsfp1_rx_rst_3=qsfp1_rx_rst_3, - qsfp1_rxd_3=qsfp1_rxd_3, - qsfp1_rxc_3=qsfp1_rxc_3, - qsfp1_tx_clk_4=qsfp1_tx_clk_4, - qsfp1_tx_rst_4=qsfp1_tx_rst_4, - qsfp1_txd_4=qsfp1_txd_4, - qsfp1_txc_4=qsfp1_txc_4, - qsfp1_rx_clk_4=qsfp1_rx_clk_4, - qsfp1_rx_rst_4=qsfp1_rx_rst_4, - qsfp1_rxd_4=qsfp1_rxd_4, - qsfp1_rxc_4=qsfp1_rxc_4, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp0_tx_clk_1.next = not qsfp0_tx_clk_1 - qsfp0_rx_clk_1.next = not qsfp0_rx_clk_1 - qsfp0_tx_clk_2.next = not qsfp0_tx_clk_2 - qsfp0_rx_clk_2.next = not qsfp0_rx_clk_2 - qsfp0_tx_clk_3.next = not qsfp0_tx_clk_3 - qsfp0_rx_clk_3.next = not qsfp0_rx_clk_3 - qsfp0_tx_clk_4.next = not qsfp0_tx_clk_4 - qsfp0_rx_clk_4.next = not qsfp0_rx_clk_4 - qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 - qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 - qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 - qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 - qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 - qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 - qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 - qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_1_sink.empty(): - pkt = qsfp0_1_sink.recv() - qsfp0_1_source.send(pkt) - if not qsfp0_2_sink.empty(): - pkt = qsfp0_2_sink.recv() - qsfp0_2_source.send(pkt) - if not qsfp0_3_sink.empty(): - pkt = qsfp0_3_sink.recv() - qsfp0_3_source.send(pkt) - if not qsfp0_4_sink.empty(): - pkt = qsfp0_4_sink.recv() - qsfp0_4_source.send(pkt) - if not qsfp1_1_sink.empty(): - pkt = qsfp1_1_sink.recv() - qsfp1_1_source.send(pkt) - if not qsfp1_2_sink.empty(): - pkt = qsfp1_2_sink.recv() - qsfp1_2_source.send(pkt) - if not qsfp1_3_sink.empty(): - pkt = qsfp1_3_sink.recv() - qsfp1_3_source.send(pkt) - if not qsfp1_4_sink.empty(): - pkt = qsfp1_4_sink.recv() - qsfp1_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst_1.next = 1 - qsfp0_rx_rst_1.next = 1 - qsfp0_tx_rst_2.next = 1 - qsfp0_rx_rst_2.next = 1 - qsfp0_tx_rst_3.next = 1 - qsfp0_rx_rst_3.next = 1 - qsfp0_tx_rst_4.next = 1 - qsfp0_rx_rst_4.next = 1 - qsfp1_tx_rst_1.next = 1 - qsfp1_rx_rst_1.next = 1 - qsfp1_tx_rst_2.next = 1 - qsfp1_rx_rst_2.next = 1 - qsfp1_tx_rst_3.next = 1 - qsfp1_rx_rst_3.next = 1 - qsfp1_tx_rst_4.next = 1 - qsfp1_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst_1.next = 0 - qsfp0_rx_rst_1.next = 0 - qsfp0_tx_rst_2.next = 0 - qsfp0_rx_rst_2.next = 0 - qsfp0_tx_rst_3.next = 0 - qsfp0_rx_rst_3.next = 0 - qsfp0_tx_rst_4.next = 0 - qsfp0_rx_rst_4.next = 0 - qsfp1_tx_rst_1.next = 0 - qsfp1_rx_rst_1.next = 0 - qsfp1_tx_rst_2.next = 0 - qsfp1_rx_rst_2.next = 0 - qsfp1_tx_rst_3.next = 0 - qsfp1_rx_rst_3.next = 0 - qsfp1_tx_rst_4.next = 0 - qsfp1_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_1_sink.wait() - - # pkt = qsfp0_1_sink.recv() - # print(pkt) - - # qsfp0_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU200/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/AU200/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 8335c86b3..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,552 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk_1 = 0; -reg qsfp0_tx_rst_1 = 0; -reg qsfp0_rx_clk_1 = 0; -reg qsfp0_rx_rst_1 = 0; -reg [63:0] qsfp0_rxd_1 = 0; -reg [7:0] qsfp0_rxc_1 = 0; -reg qsfp0_tx_clk_2 = 0; -reg qsfp0_tx_rst_2 = 0; -reg qsfp0_rx_clk_2 = 0; -reg qsfp0_rx_rst_2 = 0; -reg [63:0] qsfp0_rxd_2 = 0; -reg [7:0] qsfp0_rxc_2 = 0; -reg qsfp0_tx_clk_3 = 0; -reg qsfp0_tx_rst_3 = 0; -reg qsfp0_rx_clk_3 = 0; -reg qsfp0_rx_rst_3 = 0; -reg [63:0] qsfp0_rxd_3 = 0; -reg [7:0] qsfp0_rxc_3 = 0; -reg qsfp0_tx_clk_4 = 0; -reg qsfp0_tx_rst_4 = 0; -reg qsfp0_rx_clk_4 = 0; -reg qsfp0_rx_rst_4 = 0; -reg [63:0] qsfp0_rxd_4 = 0; -reg [7:0] qsfp0_rxc_4 = 0; -reg qsfp0_modprsl = 1; -reg qsfp0_intl = 1; -reg qsfp1_tx_clk_1 = 0; -reg qsfp1_tx_rst_1 = 0; -reg qsfp1_rx_clk_1 = 0; -reg qsfp1_rx_rst_1 = 0; -reg [63:0] qsfp1_rxd_1 = 0; -reg [7:0] qsfp1_rxc_1 = 0; -reg qsfp1_tx_clk_2 = 0; -reg qsfp1_tx_rst_2 = 0; -reg qsfp1_rx_clk_2 = 0; -reg qsfp1_rx_rst_2 = 0; -reg [63:0] qsfp1_rxd_2 = 0; -reg [7:0] qsfp1_rxc_2 = 0; -reg qsfp1_tx_clk_3 = 0; -reg qsfp1_tx_rst_3 = 0; -reg qsfp1_rx_clk_3 = 0; -reg qsfp1_rx_rst_3 = 0; -reg [63:0] qsfp1_rxd_3 = 0; -reg [7:0] qsfp1_rxc_3 = 0; -reg qsfp1_tx_clk_4 = 0; -reg qsfp1_tx_rst_4 = 0; -reg qsfp1_rx_clk_4 = 0; -reg qsfp1_rx_rst_4 = 0; -reg [63:0] qsfp1_rxd_4 = 0; -reg [7:0] qsfp1_rxc_4 = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [2:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp0_txd_1; -wire [7:0] qsfp0_txc_1; -wire [63:0] qsfp0_txd_2; -wire [7:0] qsfp0_txc_2; -wire [63:0] qsfp0_txd_3; -wire [7:0] qsfp0_txc_3; -wire [63:0] qsfp0_txd_4; -wire [7:0] qsfp0_txc_4; -wire qsfp0_modsell; -wire qsfp0_resetl; -wire qsfp0_lpmode; -wire [63:0] qsfp1_txd_1; -wire [7:0] qsfp1_txc_1; -wire [63:0] qsfp1_txd_2; -wire [7:0] qsfp1_txc_2; -wire [63:0] qsfp1_txd_3; -wire [7:0] qsfp1_txc_3; -wire [63:0] qsfp1_txd_4; -wire [7:0] qsfp1_txc_4; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk_1, - qsfp0_tx_rst_1, - qsfp0_rx_clk_1, - qsfp0_rx_rst_1, - qsfp0_rxd_1, - qsfp0_rxc_1, - qsfp0_tx_clk_2, - qsfp0_tx_rst_2, - qsfp0_rx_clk_2, - qsfp0_rx_rst_2, - qsfp0_rxd_2, - qsfp0_rxc_2, - qsfp0_tx_clk_3, - qsfp0_tx_rst_3, - qsfp0_rx_clk_3, - qsfp0_rx_rst_3, - qsfp0_rxd_3, - qsfp0_rxc_3, - qsfp0_tx_clk_4, - qsfp0_tx_rst_4, - qsfp0_rx_clk_4, - qsfp0_rx_rst_4, - qsfp0_rxd_4, - qsfp0_rxc_4, - qsfp0_modprsl, - qsfp0_intl, - qsfp1_tx_clk_1, - qsfp1_tx_rst_1, - qsfp1_rx_clk_1, - qsfp1_rx_rst_1, - qsfp1_rxd_1, - qsfp1_rxc_1, - qsfp1_tx_clk_2, - qsfp1_tx_rst_2, - qsfp1_rx_clk_2, - qsfp1_rx_rst_2, - qsfp1_rxd_2, - qsfp1_rxc_2, - qsfp1_tx_clk_3, - qsfp1_tx_rst_3, - qsfp1_rx_clk_3, - qsfp1_rx_rst_3, - qsfp1_rxd_3, - qsfp1_rxc_3, - qsfp1_tx_clk_4, - qsfp1_tx_rst_4, - qsfp1_rx_clk_4, - qsfp1_rx_rst_4, - qsfp1_rxd_4, - qsfp1_rxc_4, - qsfp1_modprsl, - qsfp1_intl, - qspi_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_txd_1, - qsfp0_txc_1, - qsfp0_txd_2, - qsfp0_txc_2, - qsfp0_txd_3, - qsfp0_txc_3, - qsfp0_txd_4, - qsfp0_txc_4, - qsfp0_modsell, - qsfp0_resetl, - qsfp0_lpmode, - qsfp1_txd_1, - qsfp1_txc_1, - qsfp1_txd_2, - qsfp1_txc_2, - qsfp1_txd_3, - qsfp1_txc_3, - qsfp1_txd_4, - qsfp1_txc_4, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk_1(qsfp0_tx_clk_1), - .qsfp0_tx_rst_1(qsfp0_tx_rst_1), - .qsfp0_txd_1(qsfp0_txd_1), - .qsfp0_txc_1(qsfp0_txc_1), - .qsfp0_rx_clk_1(qsfp0_rx_clk_1), - .qsfp0_rx_rst_1(qsfp0_rx_rst_1), - .qsfp0_rxd_1(qsfp0_rxd_1), - .qsfp0_rxc_1(qsfp0_rxc_1), - .qsfp0_tx_clk_2(qsfp0_tx_clk_2), - .qsfp0_tx_rst_2(qsfp0_tx_rst_2), - .qsfp0_txd_2(qsfp0_txd_2), - .qsfp0_txc_2(qsfp0_txc_2), - .qsfp0_rx_clk_2(qsfp0_rx_clk_2), - .qsfp0_rx_rst_2(qsfp0_rx_rst_2), - .qsfp0_rxd_2(qsfp0_rxd_2), - .qsfp0_rxc_2(qsfp0_rxc_2), - .qsfp0_tx_clk_3(qsfp0_tx_clk_3), - .qsfp0_tx_rst_3(qsfp0_tx_rst_3), - .qsfp0_txd_3(qsfp0_txd_3), - .qsfp0_txc_3(qsfp0_txc_3), - .qsfp0_rx_clk_3(qsfp0_rx_clk_3), - .qsfp0_rx_rst_3(qsfp0_rx_rst_3), - .qsfp0_rxd_3(qsfp0_rxd_3), - .qsfp0_rxc_3(qsfp0_rxc_3), - .qsfp0_tx_clk_4(qsfp0_tx_clk_4), - .qsfp0_tx_rst_4(qsfp0_tx_rst_4), - .qsfp0_txd_4(qsfp0_txd_4), - .qsfp0_txc_4(qsfp0_txc_4), - .qsfp0_rx_clk_4(qsfp0_rx_clk_4), - .qsfp0_rx_rst_4(qsfp0_rx_rst_4), - .qsfp0_rxd_4(qsfp0_rxd_4), - .qsfp0_rxc_4(qsfp0_rxc_4), - .qsfp0_modprsl(qsfp0_modprsl_int), - .qsfp0_modsell(qsfp0_modsell), - .qsfp0_resetl(qsfp0_resetl), - .qsfp0_intl(qsfp0_intl_int), - .qsfp0_lpmode(qsfp0_lpmode_int), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1), - .qsfp1_txd_1(qsfp1_txd_1), - .qsfp1_txc_1(qsfp1_txc_1), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1), - .qsfp1_rxd_1(qsfp1_rxd_1), - .qsfp1_rxc_1(qsfp1_rxc_1), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2), - .qsfp1_txd_2(qsfp1_txd_2), - .qsfp1_txc_2(qsfp1_txc_2), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2), - .qsfp1_rxd_2(qsfp1_rxd_2), - .qsfp1_rxc_2(qsfp1_rxc_2), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3), - .qsfp1_txd_3(qsfp1_txd_3), - .qsfp1_txc_3(qsfp1_txc_3), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3), - .qsfp1_rxd_3(qsfp1_rxd_3), - .qsfp1_rxc_3(qsfp1_rxc_3), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4), - .qsfp1_txd_4(qsfp1_txd_4), - .qsfp1_txc_4(qsfp1_txc_4), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4), - .qsfp1_rxd_4(qsfp1_rxd_4), - .qsfp1_rxc_4(qsfp1_rxc_4), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU200/fpga_10g/tb/udp_ep.py b/fpga/mqnic/AU200/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU200/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/AU200/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU200/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/axis_ep.py b/fpga/mqnic/AU250/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/eth_ep.py b/fpga/mqnic/AU250/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..f07e38848 --- /dev/null +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,154 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_pipeline_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..47bfb31f3 --- /dev/null +++ b/fpga/mqnic/AU250/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,586 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk, 3.102, units="ns").start()) + self.qsfp0_source = AxiStreamSource(dut, "qsfp0_rx_axis", dut.qsfp0_rx_clk, dut.qsfp0_rx_rst) + cocotb.fork(Clock(dut.qsfp0_tx_clk, 3.102, units="ns").start()) + self.qsfp0_sink = AxiStreamSink(dut, "qsfp0_tx_axis", dut.qsfp0_tx_clk, dut.qsfp0_tx_rst) + + cocotb.fork(Clock(dut.qsfp1_rx_clk, 3.102, units="ns").start()) + self.qsfp1_source = AxiStreamSource(dut, "qsfp1_rx_axis", dut.qsfp1_rx_clk, dut.qsfp1_rx_rst) + cocotb.fork(Clock(dut.qsfp1_tx_clk, 3.102, units="ns").start()) + self.qsfp1_sink = AxiStreamSink(dut, "qsfp1_tx_axis", dut.qsfp1_tx_clk, dut.qsfp1_tx_rst) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(1) + self.dut.qsfp0_tx_rst.setimmediatevalue(1) + self.dut.qsfp1_rx_rst.setimmediatevalue(1) + self.dut.qsfp1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_sink.empty(): + self.qsfp0_source.send(self.qsfp0_sink.recv()) + if not self.qsfp1_sink.empty(): + self.qsfp1_source.send(self.qsfp1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_0_sink.wait() + + # pkt = tb.qsfp1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(axis_rtl_dir, "axis_pipeline_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU250/fpga_100g/tb/ip_ep.py b/fpga/mqnic/AU250/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/mqnic.py b/fpga/mqnic/AU250/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/pcie.py b/fpga/mqnic/AU250/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/pcie_us.py b/fpga/mqnic/AU250/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/AU250/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/AU250/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index 87bcfae90..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,941 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_pipeline_register.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk = Signal(bool(0)) - qsfp0_tx_rst = Signal(bool(0)) - qsfp0_rx_clk = Signal(bool(0)) - qsfp0_rx_rst = Signal(bool(0)) - qsfp0_tx_axis_tready = Signal(bool(0)) - qsfp0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_rx_axis_tvalid = Signal(bool(0)) - qsfp0_rx_axis_tlast = Signal(bool(0)) - qsfp0_rx_axis_tuser = Signal(bool(0)) - qsfp0_modprsl = Signal(bool(1)) - qsfp0_intl = Signal(bool(1)) - qsfp1_tx_clk = Signal(bool(0)) - qsfp1_tx_rst = Signal(bool(0)) - qsfp1_rx_clk = Signal(bool(0)) - qsfp1_rx_rst = Signal(bool(0)) - qsfp1_tx_axis_tready = Signal(bool(0)) - qsfp1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_rx_axis_tvalid = Signal(bool(0)) - qsfp1_rx_axis_tlast = Signal(bool(0)) - qsfp1_rx_axis_tuser = Signal(bool(0)) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[3:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_tx_axis_tvalid = Signal(bool(0)) - qsfp0_tx_axis_tlast = Signal(bool(0)) - qsfp0_tx_axis_tuser = Signal(bool(0)) - qsfp0_modsell = Signal(bool(0)) - qsfp0_resetl = Signal(bool(0)) - qsfp0_lpmode = Signal(bool(0)) - qsfp1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_tx_axis_tvalid = Signal(bool(0)) - qsfp1_tx_axis_tlast = Signal(bool(0)) - qsfp1_tx_axis_tuser = Signal(bool(0)) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_source = axis_ep.AXIStreamSource() - qsfp0_source_pause = Signal(bool(False)) - - qsfp0_source_logic = qsfp0_source.create_logic( - qsfp0_rx_clk, - qsfp0_rx_rst, - tdata=qsfp0_rx_axis_tdata, - tkeep=qsfp0_rx_axis_tkeep, - tvalid=qsfp0_rx_axis_tvalid, - tlast=qsfp0_rx_axis_tlast, - tuser=qsfp0_rx_axis_tuser, - pause=qsfp0_source_pause, - name='qsfp0_source' - ) - - qsfp0_sink = axis_ep.AXIStreamSink() - qsfp0_sink_pause = Signal(bool(False)) - - qsfp0_sink_logic = qsfp0_sink.create_logic( - qsfp0_tx_clk, - qsfp0_tx_rst, - tdata=qsfp0_tx_axis_tdata, - tkeep=qsfp0_tx_axis_tkeep, - tvalid=qsfp0_tx_axis_tvalid, - tready=qsfp0_tx_axis_tready, - tlast=qsfp0_tx_axis_tlast, - tuser=qsfp0_tx_axis_tuser, - pause=qsfp0_sink_pause, - name='qsfp0_sink' - ) - - qsfp1_source = axis_ep.AXIStreamSource() - qsfp1_source_pause = Signal(bool(False)) - - qsfp1_source_logic = qsfp1_source.create_logic( - qsfp1_rx_clk, - qsfp1_rx_rst, - tdata=qsfp1_rx_axis_tdata, - tkeep=qsfp1_rx_axis_tkeep, - tvalid=qsfp1_rx_axis_tvalid, - tlast=qsfp1_rx_axis_tlast, - tuser=qsfp1_rx_axis_tuser, - pause=qsfp1_source_pause, - name='qsfp1_source' - ) - - qsfp1_sink = axis_ep.AXIStreamSink() - qsfp1_sink_pause = Signal(bool(False)) - - qsfp1_sink_logic = qsfp1_sink.create_logic( - qsfp1_tx_clk, - qsfp1_tx_rst, - tdata=qsfp1_tx_axis_tdata, - tkeep=qsfp1_tx_axis_tkeep, - tvalid=qsfp1_tx_axis_tvalid, - tready=qsfp1_tx_axis_tready, - tlast=qsfp1_tx_axis_tlast, - tuser=qsfp1_tx_axis_tuser, - pause=qsfp1_sink_pause, - name='qsfp1_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk=qsfp0_tx_clk, - qsfp0_tx_rst=qsfp0_tx_rst, - qsfp0_tx_axis_tdata=qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep=qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid=qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tready=qsfp0_tx_axis_tready, - qsfp0_tx_axis_tlast=qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser=qsfp0_tx_axis_tuser, - qsfp0_rx_clk=qsfp0_rx_clk, - qsfp0_rx_rst=qsfp0_rx_rst, - qsfp0_rx_axis_tdata=qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep=qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid=qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast=qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser=qsfp0_rx_axis_tuser, - qsfp0_modprsl=qsfp0_modprsl, - qsfp0_modsell=qsfp0_modsell, - qsfp0_resetl=qsfp0_resetl, - qsfp0_intl=qsfp0_intl, - qsfp0_lpmode=qsfp0_lpmode, - qsfp1_tx_clk=qsfp1_tx_clk, - qsfp1_tx_rst=qsfp1_tx_rst, - qsfp1_tx_axis_tdata=qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep=qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid=qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tready=qsfp1_tx_axis_tready, - qsfp1_tx_axis_tlast=qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser=qsfp1_tx_axis_tuser, - qsfp1_rx_clk=qsfp1_rx_clk, - qsfp1_rx_rst=qsfp1_rx_rst, - qsfp1_rx_axis_tdata=qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep=qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid=qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast=qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser=qsfp1_rx_axis_tuser, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp0_tx_clk.next = not qsfp0_tx_clk - qsfp0_rx_clk.next = not qsfp0_rx_clk - qsfp1_tx_clk.next = not qsfp1_tx_clk - qsfp1_rx_clk.next = not qsfp1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_sink.empty(): - pkt = qsfp0_sink.recv() - qsfp0_source.send(pkt) - if not qsfp1_sink.empty(): - pkt = qsfp1_sink.recv() - qsfp1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst.next = 1 - qsfp0_rx_rst.next = 1 - qsfp1_tx_rst.next = 1 - qsfp1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst.next = 0 - qsfp0_rx_rst.next = 0 - qsfp1_tx_rst.next = 0 - qsfp1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_sink.wait() - - # pkt = qsfp0_sink.recv() - # print(pkt) - - # qsfp0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU250/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/AU250/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index 9050d9955..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,454 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk = 0; -reg qsfp0_tx_rst = 0; -reg qsfp0_tx_axis_tready = 0; -reg qsfp0_rx_clk = 0; -reg qsfp0_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_rx_axis_tkeep = 0; -reg qsfp0_rx_axis_tvalid = 0; -reg qsfp0_rx_axis_tlast = 0; -reg qsfp0_rx_axis_tuser = 0; -reg qsfp0_modprsl = 1; -reg qsfp0_intl = 1; -reg qsfp1_tx_clk = 0; -reg qsfp1_tx_rst = 0; -reg qsfp1_tx_axis_tready = 0; -reg qsfp1_rx_clk = 0; -reg qsfp1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep = 0; -reg qsfp1_rx_axis_tvalid = 0; -reg qsfp1_rx_axis_tlast = 0; -reg qsfp1_rx_axis_tuser = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [2:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_tx_axis_tkeep; -wire qsfp0_tx_axis_tvalid; -wire qsfp0_tx_axis_tlast; -wire qsfp0_tx_axis_tuser; -wire qsfp0_modsell; -wire qsfp0_resetl; -wire qsfp0_lpmode; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep; -wire qsfp1_tx_axis_tvalid; -wire qsfp1_tx_axis_tlast; -wire qsfp1_tx_axis_tuser; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk, - qsfp0_tx_rst, - qsfp0_tx_axis_tready, - qsfp0_rx_clk, - qsfp0_rx_rst, - qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser, - qsfp0_modprsl, - qsfp0_intl, - qsfp1_tx_clk, - qsfp1_tx_rst, - qsfp1_tx_axis_tready, - qsfp1_rx_clk, - qsfp1_rx_rst, - qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser, - qsfp1_modprsl, - qsfp1_intl, - qspi_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser, - qsfp0_modsell, - qsfp0_resetl, - qsfp0_lpmode, - qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk(qsfp0_tx_clk), - .qsfp0_tx_rst(qsfp0_tx_rst), - .qsfp0_tx_axis_tdata(qsfp0_tx_axis_tdata), - .qsfp0_tx_axis_tkeep(qsfp0_tx_axis_tkeep), - .qsfp0_tx_axis_tvalid(qsfp0_tx_axis_tvalid), - .qsfp0_tx_axis_tready(qsfp0_tx_axis_tready), - .qsfp0_tx_axis_tlast(qsfp0_tx_axis_tlast), - .qsfp0_tx_axis_tuser(qsfp0_tx_axis_tuser), - .qsfp0_rx_clk(qsfp0_rx_clk), - .qsfp0_rx_rst(qsfp0_rx_rst), - .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata), - .qsfp0_rx_axis_tkeep(qsfp0_rx_axis_tkeep), - .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid), - .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast), - .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser), - .qsfp0_modprsl(qsfp0_modprsl_int), - .qsfp0_modsell(qsfp0_modsell), - .qsfp0_resetl(qsfp0_resetl), - .qsfp0_intl(qsfp0_intl_int), - .qsfp0_lpmode(qsfp0_lpmode_int), - .qsfp1_tx_clk(qsfp1_tx_clk), - .qsfp1_tx_rst(qsfp1_tx_rst), - .qsfp1_tx_axis_tdata(qsfp1_tx_axis_tdata), - .qsfp1_tx_axis_tkeep(qsfp1_tx_axis_tkeep), - .qsfp1_tx_axis_tvalid(qsfp1_tx_axis_tvalid), - .qsfp1_tx_axis_tready(qsfp1_tx_axis_tready), - .qsfp1_tx_axis_tlast(qsfp1_tx_axis_tlast), - .qsfp1_tx_axis_tuser(qsfp1_tx_axis_tuser), - .qsfp1_rx_clk(qsfp1_rx_clk), - .qsfp1_rx_rst(qsfp1_rx_rst), - .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata), - .qsfp1_rx_axis_tkeep(qsfp1_rx_axis_tkeep), - .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid), - .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast), - .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU250/fpga_100g/tb/udp_ep.py b/fpga/mqnic/AU250/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_100g/tb/xgmii_ep.py b/fpga/mqnic/AU250/fpga_100g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU250/fpga_100g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/axis_ep.py b/fpga/mqnic/AU250/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/eth_ep.py b/fpga/mqnic/AU250/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..73e65ecb4 --- /dev/null +++ b/fpga/mqnic/AU250/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,655 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) + cocotb.fork(Clock(dut.qsfp0_tx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp0_rx_error_count_3.setimmediatevalue(0) + dut.qsfp0_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_1_sink.empty(): + self.qsfp0_1_source.send(self.qsfp0_1_sink.recv()) + if not self.qsfp0_2_sink.empty(): + self.qsfp0_2_source.send(self.qsfp0_2_sink.recv()) + if not self.qsfp0_3_sink.empty(): + self.qsfp0_3_source.send(self.qsfp0_3_sink.recv()) + if not self.qsfp0_4_sink.empty(): + self.qsfp0_4_source.send(self.qsfp0_4_sink.recv()) + if not self.qsfp1_1_sink.empty(): + self.qsfp1_1_source.send(self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + self.qsfp1_2_source.send(self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + self.qsfp1_3_source.send(self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + self.qsfp1_4_source.send(self.qsfp1_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_1_sink.wait() + + # pkt = tb.qsfp1_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU250/fpga_10g/tb/ip_ep.py b/fpga/mqnic/AU250/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/mqnic.py b/fpga/mqnic/AU250/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/pcie.py b/fpga/mqnic/AU250/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/pcie_us.py b/fpga/mqnic/AU250/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/AU250/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/AU250/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 3afc41b44..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1028 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk_1 = Signal(bool(0)) - qsfp0_tx_rst_1 = Signal(bool(0)) - qsfp0_rx_clk_1 = Signal(bool(0)) - qsfp0_rx_rst_1 = Signal(bool(0)) - qsfp0_rxd_1 = Signal(intbv(0)[64:]) - qsfp0_rxc_1 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_2 = Signal(bool(0)) - qsfp0_tx_rst_2 = Signal(bool(0)) - qsfp0_rx_clk_2 = Signal(bool(0)) - qsfp0_rx_rst_2 = Signal(bool(0)) - qsfp0_rxd_2 = Signal(intbv(0)[64:]) - qsfp0_rxc_2 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_3 = Signal(bool(0)) - qsfp0_tx_rst_3 = Signal(bool(0)) - qsfp0_rx_clk_3 = Signal(bool(0)) - qsfp0_rx_rst_3 = Signal(bool(0)) - qsfp0_rxd_3 = Signal(intbv(0)[64:]) - qsfp0_rxc_3 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_4 = Signal(bool(0)) - qsfp0_tx_rst_4 = Signal(bool(0)) - qsfp0_rx_clk_4 = Signal(bool(0)) - qsfp0_rx_rst_4 = Signal(bool(0)) - qsfp0_rxd_4 = Signal(intbv(0)[64:]) - qsfp0_rxc_4 = Signal(intbv(0)[8:]) - qsfp0_modprsl = Signal(bool(1)) - qsfp0_intl = Signal(bool(1)) - qsfp1_tx_clk_1 = Signal(bool(0)) - qsfp1_tx_rst_1 = Signal(bool(0)) - qsfp1_rx_clk_1 = Signal(bool(0)) - qsfp1_rx_rst_1 = Signal(bool(0)) - qsfp1_rxd_1 = Signal(intbv(0)[64:]) - qsfp1_rxc_1 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_2 = Signal(bool(0)) - qsfp1_tx_rst_2 = Signal(bool(0)) - qsfp1_rx_clk_2 = Signal(bool(0)) - qsfp1_rx_rst_2 = Signal(bool(0)) - qsfp1_rxd_2 = Signal(intbv(0)[64:]) - qsfp1_rxc_2 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_3 = Signal(bool(0)) - qsfp1_tx_rst_3 = Signal(bool(0)) - qsfp1_rx_clk_3 = Signal(bool(0)) - qsfp1_rx_rst_3 = Signal(bool(0)) - qsfp1_rxd_3 = Signal(intbv(0)[64:]) - qsfp1_rxc_3 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_4 = Signal(bool(0)) - qsfp1_tx_rst_4 = Signal(bool(0)) - qsfp1_rx_clk_4 = Signal(bool(0)) - qsfp1_rx_rst_4 = Signal(bool(0)) - qsfp1_rxd_4 = Signal(intbv(0)[64:]) - qsfp1_rxc_4 = Signal(intbv(0)[8:]) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[3:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_txd_1 = Signal(intbv(0)[64:]) - qsfp0_txc_1 = Signal(intbv(0)[8:]) - qsfp0_txd_2 = Signal(intbv(0)[64:]) - qsfp0_txc_2 = Signal(intbv(0)[8:]) - qsfp0_txd_3 = Signal(intbv(0)[64:]) - qsfp0_txc_3 = Signal(intbv(0)[8:]) - qsfp0_txd_4 = Signal(intbv(0)[64:]) - qsfp0_txc_4 = Signal(intbv(0)[8:]) - qsfp0_modsell = Signal(bool(0)) - qsfp0_resetl = Signal(bool(0)) - qsfp0_lpmode = Signal(bool(0)) - qsfp1_txd_1 = Signal(intbv(0)[64:]) - qsfp1_txc_1 = Signal(intbv(0)[8:]) - qsfp1_txd_2 = Signal(intbv(0)[64:]) - qsfp1_txc_2 = Signal(intbv(0)[8:]) - qsfp1_txd_3 = Signal(intbv(0)[64:]) - qsfp1_txc_3 = Signal(intbv(0)[8:]) - qsfp1_txd_4 = Signal(intbv(0)[64:]) - qsfp1_txc_4 = Signal(intbv(0)[8:]) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_1_source = xgmii_ep.XGMIISource() - qsfp0_1_source_logic = qsfp0_1_source.create_logic(qsfp0_rx_clk_1, qsfp0_rx_rst_1, txd=qsfp0_rxd_1, txc=qsfp0_rxc_1, name='qsfp0_1_source') - - qsfp0_1_sink = xgmii_ep.XGMIISink() - qsfp0_1_sink_logic = qsfp0_1_sink.create_logic(qsfp0_tx_clk_1, qsfp0_tx_rst_1, rxd=qsfp0_txd_1, rxc=qsfp0_txc_1, name='qsfp0_1_sink') - - qsfp0_2_source = xgmii_ep.XGMIISource() - qsfp0_2_source_logic = qsfp0_2_source.create_logic(qsfp0_rx_clk_2, qsfp0_rx_rst_2, txd=qsfp0_rxd_2, txc=qsfp0_rxc_2, name='qsfp0_2_source') - - qsfp0_2_sink = xgmii_ep.XGMIISink() - qsfp0_2_sink_logic = qsfp0_2_sink.create_logic(qsfp0_tx_clk_2, qsfp0_tx_rst_2, rxd=qsfp0_txd_2, rxc=qsfp0_txc_2, name='qsfp0_2_sink') - - qsfp0_3_source = xgmii_ep.XGMIISource() - qsfp0_3_source_logic = qsfp0_3_source.create_logic(qsfp0_rx_clk_3, qsfp0_rx_rst_3, txd=qsfp0_rxd_3, txc=qsfp0_rxc_3, name='qsfp0_3_source') - - qsfp0_3_sink = xgmii_ep.XGMIISink() - qsfp0_3_sink_logic = qsfp0_3_sink.create_logic(qsfp0_tx_clk_3, qsfp0_tx_rst_3, rxd=qsfp0_txd_3, rxc=qsfp0_txc_3, name='qsfp0_3_sink') - - qsfp0_4_source = xgmii_ep.XGMIISource() - qsfp0_4_source_logic = qsfp0_4_source.create_logic(qsfp0_rx_clk_4, qsfp0_rx_rst_4, txd=qsfp0_rxd_4, txc=qsfp0_rxc_4, name='qsfp0_4_source') - - qsfp0_4_sink = xgmii_ep.XGMIISink() - qsfp0_4_sink_logic = qsfp0_4_sink.create_logic(qsfp0_tx_clk_4, qsfp0_tx_rst_4, rxd=qsfp0_txd_4, rxc=qsfp0_txc_4, name='qsfp0_4_sink') - - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') - - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') - - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') - - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') - - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') - - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') - - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') - - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk_1=qsfp0_tx_clk_1, - qsfp0_tx_rst_1=qsfp0_tx_rst_1, - qsfp0_txd_1=qsfp0_txd_1, - qsfp0_txc_1=qsfp0_txc_1, - qsfp0_rx_clk_1=qsfp0_rx_clk_1, - qsfp0_rx_rst_1=qsfp0_rx_rst_1, - qsfp0_rxd_1=qsfp0_rxd_1, - qsfp0_rxc_1=qsfp0_rxc_1, - qsfp0_tx_clk_2=qsfp0_tx_clk_2, - qsfp0_tx_rst_2=qsfp0_tx_rst_2, - qsfp0_txd_2=qsfp0_txd_2, - qsfp0_txc_2=qsfp0_txc_2, - qsfp0_rx_clk_2=qsfp0_rx_clk_2, - qsfp0_rx_rst_2=qsfp0_rx_rst_2, - qsfp0_rxd_2=qsfp0_rxd_2, - qsfp0_rxc_2=qsfp0_rxc_2, - qsfp0_tx_clk_3=qsfp0_tx_clk_3, - qsfp0_tx_rst_3=qsfp0_tx_rst_3, - qsfp0_txd_3=qsfp0_txd_3, - qsfp0_txc_3=qsfp0_txc_3, - qsfp0_rx_clk_3=qsfp0_rx_clk_3, - qsfp0_rx_rst_3=qsfp0_rx_rst_3, - qsfp0_rxd_3=qsfp0_rxd_3, - qsfp0_rxc_3=qsfp0_rxc_3, - qsfp0_tx_clk_4=qsfp0_tx_clk_4, - qsfp0_tx_rst_4=qsfp0_tx_rst_4, - qsfp0_txd_4=qsfp0_txd_4, - qsfp0_txc_4=qsfp0_txc_4, - qsfp0_rx_clk_4=qsfp0_rx_clk_4, - qsfp0_rx_rst_4=qsfp0_rx_rst_4, - qsfp0_rxd_4=qsfp0_rxd_4, - qsfp0_rxc_4=qsfp0_rxc_4, - qsfp0_modprsl=qsfp0_modprsl, - qsfp0_modsell=qsfp0_modsell, - qsfp0_resetl=qsfp0_resetl, - qsfp0_intl=qsfp0_intl, - qsfp0_lpmode=qsfp0_lpmode, - qsfp1_tx_clk_1=qsfp1_tx_clk_1, - qsfp1_tx_rst_1=qsfp1_tx_rst_1, - qsfp1_txd_1=qsfp1_txd_1, - qsfp1_txc_1=qsfp1_txc_1, - qsfp1_rx_clk_1=qsfp1_rx_clk_1, - qsfp1_rx_rst_1=qsfp1_rx_rst_1, - qsfp1_rxd_1=qsfp1_rxd_1, - qsfp1_rxc_1=qsfp1_rxc_1, - qsfp1_tx_clk_2=qsfp1_tx_clk_2, - qsfp1_tx_rst_2=qsfp1_tx_rst_2, - qsfp1_txd_2=qsfp1_txd_2, - qsfp1_txc_2=qsfp1_txc_2, - qsfp1_rx_clk_2=qsfp1_rx_clk_2, - qsfp1_rx_rst_2=qsfp1_rx_rst_2, - qsfp1_rxd_2=qsfp1_rxd_2, - qsfp1_rxc_2=qsfp1_rxc_2, - qsfp1_tx_clk_3=qsfp1_tx_clk_3, - qsfp1_tx_rst_3=qsfp1_tx_rst_3, - qsfp1_txd_3=qsfp1_txd_3, - qsfp1_txc_3=qsfp1_txc_3, - qsfp1_rx_clk_3=qsfp1_rx_clk_3, - qsfp1_rx_rst_3=qsfp1_rx_rst_3, - qsfp1_rxd_3=qsfp1_rxd_3, - qsfp1_rxc_3=qsfp1_rxc_3, - qsfp1_tx_clk_4=qsfp1_tx_clk_4, - qsfp1_tx_rst_4=qsfp1_tx_rst_4, - qsfp1_txd_4=qsfp1_txd_4, - qsfp1_txc_4=qsfp1_txc_4, - qsfp1_rx_clk_4=qsfp1_rx_clk_4, - qsfp1_rx_rst_4=qsfp1_rx_rst_4, - qsfp1_rxd_4=qsfp1_rxd_4, - qsfp1_rxc_4=qsfp1_rxc_4, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp0_tx_clk_1.next = not qsfp0_tx_clk_1 - qsfp0_rx_clk_1.next = not qsfp0_rx_clk_1 - qsfp0_tx_clk_2.next = not qsfp0_tx_clk_2 - qsfp0_rx_clk_2.next = not qsfp0_rx_clk_2 - qsfp0_tx_clk_3.next = not qsfp0_tx_clk_3 - qsfp0_rx_clk_3.next = not qsfp0_rx_clk_3 - qsfp0_tx_clk_4.next = not qsfp0_tx_clk_4 - qsfp0_rx_clk_4.next = not qsfp0_rx_clk_4 - qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 - qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 - qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 - qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 - qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 - qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 - qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 - qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_1_sink.empty(): - pkt = qsfp0_1_sink.recv() - qsfp0_1_source.send(pkt) - if not qsfp0_2_sink.empty(): - pkt = qsfp0_2_sink.recv() - qsfp0_2_source.send(pkt) - if not qsfp0_3_sink.empty(): - pkt = qsfp0_3_sink.recv() - qsfp0_3_source.send(pkt) - if not qsfp0_4_sink.empty(): - pkt = qsfp0_4_sink.recv() - qsfp0_4_source.send(pkt) - if not qsfp1_1_sink.empty(): - pkt = qsfp1_1_sink.recv() - qsfp1_1_source.send(pkt) - if not qsfp1_2_sink.empty(): - pkt = qsfp1_2_sink.recv() - qsfp1_2_source.send(pkt) - if not qsfp1_3_sink.empty(): - pkt = qsfp1_3_sink.recv() - qsfp1_3_source.send(pkt) - if not qsfp1_4_sink.empty(): - pkt = qsfp1_4_sink.recv() - qsfp1_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst_1.next = 1 - qsfp0_rx_rst_1.next = 1 - qsfp0_tx_rst_2.next = 1 - qsfp0_rx_rst_2.next = 1 - qsfp0_tx_rst_3.next = 1 - qsfp0_rx_rst_3.next = 1 - qsfp0_tx_rst_4.next = 1 - qsfp0_rx_rst_4.next = 1 - qsfp1_tx_rst_1.next = 1 - qsfp1_rx_rst_1.next = 1 - qsfp1_tx_rst_2.next = 1 - qsfp1_rx_rst_2.next = 1 - qsfp1_tx_rst_3.next = 1 - qsfp1_rx_rst_3.next = 1 - qsfp1_tx_rst_4.next = 1 - qsfp1_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst_1.next = 0 - qsfp0_rx_rst_1.next = 0 - qsfp0_tx_rst_2.next = 0 - qsfp0_rx_rst_2.next = 0 - qsfp0_tx_rst_3.next = 0 - qsfp0_rx_rst_3.next = 0 - qsfp0_tx_rst_4.next = 0 - qsfp0_rx_rst_4.next = 0 - qsfp1_tx_rst_1.next = 0 - qsfp1_rx_rst_1.next = 0 - qsfp1_tx_rst_2.next = 0 - qsfp1_rx_rst_2.next = 0 - qsfp1_tx_rst_3.next = 0 - qsfp1_rx_rst_3.next = 0 - qsfp1_tx_rst_4.next = 0 - qsfp1_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_1_sink.wait() - - # pkt = qsfp0_1_sink.recv() - # print(pkt) - - # qsfp0_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU250/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/AU250/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 8335c86b3..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,552 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk_1 = 0; -reg qsfp0_tx_rst_1 = 0; -reg qsfp0_rx_clk_1 = 0; -reg qsfp0_rx_rst_1 = 0; -reg [63:0] qsfp0_rxd_1 = 0; -reg [7:0] qsfp0_rxc_1 = 0; -reg qsfp0_tx_clk_2 = 0; -reg qsfp0_tx_rst_2 = 0; -reg qsfp0_rx_clk_2 = 0; -reg qsfp0_rx_rst_2 = 0; -reg [63:0] qsfp0_rxd_2 = 0; -reg [7:0] qsfp0_rxc_2 = 0; -reg qsfp0_tx_clk_3 = 0; -reg qsfp0_tx_rst_3 = 0; -reg qsfp0_rx_clk_3 = 0; -reg qsfp0_rx_rst_3 = 0; -reg [63:0] qsfp0_rxd_3 = 0; -reg [7:0] qsfp0_rxc_3 = 0; -reg qsfp0_tx_clk_4 = 0; -reg qsfp0_tx_rst_4 = 0; -reg qsfp0_rx_clk_4 = 0; -reg qsfp0_rx_rst_4 = 0; -reg [63:0] qsfp0_rxd_4 = 0; -reg [7:0] qsfp0_rxc_4 = 0; -reg qsfp0_modprsl = 1; -reg qsfp0_intl = 1; -reg qsfp1_tx_clk_1 = 0; -reg qsfp1_tx_rst_1 = 0; -reg qsfp1_rx_clk_1 = 0; -reg qsfp1_rx_rst_1 = 0; -reg [63:0] qsfp1_rxd_1 = 0; -reg [7:0] qsfp1_rxc_1 = 0; -reg qsfp1_tx_clk_2 = 0; -reg qsfp1_tx_rst_2 = 0; -reg qsfp1_rx_clk_2 = 0; -reg qsfp1_rx_rst_2 = 0; -reg [63:0] qsfp1_rxd_2 = 0; -reg [7:0] qsfp1_rxc_2 = 0; -reg qsfp1_tx_clk_3 = 0; -reg qsfp1_tx_rst_3 = 0; -reg qsfp1_rx_clk_3 = 0; -reg qsfp1_rx_rst_3 = 0; -reg [63:0] qsfp1_rxd_3 = 0; -reg [7:0] qsfp1_rxc_3 = 0; -reg qsfp1_tx_clk_4 = 0; -reg qsfp1_tx_rst_4 = 0; -reg qsfp1_rx_clk_4 = 0; -reg qsfp1_rx_rst_4 = 0; -reg [63:0] qsfp1_rxd_4 = 0; -reg [7:0] qsfp1_rxc_4 = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [2:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp0_txd_1; -wire [7:0] qsfp0_txc_1; -wire [63:0] qsfp0_txd_2; -wire [7:0] qsfp0_txc_2; -wire [63:0] qsfp0_txd_3; -wire [7:0] qsfp0_txc_3; -wire [63:0] qsfp0_txd_4; -wire [7:0] qsfp0_txc_4; -wire qsfp0_modsell; -wire qsfp0_resetl; -wire qsfp0_lpmode; -wire [63:0] qsfp1_txd_1; -wire [7:0] qsfp1_txc_1; -wire [63:0] qsfp1_txd_2; -wire [7:0] qsfp1_txc_2; -wire [63:0] qsfp1_txd_3; -wire [7:0] qsfp1_txc_3; -wire [63:0] qsfp1_txd_4; -wire [7:0] qsfp1_txc_4; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk_1, - qsfp0_tx_rst_1, - qsfp0_rx_clk_1, - qsfp0_rx_rst_1, - qsfp0_rxd_1, - qsfp0_rxc_1, - qsfp0_tx_clk_2, - qsfp0_tx_rst_2, - qsfp0_rx_clk_2, - qsfp0_rx_rst_2, - qsfp0_rxd_2, - qsfp0_rxc_2, - qsfp0_tx_clk_3, - qsfp0_tx_rst_3, - qsfp0_rx_clk_3, - qsfp0_rx_rst_3, - qsfp0_rxd_3, - qsfp0_rxc_3, - qsfp0_tx_clk_4, - qsfp0_tx_rst_4, - qsfp0_rx_clk_4, - qsfp0_rx_rst_4, - qsfp0_rxd_4, - qsfp0_rxc_4, - qsfp0_modprsl, - qsfp0_intl, - qsfp1_tx_clk_1, - qsfp1_tx_rst_1, - qsfp1_rx_clk_1, - qsfp1_rx_rst_1, - qsfp1_rxd_1, - qsfp1_rxc_1, - qsfp1_tx_clk_2, - qsfp1_tx_rst_2, - qsfp1_rx_clk_2, - qsfp1_rx_rst_2, - qsfp1_rxd_2, - qsfp1_rxc_2, - qsfp1_tx_clk_3, - qsfp1_tx_rst_3, - qsfp1_rx_clk_3, - qsfp1_rx_rst_3, - qsfp1_rxd_3, - qsfp1_rxc_3, - qsfp1_tx_clk_4, - qsfp1_tx_rst_4, - qsfp1_rx_clk_4, - qsfp1_rx_rst_4, - qsfp1_rxd_4, - qsfp1_rxc_4, - qsfp1_modprsl, - qsfp1_intl, - qspi_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_txd_1, - qsfp0_txc_1, - qsfp0_txd_2, - qsfp0_txc_2, - qsfp0_txd_3, - qsfp0_txc_3, - qsfp0_txd_4, - qsfp0_txc_4, - qsfp0_modsell, - qsfp0_resetl, - qsfp0_lpmode, - qsfp1_txd_1, - qsfp1_txc_1, - qsfp1_txd_2, - qsfp1_txc_2, - qsfp1_txd_3, - qsfp1_txc_3, - qsfp1_txd_4, - qsfp1_txc_4, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk_1(qsfp0_tx_clk_1), - .qsfp0_tx_rst_1(qsfp0_tx_rst_1), - .qsfp0_txd_1(qsfp0_txd_1), - .qsfp0_txc_1(qsfp0_txc_1), - .qsfp0_rx_clk_1(qsfp0_rx_clk_1), - .qsfp0_rx_rst_1(qsfp0_rx_rst_1), - .qsfp0_rxd_1(qsfp0_rxd_1), - .qsfp0_rxc_1(qsfp0_rxc_1), - .qsfp0_tx_clk_2(qsfp0_tx_clk_2), - .qsfp0_tx_rst_2(qsfp0_tx_rst_2), - .qsfp0_txd_2(qsfp0_txd_2), - .qsfp0_txc_2(qsfp0_txc_2), - .qsfp0_rx_clk_2(qsfp0_rx_clk_2), - .qsfp0_rx_rst_2(qsfp0_rx_rst_2), - .qsfp0_rxd_2(qsfp0_rxd_2), - .qsfp0_rxc_2(qsfp0_rxc_2), - .qsfp0_tx_clk_3(qsfp0_tx_clk_3), - .qsfp0_tx_rst_3(qsfp0_tx_rst_3), - .qsfp0_txd_3(qsfp0_txd_3), - .qsfp0_txc_3(qsfp0_txc_3), - .qsfp0_rx_clk_3(qsfp0_rx_clk_3), - .qsfp0_rx_rst_3(qsfp0_rx_rst_3), - .qsfp0_rxd_3(qsfp0_rxd_3), - .qsfp0_rxc_3(qsfp0_rxc_3), - .qsfp0_tx_clk_4(qsfp0_tx_clk_4), - .qsfp0_tx_rst_4(qsfp0_tx_rst_4), - .qsfp0_txd_4(qsfp0_txd_4), - .qsfp0_txc_4(qsfp0_txc_4), - .qsfp0_rx_clk_4(qsfp0_rx_clk_4), - .qsfp0_rx_rst_4(qsfp0_rx_rst_4), - .qsfp0_rxd_4(qsfp0_rxd_4), - .qsfp0_rxc_4(qsfp0_rxc_4), - .qsfp0_modprsl(qsfp0_modprsl_int), - .qsfp0_modsell(qsfp0_modsell), - .qsfp0_resetl(qsfp0_resetl), - .qsfp0_intl(qsfp0_intl_int), - .qsfp0_lpmode(qsfp0_lpmode_int), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1), - .qsfp1_txd_1(qsfp1_txd_1), - .qsfp1_txc_1(qsfp1_txc_1), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1), - .qsfp1_rxd_1(qsfp1_rxd_1), - .qsfp1_rxc_1(qsfp1_rxc_1), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2), - .qsfp1_txd_2(qsfp1_txd_2), - .qsfp1_txc_2(qsfp1_txc_2), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2), - .qsfp1_rxd_2(qsfp1_rxd_2), - .qsfp1_rxc_2(qsfp1_rxc_2), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3), - .qsfp1_txd_3(qsfp1_txd_3), - .qsfp1_txc_3(qsfp1_txc_3), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3), - .qsfp1_rxd_3(qsfp1_rxd_3), - .qsfp1_rxc_3(qsfp1_rxc_3), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4), - .qsfp1_txd_4(qsfp1_txd_4), - .qsfp1_txc_4(qsfp1_txc_4), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4), - .qsfp1_rxd_4(qsfp1_rxd_4), - .qsfp1_rxc_4(qsfp1_rxc_4), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU250/fpga_10g/tb/udp_ep.py b/fpga/mqnic/AU250/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU250/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/AU250/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU250/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/axis_ep.py b/fpga/mqnic/AU280/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/eth_ep.py b/fpga/mqnic/AU280/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..f07e38848 --- /dev/null +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,154 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_pipeline_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..20e8b6abb --- /dev/null +++ b/fpga/mqnic/AU280/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,575 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk, 3.102, units="ns").start()) + self.qsfp0_source = AxiStreamSource(dut, "qsfp0_rx_axis", dut.qsfp0_rx_clk, dut.qsfp0_rx_rst) + cocotb.fork(Clock(dut.qsfp0_tx_clk, 3.102, units="ns").start()) + self.qsfp0_sink = AxiStreamSink(dut, "qsfp0_tx_axis", dut.qsfp0_tx_clk, dut.qsfp0_tx_rst) + + cocotb.fork(Clock(dut.qsfp1_rx_clk, 3.102, units="ns").start()) + self.qsfp1_source = AxiStreamSource(dut, "qsfp1_rx_axis", dut.qsfp1_rx_clk, dut.qsfp1_rx_rst) + cocotb.fork(Clock(dut.qsfp1_tx_clk, 3.102, units="ns").start()) + self.qsfp1_sink = AxiStreamSink(dut, "qsfp1_tx_axis", dut.qsfp1_tx_clk, dut.qsfp1_tx_rst) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(1) + self.dut.qsfp0_tx_rst.setimmediatevalue(1) + self.dut.qsfp1_rx_rst.setimmediatevalue(1) + self.dut.qsfp1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_sink.empty(): + self.qsfp0_source.send(self.qsfp0_sink.recv()) + if not self.qsfp1_sink.empty(): + self.qsfp1_source.send(self.qsfp1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_0_sink.wait() + + # pkt = tb.qsfp1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(axis_rtl_dir, "axis_pipeline_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU280/fpga_100g/tb/ip_ep.py b/fpga/mqnic/AU280/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/mqnic.py b/fpga/mqnic/AU280/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/pcie.py b/fpga/mqnic/AU280/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/pcie_us.py b/fpga/mqnic/AU280/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/AU280/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/AU280/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index 0ac81f46b..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,905 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/axis/rtl/axis_pipeline_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk = Signal(bool(0)) - qsfp0_tx_rst = Signal(bool(0)) - qsfp0_rx_clk = Signal(bool(0)) - qsfp0_rx_rst = Signal(bool(0)) - qsfp0_tx_axis_tready = Signal(bool(0)) - qsfp0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_rx_axis_tvalid = Signal(bool(0)) - qsfp0_rx_axis_tlast = Signal(bool(0)) - qsfp0_rx_axis_tuser = Signal(bool(0)) - qsfp1_tx_clk = Signal(bool(0)) - qsfp1_tx_rst = Signal(bool(0)) - qsfp1_rx_clk = Signal(bool(0)) - qsfp1_rx_rst = Signal(bool(0)) - qsfp1_tx_axis_tready = Signal(bool(0)) - qsfp1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_rx_axis_tvalid = Signal(bool(0)) - qsfp1_rx_axis_tlast = Signal(bool(0)) - qsfp1_rx_axis_tuser = Signal(bool(0)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_tx_axis_tvalid = Signal(bool(0)) - qsfp0_tx_axis_tlast = Signal(bool(0)) - qsfp0_tx_axis_tuser = Signal(bool(0)) - qsfp1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_tx_axis_tvalid = Signal(bool(0)) - qsfp1_tx_axis_tlast = Signal(bool(0)) - qsfp1_tx_axis_tuser = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_source = axis_ep.AXIStreamSource() - qsfp0_source_pause = Signal(bool(False)) - - qsfp0_source_logic = qsfp0_source.create_logic( - qsfp0_rx_clk, - qsfp0_rx_rst, - tdata=qsfp0_rx_axis_tdata, - tkeep=qsfp0_rx_axis_tkeep, - tvalid=qsfp0_rx_axis_tvalid, - tlast=qsfp0_rx_axis_tlast, - tuser=qsfp0_rx_axis_tuser, - pause=qsfp0_source_pause, - name='qsfp0_source' - ) - - qsfp0_sink = axis_ep.AXIStreamSink() - qsfp0_sink_pause = Signal(bool(False)) - - qsfp0_sink_logic = qsfp0_sink.create_logic( - qsfp0_tx_clk, - qsfp0_tx_rst, - tdata=qsfp0_tx_axis_tdata, - tkeep=qsfp0_tx_axis_tkeep, - tvalid=qsfp0_tx_axis_tvalid, - tready=qsfp0_tx_axis_tready, - tlast=qsfp0_tx_axis_tlast, - tuser=qsfp0_tx_axis_tuser, - pause=qsfp0_sink_pause, - name='qsfp0_sink' - ) - - qsfp1_source = axis_ep.AXIStreamSource() - qsfp1_source_pause = Signal(bool(False)) - - qsfp1_source_logic = qsfp1_source.create_logic( - qsfp1_rx_clk, - qsfp1_rx_rst, - tdata=qsfp1_rx_axis_tdata, - tkeep=qsfp1_rx_axis_tkeep, - tvalid=qsfp1_rx_axis_tvalid, - tlast=qsfp1_rx_axis_tlast, - tuser=qsfp1_rx_axis_tuser, - pause=qsfp1_source_pause, - name='qsfp1_source' - ) - - qsfp1_sink = axis_ep.AXIStreamSink() - qsfp1_sink_pause = Signal(bool(False)) - - qsfp1_sink_logic = qsfp1_sink.create_logic( - qsfp1_tx_clk, - qsfp1_tx_rst, - tdata=qsfp1_tx_axis_tdata, - tkeep=qsfp1_tx_axis_tkeep, - tvalid=qsfp1_tx_axis_tvalid, - tready=qsfp1_tx_axis_tready, - tlast=qsfp1_tx_axis_tlast, - tuser=qsfp1_tx_axis_tuser, - pause=qsfp1_sink_pause, - name='qsfp1_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk=qsfp0_tx_clk, - qsfp0_tx_rst=qsfp0_tx_rst, - qsfp0_tx_axis_tdata=qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep=qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid=qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tready=qsfp0_tx_axis_tready, - qsfp0_tx_axis_tlast=qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser=qsfp0_tx_axis_tuser, - qsfp0_rx_clk=qsfp0_rx_clk, - qsfp0_rx_rst=qsfp0_rx_rst, - qsfp0_rx_axis_tdata=qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep=qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid=qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast=qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser=qsfp0_rx_axis_tuser, - qsfp1_tx_clk=qsfp1_tx_clk, - qsfp1_tx_rst=qsfp1_tx_rst, - qsfp1_tx_axis_tdata=qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep=qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid=qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tready=qsfp1_tx_axis_tready, - qsfp1_tx_axis_tlast=qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser=qsfp1_tx_axis_tuser, - qsfp1_rx_clk=qsfp1_rx_clk, - qsfp1_rx_rst=qsfp1_rx_rst, - qsfp1_rx_axis_tdata=qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep=qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid=qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast=qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser=qsfp1_rx_axis_tuser, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp0_tx_clk.next = not qsfp0_tx_clk - qsfp0_rx_clk.next = not qsfp0_rx_clk - qsfp1_tx_clk.next = not qsfp1_tx_clk - qsfp1_rx_clk.next = not qsfp1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_sink.empty(): - pkt = qsfp0_sink.recv() - qsfp0_source.send(pkt) - if not qsfp1_sink.empty(): - pkt = qsfp1_sink.recv() - qsfp1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst.next = 1 - qsfp0_rx_rst.next = 1 - qsfp1_tx_rst.next = 1 - qsfp1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst.next = 0 - qsfp0_rx_rst.next = 0 - qsfp1_tx_rst.next = 0 - qsfp1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_sink.wait() - - # pkt = qsfp0_sink.recv() - # print(pkt) - - # qsfp0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU280/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/AU280/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index 82b634d15..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,400 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk = 0; -reg qsfp0_tx_rst = 0; -reg qsfp0_tx_axis_tready = 0; -reg qsfp0_rx_clk = 0; -reg qsfp0_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_rx_axis_tkeep = 0; -reg qsfp0_rx_axis_tvalid = 0; -reg qsfp0_rx_axis_tlast = 0; -reg qsfp0_rx_axis_tuser = 0; -reg qsfp1_tx_clk = 0; -reg qsfp1_tx_rst = 0; -reg qsfp1_tx_axis_tready = 0; -reg qsfp1_rx_clk = 0; -reg qsfp1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep = 0; -reg qsfp1_rx_axis_tvalid = 0; -reg qsfp1_rx_axis_tlast = 0; -reg qsfp1_rx_axis_tuser = 0; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_tx_axis_tkeep; -wire qsfp0_tx_axis_tvalid; -wire qsfp0_tx_axis_tlast; -wire qsfp0_tx_axis_tuser; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep; -wire qsfp1_tx_axis_tvalid; -wire qsfp1_tx_axis_tlast; -wire qsfp1_tx_axis_tuser; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk, - qsfp0_tx_rst, - qsfp0_tx_axis_tready, - qsfp0_rx_clk, - qsfp0_rx_rst, - qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser, - qsfp1_tx_clk, - qsfp1_tx_rst, - qsfp1_tx_axis_tready, - qsfp1_rx_clk, - qsfp1_rx_rst, - qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser, - qspi_dq_i - ); - $to_myhdl( - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser, - qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk(qsfp0_tx_clk), - .qsfp0_tx_rst(qsfp0_tx_rst), - .qsfp0_tx_axis_tdata(qsfp0_tx_axis_tdata), - .qsfp0_tx_axis_tkeep(qsfp0_tx_axis_tkeep), - .qsfp0_tx_axis_tvalid(qsfp0_tx_axis_tvalid), - .qsfp0_tx_axis_tready(qsfp0_tx_axis_tready), - .qsfp0_tx_axis_tlast(qsfp0_tx_axis_tlast), - .qsfp0_tx_axis_tuser(qsfp0_tx_axis_tuser), - .qsfp0_rx_clk(qsfp0_rx_clk), - .qsfp0_rx_rst(qsfp0_rx_rst), - .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata), - .qsfp0_rx_axis_tkeep(qsfp0_rx_axis_tkeep), - .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid), - .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast), - .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser), - .qsfp1_tx_clk(qsfp1_tx_clk), - .qsfp1_tx_rst(qsfp1_tx_rst), - .qsfp1_tx_axis_tdata(qsfp1_tx_axis_tdata), - .qsfp1_tx_axis_tkeep(qsfp1_tx_axis_tkeep), - .qsfp1_tx_axis_tvalid(qsfp1_tx_axis_tvalid), - .qsfp1_tx_axis_tready(qsfp1_tx_axis_tready), - .qsfp1_tx_axis_tlast(qsfp1_tx_axis_tlast), - .qsfp1_tx_axis_tuser(qsfp1_tx_axis_tuser), - .qsfp1_rx_clk(qsfp1_rx_clk), - .qsfp1_rx_rst(qsfp1_rx_rst), - .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata), - .qsfp1_rx_axis_tkeep(qsfp1_rx_axis_tkeep), - .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid), - .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast), - .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU280/fpga_100g/tb/udp_ep.py b/fpga/mqnic/AU280/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_100g/tb/xgmii_ep.py b/fpga/mqnic/AU280/fpga_100g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU280/fpga_100g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/axis_ep.py b/fpga/mqnic/AU280/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/eth_ep.py b/fpga/mqnic/AU280/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..365e7809b --- /dev/null +++ b/fpga/mqnic/AU280/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,644 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) + cocotb.fork(Clock(dut.qsfp0_tx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + dut.qsfp0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp0_rx_error_count_3.setimmediatevalue(0) + dut.qsfp0_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_1_sink.empty(): + self.qsfp0_1_source.send(self.qsfp0_1_sink.recv()) + if not self.qsfp0_2_sink.empty(): + self.qsfp0_2_source.send(self.qsfp0_2_sink.recv()) + if not self.qsfp0_3_sink.empty(): + self.qsfp0_3_source.send(self.qsfp0_3_sink.recv()) + if not self.qsfp0_4_sink.empty(): + self.qsfp0_4_source.send(self.qsfp0_4_sink.recv()) + if not self.qsfp1_1_sink.empty(): + self.qsfp1_1_source.send(self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + self.qsfp1_2_source.send(self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + self.qsfp1_3_source.send(self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + self.qsfp1_4_source.send(self.qsfp1_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_1_sink.wait() + + # pkt = tb.qsfp1_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU280/fpga_10g/tb/ip_ep.py b/fpga/mqnic/AU280/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/mqnic.py b/fpga/mqnic/AU280/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/pcie.py b/fpga/mqnic/AU280/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/pcie_us.py b/fpga/mqnic/AU280/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/AU280/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/AU280/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index ee5246ac4..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,992 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk_1 = Signal(bool(0)) - qsfp0_tx_rst_1 = Signal(bool(0)) - qsfp0_rx_clk_1 = Signal(bool(0)) - qsfp0_rx_rst_1 = Signal(bool(0)) - qsfp0_rxd_1 = Signal(intbv(0)[64:]) - qsfp0_rxc_1 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_2 = Signal(bool(0)) - qsfp0_tx_rst_2 = Signal(bool(0)) - qsfp0_rx_clk_2 = Signal(bool(0)) - qsfp0_rx_rst_2 = Signal(bool(0)) - qsfp0_rxd_2 = Signal(intbv(0)[64:]) - qsfp0_rxc_2 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_3 = Signal(bool(0)) - qsfp0_tx_rst_3 = Signal(bool(0)) - qsfp0_rx_clk_3 = Signal(bool(0)) - qsfp0_rx_rst_3 = Signal(bool(0)) - qsfp0_rxd_3 = Signal(intbv(0)[64:]) - qsfp0_rxc_3 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_4 = Signal(bool(0)) - qsfp0_tx_rst_4 = Signal(bool(0)) - qsfp0_rx_clk_4 = Signal(bool(0)) - qsfp0_rx_rst_4 = Signal(bool(0)) - qsfp0_rxd_4 = Signal(intbv(0)[64:]) - qsfp0_rxc_4 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_1 = Signal(bool(0)) - qsfp1_tx_rst_1 = Signal(bool(0)) - qsfp1_rx_clk_1 = Signal(bool(0)) - qsfp1_rx_rst_1 = Signal(bool(0)) - qsfp1_rxd_1 = Signal(intbv(0)[64:]) - qsfp1_rxc_1 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_2 = Signal(bool(0)) - qsfp1_tx_rst_2 = Signal(bool(0)) - qsfp1_rx_clk_2 = Signal(bool(0)) - qsfp1_rx_rst_2 = Signal(bool(0)) - qsfp1_rxd_2 = Signal(intbv(0)[64:]) - qsfp1_rxc_2 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_3 = Signal(bool(0)) - qsfp1_tx_rst_3 = Signal(bool(0)) - qsfp1_rx_clk_3 = Signal(bool(0)) - qsfp1_rx_rst_3 = Signal(bool(0)) - qsfp1_rxd_3 = Signal(intbv(0)[64:]) - qsfp1_rxc_3 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_4 = Signal(bool(0)) - qsfp1_tx_rst_4 = Signal(bool(0)) - qsfp1_rx_clk_4 = Signal(bool(0)) - qsfp1_rx_rst_4 = Signal(bool(0)) - qsfp1_rxd_4 = Signal(intbv(0)[64:]) - qsfp1_rxc_4 = Signal(intbv(0)[8:]) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_txd_1 = Signal(intbv(0)[64:]) - qsfp0_txc_1 = Signal(intbv(0)[8:]) - qsfp0_txd_2 = Signal(intbv(0)[64:]) - qsfp0_txc_2 = Signal(intbv(0)[8:]) - qsfp0_txd_3 = Signal(intbv(0)[64:]) - qsfp0_txc_3 = Signal(intbv(0)[8:]) - qsfp0_txd_4 = Signal(intbv(0)[64:]) - qsfp0_txc_4 = Signal(intbv(0)[8:]) - qsfp1_txd_1 = Signal(intbv(0)[64:]) - qsfp1_txc_1 = Signal(intbv(0)[8:]) - qsfp1_txd_2 = Signal(intbv(0)[64:]) - qsfp1_txc_2 = Signal(intbv(0)[8:]) - qsfp1_txd_3 = Signal(intbv(0)[64:]) - qsfp1_txc_3 = Signal(intbv(0)[8:]) - qsfp1_txd_4 = Signal(intbv(0)[64:]) - qsfp1_txc_4 = Signal(intbv(0)[8:]) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_1_source = xgmii_ep.XGMIISource() - qsfp0_1_source_logic = qsfp0_1_source.create_logic(qsfp0_rx_clk_1, qsfp0_rx_rst_1, txd=qsfp0_rxd_1, txc=qsfp0_rxc_1, name='qsfp0_1_source') - - qsfp0_1_sink = xgmii_ep.XGMIISink() - qsfp0_1_sink_logic = qsfp0_1_sink.create_logic(qsfp0_tx_clk_1, qsfp0_tx_rst_1, rxd=qsfp0_txd_1, rxc=qsfp0_txc_1, name='qsfp0_1_sink') - - qsfp0_2_source = xgmii_ep.XGMIISource() - qsfp0_2_source_logic = qsfp0_2_source.create_logic(qsfp0_rx_clk_2, qsfp0_rx_rst_2, txd=qsfp0_rxd_2, txc=qsfp0_rxc_2, name='qsfp0_2_source') - - qsfp0_2_sink = xgmii_ep.XGMIISink() - qsfp0_2_sink_logic = qsfp0_2_sink.create_logic(qsfp0_tx_clk_2, qsfp0_tx_rst_2, rxd=qsfp0_txd_2, rxc=qsfp0_txc_2, name='qsfp0_2_sink') - - qsfp0_3_source = xgmii_ep.XGMIISource() - qsfp0_3_source_logic = qsfp0_3_source.create_logic(qsfp0_rx_clk_3, qsfp0_rx_rst_3, txd=qsfp0_rxd_3, txc=qsfp0_rxc_3, name='qsfp0_3_source') - - qsfp0_3_sink = xgmii_ep.XGMIISink() - qsfp0_3_sink_logic = qsfp0_3_sink.create_logic(qsfp0_tx_clk_3, qsfp0_tx_rst_3, rxd=qsfp0_txd_3, rxc=qsfp0_txc_3, name='qsfp0_3_sink') - - qsfp0_4_source = xgmii_ep.XGMIISource() - qsfp0_4_source_logic = qsfp0_4_source.create_logic(qsfp0_rx_clk_4, qsfp0_rx_rst_4, txd=qsfp0_rxd_4, txc=qsfp0_rxc_4, name='qsfp0_4_source') - - qsfp0_4_sink = xgmii_ep.XGMIISink() - qsfp0_4_sink_logic = qsfp0_4_sink.create_logic(qsfp0_tx_clk_4, qsfp0_tx_rst_4, rxd=qsfp0_txd_4, rxc=qsfp0_txc_4, name='qsfp0_4_sink') - - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') - - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') - - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') - - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') - - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') - - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') - - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') - - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk_1=qsfp0_tx_clk_1, - qsfp0_tx_rst_1=qsfp0_tx_rst_1, - qsfp0_txd_1=qsfp0_txd_1, - qsfp0_txc_1=qsfp0_txc_1, - qsfp0_rx_clk_1=qsfp0_rx_clk_1, - qsfp0_rx_rst_1=qsfp0_rx_rst_1, - qsfp0_rxd_1=qsfp0_rxd_1, - qsfp0_rxc_1=qsfp0_rxc_1, - qsfp0_tx_clk_2=qsfp0_tx_clk_2, - qsfp0_tx_rst_2=qsfp0_tx_rst_2, - qsfp0_txd_2=qsfp0_txd_2, - qsfp0_txc_2=qsfp0_txc_2, - qsfp0_rx_clk_2=qsfp0_rx_clk_2, - qsfp0_rx_rst_2=qsfp0_rx_rst_2, - qsfp0_rxd_2=qsfp0_rxd_2, - qsfp0_rxc_2=qsfp0_rxc_2, - qsfp0_tx_clk_3=qsfp0_tx_clk_3, - qsfp0_tx_rst_3=qsfp0_tx_rst_3, - qsfp0_txd_3=qsfp0_txd_3, - qsfp0_txc_3=qsfp0_txc_3, - qsfp0_rx_clk_3=qsfp0_rx_clk_3, - qsfp0_rx_rst_3=qsfp0_rx_rst_3, - qsfp0_rxd_3=qsfp0_rxd_3, - qsfp0_rxc_3=qsfp0_rxc_3, - qsfp0_tx_clk_4=qsfp0_tx_clk_4, - qsfp0_tx_rst_4=qsfp0_tx_rst_4, - qsfp0_txd_4=qsfp0_txd_4, - qsfp0_txc_4=qsfp0_txc_4, - qsfp0_rx_clk_4=qsfp0_rx_clk_4, - qsfp0_rx_rst_4=qsfp0_rx_rst_4, - qsfp0_rxd_4=qsfp0_rxd_4, - qsfp0_rxc_4=qsfp0_rxc_4, - qsfp1_tx_clk_1=qsfp1_tx_clk_1, - qsfp1_tx_rst_1=qsfp1_tx_rst_1, - qsfp1_txd_1=qsfp1_txd_1, - qsfp1_txc_1=qsfp1_txc_1, - qsfp1_rx_clk_1=qsfp1_rx_clk_1, - qsfp1_rx_rst_1=qsfp1_rx_rst_1, - qsfp1_rxd_1=qsfp1_rxd_1, - qsfp1_rxc_1=qsfp1_rxc_1, - qsfp1_tx_clk_2=qsfp1_tx_clk_2, - qsfp1_tx_rst_2=qsfp1_tx_rst_2, - qsfp1_txd_2=qsfp1_txd_2, - qsfp1_txc_2=qsfp1_txc_2, - qsfp1_rx_clk_2=qsfp1_rx_clk_2, - qsfp1_rx_rst_2=qsfp1_rx_rst_2, - qsfp1_rxd_2=qsfp1_rxd_2, - qsfp1_rxc_2=qsfp1_rxc_2, - qsfp1_tx_clk_3=qsfp1_tx_clk_3, - qsfp1_tx_rst_3=qsfp1_tx_rst_3, - qsfp1_txd_3=qsfp1_txd_3, - qsfp1_txc_3=qsfp1_txc_3, - qsfp1_rx_clk_3=qsfp1_rx_clk_3, - qsfp1_rx_rst_3=qsfp1_rx_rst_3, - qsfp1_rxd_3=qsfp1_rxd_3, - qsfp1_rxc_3=qsfp1_rxc_3, - qsfp1_tx_clk_4=qsfp1_tx_clk_4, - qsfp1_tx_rst_4=qsfp1_tx_rst_4, - qsfp1_txd_4=qsfp1_txd_4, - qsfp1_txc_4=qsfp1_txc_4, - qsfp1_rx_clk_4=qsfp1_rx_clk_4, - qsfp1_rx_rst_4=qsfp1_rx_rst_4, - qsfp1_rxd_4=qsfp1_rxd_4, - qsfp1_rxc_4=qsfp1_rxc_4, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp0_tx_clk_1.next = not qsfp0_tx_clk_1 - qsfp0_rx_clk_1.next = not qsfp0_rx_clk_1 - qsfp0_tx_clk_2.next = not qsfp0_tx_clk_2 - qsfp0_rx_clk_2.next = not qsfp0_rx_clk_2 - qsfp0_tx_clk_3.next = not qsfp0_tx_clk_3 - qsfp0_rx_clk_3.next = not qsfp0_rx_clk_3 - qsfp0_tx_clk_4.next = not qsfp0_tx_clk_4 - qsfp0_rx_clk_4.next = not qsfp0_rx_clk_4 - qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 - qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 - qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 - qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 - qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 - qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 - qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 - qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_1_sink.empty(): - pkt = qsfp0_1_sink.recv() - qsfp0_1_source.send(pkt) - if not qsfp0_2_sink.empty(): - pkt = qsfp0_2_sink.recv() - qsfp0_2_source.send(pkt) - if not qsfp0_3_sink.empty(): - pkt = qsfp0_3_sink.recv() - qsfp0_3_source.send(pkt) - if not qsfp0_4_sink.empty(): - pkt = qsfp0_4_sink.recv() - qsfp0_4_source.send(pkt) - if not qsfp1_1_sink.empty(): - pkt = qsfp1_1_sink.recv() - qsfp1_1_source.send(pkt) - if not qsfp1_2_sink.empty(): - pkt = qsfp1_2_sink.recv() - qsfp1_2_source.send(pkt) - if not qsfp1_3_sink.empty(): - pkt = qsfp1_3_sink.recv() - qsfp1_3_source.send(pkt) - if not qsfp1_4_sink.empty(): - pkt = qsfp1_4_sink.recv() - qsfp1_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst_1.next = 1 - qsfp0_rx_rst_1.next = 1 - qsfp0_tx_rst_2.next = 1 - qsfp0_rx_rst_2.next = 1 - qsfp0_tx_rst_3.next = 1 - qsfp0_rx_rst_3.next = 1 - qsfp0_tx_rst_4.next = 1 - qsfp0_rx_rst_4.next = 1 - qsfp1_tx_rst_1.next = 1 - qsfp1_rx_rst_1.next = 1 - qsfp1_tx_rst_2.next = 1 - qsfp1_rx_rst_2.next = 1 - qsfp1_tx_rst_3.next = 1 - qsfp1_rx_rst_3.next = 1 - qsfp1_tx_rst_4.next = 1 - qsfp1_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst_1.next = 0 - qsfp0_rx_rst_1.next = 0 - qsfp0_tx_rst_2.next = 0 - qsfp0_rx_rst_2.next = 0 - qsfp0_tx_rst_3.next = 0 - qsfp0_rx_rst_3.next = 0 - qsfp0_tx_rst_4.next = 0 - qsfp0_rx_rst_4.next = 0 - qsfp1_tx_rst_1.next = 0 - qsfp1_rx_rst_1.next = 0 - qsfp1_tx_rst_2.next = 0 - qsfp1_rx_rst_2.next = 0 - qsfp1_tx_rst_3.next = 0 - qsfp1_rx_rst_3.next = 0 - qsfp1_tx_rst_4.next = 0 - qsfp1_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_1_sink.wait() - - # pkt = qsfp0_1_sink.recv() - # print(pkt) - - # qsfp0_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU280/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/AU280/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 36d0dbe44..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,498 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk_1 = 0; -reg qsfp0_tx_rst_1 = 0; -reg qsfp0_rx_clk_1 = 0; -reg qsfp0_rx_rst_1 = 0; -reg [63:0] qsfp0_rxd_1 = 0; -reg [7:0] qsfp0_rxc_1 = 0; -reg qsfp0_tx_clk_2 = 0; -reg qsfp0_tx_rst_2 = 0; -reg qsfp0_rx_clk_2 = 0; -reg qsfp0_rx_rst_2 = 0; -reg [63:0] qsfp0_rxd_2 = 0; -reg [7:0] qsfp0_rxc_2 = 0; -reg qsfp0_tx_clk_3 = 0; -reg qsfp0_tx_rst_3 = 0; -reg qsfp0_rx_clk_3 = 0; -reg qsfp0_rx_rst_3 = 0; -reg [63:0] qsfp0_rxd_3 = 0; -reg [7:0] qsfp0_rxc_3 = 0; -reg qsfp0_tx_clk_4 = 0; -reg qsfp0_tx_rst_4 = 0; -reg qsfp0_rx_clk_4 = 0; -reg qsfp0_rx_rst_4 = 0; -reg [63:0] qsfp0_rxd_4 = 0; -reg [7:0] qsfp0_rxc_4 = 0; -reg qsfp1_tx_clk_1 = 0; -reg qsfp1_tx_rst_1 = 0; -reg qsfp1_rx_clk_1 = 0; -reg qsfp1_rx_rst_1 = 0; -reg [63:0] qsfp1_rxd_1 = 0; -reg [7:0] qsfp1_rxc_1 = 0; -reg qsfp1_tx_clk_2 = 0; -reg qsfp1_tx_rst_2 = 0; -reg qsfp1_rx_clk_2 = 0; -reg qsfp1_rx_rst_2 = 0; -reg [63:0] qsfp1_rxd_2 = 0; -reg [7:0] qsfp1_rxc_2 = 0; -reg qsfp1_tx_clk_3 = 0; -reg qsfp1_tx_rst_3 = 0; -reg qsfp1_rx_clk_3 = 0; -reg qsfp1_rx_rst_3 = 0; -reg [63:0] qsfp1_rxd_3 = 0; -reg [7:0] qsfp1_rxc_3 = 0; -reg qsfp1_tx_clk_4 = 0; -reg qsfp1_tx_rst_4 = 0; -reg qsfp1_rx_clk_4 = 0; -reg qsfp1_rx_rst_4 = 0; -reg [63:0] qsfp1_rxd_4 = 0; -reg [7:0] qsfp1_rxc_4 = 0; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp0_txd_1; -wire [7:0] qsfp0_txc_1; -wire [63:0] qsfp0_txd_2; -wire [7:0] qsfp0_txc_2; -wire [63:0] qsfp0_txd_3; -wire [7:0] qsfp0_txc_3; -wire [63:0] qsfp0_txd_4; -wire [7:0] qsfp0_txc_4; -wire [63:0] qsfp1_txd_1; -wire [7:0] qsfp1_txc_1; -wire [63:0] qsfp1_txd_2; -wire [7:0] qsfp1_txc_2; -wire [63:0] qsfp1_txd_3; -wire [7:0] qsfp1_txc_3; -wire [63:0] qsfp1_txd_4; -wire [7:0] qsfp1_txc_4; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk_1, - qsfp0_tx_rst_1, - qsfp0_rx_clk_1, - qsfp0_rx_rst_1, - qsfp0_rxd_1, - qsfp0_rxc_1, - qsfp0_tx_clk_2, - qsfp0_tx_rst_2, - qsfp0_rx_clk_2, - qsfp0_rx_rst_2, - qsfp0_rxd_2, - qsfp0_rxc_2, - qsfp0_tx_clk_3, - qsfp0_tx_rst_3, - qsfp0_rx_clk_3, - qsfp0_rx_rst_3, - qsfp0_rxd_3, - qsfp0_rxc_3, - qsfp0_tx_clk_4, - qsfp0_tx_rst_4, - qsfp0_rx_clk_4, - qsfp0_rx_rst_4, - qsfp0_rxd_4, - qsfp0_rxc_4, - qsfp1_tx_clk_1, - qsfp1_tx_rst_1, - qsfp1_rx_clk_1, - qsfp1_rx_rst_1, - qsfp1_rxd_1, - qsfp1_rxc_1, - qsfp1_tx_clk_2, - qsfp1_tx_rst_2, - qsfp1_rx_clk_2, - qsfp1_rx_rst_2, - qsfp1_rxd_2, - qsfp1_rxc_2, - qsfp1_tx_clk_3, - qsfp1_tx_rst_3, - qsfp1_rx_clk_3, - qsfp1_rx_rst_3, - qsfp1_rxd_3, - qsfp1_rxc_3, - qsfp1_tx_clk_4, - qsfp1_tx_rst_4, - qsfp1_rx_clk_4, - qsfp1_rx_rst_4, - qsfp1_rxd_4, - qsfp1_rxc_4, - qspi_dq_i - ); - $to_myhdl( - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_txd_1, - qsfp0_txc_1, - qsfp0_txd_2, - qsfp0_txc_2, - qsfp0_txd_3, - qsfp0_txc_3, - qsfp0_txd_4, - qsfp0_txc_4, - qsfp1_txd_1, - qsfp1_txc_1, - qsfp1_txd_2, - qsfp1_txc_2, - qsfp1_txd_3, - qsfp1_txc_3, - qsfp1_txd_4, - qsfp1_txc_4, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk_1(qsfp0_tx_clk_1), - .qsfp0_tx_rst_1(qsfp0_tx_rst_1), - .qsfp0_txd_1(qsfp0_txd_1), - .qsfp0_txc_1(qsfp0_txc_1), - .qsfp0_rx_clk_1(qsfp0_rx_clk_1), - .qsfp0_rx_rst_1(qsfp0_rx_rst_1), - .qsfp0_rxd_1(qsfp0_rxd_1), - .qsfp0_rxc_1(qsfp0_rxc_1), - .qsfp0_tx_clk_2(qsfp0_tx_clk_2), - .qsfp0_tx_rst_2(qsfp0_tx_rst_2), - .qsfp0_txd_2(qsfp0_txd_2), - .qsfp0_txc_2(qsfp0_txc_2), - .qsfp0_rx_clk_2(qsfp0_rx_clk_2), - .qsfp0_rx_rst_2(qsfp0_rx_rst_2), - .qsfp0_rxd_2(qsfp0_rxd_2), - .qsfp0_rxc_2(qsfp0_rxc_2), - .qsfp0_tx_clk_3(qsfp0_tx_clk_3), - .qsfp0_tx_rst_3(qsfp0_tx_rst_3), - .qsfp0_txd_3(qsfp0_txd_3), - .qsfp0_txc_3(qsfp0_txc_3), - .qsfp0_rx_clk_3(qsfp0_rx_clk_3), - .qsfp0_rx_rst_3(qsfp0_rx_rst_3), - .qsfp0_rxd_3(qsfp0_rxd_3), - .qsfp0_rxc_3(qsfp0_rxc_3), - .qsfp0_tx_clk_4(qsfp0_tx_clk_4), - .qsfp0_tx_rst_4(qsfp0_tx_rst_4), - .qsfp0_txd_4(qsfp0_txd_4), - .qsfp0_txc_4(qsfp0_txc_4), - .qsfp0_rx_clk_4(qsfp0_rx_clk_4), - .qsfp0_rx_rst_4(qsfp0_rx_rst_4), - .qsfp0_rxd_4(qsfp0_rxd_4), - .qsfp0_rxc_4(qsfp0_rxc_4), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1), - .qsfp1_txd_1(qsfp1_txd_1), - .qsfp1_txc_1(qsfp1_txc_1), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1), - .qsfp1_rxd_1(qsfp1_rxd_1), - .qsfp1_rxc_1(qsfp1_rxc_1), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2), - .qsfp1_txd_2(qsfp1_txd_2), - .qsfp1_txc_2(qsfp1_txc_2), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2), - .qsfp1_rxd_2(qsfp1_rxd_2), - .qsfp1_rxc_2(qsfp1_rxc_2), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3), - .qsfp1_txd_3(qsfp1_txd_3), - .qsfp1_txc_3(qsfp1_txc_3), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3), - .qsfp1_rxd_3(qsfp1_rxd_3), - .qsfp1_rxc_3(qsfp1_rxc_3), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4), - .qsfp1_txd_4(qsfp1_txd_4), - .qsfp1_txc_4(qsfp1_txc_4), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4), - .qsfp1_rxd_4(qsfp1_rxd_4), - .qsfp1_rxc_4(qsfp1_rxc_4), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU280/fpga_10g/tb/udp_ep.py b/fpga/mqnic/AU280/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU280/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/AU280/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU280/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/axis_ep.py b/fpga/mqnic/AU50/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/eth_ep.py b/fpga/mqnic/AU50/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..f07e38848 --- /dev/null +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,154 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_pipeline_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..9aeaf00d2 --- /dev/null +++ b/fpga/mqnic/AU50/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,545 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_rx_clk, 3.102, units="ns").start()) + self.qsfp_source = AxiStreamSource(dut, "qsfp_rx_axis", dut.qsfp_rx_clk, dut.qsfp_rx_rst) + cocotb.fork(Clock(dut.qsfp_tx_clk, 3.102, units="ns").start()) + self.qsfp_sink = AxiStreamSink(dut, "qsfp_tx_axis", dut.qsfp_tx_clk, dut.qsfp_tx_rst) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_rx_rst.setimmediatevalue(0) + self.dut.qsfp_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst.setimmediatevalue(1) + self.dut.qsfp_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst.setimmediatevalue(0) + self.dut.qsfp_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_sink.empty(): + self.qsfp_source.send(self.qsfp_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_sink.wait() + + pkt = tb.qsfp_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_sink.wait() + + pkt = tb.qsfp_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(axis_rtl_dir, "axis_pipeline_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU50/fpga_100g/tb/ip_ep.py b/fpga/mqnic/AU50/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/mqnic.py b/fpga/mqnic/AU50/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/pcie.py b/fpga/mqnic/AU50/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/pcie_us.py b/fpga/mqnic/AU50/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/AU50/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/AU50/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index 13f75cc6c..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,841 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/axis/rtl/axis_pipeline_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_tx_clk = Signal(bool(0)) - qsfp_tx_rst = Signal(bool(0)) - qsfp_rx_clk = Signal(bool(0)) - qsfp_rx_rst = Signal(bool(0)) - qsfp_tx_axis_tready = Signal(bool(0)) - qsfp_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_rx_axis_tvalid = Signal(bool(0)) - qsfp_rx_axis_tlast = Signal(bool(0)) - qsfp_rx_axis_tuser = Signal(bool(0)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - qsfp_led_act = Signal(bool(0)) - qsfp_led_stat_g = Signal(bool(0)) - qsfp_led_stat_y = Signal(bool(0)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_tx_axis_tvalid = Signal(bool(0)) - qsfp_tx_axis_tlast = Signal(bool(0)) - qsfp_tx_axis_tuser = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp_source = axis_ep.AXIStreamSource() - qsfp_source_pause = Signal(bool(False)) - - qsfp_source_logic = qsfp_source.create_logic( - qsfp_rx_clk, - qsfp_rx_rst, - tdata=qsfp_rx_axis_tdata, - tkeep=qsfp_rx_axis_tkeep, - tvalid=qsfp_rx_axis_tvalid, - tlast=qsfp_rx_axis_tlast, - tuser=qsfp_rx_axis_tuser, - pause=qsfp_source_pause, - name='qsfp_source' - ) - - qsfp_sink = axis_ep.AXIStreamSink() - qsfp_sink_pause = Signal(bool(False)) - - qsfp_sink_logic = qsfp_sink.create_logic( - qsfp_tx_clk, - qsfp_tx_rst, - tdata=qsfp_tx_axis_tdata, - tkeep=qsfp_tx_axis_tkeep, - tvalid=qsfp_tx_axis_tvalid, - tready=qsfp_tx_axis_tready, - tlast=qsfp_tx_axis_tlast, - tuser=qsfp_tx_axis_tuser, - pause=qsfp_sink_pause, - name='qsfp_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - qsfp_led_act=qsfp_led_act, - qsfp_led_stat_g=qsfp_led_stat_g, - qsfp_led_stat_y=qsfp_led_stat_y, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_tx_clk=qsfp_tx_clk, - qsfp_tx_rst=qsfp_tx_rst, - qsfp_tx_axis_tdata=qsfp_tx_axis_tdata, - qsfp_tx_axis_tkeep=qsfp_tx_axis_tkeep, - qsfp_tx_axis_tvalid=qsfp_tx_axis_tvalid, - qsfp_tx_axis_tready=qsfp_tx_axis_tready, - qsfp_tx_axis_tlast=qsfp_tx_axis_tlast, - qsfp_tx_axis_tuser=qsfp_tx_axis_tuser, - qsfp_rx_clk=qsfp_rx_clk, - qsfp_rx_rst=qsfp_rx_rst, - qsfp_rx_axis_tdata=qsfp_rx_axis_tdata, - qsfp_rx_axis_tkeep=qsfp_rx_axis_tkeep, - qsfp_rx_axis_tvalid=qsfp_rx_axis_tvalid, - qsfp_rx_axis_tlast=qsfp_rx_axis_tlast, - qsfp_rx_axis_tuser=qsfp_rx_axis_tuser, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp_tx_clk.next = not qsfp_tx_clk - qsfp_rx_clk.next = not qsfp_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_sink.empty(): - pkt = qsfp_sink.recv() - qsfp_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_tx_rst.next = 1 - qsfp_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_tx_rst.next = 0 - qsfp_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_sink.wait() - - pkt = qsfp_sink.recv() - print(pkt) - - qsfp_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_sink.wait() - - # pkt = qsfp_sink.recv() - # print(pkt) - - # qsfp_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_sink.wait() - - pkt = qsfp_sink.recv() - print(pkt) - - qsfp_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU50/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/AU50/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index b141b715d..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,364 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_tx_clk = 0; -reg qsfp_tx_rst = 0; -reg qsfp_tx_axis_tready = 0; -reg qsfp_rx_clk = 0; -reg qsfp_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_rx_axis_tkeep = 0; -reg qsfp_rx_axis_tvalid = 0; -reg qsfp_rx_axis_tlast = 0; -reg qsfp_rx_axis_tuser = 0; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire qsfp_led_act; -wire qsfp_led_stat_g; -wire qsfp_led_stat_y; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_tx_axis_tkeep; -wire qsfp_tx_axis_tvalid; -wire qsfp_tx_axis_tlast; -wire qsfp_tx_axis_tuser; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_tx_clk, - qsfp_tx_rst, - qsfp_tx_axis_tready, - qsfp_rx_clk, - qsfp_rx_rst, - qsfp_rx_axis_tdata, - qsfp_rx_axis_tkeep, - qsfp_rx_axis_tvalid, - qsfp_rx_axis_tlast, - qsfp_rx_axis_tuser, - qspi_dq_i - ); - $to_myhdl( - qsfp_led_act, - qsfp_led_stat_g, - qsfp_led_stat_y, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_tx_axis_tdata, - qsfp_tx_axis_tkeep, - qsfp_tx_axis_tvalid, - qsfp_tx_axis_tlast, - qsfp_tx_axis_tuser, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .qsfp_led_act(qsfp_led_act), - .qsfp_led_stat_g(qsfp_led_stat_g), - .qsfp_led_stat_y(qsfp_led_stat_y), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_tx_clk(qsfp_tx_clk), - .qsfp_tx_rst(qsfp_tx_rst), - .qsfp_tx_axis_tdata(qsfp_tx_axis_tdata), - .qsfp_tx_axis_tkeep(qsfp_tx_axis_tkeep), - .qsfp_tx_axis_tvalid(qsfp_tx_axis_tvalid), - .qsfp_tx_axis_tready(qsfp_tx_axis_tready), - .qsfp_tx_axis_tlast(qsfp_tx_axis_tlast), - .qsfp_tx_axis_tuser(qsfp_tx_axis_tuser), - .qsfp_rx_clk(qsfp_rx_clk), - .qsfp_rx_rst(qsfp_rx_rst), - .qsfp_rx_axis_tdata(qsfp_rx_axis_tdata), - .qsfp_rx_axis_tkeep(qsfp_rx_axis_tkeep), - .qsfp_rx_axis_tvalid(qsfp_rx_axis_tvalid), - .qsfp_rx_axis_tlast(qsfp_rx_axis_tlast), - .qsfp_rx_axis_tuser(qsfp_rx_axis_tuser), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU50/fpga_100g/tb/udp_ep.py b/fpga/mqnic/AU50/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_100g/tb/xgmii_ep.py b/fpga/mqnic/AU50/fpga_100g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU50/fpga_100g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/axis_ep.py b/fpga/mqnic/AU50/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/eth_ep.py b/fpga/mqnic/AU50/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..c77a4ca39 --- /dev/null +++ b/fpga/mqnic/AU50/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,570 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_source = XgmiiSource(dut.qsfp_rxd_1, dut.qsfp_rxc_1, dut.qsfp_rx_clk_1, dut.qsfp_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_sink = XgmiiSink(dut.qsfp_txd_1, dut.qsfp_txc_1, dut.qsfp_tx_clk_1, dut.qsfp_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_2_source = XgmiiSource(dut.qsfp_rxd_2, dut.qsfp_rxc_2, dut.qsfp_rx_clk_2, dut.qsfp_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_2_sink = XgmiiSink(dut.qsfp_txd_2, dut.qsfp_txc_2, dut.qsfp_tx_clk_2, dut.qsfp_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_3_source = XgmiiSource(dut.qsfp_rxd_3, dut.qsfp_rxc_3, dut.qsfp_rx_clk_3, dut.qsfp_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_3_sink = XgmiiSink(dut.qsfp_txd_3, dut.qsfp_txc_3, dut.qsfp_tx_clk_3, dut.qsfp_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_rx_clk_4, 6.4, units="ns").start()) + self.qsfp_4_source = XgmiiSource(dut.qsfp_rxd_4, dut.qsfp_rxc_4, dut.qsfp_rx_clk_4, dut.qsfp_rx_rst_4) + cocotb.fork(Clock(dut.qsfp_tx_clk_4, 6.4, units="ns").start()) + self.qsfp_4_sink = XgmiiSink(dut.qsfp_txd_4, dut.qsfp_txc_4, dut.qsfp_tx_clk_4, dut.qsfp_tx_rst_4) + + dut.qsfp_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_rx_error_count_3.setimmediatevalue(0) + dut.qsfp_rx_error_count_4.setimmediatevalue(0) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_1_sink.empty(): + self.qsfp_1_source.send(self.qsfp_1_sink.recv()) + if not self.qsfp_2_sink.empty(): + self.qsfp_2_source.send(self.qsfp_2_sink.recv()) + if not self.qsfp_3_sink.empty(): + self.qsfp_3_source.send(self.qsfp_3_sink.recv()) + if not self.qsfp_4_sink.empty(): + self.qsfp_4_source.send(self.qsfp_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_1_sink.wait() + + pkt = tb.qsfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_1_sink.wait() + + pkt = tb.qsfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/AU50/fpga_10g/tb/ip_ep.py b/fpga/mqnic/AU50/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/mqnic.py b/fpga/mqnic/AU50/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/pcie.py b/fpga/mqnic/AU50/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/pcie_us.py b/fpga/mqnic/AU50/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/AU50/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/AU50/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 3f10cbb33..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,874 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_tx_clk_1 = Signal(bool(0)) - qsfp_tx_rst_1 = Signal(bool(0)) - qsfp_rx_clk_1 = Signal(bool(0)) - qsfp_rx_rst_1 = Signal(bool(0)) - qsfp_rxd_1 = Signal(intbv(0)[64:]) - qsfp_rxc_1 = Signal(intbv(0)[8:]) - qsfp_tx_clk_2 = Signal(bool(0)) - qsfp_tx_rst_2 = Signal(bool(0)) - qsfp_rx_clk_2 = Signal(bool(0)) - qsfp_rx_rst_2 = Signal(bool(0)) - qsfp_rxd_2 = Signal(intbv(0)[64:]) - qsfp_rxc_2 = Signal(intbv(0)[8:]) - qsfp_tx_clk_3 = Signal(bool(0)) - qsfp_tx_rst_3 = Signal(bool(0)) - qsfp_rx_clk_3 = Signal(bool(0)) - qsfp_rx_rst_3 = Signal(bool(0)) - qsfp_rxd_3 = Signal(intbv(0)[64:]) - qsfp_rxc_3 = Signal(intbv(0)[8:]) - qsfp_tx_clk_4 = Signal(bool(0)) - qsfp_tx_rst_4 = Signal(bool(0)) - qsfp_rx_clk_4 = Signal(bool(0)) - qsfp_rx_rst_4 = Signal(bool(0)) - qsfp_rxd_4 = Signal(intbv(0)[64:]) - qsfp_rxc_4 = Signal(intbv(0)[8:]) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - qsfp_led_act = Signal(bool(0)) - qsfp_led_stat_g = Signal(bool(0)) - qsfp_led_stat_y = Signal(bool(0)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_txd_1 = Signal(intbv(0)[64:]) - qsfp_txc_1 = Signal(intbv(0)[8:]) - qsfp_txd_2 = Signal(intbv(0)[64:]) - qsfp_txc_2 = Signal(intbv(0)[8:]) - qsfp_txd_3 = Signal(intbv(0)[64:]) - qsfp_txc_3 = Signal(intbv(0)[8:]) - qsfp_txd_4 = Signal(intbv(0)[64:]) - qsfp_txc_4 = Signal(intbv(0)[8:]) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp_1_source = xgmii_ep.XGMIISource() - qsfp_1_source_logic = qsfp_1_source.create_logic(qsfp_rx_clk_1, qsfp_rx_rst_1, txd=qsfp_rxd_1, txc=qsfp_rxc_1, name='qsfp_1_source') - - qsfp_1_sink = xgmii_ep.XGMIISink() - qsfp_1_sink_logic = qsfp_1_sink.create_logic(qsfp_tx_clk_1, qsfp_tx_rst_1, rxd=qsfp_txd_1, rxc=qsfp_txc_1, name='qsfp_1_sink') - - qsfp_2_source = xgmii_ep.XGMIISource() - qsfp_2_source_logic = qsfp_2_source.create_logic(qsfp_rx_clk_2, qsfp_rx_rst_2, txd=qsfp_rxd_2, txc=qsfp_rxc_2, name='qsfp_2_source') - - qsfp_2_sink = xgmii_ep.XGMIISink() - qsfp_2_sink_logic = qsfp_2_sink.create_logic(qsfp_tx_clk_2, qsfp_tx_rst_2, rxd=qsfp_txd_2, rxc=qsfp_txc_2, name='qsfp_2_sink') - - qsfp_3_source = xgmii_ep.XGMIISource() - qsfp_3_source_logic = qsfp_3_source.create_logic(qsfp_rx_clk_3, qsfp_rx_rst_3, txd=qsfp_rxd_3, txc=qsfp_rxc_3, name='qsfp_3_source') - - qsfp_3_sink = xgmii_ep.XGMIISink() - qsfp_3_sink_logic = qsfp_3_sink.create_logic(qsfp_tx_clk_3, qsfp_tx_rst_3, rxd=qsfp_txd_3, rxc=qsfp_txc_3, name='qsfp_3_sink') - - qsfp_4_source = xgmii_ep.XGMIISource() - qsfp_4_source_logic = qsfp_4_source.create_logic(qsfp_rx_clk_4, qsfp_rx_rst_4, txd=qsfp_rxd_4, txc=qsfp_rxc_4, name='qsfp_4_source') - - qsfp_4_sink = xgmii_ep.XGMIISink() - qsfp_4_sink_logic = qsfp_4_sink.create_logic(qsfp_tx_clk_4, qsfp_tx_rst_4, rxd=qsfp_txd_4, rxc=qsfp_txc_4, name='qsfp_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - qsfp_led_act=qsfp_led_act, - qsfp_led_stat_g=qsfp_led_stat_g, - qsfp_led_stat_y=qsfp_led_stat_y, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_tx_clk_1=qsfp_tx_clk_1, - qsfp_tx_rst_1=qsfp_tx_rst_1, - qsfp_txd_1=qsfp_txd_1, - qsfp_txc_1=qsfp_txc_1, - qsfp_rx_clk_1=qsfp_rx_clk_1, - qsfp_rx_rst_1=qsfp_rx_rst_1, - qsfp_rxd_1=qsfp_rxd_1, - qsfp_rxc_1=qsfp_rxc_1, - qsfp_tx_clk_2=qsfp_tx_clk_2, - qsfp_tx_rst_2=qsfp_tx_rst_2, - qsfp_txd_2=qsfp_txd_2, - qsfp_txc_2=qsfp_txc_2, - qsfp_rx_clk_2=qsfp_rx_clk_2, - qsfp_rx_rst_2=qsfp_rx_rst_2, - qsfp_rxd_2=qsfp_rxd_2, - qsfp_rxc_2=qsfp_rxc_2, - qsfp_tx_clk_3=qsfp_tx_clk_3, - qsfp_tx_rst_3=qsfp_tx_rst_3, - qsfp_txd_3=qsfp_txd_3, - qsfp_txc_3=qsfp_txc_3, - qsfp_rx_clk_3=qsfp_rx_clk_3, - qsfp_rx_rst_3=qsfp_rx_rst_3, - qsfp_rxd_3=qsfp_rxd_3, - qsfp_rxc_3=qsfp_rxc_3, - qsfp_tx_clk_4=qsfp_tx_clk_4, - qsfp_tx_rst_4=qsfp_tx_rst_4, - qsfp_txd_4=qsfp_txd_4, - qsfp_txc_4=qsfp_txc_4, - qsfp_rx_clk_4=qsfp_rx_clk_4, - qsfp_rx_rst_4=qsfp_rx_rst_4, - qsfp_rxd_4=qsfp_rxd_4, - qsfp_rxc_4=qsfp_rxc_4, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp_tx_clk_1.next = not qsfp_tx_clk_1 - qsfp_rx_clk_1.next = not qsfp_rx_clk_1 - qsfp_tx_clk_2.next = not qsfp_tx_clk_2 - qsfp_rx_clk_2.next = not qsfp_rx_clk_2 - qsfp_tx_clk_3.next = not qsfp_tx_clk_3 - qsfp_rx_clk_3.next = not qsfp_rx_clk_3 - qsfp_tx_clk_4.next = not qsfp_tx_clk_4 - qsfp_rx_clk_4.next = not qsfp_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_1_sink.empty(): - pkt = qsfp_1_sink.recv() - qsfp_1_source.send(pkt) - if not qsfp_2_sink.empty(): - pkt = qsfp_2_sink.recv() - qsfp_2_source.send(pkt) - if not qsfp_3_sink.empty(): - pkt = qsfp_3_sink.recv() - qsfp_3_source.send(pkt) - if not qsfp_4_sink.empty(): - pkt = qsfp_4_sink.recv() - qsfp_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_tx_rst_1.next = 1 - qsfp_rx_rst_1.next = 1 - qsfp_tx_rst_2.next = 1 - qsfp_rx_rst_2.next = 1 - qsfp_tx_rst_3.next = 1 - qsfp_rx_rst_3.next = 1 - qsfp_tx_rst_4.next = 1 - qsfp_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_tx_rst_1.next = 0 - qsfp_rx_rst_1.next = 0 - qsfp_tx_rst_2.next = 0 - qsfp_rx_rst_2.next = 0 - qsfp_tx_rst_3.next = 0 - qsfp_rx_rst_3.next = 0 - qsfp_tx_rst_4.next = 0 - qsfp_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_1_sink.wait() - - pkt = qsfp_1_sink.recv() - print(pkt) - - qsfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_sink.wait() - - # pkt = qsfp_1_sink.recv() - # print(pkt) - - # qsfp_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_1_sink.wait() - - pkt = qsfp_1_sink.recv() - print(pkt) - - qsfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/AU50/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/AU50/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 34316ae0d..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,411 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_tx_clk_1 = 0; -reg qsfp_tx_rst_1 = 0; -reg qsfp_rx_clk_1 = 0; -reg qsfp_rx_rst_1 = 0; -reg [63:0] qsfp_rxd_1 = 0; -reg [7:0] qsfp_rxc_1 = 0; -reg qsfp_tx_clk_2 = 0; -reg qsfp_tx_rst_2 = 0; -reg qsfp_rx_clk_2 = 0; -reg qsfp_rx_rst_2 = 0; -reg [63:0] qsfp_rxd_2 = 0; -reg [7:0] qsfp_rxc_2 = 0; -reg qsfp_tx_clk_3 = 0; -reg qsfp_tx_rst_3 = 0; -reg qsfp_rx_clk_3 = 0; -reg qsfp_rx_rst_3 = 0; -reg [63:0] qsfp_rxd_3 = 0; -reg [7:0] qsfp_rxc_3 = 0; -reg qsfp_tx_clk_4 = 0; -reg qsfp_tx_rst_4 = 0; -reg qsfp_rx_clk_4 = 0; -reg qsfp_rx_rst_4 = 0; -reg [63:0] qsfp_rxd_4 = 0; -reg [7:0] qsfp_rxc_4 = 0; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire qsfp_led_act; -wire qsfp_led_stat_g; -wire qsfp_led_stat_y; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_txd_1; -wire [7:0] qsfp_txc_1; -wire [63:0] qsfp_txd_2; -wire [7:0] qsfp_txc_2; -wire [63:0] qsfp_txd_3; -wire [7:0] qsfp_txc_3; -wire [63:0] qsfp_txd_4; -wire [7:0] qsfp_txc_4; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_tx_clk_1, - qsfp_tx_rst_1, - qsfp_rx_clk_1, - qsfp_rx_rst_1, - qsfp_rxd_1, - qsfp_rxc_1, - qsfp_tx_clk_2, - qsfp_tx_rst_2, - qsfp_rx_clk_2, - qsfp_rx_rst_2, - qsfp_rxd_2, - qsfp_rxc_2, - qsfp_tx_clk_3, - qsfp_tx_rst_3, - qsfp_rx_clk_3, - qsfp_rx_rst_3, - qsfp_rxd_3, - qsfp_rxc_3, - qsfp_tx_clk_4, - qsfp_tx_rst_4, - qsfp_rx_clk_4, - qsfp_rx_rst_4, - qsfp_rxd_4, - qsfp_rxc_4, - qspi_dq_i - ); - $to_myhdl( - qsfp_led_act, - qsfp_led_stat_g, - qsfp_led_stat_y, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_txd_1, - qsfp_txc_1, - qsfp_txd_2, - qsfp_txc_2, - qsfp_txd_3, - qsfp_txc_3, - qsfp_txd_4, - qsfp_txc_4, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .qsfp_led_act(qsfp_led_act), - .qsfp_led_stat_g(qsfp_led_stat_g), - .qsfp_led_stat_y(qsfp_led_stat_y), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_tx_clk_1(qsfp_tx_clk_1), - .qsfp_tx_rst_1(qsfp_tx_rst_1), - .qsfp_txd_1(qsfp_txd_1), - .qsfp_txc_1(qsfp_txc_1), - .qsfp_rx_clk_1(qsfp_rx_clk_1), - .qsfp_rx_rst_1(qsfp_rx_rst_1), - .qsfp_rxd_1(qsfp_rxd_1), - .qsfp_rxc_1(qsfp_rxc_1), - .qsfp_tx_clk_2(qsfp_tx_clk_2), - .qsfp_tx_rst_2(qsfp_tx_rst_2), - .qsfp_txd_2(qsfp_txd_2), - .qsfp_txc_2(qsfp_txc_2), - .qsfp_rx_clk_2(qsfp_rx_clk_2), - .qsfp_rx_rst_2(qsfp_rx_rst_2), - .qsfp_rxd_2(qsfp_rxd_2), - .qsfp_rxc_2(qsfp_rxc_2), - .qsfp_tx_clk_3(qsfp_tx_clk_3), - .qsfp_tx_rst_3(qsfp_tx_rst_3), - .qsfp_txd_3(qsfp_txd_3), - .qsfp_txc_3(qsfp_txc_3), - .qsfp_rx_clk_3(qsfp_rx_clk_3), - .qsfp_rx_rst_3(qsfp_rx_rst_3), - .qsfp_rxd_3(qsfp_rxd_3), - .qsfp_rxc_3(qsfp_rxc_3), - .qsfp_tx_clk_4(qsfp_tx_clk_4), - .qsfp_tx_rst_4(qsfp_tx_rst_4), - .qsfp_txd_4(qsfp_txd_4), - .qsfp_txc_4(qsfp_txc_4), - .qsfp_rx_clk_4(qsfp_rx_clk_4), - .qsfp_rx_rst_4(qsfp_rx_rst_4), - .qsfp_rxd_4(qsfp_rxd_4), - .qsfp_rxc_4(qsfp_rxc_4), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/AU50/fpga_10g/tb/udp_ep.py b/fpga/mqnic/AU50/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/AU50/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/AU50/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/AU50/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/axis_ep.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/eth_ep.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/Makefile b/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..e118ed2ab --- /dev/null +++ b/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= 60 +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= 75 +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= 85 +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= 33 +export PARAM_RQ_SEQ_NUM_WIDTH ?= 4 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/mqnic.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..b2537d786 --- /dev/null +++ b/fpga/mqnic/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,566 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num=dut.s_axis_rq_seq_num, + pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.sfp_1_rx_clk, 6.4, units="ns").start()) + self.sfp_1_source = XgmiiSource(dut.sfp_1_rxd, dut.sfp_1_rxc, dut.sfp_1_rx_clk, dut.sfp_1_rx_rst) + cocotb.fork(Clock(dut.sfp_1_tx_clk, 6.4, units="ns").start()) + self.sfp_1_sink = XgmiiSink(dut.sfp_1_txd, dut.sfp_1_txc, dut.sfp_1_tx_clk, dut.sfp_1_tx_rst) + + cocotb.fork(Clock(dut.sfp_2_rx_clk, 6.4, units="ns").start()) + self.sfp_2_source = XgmiiSource(dut.sfp_2_rxd, dut.sfp_2_rxc, dut.sfp_2_rx_clk, dut.sfp_2_rx_rst) + cocotb.fork(Clock(dut.sfp_2_tx_clk, 6.4, units="ns").start()) + self.sfp_2_sink = XgmiiSink(dut.sfp_2_txd, dut.sfp_2_txc, dut.sfp_2_tx_clk, dut.sfp_2_tx_rst) + + dut.sfp_1_npres.setimmediatevalue(0) + dut.sfp_2_npres.setimmediatevalue(0) + dut.sfp_1_los.setimmediatevalue(0) + dut.sfp_2_los.setimmediatevalue(0) + + dut.sma_in.setimmediatevalue(0) + + dut.sfp_i2c_scl_i.setimmediatevalue(1) + dut.sfp_1_i2c_sda_i.setimmediatevalue(1) + dut.sfp_2_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.flash_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(1) + self.dut.sfp_1_tx_rst.setimmediatevalue(1) + self.dut.sfp_2_rx_rst.setimmediatevalue(1) + self.dut.sfp_2_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.sfp_1_sink.empty(): + self.sfp_1_source.send(self.sfp_1_sink.recv()) + if not self.sfp_2_sink.empty(): + self.sfp_2_source.send(self.sfp_2_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.sfp_2_sink.wait() + + # pkt = tb.sfp_2_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.sfp_2_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/ip_ep.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/mqnic.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/pcie.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/pcie_us.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/test_fpga_core.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/test_fpga_core.py deleted file mode 100755 index bec15b957..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/test_fpga_core.py +++ /dev/null @@ -1,844 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_us -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 60 - AXIS_PCIE_CQ_USER_WIDTH = 85 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 4 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(0)[2:]) - pcie_tfc_npd_av = Signal(intbv(0)[2:]) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - sfp_1_tx_clk = Signal(bool(0)) - sfp_1_tx_rst = Signal(bool(0)) - sfp_1_rx_clk = Signal(bool(0)) - sfp_1_rx_rst = Signal(bool(0)) - sfp_1_rxd = Signal(intbv(0)[64:]) - sfp_1_rxc = Signal(intbv(0)[8:]) - sfp_2_tx_clk = Signal(bool(0)) - sfp_2_tx_rst = Signal(bool(0)) - sfp_2_rx_clk = Signal(bool(0)) - sfp_2_rx_rst = Signal(bool(0)) - sfp_2_rxd = Signal(intbv(0)[64:]) - sfp_2_rxc = Signal(intbv(0)[8:]) - sfp_1_npres = Signal(bool(0)) - sfp_2_npres = Signal(bool(0)) - sfp_1_los = Signal(bool(0)) - sfp_2_los = Signal(bool(0)) - sfp_i2c_scl_i = Signal(bool(1)) - sfp_1_i2c_sda_i = Signal(bool(1)) - sfp_2_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - flash_dq_i = Signal(intbv(0)[16:]) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sma_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - sfp_1_txd = Signal(intbv(0)[64:]) - sfp_1_txc = Signal(intbv(0)[8:]) - sfp_2_txd = Signal(intbv(0)[64:]) - sfp_2_txc = Signal(intbv(0)[8:]) - sfp_1_tx_disable = Signal(bool(0)) - sfp_2_tx_disable = Signal(bool(0)) - sfp_1_rs = Signal(bool(0)) - sfp_2_rs = Signal(bool(0)) - sfp_i2c_scl_o = Signal(bool(1)) - sfp_i2c_scl_t = Signal(bool(1)) - sfp_1_i2c_sda_o = Signal(bool(1)) - sfp_1_i2c_sda_t = Signal(bool(1)) - sfp_2_i2c_sda_o = Signal(bool(1)) - sfp_2_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - flash_dq_o = Signal(intbv(0)[16:]) - flash_dq_oe = Signal(bool(0)) - flash_addr = Signal(intbv(0)[23:]) - flash_region = Signal(bool(0)) - flash_region_oe = Signal(bool(0)) - flash_ce_n = Signal(bool(1)) - flash_oe_n = Signal(bool(1)) - flash_we_n = Signal(bool(1)) - flash_adv_n = Signal(bool(1)) - - # sources and sinks - sfp_1_source = xgmii_ep.XGMIISource() - sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') - - sfp_1_sink = xgmii_ep.XGMIISink() - sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') - - sfp_2_source = xgmii_ep.XGMIISource() - sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') - - sfp_2_sink = xgmii_ep.XGMIISink() - sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num=s_axis_rq_seq_num, - pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sfp_1_led=sfp_1_led, - sfp_2_led=sfp_2_led, - sma_led=sma_led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num=s_axis_rq_seq_num, - s_axis_rq_seq_num_valid=s_axis_rq_seq_num_valid, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - sfp_1_tx_clk=sfp_1_tx_clk, - sfp_1_tx_rst=sfp_1_tx_rst, - sfp_1_txd=sfp_1_txd, - sfp_1_txc=sfp_1_txc, - sfp_1_rx_clk=sfp_1_rx_clk, - sfp_1_rx_rst=sfp_1_rx_rst, - sfp_1_rxd=sfp_1_rxd, - sfp_1_rxc=sfp_1_rxc, - sfp_2_tx_clk=sfp_2_tx_clk, - sfp_2_tx_rst=sfp_2_tx_rst, - sfp_2_txd=sfp_2_txd, - sfp_2_txc=sfp_2_txc, - sfp_2_rx_clk=sfp_2_rx_clk, - sfp_2_rx_rst=sfp_2_rx_rst, - sfp_2_rxd=sfp_2_rxd, - sfp_2_rxc=sfp_2_rxc, - sfp_1_tx_disable=sfp_1_tx_disable, - sfp_2_tx_disable=sfp_2_tx_disable, - sfp_1_npres=sfp_1_npres, - sfp_2_npres=sfp_2_npres, - sfp_1_los=sfp_1_los, - sfp_2_los=sfp_2_los, - sfp_1_rs=sfp_1_rs, - sfp_2_rs=sfp_2_rs, - sfp_i2c_scl_i=sfp_i2c_scl_i, - sfp_i2c_scl_o=sfp_i2c_scl_o, - sfp_i2c_scl_t=sfp_i2c_scl_t, - sfp_1_i2c_sda_i=sfp_1_i2c_sda_i, - sfp_1_i2c_sda_o=sfp_1_i2c_sda_o, - sfp_1_i2c_sda_t=sfp_1_i2c_sda_t, - sfp_2_i2c_sda_i=sfp_2_i2c_sda_i, - sfp_2_i2c_sda_o=sfp_2_i2c_sda_o, - sfp_2_i2c_sda_t=sfp_2_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - fpga_boot=fpga_boot, - flash_dq_i=flash_dq_i, - flash_dq_o=flash_dq_o, - flash_dq_oe=flash_dq_oe, - flash_addr=flash_addr, - flash_region=flash_region, - flash_region_oe=flash_region_oe, - flash_ce_n=flash_ce_n, - flash_oe_n=flash_oe_n, - flash_we_n=flash_we_n, - flash_adv_n=flash_adv_n - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - sfp_1_tx_clk.next = clk - sfp_1_tx_rst.next = rst - sfp_1_rx_clk.next = clk - sfp_1_rx_rst.next = rst - sfp_2_tx_clk.next = clk - sfp_2_tx_rst.next = rst - sfp_2_rx_clk.next = clk - sfp_2_rx_rst.next = rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not sfp_1_sink.empty(): - pkt = sfp_1_sink.recv() - sfp_1_source.send(pkt) - if not sfp_2_sink.empty(): - pkt = sfp_2_sink.recv() - sfp_2_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - # configure PTP period out - yield from rc.mem_write_dword(driver.hw_addr+0x270, 0) # start fns - yield from rc.mem_write_dword(driver.hw_addr+0x274, 0) # start ns - yield from rc.mem_write_dword(driver.hw_addr+0x278, 0) # start sec (low) - yield from rc.mem_write_dword(driver.hw_addr+0x27C, 0) # start sec (high) - - yield from rc.mem_write_dword(driver.hw_addr+0x290, 0) # width fns - yield from rc.mem_write_dword(driver.hw_addr+0x294, 1000) # width ns - yield from rc.mem_write_dword(driver.hw_addr+0x298, 0) # width sec (low) - yield from rc.mem_write_dword(driver.hw_addr+0x29C, 0) # width sec (high) - - yield from rc.mem_write_dword(driver.hw_addr+0x280, 0) # period fns - yield from rc.mem_write_dword(driver.hw_addr+0x284, 2000) # period ns - yield from rc.mem_write_dword(driver.hw_addr+0x288, 0) # period sec (low) - yield from rc.mem_write_dword(driver.hw_addr+0x28C, 0) # period sec (high) - - yield from rc.mem_write_dword(driver.hw_addr+0x260, 1) # enable output - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/test_fpga_core.v b/fpga/mqnic/ExaNIC_X10/fpga/tb/test_fpga_core.v deleted file mode 100644 index 6581cb979..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/test_fpga_core.v +++ /dev/null @@ -1,441 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 256; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 60; -parameter AXIS_PCIE_CQ_USER_WIDTH = 85; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 4; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num = 0; -reg s_axis_rq_seq_num_valid = 0; -reg [1:0] pcie_tfc_nph_av = 0; -reg [1:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [7:0] cfg_interrupt_msi_vf_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg sfp_1_tx_clk = 0; -reg sfp_1_tx_rst = 0; -reg sfp_1_rx_clk = 0; -reg sfp_1_rx_rst = 0; -reg [63:0] sfp_1_rxd = 0; -reg [7:0] sfp_1_rxc = 0; -reg sfp_2_tx_clk = 0; -reg sfp_2_tx_rst = 0; -reg sfp_2_rx_clk = 0; -reg sfp_2_rx_rst = 0; -reg [63:0] sfp_2_rxd = 0; -reg [7:0] sfp_2_rxc = 0; -reg sfp_1_npres = 0; -reg sfp_2_npres = 0; -reg sfp_1_los = 0; -reg sfp_2_los = 0; -reg sfp_i2c_scl_i = 1; -reg sfp_1_i2c_sda_i = 1; -reg sfp_2_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [15:0] flash_dq_i = 0; - -// Outputs -wire [1:0] sfp_1_led; -wire [1:0] sfp_2_led; -wire [1:0] sma_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [18:0] cfg_mgmt_addr; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] sfp_1_txd; -wire [7:0] sfp_1_txc; -wire [63:0] sfp_2_txd; -wire [7:0] sfp_2_txc; -wire sfp_1_tx_disable; -wire sfp_2_tx_disable; -wire sfp_1_rs; -wire sfp_2_rs; -wire sfp_i2c_scl_o; -wire sfp_i2c_scl_t; -wire sfp_1_i2c_sda_o; -wire sfp_1_i2c_sda_t; -wire sfp_2_i2c_sda_o; -wire sfp_2_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire fpga_boot; -wire [15:0] flash_dq_o; -wire flash_dq_oe; -wire [22:0] flash_addr; -wire flash_region; -wire flash_region_oe; -wire flash_ce_n; -wire flash_oe_n; -wire flash_we_n; -wire flash_adv_n; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num, - s_axis_rq_seq_num_valid, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - sfp_1_tx_clk, - sfp_1_tx_rst, - sfp_1_rx_clk, - sfp_1_rx_rst, - sfp_1_rxd, - sfp_1_rxc, - sfp_2_tx_clk, - sfp_2_tx_rst, - sfp_2_rx_clk, - sfp_2_rx_rst, - sfp_2_rxd, - sfp_2_rxc, - sfp_1_npres, - sfp_2_npres, - sfp_1_los, - sfp_2_los, - sfp_i2c_scl_i, - sfp_1_i2c_sda_i, - sfp_2_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - flash_dq_i - ); - $to_myhdl( - sfp_1_led, - sfp_2_led, - sma_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - sfp_1_txd, - sfp_1_txc, - sfp_2_txd, - sfp_2_txc, - sfp_1_tx_disable, - sfp_2_tx_disable, - sfp_1_rs, - sfp_2_rs, - sfp_i2c_scl_o, - sfp_i2c_scl_t, - sfp_1_i2c_sda_o, - sfp_1_i2c_sda_t, - sfp_2_i2c_sda_o, - sfp_2_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - fpga_boot, - flash_dq_o, - flash_dq_oe, - flash_addr, - flash_region, - flash_region_oe, - flash_ce_n, - flash_oe_n, - flash_we_n, - flash_adv_n - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sfp_1_led(sfp_1_led), - .sfp_2_led(sfp_2_led), - .sma_led(sma_led), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num(s_axis_rq_seq_num), - .s_axis_rq_seq_num_valid(s_axis_rq_seq_num_valid), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .sfp_1_tx_clk(sfp_1_tx_clk), - .sfp_1_tx_rst(sfp_1_tx_rst), - .sfp_1_txd(sfp_1_txd), - .sfp_1_txc(sfp_1_txc), - .sfp_1_rx_clk(sfp_1_rx_clk), - .sfp_1_rx_rst(sfp_1_rx_rst), - .sfp_1_rxd(sfp_1_rxd), - .sfp_1_rxc(sfp_1_rxc), - .sfp_2_tx_clk(sfp_2_tx_clk), - .sfp_2_tx_rst(sfp_2_tx_rst), - .sfp_2_txd(sfp_2_txd), - .sfp_2_txc(sfp_2_txc), - .sfp_2_rx_clk(sfp_2_rx_clk), - .sfp_2_rx_rst(sfp_2_rx_rst), - .sfp_2_rxd(sfp_2_rxd), - .sfp_2_rxc(sfp_2_rxc), - .sfp_1_tx_disable(sfp_1_tx_disable), - .sfp_2_tx_disable(sfp_2_tx_disable), - .sfp_1_npres(sfp_1_npres), - .sfp_2_npres(sfp_2_npres), - .sfp_1_los(sfp_1_los), - .sfp_2_los(sfp_2_los), - .sfp_1_rs(sfp_1_rs), - .sfp_2_rs(sfp_2_rs), - .sfp_i2c_scl_i(sfp_i2c_scl_i), - .sfp_i2c_scl_o(sfp_i2c_scl_o), - .sfp_i2c_scl_t(sfp_i2c_scl_t), - .sfp_1_i2c_sda_i(sfp_1_i2c_sda_i), - .sfp_1_i2c_sda_o(sfp_1_i2c_sda_o), - .sfp_1_i2c_sda_t(sfp_1_i2c_sda_t), - .sfp_2_i2c_sda_i(sfp_2_i2c_sda_i), - .sfp_2_i2c_sda_o(sfp_2_i2c_sda_o), - .sfp_2_i2c_sda_t(sfp_2_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .fpga_boot(fpga_boot), - .flash_dq_i(flash_dq_i), - .flash_dq_o(flash_dq_o), - .flash_dq_oe(flash_dq_oe), - .flash_addr(flash_addr), - .flash_region(flash_region), - .flash_region_oe(flash_region_oe), - .flash_ce_n(flash_ce_n), - .flash_oe_n(flash_oe_n), - .flash_we_n(flash_we_n), - .flash_adv_n(flash_adv_n) -); - -endmodule diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/udp_ep.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X10/fpga/tb/xgmii_ep.py b/fpga/mqnic/ExaNIC_X10/fpga/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/ExaNIC_X10/fpga/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/axis_ep.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/eth_ep.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..03327e441 --- /dev/null +++ b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..8f6ca8a41 --- /dev/null +++ b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,570 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.sfp_1_rx_clk, 6.4, units="ns").start()) + self.sfp_1_source = XgmiiSource(dut.sfp_1_rxd, dut.sfp_1_rxc, dut.sfp_1_rx_clk, dut.sfp_1_rx_rst) + cocotb.fork(Clock(dut.sfp_1_tx_clk, 6.4, units="ns").start()) + self.sfp_1_sink = XgmiiSink(dut.sfp_1_txd, dut.sfp_1_txc, dut.sfp_1_tx_clk, dut.sfp_1_tx_rst) + + cocotb.fork(Clock(dut.sfp_2_rx_clk, 6.4, units="ns").start()) + self.sfp_2_source = XgmiiSource(dut.sfp_2_rxd, dut.sfp_2_rxc, dut.sfp_2_rx_clk, dut.sfp_2_rx_rst) + cocotb.fork(Clock(dut.sfp_2_tx_clk, 6.4, units="ns").start()) + self.sfp_2_sink = XgmiiSink(dut.sfp_2_txd, dut.sfp_2_txc, dut.sfp_2_tx_clk, dut.sfp_2_tx_rst) + + dut.sfp_1_npres.setimmediatevalue(0) + dut.sfp_2_npres.setimmediatevalue(0) + dut.sfp_1_los.setimmediatevalue(0) + dut.sfp_2_los.setimmediatevalue(0) + + dut.sma_in.setimmediatevalue(0) + + dut.sfp_i2c_scl_i.setimmediatevalue(1) + dut.sfp_1_i2c_sda_i.setimmediatevalue(1) + dut.sfp_2_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.flash_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(1) + self.dut.sfp_1_tx_rst.setimmediatevalue(1) + self.dut.sfp_2_rx_rst.setimmediatevalue(1) + self.dut.sfp_2_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.sfp_1_sink.empty(): + self.sfp_1_source.send(self.sfp_1_sink.recv()) + if not self.sfp_2_sink.empty(): + self.sfp_2_source.send(self.sfp_2_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.sfp_2_sink.wait() + + # pkt = tb.sfp_2_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.sfp_2_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/ip_ep.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/mqnic.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie_us.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 1bc04d11c..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,833 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 62 - AXIS_PCIE_CQ_USER_WIDTH = 88 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(0)[4:]) - pcie_tfc_npd_av = Signal(intbv(0)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - sfp_1_tx_clk = Signal(bool(0)) - sfp_1_tx_rst = Signal(bool(0)) - sfp_1_rx_clk = Signal(bool(0)) - sfp_1_rx_rst = Signal(bool(0)) - sfp_1_rxd = Signal(intbv(0)[64:]) - sfp_1_rxc = Signal(intbv(0)[8:]) - sfp_2_tx_clk = Signal(bool(0)) - sfp_2_tx_rst = Signal(bool(0)) - sfp_2_rx_clk = Signal(bool(0)) - sfp_2_rx_rst = Signal(bool(0)) - sfp_2_rxd = Signal(intbv(0)[64:]) - sfp_2_rxc = Signal(intbv(0)[8:]) - sfp_1_npres = Signal(bool(0)) - sfp_2_npres = Signal(bool(0)) - sfp_1_los = Signal(bool(0)) - sfp_2_los = Signal(bool(0)) - sfp_i2c_scl_i = Signal(bool(1)) - sfp_1_i2c_sda_i = Signal(bool(1)) - sfp_2_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - flash_dq_i = Signal(intbv(0)[16:]) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sma_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - sfp_1_txd = Signal(intbv(0)[64:]) - sfp_1_txc = Signal(intbv(0)[8:]) - sfp_2_txd = Signal(intbv(0)[64:]) - sfp_2_txc = Signal(intbv(0)[8:]) - sfp_1_tx_disable = Signal(bool(0)) - sfp_2_tx_disable = Signal(bool(0)) - sfp_1_rs = Signal(bool(0)) - sfp_2_rs = Signal(bool(0)) - sfp_i2c_scl_o = Signal(bool(1)) - sfp_i2c_scl_t = Signal(bool(1)) - sfp_1_i2c_sda_o = Signal(bool(1)) - sfp_1_i2c_sda_t = Signal(bool(1)) - sfp_2_i2c_sda_o = Signal(bool(1)) - sfp_2_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - flash_dq_o = Signal(intbv(0)[16:]) - flash_dq_oe = Signal(bool(0)) - flash_addr = Signal(intbv(0)[23:]) - flash_region = Signal(bool(0)) - flash_region_oe = Signal(bool(0)) - flash_ce_n = Signal(bool(1)) - flash_oe_n = Signal(bool(1)) - flash_we_n = Signal(bool(1)) - flash_adv_n = Signal(bool(1)) - - # sources and sinks - sfp_1_source = xgmii_ep.XGMIISource() - sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') - - sfp_1_sink = xgmii_ep.XGMIISink() - sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') - - sfp_2_source = xgmii_ep.XGMIISource() - sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') - - sfp_2_sink = xgmii_ep.XGMIISink() - sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(1)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sfp_1_led=sfp_1_led, - sfp_2_led=sfp_2_led, - sma_led=sma_led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - sfp_1_tx_clk=sfp_1_tx_clk, - sfp_1_tx_rst=sfp_1_tx_rst, - sfp_1_txd=sfp_1_txd, - sfp_1_txc=sfp_1_txc, - sfp_1_rx_clk=sfp_1_rx_clk, - sfp_1_rx_rst=sfp_1_rx_rst, - sfp_1_rxd=sfp_1_rxd, - sfp_1_rxc=sfp_1_rxc, - sfp_2_tx_clk=sfp_2_tx_clk, - sfp_2_tx_rst=sfp_2_tx_rst, - sfp_2_txd=sfp_2_txd, - sfp_2_txc=sfp_2_txc, - sfp_2_rx_clk=sfp_2_rx_clk, - sfp_2_rx_rst=sfp_2_rx_rst, - sfp_2_rxd=sfp_2_rxd, - sfp_2_rxc=sfp_2_rxc, - sfp_1_tx_disable=sfp_1_tx_disable, - sfp_2_tx_disable=sfp_2_tx_disable, - sfp_1_npres=sfp_1_npres, - sfp_2_npres=sfp_2_npres, - sfp_1_los=sfp_1_los, - sfp_2_los=sfp_2_los, - sfp_1_rs=sfp_1_rs, - sfp_2_rs=sfp_2_rs, - sfp_i2c_scl_i=sfp_i2c_scl_i, - sfp_i2c_scl_o=sfp_i2c_scl_o, - sfp_i2c_scl_t=sfp_i2c_scl_t, - sfp_1_i2c_sda_i=sfp_1_i2c_sda_i, - sfp_1_i2c_sda_o=sfp_1_i2c_sda_o, - sfp_1_i2c_sda_t=sfp_1_i2c_sda_t, - sfp_2_i2c_sda_i=sfp_2_i2c_sda_i, - sfp_2_i2c_sda_o=sfp_2_i2c_sda_o, - sfp_2_i2c_sda_t=sfp_2_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - fpga_boot=fpga_boot, - flash_dq_i=flash_dq_i, - flash_dq_o=flash_dq_o, - flash_dq_oe=flash_dq_oe, - flash_addr=flash_addr, - flash_region=flash_region, - flash_region_oe=flash_region_oe, - flash_ce_n=flash_ce_n, - flash_oe_n=flash_oe_n, - flash_we_n=flash_we_n, - flash_adv_n=flash_adv_n - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - sfp_1_tx_clk.next = clk - sfp_1_tx_rst.next = rst - sfp_1_rx_clk.next = clk - sfp_1_rx_rst.next = rst - sfp_2_tx_clk.next = clk - sfp_2_tx_rst.next = rst - sfp_2_rx_clk.next = clk - sfp_2_rx_rst.next = rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not sfp_1_sink.empty(): - pkt = sfp_1_sink.recv() - sfp_1_source.send(pkt) - if not sfp_2_sink.empty(): - pkt = sfp_2_sink.recv() - sfp_2_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index cc1d56e2f..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,446 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 256; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 62; -parameter AXIS_PCIE_CQ_USER_WIDTH = 88; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg sfp_1_tx_clk = 0; -reg sfp_1_tx_rst = 0; -reg sfp_1_rx_clk = 0; -reg sfp_1_rx_rst = 0; -reg [63:0] sfp_1_rxd = 0; -reg [7:0] sfp_1_rxc = 0; -reg sfp_2_tx_clk = 0; -reg sfp_2_tx_rst = 0; -reg sfp_2_rx_clk = 0; -reg sfp_2_rx_rst = 0; -reg [63:0] sfp_2_rxd = 0; -reg [7:0] sfp_2_rxc = 0; -reg sfp_1_npres = 0; -reg sfp_2_npres = 0; -reg sfp_1_los = 0; -reg sfp_2_los = 0; -reg sfp_i2c_scl_i = 1; -reg sfp_1_i2c_sda_i = 1; -reg sfp_2_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [15:0] flash_dq_i = 0; - -// Outputs -wire [1:0] sfp_1_led; -wire [1:0] sfp_2_led; -wire [1:0] sma_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] sfp_1_txd; -wire [7:0] sfp_1_txc; -wire [63:0] sfp_2_txd; -wire [7:0] sfp_2_txc; -wire sfp_1_tx_disable; -wire sfp_2_tx_disable; -wire sfp_1_rs; -wire sfp_2_rs; -wire sfp_i2c_scl_o; -wire sfp_i2c_scl_t; -wire sfp_1_i2c_sda_o; -wire sfp_1_i2c_sda_t; -wire sfp_2_i2c_sda_o; -wire sfp_2_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire fpga_boot; -wire [15:0] flash_dq_o; -wire flash_dq_oe; -wire [22:0] flash_addr; -wire flash_region; -wire flash_region_oe; -wire flash_ce_n; -wire flash_oe_n; -wire flash_we_n; -wire flash_adv_n; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - sfp_1_tx_clk, - sfp_1_tx_rst, - sfp_1_rx_clk, - sfp_1_rx_rst, - sfp_1_rxd, - sfp_1_rxc, - sfp_2_tx_clk, - sfp_2_tx_rst, - sfp_2_rx_clk, - sfp_2_rx_rst, - sfp_2_rxd, - sfp_2_rxc, - sfp_1_npres, - sfp_2_npres, - sfp_1_los, - sfp_2_los, - sfp_i2c_scl_i, - sfp_1_i2c_sda_i, - sfp_2_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - flash_dq_i - ); - $to_myhdl( - sfp_1_led, - sfp_2_led, - sma_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - sfp_1_txd, - sfp_1_txc, - sfp_2_txd, - sfp_2_txc, - sfp_1_tx_disable, - sfp_2_tx_disable, - sfp_1_rs, - sfp_2_rs, - sfp_i2c_scl_o, - sfp_i2c_scl_t, - sfp_1_i2c_sda_o, - sfp_1_i2c_sda_t, - sfp_2_i2c_sda_o, - sfp_2_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - fpga_boot, - flash_dq_o, - flash_dq_oe, - flash_addr, - flash_region, - flash_region_oe, - flash_ce_n, - flash_oe_n, - flash_we_n, - flash_adv_n - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sfp_1_led(sfp_1_led), - .sfp_2_led(sfp_2_led), - .sma_led(sma_led), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .sfp_1_tx_clk(sfp_1_tx_clk), - .sfp_1_tx_rst(sfp_1_tx_rst), - .sfp_1_txd(sfp_1_txd), - .sfp_1_txc(sfp_1_txc), - .sfp_1_rx_clk(sfp_1_rx_clk), - .sfp_1_rx_rst(sfp_1_rx_rst), - .sfp_1_rxd(sfp_1_rxd), - .sfp_1_rxc(sfp_1_rxc), - .sfp_2_tx_clk(sfp_2_tx_clk), - .sfp_2_tx_rst(sfp_2_tx_rst), - .sfp_2_txd(sfp_2_txd), - .sfp_2_txc(sfp_2_txc), - .sfp_2_rx_clk(sfp_2_rx_clk), - .sfp_2_rx_rst(sfp_2_rx_rst), - .sfp_2_rxd(sfp_2_rxd), - .sfp_2_rxc(sfp_2_rxc), - .sfp_1_tx_disable(sfp_1_tx_disable), - .sfp_2_tx_disable(sfp_2_tx_disable), - .sfp_1_npres(sfp_1_npres), - .sfp_2_npres(sfp_2_npres), - .sfp_1_los(sfp_1_los), - .sfp_2_los(sfp_2_los), - .sfp_1_rs(sfp_1_rs), - .sfp_2_rs(sfp_2_rs), - .sfp_i2c_scl_i(sfp_i2c_scl_i), - .sfp_i2c_scl_o(sfp_i2c_scl_o), - .sfp_i2c_scl_t(sfp_i2c_scl_t), - .sfp_1_i2c_sda_i(sfp_1_i2c_sda_i), - .sfp_1_i2c_sda_o(sfp_1_i2c_sda_o), - .sfp_1_i2c_sda_t(sfp_1_i2c_sda_t), - .sfp_2_i2c_sda_i(sfp_2_i2c_sda_i), - .sfp_2_i2c_sda_o(sfp_2_i2c_sda_o), - .sfp_2_i2c_sda_t(sfp_2_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .fpga_boot(fpga_boot), - .flash_dq_i(flash_dq_i), - .flash_dq_o(flash_dq_o), - .flash_dq_oe(flash_dq_oe), - .flash_addr(flash_addr), - .flash_region(flash_region), - .flash_region_oe(flash_region_oe), - .flash_ce_n(flash_ce_n), - .flash_oe_n(flash_oe_n), - .flash_we_n(flash_we_n), - .flash_adv_n(flash_adv_n) -); - -endmodule diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/udp_ep.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/ExaNIC_X25/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/axis_ep.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/eth_ep.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..e118ed2ab --- /dev/null +++ b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= 60 +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= 75 +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= 85 +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= 33 +export PARAM_RQ_SEQ_NUM_WIDTH ?= 4 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/mqnic.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..41d8d6efa --- /dev/null +++ b/fpga/mqnic/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,581 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num=dut.s_axis_rq_seq_num, + pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.sfp_1_rx_clk, 6.4, units="ns").start()) + self.sfp_1_source = XgmiiSource(dut.sfp_1_rxd, dut.sfp_1_rxc, dut.sfp_1_rx_clk, dut.sfp_1_rx_rst) + cocotb.fork(Clock(dut.sfp_1_tx_clk, 6.4, units="ns").start()) + self.sfp_1_sink = XgmiiSink(dut.sfp_1_txd, dut.sfp_1_txc, dut.sfp_1_tx_clk, dut.sfp_1_tx_rst) + + cocotb.fork(Clock(dut.sfp_2_rx_clk, 6.4, units="ns").start()) + self.sfp_2_source = XgmiiSource(dut.sfp_2_rxd, dut.sfp_2_rxc, dut.sfp_2_rx_clk, dut.sfp_2_rx_rst) + cocotb.fork(Clock(dut.sfp_2_tx_clk, 6.4, units="ns").start()) + self.sfp_2_sink = XgmiiSink(dut.sfp_2_txd, dut.sfp_2_txc, dut.sfp_2_tx_clk, dut.sfp_2_tx_rst) + + cocotb.fork(Clock(dut.sfp_3_rx_clk, 6.4, units="ns").start()) + self.sfp_3_source = XgmiiSource(dut.sfp_3_rxd, dut.sfp_3_rxc, dut.sfp_3_rx_clk, dut.sfp_3_rx_rst) + cocotb.fork(Clock(dut.sfp_3_tx_clk, 6.4, units="ns").start()) + self.sfp_3_sink = XgmiiSink(dut.sfp_3_txd, dut.sfp_3_txc, dut.sfp_3_tx_clk, dut.sfp_3_tx_rst) + + cocotb.fork(Clock(dut.sfp_4_rx_clk, 6.4, units="ns").start()) + self.sfp_4_source = XgmiiSource(dut.sfp_4_rxd, dut.sfp_4_rxc, dut.sfp_4_rx_clk, dut.sfp_4_rx_rst) + cocotb.fork(Clock(dut.sfp_4_tx_clk, 6.4, units="ns").start()) + self.sfp_4_sink = XgmiiSink(dut.sfp_4_txd, dut.sfp_4_txc, dut.sfp_4_tx_clk, dut.sfp_4_tx_rst) + + dut.btn.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + self.dut.sfp_3_rx_rst.setimmediatevalue(0) + self.dut.sfp_3_tx_rst.setimmediatevalue(0) + self.dut.sfp_4_rx_rst.setimmediatevalue(0) + self.dut.sfp_4_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(1) + self.dut.sfp_1_tx_rst.setimmediatevalue(1) + self.dut.sfp_2_rx_rst.setimmediatevalue(1) + self.dut.sfp_2_tx_rst.setimmediatevalue(1) + self.dut.sfp_3_rx_rst.setimmediatevalue(1) + self.dut.sfp_3_tx_rst.setimmediatevalue(1) + self.dut.sfp_4_rx_rst.setimmediatevalue(1) + self.dut.sfp_4_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + self.dut.sfp_3_rx_rst.setimmediatevalue(0) + self.dut.sfp_3_tx_rst.setimmediatevalue(0) + self.dut.sfp_4_rx_rst.setimmediatevalue(0) + self.dut.sfp_4_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.sfp_1_sink.empty(): + self.sfp_1_source.send(self.sfp_1_sink.recv()) + if not self.sfp_2_sink.empty(): + self.sfp_2_source.send(self.sfp_2_sink.recv()) + if not self.sfp_3_sink.empty(): + self.sfp_3_source.send(self.sfp_3_sink.recv()) + if not self.sfp_4_sink.empty(): + self.sfp_4_source.send(self.sfp_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.sfp_2_sink.wait() + + # pkt = tb.sfp_2_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.sfp_2_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/ip_ep.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/mqnic.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/pcie.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/pcie_us.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/test_fpga_core.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/test_fpga_core.py deleted file mode 100755 index da64963fe..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/test_fpga_core.py +++ /dev/null @@ -1,834 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_us -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 60 - AXIS_PCIE_CQ_USER_WIDTH = 85 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 4 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btn = Signal(intbv(0)[2:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(0)[2:]) - pcie_tfc_npd_av = Signal(intbv(0)[2:]) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - sfp_1_tx_clk = Signal(bool(0)) - sfp_1_tx_rst = Signal(bool(0)) - sfp_1_rx_clk = Signal(bool(0)) - sfp_1_rx_rst = Signal(bool(0)) - sfp_1_rxd = Signal(intbv(0)[64:]) - sfp_1_rxc = Signal(intbv(0)[8:]) - sfp_2_tx_clk = Signal(bool(0)) - sfp_2_tx_rst = Signal(bool(0)) - sfp_2_rx_clk = Signal(bool(0)) - sfp_2_rx_rst = Signal(bool(0)) - sfp_2_rxd = Signal(intbv(0)[64:]) - sfp_2_rxc = Signal(intbv(0)[8:]) - sfp_3_tx_clk = Signal(bool(0)) - sfp_3_tx_rst = Signal(bool(0)) - sfp_3_rx_clk = Signal(bool(0)) - sfp_3_rx_rst = Signal(bool(0)) - sfp_3_rxd = Signal(intbv(0)[64:]) - sfp_3_rxc = Signal(intbv(0)[8:]) - sfp_4_tx_clk = Signal(bool(0)) - sfp_4_tx_rst = Signal(bool(0)) - sfp_4_rx_clk = Signal(bool(0)) - sfp_4_rx_rst = Signal(bool(0)) - sfp_4_rxd = Signal(intbv(0)[64:]) - sfp_4_rxc = Signal(intbv(0)[8:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sfp_3_led = Signal(intbv(0)[2:]) - sfp_4_led = Signal(intbv(0)[2:]) - led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - sfp_1_txd = Signal(intbv(0)[64:]) - sfp_1_txc = Signal(intbv(0)[8:]) - sfp_2_txd = Signal(intbv(0)[64:]) - sfp_2_txc = Signal(intbv(0)[8:]) - sfp_3_txd = Signal(intbv(0)[64:]) - sfp_3_txc = Signal(intbv(0)[8:]) - sfp_4_txd = Signal(intbv(0)[64:]) - sfp_4_txc = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - - # sources and sinks - sfp_1_source = xgmii_ep.XGMIISource() - sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') - - sfp_1_sink = xgmii_ep.XGMIISink() - sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') - - sfp_2_source = xgmii_ep.XGMIISource() - sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') - - sfp_2_sink = xgmii_ep.XGMIISink() - sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_sink') - - sfp_3_source = xgmii_ep.XGMIISource() - sfp_3_source_logic = sfp_3_source.create_logic(sfp_3_rx_clk, sfp_3_rx_rst, txd=sfp_3_rxd, txc=sfp_3_rxc, name='sfp_3_source') - - sfp_3_sink = xgmii_ep.XGMIISink() - sfp_3_sink_logic = sfp_3_sink.create_logic(sfp_3_tx_clk, sfp_3_tx_rst, rxd=sfp_3_txd, rxc=sfp_3_txc, name='sfp_3_sink') - - sfp_4_source = xgmii_ep.XGMIISource() - sfp_4_source_logic = sfp_4_source.create_logic(sfp_4_rx_clk, sfp_4_rx_rst, txd=sfp_4_rxd, txc=sfp_4_rxc, name='sfp_4_source') - - sfp_4_sink = xgmii_ep.XGMIISink() - sfp_4_sink_logic = sfp_4_sink.create_logic(sfp_4_tx_clk, sfp_4_tx_rst, rxd=sfp_4_txd, rxc=sfp_4_txc, name='sfp_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num=s_axis_rq_seq_num, - pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btn=btn, - sfp_1_led=sfp_1_led, - sfp_2_led=sfp_2_led, - sfp_3_led=sfp_3_led, - sfp_4_led=sfp_4_led, - led=led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num=s_axis_rq_seq_num, - s_axis_rq_seq_num_valid=s_axis_rq_seq_num_valid, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - sfp_1_tx_clk=sfp_1_tx_clk, - sfp_1_tx_rst=sfp_1_tx_rst, - sfp_1_txd=sfp_1_txd, - sfp_1_txc=sfp_1_txc, - sfp_1_rx_clk=sfp_1_rx_clk, - sfp_1_rx_rst=sfp_1_rx_rst, - sfp_1_rxd=sfp_1_rxd, - sfp_1_rxc=sfp_1_rxc, - sfp_2_tx_clk=sfp_2_tx_clk, - sfp_2_tx_rst=sfp_2_tx_rst, - sfp_2_txd=sfp_2_txd, - sfp_2_txc=sfp_2_txc, - sfp_2_rx_clk=sfp_2_rx_clk, - sfp_2_rx_rst=sfp_2_rx_rst, - sfp_2_rxd=sfp_2_rxd, - sfp_2_rxc=sfp_2_rxc, - sfp_3_tx_clk=sfp_3_tx_clk, - sfp_3_tx_rst=sfp_3_tx_rst, - sfp_3_txd=sfp_3_txd, - sfp_3_txc=sfp_3_txc, - sfp_3_rx_clk=sfp_3_rx_clk, - sfp_3_rx_rst=sfp_3_rx_rst, - sfp_3_rxd=sfp_3_rxd, - sfp_3_rxc=sfp_3_rxc, - sfp_4_tx_clk=sfp_4_tx_clk, - sfp_4_tx_rst=sfp_4_tx_rst, - sfp_4_txd=sfp_4_txd, - sfp_4_txc=sfp_4_txc, - sfp_4_rx_clk=sfp_4_rx_clk, - sfp_4_rx_rst=sfp_4_rx_rst, - sfp_4_rxd=sfp_4_rxd, - sfp_4_rxc=sfp_4_rxc, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - sfp_1_tx_clk.next = clk - sfp_1_tx_rst.next = rst - sfp_1_rx_clk.next = clk - sfp_1_rx_rst.next = rst - sfp_2_tx_clk.next = clk - sfp_2_tx_rst.next = rst - sfp_2_rx_clk.next = clk - sfp_2_rx_rst.next = rst - sfp_3_tx_clk.next = clk - sfp_3_tx_rst.next = rst - sfp_3_rx_clk.next = clk - sfp_3_rx_rst.next = rst - sfp_4_tx_clk.next = clk - sfp_4_tx_rst.next = rst - sfp_4_rx_clk.next = clk - sfp_4_rx_rst.next = rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not sfp_1_sink.empty(): - pkt = sfp_1_sink.recv() - sfp_1_source.send(pkt) - if not sfp_2_sink.empty(): - pkt = sfp_2_sink.recv() - sfp_2_source.send(pkt) - if not sfp_3_sink.empty(): - pkt = sfp_3_sink.recv() - sfp_3_source.send(pkt) - if not sfp_4_sink.empty(): - pkt = sfp_4_sink.recv() - sfp_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate() - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/test_fpga_core.v b/fpga/mqnic/NetFPGA_SUME/fpga/tb/test_fpga_core.v deleted file mode 100644 index 9a6f08202..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/test_fpga_core.v +++ /dev/null @@ -1,414 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 256; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 60; -parameter AXIS_PCIE_CQ_USER_WIDTH = 85; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 4; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [1:0] btn = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [1:0] pcie_tfc_nph_av = 0; -reg [1:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [7:0] cfg_interrupt_msi_vf_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg sfp_1_tx_clk = 0; -reg sfp_1_tx_rst = 0; -reg sfp_1_rx_clk = 0; -reg sfp_1_rx_rst = 0; -reg [63:0] sfp_1_rxd = 0; -reg [7:0] sfp_1_rxc = 0; -reg sfp_2_tx_clk = 0; -reg sfp_2_tx_rst = 0; -reg sfp_2_rx_clk = 0; -reg sfp_2_rx_rst = 0; -reg [63:0] sfp_2_rxd = 0; -reg [7:0] sfp_2_rxc = 0; -reg sfp_3_tx_clk = 0; -reg sfp_3_tx_rst = 0; -reg sfp_3_rx_clk = 0; -reg sfp_3_rx_rst = 0; -reg [63:0] sfp_3_rxd = 0; -reg [7:0] sfp_3_rxc = 0; -reg sfp_4_tx_clk = 0; -reg sfp_4_tx_rst = 0; -reg sfp_4_rx_clk = 0; -reg sfp_4_rx_rst = 0; -reg [63:0] sfp_4_rxd = 0; -reg [7:0] sfp_4_rxc = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; - -// Outputs -wire [1:0] sfp_1_led; -wire [1:0] sfp_2_led; -wire [1:0] sfp_3_led; -wire [1:0] sfp_4_led; -wire [1:0] led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num = 0; -reg s_axis_rq_seq_num_valid = 0; -wire [18:0] cfg_mgmt_addr; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] sfp_1_txd; -wire [7:0] sfp_1_txc; -wire [63:0] sfp_2_txd; -wire [7:0] sfp_2_txc; -wire [63:0] sfp_3_txd; -wire [7:0] sfp_3_txc; -wire [63:0] sfp_4_txd; -wire [7:0] sfp_4_txc; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btn, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num, - s_axis_rq_seq_num_valid, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - sfp_1_tx_clk, - sfp_1_tx_rst, - sfp_1_rx_clk, - sfp_1_rx_rst, - sfp_1_rxd, - sfp_1_rxc, - sfp_2_tx_clk, - sfp_2_tx_rst, - sfp_2_rx_clk, - sfp_2_rx_rst, - sfp_2_rxd, - sfp_2_rxc, - sfp_3_tx_clk, - sfp_3_tx_rst, - sfp_3_rx_clk, - sfp_3_rx_rst, - sfp_3_rxd, - sfp_3_rxc, - sfp_4_tx_clk, - sfp_4_tx_rst, - sfp_4_rx_clk, - sfp_4_rx_rst, - sfp_4_rxd, - sfp_4_rxc, - i2c_scl_i, - i2c_sda_i - ); - $to_myhdl( - sfp_1_led, - sfp_2_led, - sfp_3_led, - sfp_4_led, - led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - sfp_1_txd, - sfp_1_txc, - sfp_2_txd, - sfp_2_txc, - sfp_3_txd, - sfp_3_txc, - sfp_4_txd, - sfp_4_txc, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btn(btn), - .sfp_1_led(sfp_1_led), - .sfp_2_led(sfp_2_led), - .sfp_3_led(sfp_3_led), - .sfp_4_led(sfp_4_led), - .led(led), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num(s_axis_rq_seq_num), - .s_axis_rq_seq_num_valid(s_axis_rq_seq_num_valid), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .sfp_1_tx_clk(sfp_1_tx_clk), - .sfp_1_tx_rst(sfp_1_tx_rst), - .sfp_1_txd(sfp_1_txd), - .sfp_1_txc(sfp_1_txc), - .sfp_1_rx_clk(sfp_1_rx_clk), - .sfp_1_rx_rst(sfp_1_rx_rst), - .sfp_1_rxd(sfp_1_rxd), - .sfp_1_rxc(sfp_1_rxc), - .sfp_2_tx_clk(sfp_2_tx_clk), - .sfp_2_tx_rst(sfp_2_tx_rst), - .sfp_2_txd(sfp_2_txd), - .sfp_2_txc(sfp_2_txc), - .sfp_2_rx_clk(sfp_2_rx_clk), - .sfp_2_rx_rst(sfp_2_rx_rst), - .sfp_2_rxd(sfp_2_rxd), - .sfp_2_rxc(sfp_2_rxc), - .sfp_3_tx_clk(sfp_3_tx_clk), - .sfp_3_tx_rst(sfp_3_tx_rst), - .sfp_3_txd(sfp_3_txd), - .sfp_3_txc(sfp_3_txc), - .sfp_3_rx_clk(sfp_3_rx_clk), - .sfp_3_rx_rst(sfp_3_rx_rst), - .sfp_3_rxd(sfp_3_rxd), - .sfp_3_rxc(sfp_3_rxc), - .sfp_4_tx_clk(sfp_4_tx_clk), - .sfp_4_tx_rst(sfp_4_tx_rst), - .sfp_4_txd(sfp_4_txd), - .sfp_4_txc(sfp_4_txc), - .sfp_4_rx_clk(sfp_4_rx_clk), - .sfp_4_rx_rst(sfp_4_rx_rst), - .sfp_4_rxd(sfp_4_rxd), - .sfp_4_rxc(sfp_4_rxc), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t) -); - -endmodule diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/udp_ep.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/NetFPGA_SUME/fpga/tb/xgmii_ep.py b/fpga/mqnic/NetFPGA_SUME/fpga/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/NetFPGA_SUME/fpga/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/axis_ep.py b/fpga/mqnic/VCU108/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/eth_ep.py b/fpga/mqnic/VCU108/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..e118ed2ab --- /dev/null +++ b/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= 60 +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= 75 +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= 85 +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= 33 +export PARAM_RQ_SEQ_NUM_WIDTH ?= 4 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..40fef6c25 --- /dev/null +++ b/fpga/mqnic/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,581 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num=dut.s_axis_rq_seq_num, + pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_source = XgmiiSource(dut.qsfp_rxd_1, dut.qsfp_rxc_1, dut.qsfp_rx_clk_1, dut.qsfp_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_sink = XgmiiSink(dut.qsfp_txd_1, dut.qsfp_txc_1, dut.qsfp_tx_clk_1, dut.qsfp_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_2_source = XgmiiSource(dut.qsfp_rxd_2, dut.qsfp_rxc_2, dut.qsfp_rx_clk_2, dut.qsfp_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_2_sink = XgmiiSink(dut.qsfp_txd_2, dut.qsfp_txc_2, dut.qsfp_tx_clk_2, dut.qsfp_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_3_source = XgmiiSource(dut.qsfp_rxd_3, dut.qsfp_rxc_3, dut.qsfp_rx_clk_3, dut.qsfp_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_3_sink = XgmiiSink(dut.qsfp_txd_3, dut.qsfp_txc_3, dut.qsfp_tx_clk_3, dut.qsfp_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_rx_clk_4, 6.4, units="ns").start()) + self.qsfp_4_source = XgmiiSource(dut.qsfp_rxd_4, dut.qsfp_rxc_4, dut.qsfp_rx_clk_4, dut.qsfp_rx_rst_4) + cocotb.fork(Clock(dut.qsfp_tx_clk_4, 6.4, units="ns").start()) + self.qsfp_4_sink = XgmiiSink(dut.qsfp_txd_4, dut.qsfp_txc_4, dut.qsfp_tx_clk_4, dut.qsfp_tx_rst_4) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + dut.qsfp_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_rx_error_count_3.setimmediatevalue(0) + dut.qsfp_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp_modprsl.setimmediatevalue(0) + dut.qsfp_intl.setimmediatevalue(0) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.flash_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_1_sink.empty(): + self.qsfp_1_source.send(self.qsfp_1_sink.recv()) + if not self.qsfp_2_sink.empty(): + self.qsfp_2_source.send(self.qsfp_2_sink.recv()) + if not self.qsfp_3_sink.empty(): + self.qsfp_3_source.send(self.qsfp_3_sink.recv()) + if not self.qsfp_4_sink.empty(): + self.qsfp_4_source.send(self.qsfp_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_1_sink.wait() + + pkt = tb.qsfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_1_sink.wait() + + pkt = tb.qsfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/ip_ep.py b/fpga/mqnic/VCU108/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/mqnic.py b/fpga/mqnic/VCU108/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/pcie.py b/fpga/mqnic/VCU108/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/pcie_us.py b/fpga/mqnic/VCU108/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/VCU108/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 85f65ed49..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,880 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_us -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 60 - AXIS_PCIE_CQ_USER_WIDTH = 85 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 4 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(0)[2:]) - pcie_tfc_npd_av = Signal(intbv(0)[2:]) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_tx_clk_1 = Signal(bool(0)) - qsfp_tx_rst_1 = Signal(bool(0)) - qsfp_rx_clk_1 = Signal(bool(0)) - qsfp_rx_rst_1 = Signal(bool(0)) - qsfp_rxd_1 = Signal(intbv(0)[64:]) - qsfp_rxc_1 = Signal(intbv(0)[8:]) - qsfp_tx_clk_2 = Signal(bool(0)) - qsfp_tx_rst_2 = Signal(bool(0)) - qsfp_rx_clk_2 = Signal(bool(0)) - qsfp_rx_rst_2 = Signal(bool(0)) - qsfp_rxd_2 = Signal(intbv(0)[64:]) - qsfp_rxc_2 = Signal(intbv(0)[8:]) - qsfp_tx_clk_3 = Signal(bool(0)) - qsfp_tx_rst_3 = Signal(bool(0)) - qsfp_rx_clk_3 = Signal(bool(0)) - qsfp_rx_rst_3 = Signal(bool(0)) - qsfp_rxd_3 = Signal(intbv(0)[64:]) - qsfp_rxc_3 = Signal(intbv(0)[8:]) - qsfp_tx_clk_4 = Signal(bool(0)) - qsfp_tx_rst_4 = Signal(bool(0)) - qsfp_rx_clk_4 = Signal(bool(0)) - qsfp_rx_rst_4 = Signal(bool(0)) - qsfp_rxd_4 = Signal(intbv(0)[64:]) - qsfp_rxc_4 = Signal(intbv(0)[8:]) - qsfp_modprsl = Signal(bool(1)) - qsfp_intl = Signal(bool(1)) - flash_dq_i = Signal(intbv(0)[16:]) - - # Outputs - led = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - qsfp_txd_1 = Signal(intbv(0)[64:]) - qsfp_txc_1 = Signal(intbv(0)[8:]) - qsfp_txd_2 = Signal(intbv(0)[64:]) - qsfp_txc_2 = Signal(intbv(0)[8:]) - qsfp_txd_3 = Signal(intbv(0)[64:]) - qsfp_txc_3 = Signal(intbv(0)[8:]) - qsfp_txd_4 = Signal(intbv(0)[64:]) - qsfp_txc_4 = Signal(intbv(0)[8:]) - qsfp_modsell = Signal(bool(0)) - qsfp_resetl = Signal(bool(1)) - qsfp_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - flash_dq_o = Signal(intbv(0)[16:]) - flash_dq_oe = Signal(bool(0)) - flash_addr = Signal(intbv(0)[24:]) - flash_region = Signal(intbv(0)[2:]) - flash_region_oe = Signal(bool(0)) - flash_ce_n = Signal(bool(1)) - flash_oe_n = Signal(bool(1)) - flash_we_n = Signal(bool(1)) - flash_adv_n = Signal(bool(1)) - - # sources and sinks - qsfp_1_source = xgmii_ep.XGMIISource() - qsfp_1_source_logic = qsfp_1_source.create_logic(qsfp_rx_clk_1, qsfp_rx_rst_1, txd=qsfp_rxd_1, txc=qsfp_rxc_1, name='qsfp_1_source') - - qsfp_1_sink = xgmii_ep.XGMIISink() - qsfp_1_sink_logic = qsfp_1_sink.create_logic(qsfp_tx_clk_1, qsfp_tx_rst_1, rxd=qsfp_txd_1, rxc=qsfp_txc_1, name='qsfp_1_sink') - - qsfp_2_source = xgmii_ep.XGMIISource() - qsfp_2_source_logic = qsfp_2_source.create_logic(qsfp_rx_clk_2, qsfp_rx_rst_2, txd=qsfp_rxd_2, txc=qsfp_rxc_2, name='qsfp_2_source') - - qsfp_2_sink = xgmii_ep.XGMIISink() - qsfp_2_sink_logic = qsfp_2_sink.create_logic(qsfp_tx_clk_2, qsfp_tx_rst_2, rxd=qsfp_txd_2, rxc=qsfp_txc_2, name='qsfp_2_sink') - - qsfp_3_source = xgmii_ep.XGMIISource() - qsfp_3_source_logic = qsfp_3_source.create_logic(qsfp_rx_clk_3, qsfp_rx_rst_3, txd=qsfp_rxd_3, txc=qsfp_rxc_3, name='qsfp_3_source') - - qsfp_3_sink = xgmii_ep.XGMIISink() - qsfp_3_sink_logic = qsfp_3_sink.create_logic(qsfp_tx_clk_3, qsfp_tx_rst_3, rxd=qsfp_txd_3, rxc=qsfp_txc_3, name='qsfp_3_sink') - - qsfp_4_source = xgmii_ep.XGMIISource() - qsfp_4_source_logic = qsfp_4_source.create_logic(qsfp_rx_clk_4, qsfp_rx_rst_4, txd=qsfp_rxd_4, txc=qsfp_rxc_4, name='qsfp_4_source') - - qsfp_4_sink = xgmii_ep.XGMIISink() - qsfp_4_sink_logic = qsfp_4_sink.create_logic(qsfp_tx_clk_4, qsfp_tx_rst_4, rxd=qsfp_txd_4, rxc=qsfp_txc_4, name='qsfp_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num=s_axis_rq_seq_num, - pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num=s_axis_rq_seq_num, - s_axis_rq_seq_num_valid=s_axis_rq_seq_num_valid, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_tx_clk_1=qsfp_tx_clk_1, - qsfp_tx_rst_1=qsfp_tx_rst_1, - qsfp_txd_1=qsfp_txd_1, - qsfp_txc_1=qsfp_txc_1, - qsfp_rx_clk_1=qsfp_rx_clk_1, - qsfp_rx_rst_1=qsfp_rx_rst_1, - qsfp_rxd_1=qsfp_rxd_1, - qsfp_rxc_1=qsfp_rxc_1, - qsfp_tx_clk_2=qsfp_tx_clk_2, - qsfp_tx_rst_2=qsfp_tx_rst_2, - qsfp_txd_2=qsfp_txd_2, - qsfp_txc_2=qsfp_txc_2, - qsfp_rx_clk_2=qsfp_rx_clk_2, - qsfp_rx_rst_2=qsfp_rx_rst_2, - qsfp_rxd_2=qsfp_rxd_2, - qsfp_rxc_2=qsfp_rxc_2, - qsfp_tx_clk_3=qsfp_tx_clk_3, - qsfp_tx_rst_3=qsfp_tx_rst_3, - qsfp_txd_3=qsfp_txd_3, - qsfp_txc_3=qsfp_txc_3, - qsfp_rx_clk_3=qsfp_rx_clk_3, - qsfp_rx_rst_3=qsfp_rx_rst_3, - qsfp_rxd_3=qsfp_rxd_3, - qsfp_rxc_3=qsfp_rxc_3, - qsfp_tx_clk_4=qsfp_tx_clk_4, - qsfp_tx_rst_4=qsfp_tx_rst_4, - qsfp_txd_4=qsfp_txd_4, - qsfp_txc_4=qsfp_txc_4, - qsfp_rx_clk_4=qsfp_rx_clk_4, - qsfp_rx_rst_4=qsfp_rx_rst_4, - qsfp_rxd_4=qsfp_rxd_4, - qsfp_rxc_4=qsfp_rxc_4, - qsfp_modsell=qsfp_modsell, - qsfp_resetl=qsfp_resetl, - qsfp_modprsl=qsfp_modprsl, - qsfp_intl=qsfp_intl, - qsfp_lpmode=qsfp_lpmode, - fpga_boot=fpga_boot, - flash_dq_i=flash_dq_i, - flash_dq_o=flash_dq_o, - flash_dq_oe=flash_dq_oe, - flash_addr=flash_addr, - flash_region=flash_region, - flash_region_oe=flash_region_oe, - flash_ce_n=flash_ce_n, - flash_oe_n=flash_oe_n, - flash_we_n=flash_we_n, - flash_adv_n=flash_adv_n - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def clkgen2(): - qsfp_tx_clk_1.next = not qsfp_tx_clk_1 - qsfp_rx_clk_1.next = not qsfp_rx_clk_1 - qsfp_tx_clk_2.next = not qsfp_tx_clk_2 - qsfp_rx_clk_2.next = not qsfp_rx_clk_2 - qsfp_tx_clk_3.next = not qsfp_tx_clk_3 - qsfp_rx_clk_3.next = not qsfp_rx_clk_3 - qsfp_tx_clk_4.next = not qsfp_tx_clk_4 - qsfp_rx_clk_4.next = not qsfp_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_1_sink.empty(): - pkt = qsfp_1_sink.recv() - qsfp_1_source.send(pkt) - if not qsfp_2_sink.empty(): - pkt = qsfp_2_sink.recv() - qsfp_2_source.send(pkt) - if not qsfp_3_sink.empty(): - pkt = qsfp_3_sink.recv() - qsfp_3_source.send(pkt) - if not qsfp_4_sink.empty(): - pkt = qsfp_4_sink.recv() - qsfp_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_tx_rst_1.next = 1 - qsfp_rx_rst_1.next = 1 - qsfp_tx_rst_2.next = 1 - qsfp_rx_rst_2.next = 1 - qsfp_tx_rst_3.next = 1 - qsfp_rx_rst_3.next = 1 - qsfp_tx_rst_4.next = 1 - qsfp_rx_rst_4.next = 1 - yield clk.posedge - rst.next = 0 - qsfp_tx_rst_1.next = 0 - qsfp_rx_rst_1.next = 0 - qsfp_tx_rst_2.next = 0 - qsfp_rx_rst_2.next = 0 - qsfp_tx_rst_3.next = 0 - qsfp_rx_rst_3.next = 0 - qsfp_tx_rst_4.next = 0 - qsfp_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_1_sink.wait() - - pkt = qsfp_1_sink.recv() - print(pkt) - - qsfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_1_sink.wait() - - pkt = qsfp_1_sink.recv() - print(pkt) - - qsfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/VCU108/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 2fdb7dd59..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,465 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 256; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 60; -parameter AXIS_PCIE_CQ_USER_WIDTH = 85; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 4; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg btnu = 0; -reg btnl = 0; -reg btnd = 0; -reg btnr = 0; -reg btnc = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num = 0; -reg s_axis_rq_seq_num_valid = 0; -reg [1:0] pcie_tfc_nph_av = 0; -reg [1:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [7:0] cfg_interrupt_msi_vf_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_tx_clk_1 = 0; -reg qsfp_tx_rst_1 = 0; -reg qsfp_rx_clk_1 = 0; -reg qsfp_rx_rst_1 = 0; -reg [63:0] qsfp_rxd_1 = 0; -reg [7:0] qsfp_rxc_1 = 0; -reg qsfp_tx_clk_2 = 0; -reg qsfp_tx_rst_2 = 0; -reg qsfp_rx_clk_2 = 0; -reg qsfp_rx_rst_2 = 0; -reg [63:0] qsfp_rxd_2 = 0; -reg [7:0] qsfp_rxc_2 = 0; -reg qsfp_tx_clk_3 = 0; -reg qsfp_tx_rst_3 = 0; -reg qsfp_rx_clk_3 = 0; -reg qsfp_rx_rst_3 = 0; -reg [63:0] qsfp_rxd_3 = 0; -reg [7:0] qsfp_rxc_3 = 0; -reg qsfp_tx_clk_4 = 0; -reg qsfp_tx_rst_4 = 0; -reg qsfp_rx_clk_4 = 0; -reg qsfp_rx_rst_4 = 0; -reg [63:0] qsfp_rxd_4 = 0; -reg [7:0] qsfp_rxc_4 = 0; -reg qsfp_modprsl = 1; -reg qsfp_intl = 1; -reg [15:0] flash_dq_i = 0; - -// Outputs -wire [7:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [18:0] cfg_mgmt_addr; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_txd_1; -wire [7:0] qsfp_txc_1; -wire [63:0] qsfp_txd_2; -wire [7:0] qsfp_txc_2; -wire [63:0] qsfp_txd_3; -wire [7:0] qsfp_txc_3; -wire [63:0] qsfp_txd_4; -wire [7:0] qsfp_txc_4; -wire qsfp_modsell; -wire qsfp_resetl; -wire qsfp_lpmode; -wire fpga_boot; -wire [15:0] flash_dq_o; -wire flash_dq_oe; -wire [23:0] flash_addr; -wire [1:0] flash_region; -wire flash_region_oe; -wire flash_ce_n; -wire flash_oe_n; -wire flash_we_n; -wire flash_adv_n; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num, - s_axis_rq_seq_num_valid, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_tx_clk_1, - qsfp_tx_rst_1, - qsfp_rx_clk_1, - qsfp_rx_rst_1, - qsfp_rxd_1, - qsfp_rxc_1, - qsfp_tx_clk_2, - qsfp_tx_rst_2, - qsfp_rx_clk_2, - qsfp_rx_rst_2, - qsfp_rxd_2, - qsfp_rxc_2, - qsfp_tx_clk_3, - qsfp_tx_rst_3, - qsfp_rx_clk_3, - qsfp_rx_rst_3, - qsfp_rxd_3, - qsfp_rxc_3, - qsfp_tx_clk_4, - qsfp_tx_rst_4, - qsfp_rx_clk_4, - qsfp_rx_rst_4, - qsfp_rxd_4, - qsfp_rxc_4, - qsfp_modprsl, - qsfp_intl, - flash_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_txd_1, - qsfp_txc_1, - qsfp_txd_2, - qsfp_txc_2, - qsfp_txd_3, - qsfp_txc_3, - qsfp_txd_4, - qsfp_txc_4, - qsfp_modsell, - qsfp_resetl, - qsfp_lpmode, - fpga_boot, - flash_dq_o, - flash_dq_oe, - flash_addr, - flash_region, - flash_region_oe, - flash_ce_n, - flash_oe_n, - flash_we_n, - flash_adv_n - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btnu(btnu), - .btnl(btnl), - .btnd(btnd), - .btnr(btnr), - .btnc(btnc), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num(s_axis_rq_seq_num), - .s_axis_rq_seq_num_valid(s_axis_rq_seq_num_valid), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_tx_clk_1(qsfp_tx_clk_1), - .qsfp_tx_rst_1(qsfp_tx_rst_1), - .qsfp_txd_1(qsfp_txd_1), - .qsfp_txc_1(qsfp_txc_1), - .qsfp_rx_clk_1(qsfp_rx_clk_1), - .qsfp_rx_rst_1(qsfp_rx_rst_1), - .qsfp_rxd_1(qsfp_rxd_1), - .qsfp_rxc_1(qsfp_rxc_1), - .qsfp_tx_clk_2(qsfp_tx_clk_2), - .qsfp_tx_rst_2(qsfp_tx_rst_2), - .qsfp_txd_2(qsfp_txd_2), - .qsfp_txc_2(qsfp_txc_2), - .qsfp_rx_clk_2(qsfp_rx_clk_2), - .qsfp_rx_rst_2(qsfp_rx_rst_2), - .qsfp_rxd_2(qsfp_rxd_2), - .qsfp_rxc_2(qsfp_rxc_2), - .qsfp_tx_clk_3(qsfp_tx_clk_3), - .qsfp_tx_rst_3(qsfp_tx_rst_3), - .qsfp_txd_3(qsfp_txd_3), - .qsfp_txc_3(qsfp_txc_3), - .qsfp_rx_clk_3(qsfp_rx_clk_3), - .qsfp_rx_rst_3(qsfp_rx_rst_3), - .qsfp_rxd_3(qsfp_rxd_3), - .qsfp_rxc_3(qsfp_rxc_3), - .qsfp_tx_clk_4(qsfp_tx_clk_4), - .qsfp_tx_rst_4(qsfp_tx_rst_4), - .qsfp_txd_4(qsfp_txd_4), - .qsfp_txc_4(qsfp_txc_4), - .qsfp_rx_clk_4(qsfp_rx_clk_4), - .qsfp_rx_rst_4(qsfp_rx_rst_4), - .qsfp_rxd_4(qsfp_rxd_4), - .qsfp_rxc_4(qsfp_rxc_4), - .qsfp_modprsl(qsfp_modprsl), - .qsfp_modsell(qsfp_modsell), - .qsfp_resetl(qsfp_resetl), - .qsfp_intl(qsfp_intl), - .qsfp_lpmode(qsfp_lpmode), - .fpga_boot(fpga_boot), - .flash_dq_i(flash_dq_i), - .flash_dq_o(flash_dq_o), - .flash_dq_oe(flash_dq_oe), - .flash_addr(flash_addr), - .flash_region(flash_region), - .flash_region_oe(flash_region_oe), - .flash_ce_n(flash_ce_n), - .flash_oe_n(flash_oe_n), - .flash_we_n(flash_we_n), - .flash_adv_n(flash_adv_n) -); - -endmodule diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/udp_ep.py b/fpga/mqnic/VCU108/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU108/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/VCU108/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/VCU108/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/axis_ep.py b/fpga/mqnic/VCU118/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/eth_ep.py b/fpga/mqnic/VCU118/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..1b6b1b200 --- /dev/null +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..e5caa4092 --- /dev/null +++ b/fpga/mqnic/VCU118/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,591 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp1_rx_clk, 3.102, units="ns").start()) + self.qsfp1_source = AxiStreamSource(dut, "qsfp1_rx_axis", dut.qsfp1_rx_clk, dut.qsfp1_rx_rst) + cocotb.fork(Clock(dut.qsfp1_tx_clk, 3.102, units="ns").start()) + self.qsfp1_sink = AxiStreamSink(dut, "qsfp1_tx_axis", dut.qsfp1_tx_clk, dut.qsfp1_tx_rst) + + cocotb.fork(Clock(dut.qsfp2_rx_clk, 3.102, units="ns").start()) + self.qsfp2_source = AxiStreamSource(dut, "qsfp2_rx_axis", dut.qsfp2_rx_clk, dut.qsfp2_rx_rst) + cocotb.fork(Clock(dut.qsfp2_tx_clk, 3.102, units="ns").start()) + self.qsfp2_sink = AxiStreamSink(dut, "qsfp2_tx_axis", dut.qsfp2_tx_clk, dut.qsfp2_tx_rst) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qsfp2_modprsl.setimmediatevalue(0) + dut.qsfp2_intl.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + self.dut.qsfp2_rx_rst.setimmediatevalue(0) + self.dut.qsfp2_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp1_rx_rst.setimmediatevalue(1) + self.dut.qsfp1_tx_rst.setimmediatevalue(1) + self.dut.qsfp2_rx_rst.setimmediatevalue(1) + self.dut.qsfp2_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + self.dut.qsfp2_rx_rst.setimmediatevalue(0) + self.dut.qsfp2_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp1_sink.empty(): + self.qsfp1_source.send(self.qsfp1_sink.recv()) + if not self.qsfp2_sink.empty(): + self.qsfp2_source.send(self.qsfp2_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp1_sink.wait() + + pkt = tb.qsfp1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp2_0_sink.wait() + + # pkt = tb.qsfp2_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp2_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp1_sink.wait() + + pkt = tb.qsfp1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/ip_ep.py b/fpga/mqnic/VCU118/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/mqnic.py b/fpga/mqnic/VCU118/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/pcie.py b/fpga/mqnic/VCU118/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/pcie_us.py b/fpga/mqnic/VCU118/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/VCU118/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index 315fb85dc..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,960 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp1_tx_clk = Signal(bool(0)) - qsfp1_tx_rst = Signal(bool(0)) - qsfp1_rx_clk = Signal(bool(0)) - qsfp1_rx_rst = Signal(bool(0)) - qsfp1_tx_axis_tready = Signal(bool(0)) - qsfp1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_rx_axis_tvalid = Signal(bool(0)) - qsfp1_rx_axis_tlast = Signal(bool(0)) - qsfp1_rx_axis_tuser = Signal(bool(0)) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qsfp2_tx_clk = Signal(bool(0)) - qsfp2_tx_rst = Signal(bool(0)) - qsfp2_rx_clk = Signal(bool(0)) - qsfp2_rx_rst = Signal(bool(0)) - qsfp2_tx_axis_tready = Signal(bool(0)) - qsfp2_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp2_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp2_rx_axis_tvalid = Signal(bool(0)) - qsfp2_rx_axis_tlast = Signal(bool(0)) - qsfp2_rx_axis_tuser = Signal(bool(0)) - qsfp2_modprsl = Signal(bool(1)) - qsfp2_intl = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_tx_axis_tvalid = Signal(bool(0)) - qsfp1_tx_axis_tlast = Signal(bool(0)) - qsfp1_tx_axis_tuser = Signal(bool(0)) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - qsfp2_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp2_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp2_tx_axis_tvalid = Signal(bool(0)) - qsfp2_tx_axis_tlast = Signal(bool(0)) - qsfp2_tx_axis_tuser = Signal(bool(0)) - qsfp2_modsell = Signal(bool(0)) - qsfp2_resetl = Signal(bool(0)) - qsfp2_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp1_source = axis_ep.AXIStreamSource() - qsfp1_source_pause = Signal(bool(False)) - - qsfp1_source_logic = qsfp1_source.create_logic( - qsfp1_rx_clk, - qsfp1_rx_rst, - tdata=qsfp1_rx_axis_tdata, - tkeep=qsfp1_rx_axis_tkeep, - tvalid=qsfp1_rx_axis_tvalid, - tlast=qsfp1_rx_axis_tlast, - tuser=qsfp1_rx_axis_tuser, - pause=qsfp1_source_pause, - name='qsfp1_source' - ) - - qsfp1_sink = axis_ep.AXIStreamSink() - qsfp1_sink_pause = Signal(bool(False)) - - qsfp1_sink_logic = qsfp1_sink.create_logic( - qsfp1_tx_clk, - qsfp1_tx_rst, - tdata=qsfp1_tx_axis_tdata, - tkeep=qsfp1_tx_axis_tkeep, - tvalid=qsfp1_tx_axis_tvalid, - tready=qsfp1_tx_axis_tready, - tlast=qsfp1_tx_axis_tlast, - tuser=qsfp1_tx_axis_tuser, - pause=qsfp1_sink_pause, - name='qsfp1_sink' - ) - - qsfp2_source = axis_ep.AXIStreamSource() - qsfp2_source_pause = Signal(bool(False)) - - qsfp2_source_logic = qsfp2_source.create_logic( - qsfp2_rx_clk, - qsfp2_rx_rst, - tdata=qsfp2_rx_axis_tdata, - tkeep=qsfp2_rx_axis_tkeep, - tvalid=qsfp2_rx_axis_tvalid, - tlast=qsfp2_rx_axis_tlast, - tuser=qsfp2_rx_axis_tuser, - pause=qsfp2_source_pause, - name='qsfp2_source' - ) - - qsfp2_sink = axis_ep.AXIStreamSink() - qsfp2_sink_pause = Signal(bool(False)) - - qsfp2_sink_logic = qsfp2_sink.create_logic( - qsfp2_tx_clk, - qsfp2_tx_rst, - tdata=qsfp2_tx_axis_tdata, - tkeep=qsfp2_tx_axis_tkeep, - tvalid=qsfp2_tx_axis_tvalid, - tready=qsfp2_tx_axis_tready, - tlast=qsfp2_tx_axis_tlast, - tuser=qsfp2_tx_axis_tuser, - pause=qsfp2_sink_pause, - name='qsfp2_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp1_tx_clk=qsfp1_tx_clk, - qsfp1_tx_rst=qsfp1_tx_rst, - qsfp1_tx_axis_tdata=qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep=qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid=qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tready=qsfp1_tx_axis_tready, - qsfp1_tx_axis_tlast=qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser=qsfp1_tx_axis_tuser, - qsfp1_rx_clk=qsfp1_rx_clk, - qsfp1_rx_rst=qsfp1_rx_rst, - qsfp1_rx_axis_tdata=qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep=qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid=qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast=qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser=qsfp1_rx_axis_tuser, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - qsfp2_tx_clk=qsfp2_tx_clk, - qsfp2_tx_rst=qsfp2_tx_rst, - qsfp2_tx_axis_tdata=qsfp2_tx_axis_tdata, - qsfp2_tx_axis_tkeep=qsfp2_tx_axis_tkeep, - qsfp2_tx_axis_tvalid=qsfp2_tx_axis_tvalid, - qsfp2_tx_axis_tready=qsfp2_tx_axis_tready, - qsfp2_tx_axis_tlast=qsfp2_tx_axis_tlast, - qsfp2_tx_axis_tuser=qsfp2_tx_axis_tuser, - qsfp2_rx_clk=qsfp2_rx_clk, - qsfp2_rx_rst=qsfp2_rx_rst, - qsfp2_rx_axis_tdata=qsfp2_rx_axis_tdata, - qsfp2_rx_axis_tkeep=qsfp2_rx_axis_tkeep, - qsfp2_rx_axis_tvalid=qsfp2_rx_axis_tvalid, - qsfp2_rx_axis_tlast=qsfp2_rx_axis_tlast, - qsfp2_rx_axis_tuser=qsfp2_rx_axis_tuser, - qsfp2_modprsl=qsfp2_modprsl, - qsfp2_modsell=qsfp2_modsell, - qsfp2_resetl=qsfp2_resetl, - qsfp2_intl=qsfp2_intl, - qsfp2_lpmode=qsfp2_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp1_tx_clk.next = not qsfp1_tx_clk - qsfp1_rx_clk.next = not qsfp1_rx_clk - qsfp2_tx_clk.next = not qsfp2_tx_clk - qsfp2_rx_clk.next = not qsfp2_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp1_sink.empty(): - pkt = qsfp1_sink.recv() - qsfp1_source.send(pkt) - if not qsfp2_sink.empty(): - pkt = qsfp2_sink.recv() - qsfp2_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp1_tx_rst.next = 1 - qsfp1_rx_rst.next = 1 - qsfp2_tx_rst.next = 1 - qsfp2_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp1_tx_rst.next = 0 - qsfp1_rx_rst.next = 0 - qsfp2_tx_rst.next = 0 - qsfp2_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate() - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp1_sink.wait() - - pkt = qsfp1_sink.recv() - print(pkt) - - qsfp1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp1_sink.wait() - - # pkt = qsfp1_sink.recv() - # print(pkt) - - # qsfp1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp1_sink.wait() - - pkt = qsfp1_sink.recv() - print(pkt) - - qsfp1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/VCU118/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index e1e4c0790..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,481 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg btnu = 0; -reg btnl = 0; -reg btnd = 0; -reg btnr = 0; -reg btnc = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp1_tx_clk = 0; -reg qsfp1_tx_rst = 0; -reg qsfp1_tx_axis_tready = 0; -reg qsfp1_rx_clk = 0; -reg qsfp1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep = 0; -reg qsfp1_rx_axis_tvalid = 0; -reg qsfp1_rx_axis_tlast = 0; -reg qsfp1_rx_axis_tuser = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg qsfp2_tx_clk = 0; -reg qsfp2_tx_rst = 0; -reg qsfp2_tx_axis_tready = 0; -reg qsfp2_rx_clk = 0; -reg qsfp2_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_rx_axis_tkeep = 0; -reg qsfp2_rx_axis_tvalid = 0; -reg qsfp2_rx_axis_tlast = 0; -reg qsfp2_rx_axis_tuser = 0; -reg qsfp2_modprsl = 1; -reg qsfp2_intl = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [7:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep; -wire qsfp1_tx_axis_tvalid; -wire qsfp1_tx_axis_tlast; -wire qsfp1_tx_axis_tuser; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp2_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp2_tx_axis_tkeep; -wire qsfp2_tx_axis_tvalid; -wire qsfp2_tx_axis_tlast; -wire qsfp2_tx_axis_tuser; -wire qsfp2_modsell; -wire qsfp2_resetl; -wire qsfp2_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp1_tx_clk, - qsfp1_tx_rst, - qsfp1_tx_axis_tready, - qsfp1_rx_clk, - qsfp1_rx_rst, - qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser, - qsfp1_modprsl, - qsfp1_intl, - qsfp2_tx_clk, - qsfp2_tx_rst, - qsfp2_tx_axis_tready, - qsfp2_rx_clk, - qsfp2_rx_rst, - qsfp2_rx_axis_tdata, - qsfp2_rx_axis_tkeep, - qsfp2_rx_axis_tvalid, - qsfp2_rx_axis_tlast, - qsfp2_rx_axis_tuser, - qsfp2_modprsl, - qsfp2_intl, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - qsfp2_tx_axis_tdata, - qsfp2_tx_axis_tkeep, - qsfp2_tx_axis_tvalid, - qsfp2_tx_axis_tlast, - qsfp2_tx_axis_tuser, - qsfp2_modsell, - qsfp2_resetl, - qsfp2_lpmode, - fpga_boot, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btnu(btnu), - .btnl(btnl), - .btnd(btnd), - .btnr(btnr), - .btnc(btnc), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp1_tx_clk(qsfp1_tx_clk), - .qsfp1_tx_rst(qsfp1_tx_rst), - .qsfp1_tx_axis_tdata(qsfp1_tx_axis_tdata), - .qsfp1_tx_axis_tkeep(qsfp1_tx_axis_tkeep), - .qsfp1_tx_axis_tvalid(qsfp1_tx_axis_tvalid), - .qsfp1_tx_axis_tready(qsfp1_tx_axis_tready), - .qsfp1_tx_axis_tlast(qsfp1_tx_axis_tlast), - .qsfp1_tx_axis_tuser(qsfp1_tx_axis_tuser), - .qsfp1_rx_clk(qsfp1_rx_clk), - .qsfp1_rx_rst(qsfp1_rx_rst), - .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata), - .qsfp1_rx_axis_tkeep(qsfp1_rx_axis_tkeep), - .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid), - .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast), - .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .qsfp2_tx_clk(qsfp2_tx_clk), - .qsfp2_tx_rst(qsfp2_tx_rst), - .qsfp2_tx_axis_tdata(qsfp2_tx_axis_tdata), - .qsfp2_tx_axis_tkeep(qsfp2_tx_axis_tkeep), - .qsfp2_tx_axis_tvalid(qsfp2_tx_axis_tvalid), - .qsfp2_tx_axis_tready(qsfp2_tx_axis_tready), - .qsfp2_tx_axis_tlast(qsfp2_tx_axis_tlast), - .qsfp2_tx_axis_tuser(qsfp2_tx_axis_tuser), - .qsfp2_rx_clk(qsfp2_rx_clk), - .qsfp2_rx_rst(qsfp2_rx_rst), - .qsfp2_rx_axis_tdata(qsfp2_rx_axis_tdata), - .qsfp2_rx_axis_tkeep(qsfp2_rx_axis_tkeep), - .qsfp2_rx_axis_tvalid(qsfp2_rx_axis_tvalid), - .qsfp2_rx_axis_tlast(qsfp2_rx_axis_tlast), - .qsfp2_rx_axis_tuser(qsfp2_rx_axis_tuser), - .qsfp2_modprsl(qsfp2_modprsl_int), - .qsfp2_modsell(qsfp2_modsell), - .qsfp2_resetl(qsfp2_resetl), - .qsfp2_intl(qsfp2_intl_int), - .qsfp2_lpmode(qsfp2_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/udp_ep.py b/fpga/mqnic/VCU118/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_100g/tb/xgmii_ep.py b/fpga/mqnic/VCU118/fpga_100g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/VCU118/fpga_100g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/axis_ep.py b/fpga/mqnic/VCU118/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/eth_ep.py b/fpga/mqnic/VCU118/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..3e727c52b --- /dev/null +++ b/fpga/mqnic/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,661 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_1, 6.4, units="ns").start()) + self.qsfp2_1_source = XgmiiSource(dut.qsfp2_rxd_1, dut.qsfp2_rxc_1, dut.qsfp2_rx_clk_1, dut.qsfp2_rx_rst_1) + cocotb.fork(Clock(dut.qsfp2_tx_clk_1, 6.4, units="ns").start()) + self.qsfp2_1_sink = XgmiiSink(dut.qsfp2_txd_1, dut.qsfp2_txc_1, dut.qsfp2_tx_clk_1, dut.qsfp2_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_2, 6.4, units="ns").start()) + self.qsfp2_2_source = XgmiiSource(dut.qsfp2_rxd_2, dut.qsfp2_rxc_2, dut.qsfp2_rx_clk_2, dut.qsfp2_rx_rst_2) + cocotb.fork(Clock(dut.qsfp2_tx_clk_2, 6.4, units="ns").start()) + self.qsfp2_2_sink = XgmiiSink(dut.qsfp2_txd_2, dut.qsfp2_txc_2, dut.qsfp2_tx_clk_2, dut.qsfp2_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_3, 6.4, units="ns").start()) + self.qsfp2_3_source = XgmiiSource(dut.qsfp2_rxd_3, dut.qsfp2_rxc_3, dut.qsfp2_rx_clk_3, dut.qsfp2_rx_rst_3) + cocotb.fork(Clock(dut.qsfp2_tx_clk_3, 6.4, units="ns").start()) + self.qsfp2_3_sink = XgmiiSink(dut.qsfp2_txd_3, dut.qsfp2_txc_3, dut.qsfp2_tx_clk_3, dut.qsfp2_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_4, 6.4, units="ns").start()) + self.qsfp2_4_source = XgmiiSource(dut.qsfp2_rxd_4, dut.qsfp2_rxc_4, dut.qsfp2_rx_clk_4, dut.qsfp2_rx_rst_4) + cocotb.fork(Clock(dut.qsfp2_tx_clk_4, 6.4, units="ns").start()) + self.qsfp2_4_sink = XgmiiSink(dut.qsfp2_txd_4, dut.qsfp2_txc_4, dut.qsfp2_tx_clk_4, dut.qsfp2_tx_rst_4) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp2_rx_error_count_1.setimmediatevalue(0) + dut.qsfp2_rx_error_count_2.setimmediatevalue(0) + dut.qsfp2_rx_error_count_3.setimmediatevalue(0) + dut.qsfp2_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qsfp2_modprsl.setimmediatevalue(0) + dut.qsfp2_intl.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp1_1_sink.empty(): + self.qsfp1_1_source.send(self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + self.qsfp1_2_source.send(self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + self.qsfp1_3_source.send(self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + self.qsfp1_4_source.send(self.qsfp1_4_sink.recv()) + if not self.qsfp2_1_sink.empty(): + self.qsfp2_1_source.send(self.qsfp2_1_sink.recv()) + if not self.qsfp2_2_sink.empty(): + self.qsfp2_2_source.send(self.qsfp2_2_sink.recv()) + if not self.qsfp2_3_sink.empty(): + self.qsfp2_3_source.send(self.qsfp2_3_sink.recv()) + if not self.qsfp2_4_sink.empty(): + self.qsfp2_4_source.send(self.qsfp2_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp1_1_sink.wait() + + pkt = tb.qsfp1_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp1_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp2_1_sink.wait() + + # pkt = tb.qsfp2_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp2_1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp1_1_sink.wait() + + pkt = tb.qsfp1_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp1_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/ip_ep.py b/fpga/mqnic/VCU118/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/mqnic.py b/fpga/mqnic/VCU118/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/pcie.py b/fpga/mqnic/VCU118/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/pcie_us.py b/fpga/mqnic/VCU118/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/VCU118/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/VCU118/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 5dfd0466e..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1047 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp1_tx_clk_1 = Signal(bool(0)) - qsfp1_tx_rst_1 = Signal(bool(0)) - qsfp1_rx_clk_1 = Signal(bool(0)) - qsfp1_rx_rst_1 = Signal(bool(0)) - qsfp1_rxd_1 = Signal(intbv(0)[64:]) - qsfp1_rxc_1 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_2 = Signal(bool(0)) - qsfp1_tx_rst_2 = Signal(bool(0)) - qsfp1_rx_clk_2 = Signal(bool(0)) - qsfp1_rx_rst_2 = Signal(bool(0)) - qsfp1_rxd_2 = Signal(intbv(0)[64:]) - qsfp1_rxc_2 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_3 = Signal(bool(0)) - qsfp1_tx_rst_3 = Signal(bool(0)) - qsfp1_rx_clk_3 = Signal(bool(0)) - qsfp1_rx_rst_3 = Signal(bool(0)) - qsfp1_rxd_3 = Signal(intbv(0)[64:]) - qsfp1_rxc_3 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_4 = Signal(bool(0)) - qsfp1_tx_rst_4 = Signal(bool(0)) - qsfp1_rx_clk_4 = Signal(bool(0)) - qsfp1_rx_rst_4 = Signal(bool(0)) - qsfp1_rxd_4 = Signal(intbv(0)[64:]) - qsfp1_rxc_4 = Signal(intbv(0)[8:]) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qsfp2_tx_clk_1 = Signal(bool(0)) - qsfp2_tx_rst_1 = Signal(bool(0)) - qsfp2_rx_clk_1 = Signal(bool(0)) - qsfp2_rx_rst_1 = Signal(bool(0)) - qsfp2_rxd_1 = Signal(intbv(0)[64:]) - qsfp2_rxc_1 = Signal(intbv(0)[8:]) - qsfp2_tx_clk_2 = Signal(bool(0)) - qsfp2_tx_rst_2 = Signal(bool(0)) - qsfp2_rx_clk_2 = Signal(bool(0)) - qsfp2_rx_rst_2 = Signal(bool(0)) - qsfp2_rxd_2 = Signal(intbv(0)[64:]) - qsfp2_rxc_2 = Signal(intbv(0)[8:]) - qsfp2_tx_clk_3 = Signal(bool(0)) - qsfp2_tx_rst_3 = Signal(bool(0)) - qsfp2_rx_clk_3 = Signal(bool(0)) - qsfp2_rx_rst_3 = Signal(bool(0)) - qsfp2_rxd_3 = Signal(intbv(0)[64:]) - qsfp2_rxc_3 = Signal(intbv(0)[8:]) - qsfp2_tx_clk_4 = Signal(bool(0)) - qsfp2_tx_rst_4 = Signal(bool(0)) - qsfp2_rx_clk_4 = Signal(bool(0)) - qsfp2_rx_rst_4 = Signal(bool(0)) - qsfp2_rxd_4 = Signal(intbv(0)[64:]) - qsfp2_rxc_4 = Signal(intbv(0)[8:]) - qsfp2_modprsl = Signal(bool(1)) - qsfp2_intl = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp1_txd_1 = Signal(intbv(0)[64:]) - qsfp1_txc_1 = Signal(intbv(0)[8:]) - qsfp1_txd_2 = Signal(intbv(0)[64:]) - qsfp1_txc_2 = Signal(intbv(0)[8:]) - qsfp1_txd_3 = Signal(intbv(0)[64:]) - qsfp1_txc_3 = Signal(intbv(0)[8:]) - qsfp1_txd_4 = Signal(intbv(0)[64:]) - qsfp1_txc_4 = Signal(intbv(0)[8:]) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - qsfp2_txd_1 = Signal(intbv(0)[64:]) - qsfp2_txc_1 = Signal(intbv(0)[8:]) - qsfp2_txd_2 = Signal(intbv(0)[64:]) - qsfp2_txc_2 = Signal(intbv(0)[8:]) - qsfp2_txd_3 = Signal(intbv(0)[64:]) - qsfp2_txc_3 = Signal(intbv(0)[8:]) - qsfp2_txd_4 = Signal(intbv(0)[64:]) - qsfp2_txc_4 = Signal(intbv(0)[8:]) - qsfp2_modsell = Signal(bool(0)) - qsfp2_resetl = Signal(bool(0)) - qsfp2_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') - - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') - - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') - - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') - - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') - - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') - - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') - - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - - qsfp2_1_source = xgmii_ep.XGMIISource() - qsfp2_1_source_logic = qsfp2_1_source.create_logic(qsfp2_rx_clk_1, qsfp2_rx_rst_1, txd=qsfp2_rxd_1, txc=qsfp2_rxc_1, name='qsfp2_1_source') - - qsfp2_1_sink = xgmii_ep.XGMIISink() - qsfp2_1_sink_logic = qsfp2_1_sink.create_logic(qsfp2_tx_clk_1, qsfp2_tx_rst_1, rxd=qsfp2_txd_1, rxc=qsfp2_txc_1, name='qsfp2_1_sink') - - qsfp2_2_source = xgmii_ep.XGMIISource() - qsfp2_2_source_logic = qsfp2_2_source.create_logic(qsfp2_rx_clk_2, qsfp2_rx_rst_2, txd=qsfp2_rxd_2, txc=qsfp2_rxc_2, name='qsfp2_2_source') - - qsfp2_2_sink = xgmii_ep.XGMIISink() - qsfp2_2_sink_logic = qsfp2_2_sink.create_logic(qsfp2_tx_clk_2, qsfp2_tx_rst_2, rxd=qsfp2_txd_2, rxc=qsfp2_txc_2, name='qsfp2_2_sink') - - qsfp2_3_source = xgmii_ep.XGMIISource() - qsfp2_3_source_logic = qsfp2_3_source.create_logic(qsfp2_rx_clk_3, qsfp2_rx_rst_3, txd=qsfp2_rxd_3, txc=qsfp2_rxc_3, name='qsfp2_3_source') - - qsfp2_3_sink = xgmii_ep.XGMIISink() - qsfp2_3_sink_logic = qsfp2_3_sink.create_logic(qsfp2_tx_clk_3, qsfp2_tx_rst_3, rxd=qsfp2_txd_3, rxc=qsfp2_txc_3, name='qsfp2_3_sink') - - qsfp2_4_source = xgmii_ep.XGMIISource() - qsfp2_4_source_logic = qsfp2_4_source.create_logic(qsfp2_rx_clk_4, qsfp2_rx_rst_4, txd=qsfp2_rxd_4, txc=qsfp2_rxc_4, name='qsfp2_4_source') - - qsfp2_4_sink = xgmii_ep.XGMIISink() - qsfp2_4_sink_logic = qsfp2_4_sink.create_logic(qsfp2_tx_clk_4, qsfp2_tx_rst_4, rxd=qsfp2_txd_4, rxc=qsfp2_txc_4, name='qsfp2_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp1_tx_clk_1=qsfp1_tx_clk_1, - qsfp1_tx_rst_1=qsfp1_tx_rst_1, - qsfp1_txd_1=qsfp1_txd_1, - qsfp1_txc_1=qsfp1_txc_1, - qsfp1_rx_clk_1=qsfp1_rx_clk_1, - qsfp1_rx_rst_1=qsfp1_rx_rst_1, - qsfp1_rxd_1=qsfp1_rxd_1, - qsfp1_rxc_1=qsfp1_rxc_1, - qsfp1_tx_clk_2=qsfp1_tx_clk_2, - qsfp1_tx_rst_2=qsfp1_tx_rst_2, - qsfp1_txd_2=qsfp1_txd_2, - qsfp1_txc_2=qsfp1_txc_2, - qsfp1_rx_clk_2=qsfp1_rx_clk_2, - qsfp1_rx_rst_2=qsfp1_rx_rst_2, - qsfp1_rxd_2=qsfp1_rxd_2, - qsfp1_rxc_2=qsfp1_rxc_2, - qsfp1_tx_clk_3=qsfp1_tx_clk_3, - qsfp1_tx_rst_3=qsfp1_tx_rst_3, - qsfp1_txd_3=qsfp1_txd_3, - qsfp1_txc_3=qsfp1_txc_3, - qsfp1_rx_clk_3=qsfp1_rx_clk_3, - qsfp1_rx_rst_3=qsfp1_rx_rst_3, - qsfp1_rxd_3=qsfp1_rxd_3, - qsfp1_rxc_3=qsfp1_rxc_3, - qsfp1_tx_clk_4=qsfp1_tx_clk_4, - qsfp1_tx_rst_4=qsfp1_tx_rst_4, - qsfp1_txd_4=qsfp1_txd_4, - qsfp1_txc_4=qsfp1_txc_4, - qsfp1_rx_clk_4=qsfp1_rx_clk_4, - qsfp1_rx_rst_4=qsfp1_rx_rst_4, - qsfp1_rxd_4=qsfp1_rxd_4, - qsfp1_rxc_4=qsfp1_rxc_4, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - qsfp2_tx_clk_1=qsfp2_tx_clk_1, - qsfp2_tx_rst_1=qsfp2_tx_rst_1, - qsfp2_txd_1=qsfp2_txd_1, - qsfp2_txc_1=qsfp2_txc_1, - qsfp2_rx_clk_1=qsfp2_rx_clk_1, - qsfp2_rx_rst_1=qsfp2_rx_rst_1, - qsfp2_rxd_1=qsfp2_rxd_1, - qsfp2_rxc_1=qsfp2_rxc_1, - qsfp2_tx_clk_2=qsfp2_tx_clk_2, - qsfp2_tx_rst_2=qsfp2_tx_rst_2, - qsfp2_txd_2=qsfp2_txd_2, - qsfp2_txc_2=qsfp2_txc_2, - qsfp2_rx_clk_2=qsfp2_rx_clk_2, - qsfp2_rx_rst_2=qsfp2_rx_rst_2, - qsfp2_rxd_2=qsfp2_rxd_2, - qsfp2_rxc_2=qsfp2_rxc_2, - qsfp2_tx_clk_3=qsfp2_tx_clk_3, - qsfp2_tx_rst_3=qsfp2_tx_rst_3, - qsfp2_txd_3=qsfp2_txd_3, - qsfp2_txc_3=qsfp2_txc_3, - qsfp2_rx_clk_3=qsfp2_rx_clk_3, - qsfp2_rx_rst_3=qsfp2_rx_rst_3, - qsfp2_rxd_3=qsfp2_rxd_3, - qsfp2_rxc_3=qsfp2_rxc_3, - qsfp2_tx_clk_4=qsfp2_tx_clk_4, - qsfp2_tx_rst_4=qsfp2_tx_rst_4, - qsfp2_txd_4=qsfp2_txd_4, - qsfp2_txc_4=qsfp2_txc_4, - qsfp2_rx_clk_4=qsfp2_rx_clk_4, - qsfp2_rx_rst_4=qsfp2_rx_rst_4, - qsfp2_rxd_4=qsfp2_rxd_4, - qsfp2_rxc_4=qsfp2_rxc_4, - qsfp2_modprsl=qsfp2_modprsl, - qsfp2_modsell=qsfp2_modsell, - qsfp2_resetl=qsfp2_resetl, - qsfp2_intl=qsfp2_intl, - qsfp2_lpmode=qsfp2_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 - qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 - qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 - qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 - qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 - qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 - qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 - qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 - qsfp2_tx_clk_1.next = not qsfp2_tx_clk_1 - qsfp2_rx_clk_1.next = not qsfp2_rx_clk_1 - qsfp2_tx_clk_2.next = not qsfp2_tx_clk_2 - qsfp2_rx_clk_2.next = not qsfp2_rx_clk_2 - qsfp2_tx_clk_3.next = not qsfp2_tx_clk_3 - qsfp2_rx_clk_3.next = not qsfp2_rx_clk_3 - qsfp2_tx_clk_4.next = not qsfp2_tx_clk_4 - qsfp2_rx_clk_4.next = not qsfp2_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp1_1_sink.empty(): - pkt = qsfp1_1_sink.recv() - qsfp1_1_source.send(pkt) - if not qsfp1_2_sink.empty(): - pkt = qsfp1_2_sink.recv() - qsfp1_2_source.send(pkt) - if not qsfp1_3_sink.empty(): - pkt = qsfp1_3_sink.recv() - qsfp1_3_source.send(pkt) - if not qsfp1_4_sink.empty(): - pkt = qsfp1_4_sink.recv() - qsfp1_4_source.send(pkt) - if not qsfp2_1_sink.empty(): - pkt = qsfp2_1_sink.recv() - qsfp2_1_source.send(pkt) - if not qsfp2_2_sink.empty(): - pkt = qsfp2_2_sink.recv() - qsfp2_2_source.send(pkt) - if not qsfp2_3_sink.empty(): - pkt = qsfp2_3_sink.recv() - qsfp2_3_source.send(pkt) - if not qsfp2_4_sink.empty(): - pkt = qsfp2_4_sink.recv() - qsfp2_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp1_tx_rst_1.next = 1 - qsfp1_rx_rst_1.next = 1 - qsfp1_tx_rst_2.next = 1 - qsfp1_rx_rst_2.next = 1 - qsfp1_tx_rst_3.next = 1 - qsfp1_rx_rst_3.next = 1 - qsfp1_tx_rst_4.next = 1 - qsfp1_rx_rst_4.next = 1 - qsfp2_tx_rst_1.next = 1 - qsfp2_rx_rst_1.next = 1 - qsfp2_tx_rst_2.next = 1 - qsfp2_rx_rst_2.next = 1 - qsfp2_tx_rst_3.next = 1 - qsfp2_rx_rst_3.next = 1 - qsfp2_tx_rst_4.next = 1 - qsfp2_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp1_tx_rst_1.next = 0 - qsfp1_rx_rst_1.next = 0 - qsfp1_tx_rst_2.next = 0 - qsfp1_rx_rst_2.next = 0 - qsfp1_tx_rst_3.next = 0 - qsfp1_rx_rst_3.next = 0 - qsfp1_tx_rst_4.next = 0 - qsfp1_rx_rst_4.next = 0 - qsfp2_tx_rst_1.next = 0 - qsfp2_rx_rst_1.next = 0 - qsfp2_tx_rst_2.next = 0 - qsfp2_rx_rst_2.next = 0 - qsfp2_tx_rst_3.next = 0 - qsfp2_rx_rst_3.next = 0 - qsfp2_tx_rst_4.next = 0 - qsfp2_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp1_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp1_1_sink.wait() - - pkt = qsfp1_1_sink.recv() - print(pkt) - - qsfp1_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp1_1_sink.wait() - - # pkt = qsfp1_1_sink.recv() - # print(pkt) - - # qsfp1_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp1_1_sink.wait() - - pkt = qsfp1_1_sink.recv() - print(pkt) - - qsfp1_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/VCU118/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 8aa425bc2..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg btnu = 0; -reg btnl = 0; -reg btnd = 0; -reg btnr = 0; -reg btnc = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp1_tx_clk_1 = 0; -reg qsfp1_tx_rst_1 = 0; -reg qsfp1_rx_clk_1 = 0; -reg qsfp1_rx_rst_1 = 0; -reg [63:0] qsfp1_rxd_1 = 0; -reg [7:0] qsfp1_rxc_1 = 0; -reg qsfp1_tx_clk_2 = 0; -reg qsfp1_tx_rst_2 = 0; -reg qsfp1_rx_clk_2 = 0; -reg qsfp1_rx_rst_2 = 0; -reg [63:0] qsfp1_rxd_2 = 0; -reg [7:0] qsfp1_rxc_2 = 0; -reg qsfp1_tx_clk_3 = 0; -reg qsfp1_tx_rst_3 = 0; -reg qsfp1_rx_clk_3 = 0; -reg qsfp1_rx_rst_3 = 0; -reg [63:0] qsfp1_rxd_3 = 0; -reg [7:0] qsfp1_rxc_3 = 0; -reg qsfp1_tx_clk_4 = 0; -reg qsfp1_tx_rst_4 = 0; -reg qsfp1_rx_clk_4 = 0; -reg qsfp1_rx_rst_4 = 0; -reg [63:0] qsfp1_rxd_4 = 0; -reg [7:0] qsfp1_rxc_4 = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg qsfp2_tx_clk_1 = 0; -reg qsfp2_tx_rst_1 = 0; -reg qsfp2_rx_clk_1 = 0; -reg qsfp2_rx_rst_1 = 0; -reg [63:0] qsfp2_rxd_1 = 0; -reg [7:0] qsfp2_rxc_1 = 0; -reg qsfp2_tx_clk_2 = 0; -reg qsfp2_tx_rst_2 = 0; -reg qsfp2_rx_clk_2 = 0; -reg qsfp2_rx_rst_2 = 0; -reg [63:0] qsfp2_rxd_2 = 0; -reg [7:0] qsfp2_rxc_2 = 0; -reg qsfp2_tx_clk_3 = 0; -reg qsfp2_tx_rst_3 = 0; -reg qsfp2_rx_clk_3 = 0; -reg qsfp2_rx_rst_3 = 0; -reg [63:0] qsfp2_rxd_3 = 0; -reg [7:0] qsfp2_rxc_3 = 0; -reg qsfp2_tx_clk_4 = 0; -reg qsfp2_tx_rst_4 = 0; -reg qsfp2_rx_clk_4 = 0; -reg qsfp2_rx_rst_4 = 0; -reg [63:0] qsfp2_rxd_4 = 0; -reg [7:0] qsfp2_rxc_4 = 0; -reg qsfp2_modprsl = 1; -reg qsfp2_intl = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [7:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp1_txd_1; -wire [7:0] qsfp1_txc_1; -wire [63:0] qsfp1_txd_2; -wire [7:0] qsfp1_txc_2; -wire [63:0] qsfp1_txd_3; -wire [7:0] qsfp1_txc_3; -wire [63:0] qsfp1_txd_4; -wire [7:0] qsfp1_txc_4; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire [63:0] qsfp2_txd_1; -wire [7:0] qsfp2_txc_1; -wire [63:0] qsfp2_txd_2; -wire [7:0] qsfp2_txc_2; -wire [63:0] qsfp2_txd_3; -wire [7:0] qsfp2_txc_3; -wire [63:0] qsfp2_txd_4; -wire [7:0] qsfp2_txc_4; -wire qsfp2_modsell; -wire qsfp2_resetl; -wire qsfp2_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp1_tx_clk_1, - qsfp1_tx_rst_1, - qsfp1_rx_clk_1, - qsfp1_rx_rst_1, - qsfp1_rxd_1, - qsfp1_rxc_1, - qsfp1_tx_clk_2, - qsfp1_tx_rst_2, - qsfp1_rx_clk_2, - qsfp1_rx_rst_2, - qsfp1_rxd_2, - qsfp1_rxc_2, - qsfp1_tx_clk_3, - qsfp1_tx_rst_3, - qsfp1_rx_clk_3, - qsfp1_rx_rst_3, - qsfp1_rxd_3, - qsfp1_rxc_3, - qsfp1_tx_clk_4, - qsfp1_tx_rst_4, - qsfp1_rx_clk_4, - qsfp1_rx_rst_4, - qsfp1_rxd_4, - qsfp1_rxc_4, - qsfp1_modprsl, - qsfp1_intl, - qsfp2_tx_clk_1, - qsfp2_tx_rst_1, - qsfp2_rx_clk_1, - qsfp2_rx_rst_1, - qsfp2_rxd_1, - qsfp2_rxc_1, - qsfp2_tx_clk_2, - qsfp2_tx_rst_2, - qsfp2_rx_clk_2, - qsfp2_rx_rst_2, - qsfp2_rxd_2, - qsfp2_rxc_2, - qsfp2_tx_clk_3, - qsfp2_tx_rst_3, - qsfp2_rx_clk_3, - qsfp2_rx_rst_3, - qsfp2_rxd_3, - qsfp2_rxc_3, - qsfp2_tx_clk_4, - qsfp2_tx_rst_4, - qsfp2_rx_clk_4, - qsfp2_rx_rst_4, - qsfp2_rxd_4, - qsfp2_rxc_4, - qsfp2_modprsl, - qsfp2_intl, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp1_txd_1, - qsfp1_txc_1, - qsfp1_txd_2, - qsfp1_txc_2, - qsfp1_txd_3, - qsfp1_txc_3, - qsfp1_txd_4, - qsfp1_txc_4, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - qsfp2_txd_1, - qsfp2_txc_1, - qsfp2_txd_2, - qsfp2_txc_2, - qsfp2_txd_3, - qsfp2_txc_3, - qsfp2_txd_4, - qsfp2_txc_4, - qsfp2_modsell, - qsfp2_resetl, - qsfp2_lpmode, - fpga_boot, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btnu(btnu), - .btnl(btnl), - .btnd(btnd), - .btnr(btnr), - .btnc(btnc), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1), - .qsfp1_txd_1(qsfp1_txd_1), - .qsfp1_txc_1(qsfp1_txc_1), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1), - .qsfp1_rxd_1(qsfp1_rxd_1), - .qsfp1_rxc_1(qsfp1_rxc_1), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2), - .qsfp1_txd_2(qsfp1_txd_2), - .qsfp1_txc_2(qsfp1_txc_2), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2), - .qsfp1_rxd_2(qsfp1_rxd_2), - .qsfp1_rxc_2(qsfp1_rxc_2), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3), - .qsfp1_txd_3(qsfp1_txd_3), - .qsfp1_txc_3(qsfp1_txc_3), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3), - .qsfp1_rxd_3(qsfp1_rxd_3), - .qsfp1_rxc_3(qsfp1_rxc_3), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4), - .qsfp1_txd_4(qsfp1_txd_4), - .qsfp1_txc_4(qsfp1_txc_4), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4), - .qsfp1_rxd_4(qsfp1_rxd_4), - .qsfp1_rxc_4(qsfp1_rxc_4), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .qsfp2_tx_clk_1(qsfp2_tx_clk_1), - .qsfp2_tx_rst_1(qsfp2_tx_rst_1), - .qsfp2_txd_1(qsfp2_txd_1), - .qsfp2_txc_1(qsfp2_txc_1), - .qsfp2_rx_clk_1(qsfp2_rx_clk_1), - .qsfp2_rx_rst_1(qsfp2_rx_rst_1), - .qsfp2_rxd_1(qsfp2_rxd_1), - .qsfp2_rxc_1(qsfp2_rxc_1), - .qsfp2_tx_clk_2(qsfp2_tx_clk_2), - .qsfp2_tx_rst_2(qsfp2_tx_rst_2), - .qsfp2_txd_2(qsfp2_txd_2), - .qsfp2_txc_2(qsfp2_txc_2), - .qsfp2_rx_clk_2(qsfp2_rx_clk_2), - .qsfp2_rx_rst_2(qsfp2_rx_rst_2), - .qsfp2_rxd_2(qsfp2_rxd_2), - .qsfp2_rxc_2(qsfp2_rxc_2), - .qsfp2_tx_clk_3(qsfp2_tx_clk_3), - .qsfp2_tx_rst_3(qsfp2_tx_rst_3), - .qsfp2_txd_3(qsfp2_txd_3), - .qsfp2_txc_3(qsfp2_txc_3), - .qsfp2_rx_clk_3(qsfp2_rx_clk_3), - .qsfp2_rx_rst_3(qsfp2_rx_rst_3), - .qsfp2_rxd_3(qsfp2_rxd_3), - .qsfp2_rxc_3(qsfp2_rxc_3), - .qsfp2_tx_clk_4(qsfp2_tx_clk_4), - .qsfp2_tx_rst_4(qsfp2_tx_rst_4), - .qsfp2_txd_4(qsfp2_txd_4), - .qsfp2_txc_4(qsfp2_txc_4), - .qsfp2_rx_clk_4(qsfp2_rx_clk_4), - .qsfp2_rx_rst_4(qsfp2_rx_rst_4), - .qsfp2_rxd_4(qsfp2_rxd_4), - .qsfp2_rxc_4(qsfp2_rxc_4), - .qsfp2_modprsl(qsfp2_modprsl_int), - .qsfp2_modsell(qsfp2_modsell), - .qsfp2_resetl(qsfp2_resetl), - .qsfp2_intl(qsfp2_intl_int), - .qsfp2_lpmode(qsfp2_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/udp_ep.py b/fpga/mqnic/VCU118/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU118/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/VCU118/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/VCU118/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/axis_ep.py b/fpga/mqnic/VCU1525/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/eth_ep.py b/fpga/mqnic/VCU1525/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..1b6b1b200 --- /dev/null +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..e241e3779 --- /dev/null +++ b/fpga/mqnic/VCU1525/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,585 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk, 3.102, units="ns").start()) + self.qsfp0_source = AxiStreamSource(dut, "qsfp0_rx_axis", dut.qsfp0_rx_clk, dut.qsfp0_rx_rst) + cocotb.fork(Clock(dut.qsfp0_tx_clk, 3.102, units="ns").start()) + self.qsfp0_sink = AxiStreamSink(dut, "qsfp0_tx_axis", dut.qsfp0_tx_clk, dut.qsfp0_tx_rst) + + cocotb.fork(Clock(dut.qsfp1_rx_clk, 3.102, units="ns").start()) + self.qsfp1_source = AxiStreamSource(dut, "qsfp1_rx_axis", dut.qsfp1_rx_clk, dut.qsfp1_rx_rst) + cocotb.fork(Clock(dut.qsfp1_tx_clk, 3.102, units="ns").start()) + self.qsfp1_sink = AxiStreamSink(dut, "qsfp1_tx_axis", dut.qsfp1_tx_clk, dut.qsfp1_tx_rst) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(1) + self.dut.qsfp0_tx_rst.setimmediatevalue(1) + self.dut.qsfp1_rx_rst.setimmediatevalue(1) + self.dut.qsfp1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst.setimmediatevalue(0) + self.dut.qsfp0_tx_rst.setimmediatevalue(0) + self.dut.qsfp1_rx_rst.setimmediatevalue(0) + self.dut.qsfp1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_sink.empty(): + self.qsfp0_source.send(self.qsfp0_sink.recv()) + if not self.qsfp1_sink.empty(): + self.qsfp1_source.send(self.qsfp1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_0_sink.wait() + + # pkt = tb.qsfp1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_sink.wait() + + pkt = tb.qsfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/ip_ep.py b/fpga/mqnic/VCU1525/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/mqnic.py b/fpga/mqnic/VCU1525/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/pcie.py b/fpga/mqnic/VCU1525/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/pcie_us.py b/fpga/mqnic/VCU1525/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/VCU1525/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index bd17d57c1..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,940 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk = Signal(bool(0)) - qsfp0_tx_rst = Signal(bool(0)) - qsfp0_rx_clk = Signal(bool(0)) - qsfp0_rx_rst = Signal(bool(0)) - qsfp0_tx_axis_tready = Signal(bool(0)) - qsfp0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_rx_axis_tvalid = Signal(bool(0)) - qsfp0_rx_axis_tlast = Signal(bool(0)) - qsfp0_rx_axis_tuser = Signal(bool(0)) - qsfp0_modprsl = Signal(bool(1)) - qsfp0_intl = Signal(bool(1)) - qsfp1_tx_clk = Signal(bool(0)) - qsfp1_tx_rst = Signal(bool(0)) - qsfp1_rx_clk = Signal(bool(0)) - qsfp1_rx_rst = Signal(bool(0)) - qsfp1_tx_axis_tready = Signal(bool(0)) - qsfp1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_rx_axis_tvalid = Signal(bool(0)) - qsfp1_rx_axis_tlast = Signal(bool(0)) - qsfp1_rx_axis_tuser = Signal(bool(0)) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[3:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp0_tx_axis_tvalid = Signal(bool(0)) - qsfp0_tx_axis_tlast = Signal(bool(0)) - qsfp0_tx_axis_tuser = Signal(bool(0)) - qsfp0_modsell = Signal(bool(0)) - qsfp0_resetl = Signal(bool(0)) - qsfp0_lpmode = Signal(bool(0)) - qsfp1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp1_tx_axis_tvalid = Signal(bool(0)) - qsfp1_tx_axis_tlast = Signal(bool(0)) - qsfp1_tx_axis_tuser = Signal(bool(0)) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_source = axis_ep.AXIStreamSource() - qsfp0_source_pause = Signal(bool(False)) - - qsfp0_source_logic = qsfp0_source.create_logic( - qsfp0_rx_clk, - qsfp0_rx_rst, - tdata=qsfp0_rx_axis_tdata, - tkeep=qsfp0_rx_axis_tkeep, - tvalid=qsfp0_rx_axis_tvalid, - tlast=qsfp0_rx_axis_tlast, - tuser=qsfp0_rx_axis_tuser, - pause=qsfp0_source_pause, - name='qsfp0_source' - ) - - qsfp0_sink = axis_ep.AXIStreamSink() - qsfp0_sink_pause = Signal(bool(False)) - - qsfp0_sink_logic = qsfp0_sink.create_logic( - qsfp0_tx_clk, - qsfp0_tx_rst, - tdata=qsfp0_tx_axis_tdata, - tkeep=qsfp0_tx_axis_tkeep, - tvalid=qsfp0_tx_axis_tvalid, - tready=qsfp0_tx_axis_tready, - tlast=qsfp0_tx_axis_tlast, - tuser=qsfp0_tx_axis_tuser, - pause=qsfp0_sink_pause, - name='qsfp0_sink' - ) - - qsfp1_source = axis_ep.AXIStreamSource() - qsfp1_source_pause = Signal(bool(False)) - - qsfp1_source_logic = qsfp1_source.create_logic( - qsfp1_rx_clk, - qsfp1_rx_rst, - tdata=qsfp1_rx_axis_tdata, - tkeep=qsfp1_rx_axis_tkeep, - tvalid=qsfp1_rx_axis_tvalid, - tlast=qsfp1_rx_axis_tlast, - tuser=qsfp1_rx_axis_tuser, - pause=qsfp1_source_pause, - name='qsfp1_source' - ) - - qsfp1_sink = axis_ep.AXIStreamSink() - qsfp1_sink_pause = Signal(bool(False)) - - qsfp1_sink_logic = qsfp1_sink.create_logic( - qsfp1_tx_clk, - qsfp1_tx_rst, - tdata=qsfp1_tx_axis_tdata, - tkeep=qsfp1_tx_axis_tkeep, - tvalid=qsfp1_tx_axis_tvalid, - tready=qsfp1_tx_axis_tready, - tlast=qsfp1_tx_axis_tlast, - tuser=qsfp1_tx_axis_tuser, - pause=qsfp1_sink_pause, - name='qsfp1_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk=qsfp0_tx_clk, - qsfp0_tx_rst=qsfp0_tx_rst, - qsfp0_tx_axis_tdata=qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep=qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid=qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tready=qsfp0_tx_axis_tready, - qsfp0_tx_axis_tlast=qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser=qsfp0_tx_axis_tuser, - qsfp0_rx_clk=qsfp0_rx_clk, - qsfp0_rx_rst=qsfp0_rx_rst, - qsfp0_rx_axis_tdata=qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep=qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid=qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast=qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser=qsfp0_rx_axis_tuser, - qsfp0_modprsl=qsfp0_modprsl, - qsfp0_modsell=qsfp0_modsell, - qsfp0_resetl=qsfp0_resetl, - qsfp0_intl=qsfp0_intl, - qsfp0_lpmode=qsfp0_lpmode, - qsfp1_tx_clk=qsfp1_tx_clk, - qsfp1_tx_rst=qsfp1_tx_rst, - qsfp1_tx_axis_tdata=qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep=qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid=qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tready=qsfp1_tx_axis_tready, - qsfp1_tx_axis_tlast=qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser=qsfp1_tx_axis_tuser, - qsfp1_rx_clk=qsfp1_rx_clk, - qsfp1_rx_rst=qsfp1_rx_rst, - qsfp1_rx_axis_tdata=qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep=qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid=qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast=qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser=qsfp1_rx_axis_tuser, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp0_tx_clk.next = not qsfp0_tx_clk - qsfp0_rx_clk.next = not qsfp0_rx_clk - qsfp1_tx_clk.next = not qsfp1_tx_clk - qsfp1_rx_clk.next = not qsfp1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_sink.empty(): - pkt = qsfp0_sink.recv() - qsfp0_source.send(pkt) - if not qsfp1_sink.empty(): - pkt = qsfp1_sink.recv() - qsfp1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst.next = 1 - qsfp0_rx_rst.next = 1 - qsfp1_tx_rst.next = 1 - qsfp1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst.next = 0 - qsfp0_rx_rst.next = 0 - qsfp1_tx_rst.next = 0 - qsfp1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_sink.wait() - - # pkt = qsfp0_sink.recv() - # print(pkt) - - # qsfp0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_sink.wait() - - pkt = qsfp0_sink.recv() - print(pkt) - - qsfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/VCU1525/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index 9050d9955..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,454 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk = 0; -reg qsfp0_tx_rst = 0; -reg qsfp0_tx_axis_tready = 0; -reg qsfp0_rx_clk = 0; -reg qsfp0_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_rx_axis_tkeep = 0; -reg qsfp0_rx_axis_tvalid = 0; -reg qsfp0_rx_axis_tlast = 0; -reg qsfp0_rx_axis_tuser = 0; -reg qsfp0_modprsl = 1; -reg qsfp0_intl = 1; -reg qsfp1_tx_clk = 0; -reg qsfp1_tx_rst = 0; -reg qsfp1_tx_axis_tready = 0; -reg qsfp1_rx_clk = 0; -reg qsfp1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_rx_axis_tkeep = 0; -reg qsfp1_rx_axis_tvalid = 0; -reg qsfp1_rx_axis_tlast = 0; -reg qsfp1_rx_axis_tuser = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [2:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp0_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp0_tx_axis_tkeep; -wire qsfp0_tx_axis_tvalid; -wire qsfp0_tx_axis_tlast; -wire qsfp0_tx_axis_tuser; -wire qsfp0_modsell; -wire qsfp0_resetl; -wire qsfp0_lpmode; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp1_tx_axis_tkeep; -wire qsfp1_tx_axis_tvalid; -wire qsfp1_tx_axis_tlast; -wire qsfp1_tx_axis_tuser; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk, - qsfp0_tx_rst, - qsfp0_tx_axis_tready, - qsfp0_rx_clk, - qsfp0_rx_rst, - qsfp0_rx_axis_tdata, - qsfp0_rx_axis_tkeep, - qsfp0_rx_axis_tvalid, - qsfp0_rx_axis_tlast, - qsfp0_rx_axis_tuser, - qsfp0_modprsl, - qsfp0_intl, - qsfp1_tx_clk, - qsfp1_tx_rst, - qsfp1_tx_axis_tready, - qsfp1_rx_clk, - qsfp1_rx_rst, - qsfp1_rx_axis_tdata, - qsfp1_rx_axis_tkeep, - qsfp1_rx_axis_tvalid, - qsfp1_rx_axis_tlast, - qsfp1_rx_axis_tuser, - qsfp1_modprsl, - qsfp1_intl, - qspi_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_tx_axis_tdata, - qsfp0_tx_axis_tkeep, - qsfp0_tx_axis_tvalid, - qsfp0_tx_axis_tlast, - qsfp0_tx_axis_tuser, - qsfp0_modsell, - qsfp0_resetl, - qsfp0_lpmode, - qsfp1_tx_axis_tdata, - qsfp1_tx_axis_tkeep, - qsfp1_tx_axis_tvalid, - qsfp1_tx_axis_tlast, - qsfp1_tx_axis_tuser, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk(qsfp0_tx_clk), - .qsfp0_tx_rst(qsfp0_tx_rst), - .qsfp0_tx_axis_tdata(qsfp0_tx_axis_tdata), - .qsfp0_tx_axis_tkeep(qsfp0_tx_axis_tkeep), - .qsfp0_tx_axis_tvalid(qsfp0_tx_axis_tvalid), - .qsfp0_tx_axis_tready(qsfp0_tx_axis_tready), - .qsfp0_tx_axis_tlast(qsfp0_tx_axis_tlast), - .qsfp0_tx_axis_tuser(qsfp0_tx_axis_tuser), - .qsfp0_rx_clk(qsfp0_rx_clk), - .qsfp0_rx_rst(qsfp0_rx_rst), - .qsfp0_rx_axis_tdata(qsfp0_rx_axis_tdata), - .qsfp0_rx_axis_tkeep(qsfp0_rx_axis_tkeep), - .qsfp0_rx_axis_tvalid(qsfp0_rx_axis_tvalid), - .qsfp0_rx_axis_tlast(qsfp0_rx_axis_tlast), - .qsfp0_rx_axis_tuser(qsfp0_rx_axis_tuser), - .qsfp0_modprsl(qsfp0_modprsl_int), - .qsfp0_modsell(qsfp0_modsell), - .qsfp0_resetl(qsfp0_resetl), - .qsfp0_intl(qsfp0_intl_int), - .qsfp0_lpmode(qsfp0_lpmode_int), - .qsfp1_tx_clk(qsfp1_tx_clk), - .qsfp1_tx_rst(qsfp1_tx_rst), - .qsfp1_tx_axis_tdata(qsfp1_tx_axis_tdata), - .qsfp1_tx_axis_tkeep(qsfp1_tx_axis_tkeep), - .qsfp1_tx_axis_tvalid(qsfp1_tx_axis_tvalid), - .qsfp1_tx_axis_tready(qsfp1_tx_axis_tready), - .qsfp1_tx_axis_tlast(qsfp1_tx_axis_tlast), - .qsfp1_tx_axis_tuser(qsfp1_tx_axis_tuser), - .qsfp1_rx_clk(qsfp1_rx_clk), - .qsfp1_rx_rst(qsfp1_rx_rst), - .qsfp1_rx_axis_tdata(qsfp1_rx_axis_tdata), - .qsfp1_rx_axis_tkeep(qsfp1_rx_axis_tkeep), - .qsfp1_rx_axis_tvalid(qsfp1_rx_axis_tvalid), - .qsfp1_rx_axis_tlast(qsfp1_rx_axis_tlast), - .qsfp1_rx_axis_tuser(qsfp1_rx_axis_tuser), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/udp_ep.py b/fpga/mqnic/VCU1525/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_100g/tb/xgmii_ep.py b/fpga/mqnic/VCU1525/fpga_100g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/VCU1525/fpga_100g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/axis_ep.py b/fpga/mqnic/VCU1525/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/eth_ep.py b/fpga/mqnic/VCU1525/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..73e65ecb4 --- /dev/null +++ b/fpga/mqnic/VCU1525/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,655 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_source = XgmiiSource(dut.qsfp0_rxd_1, dut.qsfp0_rxc_1, dut.qsfp0_rx_clk_1, dut.qsfp0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp0_1_sink = XgmiiSink(dut.qsfp0_txd_1, dut.qsfp0_txc_1, dut.qsfp0_tx_clk_1, dut.qsfp0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_source = XgmiiSource(dut.qsfp0_rxd_2, dut.qsfp0_rxc_2, dut.qsfp0_rx_clk_2, dut.qsfp0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp0_2_sink = XgmiiSink(dut.qsfp0_txd_2, dut.qsfp0_txc_2, dut.qsfp0_tx_clk_2, dut.qsfp0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_source = XgmiiSource(dut.qsfp0_rxd_3, dut.qsfp0_rxc_3, dut.qsfp0_rx_clk_3, dut.qsfp0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp0_3_sink = XgmiiSink(dut.qsfp0_txd_3, dut.qsfp0_txc_3, dut.qsfp0_tx_clk_3, dut.qsfp0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp0_rx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_source = XgmiiSource(dut.qsfp0_rxd_4, dut.qsfp0_rxc_4, dut.qsfp0_rx_clk_4, dut.qsfp0_rx_rst_4) + cocotb.fork(Clock(dut.qsfp0_tx_clk_4, 6.4, units="ns").start()) + self.qsfp0_4_sink = XgmiiSink(dut.qsfp0_txd_4, dut.qsfp0_txc_4, dut.qsfp0_tx_clk_4, dut.qsfp0_tx_rst_4) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp0_rx_error_count_3.setimmediatevalue(0) + dut.qsfp0_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp0_modprsl.setimmediatevalue(0) + dut.qsfp0_intl.setimmediatevalue(1) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qspi_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp0_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp0_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp0_1_sink.empty(): + self.qsfp0_1_source.send(self.qsfp0_1_sink.recv()) + if not self.qsfp0_2_sink.empty(): + self.qsfp0_2_source.send(self.qsfp0_2_sink.recv()) + if not self.qsfp0_3_sink.empty(): + self.qsfp0_3_source.send(self.qsfp0_3_sink.recv()) + if not self.qsfp0_4_sink.empty(): + self.qsfp0_4_source.send(self.qsfp0_4_sink.recv()) + if not self.qsfp1_1_sink.empty(): + self.qsfp1_1_source.send(self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + self.qsfp1_2_source.send(self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + self.qsfp1_3_source.send(self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + self.qsfp1_4_source.send(self.qsfp1_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp1_1_sink.wait() + + # pkt = tb.qsfp1_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp1_1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp0_1_sink.wait() + + pkt = tb.qsfp0_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp0_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/ip_ep.py b/fpga/mqnic/VCU1525/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/mqnic.py b/fpga/mqnic/VCU1525/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/pcie.py b/fpga/mqnic/VCU1525/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/pcie_us.py b/fpga/mqnic/VCU1525/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/VCU1525/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/VCU1525/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 3afc41b44..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1028 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp0_tx_clk_1 = Signal(bool(0)) - qsfp0_tx_rst_1 = Signal(bool(0)) - qsfp0_rx_clk_1 = Signal(bool(0)) - qsfp0_rx_rst_1 = Signal(bool(0)) - qsfp0_rxd_1 = Signal(intbv(0)[64:]) - qsfp0_rxc_1 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_2 = Signal(bool(0)) - qsfp0_tx_rst_2 = Signal(bool(0)) - qsfp0_rx_clk_2 = Signal(bool(0)) - qsfp0_rx_rst_2 = Signal(bool(0)) - qsfp0_rxd_2 = Signal(intbv(0)[64:]) - qsfp0_rxc_2 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_3 = Signal(bool(0)) - qsfp0_tx_rst_3 = Signal(bool(0)) - qsfp0_rx_clk_3 = Signal(bool(0)) - qsfp0_rx_rst_3 = Signal(bool(0)) - qsfp0_rxd_3 = Signal(intbv(0)[64:]) - qsfp0_rxc_3 = Signal(intbv(0)[8:]) - qsfp0_tx_clk_4 = Signal(bool(0)) - qsfp0_tx_rst_4 = Signal(bool(0)) - qsfp0_rx_clk_4 = Signal(bool(0)) - qsfp0_rx_rst_4 = Signal(bool(0)) - qsfp0_rxd_4 = Signal(intbv(0)[64:]) - qsfp0_rxc_4 = Signal(intbv(0)[8:]) - qsfp0_modprsl = Signal(bool(1)) - qsfp0_intl = Signal(bool(1)) - qsfp1_tx_clk_1 = Signal(bool(0)) - qsfp1_tx_rst_1 = Signal(bool(0)) - qsfp1_rx_clk_1 = Signal(bool(0)) - qsfp1_rx_rst_1 = Signal(bool(0)) - qsfp1_rxd_1 = Signal(intbv(0)[64:]) - qsfp1_rxc_1 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_2 = Signal(bool(0)) - qsfp1_tx_rst_2 = Signal(bool(0)) - qsfp1_rx_clk_2 = Signal(bool(0)) - qsfp1_rx_rst_2 = Signal(bool(0)) - qsfp1_rxd_2 = Signal(intbv(0)[64:]) - qsfp1_rxc_2 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_3 = Signal(bool(0)) - qsfp1_tx_rst_3 = Signal(bool(0)) - qsfp1_rx_clk_3 = Signal(bool(0)) - qsfp1_rx_rst_3 = Signal(bool(0)) - qsfp1_rxd_3 = Signal(intbv(0)[64:]) - qsfp1_rxc_3 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_4 = Signal(bool(0)) - qsfp1_tx_rst_4 = Signal(bool(0)) - qsfp1_rx_clk_4 = Signal(bool(0)) - qsfp1_rx_rst_4 = Signal(bool(0)) - qsfp1_rxd_4 = Signal(intbv(0)[64:]) - qsfp1_rxc_4 = Signal(intbv(0)[8:]) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[3:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp0_txd_1 = Signal(intbv(0)[64:]) - qsfp0_txc_1 = Signal(intbv(0)[8:]) - qsfp0_txd_2 = Signal(intbv(0)[64:]) - qsfp0_txc_2 = Signal(intbv(0)[8:]) - qsfp0_txd_3 = Signal(intbv(0)[64:]) - qsfp0_txc_3 = Signal(intbv(0)[8:]) - qsfp0_txd_4 = Signal(intbv(0)[64:]) - qsfp0_txc_4 = Signal(intbv(0)[8:]) - qsfp0_modsell = Signal(bool(0)) - qsfp0_resetl = Signal(bool(0)) - qsfp0_lpmode = Signal(bool(0)) - qsfp1_txd_1 = Signal(intbv(0)[64:]) - qsfp1_txc_1 = Signal(intbv(0)[8:]) - qsfp1_txd_2 = Signal(intbv(0)[64:]) - qsfp1_txc_2 = Signal(intbv(0)[8:]) - qsfp1_txd_3 = Signal(intbv(0)[64:]) - qsfp1_txc_3 = Signal(intbv(0)[8:]) - qsfp1_txd_4 = Signal(intbv(0)[64:]) - qsfp1_txc_4 = Signal(intbv(0)[8:]) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp0_1_source = xgmii_ep.XGMIISource() - qsfp0_1_source_logic = qsfp0_1_source.create_logic(qsfp0_rx_clk_1, qsfp0_rx_rst_1, txd=qsfp0_rxd_1, txc=qsfp0_rxc_1, name='qsfp0_1_source') - - qsfp0_1_sink = xgmii_ep.XGMIISink() - qsfp0_1_sink_logic = qsfp0_1_sink.create_logic(qsfp0_tx_clk_1, qsfp0_tx_rst_1, rxd=qsfp0_txd_1, rxc=qsfp0_txc_1, name='qsfp0_1_sink') - - qsfp0_2_source = xgmii_ep.XGMIISource() - qsfp0_2_source_logic = qsfp0_2_source.create_logic(qsfp0_rx_clk_2, qsfp0_rx_rst_2, txd=qsfp0_rxd_2, txc=qsfp0_rxc_2, name='qsfp0_2_source') - - qsfp0_2_sink = xgmii_ep.XGMIISink() - qsfp0_2_sink_logic = qsfp0_2_sink.create_logic(qsfp0_tx_clk_2, qsfp0_tx_rst_2, rxd=qsfp0_txd_2, rxc=qsfp0_txc_2, name='qsfp0_2_sink') - - qsfp0_3_source = xgmii_ep.XGMIISource() - qsfp0_3_source_logic = qsfp0_3_source.create_logic(qsfp0_rx_clk_3, qsfp0_rx_rst_3, txd=qsfp0_rxd_3, txc=qsfp0_rxc_3, name='qsfp0_3_source') - - qsfp0_3_sink = xgmii_ep.XGMIISink() - qsfp0_3_sink_logic = qsfp0_3_sink.create_logic(qsfp0_tx_clk_3, qsfp0_tx_rst_3, rxd=qsfp0_txd_3, rxc=qsfp0_txc_3, name='qsfp0_3_sink') - - qsfp0_4_source = xgmii_ep.XGMIISource() - qsfp0_4_source_logic = qsfp0_4_source.create_logic(qsfp0_rx_clk_4, qsfp0_rx_rst_4, txd=qsfp0_rxd_4, txc=qsfp0_rxc_4, name='qsfp0_4_source') - - qsfp0_4_sink = xgmii_ep.XGMIISink() - qsfp0_4_sink_logic = qsfp0_4_sink.create_logic(qsfp0_tx_clk_4, qsfp0_tx_rst_4, rxd=qsfp0_txd_4, rxc=qsfp0_txc_4, name='qsfp0_4_sink') - - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') - - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') - - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') - - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') - - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') - - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') - - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') - - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp0_tx_clk_1=qsfp0_tx_clk_1, - qsfp0_tx_rst_1=qsfp0_tx_rst_1, - qsfp0_txd_1=qsfp0_txd_1, - qsfp0_txc_1=qsfp0_txc_1, - qsfp0_rx_clk_1=qsfp0_rx_clk_1, - qsfp0_rx_rst_1=qsfp0_rx_rst_1, - qsfp0_rxd_1=qsfp0_rxd_1, - qsfp0_rxc_1=qsfp0_rxc_1, - qsfp0_tx_clk_2=qsfp0_tx_clk_2, - qsfp0_tx_rst_2=qsfp0_tx_rst_2, - qsfp0_txd_2=qsfp0_txd_2, - qsfp0_txc_2=qsfp0_txc_2, - qsfp0_rx_clk_2=qsfp0_rx_clk_2, - qsfp0_rx_rst_2=qsfp0_rx_rst_2, - qsfp0_rxd_2=qsfp0_rxd_2, - qsfp0_rxc_2=qsfp0_rxc_2, - qsfp0_tx_clk_3=qsfp0_tx_clk_3, - qsfp0_tx_rst_3=qsfp0_tx_rst_3, - qsfp0_txd_3=qsfp0_txd_3, - qsfp0_txc_3=qsfp0_txc_3, - qsfp0_rx_clk_3=qsfp0_rx_clk_3, - qsfp0_rx_rst_3=qsfp0_rx_rst_3, - qsfp0_rxd_3=qsfp0_rxd_3, - qsfp0_rxc_3=qsfp0_rxc_3, - qsfp0_tx_clk_4=qsfp0_tx_clk_4, - qsfp0_tx_rst_4=qsfp0_tx_rst_4, - qsfp0_txd_4=qsfp0_txd_4, - qsfp0_txc_4=qsfp0_txc_4, - qsfp0_rx_clk_4=qsfp0_rx_clk_4, - qsfp0_rx_rst_4=qsfp0_rx_rst_4, - qsfp0_rxd_4=qsfp0_rxd_4, - qsfp0_rxc_4=qsfp0_rxc_4, - qsfp0_modprsl=qsfp0_modprsl, - qsfp0_modsell=qsfp0_modsell, - qsfp0_resetl=qsfp0_resetl, - qsfp0_intl=qsfp0_intl, - qsfp0_lpmode=qsfp0_lpmode, - qsfp1_tx_clk_1=qsfp1_tx_clk_1, - qsfp1_tx_rst_1=qsfp1_tx_rst_1, - qsfp1_txd_1=qsfp1_txd_1, - qsfp1_txc_1=qsfp1_txc_1, - qsfp1_rx_clk_1=qsfp1_rx_clk_1, - qsfp1_rx_rst_1=qsfp1_rx_rst_1, - qsfp1_rxd_1=qsfp1_rxd_1, - qsfp1_rxc_1=qsfp1_rxc_1, - qsfp1_tx_clk_2=qsfp1_tx_clk_2, - qsfp1_tx_rst_2=qsfp1_tx_rst_2, - qsfp1_txd_2=qsfp1_txd_2, - qsfp1_txc_2=qsfp1_txc_2, - qsfp1_rx_clk_2=qsfp1_rx_clk_2, - qsfp1_rx_rst_2=qsfp1_rx_rst_2, - qsfp1_rxd_2=qsfp1_rxd_2, - qsfp1_rxc_2=qsfp1_rxc_2, - qsfp1_tx_clk_3=qsfp1_tx_clk_3, - qsfp1_tx_rst_3=qsfp1_tx_rst_3, - qsfp1_txd_3=qsfp1_txd_3, - qsfp1_txc_3=qsfp1_txc_3, - qsfp1_rx_clk_3=qsfp1_rx_clk_3, - qsfp1_rx_rst_3=qsfp1_rx_rst_3, - qsfp1_rxd_3=qsfp1_rxd_3, - qsfp1_rxc_3=qsfp1_rxc_3, - qsfp1_tx_clk_4=qsfp1_tx_clk_4, - qsfp1_tx_rst_4=qsfp1_tx_rst_4, - qsfp1_txd_4=qsfp1_txd_4, - qsfp1_txc_4=qsfp1_txc_4, - qsfp1_rx_clk_4=qsfp1_rx_clk_4, - qsfp1_rx_rst_4=qsfp1_rx_rst_4, - qsfp1_rxd_4=qsfp1_rxd_4, - qsfp1_rxc_4=qsfp1_rxc_4, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp0_tx_clk_1.next = not qsfp0_tx_clk_1 - qsfp0_rx_clk_1.next = not qsfp0_rx_clk_1 - qsfp0_tx_clk_2.next = not qsfp0_tx_clk_2 - qsfp0_rx_clk_2.next = not qsfp0_rx_clk_2 - qsfp0_tx_clk_3.next = not qsfp0_tx_clk_3 - qsfp0_rx_clk_3.next = not qsfp0_rx_clk_3 - qsfp0_tx_clk_4.next = not qsfp0_tx_clk_4 - qsfp0_rx_clk_4.next = not qsfp0_rx_clk_4 - qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 - qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 - qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 - qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 - qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 - qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 - qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 - qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp0_1_sink.empty(): - pkt = qsfp0_1_sink.recv() - qsfp0_1_source.send(pkt) - if not qsfp0_2_sink.empty(): - pkt = qsfp0_2_sink.recv() - qsfp0_2_source.send(pkt) - if not qsfp0_3_sink.empty(): - pkt = qsfp0_3_sink.recv() - qsfp0_3_source.send(pkt) - if not qsfp0_4_sink.empty(): - pkt = qsfp0_4_sink.recv() - qsfp0_4_source.send(pkt) - if not qsfp1_1_sink.empty(): - pkt = qsfp1_1_sink.recv() - qsfp1_1_source.send(pkt) - if not qsfp1_2_sink.empty(): - pkt = qsfp1_2_sink.recv() - qsfp1_2_source.send(pkt) - if not qsfp1_3_sink.empty(): - pkt = qsfp1_3_sink.recv() - qsfp1_3_source.send(pkt) - if not qsfp1_4_sink.empty(): - pkt = qsfp1_4_sink.recv() - qsfp1_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp0_tx_rst_1.next = 1 - qsfp0_rx_rst_1.next = 1 - qsfp0_tx_rst_2.next = 1 - qsfp0_rx_rst_2.next = 1 - qsfp0_tx_rst_3.next = 1 - qsfp0_rx_rst_3.next = 1 - qsfp0_tx_rst_4.next = 1 - qsfp0_rx_rst_4.next = 1 - qsfp1_tx_rst_1.next = 1 - qsfp1_rx_rst_1.next = 1 - qsfp1_tx_rst_2.next = 1 - qsfp1_rx_rst_2.next = 1 - qsfp1_tx_rst_3.next = 1 - qsfp1_rx_rst_3.next = 1 - qsfp1_tx_rst_4.next = 1 - qsfp1_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp0_tx_rst_1.next = 0 - qsfp0_rx_rst_1.next = 0 - qsfp0_tx_rst_2.next = 0 - qsfp0_rx_rst_2.next = 0 - qsfp0_tx_rst_3.next = 0 - qsfp0_rx_rst_3.next = 0 - qsfp0_tx_rst_4.next = 0 - qsfp0_rx_rst_4.next = 0 - qsfp1_tx_rst_1.next = 0 - qsfp1_rx_rst_1.next = 0 - qsfp1_tx_rst_2.next = 0 - qsfp1_rx_rst_2.next = 0 - qsfp1_tx_rst_3.next = 0 - qsfp1_rx_rst_3.next = 0 - qsfp1_tx_rst_4.next = 0 - qsfp1_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp0_1_sink.wait() - - # pkt = qsfp0_1_sink.recv() - # print(pkt) - - # qsfp0_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp0_1_sink.wait() - - pkt = qsfp0_1_sink.recv() - print(pkt) - - qsfp0_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/VCU1525/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 8335c86b3..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,552 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp0_tx_clk_1 = 0; -reg qsfp0_tx_rst_1 = 0; -reg qsfp0_rx_clk_1 = 0; -reg qsfp0_rx_rst_1 = 0; -reg [63:0] qsfp0_rxd_1 = 0; -reg [7:0] qsfp0_rxc_1 = 0; -reg qsfp0_tx_clk_2 = 0; -reg qsfp0_tx_rst_2 = 0; -reg qsfp0_rx_clk_2 = 0; -reg qsfp0_rx_rst_2 = 0; -reg [63:0] qsfp0_rxd_2 = 0; -reg [7:0] qsfp0_rxc_2 = 0; -reg qsfp0_tx_clk_3 = 0; -reg qsfp0_tx_rst_3 = 0; -reg qsfp0_rx_clk_3 = 0; -reg qsfp0_rx_rst_3 = 0; -reg [63:0] qsfp0_rxd_3 = 0; -reg [7:0] qsfp0_rxc_3 = 0; -reg qsfp0_tx_clk_4 = 0; -reg qsfp0_tx_rst_4 = 0; -reg qsfp0_rx_clk_4 = 0; -reg qsfp0_rx_rst_4 = 0; -reg [63:0] qsfp0_rxd_4 = 0; -reg [7:0] qsfp0_rxc_4 = 0; -reg qsfp0_modprsl = 1; -reg qsfp0_intl = 1; -reg qsfp1_tx_clk_1 = 0; -reg qsfp1_tx_rst_1 = 0; -reg qsfp1_rx_clk_1 = 0; -reg qsfp1_rx_rst_1 = 0; -reg [63:0] qsfp1_rxd_1 = 0; -reg [7:0] qsfp1_rxc_1 = 0; -reg qsfp1_tx_clk_2 = 0; -reg qsfp1_tx_rst_2 = 0; -reg qsfp1_rx_clk_2 = 0; -reg qsfp1_rx_rst_2 = 0; -reg [63:0] qsfp1_rxd_2 = 0; -reg [7:0] qsfp1_rxc_2 = 0; -reg qsfp1_tx_clk_3 = 0; -reg qsfp1_tx_rst_3 = 0; -reg qsfp1_rx_clk_3 = 0; -reg qsfp1_rx_rst_3 = 0; -reg [63:0] qsfp1_rxd_3 = 0; -reg [7:0] qsfp1_rxc_3 = 0; -reg qsfp1_tx_clk_4 = 0; -reg qsfp1_tx_rst_4 = 0; -reg qsfp1_rx_clk_4 = 0; -reg qsfp1_rx_rst_4 = 0; -reg [63:0] qsfp1_rxd_4 = 0; -reg [7:0] qsfp1_rxc_4 = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [2:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp0_txd_1; -wire [7:0] qsfp0_txc_1; -wire [63:0] qsfp0_txd_2; -wire [7:0] qsfp0_txc_2; -wire [63:0] qsfp0_txd_3; -wire [7:0] qsfp0_txc_3; -wire [63:0] qsfp0_txd_4; -wire [7:0] qsfp0_txc_4; -wire qsfp0_modsell; -wire qsfp0_resetl; -wire qsfp0_lpmode; -wire [63:0] qsfp1_txd_1; -wire [7:0] qsfp1_txc_1; -wire [63:0] qsfp1_txd_2; -wire [7:0] qsfp1_txc_2; -wire [63:0] qsfp1_txd_3; -wire [7:0] qsfp1_txc_3; -wire [63:0] qsfp1_txd_4; -wire [7:0] qsfp1_txc_4; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp0_tx_clk_1, - qsfp0_tx_rst_1, - qsfp0_rx_clk_1, - qsfp0_rx_rst_1, - qsfp0_rxd_1, - qsfp0_rxc_1, - qsfp0_tx_clk_2, - qsfp0_tx_rst_2, - qsfp0_rx_clk_2, - qsfp0_rx_rst_2, - qsfp0_rxd_2, - qsfp0_rxc_2, - qsfp0_tx_clk_3, - qsfp0_tx_rst_3, - qsfp0_rx_clk_3, - qsfp0_rx_rst_3, - qsfp0_rxd_3, - qsfp0_rxc_3, - qsfp0_tx_clk_4, - qsfp0_tx_rst_4, - qsfp0_rx_clk_4, - qsfp0_rx_rst_4, - qsfp0_rxd_4, - qsfp0_rxc_4, - qsfp0_modprsl, - qsfp0_intl, - qsfp1_tx_clk_1, - qsfp1_tx_rst_1, - qsfp1_rx_clk_1, - qsfp1_rx_rst_1, - qsfp1_rxd_1, - qsfp1_rxc_1, - qsfp1_tx_clk_2, - qsfp1_tx_rst_2, - qsfp1_rx_clk_2, - qsfp1_rx_rst_2, - qsfp1_rxd_2, - qsfp1_rxc_2, - qsfp1_tx_clk_3, - qsfp1_tx_rst_3, - qsfp1_rx_clk_3, - qsfp1_rx_rst_3, - qsfp1_rxd_3, - qsfp1_rxc_3, - qsfp1_tx_clk_4, - qsfp1_tx_rst_4, - qsfp1_rx_clk_4, - qsfp1_rx_rst_4, - qsfp1_rxd_4, - qsfp1_rxc_4, - qsfp1_modprsl, - qsfp1_intl, - qspi_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp0_txd_1, - qsfp0_txc_1, - qsfp0_txd_2, - qsfp0_txc_2, - qsfp0_txd_3, - qsfp0_txc_3, - qsfp0_txd_4, - qsfp0_txc_4, - qsfp0_modsell, - qsfp0_resetl, - qsfp0_lpmode, - qsfp1_txd_1, - qsfp1_txc_1, - qsfp1_txd_2, - qsfp1_txc_2, - qsfp1_txd_3, - qsfp1_txc_3, - qsfp1_txd_4, - qsfp1_txc_4, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp0_tx_clk_1(qsfp0_tx_clk_1), - .qsfp0_tx_rst_1(qsfp0_tx_rst_1), - .qsfp0_txd_1(qsfp0_txd_1), - .qsfp0_txc_1(qsfp0_txc_1), - .qsfp0_rx_clk_1(qsfp0_rx_clk_1), - .qsfp0_rx_rst_1(qsfp0_rx_rst_1), - .qsfp0_rxd_1(qsfp0_rxd_1), - .qsfp0_rxc_1(qsfp0_rxc_1), - .qsfp0_tx_clk_2(qsfp0_tx_clk_2), - .qsfp0_tx_rst_2(qsfp0_tx_rst_2), - .qsfp0_txd_2(qsfp0_txd_2), - .qsfp0_txc_2(qsfp0_txc_2), - .qsfp0_rx_clk_2(qsfp0_rx_clk_2), - .qsfp0_rx_rst_2(qsfp0_rx_rst_2), - .qsfp0_rxd_2(qsfp0_rxd_2), - .qsfp0_rxc_2(qsfp0_rxc_2), - .qsfp0_tx_clk_3(qsfp0_tx_clk_3), - .qsfp0_tx_rst_3(qsfp0_tx_rst_3), - .qsfp0_txd_3(qsfp0_txd_3), - .qsfp0_txc_3(qsfp0_txc_3), - .qsfp0_rx_clk_3(qsfp0_rx_clk_3), - .qsfp0_rx_rst_3(qsfp0_rx_rst_3), - .qsfp0_rxd_3(qsfp0_rxd_3), - .qsfp0_rxc_3(qsfp0_rxc_3), - .qsfp0_tx_clk_4(qsfp0_tx_clk_4), - .qsfp0_tx_rst_4(qsfp0_tx_rst_4), - .qsfp0_txd_4(qsfp0_txd_4), - .qsfp0_txc_4(qsfp0_txc_4), - .qsfp0_rx_clk_4(qsfp0_rx_clk_4), - .qsfp0_rx_rst_4(qsfp0_rx_rst_4), - .qsfp0_rxd_4(qsfp0_rxd_4), - .qsfp0_rxc_4(qsfp0_rxc_4), - .qsfp0_modprsl(qsfp0_modprsl_int), - .qsfp0_modsell(qsfp0_modsell), - .qsfp0_resetl(qsfp0_resetl), - .qsfp0_intl(qsfp0_intl_int), - .qsfp0_lpmode(qsfp0_lpmode_int), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1), - .qsfp1_txd_1(qsfp1_txd_1), - .qsfp1_txc_1(qsfp1_txc_1), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1), - .qsfp1_rxd_1(qsfp1_rxd_1), - .qsfp1_rxc_1(qsfp1_rxc_1), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2), - .qsfp1_txd_2(qsfp1_txd_2), - .qsfp1_txc_2(qsfp1_txc_2), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2), - .qsfp1_rxd_2(qsfp1_rxd_2), - .qsfp1_rxc_2(qsfp1_rxc_2), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3), - .qsfp1_txd_3(qsfp1_txd_3), - .qsfp1_txc_3(qsfp1_txc_3), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3), - .qsfp1_rxd_3(qsfp1_rxd_3), - .qsfp1_rxc_3(qsfp1_rxc_3), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4), - .qsfp1_txd_4(qsfp1_txd_4), - .qsfp1_txc_4(qsfp1_txc_4), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4), - .qsfp1_rxd_4(qsfp1_rxd_4), - .qsfp1_rxc_4(qsfp1_rxc_4), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/udp_ep.py b/fpga/mqnic/VCU1525/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/VCU1525/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/VCU1525/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/VCU1525/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/axis_ep.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/eth_ep.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/Makefile b/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/Makefile new file mode 100644 index 000000000..937430b13 --- /dev/null +++ b/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 128 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/mqnic.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..e48c08afe --- /dev/null +++ b/fpga/mqnic/ZCU106/fpga_pcie/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,564 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=4, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.sfp0_rx_clk, 6.4, units="ns").start()) + self.sfp0_source = XgmiiSource(dut.sfp0_rxd, dut.sfp0_rxc, dut.sfp0_rx_clk, dut.sfp0_rx_rst) + cocotb.fork(Clock(dut.sfp0_tx_clk, 6.4, units="ns").start()) + self.sfp0_sink = XgmiiSink(dut.sfp0_txd, dut.sfp0_txc, dut.sfp0_tx_clk, dut.sfp0_tx_rst) + + cocotb.fork(Clock(dut.sfp1_rx_clk, 6.4, units="ns").start()) + self.sfp1_source = XgmiiSource(dut.sfp1_rxd, dut.sfp1_rxc, dut.sfp1_rx_clk, dut.sfp1_rx_rst) + cocotb.fork(Clock(dut.sfp1_tx_clk, 6.4, units="ns").start()) + self.sfp1_sink = XgmiiSink(dut.sfp1_txd, dut.sfp1_txc, dut.sfp1_tx_clk, dut.sfp1_tx_rst) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.sfp0_rx_rst.setimmediatevalue(0) + self.dut.sfp0_tx_rst.setimmediatevalue(0) + self.dut.sfp1_rx_rst.setimmediatevalue(0) + self.dut.sfp1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp0_rx_rst.setimmediatevalue(1) + self.dut.sfp0_tx_rst.setimmediatevalue(1) + self.dut.sfp1_rx_rst.setimmediatevalue(1) + self.dut.sfp1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp0_rx_rst.setimmediatevalue(0) + self.dut.sfp0_tx_rst.setimmediatevalue(0) + self.dut.sfp1_rx_rst.setimmediatevalue(0) + self.dut.sfp1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.sfp0_sink.empty(): + self.sfp0_source.send(self.sfp0_sink.recv()) + if not self.sfp1_sink.empty(): + self.sfp1_source.send(self.sfp1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.sfp0_sink.wait() + + pkt = tb.sfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.sfp1_sink.wait() + + # pkt = tb.sfp1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.sfp1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.sfp0_sink.wait() + + pkt = tb.sfp0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 128 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/ip_ep.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/mqnic.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie_us.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie_usp.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/test_fpga_core.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/test_fpga_core.py deleted file mode 100755 index 0d020c52b..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/test_fpga_core.py +++ /dev/null @@ -1,825 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 128 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 62 - AXIS_PCIE_CQ_USER_WIDTH = 88 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[8:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - sfp0_tx_clk = Signal(bool(0)) - sfp0_tx_rst = Signal(bool(0)) - sfp0_rx_clk = Signal(bool(0)) - sfp0_rx_rst = Signal(bool(0)) - sfp0_rxd = Signal(intbv(0)[64:]) - sfp0_rxc = Signal(intbv(0)[8:]) - sfp1_tx_clk = Signal(bool(0)) - sfp1_tx_rst = Signal(bool(0)) - sfp1_rx_clk = Signal(bool(0)) - sfp1_rx_rst = Signal(bool(0)) - sfp1_rxd = Signal(intbv(0)[64:]) - sfp1_rxc = Signal(intbv(0)[8:]) - - # Outputs - led = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - sfp0_txd = Signal(intbv(0)[64:]) - sfp0_txc = Signal(intbv(0)[8:]) - sfp0_tx_disable_b = Signal(bool(0)) - sfp1_txd = Signal(intbv(0)[64:]) - sfp1_txc = Signal(intbv(0)[8:]) - sfp1_tx_disable_b = Signal(bool(0)) - - # sources and sinks - sfp0_source = xgmii_ep.XGMIISource() - sfp0_source_logic = sfp0_source.create_logic(sfp0_rx_clk, sfp0_rx_rst, txd=sfp0_rxd, txc=sfp0_rxc, name='sfp0_source') - - sfp0_sink = xgmii_ep.XGMIISink() - sfp0_sink_logic = sfp0_sink.create_logic(sfp0_tx_clk, sfp0_tx_rst, rxd=sfp0_txd, rxc=sfp0_txc, name='sfp0_sink') - - sfp1_source = xgmii_ep.XGMIISource() - sfp1_source_logic = sfp1_source.create_logic(sfp1_rx_clk, sfp1_rx_rst, txd=sfp1_rxd, txc=sfp1_rxc, name='sfp1_source') - - sfp1_sink = xgmii_ep.XGMIISink() - sfp1_sink_logic = sfp1_sink.create_logic(sfp1_tx_clk, sfp1_tx_rst, rxd=sfp1_txd, rxc=sfp1_txc, name='sfp1_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 4 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - sfp0_tx_clk=sfp0_tx_clk, - sfp0_tx_rst=sfp0_tx_rst, - sfp0_txd=sfp0_txd, - sfp0_txc=sfp0_txc, - sfp0_rx_clk=sfp0_rx_clk, - sfp0_rx_rst=sfp0_rx_rst, - sfp0_rxd=sfp0_rxd, - sfp0_rxc=sfp0_rxc, - sfp0_tx_disable_b=sfp0_tx_disable_b, - sfp1_tx_clk=sfp1_tx_clk, - sfp1_tx_rst=sfp1_tx_rst, - sfp1_txd=sfp1_txd, - sfp1_txc=sfp1_txc, - sfp1_rx_clk=sfp1_rx_clk, - sfp1_rx_rst=sfp1_rx_rst, - sfp1_rxd=sfp1_rxd, - sfp1_rxc=sfp1_rxc, - sfp1_tx_disable_b=sfp1_tx_disable_b - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - sfp0_tx_clk.next = not sfp0_tx_clk - sfp0_rx_clk.next = not sfp0_rx_clk - sfp1_tx_clk.next = not sfp1_tx_clk - sfp1_rx_clk.next = not sfp1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not sfp0_sink.empty(): - pkt = sfp0_sink.recv() - sfp0_source.send(pkt) - if not sfp1_sink.empty(): - pkt = sfp1_sink.recv() - sfp1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - sfp0_tx_rst.next = 1 - sfp0_rx_rst.next = 1 - sfp1_tx_rst.next = 1 - sfp1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - sfp0_tx_rst.next = 0 - sfp0_rx_rst.next = 0 - sfp1_tx_rst.next = 0 - sfp1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #sfp0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield sfp0_sink.wait() - - pkt = sfp0_sink.recv() - print(pkt) - - sfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield sfp0_sink.wait() - - # pkt = sfp0_sink.recv() - # print(pkt) - - # sfp0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield sfp0_sink.wait() - - pkt = sfp0_sink.recv() - print(pkt) - - sfp0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/test_fpga_core.v b/fpga/mqnic/ZCU106/fpga_pcie/tb/test_fpga_core.v deleted file mode 100644 index dac1f528e..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/test_fpga_core.v +++ /dev/null @@ -1,381 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 128; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 62; -parameter AXIS_PCIE_CQ_USER_WIDTH = 88; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg btnu = 0; -reg btnl = 0; -reg btnd = 0; -reg btnr = 0; -reg btnc = 0; -reg [7:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg sfp0_tx_clk = 0; -reg sfp0_tx_rst = 0; -reg sfp0_rx_clk = 0; -reg sfp0_rx_rst = 0; -reg [63:0] sfp0_rxd = 0; -reg [7:0] sfp0_rxc = 0; -reg sfp1_tx_clk = 0; -reg sfp1_tx_rst = 0; -reg sfp1_rx_clk = 0; -reg sfp1_rx_rst = 0; -reg [63:0] sfp1_rxd = 0; -reg [7:0] sfp1_rxc = 0; - -// Outputs -wire [7:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] sfp0_txd; -wire [7:0] sfp0_txc; -wire sfp0_tx_disable_b; -wire [63:0] sfp1_txd; -wire [7:0] sfp1_txc; -wire sfp1_tx_disable_b; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - sfp0_tx_clk, - sfp0_tx_rst, - sfp0_rx_clk, - sfp0_rx_rst, - sfp0_rxd, - sfp0_rxc, - sfp1_tx_clk, - sfp1_tx_rst, - sfp1_rx_clk, - sfp1_rx_rst, - sfp1_rxd, - sfp1_rxc - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - sfp0_txd, - sfp0_txc, - sfp0_tx_disable_b, - sfp1_txd, - sfp1_txc, - sfp1_tx_disable_b - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btnu(btnu), - .btnl(btnl), - .btnd(btnd), - .btnr(btnr), - .btnc(btnc), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .sfp0_tx_clk(sfp0_tx_clk), - .sfp0_tx_rst(sfp0_tx_rst), - .sfp0_txd(sfp0_txd), - .sfp0_txc(sfp0_txc), - .sfp0_rx_clk(sfp0_rx_clk), - .sfp0_rx_rst(sfp0_rx_rst), - .sfp0_rxd(sfp0_rxd), - .sfp0_rxc(sfp0_rxc), - .sfp0_tx_disable_b(sfp0_tx_disable_b), - .sfp1_tx_clk(sfp1_tx_clk), - .sfp1_tx_rst(sfp1_tx_rst), - .sfp1_txd(sfp1_txd), - .sfp1_txc(sfp1_txc), - .sfp1_rx_clk(sfp1_rx_clk), - .sfp1_rx_rst(sfp1_rx_rst), - .sfp1_rxd(sfp1_rxd), - .sfp1_rxc(sfp1_rxc), - .sfp1_tx_disable_b(sfp1_tx_disable_b) -); - -endmodule diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/udp_ep.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/ZCU106/fpga_pcie/tb/xgmii_ep.py b/fpga/mqnic/ZCU106/fpga_pcie/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/ZCU106/fpga_pcie/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/axis_ep.py b/fpga/mqnic/fb2CG/fpga_100g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/eth_ep.py b/fpga/mqnic/fb2CG/fpga_100g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile new file mode 100644 index 000000000..1b6b1b200 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 +export PARAM_AXIS_ETH_DATA_WIDTH = 512 +export PARAM_AXIS_ETH_KEEP_WIDTH = $(shell expr $(PARAM_AXIS_ETH_DATA_WIDTH) / 8 ) + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + COMPILE_ARGS += -GAXIS_ETH_DATA_WIDTH=$(PARAM_AXIS_ETH_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_ETH_KEEP_WIDTH=$(PARAM_AXIS_ETH_KEEP_WIDTH) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/mqnic.py b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..755484992 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_100g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,586 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.axi import AxiStreamSource, AxiStreamSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk, 3.102, units="ns").start()) + self.qsfp_0_source = AxiStreamSource(dut, "qsfp_0_rx_axis", dut.qsfp_0_rx_clk, dut.qsfp_0_rx_rst) + cocotb.fork(Clock(dut.qsfp_0_tx_clk, 3.102, units="ns").start()) + self.qsfp_0_sink = AxiStreamSink(dut, "qsfp_0_tx_axis", dut.qsfp_0_tx_clk, dut.qsfp_0_tx_rst) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk, 3.102, units="ns").start()) + self.qsfp_1_source = AxiStreamSource(dut, "qsfp_1_rx_axis", dut.qsfp_1_rx_clk, dut.qsfp_1_rx_rst) + cocotb.fork(Clock(dut.qsfp_1_tx_clk, 3.102, units="ns").start()) + self.qsfp_1_sink = AxiStreamSink(dut, "qsfp_1_tx_axis", dut.qsfp_1_tx_clk, dut.qsfp_1_tx_rst) + + dut.qsfp_0_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_0_i2c_sda_i.setimmediatevalue(1) + dut.qsfp_0_intr_n.setimmediatevalue(1) + dut.qsfp_0_mod_prsnt_n.setimmediatevalue(0) + + dut.qsfp_1_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_1_i2c_sda_i.setimmediatevalue(1) + dut.qsfp_1_intr_n.setimmediatevalue(1) + dut.qsfp_1_mod_prsnt_n.setimmediatevalue(0) + + dut.qspi_dq_i.setimmediatevalue(0) + + dut.pps_in.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_sink.empty(): + self.qsfp_0_source.send(self.qsfp_0_sink.recv()) + if not self.qsfp_1_sink.empty(): + self.qsfp_1_source.send(self.qsfp_1_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_sink.wait() + + pkt = tb.qsfp_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_sink.wait() + + pkt = tb.qsfp_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Jumbo frames") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(9014)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + parameters['AXIS_ETH_DATA_WIDTH'] = 512 + parameters['AXIS_ETH_KEEP_WIDTH'] = parameters['AXIS_ETH_DATA_WIDTH'] // 8 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/ip_ep.py b/fpga/mqnic/fb2CG/fpga_100g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/mqnic.py b/fpga/mqnic/fb2CG/fpga_100g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/pcie.py b/fpga/mqnic/fb2CG/fpga_100g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/pcie_us.py b/fpga/mqnic/fb2CG/fpga_100g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/pcie_usp.py b/fpga/mqnic/fb2CG/fpga_100g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_100g/tb/test_fpga_core.py deleted file mode 100755 index 7b5dcaffb..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/test_fpga_core.py +++ /dev/null @@ -1,957 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - AXIS_ETH_DATA_WIDTH = 512 - AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - pps_in = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk = Signal(bool(0)) - qsfp_0_tx_rst = Signal(bool(0)) - qsfp_0_rx_clk = Signal(bool(0)) - qsfp_0_rx_rst = Signal(bool(0)) - qsfp_0_tx_axis_tready = Signal(bool(0)) - qsfp_0_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_0_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_0_rx_axis_tvalid = Signal(bool(0)) - qsfp_0_rx_axis_tlast = Signal(bool(0)) - qsfp_0_rx_axis_tuser = Signal(bool(0)) - qsfp_0_mod_prsnt_n = Signal(bool(0)) - qsfp_0_intr_n = Signal(bool(0)) - qsfp_0_i2c_scl_i = Signal(bool(0)) - qsfp_0_i2c_sda_i = Signal(bool(0)) - qsfp_1_tx_clk = Signal(bool(0)) - qsfp_1_tx_rst = Signal(bool(0)) - qsfp_1_rx_clk = Signal(bool(0)) - qsfp_1_rx_rst = Signal(bool(0)) - qsfp_1_tx_axis_tready = Signal(bool(0)) - qsfp_1_rx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_1_rx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_1_rx_axis_tvalid = Signal(bool(0)) - qsfp_1_rx_axis_tlast = Signal(bool(0)) - qsfp_1_rx_axis_tuser = Signal(bool(0)) - qsfp_1_mod_prsnt_n = Signal(bool(0)) - qsfp_1_intr_n = Signal(bool(0)) - qsfp_1_i2c_scl_i = Signal(bool(0)) - qsfp_1_i2c_sda_i = Signal(bool(0)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led_red = Signal(intbv(0)[7:]) - led_green = Signal(intbv(0)[7:]) - led_bmc = Signal(intbv(0)[2:]) - led_exp = Signal(intbv(0)[2:]) - pps_out = Signal(bool(0)) - pps_out_en = Signal(bool(0)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_0_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_0_tx_axis_tvalid = Signal(bool(0)) - qsfp_0_tx_axis_tlast = Signal(bool(0)) - qsfp_0_tx_axis_tuser = Signal(bool(0)) - qsfp_0_reset_n = Signal(bool(0)) - qsfp_0_lp_mode = Signal(bool(0)) - qsfp_0_i2c_scl_o = Signal(bool(1)) - qsfp_0_i2c_scl_t = Signal(bool(1)) - qsfp_0_i2c_sda_o = Signal(bool(1)) - qsfp_0_i2c_sda_t = Signal(bool(1)) - qsfp_1_tx_axis_tdata = Signal(intbv(0)[AXIS_ETH_DATA_WIDTH:]) - qsfp_1_tx_axis_tkeep = Signal(intbv(0)[AXIS_ETH_KEEP_WIDTH:]) - qsfp_1_tx_axis_tvalid = Signal(bool(0)) - qsfp_1_tx_axis_tlast = Signal(bool(0)) - qsfp_1_tx_axis_tuser = Signal(bool(0)) - qsfp_1_reset_n = Signal(bool(0)) - qsfp_1_lp_mode = Signal(bool(0)) - qsfp_1_i2c_scl_o = Signal(bool(1)) - qsfp_1_i2c_scl_t = Signal(bool(1)) - qsfp_1_i2c_sda_o = Signal(bool(1)) - qsfp_1_i2c_sda_t = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp_0_source = axis_ep.AXIStreamSource() - qsfp_0_source_pause = Signal(bool(False)) - - qsfp_0_source_logic = qsfp_0_source.create_logic( - qsfp_0_rx_clk, - qsfp_0_rx_rst, - tdata=qsfp_0_rx_axis_tdata, - tkeep=qsfp_0_rx_axis_tkeep, - tvalid=qsfp_0_rx_axis_tvalid, - tlast=qsfp_0_rx_axis_tlast, - tuser=qsfp_0_rx_axis_tuser, - pause=qsfp_0_source_pause, - name='qsfp_0_source' - ) - - qsfp_0_sink = axis_ep.AXIStreamSink() - qsfp_0_sink_pause = Signal(bool(False)) - - qsfp_0_sink_logic = qsfp_0_sink.create_logic( - qsfp_0_tx_clk, - qsfp_0_tx_rst, - tdata=qsfp_0_tx_axis_tdata, - tkeep=qsfp_0_tx_axis_tkeep, - tvalid=qsfp_0_tx_axis_tvalid, - tready=qsfp_0_tx_axis_tready, - tlast=qsfp_0_tx_axis_tlast, - tuser=qsfp_0_tx_axis_tuser, - pause=qsfp_0_sink_pause, - name='qsfp_0_sink' - ) - - qsfp_1_source = axis_ep.AXIStreamSource() - qsfp_1_source_pause = Signal(bool(False)) - - qsfp_1_source_logic = qsfp_1_source.create_logic( - qsfp_1_rx_clk, - qsfp_1_rx_rst, - tdata=qsfp_1_rx_axis_tdata, - tkeep=qsfp_1_rx_axis_tkeep, - tvalid=qsfp_1_rx_axis_tvalid, - tlast=qsfp_1_rx_axis_tlast, - tuser=qsfp_1_rx_axis_tuser, - pause=qsfp_1_source_pause, - name='qsfp_1_source' - ) - - qsfp_1_sink = axis_ep.AXIStreamSink() - qsfp_1_sink_pause = Signal(bool(False)) - - qsfp_1_sink_logic = qsfp_1_sink.create_logic( - qsfp_1_tx_clk, - qsfp_1_tx_rst, - tdata=qsfp_1_tx_axis_tdata, - tkeep=qsfp_1_tx_axis_tkeep, - tvalid=qsfp_1_tx_axis_tvalid, - tready=qsfp_1_tx_axis_tready, - tlast=qsfp_1_tx_axis_tlast, - tuser=qsfp_1_tx_axis_tuser, - pause=qsfp_1_sink_pause, - name='qsfp_1_sink' - ) - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - led_red=led_red, - led_green=led_green, - led_bmc=led_bmc, - led_exp=led_exp, - pps_in=pps_in, - pps_out=pps_out, - pps_out_en=pps_out_en, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk=qsfp_0_tx_clk, - qsfp_0_tx_rst=qsfp_0_tx_rst, - qsfp_0_tx_axis_tdata=qsfp_0_tx_axis_tdata, - qsfp_0_tx_axis_tkeep=qsfp_0_tx_axis_tkeep, - qsfp_0_tx_axis_tvalid=qsfp_0_tx_axis_tvalid, - qsfp_0_tx_axis_tready=qsfp_0_tx_axis_tready, - qsfp_0_tx_axis_tlast=qsfp_0_tx_axis_tlast, - qsfp_0_tx_axis_tuser=qsfp_0_tx_axis_tuser, - qsfp_0_rx_clk=qsfp_0_rx_clk, - qsfp_0_rx_rst=qsfp_0_rx_rst, - qsfp_0_rx_axis_tdata=qsfp_0_rx_axis_tdata, - qsfp_0_rx_axis_tkeep=qsfp_0_rx_axis_tkeep, - qsfp_0_rx_axis_tvalid=qsfp_0_rx_axis_tvalid, - qsfp_0_rx_axis_tlast=qsfp_0_rx_axis_tlast, - qsfp_0_rx_axis_tuser=qsfp_0_rx_axis_tuser, - qsfp_0_mod_prsnt_n=qsfp_0_mod_prsnt_n, - qsfp_0_reset_n=qsfp_0_reset_n, - qsfp_0_lp_mode=qsfp_0_lp_mode, - qsfp_0_intr_n=qsfp_0_intr_n, - qsfp_0_i2c_scl_i=qsfp_0_i2c_scl_i, - qsfp_0_i2c_scl_o=qsfp_0_i2c_scl_o, - qsfp_0_i2c_scl_t=qsfp_0_i2c_scl_t, - qsfp_0_i2c_sda_i=qsfp_0_i2c_sda_i, - qsfp_0_i2c_sda_o=qsfp_0_i2c_sda_o, - qsfp_0_i2c_sda_t=qsfp_0_i2c_sda_t, - qsfp_1_tx_clk=qsfp_1_tx_clk, - qsfp_1_tx_rst=qsfp_1_tx_rst, - qsfp_1_tx_axis_tdata=qsfp_1_tx_axis_tdata, - qsfp_1_tx_axis_tkeep=qsfp_1_tx_axis_tkeep, - qsfp_1_tx_axis_tvalid=qsfp_1_tx_axis_tvalid, - qsfp_1_tx_axis_tready=qsfp_1_tx_axis_tready, - qsfp_1_tx_axis_tlast=qsfp_1_tx_axis_tlast, - qsfp_1_tx_axis_tuser=qsfp_1_tx_axis_tuser, - qsfp_1_rx_clk=qsfp_1_rx_clk, - qsfp_1_rx_rst=qsfp_1_rx_rst, - qsfp_1_rx_axis_tdata=qsfp_1_rx_axis_tdata, - qsfp_1_rx_axis_tkeep=qsfp_1_rx_axis_tkeep, - qsfp_1_rx_axis_tvalid=qsfp_1_rx_axis_tvalid, - qsfp_1_rx_axis_tlast=qsfp_1_rx_axis_tlast, - qsfp_1_rx_axis_tuser=qsfp_1_rx_axis_tuser, - qsfp_1_mod_prsnt_n=qsfp_1_mod_prsnt_n, - qsfp_1_reset_n=qsfp_1_reset_n, - qsfp_1_lp_mode=qsfp_1_lp_mode, - qsfp_1_intr_n=qsfp_1_intr_n, - qsfp_1_i2c_scl_i=qsfp_1_i2c_scl_i, - qsfp_1_i2c_scl_o=qsfp_1_i2c_scl_o, - qsfp_1_i2c_scl_t=qsfp_1_i2c_scl_t, - qsfp_1_i2c_sda_i=qsfp_1_i2c_sda_i, - qsfp_1_i2c_sda_o=qsfp_1_i2c_sda_o, - qsfp_1_i2c_sda_t=qsfp_1_i2c_sda_t, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(2)) - def qsfp_clkgen(): - qsfp_0_tx_clk.next = not qsfp_0_tx_clk - qsfp_0_rx_clk.next = not qsfp_0_rx_clk - qsfp_1_tx_clk.next = not qsfp_1_tx_clk - qsfp_1_rx_clk.next = not qsfp_1_rx_clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_sink.empty(): - pkt = qsfp_0_sink.recv() - qsfp_0_source.send(pkt) - if not qsfp_1_sink.empty(): - pkt = qsfp_1_sink.recv() - qsfp_1_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst.next = 1 - qsfp_0_rx_rst.next = 1 - qsfp_1_tx_rst.next = 1 - qsfp_1_rx_rst.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst.next = 0 - qsfp_0_rx_rst.next = 0 - qsfp_1_tx_rst.next = 0 - qsfp_1_rx_rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_sink.wait() - - pkt = qsfp_0_sink.recv() - print(pkt) - - qsfp_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_sink.wait() - - # pkt = qsfp_1_sink.recv() - # print(pkt) - - # qsfp_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_sink.wait() - - pkt = qsfp_0_sink.recv() - print(pkt) - - qsfp_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 7: jumbo frames") - current_test.next = 7 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(9014)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/test_fpga_core.v b/fpga/mqnic/fb2CG/fpga_100g/tb/test_fpga_core.v deleted file mode 100644 index 5c970e104..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/test_fpga_core.v +++ /dev/null @@ -1,481 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; -parameter AXIS_ETH_DATA_WIDTH = 512; -parameter AXIS_ETH_KEEP_WIDTH = AXIS_ETH_DATA_WIDTH/8; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg pps_in = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk = 0; -reg qsfp_0_tx_rst = 0; -reg qsfp_0_tx_axis_tready = 0; -reg qsfp_0_rx_clk = 0; -reg qsfp_0_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp_0_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_0_rx_axis_tkeep = 0; -reg qsfp_0_rx_axis_tvalid = 0; -reg qsfp_0_rx_axis_tlast = 0; -reg qsfp_0_rx_axis_tuser = 0; -reg qsfp_0_mod_prsnt_n = 0; -reg qsfp_0_intr_n = 0; -reg qsfp_0_i2c_scl_i = 1; -reg qsfp_0_i2c_sda_i = 1; -reg qsfp_1_tx_clk = 0; -reg qsfp_1_tx_rst = 0; -reg qsfp_1_tx_axis_tready = 0; -reg qsfp_1_rx_clk = 0; -reg qsfp_1_rx_rst = 0; -reg [AXIS_ETH_DATA_WIDTH-1:0] qsfp_1_rx_axis_tdata = 0; -reg [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_1_rx_axis_tkeep = 0; -reg qsfp_1_rx_axis_tvalid = 0; -reg qsfp_1_rx_axis_tlast = 0; -reg qsfp_1_rx_axis_tuser = 0; -reg qsfp_1_mod_prsnt_n = 0; -reg qsfp_1_intr_n = 0; -reg qsfp_1_i2c_scl_i = 1; -reg qsfp_1_i2c_sda_i = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [7:0] led_red; -wire [7:0] led_green; -wire [1:0] led_bmc; -wire [1:0] led_exp; -wire pps_out; -wire pps_out_en; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp_0_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_0_tx_axis_tkeep; -wire qsfp_0_tx_axis_tvalid; -wire qsfp_0_tx_axis_tlast; -wire qsfp_0_tx_axis_tuser; -wire qsfp_0_reset_n; -wire qsfp_0_lp_mode; -wire qsfp_0_i2c_scl_o; -wire qsfp_0_i2c_scl_t; -wire qsfp_0_i2c_sda_o; -wire qsfp_0_i2c_sda_t; -wire [AXIS_ETH_DATA_WIDTH-1:0] qsfp_1_tx_axis_tdata; -wire [AXIS_ETH_KEEP_WIDTH-1:0] qsfp_1_tx_axis_tkeep; -wire qsfp_1_tx_axis_tvalid; -wire qsfp_1_tx_axis_tlast; -wire qsfp_1_tx_axis_tuser; -wire qsfp_1_reset_n; -wire qsfp_1_lp_mode; -wire qsfp_1_i2c_scl_o; -wire qsfp_1_i2c_scl_t; -wire qsfp_1_i2c_sda_o; -wire qsfp_1_i2c_sda_t; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - pps_in, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk, - qsfp_0_tx_rst, - qsfp_0_tx_axis_tready, - qsfp_0_rx_clk, - qsfp_0_rx_rst, - qsfp_0_rx_axis_tdata, - qsfp_0_rx_axis_tkeep, - qsfp_0_rx_axis_tvalid, - qsfp_0_rx_axis_tlast, - qsfp_0_rx_axis_tuser, - qsfp_0_mod_prsnt_n, - qsfp_0_intr_n, - qsfp_0_i2c_scl_i, - qsfp_0_i2c_sda_i, - qsfp_1_tx_clk, - qsfp_1_tx_rst, - qsfp_1_tx_axis_tready, - qsfp_1_rx_clk, - qsfp_1_rx_rst, - qsfp_1_rx_axis_tdata, - qsfp_1_rx_axis_tkeep, - qsfp_1_rx_axis_tvalid, - qsfp_1_rx_axis_tlast, - qsfp_1_rx_axis_tuser, - qsfp_1_mod_prsnt_n, - qsfp_1_intr_n, - qsfp_1_i2c_scl_i, - qsfp_1_i2c_sda_i, - qspi_dq_i - ); - $to_myhdl( - led_red, - led_green, - led_bmc, - led_exp, - pps_out, - pps_out_en, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_tx_axis_tdata, - qsfp_0_tx_axis_tkeep, - qsfp_0_tx_axis_tvalid, - qsfp_0_tx_axis_tlast, - qsfp_0_tx_axis_tuser, - qsfp_0_reset_n, - qsfp_0_lp_mode, - qsfp_0_i2c_scl_o, - qsfp_0_i2c_scl_t, - qsfp_0_i2c_sda_o, - qsfp_0_i2c_sda_t, - qsfp_1_tx_axis_tdata, - qsfp_1_tx_axis_tkeep, - qsfp_1_tx_axis_tvalid, - qsfp_1_tx_axis_tlast, - qsfp_1_tx_axis_tuser, - qsfp_1_reset_n, - qsfp_1_lp_mode, - qsfp_1_i2c_scl_o, - qsfp_1_i2c_scl_t, - qsfp_1_i2c_sda_o, - qsfp_1_i2c_sda_t, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE), - .AXIS_ETH_DATA_WIDTH(AXIS_ETH_DATA_WIDTH), - .AXIS_ETH_KEEP_WIDTH(AXIS_ETH_KEEP_WIDTH) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .led_red(led_red), - .led_green(led_green), - .led_bmc(led_bmc), - .led_exp(led_exp), - .pps_in(pps_in), - .pps_out(pps_out), - .pps_out_en(pps_out_en), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk(qsfp_0_tx_clk), - .qsfp_0_tx_rst(qsfp_0_tx_rst), - .qsfp_0_tx_axis_tdata(qsfp_0_tx_axis_tdata), - .qsfp_0_tx_axis_tkeep(qsfp_0_tx_axis_tkeep), - .qsfp_0_tx_axis_tvalid(qsfp_0_tx_axis_tvalid), - .qsfp_0_tx_axis_tready(qsfp_0_tx_axis_tready), - .qsfp_0_tx_axis_tlast(qsfp_0_tx_axis_tlast), - .qsfp_0_tx_axis_tuser(qsfp_0_tx_axis_tuser), - .qsfp_0_rx_clk(qsfp_0_rx_clk), - .qsfp_0_rx_rst(qsfp_0_rx_rst), - .qsfp_0_rx_axis_tdata(qsfp_0_rx_axis_tdata), - .qsfp_0_rx_axis_tkeep(qsfp_0_rx_axis_tkeep), - .qsfp_0_rx_axis_tvalid(qsfp_0_rx_axis_tvalid), - .qsfp_0_rx_axis_tlast(qsfp_0_rx_axis_tlast), - .qsfp_0_rx_axis_tuser(qsfp_0_rx_axis_tuser), - .qsfp_0_mod_prsnt_n(qsfp_0_mod_prsnt_n), - .qsfp_0_reset_n(qsfp_0_reset_n), - .qsfp_0_lp_mode(qsfp_0_lp_mode), - .qsfp_0_intr_n(qsfp_0_intr_n), - .qsfp_0_i2c_scl_i(qsfp_0_i2c_scl_i), - .qsfp_0_i2c_scl_o(qsfp_0_i2c_scl_o), - .qsfp_0_i2c_scl_t(qsfp_0_i2c_scl_t), - .qsfp_0_i2c_sda_i(qsfp_0_i2c_sda_i), - .qsfp_0_i2c_sda_o(qsfp_0_i2c_sda_o), - .qsfp_0_i2c_sda_t(qsfp_0_i2c_sda_t), - .qsfp_1_tx_clk(qsfp_1_tx_clk), - .qsfp_1_tx_rst(qsfp_1_tx_rst), - .qsfp_1_tx_axis_tdata(qsfp_1_tx_axis_tdata), - .qsfp_1_tx_axis_tkeep(qsfp_1_tx_axis_tkeep), - .qsfp_1_tx_axis_tvalid(qsfp_1_tx_axis_tvalid), - .qsfp_1_tx_axis_tready(qsfp_1_tx_axis_tready), - .qsfp_1_tx_axis_tlast(qsfp_1_tx_axis_tlast), - .qsfp_1_tx_axis_tuser(qsfp_1_tx_axis_tuser), - .qsfp_1_rx_clk(qsfp_1_rx_clk), - .qsfp_1_rx_rst(qsfp_1_rx_rst), - .qsfp_1_rx_axis_tdata(qsfp_1_rx_axis_tdata), - .qsfp_1_rx_axis_tkeep(qsfp_1_rx_axis_tkeep), - .qsfp_1_rx_axis_tvalid(qsfp_1_rx_axis_tvalid), - .qsfp_1_rx_axis_tlast(qsfp_1_rx_axis_tlast), - .qsfp_1_rx_axis_tuser(qsfp_1_rx_axis_tuser), - .qsfp_1_mod_prsnt_n(qsfp_1_mod_prsnt_n), - .qsfp_1_reset_n(qsfp_1_reset_n), - .qsfp_1_lp_mode(qsfp_1_lp_mode), - .qsfp_1_intr_n(qsfp_1_intr_n), - .qsfp_1_i2c_scl_i(qsfp_1_i2c_scl_i), - .qsfp_1_i2c_scl_o(qsfp_1_i2c_scl_o), - .qsfp_1_i2c_scl_t(qsfp_1_i2c_scl_t), - .qsfp_1_i2c_sda_i(qsfp_1_i2c_sda_i), - .qsfp_1_i2c_sda_o(qsfp_1_i2c_sda_o), - .qsfp_1_i2c_sda_t(qsfp_1_i2c_sda_t), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/fb2CG/fpga_100g/tb/udp_ep.py b/fpga/mqnic/fb2CG/fpga_100g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/fb2CG/fpga_100g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/axis_ep.py b/fpga/mqnic/fb2CG/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/eth_ep.py b/fpga/mqnic/fb2CG/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..bde8058a9 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,656 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk_0, 6.4, units="ns").start()) + self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_0, 6.4, units="ns").start()) + self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_0, 6.4, units="ns").start()) + self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_0, 6.4, units="ns").start()) + self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3) + + dut.qsfp_0_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_0_i2c_sda_i.setimmediatevalue(1) + dut.qsfp_0_intr_n.setimmediatevalue(1) + dut.qsfp_0_mod_prsnt_n.setimmediatevalue(0) + + dut.qsfp_0_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_1_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_1_i2c_sda_i.setimmediatevalue(1) + dut.qsfp_1_intr_n.setimmediatevalue(1) + dut.qsfp_1_mod_prsnt_n.setimmediatevalue(0) + + dut.qsfp_1_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_3.setimmediatevalue(0) + + dut.qspi_dq_i.setimmediatevalue(0) + + dut.pps_in.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_0_sink.empty(): + self.qsfp_0_0_source.send(self.qsfp_0_0_sink.recv()) + if not self.qsfp_0_1_sink.empty(): + self.qsfp_0_1_source.send(self.qsfp_0_1_sink.recv()) + if not self.qsfp_0_2_sink.empty(): + self.qsfp_0_2_source.send(self.qsfp_0_2_sink.recv()) + if not self.qsfp_0_3_sink.empty(): + self.qsfp_0_3_source.send(self.qsfp_0_3_sink.recv()) + if not self.qsfp_1_0_sink.empty(): + self.qsfp_1_0_source.send(self.qsfp_1_0_sink.recv()) + if not self.qsfp_1_1_sink.empty(): + self.qsfp_1_1_source.send(self.qsfp_1_1_sink.recv()) + if not self.qsfp_1_2_sink.empty(): + self.qsfp_1_2_source.send(self.qsfp_1_2_sink.recv()) + if not self.qsfp_1_3_sink.empty(): + self.qsfp_1_3_source.send(self.qsfp_1_3_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/ip_ep.py b/fpga/mqnic/fb2CG/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/mqnic.py b/fpga/mqnic/fb2CG/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/pcie.py b/fpga/mqnic/fb2CG/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/pcie_us.py b/fpga/mqnic/fb2CG/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/pcie_usp.py b/fpga/mqnic/fb2CG/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index deaee3974..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1047 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - pps_in = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk_0 = Signal(bool(0)) - qsfp_0_tx_rst_0 = Signal(bool(0)) - qsfp_0_rx_clk_0 = Signal(bool(0)) - qsfp_0_rx_rst_0 = Signal(bool(0)) - qsfp_0_rxd_0 = Signal(intbv(0)[64:]) - qsfp_0_rxc_0 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_1 = Signal(bool(0)) - qsfp_0_tx_rst_1 = Signal(bool(0)) - qsfp_0_rx_clk_1 = Signal(bool(0)) - qsfp_0_rx_rst_1 = Signal(bool(0)) - qsfp_0_rxd_1 = Signal(intbv(0)[64:]) - qsfp_0_rxc_1 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_2 = Signal(bool(0)) - qsfp_0_tx_rst_2 = Signal(bool(0)) - qsfp_0_rx_clk_2 = Signal(bool(0)) - qsfp_0_rx_rst_2 = Signal(bool(0)) - qsfp_0_rxd_2 = Signal(intbv(0)[64:]) - qsfp_0_rxc_2 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_3 = Signal(bool(0)) - qsfp_0_tx_rst_3 = Signal(bool(0)) - qsfp_0_rx_clk_3 = Signal(bool(0)) - qsfp_0_rx_rst_3 = Signal(bool(0)) - qsfp_0_rxd_3 = Signal(intbv(0)[64:]) - qsfp_0_rxc_3 = Signal(intbv(0)[8:]) - qsfp_0_mod_prsnt_n = Signal(bool(0)) - qsfp_0_intr_n = Signal(bool(0)) - qsfp_0_i2c_scl_i = Signal(bool(0)) - qsfp_0_i2c_sda_i = Signal(bool(0)) - qsfp_1_tx_clk_0 = Signal(bool(0)) - qsfp_1_tx_rst_0 = Signal(bool(0)) - qsfp_1_rx_clk_0 = Signal(bool(0)) - qsfp_1_rx_rst_0 = Signal(bool(0)) - qsfp_1_rxd_0 = Signal(intbv(0)[64:]) - qsfp_1_rxc_0 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_1 = Signal(bool(0)) - qsfp_1_tx_rst_1 = Signal(bool(0)) - qsfp_1_rx_clk_1 = Signal(bool(0)) - qsfp_1_rx_rst_1 = Signal(bool(0)) - qsfp_1_rxd_1 = Signal(intbv(0)[64:]) - qsfp_1_rxc_1 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_2 = Signal(bool(0)) - qsfp_1_tx_rst_2 = Signal(bool(0)) - qsfp_1_rx_clk_2 = Signal(bool(0)) - qsfp_1_rx_rst_2 = Signal(bool(0)) - qsfp_1_rxd_2 = Signal(intbv(0)[64:]) - qsfp_1_rxc_2 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_3 = Signal(bool(0)) - qsfp_1_tx_rst_3 = Signal(bool(0)) - qsfp_1_rx_clk_3 = Signal(bool(0)) - qsfp_1_rx_rst_3 = Signal(bool(0)) - qsfp_1_rxd_3 = Signal(intbv(0)[64:]) - qsfp_1_rxc_3 = Signal(intbv(0)[8:]) - qsfp_1_mod_prsnt_n = Signal(bool(0)) - qsfp_1_intr_n = Signal(bool(0)) - qsfp_1_i2c_scl_i = Signal(bool(0)) - qsfp_1_i2c_sda_i = Signal(bool(0)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led_red = Signal(intbv(0)[7:]) - led_green = Signal(intbv(0)[7:]) - led_bmc = Signal(intbv(0)[2:]) - led_exp = Signal(intbv(0)[2:]) - pps_out = Signal(bool(0)) - pps_out_en = Signal(bool(0)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_txd_0 = Signal(intbv(0)[64:]) - qsfp_0_txc_0 = Signal(intbv(0)[8:]) - qsfp_0_txd_1 = Signal(intbv(0)[64:]) - qsfp_0_txc_1 = Signal(intbv(0)[8:]) - qsfp_0_txd_2 = Signal(intbv(0)[64:]) - qsfp_0_txc_2 = Signal(intbv(0)[8:]) - qsfp_0_txd_3 = Signal(intbv(0)[64:]) - qsfp_0_txc_3 = Signal(intbv(0)[8:]) - qsfp_0_reset_n = Signal(bool(0)) - qsfp_0_lp_mode = Signal(bool(0)) - qsfp_0_i2c_scl_o = Signal(bool(1)) - qsfp_0_i2c_scl_t = Signal(bool(1)) - qsfp_0_i2c_sda_o = Signal(bool(1)) - qsfp_0_i2c_sda_t = Signal(bool(1)) - qsfp_1_txd_0 = Signal(intbv(0)[64:]) - qsfp_1_txc_0 = Signal(intbv(0)[8:]) - qsfp_1_txd_1 = Signal(intbv(0)[64:]) - qsfp_1_txc_1 = Signal(intbv(0)[8:]) - qsfp_1_txd_2 = Signal(intbv(0)[64:]) - qsfp_1_txc_2 = Signal(intbv(0)[8:]) - qsfp_1_txd_3 = Signal(intbv(0)[64:]) - qsfp_1_txc_3 = Signal(intbv(0)[8:]) - qsfp_1_reset_n = Signal(bool(0)) - qsfp_1_lp_mode = Signal(bool(0)) - qsfp_1_i2c_scl_o = Signal(bool(1)) - qsfp_1_i2c_scl_t = Signal(bool(1)) - qsfp_1_i2c_sda_o = Signal(bool(1)) - qsfp_1_i2c_sda_t = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp_0_0_source = xgmii_ep.XGMIISource() - qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') - - qsfp_0_0_sink = xgmii_ep.XGMIISink() - qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') - - qsfp_0_1_source = xgmii_ep.XGMIISource() - qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') - - qsfp_0_1_sink = xgmii_ep.XGMIISink() - qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') - - qsfp_0_2_source = xgmii_ep.XGMIISource() - qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') - - qsfp_0_2_sink = xgmii_ep.XGMIISink() - qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') - - qsfp_0_3_source = xgmii_ep.XGMIISource() - qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') - - qsfp_0_3_sink = xgmii_ep.XGMIISink() - qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') - - qsfp_1_0_source = xgmii_ep.XGMIISource() - qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') - - qsfp_1_0_sink = xgmii_ep.XGMIISink() - qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') - - qsfp_1_1_source = xgmii_ep.XGMIISource() - qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') - - qsfp_1_1_sink = xgmii_ep.XGMIISink() - qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') - - qsfp_1_2_source = xgmii_ep.XGMIISource() - qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') - - qsfp_1_2_sink = xgmii_ep.XGMIISink() - qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') - - qsfp_1_3_source = xgmii_ep.XGMIISource() - qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') - - qsfp_1_3_sink = xgmii_ep.XGMIISink() - qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - led_red=led_red, - led_green=led_green, - led_bmc=led_bmc, - led_exp=led_exp, - pps_in=pps_in, - pps_out=pps_out, - pps_out_en=pps_out_en, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, - qsfp_0_txd_0=qsfp_0_txd_0, - qsfp_0_txc_0=qsfp_0_txc_0, - qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, - qsfp_0_rxd_0=qsfp_0_rxd_0, - qsfp_0_rxc_0=qsfp_0_rxc_0, - qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, - qsfp_0_txd_1=qsfp_0_txd_1, - qsfp_0_txc_1=qsfp_0_txc_1, - qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, - qsfp_0_rxd_1=qsfp_0_rxd_1, - qsfp_0_rxc_1=qsfp_0_rxc_1, - qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, - qsfp_0_txd_2=qsfp_0_txd_2, - qsfp_0_txc_2=qsfp_0_txc_2, - qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, - qsfp_0_rxd_2=qsfp_0_rxd_2, - qsfp_0_rxc_2=qsfp_0_rxc_2, - qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, - qsfp_0_txd_3=qsfp_0_txd_3, - qsfp_0_txc_3=qsfp_0_txc_3, - qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, - qsfp_0_rxd_3=qsfp_0_rxd_3, - qsfp_0_rxc_3=qsfp_0_rxc_3, - qsfp_0_mod_prsnt_n=qsfp_0_mod_prsnt_n, - qsfp_0_reset_n=qsfp_0_reset_n, - qsfp_0_lp_mode=qsfp_0_lp_mode, - qsfp_0_intr_n=qsfp_0_intr_n, - qsfp_0_i2c_scl_i=qsfp_0_i2c_scl_i, - qsfp_0_i2c_scl_o=qsfp_0_i2c_scl_o, - qsfp_0_i2c_scl_t=qsfp_0_i2c_scl_t, - qsfp_0_i2c_sda_i=qsfp_0_i2c_sda_i, - qsfp_0_i2c_sda_o=qsfp_0_i2c_sda_o, - qsfp_0_i2c_sda_t=qsfp_0_i2c_sda_t, - qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, - qsfp_1_txd_0=qsfp_1_txd_0, - qsfp_1_txc_0=qsfp_1_txc_0, - qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, - qsfp_1_rxd_0=qsfp_1_rxd_0, - qsfp_1_rxc_0=qsfp_1_rxc_0, - qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, - qsfp_1_txd_1=qsfp_1_txd_1, - qsfp_1_txc_1=qsfp_1_txc_1, - qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, - qsfp_1_rxd_1=qsfp_1_rxd_1, - qsfp_1_rxc_1=qsfp_1_rxc_1, - qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, - qsfp_1_txd_2=qsfp_1_txd_2, - qsfp_1_txc_2=qsfp_1_txc_2, - qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, - qsfp_1_rxd_2=qsfp_1_rxd_2, - qsfp_1_rxc_2=qsfp_1_rxc_2, - qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, - qsfp_1_txd_3=qsfp_1_txd_3, - qsfp_1_txc_3=qsfp_1_txc_3, - qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, - qsfp_1_rxd_3=qsfp_1_rxd_3, - qsfp_1_rxc_3=qsfp_1_rxc_3, - qsfp_1_mod_prsnt_n=qsfp_1_mod_prsnt_n, - qsfp_1_reset_n=qsfp_1_reset_n, - qsfp_1_lp_mode=qsfp_1_lp_mode, - qsfp_1_intr_n=qsfp_1_intr_n, - qsfp_1_i2c_scl_i=qsfp_1_i2c_scl_i, - qsfp_1_i2c_scl_o=qsfp_1_i2c_scl_o, - qsfp_1_i2c_scl_t=qsfp_1_i2c_scl_t, - qsfp_1_i2c_sda_i=qsfp_1_i2c_sda_i, - qsfp_1_i2c_sda_o=qsfp_1_i2c_sda_o, - qsfp_1_i2c_sda_t=qsfp_1_i2c_sda_t, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 - qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 - qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 - qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 - qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 - qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 - qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 - qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 - qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 - qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 - qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 - qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 - qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 - qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 - qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 - qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_0_sink.empty(): - pkt = qsfp_0_0_sink.recv() - qsfp_0_0_source.send(pkt) - if not qsfp_0_1_sink.empty(): - pkt = qsfp_0_1_sink.recv() - qsfp_0_1_source.send(pkt) - if not qsfp_0_2_sink.empty(): - pkt = qsfp_0_2_sink.recv() - qsfp_0_2_source.send(pkt) - if not qsfp_0_3_sink.empty(): - pkt = qsfp_0_3_sink.recv() - qsfp_0_3_source.send(pkt) - if not qsfp_1_0_sink.empty(): - pkt = qsfp_1_0_sink.recv() - qsfp_1_0_source.send(pkt) - if not qsfp_1_1_sink.empty(): - pkt = qsfp_1_1_sink.recv() - qsfp_1_1_source.send(pkt) - if not qsfp_1_2_sink.empty(): - pkt = qsfp_1_2_sink.recv() - qsfp_1_2_source.send(pkt) - if not qsfp_1_3_sink.empty(): - pkt = qsfp_1_3_sink.recv() - qsfp_1_3_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst_0.next = 1 - qsfp_0_rx_rst_0.next = 1 - qsfp_0_tx_rst_1.next = 1 - qsfp_0_rx_rst_1.next = 1 - qsfp_0_tx_rst_2.next = 1 - qsfp_0_rx_rst_2.next = 1 - qsfp_0_tx_rst_3.next = 1 - qsfp_0_rx_rst_3.next = 1 - qsfp_1_tx_rst_0.next = 1 - qsfp_1_rx_rst_0.next = 1 - qsfp_1_tx_rst_1.next = 1 - qsfp_1_rx_rst_1.next = 1 - qsfp_1_tx_rst_2.next = 1 - qsfp_1_rx_rst_2.next = 1 - qsfp_1_tx_rst_3.next = 1 - qsfp_1_rx_rst_3.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst_0.next = 0 - qsfp_0_rx_rst_0.next = 0 - qsfp_0_tx_rst_1.next = 0 - qsfp_0_rx_rst_1.next = 0 - qsfp_0_tx_rst_2.next = 0 - qsfp_0_rx_rst_2.next = 0 - qsfp_0_tx_rst_3.next = 0 - qsfp_0_rx_rst_3.next = 0 - qsfp_1_tx_rst_0.next = 0 - qsfp_1_rx_rst_0.next = 0 - qsfp_1_tx_rst_1.next = 0 - qsfp_1_rx_rst_1.next = 0 - qsfp_1_tx_rst_2.next = 0 - qsfp_1_rx_rst_2.next = 0 - qsfp_1_tx_rst_3.next = 0 - qsfp_1_rx_rst_3.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_0_sink.wait() - - # pkt = qsfp_1_0_sink.recv() - # print(pkt) - - # qsfp_1_0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic/fb2CG/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 5a93aa2e5..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg pps_in = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk_0 = 0; -reg qsfp_0_tx_rst_0 = 0; -reg qsfp_0_rx_clk_0 = 0; -reg qsfp_0_rx_rst_0 = 0; -reg [63:0] qsfp_0_rxd_0 = 0; -reg [7:0] qsfp_0_rxc_0 = 0; -reg qsfp_0_tx_clk_1 = 0; -reg qsfp_0_tx_rst_1 = 0; -reg qsfp_0_rx_clk_1 = 0; -reg qsfp_0_rx_rst_1 = 0; -reg [63:0] qsfp_0_rxd_1 = 0; -reg [7:0] qsfp_0_rxc_1 = 0; -reg qsfp_0_tx_clk_2 = 0; -reg qsfp_0_tx_rst_2 = 0; -reg qsfp_0_rx_clk_2 = 0; -reg qsfp_0_rx_rst_2 = 0; -reg [63:0] qsfp_0_rxd_2 = 0; -reg [7:0] qsfp_0_rxc_2 = 0; -reg qsfp_0_tx_clk_3 = 0; -reg qsfp_0_tx_rst_3 = 0; -reg qsfp_0_rx_clk_3 = 0; -reg qsfp_0_rx_rst_3 = 0; -reg [63:0] qsfp_0_rxd_3 = 0; -reg [7:0] qsfp_0_rxc_3 = 0; -reg qsfp_0_mod_prsnt_n = 0; -reg qsfp_0_intr_n = 0; -reg qsfp_0_i2c_scl_i = 1; -reg qsfp_0_i2c_sda_i = 1; -reg qsfp_1_tx_clk_0 = 0; -reg qsfp_1_tx_rst_0 = 0; -reg qsfp_1_rx_clk_0 = 0; -reg qsfp_1_rx_rst_0 = 0; -reg [63:0] qsfp_1_rxd_0 = 0; -reg [7:0] qsfp_1_rxc_0 = 0; -reg qsfp_1_tx_clk_1 = 0; -reg qsfp_1_tx_rst_1 = 0; -reg qsfp_1_rx_clk_1 = 0; -reg qsfp_1_rx_rst_1 = 0; -reg [63:0] qsfp_1_rxd_1 = 0; -reg [7:0] qsfp_1_rxc_1 = 0; -reg qsfp_1_tx_clk_2 = 0; -reg qsfp_1_tx_rst_2 = 0; -reg qsfp_1_rx_clk_2 = 0; -reg qsfp_1_rx_rst_2 = 0; -reg [63:0] qsfp_1_rxd_2 = 0; -reg [7:0] qsfp_1_rxc_2 = 0; -reg qsfp_1_tx_clk_3 = 0; -reg qsfp_1_tx_rst_3 = 0; -reg qsfp_1_rx_clk_3 = 0; -reg qsfp_1_rx_rst_3 = 0; -reg [63:0] qsfp_1_rxd_3 = 0; -reg [7:0] qsfp_1_rxc_3 = 0; -reg qsfp_1_mod_prsnt_n = 0; -reg qsfp_1_intr_n = 0; -reg qsfp_1_i2c_scl_i = 1; -reg qsfp_1_i2c_sda_i = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [7:0] led_red; -wire [7:0] led_green; -wire [1:0] led_bmc; -wire [1:0] led_exp; -wire pps_out; -wire pps_out_en; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_0_txd_0; -wire [7:0] qsfp_0_txc_0; -wire [63:0] qsfp_0_txd_1; -wire [7:0] qsfp_0_txc_1; -wire [63:0] qsfp_0_txd_2; -wire [7:0] qsfp_0_txc_2; -wire [63:0] qsfp_0_txd_3; -wire [7:0] qsfp_0_txc_3; -wire qsfp_0_reset_n; -wire qsfp_0_lp_mode; -wire qsfp_0_i2c_scl_o; -wire qsfp_0_i2c_scl_t; -wire qsfp_0_i2c_sda_o; -wire qsfp_0_i2c_sda_t; -wire [63:0] qsfp_1_txd_0; -wire [7:0] qsfp_1_txc_0; -wire [63:0] qsfp_1_txd_1; -wire [7:0] qsfp_1_txc_1; -wire [63:0] qsfp_1_txd_2; -wire [7:0] qsfp_1_txc_2; -wire [63:0] qsfp_1_txd_3; -wire [7:0] qsfp_1_txc_3; -wire qsfp_1_reset_n; -wire qsfp_1_lp_mode; -wire qsfp_1_i2c_scl_o; -wire qsfp_1_i2c_scl_t; -wire qsfp_1_i2c_sda_o; -wire qsfp_1_i2c_sda_t; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - pps_in, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0, - qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0, - qsfp_0_rxd_0, - qsfp_0_rxc_0, - qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1, - qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1, - qsfp_0_rxd_1, - qsfp_0_rxc_1, - qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2, - qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2, - qsfp_0_rxd_2, - qsfp_0_rxc_2, - qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3, - qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3, - qsfp_0_rxd_3, - qsfp_0_rxc_3, - qsfp_0_mod_prsnt_n, - qsfp_0_intr_n, - qsfp_0_i2c_scl_i, - qsfp_0_i2c_sda_i, - qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0, - qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0, - qsfp_1_rxd_0, - qsfp_1_rxc_0, - qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1, - qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1, - qsfp_1_rxd_1, - qsfp_1_rxc_1, - qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2, - qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2, - qsfp_1_rxd_2, - qsfp_1_rxc_2, - qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3, - qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3, - qsfp_1_rxd_3, - qsfp_1_rxc_3, - qsfp_1_mod_prsnt_n, - qsfp_1_intr_n, - qsfp_1_i2c_scl_i, - qsfp_1_i2c_sda_i, - qspi_dq_i - ); - $to_myhdl( - led_red, - led_green, - led_bmc, - led_exp, - pps_out, - pps_out_en, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_txd_0, - qsfp_0_txc_0, - qsfp_0_txd_1, - qsfp_0_txc_1, - qsfp_0_txd_2, - qsfp_0_txc_2, - qsfp_0_txd_3, - qsfp_0_txc_3, - qsfp_0_reset_n, - qsfp_0_lp_mode, - qsfp_0_i2c_scl_o, - qsfp_0_i2c_scl_t, - qsfp_0_i2c_sda_o, - qsfp_0_i2c_sda_t, - qsfp_1_txd_0, - qsfp_1_txc_0, - qsfp_1_txd_1, - qsfp_1_txc_1, - qsfp_1_txd_2, - qsfp_1_txc_2, - qsfp_1_txd_3, - qsfp_1_txc_3, - qsfp_1_reset_n, - qsfp_1_lp_mode, - qsfp_1_i2c_scl_o, - qsfp_1_i2c_scl_t, - qsfp_1_i2c_sda_o, - qsfp_1_i2c_sda_t, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .led_red(led_red), - .led_green(led_green), - .led_bmc(led_bmc), - .led_exp(led_exp), - .pps_in(pps_in), - .pps_out(pps_out), - .pps_out_en(pps_out_en), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), - .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), - .qsfp_0_txd_0(qsfp_0_txd_0), - .qsfp_0_txc_0(qsfp_0_txc_0), - .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), - .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), - .qsfp_0_rxd_0(qsfp_0_rxd_0), - .qsfp_0_rxc_0(qsfp_0_rxc_0), - .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), - .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), - .qsfp_0_txd_1(qsfp_0_txd_1), - .qsfp_0_txc_1(qsfp_0_txc_1), - .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), - .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), - .qsfp_0_rxd_1(qsfp_0_rxd_1), - .qsfp_0_rxc_1(qsfp_0_rxc_1), - .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), - .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), - .qsfp_0_txd_2(qsfp_0_txd_2), - .qsfp_0_txc_2(qsfp_0_txc_2), - .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), - .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), - .qsfp_0_rxd_2(qsfp_0_rxd_2), - .qsfp_0_rxc_2(qsfp_0_rxc_2), - .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), - .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), - .qsfp_0_txd_3(qsfp_0_txd_3), - .qsfp_0_txc_3(qsfp_0_txc_3), - .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), - .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), - .qsfp_0_rxd_3(qsfp_0_rxd_3), - .qsfp_0_rxc_3(qsfp_0_rxc_3), - .qsfp_0_mod_prsnt_n(qsfp_0_mod_prsnt_n), - .qsfp_0_reset_n(qsfp_0_reset_n), - .qsfp_0_lp_mode(qsfp_0_lp_mode), - .qsfp_0_intr_n(qsfp_0_intr_n), - .qsfp_0_i2c_scl_i(qsfp_0_i2c_scl_i), - .qsfp_0_i2c_scl_o(qsfp_0_i2c_scl_o), - .qsfp_0_i2c_scl_t(qsfp_0_i2c_scl_t), - .qsfp_0_i2c_sda_i(qsfp_0_i2c_sda_i), - .qsfp_0_i2c_sda_o(qsfp_0_i2c_sda_o), - .qsfp_0_i2c_sda_t(qsfp_0_i2c_sda_t), - .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), - .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), - .qsfp_1_txd_0(qsfp_1_txd_0), - .qsfp_1_txc_0(qsfp_1_txc_0), - .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), - .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), - .qsfp_1_rxd_0(qsfp_1_rxd_0), - .qsfp_1_rxc_0(qsfp_1_rxc_0), - .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), - .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), - .qsfp_1_txd_1(qsfp_1_txd_1), - .qsfp_1_txc_1(qsfp_1_txc_1), - .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), - .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), - .qsfp_1_rxd_1(qsfp_1_rxd_1), - .qsfp_1_rxc_1(qsfp_1_rxc_1), - .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), - .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), - .qsfp_1_txd_2(qsfp_1_txd_2), - .qsfp_1_txc_2(qsfp_1_txc_2), - .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), - .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), - .qsfp_1_rxd_2(qsfp_1_rxd_2), - .qsfp_1_rxc_2(qsfp_1_rxc_2), - .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), - .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), - .qsfp_1_txd_3(qsfp_1_txd_3), - .qsfp_1_txc_3(qsfp_1_txc_3), - .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), - .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), - .qsfp_1_rxd_3(qsfp_1_rxd_3), - .qsfp_1_rxc_3(qsfp_1_rxc_3), - .qsfp_1_mod_prsnt_n(qsfp_1_mod_prsnt_n), - .qsfp_1_reset_n(qsfp_1_reset_n), - .qsfp_1_lp_mode(qsfp_1_lp_mode), - .qsfp_1_intr_n(qsfp_1_intr_n), - .qsfp_1_i2c_scl_i(qsfp_1_i2c_scl_i), - .qsfp_1_i2c_scl_o(qsfp_1_i2c_scl_o), - .qsfp_1_i2c_scl_t(qsfp_1_i2c_scl_t), - .qsfp_1_i2c_sda_i(qsfp_1_i2c_sda_i), - .qsfp_1_i2c_sda_o(qsfp_1_i2c_sda_o), - .qsfp_1_i2c_sda_t(qsfp_1_i2c_sda_t), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/udp_ep.py b/fpga/mqnic/fb2CG/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic/fb2CG/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/fb2CG/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/axis_ep.py b/fpga/mqnic/fb2CG/fpga_25g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/eth_ep.py b/fpga/mqnic/fb2CG/fpga_25g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile new file mode 100644 index 000000000..493d83d42 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/Makefile @@ -0,0 +1,152 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/mqnic.py b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..4c9b4e09a --- /dev/null +++ b/fpga/mqnic/fb2CG/fpga_25g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,656 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk_0, 2.56, units="ns").start()) + self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_0, 2.56, units="ns").start()) + self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_1, 2.56, units="ns").start()) + self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_1, 2.56, units="ns").start()) + self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_2, 2.56, units="ns").start()) + self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_2, 2.56, units="ns").start()) + self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_3, 2.56, units="ns").start()) + self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_3, 2.56, units="ns").start()) + self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_0, 2.56, units="ns").start()) + self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_0, 2.56, units="ns").start()) + self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_1, 2.56, units="ns").start()) + self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_1, 2.56, units="ns").start()) + self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_2, 2.56, units="ns").start()) + self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_2, 2.56, units="ns").start()) + self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_3, 2.56, units="ns").start()) + self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_3, 2.56, units="ns").start()) + self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3) + + dut.qsfp_0_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_0_i2c_sda_i.setimmediatevalue(1) + dut.qsfp_0_intr_n.setimmediatevalue(1) + dut.qsfp_0_mod_prsnt_n.setimmediatevalue(0) + + dut.qsfp_0_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_1_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_1_i2c_sda_i.setimmediatevalue(1) + dut.qsfp_1_intr_n.setimmediatevalue(1) + dut.qsfp_1_mod_prsnt_n.setimmediatevalue(0) + + dut.qsfp_1_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_3.setimmediatevalue(0) + + dut.qspi_dq_i.setimmediatevalue(0) + + dut.pps_in.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_0_sink.empty(): + self.qsfp_0_0_source.send(self.qsfp_0_0_sink.recv()) + if not self.qsfp_0_1_sink.empty(): + self.qsfp_0_1_source.send(self.qsfp_0_1_sink.recv()) + if not self.qsfp_0_2_sink.empty(): + self.qsfp_0_2_source.send(self.qsfp_0_2_sink.recv()) + if not self.qsfp_0_3_sink.empty(): + self.qsfp_0_3_source.send(self.qsfp_0_3_sink.recv()) + if not self.qsfp_1_0_sink.empty(): + self.qsfp_1_0_source.send(self.qsfp_1_0_sink.recv()) + if not self.qsfp_1_1_sink.empty(): + self.qsfp_1_1_source.send(self.qsfp_1_1_sink.recv()) + if not self.qsfp_1_2_sink.empty(): + self.qsfp_1_2_source.send(self.qsfp_1_2_sink.recv()) + if not self.qsfp_1_3_sink.empty(): + self.qsfp_1_3_source.send(self.qsfp_1_3_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/ip_ep.py b/fpga/mqnic/fb2CG/fpga_25g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/mqnic.py b/fpga/mqnic/fb2CG/fpga_25g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/pcie.py b/fpga/mqnic/fb2CG/fpga_25g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/pcie_us.py b/fpga/mqnic/fb2CG/fpga_25g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/pcie_usp.py b/fpga/mqnic/fb2CG/fpga_25g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/test_fpga_core.py b/fpga/mqnic/fb2CG/fpga_25g/tb/test_fpga_core.py deleted file mode 100755 index 3ebddf276..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/test_fpga_core.py +++ /dev/null @@ -1,1047 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - pps_in = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk_0 = Signal(bool(0)) - qsfp_0_tx_rst_0 = Signal(bool(0)) - qsfp_0_rx_clk_0 = Signal(bool(0)) - qsfp_0_rx_rst_0 = Signal(bool(0)) - qsfp_0_rxd_0 = Signal(intbv(0)[64:]) - qsfp_0_rxc_0 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_1 = Signal(bool(0)) - qsfp_0_tx_rst_1 = Signal(bool(0)) - qsfp_0_rx_clk_1 = Signal(bool(0)) - qsfp_0_rx_rst_1 = Signal(bool(0)) - qsfp_0_rxd_1 = Signal(intbv(0)[64:]) - qsfp_0_rxc_1 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_2 = Signal(bool(0)) - qsfp_0_tx_rst_2 = Signal(bool(0)) - qsfp_0_rx_clk_2 = Signal(bool(0)) - qsfp_0_rx_rst_2 = Signal(bool(0)) - qsfp_0_rxd_2 = Signal(intbv(0)[64:]) - qsfp_0_rxc_2 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_3 = Signal(bool(0)) - qsfp_0_tx_rst_3 = Signal(bool(0)) - qsfp_0_rx_clk_3 = Signal(bool(0)) - qsfp_0_rx_rst_3 = Signal(bool(0)) - qsfp_0_rxd_3 = Signal(intbv(0)[64:]) - qsfp_0_rxc_3 = Signal(intbv(0)[8:]) - qsfp_0_mod_prsnt_n = Signal(bool(0)) - qsfp_0_intr_n = Signal(bool(0)) - qsfp_0_i2c_scl_i = Signal(bool(0)) - qsfp_0_i2c_sda_i = Signal(bool(0)) - qsfp_1_tx_clk_0 = Signal(bool(0)) - qsfp_1_tx_rst_0 = Signal(bool(0)) - qsfp_1_rx_clk_0 = Signal(bool(0)) - qsfp_1_rx_rst_0 = Signal(bool(0)) - qsfp_1_rxd_0 = Signal(intbv(0)[64:]) - qsfp_1_rxc_0 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_1 = Signal(bool(0)) - qsfp_1_tx_rst_1 = Signal(bool(0)) - qsfp_1_rx_clk_1 = Signal(bool(0)) - qsfp_1_rx_rst_1 = Signal(bool(0)) - qsfp_1_rxd_1 = Signal(intbv(0)[64:]) - qsfp_1_rxc_1 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_2 = Signal(bool(0)) - qsfp_1_tx_rst_2 = Signal(bool(0)) - qsfp_1_rx_clk_2 = Signal(bool(0)) - qsfp_1_rx_rst_2 = Signal(bool(0)) - qsfp_1_rxd_2 = Signal(intbv(0)[64:]) - qsfp_1_rxc_2 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_3 = Signal(bool(0)) - qsfp_1_tx_rst_3 = Signal(bool(0)) - qsfp_1_rx_clk_3 = Signal(bool(0)) - qsfp_1_rx_rst_3 = Signal(bool(0)) - qsfp_1_rxd_3 = Signal(intbv(0)[64:]) - qsfp_1_rxc_3 = Signal(intbv(0)[8:]) - qsfp_1_mod_prsnt_n = Signal(bool(0)) - qsfp_1_intr_n = Signal(bool(0)) - qsfp_1_i2c_scl_i = Signal(bool(0)) - qsfp_1_i2c_sda_i = Signal(bool(0)) - qspi_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led_red = Signal(intbv(0)[7:]) - led_green = Signal(intbv(0)[7:]) - led_bmc = Signal(intbv(0)[2:]) - led_exp = Signal(intbv(0)[2:]) - pps_out = Signal(bool(0)) - pps_out_en = Signal(bool(0)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_txd_0 = Signal(intbv(0)[64:]) - qsfp_0_txc_0 = Signal(intbv(0)[8:]) - qsfp_0_txd_1 = Signal(intbv(0)[64:]) - qsfp_0_txc_1 = Signal(intbv(0)[8:]) - qsfp_0_txd_2 = Signal(intbv(0)[64:]) - qsfp_0_txc_2 = Signal(intbv(0)[8:]) - qsfp_0_txd_3 = Signal(intbv(0)[64:]) - qsfp_0_txc_3 = Signal(intbv(0)[8:]) - qsfp_0_reset_n = Signal(bool(0)) - qsfp_0_lp_mode = Signal(bool(0)) - qsfp_0_i2c_scl_o = Signal(bool(1)) - qsfp_0_i2c_scl_t = Signal(bool(1)) - qsfp_0_i2c_sda_o = Signal(bool(1)) - qsfp_0_i2c_sda_t = Signal(bool(1)) - qsfp_1_txd_0 = Signal(intbv(0)[64:]) - qsfp_1_txc_0 = Signal(intbv(0)[8:]) - qsfp_1_txd_1 = Signal(intbv(0)[64:]) - qsfp_1_txc_1 = Signal(intbv(0)[8:]) - qsfp_1_txd_2 = Signal(intbv(0)[64:]) - qsfp_1_txc_2 = Signal(intbv(0)[8:]) - qsfp_1_txd_3 = Signal(intbv(0)[64:]) - qsfp_1_txc_3 = Signal(intbv(0)[8:]) - qsfp_1_reset_n = Signal(bool(0)) - qsfp_1_lp_mode = Signal(bool(0)) - qsfp_1_i2c_scl_o = Signal(bool(1)) - qsfp_1_i2c_scl_t = Signal(bool(1)) - qsfp_1_i2c_sda_o = Signal(bool(1)) - qsfp_1_i2c_sda_t = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_dq_o = Signal(intbv(0)[4:]) - qspi_dq_oe = Signal(intbv(0)[4:]) - qspi_cs = Signal(bool(0)) - - # sources and sinks - qsfp_0_0_source = xgmii_ep.XGMIISource() - qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') - - qsfp_0_0_sink = xgmii_ep.XGMIISink() - qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') - - qsfp_0_1_source = xgmii_ep.XGMIISource() - qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') - - qsfp_0_1_sink = xgmii_ep.XGMIISink() - qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') - - qsfp_0_2_source = xgmii_ep.XGMIISource() - qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') - - qsfp_0_2_sink = xgmii_ep.XGMIISink() - qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') - - qsfp_0_3_source = xgmii_ep.XGMIISource() - qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') - - qsfp_0_3_sink = xgmii_ep.XGMIISink() - qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') - - qsfp_1_0_source = xgmii_ep.XGMIISource() - qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') - - qsfp_1_0_sink = xgmii_ep.XGMIISink() - qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') - - qsfp_1_1_source = xgmii_ep.XGMIISource() - qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') - - qsfp_1_1_sink = xgmii_ep.XGMIISink() - qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') - - qsfp_1_2_source = xgmii_ep.XGMIISource() - qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') - - qsfp_1_2_sink = xgmii_ep.XGMIISink() - qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') - - qsfp_1_3_source = xgmii_ep.XGMIISource() - qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') - - qsfp_1_3_sink = xgmii_ep.XGMIISink() - qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - led_red=led_red, - led_green=led_green, - led_bmc=led_bmc, - led_exp=led_exp, - pps_in=pps_in, - pps_out=pps_out, - pps_out_en=pps_out_en, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, - qsfp_0_txd_0=qsfp_0_txd_0, - qsfp_0_txc_0=qsfp_0_txc_0, - qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, - qsfp_0_rxd_0=qsfp_0_rxd_0, - qsfp_0_rxc_0=qsfp_0_rxc_0, - qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, - qsfp_0_txd_1=qsfp_0_txd_1, - qsfp_0_txc_1=qsfp_0_txc_1, - qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, - qsfp_0_rxd_1=qsfp_0_rxd_1, - qsfp_0_rxc_1=qsfp_0_rxc_1, - qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, - qsfp_0_txd_2=qsfp_0_txd_2, - qsfp_0_txc_2=qsfp_0_txc_2, - qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, - qsfp_0_rxd_2=qsfp_0_rxd_2, - qsfp_0_rxc_2=qsfp_0_rxc_2, - qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, - qsfp_0_txd_3=qsfp_0_txd_3, - qsfp_0_txc_3=qsfp_0_txc_3, - qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, - qsfp_0_rxd_3=qsfp_0_rxd_3, - qsfp_0_rxc_3=qsfp_0_rxc_3, - qsfp_0_mod_prsnt_n=qsfp_0_mod_prsnt_n, - qsfp_0_reset_n=qsfp_0_reset_n, - qsfp_0_lp_mode=qsfp_0_lp_mode, - qsfp_0_intr_n=qsfp_0_intr_n, - qsfp_0_i2c_scl_i=qsfp_0_i2c_scl_i, - qsfp_0_i2c_scl_o=qsfp_0_i2c_scl_o, - qsfp_0_i2c_scl_t=qsfp_0_i2c_scl_t, - qsfp_0_i2c_sda_i=qsfp_0_i2c_sda_i, - qsfp_0_i2c_sda_o=qsfp_0_i2c_sda_o, - qsfp_0_i2c_sda_t=qsfp_0_i2c_sda_t, - qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, - qsfp_1_txd_0=qsfp_1_txd_0, - qsfp_1_txc_0=qsfp_1_txc_0, - qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, - qsfp_1_rxd_0=qsfp_1_rxd_0, - qsfp_1_rxc_0=qsfp_1_rxc_0, - qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, - qsfp_1_txd_1=qsfp_1_txd_1, - qsfp_1_txc_1=qsfp_1_txc_1, - qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, - qsfp_1_rxd_1=qsfp_1_rxd_1, - qsfp_1_rxc_1=qsfp_1_rxc_1, - qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, - qsfp_1_txd_2=qsfp_1_txd_2, - qsfp_1_txc_2=qsfp_1_txc_2, - qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, - qsfp_1_rxd_2=qsfp_1_rxd_2, - qsfp_1_rxc_2=qsfp_1_rxc_2, - qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, - qsfp_1_txd_3=qsfp_1_txd_3, - qsfp_1_txc_3=qsfp_1_txc_3, - qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, - qsfp_1_rxd_3=qsfp_1_rxd_3, - qsfp_1_rxc_3=qsfp_1_rxc_3, - qsfp_1_mod_prsnt_n=qsfp_1_mod_prsnt_n, - qsfp_1_reset_n=qsfp_1_reset_n, - qsfp_1_lp_mode=qsfp_1_lp_mode, - qsfp_1_intr_n=qsfp_1_intr_n, - qsfp_1_i2c_scl_i=qsfp_1_i2c_scl_i, - qsfp_1_i2c_scl_o=qsfp_1_i2c_scl_o, - qsfp_1_i2c_scl_t=qsfp_1_i2c_scl_t, - qsfp_1_i2c_sda_i=qsfp_1_i2c_sda_i, - qsfp_1_i2c_sda_o=qsfp_1_i2c_sda_o, - qsfp_1_i2c_sda_t=qsfp_1_i2c_sda_t, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_dq_i=qspi_dq_i, - qspi_dq_o=qspi_dq_o, - qspi_dq_oe=qspi_dq_oe, - qspi_cs=qspi_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(1)) - def qsfp_clkgen(): - qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 - qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 - qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 - qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 - qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 - qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 - qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 - qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 - qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 - qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 - qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 - qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 - qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 - qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 - qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 - qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_0_sink.empty(): - pkt = qsfp_0_0_sink.recv() - qsfp_0_0_source.send(pkt) - if not qsfp_0_1_sink.empty(): - pkt = qsfp_0_1_sink.recv() - qsfp_0_1_source.send(pkt) - if not qsfp_0_2_sink.empty(): - pkt = qsfp_0_2_sink.recv() - qsfp_0_2_source.send(pkt) - if not qsfp_0_3_sink.empty(): - pkt = qsfp_0_3_sink.recv() - qsfp_0_3_source.send(pkt) - if not qsfp_1_0_sink.empty(): - pkt = qsfp_1_0_sink.recv() - qsfp_1_0_source.send(pkt) - if not qsfp_1_1_sink.empty(): - pkt = qsfp_1_1_sink.recv() - qsfp_1_1_source.send(pkt) - if not qsfp_1_2_sink.empty(): - pkt = qsfp_1_2_sink.recv() - qsfp_1_2_source.send(pkt) - if not qsfp_1_3_sink.empty(): - pkt = qsfp_1_3_sink.recv() - qsfp_1_3_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst_0.next = 1 - qsfp_0_rx_rst_0.next = 1 - qsfp_0_tx_rst_1.next = 1 - qsfp_0_rx_rst_1.next = 1 - qsfp_0_tx_rst_2.next = 1 - qsfp_0_rx_rst_2.next = 1 - qsfp_0_tx_rst_3.next = 1 - qsfp_0_rx_rst_3.next = 1 - qsfp_1_tx_rst_0.next = 1 - qsfp_1_rx_rst_0.next = 1 - qsfp_1_tx_rst_1.next = 1 - qsfp_1_rx_rst_1.next = 1 - qsfp_1_tx_rst_2.next = 1 - qsfp_1_rx_rst_2.next = 1 - qsfp_1_tx_rst_3.next = 1 - qsfp_1_rx_rst_3.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst_0.next = 0 - qsfp_0_rx_rst_0.next = 0 - qsfp_0_tx_rst_1.next = 0 - qsfp_0_rx_rst_1.next = 0 - qsfp_0_tx_rst_2.next = 0 - qsfp_0_rx_rst_2.next = 0 - qsfp_0_tx_rst_3.next = 0 - qsfp_0_rx_rst_3.next = 0 - qsfp_1_tx_rst_0.next = 0 - qsfp_1_rx_rst_0.next = 0 - qsfp_1_tx_rst_1.next = 0 - qsfp_1_rx_rst_1.next = 0 - qsfp_1_tx_rst_2.next = 0 - qsfp_1_rx_rst_2.next = 0 - qsfp_1_tx_rst_3.next = 0 - qsfp_1_rx_rst_3.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_0_sink.wait() - - # pkt = qsfp_1_0_sink.recv() - # print(pkt) - - # qsfp_1_0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/test_fpga_core.v b/fpga/mqnic/fb2CG/fpga_25g/tb/test_fpga_core.v deleted file mode 100644 index 5a93aa2e5..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/test_fpga_core.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg pps_in = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk_0 = 0; -reg qsfp_0_tx_rst_0 = 0; -reg qsfp_0_rx_clk_0 = 0; -reg qsfp_0_rx_rst_0 = 0; -reg [63:0] qsfp_0_rxd_0 = 0; -reg [7:0] qsfp_0_rxc_0 = 0; -reg qsfp_0_tx_clk_1 = 0; -reg qsfp_0_tx_rst_1 = 0; -reg qsfp_0_rx_clk_1 = 0; -reg qsfp_0_rx_rst_1 = 0; -reg [63:0] qsfp_0_rxd_1 = 0; -reg [7:0] qsfp_0_rxc_1 = 0; -reg qsfp_0_tx_clk_2 = 0; -reg qsfp_0_tx_rst_2 = 0; -reg qsfp_0_rx_clk_2 = 0; -reg qsfp_0_rx_rst_2 = 0; -reg [63:0] qsfp_0_rxd_2 = 0; -reg [7:0] qsfp_0_rxc_2 = 0; -reg qsfp_0_tx_clk_3 = 0; -reg qsfp_0_tx_rst_3 = 0; -reg qsfp_0_rx_clk_3 = 0; -reg qsfp_0_rx_rst_3 = 0; -reg [63:0] qsfp_0_rxd_3 = 0; -reg [7:0] qsfp_0_rxc_3 = 0; -reg qsfp_0_mod_prsnt_n = 0; -reg qsfp_0_intr_n = 0; -reg qsfp_0_i2c_scl_i = 1; -reg qsfp_0_i2c_sda_i = 1; -reg qsfp_1_tx_clk_0 = 0; -reg qsfp_1_tx_rst_0 = 0; -reg qsfp_1_rx_clk_0 = 0; -reg qsfp_1_rx_rst_0 = 0; -reg [63:0] qsfp_1_rxd_0 = 0; -reg [7:0] qsfp_1_rxc_0 = 0; -reg qsfp_1_tx_clk_1 = 0; -reg qsfp_1_tx_rst_1 = 0; -reg qsfp_1_rx_clk_1 = 0; -reg qsfp_1_rx_rst_1 = 0; -reg [63:0] qsfp_1_rxd_1 = 0; -reg [7:0] qsfp_1_rxc_1 = 0; -reg qsfp_1_tx_clk_2 = 0; -reg qsfp_1_tx_rst_2 = 0; -reg qsfp_1_rx_clk_2 = 0; -reg qsfp_1_rx_rst_2 = 0; -reg [63:0] qsfp_1_rxd_2 = 0; -reg [7:0] qsfp_1_rxc_2 = 0; -reg qsfp_1_tx_clk_3 = 0; -reg qsfp_1_tx_rst_3 = 0; -reg qsfp_1_rx_clk_3 = 0; -reg qsfp_1_rx_rst_3 = 0; -reg [63:0] qsfp_1_rxd_3 = 0; -reg [7:0] qsfp_1_rxc_3 = 0; -reg qsfp_1_mod_prsnt_n = 0; -reg qsfp_1_intr_n = 0; -reg qsfp_1_i2c_scl_i = 1; -reg qsfp_1_i2c_sda_i = 1; -reg [3:0] qspi_dq_i = 0; - -// Outputs -wire [7:0] led_red; -wire [7:0] led_green; -wire [1:0] led_bmc; -wire [1:0] led_exp; -wire pps_out; -wire pps_out_en; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_0_txd_0; -wire [7:0] qsfp_0_txc_0; -wire [63:0] qsfp_0_txd_1; -wire [7:0] qsfp_0_txc_1; -wire [63:0] qsfp_0_txd_2; -wire [7:0] qsfp_0_txc_2; -wire [63:0] qsfp_0_txd_3; -wire [7:0] qsfp_0_txc_3; -wire qsfp_0_reset_n; -wire qsfp_0_lp_mode; -wire qsfp_0_i2c_scl_o; -wire qsfp_0_i2c_scl_t; -wire qsfp_0_i2c_sda_o; -wire qsfp_0_i2c_sda_t; -wire [63:0] qsfp_1_txd_0; -wire [7:0] qsfp_1_txc_0; -wire [63:0] qsfp_1_txd_1; -wire [7:0] qsfp_1_txc_1; -wire [63:0] qsfp_1_txd_2; -wire [7:0] qsfp_1_txc_2; -wire [63:0] qsfp_1_txd_3; -wire [7:0] qsfp_1_txc_3; -wire qsfp_1_reset_n; -wire qsfp_1_lp_mode; -wire qsfp_1_i2c_scl_o; -wire qsfp_1_i2c_scl_t; -wire qsfp_1_i2c_sda_o; -wire qsfp_1_i2c_sda_t; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_dq_o; -wire [3:0] qspi_dq_oe; -wire qspi_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - pps_in, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0, - qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0, - qsfp_0_rxd_0, - qsfp_0_rxc_0, - qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1, - qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1, - qsfp_0_rxd_1, - qsfp_0_rxc_1, - qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2, - qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2, - qsfp_0_rxd_2, - qsfp_0_rxc_2, - qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3, - qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3, - qsfp_0_rxd_3, - qsfp_0_rxc_3, - qsfp_0_mod_prsnt_n, - qsfp_0_intr_n, - qsfp_0_i2c_scl_i, - qsfp_0_i2c_sda_i, - qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0, - qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0, - qsfp_1_rxd_0, - qsfp_1_rxc_0, - qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1, - qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1, - qsfp_1_rxd_1, - qsfp_1_rxc_1, - qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2, - qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2, - qsfp_1_rxd_2, - qsfp_1_rxc_2, - qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3, - qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3, - qsfp_1_rxd_3, - qsfp_1_rxc_3, - qsfp_1_mod_prsnt_n, - qsfp_1_intr_n, - qsfp_1_i2c_scl_i, - qsfp_1_i2c_sda_i, - qspi_dq_i - ); - $to_myhdl( - led_red, - led_green, - led_bmc, - led_exp, - pps_out, - pps_out_en, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_txd_0, - qsfp_0_txc_0, - qsfp_0_txd_1, - qsfp_0_txc_1, - qsfp_0_txd_2, - qsfp_0_txc_2, - qsfp_0_txd_3, - qsfp_0_txc_3, - qsfp_0_reset_n, - qsfp_0_lp_mode, - qsfp_0_i2c_scl_o, - qsfp_0_i2c_scl_t, - qsfp_0_i2c_sda_o, - qsfp_0_i2c_sda_t, - qsfp_1_txd_0, - qsfp_1_txc_0, - qsfp_1_txd_1, - qsfp_1_txc_1, - qsfp_1_txd_2, - qsfp_1_txc_2, - qsfp_1_txd_3, - qsfp_1_txc_3, - qsfp_1_reset_n, - qsfp_1_lp_mode, - qsfp_1_i2c_scl_o, - qsfp_1_i2c_scl_t, - qsfp_1_i2c_sda_o, - qsfp_1_i2c_sda_t, - fpga_boot, - qspi_clk, - qspi_dq_o, - qspi_dq_oe, - qspi_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .led_red(led_red), - .led_green(led_green), - .led_bmc(led_bmc), - .led_exp(led_exp), - .pps_in(pps_in), - .pps_out(pps_out), - .pps_out_en(pps_out_en), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), - .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), - .qsfp_0_txd_0(qsfp_0_txd_0), - .qsfp_0_txc_0(qsfp_0_txc_0), - .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), - .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), - .qsfp_0_rxd_0(qsfp_0_rxd_0), - .qsfp_0_rxc_0(qsfp_0_rxc_0), - .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), - .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), - .qsfp_0_txd_1(qsfp_0_txd_1), - .qsfp_0_txc_1(qsfp_0_txc_1), - .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), - .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), - .qsfp_0_rxd_1(qsfp_0_rxd_1), - .qsfp_0_rxc_1(qsfp_0_rxc_1), - .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), - .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), - .qsfp_0_txd_2(qsfp_0_txd_2), - .qsfp_0_txc_2(qsfp_0_txc_2), - .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), - .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), - .qsfp_0_rxd_2(qsfp_0_rxd_2), - .qsfp_0_rxc_2(qsfp_0_rxc_2), - .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), - .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), - .qsfp_0_txd_3(qsfp_0_txd_3), - .qsfp_0_txc_3(qsfp_0_txc_3), - .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), - .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), - .qsfp_0_rxd_3(qsfp_0_rxd_3), - .qsfp_0_rxc_3(qsfp_0_rxc_3), - .qsfp_0_mod_prsnt_n(qsfp_0_mod_prsnt_n), - .qsfp_0_reset_n(qsfp_0_reset_n), - .qsfp_0_lp_mode(qsfp_0_lp_mode), - .qsfp_0_intr_n(qsfp_0_intr_n), - .qsfp_0_i2c_scl_i(qsfp_0_i2c_scl_i), - .qsfp_0_i2c_scl_o(qsfp_0_i2c_scl_o), - .qsfp_0_i2c_scl_t(qsfp_0_i2c_scl_t), - .qsfp_0_i2c_sda_i(qsfp_0_i2c_sda_i), - .qsfp_0_i2c_sda_o(qsfp_0_i2c_sda_o), - .qsfp_0_i2c_sda_t(qsfp_0_i2c_sda_t), - .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), - .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), - .qsfp_1_txd_0(qsfp_1_txd_0), - .qsfp_1_txc_0(qsfp_1_txc_0), - .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), - .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), - .qsfp_1_rxd_0(qsfp_1_rxd_0), - .qsfp_1_rxc_0(qsfp_1_rxc_0), - .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), - .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), - .qsfp_1_txd_1(qsfp_1_txd_1), - .qsfp_1_txc_1(qsfp_1_txc_1), - .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), - .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), - .qsfp_1_rxd_1(qsfp_1_rxd_1), - .qsfp_1_rxc_1(qsfp_1_rxc_1), - .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), - .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), - .qsfp_1_txd_2(qsfp_1_txd_2), - .qsfp_1_txc_2(qsfp_1_txc_2), - .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), - .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), - .qsfp_1_rxd_2(qsfp_1_rxd_2), - .qsfp_1_rxc_2(qsfp_1_rxc_2), - .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), - .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), - .qsfp_1_txd_3(qsfp_1_txd_3), - .qsfp_1_txc_3(qsfp_1_txc_3), - .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), - .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), - .qsfp_1_rxd_3(qsfp_1_rxd_3), - .qsfp_1_rxc_3(qsfp_1_rxc_3), - .qsfp_1_mod_prsnt_n(qsfp_1_mod_prsnt_n), - .qsfp_1_reset_n(qsfp_1_reset_n), - .qsfp_1_lp_mode(qsfp_1_lp_mode), - .qsfp_1_intr_n(qsfp_1_intr_n), - .qsfp_1_i2c_scl_i(qsfp_1_i2c_scl_i), - .qsfp_1_i2c_scl_o(qsfp_1_i2c_scl_o), - .qsfp_1_i2c_scl_t(qsfp_1_i2c_scl_t), - .qsfp_1_i2c_sda_i(qsfp_1_i2c_sda_i), - .qsfp_1_i2c_sda_o(qsfp_1_i2c_sda_o), - .qsfp_1_i2c_sda_t(qsfp_1_i2c_sda_t), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_dq_i(qspi_dq_i), - .qspi_dq_o(qspi_dq_o), - .qspi_dq_oe(qspi_dq_oe), - .qspi_cs(qspi_cs) -); - -endmodule diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/udp_ep.py b/fpga/mqnic/fb2CG/fpga_25g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic/fb2CG/fpga_25g/tb/xgmii_ep.py b/fpga/mqnic/fb2CG/fpga_25g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic/fb2CG/fpga_25g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..4ac009807 --- /dev/null +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_ctrl_tdma.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..323f44feb --- /dev/null +++ b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,713 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_0_rx_clk_0, 6.4, units="ns").start()) + self.qsfp_0_0_source = XgmiiSource(dut.qsfp_0_rxd_0, dut.qsfp_0_rxc_0, dut.qsfp_0_rx_clk_0, dut.qsfp_0_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_0, 6.4, units="ns").start()) + self.qsfp_0_0_sink = XgmiiSink(dut.qsfp_0_txd_0, dut.qsfp_0_txc_0, dut.qsfp_0_tx_clk_0, dut.qsfp_0_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_0_1_source = XgmiiSource(dut.qsfp_0_rxd_1, dut.qsfp_0_rxc_1, dut.qsfp_0_rx_clk_1, dut.qsfp_0_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_0_1_sink = XgmiiSink(dut.qsfp_0_txd_1, dut.qsfp_0_txc_1, dut.qsfp_0_tx_clk_1, dut.qsfp_0_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_0_2_source = XgmiiSource(dut.qsfp_0_rxd_2, dut.qsfp_0_rxc_2, dut.qsfp_0_rx_clk_2, dut.qsfp_0_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_0_2_sink = XgmiiSink(dut.qsfp_0_txd_2, dut.qsfp_0_txc_2, dut.qsfp_0_tx_clk_2, dut.qsfp_0_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_0_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_0_3_source = XgmiiSource(dut.qsfp_0_rxd_3, dut.qsfp_0_rxc_3, dut.qsfp_0_rx_clk_3, dut.qsfp_0_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_0_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_0_3_sink = XgmiiSink(dut.qsfp_0_txd_3, dut.qsfp_0_txc_3, dut.qsfp_0_tx_clk_3, dut.qsfp_0_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_0, 6.4, units="ns").start()) + self.qsfp_1_0_source = XgmiiSource(dut.qsfp_1_rxd_0, dut.qsfp_1_rxc_0, dut.qsfp_1_rx_clk_0, dut.qsfp_1_rx_rst_0) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_0, 6.4, units="ns").start()) + self.qsfp_1_0_sink = XgmiiSink(dut.qsfp_1_txd_0, dut.qsfp_1_txc_0, dut.qsfp_1_tx_clk_0, dut.qsfp_1_tx_rst_0) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_1_source = XgmiiSource(dut.qsfp_1_rxd_1, dut.qsfp_1_rxc_1, dut.qsfp_1_rx_clk_1, dut.qsfp_1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_1_sink = XgmiiSink(dut.qsfp_1_txd_1, dut.qsfp_1_txc_1, dut.qsfp_1_tx_clk_1, dut.qsfp_1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_1_2_source = XgmiiSource(dut.qsfp_1_rxd_2, dut.qsfp_1_rxc_2, dut.qsfp_1_rx_clk_2, dut.qsfp_1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_1_2_sink = XgmiiSink(dut.qsfp_1_txd_2, dut.qsfp_1_txc_2, dut.qsfp_1_tx_clk_2, dut.qsfp_1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_1_3_source = XgmiiSource(dut.qsfp_1_rxd_3, dut.qsfp_1_rxc_3, dut.qsfp_1_rx_clk_3, dut.qsfp_1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_1_3_sink = XgmiiSink(dut.qsfp_1_txd_3, dut.qsfp_1_txc_3, dut.qsfp_1_tx_clk_3, dut.qsfp_1_tx_rst_3) + + dut.user_sw.setimmediatevalue(0) + + dut.qsfp_0_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_0_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_1_rx_error_count_0.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_1_rx_error_count_3.setimmediatevalue(0) + + dut.qsfp_0_modprs_l.setimmediatevalue(0) + dut.qsfp_1_modprs_l.setimmediatevalue(0) + + dut.qsfp_int_l.setimmediatevalue(1) + dut.qsfp_i2c_scl_i.setimmediatevalue(1) + dut.qsfp_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_0_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_0_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_0_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_0.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_1_tx_rst_3.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_0_0_sink.empty(): + self.qsfp_0_0_source.send(self.qsfp_0_0_sink.recv()) + if not self.qsfp_0_1_sink.empty(): + self.qsfp_0_1_source.send(self.qsfp_0_1_sink.recv()) + if not self.qsfp_0_2_sink.empty(): + self.qsfp_0_2_source.send(self.qsfp_0_2_sink.recv()) + if not self.qsfp_0_3_sink.empty(): + self.qsfp_0_3_source.send(self.qsfp_0_3_sink.recv()) + if not self.qsfp_1_0_sink.empty(): + self.qsfp_1_0_source.send(self.qsfp_1_0_sink.recv()) + if not self.qsfp_1_1_sink.empty(): + self.qsfp_1_1_source.send(self.qsfp_1_1_sink.recv()) + if not self.qsfp_1_2_sink.empty(): + self.qsfp_1_2_source.send(self.qsfp_1_2_sink.recv()) + if not self.qsfp_1_3_sink.empty(): + self.qsfp_1_3_source.send(self.qsfp_1_3_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp_1_0_sink.wait() + + # pkt = tb.qsfp_1_0_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp_1_0_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_0_0_sink.wait() + + pkt = tb.qsfp_0_0_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_0_0_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await Timer(1000, 'ns') + + tb.log.info("TDMA") + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + # configure TDMA scheduler + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) + + # enable queues with global enable off + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) + + # configure slots + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) + + await tb.rc.mem_read(tb.driver.hw_addr, 4) # wait for all writes to complete + + # send packets + for k in range(count): + await tb.driver.interfaces[0].start_xmit(pkts[k], k % 4) + + for k in range(count): + pkt = tb.driver.interfaces[0].recv() + + if not pkt: + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + print(pkt) + # assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_ctrl_tdma.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = int(parameters['AXIS_PCIE_DATA_WIDTH']/32) + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/mqnic.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie_us.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie_usp.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index 19258a6d6..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1105 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tx_scheduler_ctrl_tdma.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - user_sw = Signal(intbv(0)[2:]) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_0_tx_clk_0 = Signal(bool(0)) - qsfp_0_tx_rst_0 = Signal(bool(0)) - qsfp_0_rx_clk_0 = Signal(bool(0)) - qsfp_0_rx_rst_0 = Signal(bool(0)) - qsfp_0_rxd_0 = Signal(intbv(0)[64:]) - qsfp_0_rxc_0 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_1 = Signal(bool(0)) - qsfp_0_tx_rst_1 = Signal(bool(0)) - qsfp_0_rx_clk_1 = Signal(bool(0)) - qsfp_0_rx_rst_1 = Signal(bool(0)) - qsfp_0_rxd_1 = Signal(intbv(0)[64:]) - qsfp_0_rxc_1 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_2 = Signal(bool(0)) - qsfp_0_tx_rst_2 = Signal(bool(0)) - qsfp_0_rx_clk_2 = Signal(bool(0)) - qsfp_0_rx_rst_2 = Signal(bool(0)) - qsfp_0_rxd_2 = Signal(intbv(0)[64:]) - qsfp_0_rxc_2 = Signal(intbv(0)[8:]) - qsfp_0_tx_clk_3 = Signal(bool(0)) - qsfp_0_tx_rst_3 = Signal(bool(0)) - qsfp_0_rx_clk_3 = Signal(bool(0)) - qsfp_0_rx_rst_3 = Signal(bool(0)) - qsfp_0_rxd_3 = Signal(intbv(0)[64:]) - qsfp_0_rxc_3 = Signal(intbv(0)[8:]) - qsfp_0_modprs_l = Signal(bool(0)) - qsfp_1_tx_clk_0 = Signal(bool(0)) - qsfp_1_tx_rst_0 = Signal(bool(0)) - qsfp_1_rx_clk_0 = Signal(bool(0)) - qsfp_1_rx_rst_0 = Signal(bool(0)) - qsfp_1_rxd_0 = Signal(intbv(0)[64:]) - qsfp_1_rxc_0 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_1 = Signal(bool(0)) - qsfp_1_tx_rst_1 = Signal(bool(0)) - qsfp_1_rx_clk_1 = Signal(bool(0)) - qsfp_1_rx_rst_1 = Signal(bool(0)) - qsfp_1_rxd_1 = Signal(intbv(0)[64:]) - qsfp_1_rxc_1 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_2 = Signal(bool(0)) - qsfp_1_tx_rst_2 = Signal(bool(0)) - qsfp_1_rx_clk_2 = Signal(bool(0)) - qsfp_1_rx_rst_2 = Signal(bool(0)) - qsfp_1_rxd_2 = Signal(intbv(0)[64:]) - qsfp_1_rxc_2 = Signal(intbv(0)[8:]) - qsfp_1_tx_clk_3 = Signal(bool(0)) - qsfp_1_tx_rst_3 = Signal(bool(0)) - qsfp_1_rx_clk_3 = Signal(bool(0)) - qsfp_1_rx_rst_3 = Signal(bool(0)) - qsfp_1_rxd_3 = Signal(intbv(0)[64:]) - qsfp_1_rxc_3 = Signal(intbv(0)[8:]) - qsfp_1_modprs_l = Signal(bool(0)) - qsfp_int_l = Signal(bool(0)) - qsfp_i2c_scl_i = Signal(bool(1)) - qsfp_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - user_led_g = Signal(intbv(0)[2:]) - user_led_r = Signal(bool(0)) - front_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp_0_txd_0 = Signal(intbv(0)[64:]) - qsfp_0_txc_0 = Signal(intbv(0)[8:]) - qsfp_0_txd_1 = Signal(intbv(0)[64:]) - qsfp_0_txc_1 = Signal(intbv(0)[8:]) - qsfp_0_txd_2 = Signal(intbv(0)[64:]) - qsfp_0_txc_2 = Signal(intbv(0)[8:]) - qsfp_0_txd_3 = Signal(intbv(0)[64:]) - qsfp_0_txc_3 = Signal(intbv(0)[8:]) - qsfp_0_sel_l = Signal(bool(1)) - qsfp_1_txd_0 = Signal(intbv(0)[64:]) - qsfp_1_txc_0 = Signal(intbv(0)[8:]) - qsfp_1_txd_1 = Signal(intbv(0)[64:]) - qsfp_1_txc_1 = Signal(intbv(0)[8:]) - qsfp_1_txd_2 = Signal(intbv(0)[64:]) - qsfp_1_txc_2 = Signal(intbv(0)[8:]) - qsfp_1_txd_3 = Signal(intbv(0)[64:]) - qsfp_1_txc_3 = Signal(intbv(0)[8:]) - qsfp_1_sel_l = Signal(bool(1)) - qsfp_reset_l = Signal(bool(1)) - qsfp_i2c_scl_o = Signal(bool(1)) - qsfp_i2c_scl_t = Signal(bool(1)) - qsfp_i2c_sda_o = Signal(bool(1)) - qsfp_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - eeprom_wp = Signal(bool(1)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp_0_0_source = xgmii_ep.XGMIISource() - qsfp_0_0_source_logic = qsfp_0_0_source.create_logic(qsfp_0_rx_clk_0, qsfp_0_rx_rst_0, txd=qsfp_0_rxd_0, txc=qsfp_0_rxc_0, name='qsfp_0_0_source') - - qsfp_0_0_sink = xgmii_ep.XGMIISink() - qsfp_0_0_sink_logic = qsfp_0_0_sink.create_logic(qsfp_0_tx_clk_0, qsfp_0_tx_rst_0, rxd=qsfp_0_txd_0, rxc=qsfp_0_txc_0, name='qsfp_0_0_sink') - - qsfp_0_1_source = xgmii_ep.XGMIISource() - qsfp_0_1_source_logic = qsfp_0_1_source.create_logic(qsfp_0_rx_clk_1, qsfp_0_rx_rst_1, txd=qsfp_0_rxd_1, txc=qsfp_0_rxc_1, name='qsfp_0_1_source') - - qsfp_0_1_sink = xgmii_ep.XGMIISink() - qsfp_0_1_sink_logic = qsfp_0_1_sink.create_logic(qsfp_0_tx_clk_1, qsfp_0_tx_rst_1, rxd=qsfp_0_txd_1, rxc=qsfp_0_txc_1, name='qsfp_0_1_sink') - - qsfp_0_2_source = xgmii_ep.XGMIISource() - qsfp_0_2_source_logic = qsfp_0_2_source.create_logic(qsfp_0_rx_clk_2, qsfp_0_rx_rst_2, txd=qsfp_0_rxd_2, txc=qsfp_0_rxc_2, name='qsfp_0_2_source') - - qsfp_0_2_sink = xgmii_ep.XGMIISink() - qsfp_0_2_sink_logic = qsfp_0_2_sink.create_logic(qsfp_0_tx_clk_2, qsfp_0_tx_rst_2, rxd=qsfp_0_txd_2, rxc=qsfp_0_txc_2, name='qsfp_0_2_sink') - - qsfp_0_3_source = xgmii_ep.XGMIISource() - qsfp_0_3_source_logic = qsfp_0_3_source.create_logic(qsfp_0_rx_clk_3, qsfp_0_rx_rst_3, txd=qsfp_0_rxd_3, txc=qsfp_0_rxc_3, name='qsfp_0_3_source') - - qsfp_0_3_sink = xgmii_ep.XGMIISink() - qsfp_0_3_sink_logic = qsfp_0_3_sink.create_logic(qsfp_0_tx_clk_3, qsfp_0_tx_rst_3, rxd=qsfp_0_txd_3, rxc=qsfp_0_txc_3, name='qsfp_0_3_sink') - - qsfp_1_0_source = xgmii_ep.XGMIISource() - qsfp_1_0_source_logic = qsfp_1_0_source.create_logic(qsfp_1_rx_clk_0, qsfp_1_rx_rst_0, txd=qsfp_1_rxd_0, txc=qsfp_1_rxc_0, name='qsfp_1_0_source') - - qsfp_1_0_sink = xgmii_ep.XGMIISink() - qsfp_1_0_sink_logic = qsfp_1_0_sink.create_logic(qsfp_1_tx_clk_0, qsfp_1_tx_rst_0, rxd=qsfp_1_txd_0, rxc=qsfp_1_txc_0, name='qsfp_1_0_sink') - - qsfp_1_1_source = xgmii_ep.XGMIISource() - qsfp_1_1_source_logic = qsfp_1_1_source.create_logic(qsfp_1_rx_clk_1, qsfp_1_rx_rst_1, txd=qsfp_1_rxd_1, txc=qsfp_1_rxc_1, name='qsfp_1_1_source') - - qsfp_1_1_sink = xgmii_ep.XGMIISink() - qsfp_1_1_sink_logic = qsfp_1_1_sink.create_logic(qsfp_1_tx_clk_1, qsfp_1_tx_rst_1, rxd=qsfp_1_txd_1, rxc=qsfp_1_txc_1, name='qsfp_1_1_sink') - - qsfp_1_2_source = xgmii_ep.XGMIISource() - qsfp_1_2_source_logic = qsfp_1_2_source.create_logic(qsfp_1_rx_clk_2, qsfp_1_rx_rst_2, txd=qsfp_1_rxd_2, txc=qsfp_1_rxc_2, name='qsfp_1_2_source') - - qsfp_1_2_sink = xgmii_ep.XGMIISink() - qsfp_1_2_sink_logic = qsfp_1_2_sink.create_logic(qsfp_1_tx_clk_2, qsfp_1_tx_rst_2, rxd=qsfp_1_txd_2, rxc=qsfp_1_txc_2, name='qsfp_1_2_sink') - - qsfp_1_3_source = xgmii_ep.XGMIISource() - qsfp_1_3_source_logic = qsfp_1_3_source.create_logic(qsfp_1_rx_clk_3, qsfp_1_rx_rst_3, txd=qsfp_1_rxd_3, txc=qsfp_1_rxc_3, name='qsfp_1_3_source') - - qsfp_1_3_sink = xgmii_ep.XGMIISink() - qsfp_1_3_sink_logic = qsfp_1_3_sink.create_logic(qsfp_1_tx_clk_3, qsfp_1_tx_rst_3, rxd=qsfp_1_txd_3, rxc=qsfp_1_txc_3, name='qsfp_1_3_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - user_led_g=user_led_g, - user_led_r=user_led_r, - front_led=front_led, - user_sw=user_sw, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_0_tx_clk_0=qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0=qsfp_0_tx_rst_0, - qsfp_0_txd_0=qsfp_0_txd_0, - qsfp_0_txc_0=qsfp_0_txc_0, - qsfp_0_rx_clk_0=qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0=qsfp_0_rx_rst_0, - qsfp_0_rxd_0=qsfp_0_rxd_0, - qsfp_0_rxc_0=qsfp_0_rxc_0, - qsfp_0_tx_clk_1=qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1=qsfp_0_tx_rst_1, - qsfp_0_txd_1=qsfp_0_txd_1, - qsfp_0_txc_1=qsfp_0_txc_1, - qsfp_0_rx_clk_1=qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1=qsfp_0_rx_rst_1, - qsfp_0_rxd_1=qsfp_0_rxd_1, - qsfp_0_rxc_1=qsfp_0_rxc_1, - qsfp_0_tx_clk_2=qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2=qsfp_0_tx_rst_2, - qsfp_0_txd_2=qsfp_0_txd_2, - qsfp_0_txc_2=qsfp_0_txc_2, - qsfp_0_rx_clk_2=qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2=qsfp_0_rx_rst_2, - qsfp_0_rxd_2=qsfp_0_rxd_2, - qsfp_0_rxc_2=qsfp_0_rxc_2, - qsfp_0_tx_clk_3=qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3=qsfp_0_tx_rst_3, - qsfp_0_txd_3=qsfp_0_txd_3, - qsfp_0_txc_3=qsfp_0_txc_3, - qsfp_0_rx_clk_3=qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3=qsfp_0_rx_rst_3, - qsfp_0_rxd_3=qsfp_0_rxd_3, - qsfp_0_rxc_3=qsfp_0_rxc_3, - qsfp_0_modprs_l=qsfp_0_modprs_l, - qsfp_0_sel_l=qsfp_0_sel_l, - qsfp_1_tx_clk_0=qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0=qsfp_1_tx_rst_0, - qsfp_1_txd_0=qsfp_1_txd_0, - qsfp_1_txc_0=qsfp_1_txc_0, - qsfp_1_rx_clk_0=qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0=qsfp_1_rx_rst_0, - qsfp_1_rxd_0=qsfp_1_rxd_0, - qsfp_1_rxc_0=qsfp_1_rxc_0, - qsfp_1_tx_clk_1=qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1=qsfp_1_tx_rst_1, - qsfp_1_txd_1=qsfp_1_txd_1, - qsfp_1_txc_1=qsfp_1_txc_1, - qsfp_1_rx_clk_1=qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1=qsfp_1_rx_rst_1, - qsfp_1_rxd_1=qsfp_1_rxd_1, - qsfp_1_rxc_1=qsfp_1_rxc_1, - qsfp_1_tx_clk_2=qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2=qsfp_1_tx_rst_2, - qsfp_1_txd_2=qsfp_1_txd_2, - qsfp_1_txc_2=qsfp_1_txc_2, - qsfp_1_rx_clk_2=qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2=qsfp_1_rx_rst_2, - qsfp_1_rxd_2=qsfp_1_rxd_2, - qsfp_1_rxc_2=qsfp_1_rxc_2, - qsfp_1_tx_clk_3=qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3=qsfp_1_tx_rst_3, - qsfp_1_txd_3=qsfp_1_txd_3, - qsfp_1_txc_3=qsfp_1_txc_3, - qsfp_1_rx_clk_3=qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3=qsfp_1_rx_rst_3, - qsfp_1_rxd_3=qsfp_1_rxd_3, - qsfp_1_rxc_3=qsfp_1_rxc_3, - qsfp_1_modprs_l=qsfp_1_modprs_l, - qsfp_1_sel_l=qsfp_1_sel_l, - qsfp_reset_l=qsfp_reset_l, - qsfp_int_l=qsfp_int_l, - qsfp_i2c_scl_i=qsfp_i2c_scl_i, - qsfp_i2c_scl_o=qsfp_i2c_scl_o, - qsfp_i2c_scl_t=qsfp_i2c_scl_t, - qsfp_i2c_sda_i=qsfp_i2c_sda_i, - qsfp_i2c_sda_o=qsfp_i2c_sda_o, - qsfp_i2c_sda_t=qsfp_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - eeprom_wp=eeprom_wp, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp_0_tx_clk_0.next = not qsfp_0_tx_clk_0 - qsfp_0_rx_clk_0.next = not qsfp_0_rx_clk_0 - qsfp_0_tx_clk_1.next = not qsfp_0_tx_clk_1 - qsfp_0_rx_clk_1.next = not qsfp_0_rx_clk_1 - qsfp_0_tx_clk_2.next = not qsfp_0_tx_clk_2 - qsfp_0_rx_clk_2.next = not qsfp_0_rx_clk_2 - qsfp_0_tx_clk_3.next = not qsfp_0_tx_clk_3 - qsfp_0_rx_clk_3.next = not qsfp_0_rx_clk_3 - qsfp_1_tx_clk_0.next = not qsfp_1_tx_clk_0 - qsfp_1_rx_clk_0.next = not qsfp_1_rx_clk_0 - qsfp_1_tx_clk_1.next = not qsfp_1_tx_clk_1 - qsfp_1_rx_clk_1.next = not qsfp_1_rx_clk_1 - qsfp_1_tx_clk_2.next = not qsfp_1_tx_clk_2 - qsfp_1_rx_clk_2.next = not qsfp_1_rx_clk_2 - qsfp_1_tx_clk_3.next = not qsfp_1_tx_clk_3 - qsfp_1_rx_clk_3.next = not qsfp_1_rx_clk_3 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_0_0_sink.empty(): - pkt = qsfp_0_0_sink.recv() - qsfp_0_0_source.send(pkt) - if not qsfp_0_1_sink.empty(): - pkt = qsfp_0_1_sink.recv() - qsfp_0_1_source.send(pkt) - if not qsfp_0_2_sink.empty(): - pkt = qsfp_0_2_sink.recv() - qsfp_0_2_source.send(pkt) - if not qsfp_0_3_sink.empty(): - pkt = qsfp_0_3_sink.recv() - qsfp_0_3_source.send(pkt) - if not qsfp_1_0_sink.empty(): - pkt = qsfp_1_0_sink.recv() - qsfp_1_0_source.send(pkt) - if not qsfp_1_1_sink.empty(): - pkt = qsfp_1_1_sink.recv() - qsfp_1_1_source.send(pkt) - if not qsfp_1_2_sink.empty(): - pkt = qsfp_1_2_sink.recv() - qsfp_1_2_source.send(pkt) - if not qsfp_1_3_sink.empty(): - pkt = qsfp_1_3_sink.recv() - qsfp_1_3_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_0_tx_rst_0.next = 1 - qsfp_0_rx_rst_0.next = 1 - qsfp_0_tx_rst_1.next = 1 - qsfp_0_rx_rst_1.next = 1 - qsfp_0_tx_rst_2.next = 1 - qsfp_0_rx_rst_2.next = 1 - qsfp_0_tx_rst_3.next = 1 - qsfp_0_rx_rst_3.next = 1 - qsfp_1_tx_rst_0.next = 1 - qsfp_1_rx_rst_0.next = 1 - qsfp_1_tx_rst_1.next = 1 - qsfp_1_rx_rst_1.next = 1 - qsfp_1_tx_rst_2.next = 1 - qsfp_1_rx_rst_2.next = 1 - qsfp_1_tx_rst_3.next = 1 - qsfp_1_rx_rst_3.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp_0_tx_rst_0.next = 0 - qsfp_0_rx_rst_0.next = 0 - qsfp_0_tx_rst_1.next = 0 - qsfp_0_rx_rst_1.next = 0 - qsfp_0_tx_rst_2.next = 0 - qsfp_0_rx_rst_2.next = 0 - qsfp_0_tx_rst_3.next = 0 - qsfp_0_rx_rst_3.next = 0 - qsfp_1_tx_rst_0.next = 0 - qsfp_1_rx_rst_0.next = 0 - qsfp_1_tx_rst_1.next = 0 - qsfp_1_rx_rst_1.next = 0 - qsfp_1_tx_rst_2.next = 0 - qsfp_1_rx_rst_2.next = 0 - qsfp_1_tx_rst_3.next = 0 - qsfp_1_rx_rst_3.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp_1_0_sink.wait() - - # pkt = qsfp_1_0_sink.recv() - # print(pkt) - - # qsfp_1_0_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_0_0_sink.wait() - - pkt = qsfp_0_0_sink.recv() - print(pkt) - - qsfp_0_0_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(1000) - - yield clk.posedge - print("test 7: TDMA") - current_test.next = 7 - - count = 16 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - # configure TDMA - - # configure TDMA scheduler - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) # schedule period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) # schedule period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) # schedule period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) # schedule period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) # timeslot period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) # timeslot period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) # timeslot period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) # timeslot period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) # active period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) # active period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) # active period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) # active period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) # enable TDMA - - # enable queues with global enable off - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) - - # configure slots - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - # send packets - for k in range(count): - yield from driver.interfaces[0].start_xmit(pkts[k], k%4) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - #assert pkt.data == pkts[k] - #assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index fd659261e..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,576 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg [1:0] user_sw = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_0_tx_clk_0 = 0; -reg qsfp_0_tx_rst_0 = 0; -reg qsfp_0_rx_clk_0 = 0; -reg qsfp_0_rx_rst_0 = 0; -reg [63:0] qsfp_0_rxd_0 = 0; -reg [7:0] qsfp_0_rxc_0 = 0; -reg qsfp_0_tx_clk_1 = 0; -reg qsfp_0_tx_rst_1 = 0; -reg qsfp_0_rx_clk_1 = 0; -reg qsfp_0_rx_rst_1 = 0; -reg [63:0] qsfp_0_rxd_1 = 0; -reg [7:0] qsfp_0_rxc_1 = 0; -reg qsfp_0_tx_clk_2 = 0; -reg qsfp_0_tx_rst_2 = 0; -reg qsfp_0_rx_clk_2 = 0; -reg qsfp_0_rx_rst_2 = 0; -reg [63:0] qsfp_0_rxd_2 = 0; -reg [7:0] qsfp_0_rxc_2 = 0; -reg qsfp_0_tx_clk_3 = 0; -reg qsfp_0_tx_rst_3 = 0; -reg qsfp_0_rx_clk_3 = 0; -reg qsfp_0_rx_rst_3 = 0; -reg [63:0] qsfp_0_rxd_3 = 0; -reg [7:0] qsfp_0_rxc_3 = 0; -reg qsfp_0_modprs_l = 0; -reg qsfp_1_tx_clk_0 = 0; -reg qsfp_1_tx_rst_0 = 0; -reg qsfp_1_rx_clk_0 = 0; -reg qsfp_1_rx_rst_0 = 0; -reg [63:0] qsfp_1_rxd_0 = 0; -reg [7:0] qsfp_1_rxc_0 = 0; -reg qsfp_1_tx_clk_1 = 0; -reg qsfp_1_tx_rst_1 = 0; -reg qsfp_1_rx_clk_1 = 0; -reg qsfp_1_rx_rst_1 = 0; -reg [63:0] qsfp_1_rxd_1 = 0; -reg [7:0] qsfp_1_rxc_1 = 0; -reg qsfp_1_tx_clk_2 = 0; -reg qsfp_1_tx_rst_2 = 0; -reg qsfp_1_rx_clk_2 = 0; -reg qsfp_1_rx_rst_2 = 0; -reg [63:0] qsfp_1_rxd_2 = 0; -reg [7:0] qsfp_1_rxc_2 = 0; -reg qsfp_1_tx_clk_3 = 0; -reg qsfp_1_tx_rst_3 = 0; -reg qsfp_1_rx_clk_3 = 0; -reg qsfp_1_rx_rst_3 = 0; -reg [63:0] qsfp_1_rxd_3 = 0; -reg [7:0] qsfp_1_rxc_3 = 0; -reg qsfp_1_modprs_l = 0; -reg qsfp_int_l = 0; -reg qsfp_i2c_scl_i = 1; -reg qsfp_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [1:0] user_led_g; -wire user_led_r; -wire [1:0] front_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_0_txd_0; -wire [7:0] qsfp_0_txc_0; -wire [63:0] qsfp_0_txd_1; -wire [7:0] qsfp_0_txc_1; -wire [63:0] qsfp_0_txd_2; -wire [7:0] qsfp_0_txc_2; -wire [63:0] qsfp_0_txd_3; -wire [7:0] qsfp_0_txc_3; -wire qsfp_0_sel_l; -wire [63:0] qsfp_1_txd_0; -wire [7:0] qsfp_1_txc_0; -wire [63:0] qsfp_1_txd_1; -wire [7:0] qsfp_1_txc_1; -wire [63:0] qsfp_1_txd_2; -wire [7:0] qsfp_1_txc_2; -wire [63:0] qsfp_1_txd_3; -wire [7:0] qsfp_1_txc_3; -wire qsfp_1_sel_l; -wire qsfp_reset_l; -wire qsfp_i2c_scl_o; -wire qsfp_i2c_scl_t; -wire qsfp_i2c_sda_o; -wire qsfp_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire eeprom_wp; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - user_sw, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_0_tx_clk_0, - qsfp_0_tx_rst_0, - qsfp_0_rx_clk_0, - qsfp_0_rx_rst_0, - qsfp_0_rxd_0, - qsfp_0_rxc_0, - qsfp_0_tx_clk_1, - qsfp_0_tx_rst_1, - qsfp_0_rx_clk_1, - qsfp_0_rx_rst_1, - qsfp_0_rxd_1, - qsfp_0_rxc_1, - qsfp_0_tx_clk_2, - qsfp_0_tx_rst_2, - qsfp_0_rx_clk_2, - qsfp_0_rx_rst_2, - qsfp_0_rxd_2, - qsfp_0_rxc_2, - qsfp_0_tx_clk_3, - qsfp_0_tx_rst_3, - qsfp_0_rx_clk_3, - qsfp_0_rx_rst_3, - qsfp_0_rxd_3, - qsfp_0_rxc_3, - qsfp_0_modprs_l, - qsfp_1_tx_clk_0, - qsfp_1_tx_rst_0, - qsfp_1_rx_clk_0, - qsfp_1_rx_rst_0, - qsfp_1_rxd_0, - qsfp_1_rxc_0, - qsfp_1_tx_clk_1, - qsfp_1_tx_rst_1, - qsfp_1_rx_clk_1, - qsfp_1_rx_rst_1, - qsfp_1_rxd_1, - qsfp_1_rxc_1, - qsfp_1_tx_clk_2, - qsfp_1_tx_rst_2, - qsfp_1_rx_clk_2, - qsfp_1_rx_rst_2, - qsfp_1_rxd_2, - qsfp_1_rxc_2, - qsfp_1_tx_clk_3, - qsfp_1_tx_rst_3, - qsfp_1_rx_clk_3, - qsfp_1_rx_rst_3, - qsfp_1_rxd_3, - qsfp_1_rxc_3, - qsfp_1_modprs_l, - qsfp_int_l, - qsfp_i2c_scl_i, - qsfp_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - user_led_g, - user_led_r, - front_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_0_txd_0, - qsfp_0_txc_0, - qsfp_0_txd_1, - qsfp_0_txc_1, - qsfp_0_txd_2, - qsfp_0_txc_2, - qsfp_0_txd_3, - qsfp_0_txc_3, - qsfp_0_sel_l, - qsfp_1_txd_0, - qsfp_1_txc_0, - qsfp_1_txd_1, - qsfp_1_txc_1, - qsfp_1_txd_2, - qsfp_1_txc_2, - qsfp_1_txd_3, - qsfp_1_txc_3, - qsfp_1_sel_l, - qsfp_reset_l, - qsfp_i2c_scl_o, - qsfp_i2c_scl_t, - qsfp_i2c_sda_o, - qsfp_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - eeprom_wp, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .user_led_g(user_led_g), - .user_led_r(user_led_r), - .front_led(front_led), - .user_sw(user_sw), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_0_tx_clk_0(qsfp_0_tx_clk_0), - .qsfp_0_tx_rst_0(qsfp_0_tx_rst_0), - .qsfp_0_txd_0(qsfp_0_txd_0), - .qsfp_0_txc_0(qsfp_0_txc_0), - .qsfp_0_rx_clk_0(qsfp_0_rx_clk_0), - .qsfp_0_rx_rst_0(qsfp_0_rx_rst_0), - .qsfp_0_rxd_0(qsfp_0_rxd_0), - .qsfp_0_rxc_0(qsfp_0_rxc_0), - .qsfp_0_tx_clk_1(qsfp_0_tx_clk_1), - .qsfp_0_tx_rst_1(qsfp_0_tx_rst_1), - .qsfp_0_txd_1(qsfp_0_txd_1), - .qsfp_0_txc_1(qsfp_0_txc_1), - .qsfp_0_rx_clk_1(qsfp_0_rx_clk_1), - .qsfp_0_rx_rst_1(qsfp_0_rx_rst_1), - .qsfp_0_rxd_1(qsfp_0_rxd_1), - .qsfp_0_rxc_1(qsfp_0_rxc_1), - .qsfp_0_tx_clk_2(qsfp_0_tx_clk_2), - .qsfp_0_tx_rst_2(qsfp_0_tx_rst_2), - .qsfp_0_txd_2(qsfp_0_txd_2), - .qsfp_0_txc_2(qsfp_0_txc_2), - .qsfp_0_rx_clk_2(qsfp_0_rx_clk_2), - .qsfp_0_rx_rst_2(qsfp_0_rx_rst_2), - .qsfp_0_rxd_2(qsfp_0_rxd_2), - .qsfp_0_rxc_2(qsfp_0_rxc_2), - .qsfp_0_tx_clk_3(qsfp_0_tx_clk_3), - .qsfp_0_tx_rst_3(qsfp_0_tx_rst_3), - .qsfp_0_txd_3(qsfp_0_txd_3), - .qsfp_0_txc_3(qsfp_0_txc_3), - .qsfp_0_rx_clk_3(qsfp_0_rx_clk_3), - .qsfp_0_rx_rst_3(qsfp_0_rx_rst_3), - .qsfp_0_rxd_3(qsfp_0_rxd_3), - .qsfp_0_rxc_3(qsfp_0_rxc_3), - .qsfp_0_modprs_l(qsfp_0_modprs_l), - .qsfp_0_sel_l(qsfp_0_sel_l), - .qsfp_1_tx_clk_0(qsfp_1_tx_clk_0), - .qsfp_1_tx_rst_0(qsfp_1_tx_rst_0), - .qsfp_1_txd_0(qsfp_1_txd_0), - .qsfp_1_txc_0(qsfp_1_txc_0), - .qsfp_1_rx_clk_0(qsfp_1_rx_clk_0), - .qsfp_1_rx_rst_0(qsfp_1_rx_rst_0), - .qsfp_1_rxd_0(qsfp_1_rxd_0), - .qsfp_1_rxc_0(qsfp_1_rxc_0), - .qsfp_1_tx_clk_1(qsfp_1_tx_clk_1), - .qsfp_1_tx_rst_1(qsfp_1_tx_rst_1), - .qsfp_1_txd_1(qsfp_1_txd_1), - .qsfp_1_txc_1(qsfp_1_txc_1), - .qsfp_1_rx_clk_1(qsfp_1_rx_clk_1), - .qsfp_1_rx_rst_1(qsfp_1_rx_rst_1), - .qsfp_1_rxd_1(qsfp_1_rxd_1), - .qsfp_1_rxc_1(qsfp_1_rxc_1), - .qsfp_1_tx_clk_2(qsfp_1_tx_clk_2), - .qsfp_1_tx_rst_2(qsfp_1_tx_rst_2), - .qsfp_1_txd_2(qsfp_1_txd_2), - .qsfp_1_txc_2(qsfp_1_txc_2), - .qsfp_1_rx_clk_2(qsfp_1_rx_clk_2), - .qsfp_1_rx_rst_2(qsfp_1_rx_rst_2), - .qsfp_1_rxd_2(qsfp_1_rxd_2), - .qsfp_1_rxc_2(qsfp_1_rxc_2), - .qsfp_1_tx_clk_3(qsfp_1_tx_clk_3), - .qsfp_1_tx_rst_3(qsfp_1_tx_rst_3), - .qsfp_1_txd_3(qsfp_1_txd_3), - .qsfp_1_txc_3(qsfp_1_txc_3), - .qsfp_1_rx_clk_3(qsfp_1_rx_clk_3), - .qsfp_1_rx_rst_3(qsfp_1_rx_rst_3), - .qsfp_1_rxd_3(qsfp_1_rxd_3), - .qsfp_1_rxc_3(qsfp_1_rxc_3), - .qsfp_1_modprs_l(qsfp_1_modprs_l), - .qsfp_1_sel_l(qsfp_1_sel_l), - .qsfp_reset_l(qsfp_reset_l), - .qsfp_int_l(qsfp_int_l), - .qsfp_i2c_scl_i(qsfp_i2c_scl_i), - .qsfp_i2c_scl_o(qsfp_i2c_scl_o), - .qsfp_i2c_scl_t(qsfp_i2c_scl_t), - .qsfp_i2c_sda_i(qsfp_i2c_sda_i), - .qsfp_i2c_sda_o(qsfp_i2c_sda_o), - .qsfp_i2c_sda_t(qsfp_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .eeprom_wp(eeprom_wp), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic_tdma/ADM_PCIE_9V3/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/axis_ep.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/eth_ep.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/Makefile b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/Makefile new file mode 100644 index 000000000..ad944cc4b --- /dev/null +++ b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_ctrl_tdma.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= 60 +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= 75 +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= 85 +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= 33 +export PARAM_RQ_SEQ_NUM_WIDTH ?= 4 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/mqnic.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..d662353a2 --- /dev/null +++ b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,622 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num=dut.s_axis_rq_seq_num, + pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.sfp_1_rx_clk, 6.4, units="ns").start()) + self.sfp_1_source = XgmiiSource(dut.sfp_1_rxd, dut.sfp_1_rxc, dut.sfp_1_rx_clk, dut.sfp_1_rx_rst) + cocotb.fork(Clock(dut.sfp_1_tx_clk, 6.4, units="ns").start()) + self.sfp_1_sink = XgmiiSink(dut.sfp_1_txd, dut.sfp_1_txc, dut.sfp_1_tx_clk, dut.sfp_1_tx_rst) + + cocotb.fork(Clock(dut.sfp_2_rx_clk, 6.4, units="ns").start()) + self.sfp_2_source = XgmiiSource(dut.sfp_2_rxd, dut.sfp_2_rxc, dut.sfp_2_rx_clk, dut.sfp_2_rx_rst) + cocotb.fork(Clock(dut.sfp_2_tx_clk, 6.4, units="ns").start()) + self.sfp_2_sink = XgmiiSink(dut.sfp_2_txd, dut.sfp_2_txc, dut.sfp_2_tx_clk, dut.sfp_2_tx_rst) + + dut.sfp_1_npres.setimmediatevalue(0) + dut.sfp_2_npres.setimmediatevalue(0) + dut.sfp_1_los.setimmediatevalue(0) + dut.sfp_2_los.setimmediatevalue(0) + + dut.sma_in.setimmediatevalue(0) + + dut.sfp_i2c_scl_i.setimmediatevalue(1) + dut.sfp_1_i2c_sda_i.setimmediatevalue(1) + dut.sfp_2_i2c_sda_i.setimmediatevalue(1) + + dut.eeprom_i2c_scl_i.setimmediatevalue(1) + dut.eeprom_i2c_sda_i.setimmediatevalue(1) + + dut.flash_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(1) + self.dut.sfp_1_tx_rst.setimmediatevalue(1) + self.dut.sfp_2_rx_rst.setimmediatevalue(1) + self.dut.sfp_2_tx_rst.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.sfp_1_rx_rst.setimmediatevalue(0) + self.dut.sfp_1_tx_rst.setimmediatevalue(0) + self.dut.sfp_2_rx_rst.setimmediatevalue(0) + self.dut.sfp_2_tx_rst.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.sfp_1_sink.empty(): + self.sfp_1_source.send(self.sfp_1_sink.recv()) + if not self.sfp_2_sink.empty(): + self.sfp_2_source.send(self.sfp_2_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.sfp_2_sink.wait() + + # pkt = tb.sfp_2_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.sfp_2_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.sfp_1_sink.wait() + + pkt = tb.sfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.sfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await Timer(1000, 'ns') + + tb.log.info("TDMA") + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + # configure TDMA scheduler + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) + + # enable queues with global enable off + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) + + # configure slots + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) + + await tb.rc.mem_read(tb.driver.hw_addr, 4) # wait for all writes to complete + + # send packets + for k in range(count): + await tb.driver.interfaces[0].start_xmit(pkts[k], k % 4) + + for k in range(count): + pkt = tb.driver.interfaces[0].recv() + + if not pkt: + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + print(pkt) + # assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_ctrl_tdma.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/ip_ep.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/mqnic.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/pcie.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/pcie_us.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/test_fpga_core.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/test_fpga_core.py deleted file mode 100755 index 735a9540f..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/test_fpga_core.py +++ /dev/null @@ -1,886 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_us -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tx_scheduler_ctrl_tdma.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 60 - AXIS_PCIE_CQ_USER_WIDTH = 85 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 4 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(0)[2:]) - pcie_tfc_npd_av = Signal(intbv(0)[2:]) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - sfp_1_tx_clk = Signal(bool(0)) - sfp_1_tx_rst = Signal(bool(0)) - sfp_1_rx_clk = Signal(bool(0)) - sfp_1_rx_rst = Signal(bool(0)) - sfp_1_rxd = Signal(intbv(0)[64:]) - sfp_1_rxc = Signal(intbv(0)[8:]) - sfp_2_tx_clk = Signal(bool(0)) - sfp_2_tx_rst = Signal(bool(0)) - sfp_2_rx_clk = Signal(bool(0)) - sfp_2_rx_rst = Signal(bool(0)) - sfp_2_rxd = Signal(intbv(0)[64:]) - sfp_2_rxc = Signal(intbv(0)[8:]) - sfp_1_npres = Signal(bool(0)) - sfp_2_npres = Signal(bool(0)) - sfp_1_los = Signal(bool(0)) - sfp_2_los = Signal(bool(0)) - sfp_i2c_scl_i = Signal(bool(1)) - sfp_1_i2c_sda_i = Signal(bool(1)) - sfp_2_i2c_sda_i = Signal(bool(1)) - eeprom_i2c_scl_i = Signal(bool(1)) - eeprom_i2c_sda_i = Signal(bool(1)) - flash_dq_i = Signal(intbv(0)[16:]) - - # Outputs - sfp_1_led = Signal(intbv(0)[2:]) - sfp_2_led = Signal(intbv(0)[2:]) - sma_led = Signal(intbv(0)[2:]) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - sfp_1_txd = Signal(intbv(0)[64:]) - sfp_1_txc = Signal(intbv(0)[8:]) - sfp_2_txd = Signal(intbv(0)[64:]) - sfp_2_txc = Signal(intbv(0)[8:]) - sfp_1_tx_disable = Signal(bool(0)) - sfp_2_tx_disable = Signal(bool(0)) - sfp_1_rs = Signal(bool(0)) - sfp_2_rs = Signal(bool(0)) - sfp_i2c_scl_o = Signal(bool(1)) - sfp_i2c_scl_t = Signal(bool(1)) - sfp_1_i2c_sda_o = Signal(bool(1)) - sfp_1_i2c_sda_t = Signal(bool(1)) - sfp_2_i2c_sda_o = Signal(bool(1)) - sfp_2_i2c_sda_t = Signal(bool(1)) - eeprom_i2c_scl_o = Signal(bool(1)) - eeprom_i2c_scl_t = Signal(bool(1)) - eeprom_i2c_sda_o = Signal(bool(1)) - eeprom_i2c_sda_t = Signal(bool(1)) - fpga_boot = Signal(bool(0)) - flash_dq_o = Signal(intbv(0)[16:]) - flash_dq_oe = Signal(bool(0)) - flash_addr = Signal(intbv(0)[23:]) - flash_region = Signal(bool(0)) - flash_region_oe = Signal(bool(0)) - flash_ce_n = Signal(bool(1)) - flash_oe_n = Signal(bool(1)) - flash_we_n = Signal(bool(1)) - flash_adv_n = Signal(bool(1)) - - # sources and sinks - sfp_1_source = xgmii_ep.XGMIISource() - sfp_1_source_logic = sfp_1_source.create_logic(sfp_1_rx_clk, sfp_1_rx_rst, txd=sfp_1_rxd, txc=sfp_1_rxc, name='sfp_1_source') - - sfp_1_sink = xgmii_ep.XGMIISink() - sfp_1_sink_logic = sfp_1_sink.create_logic(sfp_1_tx_clk, sfp_1_tx_rst, rxd=sfp_1_txd, rxc=sfp_1_txc, name='sfp_1_sink') - - sfp_2_source = xgmii_ep.XGMIISource() - sfp_2_source_logic = sfp_2_source.create_logic(sfp_2_rx_clk, sfp_2_rx_rst, txd=sfp_2_rxd, txc=sfp_2_rxc, name='sfp_2_source') - - sfp_2_sink = xgmii_ep.XGMIISink() - sfp_2_sink_logic = sfp_2_sink.create_logic(sfp_2_tx_clk, sfp_2_tx_rst, rxd=sfp_2_txd, rxc=sfp_2_txc, name='sfp_2_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num=s_axis_rq_seq_num, - pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - sfp_1_led=sfp_1_led, - sfp_2_led=sfp_2_led, - sma_led=sma_led, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num=s_axis_rq_seq_num, - s_axis_rq_seq_num_valid=s_axis_rq_seq_num_valid, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - sfp_1_tx_clk=sfp_1_tx_clk, - sfp_1_tx_rst=sfp_1_tx_rst, - sfp_1_txd=sfp_1_txd, - sfp_1_txc=sfp_1_txc, - sfp_1_rx_clk=sfp_1_rx_clk, - sfp_1_rx_rst=sfp_1_rx_rst, - sfp_1_rxd=sfp_1_rxd, - sfp_1_rxc=sfp_1_rxc, - sfp_2_tx_clk=sfp_2_tx_clk, - sfp_2_tx_rst=sfp_2_tx_rst, - sfp_2_txd=sfp_2_txd, - sfp_2_txc=sfp_2_txc, - sfp_2_rx_clk=sfp_2_rx_clk, - sfp_2_rx_rst=sfp_2_rx_rst, - sfp_2_rxd=sfp_2_rxd, - sfp_2_rxc=sfp_2_rxc, - sfp_1_tx_disable=sfp_1_tx_disable, - sfp_2_tx_disable=sfp_2_tx_disable, - sfp_1_npres=sfp_1_npres, - sfp_2_npres=sfp_2_npres, - sfp_1_los=sfp_1_los, - sfp_2_los=sfp_2_los, - sfp_1_rs=sfp_1_rs, - sfp_2_rs=sfp_2_rs, - sfp_i2c_scl_i=sfp_i2c_scl_i, - sfp_i2c_scl_o=sfp_i2c_scl_o, - sfp_i2c_scl_t=sfp_i2c_scl_t, - sfp_1_i2c_sda_i=sfp_1_i2c_sda_i, - sfp_1_i2c_sda_o=sfp_1_i2c_sda_o, - sfp_1_i2c_sda_t=sfp_1_i2c_sda_t, - sfp_2_i2c_sda_i=sfp_2_i2c_sda_i, - sfp_2_i2c_sda_o=sfp_2_i2c_sda_o, - sfp_2_i2c_sda_t=sfp_2_i2c_sda_t, - eeprom_i2c_scl_i=eeprom_i2c_scl_i, - eeprom_i2c_scl_o=eeprom_i2c_scl_o, - eeprom_i2c_scl_t=eeprom_i2c_scl_t, - eeprom_i2c_sda_i=eeprom_i2c_sda_i, - eeprom_i2c_sda_o=eeprom_i2c_sda_o, - eeprom_i2c_sda_t=eeprom_i2c_sda_t, - fpga_boot=fpga_boot, - flash_dq_i=flash_dq_i, - flash_dq_o=flash_dq_o, - flash_dq_oe=flash_dq_oe, - flash_addr=flash_addr, - flash_region=flash_region, - flash_region_oe=flash_region_oe, - flash_ce_n=flash_ce_n, - flash_oe_n=flash_oe_n, - flash_we_n=flash_we_n, - flash_adv_n=flash_adv_n - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - sfp_1_tx_clk.next = clk - sfp_1_tx_rst.next = rst - sfp_1_rx_clk.next = clk - sfp_1_rx_rst.next = rst - sfp_2_tx_clk.next = clk - sfp_2_tx_rst.next = rst - sfp_2_rx_clk.next = clk - sfp_2_rx_rst.next = rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not sfp_1_sink.empty(): - pkt = sfp_1_sink.recv() - sfp_1_source.send(pkt) - if not sfp_2_sink.empty(): - pkt = sfp_2_sink.recv() - sfp_2_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - yield clk.posedge - rst.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield sfp_1_sink.wait() - - pkt = sfp_1_sink.recv() - print(pkt) - - sfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(1000) - - yield clk.posedge - print("test 7: TDMA") - current_test.next = 7 - - count = 16 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - # configure TDMA - - # configure TDMA scheduler - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) # schedule period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) # schedule period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) # schedule period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) # schedule period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) # timeslot period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) # timeslot period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) # timeslot period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) # timeslot period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) # active period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) # active period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) # active period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) # active period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) # enable TDMA - - # enable queues with global enable off - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) - - # configure slots - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - # send packets - for k in range(count): - yield from driver.interfaces[0].start_xmit(pkts[k], k%4) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - #assert pkt.data == pkts[k] - #assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/test_fpga_core.v b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/test_fpga_core.v deleted file mode 100644 index 6581cb979..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/test_fpga_core.v +++ /dev/null @@ -1,441 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 256; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 60; -parameter AXIS_PCIE_CQ_USER_WIDTH = 85; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 4; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num = 0; -reg s_axis_rq_seq_num_valid = 0; -reg [1:0] pcie_tfc_nph_av = 0; -reg [1:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [7:0] cfg_interrupt_msi_vf_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg sfp_1_tx_clk = 0; -reg sfp_1_tx_rst = 0; -reg sfp_1_rx_clk = 0; -reg sfp_1_rx_rst = 0; -reg [63:0] sfp_1_rxd = 0; -reg [7:0] sfp_1_rxc = 0; -reg sfp_2_tx_clk = 0; -reg sfp_2_tx_rst = 0; -reg sfp_2_rx_clk = 0; -reg sfp_2_rx_rst = 0; -reg [63:0] sfp_2_rxd = 0; -reg [7:0] sfp_2_rxc = 0; -reg sfp_1_npres = 0; -reg sfp_2_npres = 0; -reg sfp_1_los = 0; -reg sfp_2_los = 0; -reg sfp_i2c_scl_i = 1; -reg sfp_1_i2c_sda_i = 1; -reg sfp_2_i2c_sda_i = 1; -reg eeprom_i2c_scl_i = 1; -reg eeprom_i2c_sda_i = 1; -reg [15:0] flash_dq_i = 0; - -// Outputs -wire [1:0] sfp_1_led; -wire [1:0] sfp_2_led; -wire [1:0] sma_led; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [18:0] cfg_mgmt_addr; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] sfp_1_txd; -wire [7:0] sfp_1_txc; -wire [63:0] sfp_2_txd; -wire [7:0] sfp_2_txc; -wire sfp_1_tx_disable; -wire sfp_2_tx_disable; -wire sfp_1_rs; -wire sfp_2_rs; -wire sfp_i2c_scl_o; -wire sfp_i2c_scl_t; -wire sfp_1_i2c_sda_o; -wire sfp_1_i2c_sda_t; -wire sfp_2_i2c_sda_o; -wire sfp_2_i2c_sda_t; -wire eeprom_i2c_scl_o; -wire eeprom_i2c_scl_t; -wire eeprom_i2c_sda_o; -wire eeprom_i2c_sda_t; -wire fpga_boot; -wire [15:0] flash_dq_o; -wire flash_dq_oe; -wire [22:0] flash_addr; -wire flash_region; -wire flash_region_oe; -wire flash_ce_n; -wire flash_oe_n; -wire flash_we_n; -wire flash_adv_n; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num, - s_axis_rq_seq_num_valid, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - sfp_1_tx_clk, - sfp_1_tx_rst, - sfp_1_rx_clk, - sfp_1_rx_rst, - sfp_1_rxd, - sfp_1_rxc, - sfp_2_tx_clk, - sfp_2_tx_rst, - sfp_2_rx_clk, - sfp_2_rx_rst, - sfp_2_rxd, - sfp_2_rxc, - sfp_1_npres, - sfp_2_npres, - sfp_1_los, - sfp_2_los, - sfp_i2c_scl_i, - sfp_1_i2c_sda_i, - sfp_2_i2c_sda_i, - eeprom_i2c_scl_i, - eeprom_i2c_sda_i, - flash_dq_i - ); - $to_myhdl( - sfp_1_led, - sfp_2_led, - sma_led, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - sfp_1_txd, - sfp_1_txc, - sfp_2_txd, - sfp_2_txc, - sfp_1_tx_disable, - sfp_2_tx_disable, - sfp_1_rs, - sfp_2_rs, - sfp_i2c_scl_o, - sfp_i2c_scl_t, - sfp_1_i2c_sda_o, - sfp_1_i2c_sda_t, - sfp_2_i2c_sda_o, - sfp_2_i2c_sda_t, - eeprom_i2c_scl_o, - eeprom_i2c_scl_t, - eeprom_i2c_sda_o, - eeprom_i2c_sda_t, - fpga_boot, - flash_dq_o, - flash_dq_oe, - flash_addr, - flash_region, - flash_region_oe, - flash_ce_n, - flash_oe_n, - flash_we_n, - flash_adv_n - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .sfp_1_led(sfp_1_led), - .sfp_2_led(sfp_2_led), - .sma_led(sma_led), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num(s_axis_rq_seq_num), - .s_axis_rq_seq_num_valid(s_axis_rq_seq_num_valid), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .sfp_1_tx_clk(sfp_1_tx_clk), - .sfp_1_tx_rst(sfp_1_tx_rst), - .sfp_1_txd(sfp_1_txd), - .sfp_1_txc(sfp_1_txc), - .sfp_1_rx_clk(sfp_1_rx_clk), - .sfp_1_rx_rst(sfp_1_rx_rst), - .sfp_1_rxd(sfp_1_rxd), - .sfp_1_rxc(sfp_1_rxc), - .sfp_2_tx_clk(sfp_2_tx_clk), - .sfp_2_tx_rst(sfp_2_tx_rst), - .sfp_2_txd(sfp_2_txd), - .sfp_2_txc(sfp_2_txc), - .sfp_2_rx_clk(sfp_2_rx_clk), - .sfp_2_rx_rst(sfp_2_rx_rst), - .sfp_2_rxd(sfp_2_rxd), - .sfp_2_rxc(sfp_2_rxc), - .sfp_1_tx_disable(sfp_1_tx_disable), - .sfp_2_tx_disable(sfp_2_tx_disable), - .sfp_1_npres(sfp_1_npres), - .sfp_2_npres(sfp_2_npres), - .sfp_1_los(sfp_1_los), - .sfp_2_los(sfp_2_los), - .sfp_1_rs(sfp_1_rs), - .sfp_2_rs(sfp_2_rs), - .sfp_i2c_scl_i(sfp_i2c_scl_i), - .sfp_i2c_scl_o(sfp_i2c_scl_o), - .sfp_i2c_scl_t(sfp_i2c_scl_t), - .sfp_1_i2c_sda_i(sfp_1_i2c_sda_i), - .sfp_1_i2c_sda_o(sfp_1_i2c_sda_o), - .sfp_1_i2c_sda_t(sfp_1_i2c_sda_t), - .sfp_2_i2c_sda_i(sfp_2_i2c_sda_i), - .sfp_2_i2c_sda_o(sfp_2_i2c_sda_o), - .sfp_2_i2c_sda_t(sfp_2_i2c_sda_t), - .eeprom_i2c_scl_i(eeprom_i2c_scl_i), - .eeprom_i2c_scl_o(eeprom_i2c_scl_o), - .eeprom_i2c_scl_t(eeprom_i2c_scl_t), - .eeprom_i2c_sda_i(eeprom_i2c_sda_i), - .eeprom_i2c_sda_o(eeprom_i2c_sda_o), - .eeprom_i2c_sda_t(eeprom_i2c_sda_t), - .fpga_boot(fpga_boot), - .flash_dq_i(flash_dq_i), - .flash_dq_o(flash_dq_o), - .flash_dq_oe(flash_dq_oe), - .flash_addr(flash_addr), - .flash_region(flash_region), - .flash_region_oe(flash_region_oe), - .flash_ce_n(flash_ce_n), - .flash_oe_n(flash_oe_n), - .flash_we_n(flash_we_n), - .flash_adv_n(flash_adv_n) -); - -endmodule diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/udp_ep.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/xgmii_ep.py b/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic_tdma/ExaNIC_X10/fpga/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/axis_ep.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/eth_ep.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..ad944cc4b --- /dev/null +++ b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_ctrl_tdma.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 256 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= 60 +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= 75 +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= 85 +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= 33 +export PARAM_RQ_SEQ_NUM_WIDTH ?= 4 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..a90fc863f --- /dev/null +++ b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,637 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=8, + user_clk_frequency=250e6, + alignment="dword", + straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num=dut.s_axis_rq_seq_num, + pcie_rq_seq_num_vld=dut.s_axis_rq_seq_num_valid, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_vf_enable=dut.cfg_interrupt_msi_vf_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp_rx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_source = XgmiiSource(dut.qsfp_rxd_1, dut.qsfp_rxc_1, dut.qsfp_rx_clk_1, dut.qsfp_rx_rst_1) + cocotb.fork(Clock(dut.qsfp_tx_clk_1, 6.4, units="ns").start()) + self.qsfp_1_sink = XgmiiSink(dut.qsfp_txd_1, dut.qsfp_txc_1, dut.qsfp_tx_clk_1, dut.qsfp_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp_rx_clk_2, 6.4, units="ns").start()) + self.qsfp_2_source = XgmiiSource(dut.qsfp_rxd_2, dut.qsfp_rxc_2, dut.qsfp_rx_clk_2, dut.qsfp_rx_rst_2) + cocotb.fork(Clock(dut.qsfp_tx_clk_2, 6.4, units="ns").start()) + self.qsfp_2_sink = XgmiiSink(dut.qsfp_txd_2, dut.qsfp_txc_2, dut.qsfp_tx_clk_2, dut.qsfp_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp_rx_clk_3, 6.4, units="ns").start()) + self.qsfp_3_source = XgmiiSource(dut.qsfp_rxd_3, dut.qsfp_rxc_3, dut.qsfp_rx_clk_3, dut.qsfp_rx_rst_3) + cocotb.fork(Clock(dut.qsfp_tx_clk_3, 6.4, units="ns").start()) + self.qsfp_3_sink = XgmiiSink(dut.qsfp_txd_3, dut.qsfp_txc_3, dut.qsfp_tx_clk_3, dut.qsfp_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp_rx_clk_4, 6.4, units="ns").start()) + self.qsfp_4_source = XgmiiSource(dut.qsfp_rxd_4, dut.qsfp_rxc_4, dut.qsfp_rx_clk_4, dut.qsfp_rx_rst_4) + cocotb.fork(Clock(dut.qsfp_tx_clk_4, 6.4, units="ns").start()) + self.qsfp_4_sink = XgmiiSink(dut.qsfp_txd_4, dut.qsfp_txc_4, dut.qsfp_tx_clk_4, dut.qsfp_tx_rst_4) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + dut.qsfp_rx_error_count_1.setimmediatevalue(0) + dut.qsfp_rx_error_count_2.setimmediatevalue(0) + dut.qsfp_rx_error_count_3.setimmediatevalue(0) + dut.qsfp_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp_modprsl.setimmediatevalue(0) + dut.qsfp_intl.setimmediatevalue(0) + + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.flash_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp_1_sink.empty(): + self.qsfp_1_source.send(self.qsfp_1_sink.recv()) + if not self.qsfp_2_sink.empty(): + self.qsfp_2_source.send(self.qsfp_2_sink.recv()) + if not self.qsfp_3_sink.empty(): + self.qsfp_3_source.send(self.qsfp_3_sink.recv()) + if not self.qsfp_4_sink.empty(): + self.qsfp_4_source.send(self.qsfp_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp_1_sink.wait() + + pkt = tb.qsfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp_1_sink.wait() + + pkt = tb.qsfp_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await Timer(1000, 'ns') + + tb.log.info("TDMA") + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + # configure TDMA scheduler + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) + + # enable queues with global enable off + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) + + # configure slots + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) + + await tb.rc.mem_read(tb.driver.hw_addr, 4) # wait for all writes to complete + + # send packets + for k in range(count): + await tb.driver.interfaces[0].start_xmit(pkts[k], k % 4) + + for k in range(count): + pkt = tb.driver.interfaces[0].recv() + + if not pkt: + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + print(pkt) + # assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_ctrl_tdma.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 256 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 60 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 85 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 + parameters['RQ_SEQ_NUM_WIDTH'] = 4 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/ip_ep.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/mqnic.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/pcie.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/pcie_us.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index e1a58a5a9..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,940 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_us -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tx_scheduler_ctrl_tdma.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 256 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 75 - AXIS_PCIE_RQ_USER_WIDTH = 60 - AXIS_PCIE_CQ_USER_WIDTH = 85 - AXIS_PCIE_CC_USER_WIDTH = 33 - RQ_SEQ_NUM_WIDTH = 4 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(0)[2:]) - pcie_tfc_npd_av = Signal(intbv(0)[2:]) - cfg_max_payload = Signal(intbv(0)[3:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_vf_enable = Signal(intbv(0)[8:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp_tx_clk_1 = Signal(bool(0)) - qsfp_tx_rst_1 = Signal(bool(0)) - qsfp_rx_clk_1 = Signal(bool(0)) - qsfp_rx_rst_1 = Signal(bool(0)) - qsfp_rxd_1 = Signal(intbv(0)[64:]) - qsfp_rxc_1 = Signal(intbv(0)[8:]) - qsfp_tx_clk_2 = Signal(bool(0)) - qsfp_tx_rst_2 = Signal(bool(0)) - qsfp_rx_clk_2 = Signal(bool(0)) - qsfp_rx_rst_2 = Signal(bool(0)) - qsfp_rxd_2 = Signal(intbv(0)[64:]) - qsfp_rxc_2 = Signal(intbv(0)[8:]) - qsfp_tx_clk_3 = Signal(bool(0)) - qsfp_tx_rst_3 = Signal(bool(0)) - qsfp_rx_clk_3 = Signal(bool(0)) - qsfp_rx_rst_3 = Signal(bool(0)) - qsfp_rxd_3 = Signal(intbv(0)[64:]) - qsfp_rxc_3 = Signal(intbv(0)[8:]) - qsfp_tx_clk_4 = Signal(bool(0)) - qsfp_tx_rst_4 = Signal(bool(0)) - qsfp_rx_clk_4 = Signal(bool(0)) - qsfp_rx_rst_4 = Signal(bool(0)) - qsfp_rxd_4 = Signal(intbv(0)[64:]) - qsfp_rxc_4 = Signal(intbv(0)[8:]) - qsfp_modprsl = Signal(bool(1)) - qsfp_intl = Signal(bool(1)) - flash_dq_i = Signal(intbv(0)[16:]) - - # Outputs - led = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[19:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[4:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[9:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[4:]) - qsfp_txd_1 = Signal(intbv(0)[64:]) - qsfp_txc_1 = Signal(intbv(0)[8:]) - qsfp_txd_2 = Signal(intbv(0)[64:]) - qsfp_txc_2 = Signal(intbv(0)[8:]) - qsfp_txd_3 = Signal(intbv(0)[64:]) - qsfp_txc_3 = Signal(intbv(0)[8:]) - qsfp_txd_4 = Signal(intbv(0)[64:]) - qsfp_txc_4 = Signal(intbv(0)[8:]) - qsfp_modsell = Signal(bool(0)) - qsfp_resetl = Signal(bool(1)) - qsfp_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - flash_dq_o = Signal(intbv(0)[16:]) - flash_dq_oe = Signal(bool(0)) - flash_addr = Signal(intbv(0)[24:]) - flash_region = Signal(intbv(0)[2:]) - flash_region_oe = Signal(bool(0)) - flash_ce_n = Signal(bool(1)) - flash_oe_n = Signal(bool(1)) - flash_we_n = Signal(bool(1)) - flash_adv_n = Signal(bool(1)) - - # sources and sinks - qsfp_1_source = xgmii_ep.XGMIISource() - qsfp_1_source_logic = qsfp_1_source.create_logic(qsfp_rx_clk_1, qsfp_rx_rst_1, txd=qsfp_rxd_1, txc=qsfp_rxc_1, name='qsfp_1_source') - - qsfp_1_sink = xgmii_ep.XGMIISink() - qsfp_1_sink_logic = qsfp_1_sink.create_logic(qsfp_tx_clk_1, qsfp_tx_rst_1, rxd=qsfp_txd_1, rxc=qsfp_txc_1, name='qsfp_1_sink') - - qsfp_2_source = xgmii_ep.XGMIISource() - qsfp_2_source_logic = qsfp_2_source.create_logic(qsfp_rx_clk_2, qsfp_rx_rst_2, txd=qsfp_rxd_2, txc=qsfp_rxc_2, name='qsfp_2_source') - - qsfp_2_sink = xgmii_ep.XGMIISink() - qsfp_2_sink_logic = qsfp_2_sink.create_logic(qsfp_tx_clk_2, qsfp_tx_rst_2, rxd=qsfp_txd_2, rxc=qsfp_txc_2, name='qsfp_2_sink') - - qsfp_3_source = xgmii_ep.XGMIISource() - qsfp_3_source_logic = qsfp_3_source.create_logic(qsfp_rx_clk_3, qsfp_rx_rst_3, txd=qsfp_rxd_3, txc=qsfp_rxc_3, name='qsfp_3_source') - - qsfp_3_sink = xgmii_ep.XGMIISink() - qsfp_3_sink_logic = qsfp_3_sink.create_logic(qsfp_tx_clk_3, qsfp_tx_rst_3, rxd=qsfp_txd_3, rxc=qsfp_txc_3, name='qsfp_3_sink') - - qsfp_4_source = xgmii_ep.XGMIISource() - qsfp_4_source_logic = qsfp_4_source.create_logic(qsfp_rx_clk_4, qsfp_rx_rst_4, txd=qsfp_rxd_4, txc=qsfp_rxc_4, name='qsfp_4_source') - - qsfp_4_sink = xgmii_ep.XGMIISink() - qsfp_4_sink_logic = qsfp_4_sink.create_logic(qsfp_tx_clk_4, qsfp_tx_rst_4, rxd=qsfp_txd_4, rxc=qsfp_txc_4, name='qsfp_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_us.UltrascalePCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 8 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(bool(1)), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num=s_axis_rq_seq_num, - pcie_rq_seq_num_vld=s_axis_rq_seq_num_valid, - #pcie_rq_tag=pcie_rq_tag, - #pcie_rq_tag_vld=pcie_rq_tag_vld, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_type1_cfg_reg_access=cfg_mgmt_type1_cfg_reg_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_ltr_enable=cfg_ltr_enable, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_dpa_substate_change=cfg_dpa_substate_change, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Per-Function Status Interface - #cfg_per_func_status_control=cfg_per_func_status_control, - #cfg_per_func_status_data=cfg_per_func_status_data, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_per_function_update_done=cfg_per_function_update_done, - #cfg_per_function_number=cfg_per_function_number, - #cfg_per_function_output_request=cfg_per_function_output_request, - #cfg_dsn=cfg_dsn, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_sent=cfg_interrupt_msix_sent, - #cfg_interrupt_msix_fail=cfg_interrupt_msix_fail, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #pcie_perstn0_out=pcie_perstn0_out, - #pcie_perstn1_in=pcie_perstn1_in, - #pcie_perstn1_out=pcie_perstn1_out - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num=s_axis_rq_seq_num, - s_axis_rq_seq_num_valid=s_axis_rq_seq_num_valid, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable=cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp_tx_clk_1=qsfp_tx_clk_1, - qsfp_tx_rst_1=qsfp_tx_rst_1, - qsfp_txd_1=qsfp_txd_1, - qsfp_txc_1=qsfp_txc_1, - qsfp_rx_clk_1=qsfp_rx_clk_1, - qsfp_rx_rst_1=qsfp_rx_rst_1, - qsfp_rxd_1=qsfp_rxd_1, - qsfp_rxc_1=qsfp_rxc_1, - qsfp_tx_clk_2=qsfp_tx_clk_2, - qsfp_tx_rst_2=qsfp_tx_rst_2, - qsfp_txd_2=qsfp_txd_2, - qsfp_txc_2=qsfp_txc_2, - qsfp_rx_clk_2=qsfp_rx_clk_2, - qsfp_rx_rst_2=qsfp_rx_rst_2, - qsfp_rxd_2=qsfp_rxd_2, - qsfp_rxc_2=qsfp_rxc_2, - qsfp_tx_clk_3=qsfp_tx_clk_3, - qsfp_tx_rst_3=qsfp_tx_rst_3, - qsfp_txd_3=qsfp_txd_3, - qsfp_txc_3=qsfp_txc_3, - qsfp_rx_clk_3=qsfp_rx_clk_3, - qsfp_rx_rst_3=qsfp_rx_rst_3, - qsfp_rxd_3=qsfp_rxd_3, - qsfp_rxc_3=qsfp_rxc_3, - qsfp_tx_clk_4=qsfp_tx_clk_4, - qsfp_tx_rst_4=qsfp_tx_rst_4, - qsfp_txd_4=qsfp_txd_4, - qsfp_txc_4=qsfp_txc_4, - qsfp_rx_clk_4=qsfp_rx_clk_4, - qsfp_rx_rst_4=qsfp_rx_rst_4, - qsfp_rxd_4=qsfp_rxd_4, - qsfp_rxc_4=qsfp_rxc_4, - qsfp_modsell=qsfp_modsell, - qsfp_resetl=qsfp_resetl, - qsfp_modprsl=qsfp_modprsl, - qsfp_intl=qsfp_intl, - qsfp_lpmode=qsfp_lpmode, - fpga_boot=fpga_boot, - flash_dq_i=flash_dq_i, - flash_dq_o=flash_dq_o, - flash_dq_oe=flash_dq_oe, - flash_addr=flash_addr, - flash_region=flash_region, - flash_region_oe=flash_region_oe, - flash_ce_n=flash_ce_n, - flash_oe_n=flash_oe_n, - flash_we_n=flash_we_n, - flash_adv_n=flash_adv_n - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def clkgen2(): - qsfp_tx_clk_1.next = not qsfp_tx_clk_1 - qsfp_rx_clk_1.next = not qsfp_rx_clk_1 - qsfp_tx_clk_2.next = not qsfp_tx_clk_2 - qsfp_rx_clk_2.next = not qsfp_rx_clk_2 - qsfp_tx_clk_3.next = not qsfp_tx_clk_3 - qsfp_rx_clk_3.next = not qsfp_rx_clk_3 - qsfp_tx_clk_4.next = not qsfp_tx_clk_4 - qsfp_rx_clk_4.next = not qsfp_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp_1_sink.empty(): - pkt = qsfp_1_sink.recv() - qsfp_1_source.send(pkt) - if not qsfp_2_sink.empty(): - pkt = qsfp_2_sink.recv() - qsfp_2_source.send(pkt) - if not qsfp_3_sink.empty(): - pkt = qsfp_3_sink.recv() - qsfp_3_source.send(pkt) - if not qsfp_4_sink.empty(): - pkt = qsfp_4_sink.recv() - qsfp_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp_tx_rst_1.next = 1 - qsfp_rx_rst_1.next = 1 - qsfp_tx_rst_2.next = 1 - qsfp_rx_rst_2.next = 1 - qsfp_tx_rst_3.next = 1 - qsfp_rx_rst_3.next = 1 - qsfp_tx_rst_4.next = 1 - qsfp_rx_rst_4.next = 1 - yield clk.posedge - rst.next = 0 - qsfp_tx_rst_1.next = 0 - qsfp_rx_rst_1.next = 0 - qsfp_tx_rst_2.next = 0 - qsfp_rx_rst_2.next = 0 - qsfp_tx_rst_3.next = 0 - qsfp_rx_rst_3.next = 0 - qsfp_tx_rst_4.next = 0 - qsfp_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp_1_sink.wait() - - pkt = qsfp_1_sink.recv() - print(pkt) - - qsfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp_1_sink.wait() - - pkt = qsfp_1_sink.recv() - print(pkt) - - qsfp_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(1000) - - yield clk.posedge - print("test 7s: TDMA") - current_test.next = 7 - - count = 16 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - # configure TDMA - - # configure TDMA scheduler - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) # schedule period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) # schedule period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) # schedule period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) # schedule period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) # timeslot period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) # timeslot period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) # timeslot period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) # timeslot period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) # active period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) # active period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) # active period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) # active period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) # enable TDMA - - # enable queues with global enable off - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) - - # configure slots - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - # send packets - for k in range(count): - yield from driver.interfaces[0].start_xmit(pkts[k], k%4) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - #assert pkt.data == pkts[k] - #assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 2fdb7dd59..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,465 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 256; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 75; -parameter AXIS_PCIE_RQ_USER_WIDTH = 60; -parameter AXIS_PCIE_CQ_USER_WIDTH = 85; -parameter AXIS_PCIE_CC_USER_WIDTH = 33; -parameter RQ_SEQ_NUM_WIDTH = 4; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg btnu = 0; -reg btnl = 0; -reg btnd = 0; -reg btnr = 0; -reg btnc = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num = 0; -reg s_axis_rq_seq_num_valid = 0; -reg [1:0] pcie_tfc_nph_av = 0; -reg [1:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [7:0] cfg_interrupt_msi_vf_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp_tx_clk_1 = 0; -reg qsfp_tx_rst_1 = 0; -reg qsfp_rx_clk_1 = 0; -reg qsfp_rx_rst_1 = 0; -reg [63:0] qsfp_rxd_1 = 0; -reg [7:0] qsfp_rxc_1 = 0; -reg qsfp_tx_clk_2 = 0; -reg qsfp_tx_rst_2 = 0; -reg qsfp_rx_clk_2 = 0; -reg qsfp_rx_rst_2 = 0; -reg [63:0] qsfp_rxd_2 = 0; -reg [7:0] qsfp_rxc_2 = 0; -reg qsfp_tx_clk_3 = 0; -reg qsfp_tx_rst_3 = 0; -reg qsfp_rx_clk_3 = 0; -reg qsfp_rx_rst_3 = 0; -reg [63:0] qsfp_rxd_3 = 0; -reg [7:0] qsfp_rxc_3 = 0; -reg qsfp_tx_clk_4 = 0; -reg qsfp_tx_rst_4 = 0; -reg qsfp_rx_clk_4 = 0; -reg qsfp_rx_rst_4 = 0; -reg [63:0] qsfp_rxd_4 = 0; -reg [7:0] qsfp_rxc_4 = 0; -reg qsfp_modprsl = 1; -reg qsfp_intl = 1; -reg [15:0] flash_dq_i = 0; - -// Outputs -wire [7:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [18:0] cfg_mgmt_addr; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp_txd_1; -wire [7:0] qsfp_txc_1; -wire [63:0] qsfp_txd_2; -wire [7:0] qsfp_txc_2; -wire [63:0] qsfp_txd_3; -wire [7:0] qsfp_txc_3; -wire [63:0] qsfp_txd_4; -wire [7:0] qsfp_txc_4; -wire qsfp_modsell; -wire qsfp_resetl; -wire qsfp_lpmode; -wire fpga_boot; -wire [15:0] flash_dq_o; -wire flash_dq_oe; -wire [23:0] flash_addr; -wire [1:0] flash_region; -wire flash_region_oe; -wire flash_ce_n; -wire flash_oe_n; -wire flash_we_n; -wire flash_adv_n; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num, - s_axis_rq_seq_num_valid, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_vf_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp_tx_clk_1, - qsfp_tx_rst_1, - qsfp_rx_clk_1, - qsfp_rx_rst_1, - qsfp_rxd_1, - qsfp_rxc_1, - qsfp_tx_clk_2, - qsfp_tx_rst_2, - qsfp_rx_clk_2, - qsfp_rx_rst_2, - qsfp_rxd_2, - qsfp_rxc_2, - qsfp_tx_clk_3, - qsfp_tx_rst_3, - qsfp_rx_clk_3, - qsfp_rx_rst_3, - qsfp_rxd_3, - qsfp_rxc_3, - qsfp_tx_clk_4, - qsfp_tx_rst_4, - qsfp_rx_clk_4, - qsfp_rx_rst_4, - qsfp_rxd_4, - qsfp_rxc_4, - qsfp_modprsl, - qsfp_intl, - flash_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp_txd_1, - qsfp_txc_1, - qsfp_txd_2, - qsfp_txc_2, - qsfp_txd_3, - qsfp_txc_3, - qsfp_txd_4, - qsfp_txc_4, - qsfp_modsell, - qsfp_resetl, - qsfp_lpmode, - fpga_boot, - flash_dq_o, - flash_dq_oe, - flash_addr, - flash_region, - flash_region_oe, - flash_ce_n, - flash_oe_n, - flash_we_n, - flash_adv_n - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btnu(btnu), - .btnl(btnl), - .btnd(btnd), - .btnr(btnr), - .btnc(btnc), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num(s_axis_rq_seq_num), - .s_axis_rq_seq_num_valid(s_axis_rq_seq_num_valid), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_vf_enable(cfg_interrupt_msi_vf_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp_tx_clk_1(qsfp_tx_clk_1), - .qsfp_tx_rst_1(qsfp_tx_rst_1), - .qsfp_txd_1(qsfp_txd_1), - .qsfp_txc_1(qsfp_txc_1), - .qsfp_rx_clk_1(qsfp_rx_clk_1), - .qsfp_rx_rst_1(qsfp_rx_rst_1), - .qsfp_rxd_1(qsfp_rxd_1), - .qsfp_rxc_1(qsfp_rxc_1), - .qsfp_tx_clk_2(qsfp_tx_clk_2), - .qsfp_tx_rst_2(qsfp_tx_rst_2), - .qsfp_txd_2(qsfp_txd_2), - .qsfp_txc_2(qsfp_txc_2), - .qsfp_rx_clk_2(qsfp_rx_clk_2), - .qsfp_rx_rst_2(qsfp_rx_rst_2), - .qsfp_rxd_2(qsfp_rxd_2), - .qsfp_rxc_2(qsfp_rxc_2), - .qsfp_tx_clk_3(qsfp_tx_clk_3), - .qsfp_tx_rst_3(qsfp_tx_rst_3), - .qsfp_txd_3(qsfp_txd_3), - .qsfp_txc_3(qsfp_txc_3), - .qsfp_rx_clk_3(qsfp_rx_clk_3), - .qsfp_rx_rst_3(qsfp_rx_rst_3), - .qsfp_rxd_3(qsfp_rxd_3), - .qsfp_rxc_3(qsfp_rxc_3), - .qsfp_tx_clk_4(qsfp_tx_clk_4), - .qsfp_tx_rst_4(qsfp_tx_rst_4), - .qsfp_txd_4(qsfp_txd_4), - .qsfp_txc_4(qsfp_txc_4), - .qsfp_rx_clk_4(qsfp_rx_clk_4), - .qsfp_rx_rst_4(qsfp_rx_rst_4), - .qsfp_rxd_4(qsfp_rxd_4), - .qsfp_rxc_4(qsfp_rxc_4), - .qsfp_modprsl(qsfp_modprsl), - .qsfp_modsell(qsfp_modsell), - .qsfp_resetl(qsfp_resetl), - .qsfp_intl(qsfp_intl), - .qsfp_lpmode(qsfp_lpmode), - .fpga_boot(fpga_boot), - .flash_dq_i(flash_dq_i), - .flash_dq_o(flash_dq_o), - .flash_dq_oe(flash_dq_oe), - .flash_addr(flash_addr), - .flash_region(flash_region), - .flash_region_oe(flash_region_oe), - .flash_ce_n(flash_ce_n), - .flash_oe_n(flash_oe_n), - .flash_we_n(flash_we_n), - .flash_adv_n(flash_adv_n) -); - -endmodule diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/udp_ep.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic_tdma/VCU108/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic_tdma/VCU108/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/axis_ep.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/axis_ep.py deleted file mode 120000 index 385bb0300..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/axis_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/axis_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/eth_ep.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/eth_ep.py deleted file mode 120000 index bac19feea..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/eth_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/eth_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/Makefile b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/Makefile new file mode 100644 index 000000000..4ac009807 --- /dev/null +++ b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/Makefile @@ -0,0 +1,153 @@ +# Copyright 2020, The Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. 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. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +# CONTRIBUTORS 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. +# +# The views and conclusions contained in the software and documentation are those +# of the authors and should not be interpreted as representing official policies, +# either expressed or implied, of The Regents of the University of California. + +TOPLEVEL_LANG = verilog + +SIM ?= icarus +WAVES ?= 0 + +COCOTB_HDL_TIMEUNIT = 1ns +COCOTB_HDL_TIMEPRECISION = 1ps + +DUT = fpga_core +TOPLEVEL = $(DUT) +MODULE = test_$(DUT) +VERILOG_SOURCES += ../../rtl/$(DUT).v +VERILOG_SOURCES += ../../rtl/common/mqnic_interface.v +VERILOG_SOURCES += ../../rtl/common/mqnic_port.v +VERILOG_SOURCES += ../../rtl/common/cpl_write.v +VERILOG_SOURCES += ../../rtl/common/cpl_op_mux.v +VERILOG_SOURCES += ../../rtl/common/desc_fetch.v +VERILOG_SOURCES += ../../rtl/common/desc_op_mux.v +VERILOG_SOURCES += ../../rtl/common/queue_manager.v +VERILOG_SOURCES += ../../rtl/common/cpl_queue_manager.v +VERILOG_SOURCES += ../../rtl/common/tx_engine.v +VERILOG_SOURCES += ../../rtl/common/rx_engine.v +VERILOG_SOURCES += ../../rtl/common/tx_checksum.v +VERILOG_SOURCES += ../../rtl/common/rx_hash.v +VERILOG_SOURCES += ../../rtl/common/rx_checksum.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_rr.v +VERILOG_SOURCES += ../../rtl/common/tx_scheduler_ctrl_tdma.v +VERILOG_SOURCES += ../../rtl/common/event_mux.v +VERILOG_SOURCES += ../../rtl/common/tdma_scheduler.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber.v +VERILOG_SOURCES += ../../rtl/common/tdma_ber_ch.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g_fifo.v +VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_10g.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_rx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/axis_xgmii_tx_64.v +VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_clock_cdc.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_perout.v +VERILOG_SOURCES += ../../lib/eth/rtl/ptp_ts_extract.v +VERILOG_SOURCES += ../../lib/axi/rtl/axil_interconnect.v +VERILOG_SOURCES += ../../lib/axi/rtl/arbiter.v +VERILOG_SOURCES += ../../lib/axi/rtl/priority_encoder.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_arb_mux.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_async_fifo_adapter.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_fifo.v +VERILOG_SOURCES += ../../lib/axis/rtl/axis_register.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_axil_master.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_pcie_us_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_rd.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_if_mux_wr.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_psdpram.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_sink.v +VERILOG_SOURCES += ../../lib/pcie/rtl/dma_client_axis_source.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_cfg.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_us_msi.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pcie_tag_manager.v +VERILOG_SOURCES += ../../lib/pcie/rtl/pulse_merge.v + +# module parameters +export PARAM_AXIS_PCIE_DATA_WIDTH ?= 512 +export PARAM_AXIS_PCIE_KEEP_WIDTH ?= $(shell expr $(PARAM_AXIS_PCIE_DATA_WIDTH) / 32 ) +export PARAM_AXIS_PCIE_RQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),62,137) +export PARAM_AXIS_PCIE_RC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),75,161) +export PARAM_AXIS_PCIE_CQ_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),88,183) +export PARAM_AXIS_PCIE_CC_USER_WIDTH ?= $(if $(filter-out 512,$(PARAM_AXIS_PCIE_DATA_WIDTH)),33,81) +export PARAM_RQ_SEQ_NUM_WIDTH ?= 6 +export PARAM_BAR0_APERTURE ?= 24 + +SIM_BUILD ?= sim_build_$(MODULE) + +ifeq ($(SIM), icarus) + PLUSARGS += -fst + + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).AXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).RQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -P $(TOPLEVEL).BAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + VERILOG_SOURCES += iverilog_dump.v + COMPILE_ARGS += -s iverilog_dump + endif +else ifeq ($(SIM), verilator) + COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH + + COMPILE_ARGS += -GAXIS_PCIE_DATA_WIDTH=$(PARAM_AXIS_PCIE_DATA_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_KEEP_WIDTH=$(PARAM_AXIS_PCIE_KEEP_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RQ_USER_WIDTH=$(PARAM_AXIS_PCIE_RQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_RC_USER_WIDTH=$(PARAM_AXIS_PCIE_RC_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CQ_USER_WIDTH=$(PARAM_AXIS_PCIE_CQ_USER_WIDTH) + COMPILE_ARGS += -GAXIS_PCIE_CC_USER_WIDTH=$(PARAM_AXIS_PCIE_CC_USER_WIDTH) + COMPILE_ARGS += -GRQ_SEQ_NUM_WIDTH=$(PARAM_RQ_SEQ_NUM_WIDTH) + COMPILE_ARGS += -GBAR0_APERTURE=$(PARAM_BAR0_APERTURE) + + ifeq ($(WAVES), 1) + COMPILE_ARGS += --trace-fst + endif +endif + +iverilog_dump.v: + echo 'module iverilog_dump();' > $@ + echo 'initial begin' >> $@ + echo ' $$dumpfile("$(TOPLEVEL).fst");' >> $@ + echo ' $$dumpvars(0, $(TOPLEVEL));' >> $@ + echo 'end' >> $@ + echo 'endmodule' >> $@ + +clean:: + @rm -rf sim_build_* + @rm -rf iverilog_dump.v + @rm -rf dump.fst $(TOPLEVEL).fst + +include $(shell cocotb-config --makefiles)/Makefile.sim + diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/mqnic.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/mqnic.py new file mode 120000 index 000000000..dfa8522e7 --- /dev/null +++ b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/mqnic.py @@ -0,0 +1 @@ +../../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py new file mode 100644 index 000000000..bd60716dd --- /dev/null +++ b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py @@ -0,0 +1,717 @@ +""" + +Copyright 2020, The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR +CONTRIBUTORS 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. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of The Regents of the University of California. + +""" + +import logging +import os +import sys + +import scapy.utils +from scapy.layers.l2 import Ether +from scapy.layers.inet import IP, UDP + +import cocotb_test.simulator + +import cocotb +from cocotb.log import SimLog +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, FallingEdge, Timer + +from cocotbext.pcie.core import RootComplex +from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice + +from cocotbext.eth import XgmiiSource, XgmiiSink + +try: + import mqnic +except ImportError: + # attempt import from current directory + sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + try: + import mqnic + finally: + del sys.path[0] + + +class TB(object): + def __init__(self, dut): + self.dut = dut + + self.BAR0_APERTURE = int(os.getenv("PARAM_BAR0_APERTURE")) + + self.log = SimLog("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # PCIe + self.rc = RootComplex() + + self.rc.max_payload_size = 0x1 # 256 bytes + self.rc.max_read_request_size = 0x2 # 512 bytes + + self.dev = UltraScalePlusPcieDevice( + # configuration options + pcie_generation=3, + pcie_link_width=16, + user_clk_frequency=250e6, + alignment="dword", + cq_cc_straddle=False, + rq_rc_straddle=False, + rc_4tlp_straddle=False, + enable_pf1=False, + enable_client_tag=True, + enable_extended_tag=True, + enable_parity=False, + enable_rx_msg_interface=False, + enable_sriov=False, + enable_extended_configuration=False, + + enable_pf0_msi=True, + enable_pf1_msi=False, + + # signals + # Clock and Reset Interface + user_clk=dut.clk_250mhz, + user_reset=dut.rst_250mhz, + # user_lnk_up + # sys_clk + # sys_clk_gt + # sys_reset + # phy_rdy_out + + # Requester reQuest Interface + rq_entity=dut, + rq_name="m_axis_rq", + pcie_rq_seq_num0=dut.s_axis_rq_seq_num_0, + pcie_rq_seq_num_vld0=dut.s_axis_rq_seq_num_valid_0, + pcie_rq_seq_num1=dut.s_axis_rq_seq_num_1, + pcie_rq_seq_num_vld1=dut.s_axis_rq_seq_num_valid_1, + # pcie_rq_tag0 + # pcie_rq_tag1 + # pcie_rq_tag_av + # pcie_rq_tag_vld0 + # pcie_rq_tag_vld1 + + # Requester Completion Interface + rc_entity=dut, + rc_name="s_axis_rc", + + # Completer reQuest Interface + cq_entity=dut, + cq_name="s_axis_cq", + # pcie_cq_np_req + # pcie_cq_np_req_count + + # Completer Completion Interface + cc_entity=dut, + cc_name="m_axis_cc", + + # Transmit Flow Control Interface + # pcie_tfc_nph_av=dut.pcie_tfc_nph_av, + # pcie_tfc_npd_av=dut.pcie_tfc_npd_av, + + # Configuration Management Interface + cfg_mgmt_addr=dut.cfg_mgmt_addr, + cfg_mgmt_function_number=dut.cfg_mgmt_function_number, + cfg_mgmt_write=dut.cfg_mgmt_write, + cfg_mgmt_write_data=dut.cfg_mgmt_write_data, + cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable, + cfg_mgmt_read=dut.cfg_mgmt_read, + cfg_mgmt_read_data=dut.cfg_mgmt_read_data, + cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done, + # cfg_mgmt_debug_access + + # Configuration Status Interface + # cfg_phy_link_down + # cfg_phy_link_status + # cfg_negotiated_width + # cfg_current_speed + cfg_max_payload=dut.cfg_max_payload, + cfg_max_read_req=dut.cfg_max_read_req, + # cfg_function_status + # cfg_vf_status + # cfg_function_power_state + # cfg_vf_power_state + # cfg_link_power_state + # cfg_err_cor_out + # cfg_err_nonfatal_out + # cfg_err_fatal_out + # cfg_local_error_out + # cfg_local_error_valid + # cfg_rx_pm_state + # cfg_tx_pm_state + # cfg_ltssm_state + # cfg_rcb_status + # cfg_obff_enable + # cfg_pl_status_change + # cfg_tph_requester_enable + # cfg_tph_st_mode + # cfg_vf_tph_requester_enable + # cfg_vf_tph_st_mode + + # Configuration Received Message Interface + # cfg_msg_received + # cfg_msg_received_data + # cfg_msg_received_type + + # Configuration Transmit Message Interface + # cfg_msg_transmit + # cfg_msg_transmit_type + # cfg_msg_transmit_data + # cfg_msg_transmit_done + + # Configuration Flow Control Interface + cfg_fc_ph=dut.cfg_fc_ph, + cfg_fc_pd=dut.cfg_fc_pd, + cfg_fc_nph=dut.cfg_fc_nph, + cfg_fc_npd=dut.cfg_fc_npd, + cfg_fc_cplh=dut.cfg_fc_cplh, + cfg_fc_cpld=dut.cfg_fc_cpld, + cfg_fc_sel=dut.cfg_fc_sel, + + # Configuration Control Interface + # cfg_hot_reset_in + # cfg_hot_reset_out + # cfg_config_space_enable + # cfg_dsn + # cfg_bus_number + # cfg_ds_port_number + # cfg_ds_bus_number + # cfg_ds_device_number + # cfg_ds_function_number + # cfg_power_state_change_ack + # cfg_power_state_change_interrupt + cfg_err_cor_in=dut.status_error_cor, + cfg_err_uncor_in=dut.status_error_uncor, + # cfg_flr_in_process + # cfg_flr_done + # cfg_vf_flr_in_process + # cfg_vf_flr_func_num + # cfg_vf_flr_done + # cfg_pm_aspm_l1_entry_reject + # cfg_pm_aspm_tx_l0s_entry_disable + # cfg_req_pm_transition_l23_ready + # cfg_link_training_enable + + # Configuration Interrupt Controller Interface + # cfg_interrupt_int + # cfg_interrupt_sent + # cfg_interrupt_pending + cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable, + cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable, + cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update, + cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data, + # cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select, + cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int, + cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status, + cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable, + # cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num, + cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent, + cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail, + # cfg_interrupt_msix_enable + # cfg_interrupt_msix_mask + # cfg_interrupt_msix_vf_enable + # cfg_interrupt_msix_vf_mask + # cfg_interrupt_msix_address + # cfg_interrupt_msix_data + # cfg_interrupt_msix_int + # cfg_interrupt_msix_vec_pending + # cfg_interrupt_msix_vec_pending_status + cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr, + cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present, + cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type, + # cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag, + # cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number, + + # Configuration Extend Interface + # cfg_ext_read_received + # cfg_ext_write_received + # cfg_ext_register_number + # cfg_ext_function_number + # cfg_ext_write_data + # cfg_ext_write_byte_enable + # cfg_ext_read_data + # cfg_ext_read_data_valid + ) + + # self.dev.log.setLevel(logging.DEBUG) + + self.rc.make_port().connect(self.dev) + + self.driver = mqnic.Driver(self.rc) + + self.dev.functions[0].msi_multiple_message_capable = 5 + + self.dev.functions[0].configure_bar(0, 2**self.BAR0_APERTURE, ext=True, prefetch=True) + + # Ethernet + cocotb.fork(Clock(dut.qsfp1_rx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_source = XgmiiSource(dut.qsfp1_rxd_1, dut.qsfp1_rxc_1, dut.qsfp1_rx_clk_1, dut.qsfp1_rx_rst_1) + cocotb.fork(Clock(dut.qsfp1_tx_clk_1, 6.4, units="ns").start()) + self.qsfp1_1_sink = XgmiiSink(dut.qsfp1_txd_1, dut.qsfp1_txc_1, dut.qsfp1_tx_clk_1, dut.qsfp1_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_source = XgmiiSource(dut.qsfp1_rxd_2, dut.qsfp1_rxc_2, dut.qsfp1_rx_clk_2, dut.qsfp1_rx_rst_2) + cocotb.fork(Clock(dut.qsfp1_tx_clk_2, 6.4, units="ns").start()) + self.qsfp1_2_sink = XgmiiSink(dut.qsfp1_txd_2, dut.qsfp1_txc_2, dut.qsfp1_tx_clk_2, dut.qsfp1_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_source = XgmiiSource(dut.qsfp1_rxd_3, dut.qsfp1_rxc_3, dut.qsfp1_rx_clk_3, dut.qsfp1_rx_rst_3) + cocotb.fork(Clock(dut.qsfp1_tx_clk_3, 6.4, units="ns").start()) + self.qsfp1_3_sink = XgmiiSink(dut.qsfp1_txd_3, dut.qsfp1_txc_3, dut.qsfp1_tx_clk_3, dut.qsfp1_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp1_rx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_source = XgmiiSource(dut.qsfp1_rxd_4, dut.qsfp1_rxc_4, dut.qsfp1_rx_clk_4, dut.qsfp1_rx_rst_4) + cocotb.fork(Clock(dut.qsfp1_tx_clk_4, 6.4, units="ns").start()) + self.qsfp1_4_sink = XgmiiSink(dut.qsfp1_txd_4, dut.qsfp1_txc_4, dut.qsfp1_tx_clk_4, dut.qsfp1_tx_rst_4) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_1, 6.4, units="ns").start()) + self.qsfp2_1_source = XgmiiSource(dut.qsfp2_rxd_1, dut.qsfp2_rxc_1, dut.qsfp2_rx_clk_1, dut.qsfp2_rx_rst_1) + cocotb.fork(Clock(dut.qsfp2_tx_clk_1, 6.4, units="ns").start()) + self.qsfp2_1_sink = XgmiiSink(dut.qsfp2_txd_1, dut.qsfp2_txc_1, dut.qsfp2_tx_clk_1, dut.qsfp2_tx_rst_1) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_2, 6.4, units="ns").start()) + self.qsfp2_2_source = XgmiiSource(dut.qsfp2_rxd_2, dut.qsfp2_rxc_2, dut.qsfp2_rx_clk_2, dut.qsfp2_rx_rst_2) + cocotb.fork(Clock(dut.qsfp2_tx_clk_2, 6.4, units="ns").start()) + self.qsfp2_2_sink = XgmiiSink(dut.qsfp2_txd_2, dut.qsfp2_txc_2, dut.qsfp2_tx_clk_2, dut.qsfp2_tx_rst_2) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_3, 6.4, units="ns").start()) + self.qsfp2_3_source = XgmiiSource(dut.qsfp2_rxd_3, dut.qsfp2_rxc_3, dut.qsfp2_rx_clk_3, dut.qsfp2_rx_rst_3) + cocotb.fork(Clock(dut.qsfp2_tx_clk_3, 6.4, units="ns").start()) + self.qsfp2_3_sink = XgmiiSink(dut.qsfp2_txd_3, dut.qsfp2_txc_3, dut.qsfp2_tx_clk_3, dut.qsfp2_tx_rst_3) + + cocotb.fork(Clock(dut.qsfp2_rx_clk_4, 6.4, units="ns").start()) + self.qsfp2_4_source = XgmiiSource(dut.qsfp2_rxd_4, dut.qsfp2_rxc_4, dut.qsfp2_rx_clk_4, dut.qsfp2_rx_rst_4) + cocotb.fork(Clock(dut.qsfp2_tx_clk_4, 6.4, units="ns").start()) + self.qsfp2_4_sink = XgmiiSink(dut.qsfp2_txd_4, dut.qsfp2_txc_4, dut.qsfp2_tx_clk_4, dut.qsfp2_tx_rst_4) + + dut.btnu.setimmediatevalue(0) + dut.btnl.setimmediatevalue(0) + dut.btnd.setimmediatevalue(0) + dut.btnr.setimmediatevalue(0) + dut.btnc.setimmediatevalue(0) + dut.sw.setimmediatevalue(0) + + dut.i2c_scl_i.setimmediatevalue(1) + dut.i2c_sda_i.setimmediatevalue(1) + + dut.qsfp1_rx_error_count_1.setimmediatevalue(0) + dut.qsfp1_rx_error_count_2.setimmediatevalue(0) + dut.qsfp1_rx_error_count_3.setimmediatevalue(0) + dut.qsfp1_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp2_rx_error_count_1.setimmediatevalue(0) + dut.qsfp2_rx_error_count_2.setimmediatevalue(0) + dut.qsfp2_rx_error_count_3.setimmediatevalue(0) + dut.qsfp2_rx_error_count_4.setimmediatevalue(0) + + dut.qsfp1_modprsl.setimmediatevalue(0) + dut.qsfp1_intl.setimmediatevalue(1) + + dut.qsfp2_modprsl.setimmediatevalue(0) + dut.qsfp2_intl.setimmediatevalue(1) + + dut.qspi_0_dq_i.setimmediatevalue(0) + dut.qspi_1_dq_i.setimmediatevalue(0) + + self.loopback_enable = False + cocotb.fork(self._run_loopback()) + + async def init(self): + + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(0) + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp1_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(1) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(1) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(1) + + await FallingEdge(self.dut.rst_250mhz) + await Timer(100, 'ns') + + await RisingEdge(self.dut.clk_250mhz) + await RisingEdge(self.dut.clk_250mhz) + + self.dut.qsfp1_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp1_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp1_tx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_1.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_2.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_3.setimmediatevalue(0) + self.dut.qsfp2_rx_rst_4.setimmediatevalue(0) + self.dut.qsfp2_tx_rst_4.setimmediatevalue(0) + + await self.rc.enumerate(enable_bus_mastering=True, configure_msi=True) + + async def _run_loopback(self): + while True: + await RisingEdge(self.dut.clk_250mhz) + + if self.loopback_enable: + if not self.qsfp1_1_sink.empty(): + self.qsfp1_1_source.send(self.qsfp1_1_sink.recv()) + if not self.qsfp1_2_sink.empty(): + self.qsfp1_2_source.send(self.qsfp1_2_sink.recv()) + if not self.qsfp1_3_sink.empty(): + self.qsfp1_3_source.send(self.qsfp1_3_sink.recv()) + if not self.qsfp1_4_sink.empty(): + self.qsfp1_4_source.send(self.qsfp1_4_sink.recv()) + if not self.qsfp2_1_sink.empty(): + self.qsfp2_1_source.send(self.qsfp2_1_sink.recv()) + if not self.qsfp2_2_sink.empty(): + self.qsfp2_2_source.send(self.qsfp2_2_sink.recv()) + if not self.qsfp2_3_sink.empty(): + self.qsfp2_3_source.send(self.qsfp2_3_sink.recv()) + if not self.qsfp2_4_sink.empty(): + self.qsfp2_4_source.send(self.qsfp2_4_sink.recv()) + + +@cocotb.test() +async def run_test_nic(dut): + + tb = TB(dut) + + await tb.init() + + tb.log.info("Init driver") + await tb.driver.init_dev(tb.dev.functions[0].pcie_id) + await tb.driver.interfaces[0].open() + # await driver.interfaces[1].open() + + # enable queues + tb.log.info("Enable queues") + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) + + # wait for all writes to complete + await tb.rc.mem_read(tb.driver.hw_addr, 4) + tb.log.info("Init complete") + + tb.log.info("Send and receive single packet") + + data = bytearray([x % 256 for x in range(1024)]) + + await tb.driver.interfaces[0].start_xmit(data, 0) + + await tb.qsfp1_1_sink.wait() + + pkt = tb.qsfp1_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp1_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + # await tb.driver.interfaces[1].start_xmit(data, 0) + + # await tb.qsfp2_1_sink.wait() + + # pkt = tb.qsfp2_1_sink.recv() + # tb.log.info("Packet: %s", pkt) + + # tb.qsfp2_1_source.send(pkt) + + # await tb.driver.interfaces[1].wait() + + # pkt = tb.driver.interfaces[1].recv() + + # tb.log.info("Packet: %s", pkt) + # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.log.info("RX and TX checksum tests") + + payload = bytes([x % 256 for x in range(256)]) + eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5') + ip = IP(src='192.168.1.100', dst='192.168.1.101') + udp = UDP(sport=1, dport=2) + test_pkt = eth / ip / udp / payload + + test_pkt2 = test_pkt.copy() + test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP])) + + await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6) + + await tb.qsfp1_1_sink.wait() + + pkt = tb.qsfp1_1_sink.recv() + tb.log.info("Packet: %s", pkt) + + tb.qsfp1_1_source.send(pkt) + + await tb.driver.interfaces[0].wait() + + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + assert Ether(pkt.data).build() == test_pkt.build() + + tb.log.info("Multiple small packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + tb.log.info("Multiple large packets") + + count = 64 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + for p in pkts: + await tb.driver.interfaces[0].start_xmit(p, 0) + + for k in range(count): + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + tb.log.info("Packet: %s", pkt) + assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await Timer(1000, 'ns') + + tb.log.info("TDMA") + + count = 16 + + pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)] + + tb.loopback_enable = True + + # configure TDMA scheduler + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) + + # enable queues with global enable off + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) + for k in range(tb.driver.interfaces[0].tx_queue_count): + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) + + # configure slots + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) + await tb.rc.mem_write_dword(tb.driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) + + await tb.rc.mem_read(tb.driver.hw_addr, 4) # wait for all writes to complete + + # send packets + for k in range(count): + await tb.driver.interfaces[0].start_xmit(pkts[k], k % 4) + + for k in range(count): + pkt = tb.driver.interfaces[0].recv() + + if not pkt: + await tb.driver.interfaces[0].wait() + pkt = tb.driver.interfaces[0].recv() + + print(pkt) + # assert pkt.data == pkts[k] + assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff + + tb.loopback_enable = False + + await RisingEdge(dut.clk_250mhz) + await RisingEdge(dut.clk_250mhz) + + +# cocotb-test + +tests_dir = os.path.dirname(__file__) +rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl')) +lib_dir = os.path.abspath(os.path.join(rtl_dir, '..', 'lib')) +axi_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axi', 'rtl')) +axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'axis', 'rtl')) +eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'rtl')) +pcie_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'pcie', 'rtl')) + + +def test_fpga_core(request): + dut = "fpga_core" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + verilog_sources = [ + os.path.join(rtl_dir, f"{dut}.v"), + os.path.join(rtl_dir, "common", "mqnic_interface.v"), + os.path.join(rtl_dir, "common", "mqnic_port.v"), + os.path.join(rtl_dir, "common", "cpl_write.v"), + os.path.join(rtl_dir, "common", "cpl_op_mux.v"), + os.path.join(rtl_dir, "common", "desc_fetch.v"), + os.path.join(rtl_dir, "common", "desc_op_mux.v"), + os.path.join(rtl_dir, "common", "queue_manager.v"), + os.path.join(rtl_dir, "common", "cpl_queue_manager.v"), + os.path.join(rtl_dir, "common", "tx_engine.v"), + os.path.join(rtl_dir, "common", "rx_engine.v"), + os.path.join(rtl_dir, "common", "tx_checksum.v"), + os.path.join(rtl_dir, "common", "rx_hash.v"), + os.path.join(rtl_dir, "common", "rx_checksum.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_rr.v"), + os.path.join(rtl_dir, "common", "tx_scheduler_ctrl_tdma.v"), + os.path.join(rtl_dir, "common", "event_mux.v"), + os.path.join(rtl_dir, "common", "tdma_scheduler.v"), + os.path.join(rtl_dir, "common", "tdma_ber.v"), + os.path.join(rtl_dir, "common", "tdma_ber_ch.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g_fifo.v"), + os.path.join(eth_rtl_dir, "eth_mac_10g.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_rx_64.v"), + os.path.join(eth_rtl_dir, "axis_xgmii_tx_64.v"), + os.path.join(eth_rtl_dir, "lfsr.v"), + os.path.join(eth_rtl_dir, "ptp_clock.v"), + os.path.join(eth_rtl_dir, "ptp_clock_cdc.v"), + os.path.join(eth_rtl_dir, "ptp_perout.v"), + os.path.join(eth_rtl_dir, "ptp_ts_extract.v"), + os.path.join(axi_rtl_dir, "axil_interconnect.v"), + os.path.join(axi_rtl_dir, "arbiter.v"), + os.path.join(axi_rtl_dir, "priority_encoder.v"), + os.path.join(axis_rtl_dir, "axis_adapter.v"), + os.path.join(axis_rtl_dir, "axis_arb_mux.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo.v"), + os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"), + os.path.join(axis_rtl_dir, "axis_fifo.v"), + os.path.join(axis_rtl_dir, "axis_register.v"), + os.path.join(pcie_rtl_dir, "pcie_us_axil_master.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_pcie_us_wr.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_rd.v"), + os.path.join(pcie_rtl_dir, "dma_if_mux_wr.v"), + os.path.join(pcie_rtl_dir, "dma_psdpram.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_sink.v"), + os.path.join(pcie_rtl_dir, "dma_client_axis_source.v"), + os.path.join(pcie_rtl_dir, "pcie_us_cfg.v"), + os.path.join(pcie_rtl_dir, "pcie_us_msi.v"), + os.path.join(pcie_rtl_dir, "pcie_tag_manager.v"), + os.path.join(pcie_rtl_dir, "pulse_merge.v"), + ] + + parameters = {} + + parameters['AXIS_PCIE_DATA_WIDTH'] = 512 + parameters['AXIS_PCIE_KEEP_WIDTH'] = parameters['AXIS_PCIE_DATA_WIDTH'] // 32 + parameters['AXIS_PCIE_RQ_USER_WIDTH'] = 62 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 137 + parameters['AXIS_PCIE_RC_USER_WIDTH'] = 75 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 161 + parameters['AXIS_PCIE_CQ_USER_WIDTH'] = 88 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 183 + parameters['AXIS_PCIE_CC_USER_WIDTH'] = 33 if parameters['AXIS_PCIE_DATA_WIDTH'] < 512 else 81 + parameters['RQ_SEQ_NUM_WIDTH'] = 6 + parameters['BAR0_APERTURE'] = 24 + + extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()} + + sim_build = os.path.join(tests_dir, + "sim_build_"+request.node.name.replace('[', '-').replace(']', '')) + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + ) diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/ip_ep.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/ip_ep.py deleted file mode 120000 index 6dfa928a7..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/ip_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/ip_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/mqnic.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/mqnic.py deleted file mode 120000 index f2c96aec4..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/mqnic.py +++ /dev/null @@ -1 +0,0 @@ -../../../../common/tb/mqnic.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie.py deleted file mode 120000 index abea2f963..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie_us.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie_us.py deleted file mode 120000 index ef028ec29..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie_us.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_us.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie_usp.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie_usp.py deleted file mode 120000 index 8ce355a22..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/pcie_usp.py +++ /dev/null @@ -1 +0,0 @@ -../lib/pcie/tb/pcie_usp.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/test_fpga_core.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/test_fpga_core.py deleted file mode 100755 index a0e061d1f..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/test_fpga_core.py +++ /dev/null @@ -1,1107 +0,0 @@ -#!/usr/bin/env python -""" - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -""" - -from myhdl import * -import os - -import pcie -import pcie_usp -import xgmii_ep -import axis_ep -import eth_ep -import udp_ep - -import struct - -import mqnic - -module = 'fpga_core' -testbench = 'test_%s' % module - -srcs = [] - -srcs.append("../rtl/%s.v" % module) -srcs.append("../rtl/common/mqnic_interface.v") -srcs.append("../rtl/common/mqnic_port.v") -srcs.append("../rtl/common/cpl_write.v") -srcs.append("../rtl/common/cpl_op_mux.v") -srcs.append("../rtl/common/desc_fetch.v") -srcs.append("../rtl/common/desc_op_mux.v") -srcs.append("../rtl/common/queue_manager.v") -srcs.append("../rtl/common/cpl_queue_manager.v") -srcs.append("../rtl/common/tx_engine.v") -srcs.append("../rtl/common/rx_engine.v") -srcs.append("../rtl/common/tx_checksum.v") -srcs.append("../rtl/common/rx_hash.v") -srcs.append("../rtl/common/rx_checksum.v") -srcs.append("../rtl/common/tx_scheduler_rr.v") -srcs.append("../rtl/common/tx_scheduler_ctrl_tdma.v") -srcs.append("../rtl/common/event_mux.v") -srcs.append("../rtl/common/tdma_scheduler.v") -srcs.append("../rtl/common/tdma_ber.v") -srcs.append("../rtl/common/tdma_ber_ch.v") -srcs.append("../lib/eth/rtl/eth_mac_10g_fifo.v") -srcs.append("../lib/eth/rtl/eth_mac_10g.v") -srcs.append("../lib/eth/rtl/axis_xgmii_rx_64.v") -srcs.append("../lib/eth/rtl/axis_xgmii_tx_64.v") -srcs.append("../lib/eth/rtl/lfsr.v") -srcs.append("../lib/eth/rtl/ptp_clock.v") -srcs.append("../lib/eth/rtl/ptp_clock_cdc.v") -srcs.append("../lib/eth/rtl/ptp_perout.v") -srcs.append("../lib/eth/rtl/ptp_ts_extract.v") -srcs.append("../lib/axi/rtl/axil_interconnect.v") -srcs.append("../lib/axi/rtl/arbiter.v") -srcs.append("../lib/axi/rtl/priority_encoder.v") -srcs.append("../lib/axis/rtl/axis_adapter.v") -srcs.append("../lib/axis/rtl/axis_arb_mux.v") -srcs.append("../lib/axis/rtl/axis_async_fifo.v") -srcs.append("../lib/axis/rtl/axis_async_fifo_adapter.v") -srcs.append("../lib/axis/rtl/axis_fifo.v") -srcs.append("../lib/axis/rtl/axis_register.v") -srcs.append("../lib/pcie/rtl/pcie_us_axil_master.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_pcie_us_wr.v") -srcs.append("../lib/pcie/rtl/dma_if_mux.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_rd.v") -srcs.append("../lib/pcie/rtl/dma_if_mux_wr.v") -srcs.append("../lib/pcie/rtl/dma_psdpram.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_sink.v") -srcs.append("../lib/pcie/rtl/dma_client_axis_source.v") -srcs.append("../lib/pcie/rtl/pcie_us_cfg.v") -srcs.append("../lib/pcie/rtl/pcie_us_msi.v") -srcs.append("../lib/pcie/rtl/pcie_tag_manager.v") -srcs.append("../lib/pcie/rtl/pulse_merge.v") -srcs.append("%s.v" % testbench) - -src = ' '.join(srcs) - -build_cmd = "iverilog -o %s.vvp %s" % (testbench, src) - -def frame_checksum(frame): - data = frame[14:] - - csum = 0 - odd = False - - for b in data: - if odd: - csum += b - else: - csum += b << 8 - odd = not odd - - csum = (csum & 0xffff) + (csum >> 16) - csum = (csum & 0xffff) + (csum >> 16) - - return csum - -def bench(): - - # Parameters - AXIS_PCIE_DATA_WIDTH = 512 - AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32) - AXIS_PCIE_RC_USER_WIDTH = 161 - AXIS_PCIE_RQ_USER_WIDTH = 137 - AXIS_PCIE_CQ_USER_WIDTH = 183 - AXIS_PCIE_CC_USER_WIDTH = 81 - RQ_SEQ_NUM_WIDTH = 6 - BAR0_APERTURE = 24 - - # Inputs - clk = Signal(bool(0)) - rst = Signal(bool(0)) - current_test = Signal(intbv(0)[8:]) - - clk_250mhz = Signal(bool(0)) - rst_250mhz = Signal(bool(0)) - btnu = Signal(bool(0)) - btnl = Signal(bool(0)) - btnd = Signal(bool(0)) - btnr = Signal(bool(0)) - btnc = Signal(bool(0)) - sw = Signal(intbv(0)[4:]) - i2c_scl_i = Signal(bool(1)) - i2c_sda_i = Signal(bool(1)) - m_axis_rq_tready = Signal(bool(0)) - s_axis_rc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_rc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_rc_tlast = Signal(bool(0)) - s_axis_rc_tuser = Signal(intbv(0)[AXIS_PCIE_RC_USER_WIDTH:]) - s_axis_rc_tvalid = Signal(bool(0)) - s_axis_cq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - s_axis_cq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - s_axis_cq_tlast = Signal(bool(0)) - s_axis_cq_tuser = Signal(intbv(0)[AXIS_PCIE_CQ_USER_WIDTH:]) - s_axis_cq_tvalid = Signal(bool(0)) - m_axis_cc_tready = Signal(bool(0)) - s_axis_rq_seq_num_0 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_0 = Signal(bool(0)) - s_axis_rq_seq_num_1 = Signal(intbv(0)[RQ_SEQ_NUM_WIDTH:]) - s_axis_rq_seq_num_valid_1 = Signal(bool(0)) - pcie_tfc_nph_av = Signal(intbv(15)[4:]) - pcie_tfc_npd_av = Signal(intbv(15)[4:]) - cfg_max_payload = Signal(intbv(0)[2:]) - cfg_max_read_req = Signal(intbv(0)[3:]) - cfg_mgmt_read_data = Signal(intbv(0)[32:]) - cfg_mgmt_read_write_done = Signal(bool(0)) - cfg_fc_ph = Signal(intbv(0)[8:]) - cfg_fc_pd = Signal(intbv(0)[12:]) - cfg_fc_nph = Signal(intbv(0)[8:]) - cfg_fc_npd = Signal(intbv(0)[12:]) - cfg_fc_cplh = Signal(intbv(0)[8:]) - cfg_fc_cpld = Signal(intbv(0)[12:]) - cfg_interrupt_msi_enable = Signal(intbv(0)[4:]) - cfg_interrupt_msi_mmenable = Signal(intbv(0)[12:]) - cfg_interrupt_msi_mask_update = Signal(bool(0)) - cfg_interrupt_msi_data = Signal(intbv(0)[32:]) - cfg_interrupt_msi_sent = Signal(bool(0)) - cfg_interrupt_msi_fail = Signal(bool(0)) - qsfp1_tx_clk_1 = Signal(bool(0)) - qsfp1_tx_rst_1 = Signal(bool(0)) - qsfp1_rx_clk_1 = Signal(bool(0)) - qsfp1_rx_rst_1 = Signal(bool(0)) - qsfp1_rxd_1 = Signal(intbv(0)[64:]) - qsfp1_rxc_1 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_2 = Signal(bool(0)) - qsfp1_tx_rst_2 = Signal(bool(0)) - qsfp1_rx_clk_2 = Signal(bool(0)) - qsfp1_rx_rst_2 = Signal(bool(0)) - qsfp1_rxd_2 = Signal(intbv(0)[64:]) - qsfp1_rxc_2 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_3 = Signal(bool(0)) - qsfp1_tx_rst_3 = Signal(bool(0)) - qsfp1_rx_clk_3 = Signal(bool(0)) - qsfp1_rx_rst_3 = Signal(bool(0)) - qsfp1_rxd_3 = Signal(intbv(0)[64:]) - qsfp1_rxc_3 = Signal(intbv(0)[8:]) - qsfp1_tx_clk_4 = Signal(bool(0)) - qsfp1_tx_rst_4 = Signal(bool(0)) - qsfp1_rx_clk_4 = Signal(bool(0)) - qsfp1_rx_rst_4 = Signal(bool(0)) - qsfp1_rxd_4 = Signal(intbv(0)[64:]) - qsfp1_rxc_4 = Signal(intbv(0)[8:]) - qsfp1_modprsl = Signal(bool(1)) - qsfp1_intl = Signal(bool(1)) - qsfp2_tx_clk_1 = Signal(bool(0)) - qsfp2_tx_rst_1 = Signal(bool(0)) - qsfp2_rx_clk_1 = Signal(bool(0)) - qsfp2_rx_rst_1 = Signal(bool(0)) - qsfp2_rxd_1 = Signal(intbv(0)[64:]) - qsfp2_rxc_1 = Signal(intbv(0)[8:]) - qsfp2_tx_clk_2 = Signal(bool(0)) - qsfp2_tx_rst_2 = Signal(bool(0)) - qsfp2_rx_clk_2 = Signal(bool(0)) - qsfp2_rx_rst_2 = Signal(bool(0)) - qsfp2_rxd_2 = Signal(intbv(0)[64:]) - qsfp2_rxc_2 = Signal(intbv(0)[8:]) - qsfp2_tx_clk_3 = Signal(bool(0)) - qsfp2_tx_rst_3 = Signal(bool(0)) - qsfp2_rx_clk_3 = Signal(bool(0)) - qsfp2_rx_rst_3 = Signal(bool(0)) - qsfp2_rxd_3 = Signal(intbv(0)[64:]) - qsfp2_rxc_3 = Signal(intbv(0)[8:]) - qsfp2_tx_clk_4 = Signal(bool(0)) - qsfp2_tx_rst_4 = Signal(bool(0)) - qsfp2_rx_clk_4 = Signal(bool(0)) - qsfp2_rx_rst_4 = Signal(bool(0)) - qsfp2_rxd_4 = Signal(intbv(0)[64:]) - qsfp2_rxc_4 = Signal(intbv(0)[8:]) - qsfp2_modprsl = Signal(bool(1)) - qsfp2_intl = Signal(bool(1)) - qspi_0_dq_i = Signal(intbv(0)[4:]) - qspi_1_dq_i = Signal(intbv(0)[4:]) - - # Outputs - led = Signal(intbv(0)[8:]) - i2c_scl_o = Signal(bool(1)) - i2c_scl_t = Signal(bool(1)) - i2c_sda_o = Signal(bool(1)) - i2c_sda_t = Signal(bool(1)) - m_axis_rq_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_rq_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_rq_tlast = Signal(bool(0)) - m_axis_rq_tuser = Signal(intbv(0)[AXIS_PCIE_RQ_USER_WIDTH:]) - m_axis_rq_tvalid = Signal(bool(0)) - s_axis_rc_tready = Signal(bool(0)) - s_axis_cq_tready = Signal(bool(0)) - m_axis_cc_tdata = Signal(intbv(0)[AXIS_PCIE_DATA_WIDTH:]) - m_axis_cc_tkeep = Signal(intbv(0)[AXIS_PCIE_KEEP_WIDTH:]) - m_axis_cc_tlast = Signal(bool(0)) - m_axis_cc_tuser = Signal(intbv(0)[AXIS_PCIE_CC_USER_WIDTH:]) - m_axis_cc_tvalid = Signal(bool(0)) - status_error_cor = Signal(bool(0)) - status_error_uncor = Signal(bool(0)) - cfg_mgmt_addr = Signal(intbv(0)[10:]) - cfg_mgmt_function_number = Signal(intbv(0)[8:]) - cfg_mgmt_write = Signal(bool(0)) - cfg_mgmt_write_data = Signal(intbv(0)[32:]) - cfg_mgmt_byte_enable = Signal(intbv(0)[4:]) - cfg_mgmt_read = Signal(bool(0)) - cfg_fc_sel = Signal(intbv(4)[3:]) - cfg_interrupt_msi_int = Signal(intbv(0)[32:]) - cfg_interrupt_msi_pending_status = Signal(intbv(0)[32:]) - cfg_interrupt_msi_select = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_function_num = Signal(intbv(0)[2:]) - cfg_interrupt_msi_pending_status_data_enable = Signal(bool(0)) - cfg_interrupt_msi_attr = Signal(intbv(0)[3:]) - cfg_interrupt_msi_tph_present = Signal(bool(0)) - cfg_interrupt_msi_tph_type = Signal(intbv(0)[2:]) - cfg_interrupt_msi_tph_st_tag = Signal(intbv(0)[8:]) - cfg_interrupt_msi_function_number = Signal(intbv(0)[8:]) - qsfp1_txd_1 = Signal(intbv(0)[64:]) - qsfp1_txc_1 = Signal(intbv(0)[8:]) - qsfp1_txd_2 = Signal(intbv(0)[64:]) - qsfp1_txc_2 = Signal(intbv(0)[8:]) - qsfp1_txd_3 = Signal(intbv(0)[64:]) - qsfp1_txc_3 = Signal(intbv(0)[8:]) - qsfp1_txd_4 = Signal(intbv(0)[64:]) - qsfp1_txc_4 = Signal(intbv(0)[8:]) - qsfp1_modsell = Signal(bool(0)) - qsfp1_resetl = Signal(bool(0)) - qsfp1_lpmode = Signal(bool(0)) - qsfp2_txd_1 = Signal(intbv(0)[64:]) - qsfp2_txc_1 = Signal(intbv(0)[8:]) - qsfp2_txd_2 = Signal(intbv(0)[64:]) - qsfp2_txc_2 = Signal(intbv(0)[8:]) - qsfp2_txd_3 = Signal(intbv(0)[64:]) - qsfp2_txc_3 = Signal(intbv(0)[8:]) - qsfp2_txd_4 = Signal(intbv(0)[64:]) - qsfp2_txc_4 = Signal(intbv(0)[8:]) - qsfp2_modsell = Signal(bool(0)) - qsfp2_resetl = Signal(bool(0)) - qsfp2_lpmode = Signal(bool(0)) - fpga_boot = Signal(bool(0)) - qspi_clk = Signal(bool(0)) - qspi_0_dq_o = Signal(intbv(0)[4:]) - qspi_0_dq_oe = Signal(intbv(0)[4:]) - qspi_0_cs = Signal(bool(1)) - qspi_1_dq_o = Signal(intbv(0)[4:]) - qspi_1_dq_oe = Signal(intbv(0)[4:]) - qspi_1_cs = Signal(bool(1)) - - # sources and sinks - qsfp1_1_source = xgmii_ep.XGMIISource() - qsfp1_1_source_logic = qsfp1_1_source.create_logic(qsfp1_rx_clk_1, qsfp1_rx_rst_1, txd=qsfp1_rxd_1, txc=qsfp1_rxc_1, name='qsfp1_1_source') - - qsfp1_1_sink = xgmii_ep.XGMIISink() - qsfp1_1_sink_logic = qsfp1_1_sink.create_logic(qsfp1_tx_clk_1, qsfp1_tx_rst_1, rxd=qsfp1_txd_1, rxc=qsfp1_txc_1, name='qsfp1_1_sink') - - qsfp1_2_source = xgmii_ep.XGMIISource() - qsfp1_2_source_logic = qsfp1_2_source.create_logic(qsfp1_rx_clk_2, qsfp1_rx_rst_2, txd=qsfp1_rxd_2, txc=qsfp1_rxc_2, name='qsfp1_2_source') - - qsfp1_2_sink = xgmii_ep.XGMIISink() - qsfp1_2_sink_logic = qsfp1_2_sink.create_logic(qsfp1_tx_clk_2, qsfp1_tx_rst_2, rxd=qsfp1_txd_2, rxc=qsfp1_txc_2, name='qsfp1_2_sink') - - qsfp1_3_source = xgmii_ep.XGMIISource() - qsfp1_3_source_logic = qsfp1_3_source.create_logic(qsfp1_rx_clk_3, qsfp1_rx_rst_3, txd=qsfp1_rxd_3, txc=qsfp1_rxc_3, name='qsfp1_3_source') - - qsfp1_3_sink = xgmii_ep.XGMIISink() - qsfp1_3_sink_logic = qsfp1_3_sink.create_logic(qsfp1_tx_clk_3, qsfp1_tx_rst_3, rxd=qsfp1_txd_3, rxc=qsfp1_txc_3, name='qsfp1_3_sink') - - qsfp1_4_source = xgmii_ep.XGMIISource() - qsfp1_4_source_logic = qsfp1_4_source.create_logic(qsfp1_rx_clk_4, qsfp1_rx_rst_4, txd=qsfp1_rxd_4, txc=qsfp1_rxc_4, name='qsfp1_4_source') - - qsfp1_4_sink = xgmii_ep.XGMIISink() - qsfp1_4_sink_logic = qsfp1_4_sink.create_logic(qsfp1_tx_clk_4, qsfp1_tx_rst_4, rxd=qsfp1_txd_4, rxc=qsfp1_txc_4, name='qsfp1_4_sink') - - qsfp2_1_source = xgmii_ep.XGMIISource() - qsfp2_1_source_logic = qsfp2_1_source.create_logic(qsfp2_rx_clk_1, qsfp2_rx_rst_1, txd=qsfp2_rxd_1, txc=qsfp2_rxc_1, name='qsfp2_1_source') - - qsfp2_1_sink = xgmii_ep.XGMIISink() - qsfp2_1_sink_logic = qsfp2_1_sink.create_logic(qsfp2_tx_clk_1, qsfp2_tx_rst_1, rxd=qsfp2_txd_1, rxc=qsfp2_txc_1, name='qsfp2_1_sink') - - qsfp2_2_source = xgmii_ep.XGMIISource() - qsfp2_2_source_logic = qsfp2_2_source.create_logic(qsfp2_rx_clk_2, qsfp2_rx_rst_2, txd=qsfp2_rxd_2, txc=qsfp2_rxc_2, name='qsfp2_2_source') - - qsfp2_2_sink = xgmii_ep.XGMIISink() - qsfp2_2_sink_logic = qsfp2_2_sink.create_logic(qsfp2_tx_clk_2, qsfp2_tx_rst_2, rxd=qsfp2_txd_2, rxc=qsfp2_txc_2, name='qsfp2_2_sink') - - qsfp2_3_source = xgmii_ep.XGMIISource() - qsfp2_3_source_logic = qsfp2_3_source.create_logic(qsfp2_rx_clk_3, qsfp2_rx_rst_3, txd=qsfp2_rxd_3, txc=qsfp2_rxc_3, name='qsfp2_3_source') - - qsfp2_3_sink = xgmii_ep.XGMIISink() - qsfp2_3_sink_logic = qsfp2_3_sink.create_logic(qsfp2_tx_clk_3, qsfp2_tx_rst_3, rxd=qsfp2_txd_3, rxc=qsfp2_txc_3, name='qsfp2_3_sink') - - qsfp2_4_source = xgmii_ep.XGMIISource() - qsfp2_4_source_logic = qsfp2_4_source.create_logic(qsfp2_rx_clk_4, qsfp2_rx_rst_4, txd=qsfp2_rxd_4, txc=qsfp2_rxc_4, name='qsfp2_4_source') - - qsfp2_4_sink = xgmii_ep.XGMIISink() - qsfp2_4_sink_logic = qsfp2_4_sink.create_logic(qsfp2_tx_clk_4, qsfp2_tx_rst_4, rxd=qsfp2_txd_4, rxc=qsfp2_txc_4, name='qsfp2_4_sink') - - # Clock and Reset Interface - user_clk=Signal(bool(0)) - user_reset=Signal(bool(0)) - sys_clk=Signal(bool(0)) - sys_reset=Signal(bool(0)) - - # PCIe devices - rc = pcie.RootComplex() - - rc.max_payload_size = 0x1 # 256 bytes - rc.max_read_request_size = 0x5 # 4096 bytes - - driver = mqnic.Driver(rc) - - dev = pcie_usp.UltrascalePlusPCIe() - - dev.pcie_generation = 3 - dev.pcie_link_width = 16 - dev.user_clk_frequency = 250e6 - - dev.functions[0].msi_multiple_message_capable = 5 - - dev.functions[0].configure_bar(0, 2**BAR0_APERTURE, ext=True, prefetch=True) - - rc.make_port().connect(dev) - - cq_pause = Signal(bool(0)) - cc_pause = Signal(bool(0)) - rq_pause = Signal(bool(0)) - rc_pause = Signal(bool(0)) - - pcie_logic = dev.create_logic( - # Completer reQuest Interface - m_axis_cq_tdata=s_axis_cq_tdata, - m_axis_cq_tuser=s_axis_cq_tuser, - m_axis_cq_tlast=s_axis_cq_tlast, - m_axis_cq_tkeep=s_axis_cq_tkeep, - m_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cq_tready=s_axis_cq_tready, - #pcie_cq_np_req=pcie_cq_np_req, - pcie_cq_np_req=Signal(intbv(3)[2:]), - #pcie_cq_np_req_count=pcie_cq_np_req_count, - - # Completer Completion Interface - s_axis_cc_tdata=m_axis_cc_tdata, - s_axis_cc_tuser=m_axis_cc_tuser, - s_axis_cc_tlast=m_axis_cc_tlast, - s_axis_cc_tkeep=m_axis_cc_tkeep, - s_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_cc_tready=m_axis_cc_tready, - - # Requester reQuest Interface - s_axis_rq_tdata=m_axis_rq_tdata, - s_axis_rq_tuser=m_axis_rq_tuser, - s_axis_rq_tlast=m_axis_rq_tlast, - s_axis_rq_tkeep=m_axis_rq_tkeep, - s_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rq_tready=m_axis_rq_tready, - pcie_rq_seq_num0=s_axis_rq_seq_num_0, - pcie_rq_seq_num_vld0=s_axis_rq_seq_num_valid_0, - pcie_rq_seq_num1=s_axis_rq_seq_num_1, - pcie_rq_seq_num_vld1=s_axis_rq_seq_num_valid_1, - #pcie_rq_tag0=pcie_rq_tag0, - #pcie_rq_tag1=pcie_rq_tag1, - #pcie_rq_tag_av=pcie_rq_tag_av, - #pcie_rq_tag_vld0=pcie_rq_tag_vld0, - #pcie_rq_tag_vld1=pcie_rq_tag_vld1, - - # Requester Completion Interface - m_axis_rc_tdata=s_axis_rc_tdata, - m_axis_rc_tuser=s_axis_rc_tuser, - m_axis_rc_tlast=s_axis_rc_tlast, - m_axis_rc_tkeep=s_axis_rc_tkeep, - m_axis_rc_tvalid=s_axis_rc_tvalid, - m_axis_rc_tready=s_axis_rc_tready, - - # Transmit Flow Control Interface - #pcie_tfc_nph_av=pcie_tfc_nph_av, - #pcie_tfc_npd_av=pcie_tfc_npd_av, - - # Configuration Management Interface - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - #cfg_mgmt_debug_access=cfg_mgmt_debug_access, - - # Configuration Status Interface - #cfg_phy_link_down=cfg_phy_link_down, - #cfg_phy_link_status=cfg_phy_link_status, - #cfg_negotiated_width=cfg_negotiated_width, - #cfg_current_speed=cfg_current_speed, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - #cfg_function_status=cfg_function_status, - #cfg_vf_status=cfg_vf_status, - #cfg_function_power_state=cfg_function_power_state, - #cfg_vf_power_state=cfg_vf_power_state, - #cfg_link_power_state=cfg_link_power_state, - #cfg_err_cor_out=cfg_err_cor_out, - #cfg_err_nonfatal_out=cfg_err_nonfatal_out, - #cfg_err_fatal_out=cfg_err_fatal_out, - #cfg_local_err_out=cfg_local_err_out, - #cfg_local_err_valid=cfg_local_err_valid, - #cfg_rx_pm_state=cfg_rx_pm_state, - #cfg_tx_pm_state=cfg_tx_pm_state, - #cfg_ltssm_state=cfg_ltssm_state, - #cfg_rcb_status=cfg_rcb_status, - #cfg_obff_enable=cfg_obff_enable, - #cfg_pl_status_change=cfg_pl_status_change, - #cfg_tph_requester_enable=cfg_tph_requester_enable, - #cfg_tph_st_mode=cfg_tph_st_mode, - #cfg_vf_tph_requester_enable=cfg_vf_tph_requester_enable, - #cfg_vf_tph_st_mode=cfg_vf_tph_st_mode, - - # Configuration Received Message Interface - #cfg_msg_received=cfg_msg_received, - #cfg_msg_received_data=cfg_msg_received_data, - #cfg_msg_received_type=cfg_msg_received_type, - - # Configuration Transmit Message Interface - #cfg_msg_transmit=cfg_msg_transmit, - #cfg_msg_transmit_type=cfg_msg_transmit_type, - #cfg_msg_transmit_data=cfg_msg_transmit_data, - #cfg_msg_transmit_done=cfg_msg_transmit_done, - - # Configuration Flow Control Interface - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - - # Configuration Control Interface - #cfg_hot_reset_in=cfg_hot_reset_in, - #cfg_hot_reset_out=cfg_hot_reset_out, - #cfg_config_space_enable=cfg_config_space_enable, - #cfg_dsn=cfg_dsn, - #cfg_ds_port_number=cfg_ds_port_number, - #cfg_ds_bus_number=cfg_ds_bus_number, - #cfg_ds_device_number=cfg_ds_device_number, - #cfg_ds_function_number=cfg_ds_function_number, - #cfg_power_state_change_ack=cfg_power_state_change_ack, - #cfg_power_state_change_interrupt=cfg_power_state_change_interrupt, - cfg_err_cor_in=status_error_cor, - cfg_err_uncor_in=status_error_uncor, - #cfg_flr_done=cfg_flr_done, - #cfg_vf_flr_done=cfg_vf_flr_done, - #cfg_flr_in_process=cfg_flr_in_process, - #cfg_vf_flr_in_process=cfg_vf_flr_in_process, - #cfg_req_pm_transition_l23_ready=cfg_req_pm_transition_l23_ready, - #cfg_link_training_enable=cfg_link_training_enable, - - # Configuration Interrupt Controller Interface - #cfg_interrupt_int=cfg_interrupt_int, - #cfg_interrupt_sent=cfg_interrupt_sent, - #cfg_interrupt_pending=cfg_interrupt_pending, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - #cfg_interrupt_msix_enable=cfg_interrupt_msix_enable, - #cfg_interrupt_msix_mask=cfg_interrupt_msix_mask, - #cfg_interrupt_msix_vf_enable=cfg_interrupt_msix_vf_enable, - #cfg_interrupt_msix_vf_mask=cfg_interrupt_msix_vf_mask, - #cfg_interrupt_msix_address=cfg_interrupt_msix_address, - #cfg_interrupt_msix_data=cfg_interrupt_msix_data, - #cfg_interrupt_msix_int=cfg_interrupt_msix_int, - #cfg_interrupt_msix_vec_pending=cfg_interrupt_msix_vec_pending, - #cfg_interrupt_msix_vec_pending_status=cfg_interrupt_msix_vec_pending_status, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - - # Configuration Extend Interface - #cfg_ext_read_received=cfg_ext_read_received, - #cfg_ext_write_received=cfg_ext_write_received, - #cfg_ext_register_number=cfg_ext_register_number, - #cfg_ext_function_number=cfg_ext_function_number, - #cfg_ext_write_data=cfg_ext_write_data, - #cfg_ext_write_byte_enable=cfg_ext_write_byte_enable, - #cfg_ext_read_data=cfg_ext_read_data, - #cfg_ext_read_data_valid=cfg_ext_read_data_valid, - - # Clock and Reset Interface - user_clk=user_clk, - user_reset=user_reset, - sys_clk=sys_clk, - sys_clk_gt=sys_clk, - sys_reset=sys_reset, - #phy_rdy_out=phy_rdy_out, - - cq_pause=cq_pause, - cc_pause=cc_pause, - rq_pause=rq_pause, - rc_pause=rc_pause - ) - - # DUT - if os.system(build_cmd): - raise Exception("Error running build command") - - dut = Cosimulation( - "vvp -m myhdl %s.vvp -lxt2" % testbench, - clk=clk, - rst=rst, - current_test=current_test, - clk_250mhz=user_clk, - rst_250mhz=user_reset, - btnu=btnu, - btnl=btnl, - btnd=btnd, - btnr=btnr, - btnc=btnc, - sw=sw, - led=led, - i2c_scl_i=i2c_scl_i, - i2c_scl_o=i2c_scl_o, - i2c_scl_t=i2c_scl_t, - i2c_sda_i=i2c_sda_i, - i2c_sda_o=i2c_sda_o, - i2c_sda_t=i2c_sda_t, - m_axis_rq_tdata=m_axis_rq_tdata, - m_axis_rq_tkeep=m_axis_rq_tkeep, - m_axis_rq_tlast=m_axis_rq_tlast, - m_axis_rq_tready=m_axis_rq_tready, - m_axis_rq_tuser=m_axis_rq_tuser, - m_axis_rq_tvalid=m_axis_rq_tvalid, - s_axis_rc_tdata=s_axis_rc_tdata, - s_axis_rc_tkeep=s_axis_rc_tkeep, - s_axis_rc_tlast=s_axis_rc_tlast, - s_axis_rc_tready=s_axis_rc_tready, - s_axis_rc_tuser=s_axis_rc_tuser, - s_axis_rc_tvalid=s_axis_rc_tvalid, - s_axis_cq_tdata=s_axis_cq_tdata, - s_axis_cq_tkeep=s_axis_cq_tkeep, - s_axis_cq_tlast=s_axis_cq_tlast, - s_axis_cq_tready=s_axis_cq_tready, - s_axis_cq_tuser=s_axis_cq_tuser, - s_axis_cq_tvalid=s_axis_cq_tvalid, - m_axis_cc_tdata=m_axis_cc_tdata, - m_axis_cc_tkeep=m_axis_cc_tkeep, - m_axis_cc_tlast=m_axis_cc_tlast, - m_axis_cc_tready=m_axis_cc_tready, - m_axis_cc_tuser=m_axis_cc_tuser, - m_axis_cc_tvalid=m_axis_cc_tvalid, - s_axis_rq_seq_num_0=s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0=s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1=s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1=s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av=pcie_tfc_nph_av, - pcie_tfc_npd_av=pcie_tfc_npd_av, - cfg_max_payload=cfg_max_payload, - cfg_max_read_req=cfg_max_read_req, - cfg_mgmt_addr=cfg_mgmt_addr, - cfg_mgmt_function_number=cfg_mgmt_function_number, - cfg_mgmt_write=cfg_mgmt_write, - cfg_mgmt_write_data=cfg_mgmt_write_data, - cfg_mgmt_byte_enable=cfg_mgmt_byte_enable, - cfg_mgmt_read=cfg_mgmt_read, - cfg_mgmt_read_data=cfg_mgmt_read_data, - cfg_mgmt_read_write_done=cfg_mgmt_read_write_done, - cfg_fc_ph=cfg_fc_ph, - cfg_fc_pd=cfg_fc_pd, - cfg_fc_nph=cfg_fc_nph, - cfg_fc_npd=cfg_fc_npd, - cfg_fc_cplh=cfg_fc_cplh, - cfg_fc_cpld=cfg_fc_cpld, - cfg_fc_sel=cfg_fc_sel, - cfg_interrupt_msi_enable=cfg_interrupt_msi_enable, - cfg_interrupt_msi_int=cfg_interrupt_msi_int, - cfg_interrupt_msi_sent=cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail=cfg_interrupt_msi_fail, - cfg_interrupt_msi_mmenable=cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_pending_status=cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_mask_update=cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_select=cfg_interrupt_msi_select, - cfg_interrupt_msi_data=cfg_interrupt_msi_data, - cfg_interrupt_msi_pending_status_function_num=cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_pending_status_data_enable=cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_attr=cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present=cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type=cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag=cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number=cfg_interrupt_msi_function_number, - status_error_cor=status_error_cor, - status_error_uncor=status_error_uncor, - qsfp1_tx_clk_1=qsfp1_tx_clk_1, - qsfp1_tx_rst_1=qsfp1_tx_rst_1, - qsfp1_txd_1=qsfp1_txd_1, - qsfp1_txc_1=qsfp1_txc_1, - qsfp1_rx_clk_1=qsfp1_rx_clk_1, - qsfp1_rx_rst_1=qsfp1_rx_rst_1, - qsfp1_rxd_1=qsfp1_rxd_1, - qsfp1_rxc_1=qsfp1_rxc_1, - qsfp1_tx_clk_2=qsfp1_tx_clk_2, - qsfp1_tx_rst_2=qsfp1_tx_rst_2, - qsfp1_txd_2=qsfp1_txd_2, - qsfp1_txc_2=qsfp1_txc_2, - qsfp1_rx_clk_2=qsfp1_rx_clk_2, - qsfp1_rx_rst_2=qsfp1_rx_rst_2, - qsfp1_rxd_2=qsfp1_rxd_2, - qsfp1_rxc_2=qsfp1_rxc_2, - qsfp1_tx_clk_3=qsfp1_tx_clk_3, - qsfp1_tx_rst_3=qsfp1_tx_rst_3, - qsfp1_txd_3=qsfp1_txd_3, - qsfp1_txc_3=qsfp1_txc_3, - qsfp1_rx_clk_3=qsfp1_rx_clk_3, - qsfp1_rx_rst_3=qsfp1_rx_rst_3, - qsfp1_rxd_3=qsfp1_rxd_3, - qsfp1_rxc_3=qsfp1_rxc_3, - qsfp1_tx_clk_4=qsfp1_tx_clk_4, - qsfp1_tx_rst_4=qsfp1_tx_rst_4, - qsfp1_txd_4=qsfp1_txd_4, - qsfp1_txc_4=qsfp1_txc_4, - qsfp1_rx_clk_4=qsfp1_rx_clk_4, - qsfp1_rx_rst_4=qsfp1_rx_rst_4, - qsfp1_rxd_4=qsfp1_rxd_4, - qsfp1_rxc_4=qsfp1_rxc_4, - qsfp1_modprsl=qsfp1_modprsl, - qsfp1_modsell=qsfp1_modsell, - qsfp1_resetl=qsfp1_resetl, - qsfp1_intl=qsfp1_intl, - qsfp1_lpmode=qsfp1_lpmode, - qsfp2_tx_clk_1=qsfp2_tx_clk_1, - qsfp2_tx_rst_1=qsfp2_tx_rst_1, - qsfp2_txd_1=qsfp2_txd_1, - qsfp2_txc_1=qsfp2_txc_1, - qsfp2_rx_clk_1=qsfp2_rx_clk_1, - qsfp2_rx_rst_1=qsfp2_rx_rst_1, - qsfp2_rxd_1=qsfp2_rxd_1, - qsfp2_rxc_1=qsfp2_rxc_1, - qsfp2_tx_clk_2=qsfp2_tx_clk_2, - qsfp2_tx_rst_2=qsfp2_tx_rst_2, - qsfp2_txd_2=qsfp2_txd_2, - qsfp2_txc_2=qsfp2_txc_2, - qsfp2_rx_clk_2=qsfp2_rx_clk_2, - qsfp2_rx_rst_2=qsfp2_rx_rst_2, - qsfp2_rxd_2=qsfp2_rxd_2, - qsfp2_rxc_2=qsfp2_rxc_2, - qsfp2_tx_clk_3=qsfp2_tx_clk_3, - qsfp2_tx_rst_3=qsfp2_tx_rst_3, - qsfp2_txd_3=qsfp2_txd_3, - qsfp2_txc_3=qsfp2_txc_3, - qsfp2_rx_clk_3=qsfp2_rx_clk_3, - qsfp2_rx_rst_3=qsfp2_rx_rst_3, - qsfp2_rxd_3=qsfp2_rxd_3, - qsfp2_rxc_3=qsfp2_rxc_3, - qsfp2_tx_clk_4=qsfp2_tx_clk_4, - qsfp2_tx_rst_4=qsfp2_tx_rst_4, - qsfp2_txd_4=qsfp2_txd_4, - qsfp2_txc_4=qsfp2_txc_4, - qsfp2_rx_clk_4=qsfp2_rx_clk_4, - qsfp2_rx_rst_4=qsfp2_rx_rst_4, - qsfp2_rxd_4=qsfp2_rxd_4, - qsfp2_rxc_4=qsfp2_rxc_4, - qsfp2_modprsl=qsfp2_modprsl, - qsfp2_modsell=qsfp2_modsell, - qsfp2_resetl=qsfp2_resetl, - qsfp2_intl=qsfp2_intl, - qsfp2_lpmode=qsfp2_lpmode, - fpga_boot=fpga_boot, - qspi_clk=qspi_clk, - qspi_0_dq_i=qspi_0_dq_i, - qspi_0_dq_o=qspi_0_dq_o, - qspi_0_dq_oe=qspi_0_dq_oe, - qspi_0_cs=qspi_0_cs, - qspi_1_dq_i=qspi_1_dq_i, - qspi_1_dq_o=qspi_1_dq_o, - qspi_1_dq_oe=qspi_1_dq_oe, - qspi_1_cs=qspi_1_cs - ) - - @always(delay(5)) - def clkgen(): - clk.next = not clk - - @always(delay(3)) - def qsfp_clkgen(): - qsfp1_tx_clk_1.next = not qsfp1_tx_clk_1 - qsfp1_rx_clk_1.next = not qsfp1_rx_clk_1 - qsfp1_tx_clk_2.next = not qsfp1_tx_clk_2 - qsfp1_rx_clk_2.next = not qsfp1_rx_clk_2 - qsfp1_tx_clk_3.next = not qsfp1_tx_clk_3 - qsfp1_rx_clk_3.next = not qsfp1_rx_clk_3 - qsfp1_tx_clk_4.next = not qsfp1_tx_clk_4 - qsfp1_rx_clk_4.next = not qsfp1_rx_clk_4 - qsfp2_tx_clk_1.next = not qsfp2_tx_clk_1 - qsfp2_rx_clk_1.next = not qsfp2_rx_clk_1 - qsfp2_tx_clk_2.next = not qsfp2_tx_clk_2 - qsfp2_rx_clk_2.next = not qsfp2_rx_clk_2 - qsfp2_tx_clk_3.next = not qsfp2_tx_clk_3 - qsfp2_rx_clk_3.next = not qsfp2_rx_clk_3 - qsfp2_tx_clk_4.next = not qsfp2_tx_clk_4 - qsfp2_rx_clk_4.next = not qsfp2_rx_clk_4 - - @always_comb - def clk_logic(): - sys_clk.next = clk - sys_reset.next = not rst - - loopback_enable = Signal(bool(0)) - - @instance - def loopback(): - while True: - - yield clk.posedge - - if loopback_enable: - if not qsfp1_1_sink.empty(): - pkt = qsfp1_1_sink.recv() - qsfp1_1_source.send(pkt) - if not qsfp1_2_sink.empty(): - pkt = qsfp1_2_sink.recv() - qsfp1_2_source.send(pkt) - if not qsfp1_3_sink.empty(): - pkt = qsfp1_3_sink.recv() - qsfp1_3_source.send(pkt) - if not qsfp1_4_sink.empty(): - pkt = qsfp1_4_sink.recv() - qsfp1_4_source.send(pkt) - if not qsfp2_1_sink.empty(): - pkt = qsfp2_1_sink.recv() - qsfp2_1_source.send(pkt) - if not qsfp2_2_sink.empty(): - pkt = qsfp2_2_sink.recv() - qsfp2_2_source.send(pkt) - if not qsfp2_3_sink.empty(): - pkt = qsfp2_3_sink.recv() - qsfp2_3_source.send(pkt) - if not qsfp2_4_sink.empty(): - pkt = qsfp2_4_sink.recv() - qsfp2_4_source.send(pkt) - - @instance - def check(): - yield delay(100) - yield clk.posedge - rst.next = 1 - qsfp1_tx_rst_1.next = 1 - qsfp1_rx_rst_1.next = 1 - qsfp1_tx_rst_2.next = 1 - qsfp1_rx_rst_2.next = 1 - qsfp1_tx_rst_3.next = 1 - qsfp1_rx_rst_3.next = 1 - qsfp1_tx_rst_4.next = 1 - qsfp1_rx_rst_4.next = 1 - qsfp2_tx_rst_1.next = 1 - qsfp2_rx_rst_1.next = 1 - qsfp2_tx_rst_2.next = 1 - qsfp2_rx_rst_2.next = 1 - qsfp2_tx_rst_3.next = 1 - qsfp2_rx_rst_3.next = 1 - qsfp2_tx_rst_4.next = 1 - qsfp2_rx_rst_4.next = 1 - yield clk.posedge - yield delay(100) - rst.next = 0 - qsfp1_tx_rst_1.next = 0 - qsfp1_rx_rst_1.next = 0 - qsfp1_tx_rst_2.next = 0 - qsfp1_rx_rst_2.next = 0 - qsfp1_tx_rst_3.next = 0 - qsfp1_rx_rst_3.next = 0 - qsfp1_tx_rst_4.next = 0 - qsfp1_rx_rst_4.next = 0 - qsfp2_tx_rst_1.next = 0 - qsfp2_rx_rst_1.next = 0 - qsfp2_tx_rst_2.next = 0 - qsfp2_rx_rst_2.next = 0 - qsfp2_tx_rst_3.next = 0 - qsfp2_rx_rst_3.next = 0 - qsfp2_tx_rst_4.next = 0 - qsfp2_rx_rst_4.next = 0 - yield clk.posedge - yield delay(100) - yield clk.posedge - - # testbench stimulus - - current_tag = 1 - - yield clk.posedge - print("test 1: enumeration") - current_test.next = 1 - - yield rc.enumerate(enable_bus_mastering=True, configure_msi=True) - - yield delay(100) - - yield clk.posedge - print("test 2: init NIC") - current_test.next = 2 - - yield from driver.init_dev(dev.functions[0].get_id()) - yield from driver.interfaces[0].open() - #yield from driver.interfaces[1].open() - - # enable queues - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000003) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - yield delay(100) - - yield clk.posedge - print("test 3: send and receive a packet") - current_test.next = 3 - - # test bad packet - #qsfp1_1_source.send(b'\x55\x55\x55\x55\x55\xd5'+bytearray(range(128))) - - data = bytearray([x%256 for x in range(1024)]) - - yield from driver.interfaces[0].start_xmit(data, 0) - - yield qsfp1_1_sink.wait() - - pkt = qsfp1_1_sink.recv() - print(pkt) - - qsfp1_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - assert frame_checksum(pkt.data) == pkt.rx_checksum - - # yield from driver.interfaces[1].start_xmit(data, 0) - - # yield qsfp1_1_sink.wait() - - # pkt = qsfp1_1_sink.recv() - # print(pkt) - - # qsfp1_1_source.send(pkt) - - # yield driver.interfaces[1].wait() - - # pkt = driver.interfaces[1].recv() - - # print(pkt) - # assert frame_checksum(pkt.data) == pkt.rx_checksum - - yield delay(100) - - yield clk.posedge - print("test 4: checksum tests") - current_test.next = 4 - - test_frame = udp_ep.UDPFrame() - test_frame.eth_dest_mac = 0xDAD1D2D3D4D5 - test_frame.eth_src_mac = 0x5A5152535455 - test_frame.eth_type = 0x0800 - test_frame.ip_version = 4 - test_frame.ip_ihl = 5 - test_frame.ip_length = None - test_frame.ip_identification = 0 - test_frame.ip_flags = 2 - test_frame.ip_fragment_offset = 0 - test_frame.ip_ttl = 64 - test_frame.ip_protocol = 0x11 - test_frame.ip_header_checksum = None - test_frame.ip_source_ip = 0xc0a80164 - test_frame.ip_dest_ip = 0xc0a80165 - test_frame.udp_source_port = 1 - test_frame.udp_dest_port = 2 - test_frame.udp_length = None - test_frame.udp_checksum = None - test_frame.payload = bytearray((x%256 for x in range(256))) - - test_frame.set_udp_pseudo_header_checksum() - - axis_frame = test_frame.build_axis() - - yield from driver.interfaces[0].start_xmit(axis_frame.data, 0, 34, 6) - - yield qsfp1_1_sink.wait() - - pkt = qsfp1_1_sink.recv() - print(pkt) - - qsfp1_1_source.send(pkt) - - yield driver.interfaces[0].wait() - - pkt = driver.interfaces[0].recv() - - print(pkt) - - assert pkt.rx_checksum == frame_checksum(pkt.data) - - check_frame = udp_ep.UDPFrame() - check_frame.parse_axis(pkt.data) - - assert check_frame.verify_checksums() - - yield delay(100) - - yield clk.posedge - print("test 5: multiple small packets") - current_test.next = 5 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(64)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - yield clk.posedge - print("test 6: multiple large packets") - current_test.next = 6 - - count = 64 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - for p in pkts: - yield from driver.interfaces[0].start_xmit(p, 0) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - assert pkt.data == pkts[k] - assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(1000) - - yield clk.posedge - print("test 7: TDMA") - current_test.next = 7 - - count = 16 - - pkts = [bytearray([(x+k)%256 for x in range(1514)]) for k in range(count)] - - loopback_enable.next = True - - # configure TDMA - - # configure TDMA scheduler - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_FNS, 0) # schedule period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_NS, 40000) # schedule period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_L, 0) # schedule period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_SCHED_PERIOD_SEC_H, 0) # schedule period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_FNS, 0) # timeslot period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_NS, 10000) # timeslot period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_L, 0) # timeslot period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_TIMESLOT_PERIOD_SEC_H, 0) # timeslot period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_FNS, 0) # active period fns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_NS, 5000) # active period ns - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_L, 0) # active period sec (low) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_ACTIVE_PERIOD_SEC_H, 0) # active period sec (high) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_TDMA_CTRL, 0x00000001) # enable TDMA - - # enable queues with global enable off - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].hw_addr+mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001) - for k in range(driver.interfaces[0].tx_queue_count): - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[0].hw_addr+4*k, 0x00000001) - - # configure slots - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*0, 0x00000001) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*1, 0x00000002) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*2, 0x00000004) - yield from rc.mem_write_dword(driver.interfaces[0].ports[0].schedulers[1].hw_addr+8*3, 0x00000008) - - yield from rc.mem_read(driver.hw_addr, 4) # wait for all writes to complete - - # send packets - for k in range(count): - yield from driver.interfaces[0].start_xmit(pkts[k], k%4) - - for k in range(count): - pkt = driver.interfaces[0].recv() - - if not pkt: - yield driver.interfaces[0].wait() - pkt = driver.interfaces[0].recv() - - print(pkt) - #assert pkt.data == pkts[k] - #assert frame_checksum(pkt.data) == pkt.rx_checksum - - loopback_enable.next = False - - yield delay(100) - - raise StopSimulation - - return instances() - -def test_bench(): - sim = Simulation(bench()) - sim.run() - -if __name__ == '__main__': - print("Running test...") - test_bench() diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/test_fpga_core.v b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/test_fpga_core.v deleted file mode 100644 index 8aa425bc2..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/test_fpga_core.v +++ /dev/null @@ -1,579 +0,0 @@ -/* - -Copyright 2019, The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS OF THE UNIVERSITY OF CALIFORNIA ''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 THE REGENTS OF THE UNIVERSITY OF CALIFORNIA OR -CONTRIBUTORS 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. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of The Regents of the University of California. - -*/ - -// Language: Verilog 2001 - -`timescale 1ns / 1ps - -/* - * Testbench for fpga_core - */ -module test_fpga_core; - -// Parameters -parameter AXIS_PCIE_DATA_WIDTH = 512; -parameter AXIS_PCIE_KEEP_WIDTH = (AXIS_PCIE_DATA_WIDTH/32); -parameter AXIS_PCIE_RC_USER_WIDTH = 161; -parameter AXIS_PCIE_RQ_USER_WIDTH = 137; -parameter AXIS_PCIE_CQ_USER_WIDTH = 183; -parameter AXIS_PCIE_CC_USER_WIDTH = 81; -parameter RQ_SEQ_NUM_WIDTH = 6; -parameter BAR0_APERTURE = 24; - -// Inputs -reg clk = 0; -reg rst = 0; -reg [7:0] current_test = 0; - -reg clk_250mhz = 0; -reg rst_250mhz = 0; -reg btnu = 0; -reg btnl = 0; -reg btnd = 0; -reg btnr = 0; -reg btnc = 0; -reg [3:0] sw = 0; -reg i2c_scl_i = 1; -reg i2c_sda_i = 1; -reg m_axis_rq_tready = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_rc_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_rc_tkeep = 0; -reg s_axis_rc_tlast = 0; -reg [AXIS_PCIE_RC_USER_WIDTH-1:0] s_axis_rc_tuser = 0; -reg s_axis_rc_tvalid = 0; -reg [AXIS_PCIE_DATA_WIDTH-1:0] s_axis_cq_tdata = 0; -reg [AXIS_PCIE_KEEP_WIDTH-1:0] s_axis_cq_tkeep = 0; -reg s_axis_cq_tlast = 0; -reg [AXIS_PCIE_CQ_USER_WIDTH-1:0] s_axis_cq_tuser = 0; -reg s_axis_cq_tvalid = 0; -reg m_axis_cc_tready = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_0 = 0; -reg s_axis_rq_seq_num_valid_0 = 0; -reg [RQ_SEQ_NUM_WIDTH-1:0] s_axis_rq_seq_num_1 = 0; -reg s_axis_rq_seq_num_valid_1 = 0; -reg [3:0] pcie_tfc_nph_av = 0; -reg [3:0] pcie_tfc_npd_av = 0; -reg [2:0] cfg_max_payload = 0; -reg [2:0] cfg_max_read_req = 0; -reg [31:0] cfg_mgmt_read_data = 0; -reg cfg_mgmt_read_write_done = 0; -reg [7:0] cfg_fc_ph = 0; -reg [11:0] cfg_fc_pd = 0; -reg [7:0] cfg_fc_nph = 0; -reg [11:0] cfg_fc_npd = 0; -reg [7:0] cfg_fc_cplh = 0; -reg [11:0] cfg_fc_cpld = 0; -reg [3:0] cfg_interrupt_msi_enable = 0; -reg [11:0] cfg_interrupt_msi_mmenable = 0; -reg cfg_interrupt_msi_mask_update = 0; -reg [31:0] cfg_interrupt_msi_data = 0; -reg cfg_interrupt_msi_sent = 0; -reg cfg_interrupt_msi_fail = 0; -reg qsfp1_tx_clk_1 = 0; -reg qsfp1_tx_rst_1 = 0; -reg qsfp1_rx_clk_1 = 0; -reg qsfp1_rx_rst_1 = 0; -reg [63:0] qsfp1_rxd_1 = 0; -reg [7:0] qsfp1_rxc_1 = 0; -reg qsfp1_tx_clk_2 = 0; -reg qsfp1_tx_rst_2 = 0; -reg qsfp1_rx_clk_2 = 0; -reg qsfp1_rx_rst_2 = 0; -reg [63:0] qsfp1_rxd_2 = 0; -reg [7:0] qsfp1_rxc_2 = 0; -reg qsfp1_tx_clk_3 = 0; -reg qsfp1_tx_rst_3 = 0; -reg qsfp1_rx_clk_3 = 0; -reg qsfp1_rx_rst_3 = 0; -reg [63:0] qsfp1_rxd_3 = 0; -reg [7:0] qsfp1_rxc_3 = 0; -reg qsfp1_tx_clk_4 = 0; -reg qsfp1_tx_rst_4 = 0; -reg qsfp1_rx_clk_4 = 0; -reg qsfp1_rx_rst_4 = 0; -reg [63:0] qsfp1_rxd_4 = 0; -reg [7:0] qsfp1_rxc_4 = 0; -reg qsfp1_modprsl = 1; -reg qsfp1_intl = 1; -reg qsfp2_tx_clk_1 = 0; -reg qsfp2_tx_rst_1 = 0; -reg qsfp2_rx_clk_1 = 0; -reg qsfp2_rx_rst_1 = 0; -reg [63:0] qsfp2_rxd_1 = 0; -reg [7:0] qsfp2_rxc_1 = 0; -reg qsfp2_tx_clk_2 = 0; -reg qsfp2_tx_rst_2 = 0; -reg qsfp2_rx_clk_2 = 0; -reg qsfp2_rx_rst_2 = 0; -reg [63:0] qsfp2_rxd_2 = 0; -reg [7:0] qsfp2_rxc_2 = 0; -reg qsfp2_tx_clk_3 = 0; -reg qsfp2_tx_rst_3 = 0; -reg qsfp2_rx_clk_3 = 0; -reg qsfp2_rx_rst_3 = 0; -reg [63:0] qsfp2_rxd_3 = 0; -reg [7:0] qsfp2_rxc_3 = 0; -reg qsfp2_tx_clk_4 = 0; -reg qsfp2_tx_rst_4 = 0; -reg qsfp2_rx_clk_4 = 0; -reg qsfp2_rx_rst_4 = 0; -reg [63:0] qsfp2_rxd_4 = 0; -reg [7:0] qsfp2_rxc_4 = 0; -reg qsfp2_modprsl = 1; -reg qsfp2_intl = 1; -reg [3:0] qspi_0_dq_i = 0; -reg [3:0] qspi_1_dq_i = 0; - -// Outputs -wire [7:0] led; -wire i2c_scl_o; -wire i2c_scl_t; -wire i2c_sda_o; -wire i2c_sda_t; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_rq_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_rq_tkeep; -wire m_axis_rq_tlast; -wire [AXIS_PCIE_RQ_USER_WIDTH-1:0] m_axis_rq_tuser; -wire m_axis_rq_tvalid; -wire s_axis_rc_tready; -wire s_axis_cq_tready; -wire [AXIS_PCIE_DATA_WIDTH-1:0] m_axis_cc_tdata; -wire [AXIS_PCIE_KEEP_WIDTH-1:0] m_axis_cc_tkeep; -wire m_axis_cc_tlast; -wire [AXIS_PCIE_CC_USER_WIDTH-1:0] m_axis_cc_tuser; -wire m_axis_cc_tvalid; -wire [9:0] cfg_mgmt_addr; -wire [7:0] cfg_mgmt_function_number; -wire cfg_mgmt_write; -wire [31:0] cfg_mgmt_write_data; -wire [3:0] cfg_mgmt_byte_enable; -wire cfg_mgmt_read; -wire [2:0] cfg_fc_sel; -wire [3:0] cfg_interrupt_msi_select; -wire [31:0] cfg_interrupt_msi_int; -wire [31:0] cfg_interrupt_msi_pending_status; -wire cfg_interrupt_msi_pending_status_data_enable; -wire [3:0] cfg_interrupt_msi_pending_status_function_num; -wire [2:0] cfg_interrupt_msi_attr; -wire cfg_interrupt_msi_tph_present; -wire [1:0] cfg_interrupt_msi_tph_type; -wire [8:0] cfg_interrupt_msi_tph_st_tag; -wire [3:0] cfg_interrupt_msi_function_number; -wire status_error_cor; -wire status_error_uncor; -wire [63:0] qsfp1_txd_1; -wire [7:0] qsfp1_txc_1; -wire [63:0] qsfp1_txd_2; -wire [7:0] qsfp1_txc_2; -wire [63:0] qsfp1_txd_3; -wire [7:0] qsfp1_txc_3; -wire [63:0] qsfp1_txd_4; -wire [7:0] qsfp1_txc_4; -wire qsfp1_modsell; -wire qsfp1_resetl; -wire qsfp1_lpmode; -wire [63:0] qsfp2_txd_1; -wire [7:0] qsfp2_txc_1; -wire [63:0] qsfp2_txd_2; -wire [7:0] qsfp2_txc_2; -wire [63:0] qsfp2_txd_3; -wire [7:0] qsfp2_txc_3; -wire [63:0] qsfp2_txd_4; -wire [7:0] qsfp2_txc_4; -wire qsfp2_modsell; -wire qsfp2_resetl; -wire qsfp2_lpmode; -wire fpga_boot; -wire qspi_clk; -wire [3:0] qspi_0_dq_o; -wire [3:0] qspi_0_dq_oe; -wire qspi_0_cs; -wire [3:0] qspi_1_dq_o; -wire [3:0] qspi_1_dq_oe; -wire qspi_1_cs; - -initial begin - // myhdl integration - $from_myhdl( - clk_250mhz, - rst_250mhz, - current_test, - btnu, - btnl, - btnd, - btnr, - btnc, - sw, - i2c_scl_i, - i2c_sda_i, - m_axis_rq_tready, - s_axis_rc_tdata, - s_axis_rc_tkeep, - s_axis_rc_tlast, - s_axis_rc_tuser, - s_axis_rc_tvalid, - s_axis_cq_tdata, - s_axis_cq_tkeep, - s_axis_cq_tlast, - s_axis_cq_tuser, - s_axis_cq_tvalid, - m_axis_cc_tready, - s_axis_rq_seq_num_0, - s_axis_rq_seq_num_valid_0, - s_axis_rq_seq_num_1, - s_axis_rq_seq_num_valid_1, - pcie_tfc_nph_av, - pcie_tfc_npd_av, - cfg_max_payload, - cfg_max_read_req, - cfg_mgmt_read_data, - cfg_mgmt_read_write_done, - cfg_fc_ph, - cfg_fc_pd, - cfg_fc_nph, - cfg_fc_npd, - cfg_fc_cplh, - cfg_fc_cpld, - cfg_interrupt_msi_enable, - cfg_interrupt_msi_mmenable, - cfg_interrupt_msi_mask_update, - cfg_interrupt_msi_data, - cfg_interrupt_msi_sent, - cfg_interrupt_msi_fail, - qsfp1_tx_clk_1, - qsfp1_tx_rst_1, - qsfp1_rx_clk_1, - qsfp1_rx_rst_1, - qsfp1_rxd_1, - qsfp1_rxc_1, - qsfp1_tx_clk_2, - qsfp1_tx_rst_2, - qsfp1_rx_clk_2, - qsfp1_rx_rst_2, - qsfp1_rxd_2, - qsfp1_rxc_2, - qsfp1_tx_clk_3, - qsfp1_tx_rst_3, - qsfp1_rx_clk_3, - qsfp1_rx_rst_3, - qsfp1_rxd_3, - qsfp1_rxc_3, - qsfp1_tx_clk_4, - qsfp1_tx_rst_4, - qsfp1_rx_clk_4, - qsfp1_rx_rst_4, - qsfp1_rxd_4, - qsfp1_rxc_4, - qsfp1_modprsl, - qsfp1_intl, - qsfp2_tx_clk_1, - qsfp2_tx_rst_1, - qsfp2_rx_clk_1, - qsfp2_rx_rst_1, - qsfp2_rxd_1, - qsfp2_rxc_1, - qsfp2_tx_clk_2, - qsfp2_tx_rst_2, - qsfp2_rx_clk_2, - qsfp2_rx_rst_2, - qsfp2_rxd_2, - qsfp2_rxc_2, - qsfp2_tx_clk_3, - qsfp2_tx_rst_3, - qsfp2_rx_clk_3, - qsfp2_rx_rst_3, - qsfp2_rxd_3, - qsfp2_rxc_3, - qsfp2_tx_clk_4, - qsfp2_tx_rst_4, - qsfp2_rx_clk_4, - qsfp2_rx_rst_4, - qsfp2_rxd_4, - qsfp2_rxc_4, - qsfp2_modprsl, - qsfp2_intl, - qspi_0_dq_i, - qspi_1_dq_i - ); - $to_myhdl( - led, - i2c_scl_o, - i2c_scl_t, - i2c_sda_o, - i2c_sda_t, - m_axis_rq_tdata, - m_axis_rq_tkeep, - m_axis_rq_tlast, - m_axis_rq_tuser, - m_axis_rq_tvalid, - s_axis_rc_tready, - s_axis_cq_tready, - m_axis_cc_tdata, - m_axis_cc_tkeep, - m_axis_cc_tlast, - m_axis_cc_tuser, - m_axis_cc_tvalid, - cfg_mgmt_addr, - cfg_mgmt_function_number, - cfg_mgmt_write, - cfg_mgmt_write_data, - cfg_mgmt_byte_enable, - cfg_mgmt_read, - cfg_fc_sel, - cfg_interrupt_msi_select, - cfg_interrupt_msi_int, - cfg_interrupt_msi_pending_status, - cfg_interrupt_msi_pending_status_data_enable, - cfg_interrupt_msi_pending_status_function_num, - cfg_interrupt_msi_attr, - cfg_interrupt_msi_tph_present, - cfg_interrupt_msi_tph_type, - cfg_interrupt_msi_tph_st_tag, - cfg_interrupt_msi_function_number, - status_error_cor, - status_error_uncor, - qsfp1_txd_1, - qsfp1_txc_1, - qsfp1_txd_2, - qsfp1_txc_2, - qsfp1_txd_3, - qsfp1_txc_3, - qsfp1_txd_4, - qsfp1_txc_4, - qsfp1_modsell, - qsfp1_resetl, - qsfp1_lpmode, - qsfp2_txd_1, - qsfp2_txc_1, - qsfp2_txd_2, - qsfp2_txc_2, - qsfp2_txd_3, - qsfp2_txc_3, - qsfp2_txd_4, - qsfp2_txc_4, - qsfp2_modsell, - qsfp2_resetl, - qsfp2_lpmode, - fpga_boot, - qspi_clk, - qspi_0_dq_o, - qspi_0_dq_oe, - qspi_0_cs, - qspi_1_dq_o, - qspi_1_dq_oe, - qspi_1_cs - ); - - // dump file - $dumpfile("test_fpga_core.lxt"); - $dumpvars(0, test_fpga_core); -end - -fpga_core #( - .AXIS_PCIE_DATA_WIDTH(AXIS_PCIE_DATA_WIDTH), - .AXIS_PCIE_KEEP_WIDTH(AXIS_PCIE_KEEP_WIDTH), - .AXIS_PCIE_RC_USER_WIDTH(AXIS_PCIE_RC_USER_WIDTH), - .AXIS_PCIE_RQ_USER_WIDTH(AXIS_PCIE_RQ_USER_WIDTH), - .AXIS_PCIE_CQ_USER_WIDTH(AXIS_PCIE_CQ_USER_WIDTH), - .AXIS_PCIE_CC_USER_WIDTH(AXIS_PCIE_CC_USER_WIDTH), - .RQ_SEQ_NUM_WIDTH(RQ_SEQ_NUM_WIDTH), - .BAR0_APERTURE(BAR0_APERTURE) -) -UUT ( - .clk_250mhz(clk_250mhz), - .rst_250mhz(rst_250mhz), - .btnu(btnu), - .btnl(btnl), - .btnd(btnd), - .btnr(btnr), - .btnc(btnc), - .sw(sw), - .led(led), - .i2c_scl_i(i2c_scl_i), - .i2c_scl_o(i2c_scl_o), - .i2c_scl_t(i2c_scl_t), - .i2c_sda_i(i2c_sda_i), - .i2c_sda_o(i2c_sda_o), - .i2c_sda_t(i2c_sda_t), - .m_axis_rq_tdata(m_axis_rq_tdata), - .m_axis_rq_tkeep(m_axis_rq_tkeep), - .m_axis_rq_tlast(m_axis_rq_tlast), - .m_axis_rq_tready(m_axis_rq_tready), - .m_axis_rq_tuser(m_axis_rq_tuser), - .m_axis_rq_tvalid(m_axis_rq_tvalid), - .s_axis_rc_tdata(s_axis_rc_tdata), - .s_axis_rc_tkeep(s_axis_rc_tkeep), - .s_axis_rc_tlast(s_axis_rc_tlast), - .s_axis_rc_tready(s_axis_rc_tready), - .s_axis_rc_tuser(s_axis_rc_tuser), - .s_axis_rc_tvalid(s_axis_rc_tvalid), - .s_axis_cq_tdata(s_axis_cq_tdata), - .s_axis_cq_tkeep(s_axis_cq_tkeep), - .s_axis_cq_tlast(s_axis_cq_tlast), - .s_axis_cq_tready(s_axis_cq_tready), - .s_axis_cq_tuser(s_axis_cq_tuser), - .s_axis_cq_tvalid(s_axis_cq_tvalid), - .m_axis_cc_tdata(m_axis_cc_tdata), - .m_axis_cc_tkeep(m_axis_cc_tkeep), - .m_axis_cc_tlast(m_axis_cc_tlast), - .m_axis_cc_tready(m_axis_cc_tready), - .m_axis_cc_tuser(m_axis_cc_tuser), - .m_axis_cc_tvalid(m_axis_cc_tvalid), - .s_axis_rq_seq_num_0(s_axis_rq_seq_num_0), - .s_axis_rq_seq_num_valid_0(s_axis_rq_seq_num_valid_0), - .s_axis_rq_seq_num_1(s_axis_rq_seq_num_1), - .s_axis_rq_seq_num_valid_1(s_axis_rq_seq_num_valid_1), - .pcie_tfc_nph_av(pcie_tfc_nph_av), - .pcie_tfc_npd_av(pcie_tfc_npd_av), - .cfg_max_payload(cfg_max_payload), - .cfg_max_read_req(cfg_max_read_req), - .cfg_mgmt_addr(cfg_mgmt_addr), - .cfg_mgmt_function_number(cfg_mgmt_function_number), - .cfg_mgmt_write(cfg_mgmt_write), - .cfg_mgmt_write_data(cfg_mgmt_write_data), - .cfg_mgmt_byte_enable(cfg_mgmt_byte_enable), - .cfg_mgmt_read(cfg_mgmt_read), - .cfg_mgmt_read_data(cfg_mgmt_read_data), - .cfg_mgmt_read_write_done(cfg_mgmt_read_write_done), - .cfg_fc_ph(cfg_fc_ph), - .cfg_fc_pd(cfg_fc_pd), - .cfg_fc_nph(cfg_fc_nph), - .cfg_fc_npd(cfg_fc_npd), - .cfg_fc_cplh(cfg_fc_cplh), - .cfg_fc_cpld(cfg_fc_cpld), - .cfg_fc_sel(cfg_fc_sel), - .cfg_interrupt_msi_enable(cfg_interrupt_msi_enable), - .cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable), - .cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update), - .cfg_interrupt_msi_data(cfg_interrupt_msi_data), - .cfg_interrupt_msi_select(cfg_interrupt_msi_select), - .cfg_interrupt_msi_int(cfg_interrupt_msi_int), - .cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status), - .cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable), - .cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num), - .cfg_interrupt_msi_sent(cfg_interrupt_msi_sent), - .cfg_interrupt_msi_fail(cfg_interrupt_msi_fail), - .cfg_interrupt_msi_attr(cfg_interrupt_msi_attr), - .cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present), - .cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type), - .cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag), - .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number), - .status_error_cor(status_error_cor), - .status_error_uncor(status_error_uncor), - .qsfp1_tx_clk_1(qsfp1_tx_clk_1), - .qsfp1_tx_rst_1(qsfp1_tx_rst_1), - .qsfp1_txd_1(qsfp1_txd_1), - .qsfp1_txc_1(qsfp1_txc_1), - .qsfp1_rx_clk_1(qsfp1_rx_clk_1), - .qsfp1_rx_rst_1(qsfp1_rx_rst_1), - .qsfp1_rxd_1(qsfp1_rxd_1), - .qsfp1_rxc_1(qsfp1_rxc_1), - .qsfp1_tx_clk_2(qsfp1_tx_clk_2), - .qsfp1_tx_rst_2(qsfp1_tx_rst_2), - .qsfp1_txd_2(qsfp1_txd_2), - .qsfp1_txc_2(qsfp1_txc_2), - .qsfp1_rx_clk_2(qsfp1_rx_clk_2), - .qsfp1_rx_rst_2(qsfp1_rx_rst_2), - .qsfp1_rxd_2(qsfp1_rxd_2), - .qsfp1_rxc_2(qsfp1_rxc_2), - .qsfp1_tx_clk_3(qsfp1_tx_clk_3), - .qsfp1_tx_rst_3(qsfp1_tx_rst_3), - .qsfp1_txd_3(qsfp1_txd_3), - .qsfp1_txc_3(qsfp1_txc_3), - .qsfp1_rx_clk_3(qsfp1_rx_clk_3), - .qsfp1_rx_rst_3(qsfp1_rx_rst_3), - .qsfp1_rxd_3(qsfp1_rxd_3), - .qsfp1_rxc_3(qsfp1_rxc_3), - .qsfp1_tx_clk_4(qsfp1_tx_clk_4), - .qsfp1_tx_rst_4(qsfp1_tx_rst_4), - .qsfp1_txd_4(qsfp1_txd_4), - .qsfp1_txc_4(qsfp1_txc_4), - .qsfp1_rx_clk_4(qsfp1_rx_clk_4), - .qsfp1_rx_rst_4(qsfp1_rx_rst_4), - .qsfp1_rxd_4(qsfp1_rxd_4), - .qsfp1_rxc_4(qsfp1_rxc_4), - .qsfp1_modprsl(qsfp1_modprsl_int), - .qsfp1_modsell(qsfp1_modsell), - .qsfp1_resetl(qsfp1_resetl), - .qsfp1_intl(qsfp1_intl_int), - .qsfp1_lpmode(qsfp1_lpmode_int), - .qsfp2_tx_clk_1(qsfp2_tx_clk_1), - .qsfp2_tx_rst_1(qsfp2_tx_rst_1), - .qsfp2_txd_1(qsfp2_txd_1), - .qsfp2_txc_1(qsfp2_txc_1), - .qsfp2_rx_clk_1(qsfp2_rx_clk_1), - .qsfp2_rx_rst_1(qsfp2_rx_rst_1), - .qsfp2_rxd_1(qsfp2_rxd_1), - .qsfp2_rxc_1(qsfp2_rxc_1), - .qsfp2_tx_clk_2(qsfp2_tx_clk_2), - .qsfp2_tx_rst_2(qsfp2_tx_rst_2), - .qsfp2_txd_2(qsfp2_txd_2), - .qsfp2_txc_2(qsfp2_txc_2), - .qsfp2_rx_clk_2(qsfp2_rx_clk_2), - .qsfp2_rx_rst_2(qsfp2_rx_rst_2), - .qsfp2_rxd_2(qsfp2_rxd_2), - .qsfp2_rxc_2(qsfp2_rxc_2), - .qsfp2_tx_clk_3(qsfp2_tx_clk_3), - .qsfp2_tx_rst_3(qsfp2_tx_rst_3), - .qsfp2_txd_3(qsfp2_txd_3), - .qsfp2_txc_3(qsfp2_txc_3), - .qsfp2_rx_clk_3(qsfp2_rx_clk_3), - .qsfp2_rx_rst_3(qsfp2_rx_rst_3), - .qsfp2_rxd_3(qsfp2_rxd_3), - .qsfp2_rxc_3(qsfp2_rxc_3), - .qsfp2_tx_clk_4(qsfp2_tx_clk_4), - .qsfp2_tx_rst_4(qsfp2_tx_rst_4), - .qsfp2_txd_4(qsfp2_txd_4), - .qsfp2_txc_4(qsfp2_txc_4), - .qsfp2_rx_clk_4(qsfp2_rx_clk_4), - .qsfp2_rx_rst_4(qsfp2_rx_rst_4), - .qsfp2_rxd_4(qsfp2_rxd_4), - .qsfp2_rxc_4(qsfp2_rxc_4), - .qsfp2_modprsl(qsfp2_modprsl_int), - .qsfp2_modsell(qsfp2_modsell), - .qsfp2_resetl(qsfp2_resetl), - .qsfp2_intl(qsfp2_intl_int), - .qsfp2_lpmode(qsfp2_lpmode_int), - .fpga_boot(fpga_boot), - .qspi_clk(qspi_clk), - .qspi_0_dq_i(qspi_0_dq_i), - .qspi_0_dq_o(qspi_0_dq_o), - .qspi_0_dq_oe(qspi_0_dq_oe), - .qspi_0_cs(qspi_0_cs), - .qspi_1_dq_i(qspi_1_dq_i), - .qspi_1_dq_o(qspi_1_dq_o), - .qspi_1_dq_oe(qspi_1_dq_oe), - .qspi_1_cs(qspi_1_cs) -); - -endmodule diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/udp_ep.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/udp_ep.py deleted file mode 120000 index 073c5d3c6..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/udp_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/udp_ep.py \ No newline at end of file diff --git a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/xgmii_ep.py b/fpga/mqnic_tdma/VCU118/fpga_10g/tb/xgmii_ep.py deleted file mode 120000 index 63b6d3567..000000000 --- a/fpga/mqnic_tdma/VCU118/fpga_10g/tb/xgmii_ep.py +++ /dev/null @@ -1 +0,0 @@ -../lib/eth/tb/xgmii_ep.py \ No newline at end of file