1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

merged changes in eth

This commit is contained in:
Alex Forencich 2021-02-24 15:03:24 -08:00
commit 365d39990d
446 changed files with 23503 additions and 19231 deletions

View File

@ -0,0 +1,33 @@
name: Regression Tests
on: [push, pull_request]
jobs:
build:
name: Python ${{ matrix.python-version }} (${{ matrix.group }}/10)
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: [3.9]
group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
steps:
- uses: actions/checkout@v1
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install Icarus Verilog
run: |
sudo apt install -y --no-install-recommends iverilog
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install tox tox-gh-actions
- name: Test with tox
run: tox -- --splits 10 --group ${{ matrix.group }}

View File

@ -0,0 +1,278 @@
[
[
"example/ADM_PCIE_9V3/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
3.350716139015276
],
[
"example/ADM_PCIE_9V3/fpga_25g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
3.2391385310329497
],
[
"example/ATLYS/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.789005930942949
],
[
"example/AU200/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
3.0402835980057716
],
[
"example/AU250/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
3.017408686049748
],
[
"example/AU280/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
3.0139305790071376
],
[
"example/AU50/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.3072252210695297
],
[
"example/Arty/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
3.0037750290939584
],
[
"example/C10LP/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.011752209975384
],
[
"example/DE2-115/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.67545863596024
],
[
"example/DE5-Net/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.0110695579787716
],
[
"example/ExaNIC_X10/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.208118299022317
],
[
"example/ExaNIC_X25/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.44376450200798
],
[
"example/HXT100G/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
4.402108575042803
],
[
"example/HXT100G/fpga_cxpt16/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.9904032690101303
],
[
"example/KC705/fpga_gmii/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.6908840039977804
],
[
"example/ML605/fpga_gmii/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.7916936919791624
],
[
"example/ML605/fpga_rgmii/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.006524741067551
],
[
"example/ML605/fpga_sgmii/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.8797070909640752
],
[
"example/NetFPGA_SUME/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.31391696294304
],
[
"example/NexysVideo/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.2516418960294686
],
[
"example/VCU108/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
7.106702796998434
],
[
"example/VCU108/fpga_1g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.9049406169797294
],
[
"example/VCU108/fpga_25g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
10.083096705027856
],
[
"example/VCU118/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
10.943006486049853
],
[
"example/VCU118/fpga_1g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.7586704220157117
],
[
"example/VCU118/fpga_25g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
14.224416063982062
],
[
"example/VCU1525/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.535578682029154
],
[
"example/ZCU102/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.0530272759497166
],
[
"example/ZCU106/fpga/tb/fpga_core/test_fpga_core.py::test_fpga_core",
1.7465879460214637
],
[
"example/fb2CG/fpga_10g/tb/fpga_core/test_fpga_core.py::test_fpga_core",
2.5806369229685515
],
[
"tb/axis_gmii_rx/test_axis_gmii_rx.py::test_axis_gmii_rx",
56.64747221703874
],
[
"tb/axis_gmii_tx/test_axis_gmii_tx.py::test_axis_gmii_tx",
30.442475777002983
],
[
"tb/axis_xgmii_rx_32/test_axis_xgmii_rx_32.py::test_axis_xgmii_rx_32",
7.886729437974282
],
[
"tb/axis_xgmii_rx_64/test_axis_xgmii_rx_64.py::test_axis_xgmii_rx_64",
6.457998651952948
],
[
"tb/axis_xgmii_tx_32/test_axis_xgmii_tx_32.py::test_axis_xgmii_tx_32[0]",
8.96249749296112
],
[
"tb/axis_xgmii_tx_32/test_axis_xgmii_tx_32.py::test_axis_xgmii_tx_32[1]",
9.381603470945265
],
[
"tb/axis_xgmii_tx_64/test_axis_xgmii_tx_64.py::test_axis_xgmii_tx_64[0]",
11.737518855952658
],
[
"tb/axis_xgmii_tx_64/test_axis_xgmii_tx_64.py::test_axis_xgmii_tx_64[1]",
11.806113563012332
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[128]",
8.863175940059591
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[16]",
34.96355901501374
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[256]",
7.622430203016847
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[32]",
19.80590023502009
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[512]",
8.202056872076355
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[64]",
12.095227073063143
],
[
"tb/eth_axis_rx/test_eth_axis_rx.py::test_eth_axis_rx[8]",
62.279668925039005
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[128]",
8.613341382006183
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[16]",
33.45408461202169
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[256]",
7.692996468977071
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[32]",
19.495025975920726
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[512]",
8.79245255002752
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[64]",
12.404317863984033
],
[
"tb/eth_axis_tx/test_eth_axis_tx.py::test_eth_axis_tx[8]",
60.92513044789666
],
[
"tb/eth_mac_10g/test_eth_mac_10g.py::test_eth_mac_10g[32-0]",
21.700028119026683
],
[
"tb/eth_mac_10g/test_eth_mac_10g.py::test_eth_mac_10g[32-1]",
21.89258627599338
],
[
"tb/eth_mac_10g/test_eth_mac_10g.py::test_eth_mac_10g[64-0]",
23.73091037006816
],
[
"tb/eth_mac_10g/test_eth_mac_10g.py::test_eth_mac_10g[64-1]",
23.693007047928404
],
[
"tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py::test_eth_mac_10g_fifo[32-0]",
27.49537598504685
],
[
"tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py::test_eth_mac_10g_fifo[32-1]",
26.939815686957445
],
[
"tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py::test_eth_mac_10g_fifo[64-0]",
26.623203694005497
],
[
"tb/eth_mac_10g_fifo/test_eth_mac_10g_fifo.py::test_eth_mac_10g_fifo[64-1]",
26.543768665986136
],
[
"tb/eth_mac_1g/test_eth_mac_1g.py::test_eth_mac_1g",
88.82490837806836
],
[
"tb/eth_mac_1g_fifo/test_eth_mac_1g_fifo.py::test_eth_mac_1g_fifo",
114.0729509309167
],
[
"tb/eth_mac_1g_gmii/test_eth_mac_1g_gmii.py::test_eth_mac_1g_gmii",
189.40125144011108
],
[
"tb/eth_mac_1g_gmii_fifo/test_eth_mac_1g_gmii_fifo.py::test_eth_mac_1g_gmii_fifo",
494.74671391100856
],
[
"tb/eth_mac_1g_rgmii/test_eth_mac_1g_rgmii.py::test_eth_mac_1g_rgmii",
511.1402762809885
],
[
"tb/eth_mac_1g_rgmii_fifo/test_eth_mac_1g_rgmii_fifo.py::test_eth_mac_1g_rgmii_fifo",
711.3097275471082
],
[
"tb/eth_mac_mii/test_eth_mac_mii.py::test_eth_mac_mii",
25.211533757974394
],
[
"tb/eth_mac_mii_fifo/test_eth_mac_mii_fifo.py::test_eth_mac_mii_fifo",
95.03809778194409
]
]

View File

@ -1,15 +0,0 @@
language: python
python:
- "3.6"
before_install:
- export d=`pwd`
- export PYTHON_EXE=`which python`
- sudo apt-get update -qq
- sudo apt-get install -y iverilog
- git clone https://github.com/jandecaluwe/myhdl.git
- cd $d/myhdl && sudo $PYTHON_EXE setup.py install
- cd $d/myhdl/cosimulation/icarus && make && sudo install -m 0755 -D ./myhdl.vpi /usr/lib/x86_64-linux-gnu/ivl/myhdl.vpi
- cd $d
script:
- cd tb && py.test

View File

@ -1 +0,0 @@
README.md

View File

@ -1,5 +1,7 @@
# Verilog Ethernet Components Readme
[![Build Status](https://github.com/alexforencich/verilog-ethernet/workflows/Regression%20Tests/badge.svg?branch=master)](https://github.com/alexforencich/verilog-ethernet/actions/)
For more information and updates: http://alexforencich.com/wiki/en/verilog/ethernet/start
GitHub repository: https://github.com/alexforencich/verilog-ethernet
@ -12,8 +14,8 @@ Ethernet frames as well as IP, UDP, and ARP and the components for
constructing a complete UDP/IP stack. Includes MAC modules for gigabit and
10G/25G, a 10G/25G PCS/PMA PHY module, and a 10G/25G combination MAC/PCS/PMA
module. Includes various PTP related components for implementing systems that
require precise time synchronization. Also includes full MyHDL testbench with
intelligent bus cosimulation endpoints.
require precise time synchronization. Also includes full cocotb testbenches
that utilize [cocotbext-eth](https://github.com/alexforencich/cocotbext-eth).
For IP and ARP support only, use ip_complete (1G) or ip_complete_64 (10G/25G).
@ -569,21 +571,4 @@ bad frame
## Testing
Running the included testbenches requires MyHDL and Icarus Verilog. Make sure
that myhdl.vpi is installed properly for cosimulation to work correctly. The
testbenches can be run with a Python test runner like nose or py.test, or the
individual test scripts can be run with python directly.
### Testbench Files
tb/arp_ep.py : MyHDL ARP frame endpoints
tb/axis_ep.py : MyHDL AXI Stream endpoints
tb/baser_serdes.py : MyHDL 10GBASE-R SERDES endpoints
tb/eth_ep.py : MyHDL Ethernet frame endpoints
tb/gmii_ep.py : MyHDL GMII endpoints
tb/ip_ep.py : MyHDL IP frame endpoints
tb/mii_ep.py : MyHDL MII endpoints
tb/ptp.py : MyHDL PTP clock model
tb/rgmii_ep.py : MyHDL RGMII endpoints
tb/udp_ep.py : MyHDL UDP frame endpoints
tb/xgmii_ep.py : MyHDL XGMII endpoints
Running the included testbenches requires [cocotb](https://github.com/cocotb/cocotb), [cocotbext-axi](https://github.com/alexforencich/cocotbext-axi), [cocotbext-eth](https://github.com/alexforencich/cocotbext-eth), and [Icarus Verilog](http://iverilog.icarus.com/). The testbenches can be run with pytest directly (requires [cocotb-test](https://github.com/themperek/cocotb-test)), pytest via tox, or via cocotb makefiles.

View File

@ -24,10 +24,16 @@ set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}]
set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}]
set_false_path -to [get_ports {user_led_g[*] user_led_r front_led[*]}]
set_output_delay 0 [get_ports {user_led_g[*] user_led_r front_led[*]}]
# Switches
set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}]
set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
set_false_path -from [get_ports {user_sw[*]}]
set_input_delay 0 [get_ports {user_sw[*]}]
# GPIO
#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]]
#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]]
@ -35,124 +41,144 @@ set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]]
# QSFP28 Interfaces
set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ?
#set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l]
set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p]
set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ?
#set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l]
set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p]
set_property -dict {LOC B29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_reset_l]
set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_sda]
set_property -dict {LOC B29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_reset_l]
set_property -dict {LOC C29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_sda]
set_false_path -to [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_output_delay 0 [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_false_path -from [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
set_input_delay 0 [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
#set_false_path -to [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_output_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_false_path -from [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_input_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
# I2C interface
#set_property -dict {LOC AT25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
#set_property -dict {LOC AT26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
#set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_wp]
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
# PCIe Interface
#set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE3_CHANNEL_X1Y15 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE3_CHANNEL_X1Y15 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE3_CHANNEL_X1Y15 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE3_CHANNEL_X1Y15 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE3_CHANNEL_X1Y14 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE3_CHANNEL_X1Y14 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE3_CHANNEL_X1Y14 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE3_CHANNEL_X1Y14 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE3_CHANNEL_X1Y13 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE3_CHANNEL_X1Y13 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE3_CHANNEL_X1Y13 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE3_CHANNEL_X1Y13 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE3_CHANNEL_X1Y12 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE3_CHANNEL_X1Y12 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE3_CHANNEL_X1Y12 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE3_CHANNEL_X1Y12 / GTYE3_COMMON_X1Y3
#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE3_CHANNEL_X1Y11 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE3_CHANNEL_X1Y11 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE3_CHANNEL_X1Y11 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE3_CHANNEL_X1Y11 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE3_CHANNEL_X1Y10 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE3_CHANNEL_X1Y10 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE3_CHANNEL_X1Y10 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE3_CHANNEL_X1Y10 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE3_CHANNEL_X1Y9 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE3_CHANNEL_X1Y9 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE3_CHANNEL_X1Y9 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE3_CHANNEL_X1Y9 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE3_CHANNEL_X1Y8 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE3_CHANNEL_X1Y8 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE3_CHANNEL_X1Y8 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE3_CHANNEL_X1Y8 / GTYE3_COMMON_X1Y2
#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE3_CHANNEL_X1Y7 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE3_CHANNEL_X1Y7 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE3_CHANNEL_X1Y7 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE3_CHANNEL_X1Y7 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE3_CHANNEL_X1Y6 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE3_CHANNEL_X1Y6 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE3_CHANNEL_X1Y6 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE3_CHANNEL_X1Y6 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE3_CHANNEL_X1Y5 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE3_CHANNEL_X1Y5 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE3_CHANNEL_X1Y5 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE3_CHANNEL_X1Y5 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE3_CHANNEL_X1Y4 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE3_CHANNEL_X1Y4 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE3_CHANNEL_X1Y4 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE3_CHANNEL_X1Y4 / GTYE3_COMMON_X1Y1
#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE3_CHANNEL_X1Y3 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE3_CHANNEL_X1Y3 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE3_CHANNEL_X1Y3 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE3_CHANNEL_X1Y3 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE3_CHANNEL_X1Y2 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE3_CHANNEL_X1Y2 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE3_CHANNEL_X1Y2 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE3_CHANNEL_X1Y2 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE3_CHANNEL_X1Y1 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE3_CHANNEL_X1Y1 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE3_CHANNEL_X1Y1 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE3_CHANNEL_X1Y1 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE3_CHANNEL_X1Y0 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE3_CHANNEL_X1Y0 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE3_CHANNEL_X1Y0 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE3_CHANNEL_X1Y0 / GTYE3_COMMON_X1Y0
#set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226
#set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226
#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224
@ -164,13 +190,17 @@ set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports
#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
#set_false_path -from [get_ports {perst_0}]
#set_input_delay 0 [get_ports {perst_0}]
# QSPI flash
#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_clk}]
#set_property -dict {LOC AB8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[0]}]
#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[1]}]
#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[2]}]
#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[3]}]
#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[0]}]
#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[1]}]
#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[2]}]
#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[3]}]
#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[0]}]
#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[1]}]
#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[2]}]
#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[3]}]
#set_property -dict {LOC AV30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_cs}]
#set_false_path -to [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_output_delay 0 [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_false_path -from [get_ports {qspi_1_dq}]
#set_input_delay 0 [get_ports {qspi_1_dq}]

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,95 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,289 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
# 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)
async def init(self):
self.dut.rst.setimmediatevalue(0)
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)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
self.dut.qsfp_0_rx_rst_0 <= 1
self.dut.qsfp_0_tx_rst_0 <= 1
self.dut.qsfp_0_rx_rst_1 <= 1
self.dut.qsfp_0_tx_rst_1 <= 1
self.dut.qsfp_0_rx_rst_2 <= 1
self.dut.qsfp_0_tx_rst_2 <= 1
self.dut.qsfp_0_rx_rst_3 <= 1
self.dut.qsfp_0_tx_rst_3 <= 1
self.dut.qsfp_1_rx_rst_0 <= 1
self.dut.qsfp_1_tx_rst_0 <= 1
self.dut.qsfp_1_rx_rst_1 <= 1
self.dut.qsfp_1_tx_rst_1 <= 1
self.dut.qsfp_1_rx_rst_2 <= 1
self.dut.qsfp_1_tx_rst_2 <= 1
self.dut.qsfp_1_rx_rst_3 <= 1
self.dut.qsfp_1_tx_rst_3 <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
self.dut.qsfp_0_rx_rst_0 <= 0
self.dut.qsfp_0_tx_rst_0 <= 0
self.dut.qsfp_0_rx_rst_1 <= 0
self.dut.qsfp_0_tx_rst_1 <= 0
self.dut.qsfp_0_rx_rst_2 <= 0
self.dut.qsfp_0_tx_rst_2 <= 0
self.dut.qsfp_0_rx_rst_3 <= 0
self.dut.qsfp_0_tx_rst_3 <= 0
self.dut.qsfp_1_rx_rst_0 <= 0
self.dut.qsfp_1_tx_rst_0 <= 0
self.dut.qsfp_1_rx_rst_1 <= 0
self.dut.qsfp_1_tx_rst_1 <= 0
self.dut.qsfp_1_rx_rst_2 <= 0
self.dut.qsfp_1_tx_rst_2 <= 0
self.dut.qsfp_1_rx_rst_3 <= 0
self.dut.qsfp_1_tx_rst_3 <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp_0_0_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp_0_0_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp_0_0_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp_0_0_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,463 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import xgmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
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/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete_64.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v")
srcs.append("../lib/eth/rtl/udp_64.v")
srcs.append("../lib/eth/rtl/udp_ip_rx_64.v")
srcs.append("../lib/eth/rtl/udp_ip_tx_64.v")
srcs.append("../lib/eth/rtl/ip_complete_64.v")
srcs.append("../lib/eth/rtl/ip_64.v")
srcs.append("../lib/eth/rtl/ip_eth_rx_64.v")
srcs.append("../lib/eth/rtl/ip_eth_tx_64.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
user_sw = Signal(intbv(0)[2:])
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_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:])
# Outputs
user_led_g = Signal(intbv(0)[2:])
user_led_r = Signal(bool(0))
front_led = Signal(intbv(0)[2:])
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_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:])
# 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')
# 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,
user_led_g=user_led_g,
user_led_r=user_led_r,
front_led=front_led,
user_sw=user_sw,
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_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
)
@always(delay(4))
def clkgen():
clk.next = not clk
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
@instance
def check():
yield delay(100)
yield clk.posedge
rst.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_0_tx_rst_0.next = 1
qsfp_0_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
qsfp_1_tx_rst_0.next = 1
qsfp_1_rx_rst_0.next = 1
yield clk.posedge
rst.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_0_tx_rst_0.next = 0
qsfp_0_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
qsfp_1_tx_rst_0.next = 0
qsfp_1_rx_rst_0.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
# testbench stimulus
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while qsfp_0_0_sink.empty():
yield clk.posedge
rx_frame = qsfp_0_0_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while qsfp_0_0_sink.empty():
yield clk.posedge
rx_frame = qsfp_0_0_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert qsfp_0_0_source.empty()
assert qsfp_0_0_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()

View File

@ -1,269 +0,0 @@
/*
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [1:0] user_sw = 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_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;
// Outputs
wire [1:0] user_led_g;
wire user_led_r;
wire [1:0] front_led;
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 [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;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
user_sw,
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_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
);
$to_myhdl(
user_led_g,
user_led_r,
front_led,
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_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
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core
UUT (
.clk(clk),
.rst(rst),
.user_led_g(user_led_g),
.user_led_r(user_led_r),
.front_led(front_led),
.user_sw(user_sw),
.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_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)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/xgmii_ep.py

View File

@ -24,10 +24,16 @@ set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}]
set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}]
set_false_path -to [get_ports {user_led_g[*] user_led_r front_led[*]}]
set_output_delay 0 [get_ports {user_led_g[*] user_led_r front_led[*]}]
# Switches
set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}]
set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
set_false_path -from [get_ports {user_sw[*]}]
set_input_delay 0 [get_ports {user_sw[*]}]
# GPIO
#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]]
#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]]
@ -35,124 +41,144 @@ set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]]
# QSFP28 Interfaces
set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_128 GTYE3_CHANNEL_X0Y16 / GTYE3_COMMON_X0Y4
set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_128 GTYE3_CHANNEL_X0Y17 / GTYE3_COMMON_X0Y4
set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_128 GTYE3_CHANNEL_X0Y18 / GTYE3_COMMON_X0Y4
set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
#set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_128 GTYE3_CHANNEL_X0Y19 / GTYE3_COMMON_X0Y4
set_property -dict {LOC G38 } [get_ports qsfp_0_rx_0_p] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC G39 } [get_ports qsfp_0_rx_0_n] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F35 } [get_ports qsfp_0_tx_0_p] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F36 } [get_ports qsfp_0_tx_0_n] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E38 } [get_ports qsfp_0_rx_1_p] ;# MGTYRXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E39 } [get_ports qsfp_0_rx_1_n] ;# MGTYRXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D35 } [get_ports qsfp_0_tx_1_p] ;# MGTYTXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D36 } [get_ports qsfp_0_tx_1_n] ;# MGTYTXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C38 } [get_ports qsfp_0_rx_2_p] ;# MGTYRXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C39 } [get_ports qsfp_0_rx_2_n] ;# MGTYRXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C33 } [get_ports qsfp_0_tx_2_p] ;# MGTYTXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C34 } [get_ports qsfp_0_tx_2_n] ;# MGTYTXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B36 } [get_ports qsfp_0_rx_3_p] ;# MGTYRXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B37 } [get_ports qsfp_0_rx_3_n] ;# MGTYRXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A33 } [get_ports qsfp_0_tx_3_p] ;# MGTYTXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A34 } [get_ports qsfp_0_tx_3_n] ;# MGTYTXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ?
#set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l]
set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p]
set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_127 GTYE3_CHANNEL_X0Y12 / GTYE3_COMMON_X0Y3
set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_127 GTYE3_CHANNEL_X0Y13 / GTYE3_COMMON_X0Y3
set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_127 GTYE3_CHANNEL_X0Y14 / GTYE3_COMMON_X0Y3
set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
#set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_127 GTYE3_CHANNEL_X0Y15 / GTYE3_COMMON_X0Y3
set_property -dict {LOC R38 } [get_ports qsfp_1_rx_0_p] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC R39 } [get_ports qsfp_1_rx_0_n] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P35 } [get_ports qsfp_1_tx_0_p] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P36 } [get_ports qsfp_1_tx_0_n] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N38 } [get_ports qsfp_1_rx_1_p] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N39 } [get_ports qsfp_1_rx_1_n] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M35 } [get_ports qsfp_1_tx_1_p] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M36 } [get_ports qsfp_1_tx_1_n] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L38 } [get_ports qsfp_1_rx_2_p] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L39 } [get_ports qsfp_1_rx_2_n] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K35 } [get_ports qsfp_1_tx_2_p] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K36 } [get_ports qsfp_1_tx_2_n] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J38 } [get_ports qsfp_1_rx_3_p] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J39 } [get_ports qsfp_1_rx_3_n] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H35 } [get_ports qsfp_1_tx_3_p] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H36 } [get_ports qsfp_1_tx_3_n] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ?
#set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l]
set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p]
set_property -dict {LOC B29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_reset_l]
set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_i2c_sda]
set_property -dict {LOC B29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_reset_l]
set_property -dict {LOC C29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_sda]
set_false_path -to [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_output_delay 0 [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_false_path -from [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
set_input_delay 0 [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
#set_false_path -to [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_output_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_false_path -from [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_input_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
# I2C interface
#set_property -dict {LOC AT25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
#set_property -dict {LOC AT26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
#set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_wp]
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
# PCIe Interface
#set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE3_CHANNEL_X0Y7 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE3_CHANNEL_X0Y6 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE3_CHANNEL_X0Y5 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE3_CHANNEL_X0Y4 / GTYE3_COMMON_X0Y1
#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE3_CHANNEL_X0Y3 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE3_CHANNEL_X0Y2 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE3_CHANNEL_X0Y1 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE3_CHANNEL_X0Y0 / GTYE3_COMMON_X0Y0
#set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
#set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
#set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226
#set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226
#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224
@ -164,13 +190,17 @@ set_property -dict {LOC C29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports
#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
#set_false_path -from [get_ports {perst_0}]
#set_input_delay 0 [get_ports {perst_0}]
# QSPI flash
#set_property -dict {LOC AB10 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi_clk}]
#set_property -dict {LOC AB8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[0]}]
#set_property -dict {LOC AD8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[1]}]
#set_property -dict {LOC Y8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[2]}]
#set_property -dict {LOC AC8 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi0_dq[3]}]
#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[0]}]
#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[1]}]
#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[2]}]
#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 16} [get_ports {qspi1_dq[3]}]
#set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[0]}]
#set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[1]}]
#set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[2]}]
#set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[3]}]
#set_property -dict {LOC AV30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_cs}]
#set_false_path -to [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_output_delay 0 [get_ports {qspi_1_dq[*] qspi_1_cs}]
#set_false_path -from [get_ports {qspi_1_dq}]
#set_input_delay 0 [get_ports {qspi_1_dq}]

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,95 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,289 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 2.56, units="ns").start())
# 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)
async def init(self):
self.dut.rst.setimmediatevalue(0)
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)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
self.dut.qsfp_0_rx_rst_0 <= 1
self.dut.qsfp_0_tx_rst_0 <= 1
self.dut.qsfp_0_rx_rst_1 <= 1
self.dut.qsfp_0_tx_rst_1 <= 1
self.dut.qsfp_0_rx_rst_2 <= 1
self.dut.qsfp_0_tx_rst_2 <= 1
self.dut.qsfp_0_rx_rst_3 <= 1
self.dut.qsfp_0_tx_rst_3 <= 1
self.dut.qsfp_1_rx_rst_0 <= 1
self.dut.qsfp_1_tx_rst_0 <= 1
self.dut.qsfp_1_rx_rst_1 <= 1
self.dut.qsfp_1_tx_rst_1 <= 1
self.dut.qsfp_1_rx_rst_2 <= 1
self.dut.qsfp_1_tx_rst_2 <= 1
self.dut.qsfp_1_rx_rst_3 <= 1
self.dut.qsfp_1_tx_rst_3 <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
self.dut.qsfp_0_rx_rst_0 <= 0
self.dut.qsfp_0_tx_rst_0 <= 0
self.dut.qsfp_0_rx_rst_1 <= 0
self.dut.qsfp_0_tx_rst_1 <= 0
self.dut.qsfp_0_rx_rst_2 <= 0
self.dut.qsfp_0_tx_rst_2 <= 0
self.dut.qsfp_0_rx_rst_3 <= 0
self.dut.qsfp_0_tx_rst_3 <= 0
self.dut.qsfp_1_rx_rst_0 <= 0
self.dut.qsfp_1_tx_rst_0 <= 0
self.dut.qsfp_1_rx_rst_1 <= 0
self.dut.qsfp_1_tx_rst_1 <= 0
self.dut.qsfp_1_rx_rst_2 <= 0
self.dut.qsfp_1_tx_rst_2 <= 0
self.dut.qsfp_1_rx_rst_3 <= 0
self.dut.qsfp_1_tx_rst_3 <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp_0_0_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp_0_0_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp_0_0_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp_0_0_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,463 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import xgmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
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/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete_64.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v")
srcs.append("../lib/eth/rtl/udp_64.v")
srcs.append("../lib/eth/rtl/udp_ip_rx_64.v")
srcs.append("../lib/eth/rtl/udp_ip_tx_64.v")
srcs.append("../lib/eth/rtl/ip_complete_64.v")
srcs.append("../lib/eth/rtl/ip_64.v")
srcs.append("../lib/eth/rtl/ip_eth_rx_64.v")
srcs.append("../lib/eth/rtl/ip_eth_tx_64.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
user_sw = Signal(intbv(0)[2:])
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_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:])
# Outputs
user_led_g = Signal(intbv(0)[2:])
user_led_r = Signal(bool(0))
front_led = Signal(intbv(0)[2:])
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_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:])
# 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')
# 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,
user_led_g=user_led_g,
user_led_r=user_led_r,
front_led=front_led,
user_sw=user_sw,
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_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
)
@always(delay(4))
def clkgen():
clk.next = not clk
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
@instance
def check():
yield delay(100)
yield clk.posedge
rst.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_0_tx_rst_0.next = 1
qsfp_0_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
qsfp_1_tx_rst_0.next = 1
qsfp_1_rx_rst_0.next = 1
yield clk.posedge
rst.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_0_tx_rst_0.next = 0
qsfp_0_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
qsfp_1_tx_rst_0.next = 0
qsfp_1_rx_rst_0.next = 0
yield clk.posedge
yield delay(100)
yield clk.posedge
# testbench stimulus
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while qsfp_0_0_sink.empty():
yield clk.posedge
rx_frame = qsfp_0_0_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
qsfp_0_0_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while qsfp_0_0_sink.empty():
yield clk.posedge
rx_frame = qsfp_0_0_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert qsfp_0_0_source.empty()
assert qsfp_0_0_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()

View File

@ -1,269 +0,0 @@
/*
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [1:0] user_sw = 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_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;
// Outputs
wire [1:0] user_led_g;
wire user_led_r;
wire [1:0] front_led;
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 [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;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
user_sw,
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_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
);
$to_myhdl(
user_led_g,
user_led_r,
front_led,
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_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
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core
UUT (
.clk(clk),
.rst(rst),
.user_led_g(user_led_g),
.user_led_r(user_led_r),
.front_led(front_led),
.user_sw(user_sw),
.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_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)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/xgmii_ep.py

View File

@ -179,7 +179,9 @@ sync_signal_inst (
.out({uart_rxd_int})
);
fpga_core
fpga_core #(
.TARGET("XILINX")
)
core_inst (
/*
* Clock: 125MHz

View File

@ -31,7 +31,7 @@ THE SOFTWARE.
*/
module fpga_core #
(
parameter TARGET = "XILINX"
parameter TARGET = "GENERIC"
)
(
/*

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,101 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../lib/eth/rtl/iddr.v
VERILOG_SOURCES += ../../lib/eth/rtl/oddr.v
VERILOG_SOURCES += ../../lib/eth/rtl/ssio_sdr_in.v
VERILOG_SOURCES += ../../lib/eth/rtl/ssio_sdr_out.v
VERILOG_SOURCES += ../../lib/eth/rtl/gmii_phy_if.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g_gmii_fifo.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g_gmii.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g.v
VERILOG_SOURCES += ../../lib/eth/rtl/axis_gmii_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/axis_gmii_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,216 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import GmiiFrame, GmiiPhy
class TB:
def __init__(self, dut, speed=1000e6):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 8, units="ns").start())
# Ethernet
self.gmii_phy = GmiiPhy(dut.phy_txd, dut.phy_tx_er, dut.phy_tx_en, dut.phy_tx_clk, dut.phy_gtx_clk,
dut.phy_rxd, dut.phy_rx_er, dut.phy_rx_dv, dut.phy_rx_clk, speed=speed)
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.uart_rxd.setimmediatevalue(0)
async def init(self):
self.dut.rst.setimmediatevalue(0)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = GmiiFrame.from_payload(test_pkt.build())
await tb.gmii_phy.rx.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.gmii_phy.tx.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = GmiiFrame.from_payload(resp_pkt.build())
await tb.gmii_phy.rx.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.gmii_phy.tx.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(eth_rtl_dir, "iddr.v"),
os.path.join(eth_rtl_dir, "oddr.v"),
os.path.join(eth_rtl_dir, "ssio_sdr_in.v"),
os.path.join(eth_rtl_dir, "ssio_sdr_out.v"),
os.path.join(eth_rtl_dir, "gmii_phy_if.v"),
os.path.join(eth_rtl_dir, "eth_mac_1g_gmii_fifo.v"),
os.path.join(eth_rtl_dir, "eth_mac_1g_gmii.v"),
os.path.join(eth_rtl_dir, "eth_mac_1g.v"),
os.path.join(eth_rtl_dir, "axis_gmii_rx.v"),
os.path.join(eth_rtl_dir, "axis_gmii_tx.v"),
os.path.join(eth_rtl_dir, "lfsr.v"),
os.path.join(eth_rtl_dir, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen.v"),
os.path.join(eth_rtl_dir, "udp.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx.v"),
os.path.join(eth_rtl_dir, "ip_complete.v"),
os.path.join(eth_rtl_dir, "ip.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/gmii_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,311 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2015-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import gmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("../lib/eth/rtl/iddr.v")
srcs.append("../lib/eth/rtl/oddr.v")
srcs.append("../lib/eth/rtl/ssio_sdr_in.v")
srcs.append("../lib/eth/rtl/ssio_sdr_out.v")
srcs.append("../lib/eth/rtl/gmii_phy_if.v")
srcs.append("../lib/eth/rtl/eth_mac_1g_gmii_fifo.v")
srcs.append("../lib/eth/rtl/eth_mac_1g_gmii.v")
srcs.append("../lib/eth/rtl/eth_mac_1g.v")
srcs.append("../lib/eth/rtl/axis_gmii_rx.v")
srcs.append("../lib/eth/rtl/axis_gmii_tx.v")
srcs.append("../lib/eth/rtl/lfsr.v")
srcs.append("../lib/eth/rtl/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen.v")
srcs.append("../lib/eth/rtl/udp.v")
srcs.append("../lib/eth/rtl/udp_ip_rx.v")
srcs.append("../lib/eth/rtl/udp_ip_tx.v")
srcs.append("../lib/eth/rtl/ip_complete.v")
srcs.append("../lib/eth/rtl/ip.v")
srcs.append("../lib/eth/rtl/ip_eth_rx.v")
srcs.append("../lib/eth/rtl/ip_eth_tx.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
TARGET = "SIM"
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
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:])
phy_rx_clk = Signal(bool(0))
phy_rxd = Signal(intbv(0)[8:])
phy_rx_dv = Signal(bool(0))
phy_rx_er = Signal(bool(0))
phy_tx_clk = Signal(bool(0))
uart_rxd = Signal(bool(0))
# Outputs
led = Signal(intbv(0)[8:])
phy_gtx_clk = Signal(bool(0))
phy_txd = Signal(intbv(0)[8:])
phy_tx_en = Signal(bool(0))
phy_tx_er = Signal(bool(0))
phy_reset_n = Signal(bool(0))
uart_txd = Signal(bool(0))
# sources and sinks
mii_select = Signal(bool(0))
gmii_source = gmii_ep.GMIISource()
gmii_source_logic = gmii_source.create_logic(
phy_rx_clk,
rst,
txd=phy_rxd,
tx_en=phy_rx_dv,
tx_er=phy_rx_er,
mii_select=mii_select,
name='gmii_source'
)
gmii_sink = gmii_ep.GMIISink()
gmii_sink_logic = gmii_sink.create_logic(
phy_tx_clk,
rst,
rxd=phy_txd,
rx_dv=phy_tx_en,
rx_er=phy_tx_er,
mii_select=mii_select,
name='gmii_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,
btnu=btnu,
btnl=btnl,
btnd=btnd,
btnr=btnr,
btnc=btnc,
sw=sw,
led=led,
phy_rx_clk=phy_rx_clk,
phy_rxd=phy_rxd,
phy_rx_dv=phy_rx_dv,
phy_rx_er=phy_rx_er,
phy_gtx_clk=phy_gtx_clk,
phy_tx_clk=phy_tx_clk,
phy_txd=phy_txd,
phy_tx_en=phy_tx_en,
phy_tx_er=phy_tx_er,
phy_reset_n=phy_reset_n,
uart_rxd=uart_rxd,
uart_txd=uart_txd
)
@always(delay(4))
def clkgen():
clk.next = not clk
rx_clk_hp = Signal(int(4))
@instance
def rx_clk_gen():
while True:
yield delay(int(rx_clk_hp))
phy_rx_clk.next = not phy_rx_clk
phy_tx_clk.next = not phy_tx_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 UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while gmii_sink.empty():
yield clk.posedge
rx_frame = gmii_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
gmii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while gmii_sink.empty():
yield clk.posedge
rx_frame = gmii_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert gmii_source.empty()
assert gmii_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()

View File

@ -1,125 +0,0 @@
/*
Copyright (c) 2015-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
parameter TARGET = "SIM";
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg btnu = 0;
reg btnl = 0;
reg btnd = 0;
reg btnr = 0;
reg btnc = 0;
reg [7:0] sw = 0;
reg phy_rx_clk = 0;
reg [7:0] phy_rxd = 0;
reg phy_rx_dv = 0;
reg phy_rx_er = 0;
reg phy_tx_clk = 0;
reg uart_rxd = 0;
// Outputs
wire [7:0] led;
wire phy_gtx_clk;
wire [7:0] phy_txd;
wire phy_tx_en;
wire phy_tx_er;
wire phy_reset_n;
wire uart_txd;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
btnu,
btnl,
btnd,
btnr,
btnc,
sw,
phy_rx_clk,
phy_rxd,
phy_rx_dv,
phy_rx_er,
phy_tx_clk,
uart_rxd
);
$to_myhdl(
led,
phy_gtx_clk,
phy_txd,
phy_tx_en,
phy_tx_er,
phy_reset_n,
uart_txd
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core #(
.TARGET(TARGET)
)
UUT (
.clk(clk),
.rst(rst),
.btnu(btnu),
.btnl(btnl),
.btnd(btnd),
.btnr(btnr),
.btnc(btnc),
.sw(sw),
.led(led),
.phy_rx_clk(phy_rx_clk),
.phy_rxd(phy_rxd),
.phy_rx_dv(phy_rx_dv),
.phy_rx_er(phy_rx_er),
.phy_gtx_clk(phy_gtx_clk),
.phy_tx_clk(phy_tx_clk),
.phy_txd(phy_txd),
.phy_tx_en(phy_tx_en),
.phy_tx_er(phy_tx_er),
.phy_reset_n(phy_reset_n),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -11,9 +11,10 @@ set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.SPI_OPCODE 8'h6B [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_operating_conditions -design_power_budget 160
# System clocks
# 300 MHz (DDR 0)
#set_property -dict {LOC AY37 IOSTANDARD LVDS} [get_ports clk_300mhz_0_p]
@ -45,48 +46,75 @@ set_property -dict {LOC BC21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {
set_property -dict {LOC BB21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
set_property -dict {LOC BA20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Reset button
set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset]
set_false_path -from [get_ports {reset}]
set_input_delay 0 [get_ports {reset}]
# DIP switches
set_property -dict {LOC AN22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
set_property -dict {LOC AM19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
set_property -dict {LOC AL19 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
set_property -dict {LOC AP20 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# UART
set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_txd]
set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_rxd]
set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_txd]
set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_rxd]
#set_false_path -to [get_ports {uart_txd}]
#set_output_delay 0 [get_ports {uart_txd}]
#set_false_path -from [get_ports {uart_rxd}]
#set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AR20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC AM20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC AM21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC AN21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC BB19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BA19 IOSTANDARD LVCMOS12} [get_ports {msp_uart_rxd}]
#set_false_path -to [get_ports {msp_uart_txd}]
#set_output_delay 0 [get_ports {msp_uart_txd}]
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
# QSFP28 Interfaces
set_property -dict {LOC N4 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC N9 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M2 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M7 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L4 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L9 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K2 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K7 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
#set_property -dict {LOC M11 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U14.4 via U43.13
#set_property -dict {LOC M10 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U14.5 via U43.14
set_property -dict {LOC K11 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U9.18
#set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17
set_property -dict {LOC BE16 IOSTANDARD LVCMOS12} [get_ports qsfp0_modsell]
set_property -dict {LOC BE17 IOSTANDARD LVCMOS12} [get_ports qsfp0_resetl]
set_property -dict {LOC BE20 IOSTANDARD LVCMOS12} [get_ports qsfp0_modprsl]
set_property -dict {LOC BE21 IOSTANDARD LVCMOS12} [get_ports qsfp0_intl]
set_property -dict {LOC BD18 IOSTANDARD LVCMOS12} [get_ports qsfp0_lpmode]
set_property -dict {LOC AT22 IOSTANDARD LVCMOS12} [get_ports qsfp0_refclk_reset]
set_property -dict {LOC AT20 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[0]}]
set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}]
set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17
set_property -dict {LOC BE16 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_modsell]
set_property -dict {LOC BE17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_resetl]
set_property -dict {LOC BE20 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_modprsl]
set_property -dict {LOC BE21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_intl]
set_property -dict {LOC BD18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_lpmode]
set_property -dict {LOC AT22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_refclk_reset]
set_property -dict {LOC AT20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[0]}]
set_property -dict {LOC AU22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[1]}]
# 156.25 MHz MGT reference clock (from SI570)
#create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports qsfp0_mgt_refclk_0_p]
@ -97,34 +125,39 @@ set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}]
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
set_false_path -to [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
set_output_delay 0 [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}]
set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}]
set_property -dict {LOC U4 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC U9 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T2 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R4 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R9 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P2 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P7 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC T11 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_230 from U14.4 via U43.15
#set_property -dict {LOC T10 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_230 from U14.5 via U43.16
#set_property -dict {LOC P11 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_230 from U12.18
#set_property -dict {LOC P10 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_230 from U12.17
set_property -dict {LOC AY20 IOSTANDARD LVCMOS12} [get_ports qsfp1_modsell]
set_property -dict {LOC BC18 IOSTANDARD LVCMOS12} [get_ports qsfp1_resetl]
set_property -dict {LOC BC19 IOSTANDARD LVCMOS12} [get_ports qsfp1_modprsl]
set_property -dict {LOC AV21 IOSTANDARD LVCMOS12} [get_ports qsfp1_intl]
set_property -dict {LOC AV22 IOSTANDARD LVCMOS12} [get_ports qsfp1_lpmode]
set_property -dict {LOC AR21 IOSTANDARD LVCMOS12} [get_ports qsfp1_refclk_reset]
set_property -dict {LOC AR22 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[0]}]
set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}]
set_property -dict {LOC AY20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_modsell]
set_property -dict {LOC BC18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_resetl]
set_property -dict {LOC BC19 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_modprsl]
set_property -dict {LOC AV21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_intl]
set_property -dict {LOC AV22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_lpmode]
set_property -dict {LOC AR21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_refclk_reset]
set_property -dict {LOC AR22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[0]}]
set_property -dict {LOC AU20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[1]}]
# 156.25 MHz MGT reference clock (from SI570)
#create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p]
@ -135,11 +168,21 @@ set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}]
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
set_false_path -to [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
set_output_delay 0 [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}]
set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}]
# I2C interface
#set_property -dict {LOC BF19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_mux_reset]
set_property -dict {LOC BF20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_scl]
set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_sda]
set_false_path -to [get_ports {i2c_sda i2c_scl}]
set_output_delay 0 [get_ports {i2c_sda i2c_scl}]
set_false_path -from [get_ports {i2c_sda i2c_scl}]
set_input_delay 0 [get_ports {i2c_sda i2c_scl}]
# PCIe Interface
#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
@ -212,4 +255,5 @@ set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_p]
#set_false_path -from [get_ports {pcie_reset_n}]
#set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@ -70,3 +70,40 @@ program: $(FPGA_TOP).bit
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
%.mcs %.prm: %.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,95 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,289 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
# 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)
async def init(self):
self.dut.rst.setimmediatevalue(0)
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)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
self.dut.qsfp0_rx_rst_1 <= 1
self.dut.qsfp0_tx_rst_1 <= 1
self.dut.qsfp0_rx_rst_2 <= 1
self.dut.qsfp0_tx_rst_2 <= 1
self.dut.qsfp0_rx_rst_3 <= 1
self.dut.qsfp0_tx_rst_3 <= 1
self.dut.qsfp0_rx_rst_4 <= 1
self.dut.qsfp0_tx_rst_4 <= 1
self.dut.qsfp1_rx_rst_1 <= 1
self.dut.qsfp1_tx_rst_1 <= 1
self.dut.qsfp1_rx_rst_2 <= 1
self.dut.qsfp1_tx_rst_2 <= 1
self.dut.qsfp1_rx_rst_3 <= 1
self.dut.qsfp1_tx_rst_3 <= 1
self.dut.qsfp1_rx_rst_4 <= 1
self.dut.qsfp1_tx_rst_4 <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
self.dut.qsfp0_rx_rst_1 <= 0
self.dut.qsfp0_tx_rst_1 <= 0
self.dut.qsfp0_rx_rst_2 <= 0
self.dut.qsfp0_tx_rst_2 <= 0
self.dut.qsfp0_rx_rst_3 <= 0
self.dut.qsfp0_tx_rst_3 <= 0
self.dut.qsfp0_rx_rst_4 <= 0
self.dut.qsfp0_tx_rst_4 <= 0
self.dut.qsfp1_rx_rst_1 <= 0
self.dut.qsfp1_tx_rst_1 <= 0
self.dut.qsfp1_rx_rst_2 <= 0
self.dut.qsfp1_tx_rst_2 <= 0
self.dut.qsfp1_rx_rst_3 <= 0
self.dut.qsfp1_tx_rst_3 <= 0
self.dut.qsfp1_rx_rst_4 <= 0
self.dut.qsfp1_tx_rst_4 <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp0_1_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp0_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp0_1_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp0_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,465 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import xgmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
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/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete_64.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v")
srcs.append("../lib/eth/rtl/udp_64.v")
srcs.append("../lib/eth/rtl/udp_ip_rx_64.v")
srcs.append("../lib/eth/rtl/udp_ip_tx_64.v")
srcs.append("../lib/eth/rtl/ip_complete_64.v")
srcs.append("../lib/eth/rtl/ip_64.v")
srcs.append("../lib/eth/rtl/ip_eth_rx_64.v")
srcs.append("../lib/eth/rtl/ip_eth_tx_64.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_register.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
sw = Signal(intbv(0)[4:])
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:])
uart_txd = Signal(bool(0))
# Outputs
led = Signal(intbv(0)[3:])
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:])
uart_rxd = 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')
# 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,
sw=sw,
led=led,
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,
uart_rxd=uart_rxd,
uart_txd=uart_txd
)
@always(delay(4))
def clkgen():
clk.next = not clk
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
@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
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
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while qsfp0_1_sink.empty():
yield clk.posedge
rx_frame = qsfp0_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while qsfp0_1_sink.empty():
yield clk.posedge
rx_frame = qsfp0_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert qsfp0_1_source.empty()
assert qsfp0_1_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()

View File

@ -1,269 +0,0 @@
/*
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [3:0] sw = 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 uart_txd = 0;
// Outputs
wire [2:0] led;
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 uart_rxd;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
sw,
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,
uart_txd
);
$to_myhdl(
led,
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,
uart_rxd
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core
UUT (
.clk(clk),
.rst(rst),
.sw(sw),
.led(led),
.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),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/xgmii_ep.py

View File

@ -11,9 +11,10 @@ set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.SPI_OPCODE 8'h6B [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_operating_conditions -design_power_budget 160
# System clocks
# 300 MHz (DDR 0)
#set_property -dict {LOC AY37 IOSTANDARD LVDS} [get_ports clk_300mhz_0_p]
@ -45,48 +46,75 @@ set_property -dict {LOC BC21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {
set_property -dict {LOC BB21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
set_property -dict {LOC BA20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Reset button
set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset]
set_false_path -from [get_ports {reset}]
set_input_delay 0 [get_ports {reset}]
# DIP switches
set_property -dict {LOC AN22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
set_property -dict {LOC AM19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
set_property -dict {LOC AL19 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
set_property -dict {LOC AP20 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# UART
set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_txd]
set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_rxd]
set_property -dict {LOC BF18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_txd]
set_property -dict {LOC BB20 IOSTANDARD LVCMOS12} [get_ports uart_rxd]
#set_false_path -to [get_ports {uart_txd}]
#set_output_delay 0 [get_ports {uart_txd}]
#set_false_path -from [get_ports {uart_rxd}]
#set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AR20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC AM20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC AM21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC AN21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC BB19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BA19 IOSTANDARD LVCMOS12} [get_ports {msp_uart_rxd}]
#set_false_path -to [get_ports {msp_uart_txd}]
#set_output_delay 0 [get_ports {msp_uart_txd}]
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
# QSFP28 Interfaces
set_property -dict {LOC N4 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC N3 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC N9 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC N8 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC M2 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC M1 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC M7 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC M6 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC L4 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC L3 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC L9 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC L8 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC K2 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC K1 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC K7 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC K6 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
#set_property -dict {LOC M11 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_231 from U14.4 via U43.13
#set_property -dict {LOC M10 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_231 from U14.5 via U43.14
set_property -dict {LOC K11 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_231 from U9.18
#set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17
set_property -dict {LOC BE16 IOSTANDARD LVCMOS12} [get_ports qsfp0_modsell]
set_property -dict {LOC BE17 IOSTANDARD LVCMOS12} [get_ports qsfp0_resetl]
set_property -dict {LOC BE20 IOSTANDARD LVCMOS12} [get_ports qsfp0_modprsl]
set_property -dict {LOC BE21 IOSTANDARD LVCMOS12} [get_ports qsfp0_intl]
set_property -dict {LOC BD18 IOSTANDARD LVCMOS12} [get_ports qsfp0_lpmode]
set_property -dict {LOC AT22 IOSTANDARD LVCMOS12} [get_ports qsfp0_refclk_reset]
set_property -dict {LOC AT20 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[0]}]
set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}]
set_property -dict {LOC K10 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_231 from U9.17
set_property -dict {LOC BE16 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_modsell]
set_property -dict {LOC BE17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_resetl]
set_property -dict {LOC BE20 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_modprsl]
set_property -dict {LOC BE21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp0_intl]
set_property -dict {LOC BD18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_lpmode]
set_property -dict {LOC AT22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp0_refclk_reset]
set_property -dict {LOC AT20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[0]}]
set_property -dict {LOC AU22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[1]}]
# 156.25 MHz MGT reference clock (from SI570)
#create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports qsfp0_mgt_refclk_0_p]
@ -97,34 +125,39 @@ set_property -dict {LOC AU22 IOSTANDARD LVCMOS12} [get_ports {qsfp0_fs[1]}]
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
set_false_path -to [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
set_output_delay 0 [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode qsfp0_refclk_reset qsfp0_fs[*]}]
set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}]
set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}]
set_property -dict {LOC U4 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
set_property -dict {LOC U3 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
set_property -dict {LOC U9 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
set_property -dict {LOC U8 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y40 / GTYE4_COMMON_X1Y10
set_property -dict {LOC T2 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
set_property -dict {LOC T1 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
set_property -dict {LOC T7 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
set_property -dict {LOC T6 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y41 / GTYE4_COMMON_X1Y10
set_property -dict {LOC R4 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
set_property -dict {LOC R3 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
set_property -dict {LOC R9 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
set_property -dict {LOC R8 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y42 / GTYE4_COMMON_X1Y10
set_property -dict {LOC P2 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
set_property -dict {LOC P1 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
set_property -dict {LOC P7 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
set_property -dict {LOC P6 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y43 / GTYE4_COMMON_X1Y10
#set_property -dict {LOC T11 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_230 from U14.4 via U43.15
#set_property -dict {LOC T10 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_230 from U14.5 via U43.16
#set_property -dict {LOC P11 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_230 from U12.18
#set_property -dict {LOC P10 } [get_ports qsfp1_mgt_refclk_1_n] ;# MGTREFCLK1N_230 from U12.17
set_property -dict {LOC AY20 IOSTANDARD LVCMOS12} [get_ports qsfp1_modsell]
set_property -dict {LOC BC18 IOSTANDARD LVCMOS12} [get_ports qsfp1_resetl]
set_property -dict {LOC BC19 IOSTANDARD LVCMOS12} [get_ports qsfp1_modprsl]
set_property -dict {LOC AV21 IOSTANDARD LVCMOS12} [get_ports qsfp1_intl]
set_property -dict {LOC AV22 IOSTANDARD LVCMOS12} [get_ports qsfp1_lpmode]
set_property -dict {LOC AR21 IOSTANDARD LVCMOS12} [get_ports qsfp1_refclk_reset]
set_property -dict {LOC AR22 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[0]}]
set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}]
set_property -dict {LOC AY20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_modsell]
set_property -dict {LOC BC18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_resetl]
set_property -dict {LOC BC19 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_modprsl]
set_property -dict {LOC AV21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports qsfp1_intl]
set_property -dict {LOC AV22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_lpmode]
set_property -dict {LOC AR21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports qsfp1_refclk_reset]
set_property -dict {LOC AR22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[0]}]
set_property -dict {LOC AU20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[1]}]
# 156.25 MHz MGT reference clock (from SI570)
#create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports qsfp1_mgt_refclk_0_p]
@ -135,11 +168,21 @@ set_property -dict {LOC AU20 IOSTANDARD LVCMOS12} [get_ports {qsfp1_fs[1]}]
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
set_false_path -to [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
set_output_delay 0 [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode qsfp1_refclk_reset qsfp1_fs[*]}]
set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}]
set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}]
# I2C interface
#set_property -dict {LOC BF19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_mux_reset]
set_property -dict {LOC BF20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_scl]
set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_sda]
set_false_path -to [get_ports {i2c_sda i2c_scl}]
set_output_delay 0 [get_ports {i2c_sda i2c_scl}]
set_false_path -from [get_ports {i2c_sda i2c_scl}]
set_input_delay 0 [get_ports {i2c_sda i2c_scl}]
# PCIe Interface
#set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
#set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
@ -212,4 +255,5 @@ set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_p]
#set_false_path -from [get_ports {pcie_reset_n}]
#set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@ -70,3 +70,40 @@ program: $(FPGA_TOP).bit
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
%.mcs %.prm: %.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(FPGA_TOP).mcs $(FPGA_TOP).prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(FPGA_TOP).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(FPGA_TOP).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,95 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,289 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
# 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)
async def init(self):
self.dut.rst.setimmediatevalue(0)
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)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
self.dut.qsfp0_rx_rst_1 <= 1
self.dut.qsfp0_tx_rst_1 <= 1
self.dut.qsfp0_rx_rst_2 <= 1
self.dut.qsfp0_tx_rst_2 <= 1
self.dut.qsfp0_rx_rst_3 <= 1
self.dut.qsfp0_tx_rst_3 <= 1
self.dut.qsfp0_rx_rst_4 <= 1
self.dut.qsfp0_tx_rst_4 <= 1
self.dut.qsfp1_rx_rst_1 <= 1
self.dut.qsfp1_tx_rst_1 <= 1
self.dut.qsfp1_rx_rst_2 <= 1
self.dut.qsfp1_tx_rst_2 <= 1
self.dut.qsfp1_rx_rst_3 <= 1
self.dut.qsfp1_tx_rst_3 <= 1
self.dut.qsfp1_rx_rst_4 <= 1
self.dut.qsfp1_tx_rst_4 <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
self.dut.qsfp0_rx_rst_1 <= 0
self.dut.qsfp0_tx_rst_1 <= 0
self.dut.qsfp0_rx_rst_2 <= 0
self.dut.qsfp0_tx_rst_2 <= 0
self.dut.qsfp0_rx_rst_3 <= 0
self.dut.qsfp0_tx_rst_3 <= 0
self.dut.qsfp0_rx_rst_4 <= 0
self.dut.qsfp0_tx_rst_4 <= 0
self.dut.qsfp1_rx_rst_1 <= 0
self.dut.qsfp1_tx_rst_1 <= 0
self.dut.qsfp1_rx_rst_2 <= 0
self.dut.qsfp1_tx_rst_2 <= 0
self.dut.qsfp1_rx_rst_3 <= 0
self.dut.qsfp1_tx_rst_3 <= 0
self.dut.qsfp1_rx_rst_4 <= 0
self.dut.qsfp1_tx_rst_4 <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp0_1_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp0_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp0_1_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp0_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,465 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import xgmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
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/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete_64.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v")
srcs.append("../lib/eth/rtl/udp_64.v")
srcs.append("../lib/eth/rtl/udp_ip_rx_64.v")
srcs.append("../lib/eth/rtl/udp_ip_tx_64.v")
srcs.append("../lib/eth/rtl/ip_complete_64.v")
srcs.append("../lib/eth/rtl/ip_64.v")
srcs.append("../lib/eth/rtl/ip_eth_rx_64.v")
srcs.append("../lib/eth/rtl/ip_eth_tx_64.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_register.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
sw = Signal(intbv(0)[4:])
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:])
uart_txd = Signal(bool(0))
# Outputs
led = Signal(intbv(0)[3:])
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:])
uart_rxd = 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')
# 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,
sw=sw,
led=led,
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,
uart_rxd=uart_rxd,
uart_txd=uart_txd
)
@always(delay(4))
def clkgen():
clk.next = not clk
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
@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
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
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while qsfp0_1_sink.empty():
yield clk.posedge
rx_frame = qsfp0_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while qsfp0_1_sink.empty():
yield clk.posedge
rx_frame = qsfp0_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert qsfp0_1_source.empty()
assert qsfp0_1_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()

View File

@ -1,269 +0,0 @@
/*
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [3:0] sw = 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 uart_txd = 0;
// Outputs
wire [2:0] led;
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 uart_rxd;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
sw,
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,
uart_txd
);
$to_myhdl(
led,
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,
uart_rxd
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core
UUT (
.clk(clk),
.rst(rst),
.sw(sw),
.led(led),
.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),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/xgmii_ep.py

View File

@ -14,6 +14,8 @@ set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_operating_conditions -design_power_budget 160
# System clocks
# 100 MHz (DDR4)
#set_property -dict {LOC BJ43 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
@ -38,34 +40,45 @@ set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
# Reset button
set_property -dict {LOC L30 IOSTANDARD LVCMOS18} [get_ports reset]
set_false_path -from [get_ports {reset}]
set_input_delay 0 [get_ports {reset}]
# UART
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart_txd]
#set_property -dict {LOC B33 IOSTANDARD LVCMOS18} [get_ports usb_uart_rxd]
#set_false_path -to [get_ports {uart_txd}]
#set_output_delay 0 [get_ports {uart_txd}]
#set_false_path -from [get_ports {uart_rxd}]
#set_input_delay 0 [get_ports {uart_rxd}]
# HBM overtemp
set_property -dict {LOC D32 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
set_false_path -to [get_ports {hbm_cattrip}]
set_output_delay 0 [get_ports {hbm_cattrip}]
# QSFP28 Interfaces
set_property -dict {LOC L53 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_134 GTYE3_CHANNEL_X0Y40 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC L54 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_134 GTYE3_CHANNEL_X0Y40 / GTYE3_COMMON_X0Y10
set_property -dict {LOC L48 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_134 GTYE3_CHANNEL_X0Y40 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC L49 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_134 GTYE3_CHANNEL_X0Y40 / GTYE3_COMMON_X0Y10
set_property -dict {LOC K51 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_134 GTYE3_CHANNEL_X0Y41 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC K52 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_134 GTYE3_CHANNEL_X0Y41 / GTYE3_COMMON_X0Y10
set_property -dict {LOC L44 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_134 GTYE3_CHANNEL_X0Y41 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC L45 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_134 GTYE3_CHANNEL_X0Y41 / GTYE3_COMMON_X0Y10
set_property -dict {LOC J53 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_134 GTYE3_CHANNEL_X0Y42 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC J54 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_134 GTYE3_CHANNEL_X0Y42 / GTYE3_COMMON_X0Y10
set_property -dict {LOC K46 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_134 GTYE3_CHANNEL_X0Y42 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC K47 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_134 GTYE3_CHANNEL_X0Y42 / GTYE3_COMMON_X0Y10
set_property -dict {LOC H51 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_134 GTYE3_CHANNEL_X0Y43 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC H52 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_134 GTYE3_CHANNEL_X0Y43 / GTYE3_COMMON_X0Y10
set_property -dict {LOC J48 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_134 GTYE3_CHANNEL_X0Y43 / GTYE3_COMMON_X0Y10
#set_property -dict {LOC J49 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_134 GTYE3_CHANNEL_X0Y43 / GTYE3_COMMON_X0Y10
set_property -dict {LOC L53 } [get_ports qsfp0_rx1_p] ;# MGTYRXP0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L54 } [get_ports qsfp0_rx1_n] ;# MGTYRXN0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L48 } [get_ports qsfp0_tx1_p] ;# MGTYTXP0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L49 } [get_ports qsfp0_tx1_n] ;# MGTYTXN0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K51 } [get_ports qsfp0_rx2_p] ;# MGTYRXP1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K52 } [get_ports qsfp0_rx2_n] ;# MGTYRXN1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L44 } [get_ports qsfp0_tx2_p] ;# MGTYTXP1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L45 } [get_ports qsfp0_tx2_n] ;# MGTYTXN1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J53 } [get_ports qsfp0_rx3_p] ;# MGTYRXP2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J54 } [get_ports qsfp0_rx3_n] ;# MGTYRXN2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K46 } [get_ports qsfp0_tx3_p] ;# MGTYTXP2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K47 } [get_ports qsfp0_tx3_n] ;# MGTYTXN2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC H51 } [get_ports qsfp0_rx4_p] ;# MGTYRXP3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC H52 } [get_ports qsfp0_rx4_n] ;# MGTYRXN3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J48 } [get_ports qsfp0_tx4_p] ;# MGTYTXP3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J49 } [get_ports qsfp0_tx4_n] ;# MGTYTXN3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
#set_property -dict {LOC T42 } [get_ports qsfp0_mgt_refclk_0_p] ;# MGTREFCLK0P_134 from SI570
#set_property -dict {LOC T43 } [get_ports qsfp0_mgt_refclk_0_n] ;# MGTREFCLK0N_134 from SI570
set_property -dict {LOC R40 } [get_ports qsfp0_mgt_refclk_1_p] ;# MGTREFCLK1P_134 from SI546
#set_property -dict {LOC R41 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_134 from SI546
set_property -dict {LOC R41 } [get_ports qsfp0_mgt_refclk_1_n] ;# MGTREFCLK1N_134 from SI546
set_property -dict {LOC H32 IOSTANDARD LVCMOS18} [get_ports qsfp0_refclk_oe_b]
set_property -dict {LOC G32 IOSTANDARD LVCMOS18} [get_ports qsfp0_refclk_fs]
@ -78,22 +91,25 @@ set_property -dict {LOC G32 IOSTANDARD LVCMOS18} [get_ports qsfp0_refclk_fs]
# 161.1328125 MHz MGT reference clock (from SI546, fs = 1)
create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports qsfp0_mgt_refclk_1_p]
set_property -dict {LOC G53 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_135 GTYE3_CHANNEL_X0Y44 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC G54 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_135 GTYE3_CHANNEL_X0Y44 / GTYE3_COMMON_X0Y11
set_property -dict {LOC G48 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_135 GTYE3_CHANNEL_X0Y44 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC G49 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_135 GTYE3_CHANNEL_X0Y44 / GTYE3_COMMON_X0Y11
set_property -dict {LOC F51 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_135 GTYE3_CHANNEL_X0Y45 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC F52 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_135 GTYE3_CHANNEL_X0Y45 / GTYE3_COMMON_X0Y11
set_property -dict {LOC E48 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_135 GTYE3_CHANNEL_X0Y45 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC E49 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_135 GTYE3_CHANNEL_X0Y45 / GTYE3_COMMON_X0Y11
set_property -dict {LOC E53 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_135 GTYE3_CHANNEL_X0Y46 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC E54 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_135 GTYE3_CHANNEL_X0Y46 / GTYE3_COMMON_X0Y11
set_property -dict {LOC C48 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_135 GTYE3_CHANNEL_X0Y46 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC C49 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_135 GTYE3_CHANNEL_X0Y46 / GTYE3_COMMON_X0Y11
set_property -dict {LOC D51 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_135 GTYE3_CHANNEL_X0Y47 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC D52 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_135 GTYE3_CHANNEL_X0Y47 / GTYE3_COMMON_X0Y11
set_property -dict {LOC A49 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_135 GTYE3_CHANNEL_X0Y47 / GTYE3_COMMON_X0Y11
#set_property -dict {LOC A50 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_135 GTYE3_CHANNEL_X0Y47 / GTYE3_COMMON_X0Y11
set_false_path -to [get_ports {qsfp0_refclk_oe_b qsfp0_refclk_fs}]
set_output_delay 0 [get_ports {qsfp0_refclk_oe_b qsfp0_refclk_fs}]
set_property -dict {LOC G53 } [get_ports qsfp1_rx1_p] ;# MGTYRXP0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC G54 } [get_ports qsfp1_rx1_n] ;# MGTYRXN0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC G48 } [get_ports qsfp1_tx1_p] ;# MGTYTXP0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC G49 } [get_ports qsfp1_tx1_n] ;# MGTYTXN0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC F51 } [get_ports qsfp1_rx2_p] ;# MGTYRXP1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC F52 } [get_ports qsfp1_rx2_n] ;# MGTYRXN1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E48 } [get_ports qsfp1_tx2_p] ;# MGTYTXP1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E49 } [get_ports qsfp1_tx2_n] ;# MGTYTXN1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E53 } [get_ports qsfp1_rx3_p] ;# MGTYRXP2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E54 } [get_ports qsfp1_rx3_n] ;# MGTYRXN2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC C48 } [get_ports qsfp1_tx3_p] ;# MGTYTXP2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC C49 } [get_ports qsfp1_tx3_n] ;# MGTYTXN2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC D51 } [get_ports qsfp1_rx4_p] ;# MGTYRXP3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC D52 } [get_ports qsfp1_rx4_n] ;# MGTYRXN3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC A49 } [get_ports qsfp1_tx4_p] ;# MGTYTXP3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC A50 } [get_ports qsfp1_tx4_n] ;# MGTYTXN3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
#set_property -dict {LOC P42 } [get_ports qsfp1_mgt_refclk_0_p] ;# MGTREFCLK0P_135 from SI570
#set_property -dict {LOC P43 } [get_ports qsfp1_mgt_refclk_0_n] ;# MGTREFCLK0N_135 from SI570
#set_property -dict {LOC M42 } [get_ports qsfp1_mgt_refclk_1_p] ;# MGTREFCLK1P_135 from SI546
@ -110,6 +126,9 @@ set_property -dict {LOC G33 IOSTANDARD LVCMOS18} [get_ports qsfp1_refclk_fs]
# 161.1328125 MHz MGT reference clock (from SI546, fs = 1)
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports qsfp1_mgt_refclk_1_p]
set_false_path -to [get_ports {qsfp1_refclk_oe_b qsfp1_refclk_fs}]
set_output_delay 0 [get_ports {qsfp1_refclk_oe_b qsfp1_refclk_fs}]
# PCIe Interface
#set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
#set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
@ -191,4 +210,5 @@ set_property -dict {LOC G33 IOSTANDARD LVCMOS18} [get_ports qsfp1_refclk_fs]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports pcie_refclk_3_p]
#set_false_path -from [get_ports {pcie_reset_n}]
#set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@ -70,7 +70,7 @@ program: $(FPGA_TOP).bit
vivado -nojournal -nolog -mode batch -source program.tcl
%.mcs %.prm: %.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
@ -78,7 +78,7 @@ program: $(FPGA_TOP).bit
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,95 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,287 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
# 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)
async def init(self):
self.dut.rst.setimmediatevalue(0)
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)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
self.dut.qsfp0_rx_rst_1 <= 1
self.dut.qsfp0_tx_rst_1 <= 1
self.dut.qsfp0_rx_rst_2 <= 1
self.dut.qsfp0_tx_rst_2 <= 1
self.dut.qsfp0_rx_rst_3 <= 1
self.dut.qsfp0_tx_rst_3 <= 1
self.dut.qsfp0_rx_rst_4 <= 1
self.dut.qsfp0_tx_rst_4 <= 1
self.dut.qsfp1_rx_rst_1 <= 1
self.dut.qsfp1_tx_rst_1 <= 1
self.dut.qsfp1_rx_rst_2 <= 1
self.dut.qsfp1_tx_rst_2 <= 1
self.dut.qsfp1_rx_rst_3 <= 1
self.dut.qsfp1_tx_rst_3 <= 1
self.dut.qsfp1_rx_rst_4 <= 1
self.dut.qsfp1_tx_rst_4 <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
self.dut.qsfp0_rx_rst_1 <= 0
self.dut.qsfp0_tx_rst_1 <= 0
self.dut.qsfp0_rx_rst_2 <= 0
self.dut.qsfp0_tx_rst_2 <= 0
self.dut.qsfp0_rx_rst_3 <= 0
self.dut.qsfp0_tx_rst_3 <= 0
self.dut.qsfp0_rx_rst_4 <= 0
self.dut.qsfp0_tx_rst_4 <= 0
self.dut.qsfp1_rx_rst_1 <= 0
self.dut.qsfp1_tx_rst_1 <= 0
self.dut.qsfp1_rx_rst_2 <= 0
self.dut.qsfp1_tx_rst_2 <= 0
self.dut.qsfp1_rx_rst_3 <= 0
self.dut.qsfp1_tx_rst_3 <= 0
self.dut.qsfp1_rx_rst_4 <= 0
self.dut.qsfp1_tx_rst_4 <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp0_1_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp0_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp0_1_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp0_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,455 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import xgmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
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/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete_64.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v")
srcs.append("../lib/eth/rtl/udp_64.v")
srcs.append("../lib/eth/rtl/udp_ip_rx_64.v")
srcs.append("../lib/eth/rtl/udp_ip_tx_64.v")
srcs.append("../lib/eth/rtl/ip_complete_64.v")
srcs.append("../lib/eth/rtl/ip_64.v")
srcs.append("../lib/eth/rtl/ip_eth_rx_64.v")
srcs.append("../lib/eth/rtl/ip_eth_tx_64.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_register.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
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:])
# Outputs
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:])
# 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')
# 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,
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
)
@always(delay(4))
def clkgen():
clk.next = not clk
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
@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
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
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while qsfp0_1_sink.empty():
yield clk.posedge
rx_frame = qsfp0_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
qsfp0_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while qsfp0_1_sink.empty():
yield clk.posedge
rx_frame = qsfp0_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert qsfp0_1_source.empty()
assert qsfp0_1_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()

View File

@ -1,257 +0,0 @@
/*
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 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;
// Outputs
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;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
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
);
$to_myhdl(
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
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core
UUT (
.clk(clk),
.rst(rst),
.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)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/xgmii_ep.py

View File

@ -32,6 +32,9 @@ set_property -dict {LOC E18 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qs
set_property -dict {LOC E16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_stat_g]
set_property -dict {LOC F17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_stat_y]
set_false_path -to [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
set_output_delay 0 [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
# UART
#set_property -dict {LOC BE26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart0_txd]
#set_property -dict {LOC BF26 IOSTANDARD LVCMOS18} [get_ports usb_uart0_rxd]
@ -40,9 +43,28 @@ set_property -dict {LOC F17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qs
#set_property -dict {LOC A19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports usb_uart2_txd]
#set_property -dict {LOC A18 IOSTANDARD LVCMOS18} [get_ports usb_uart2_rxd]
#set_false_path -to [get_ports {usb_uart0_txd usb_uart1_txd usb_uart2_txd}]
#set_output_delay 0 [get_ports {usb_uart0_txd usb_uart1_txd usb_uart2_txd}]
#set_false_path -from [get_ports {usb_uart0_rxd usb_uart1_rxd usb_uart2_rxd}]
#set_input_delay 0 [get_ports {usb_uart0_rxd usb_uart1_rxd usb_uart2_rxd}]
# BMC
#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC C17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC BB25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BB26 IOSTANDARD LVCMOS18} [get_ports {msp_uart_rxd}]
#set_false_path -to [get_ports {msp_uart_txd}]
#set_output_delay 0 [get_ports {msp_uart_txd}]
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
# HBM overtemp
set_property -dict {LOC J18 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
set_false_path -to [get_ports {hbm_cattrip}]
set_output_delay 0 [get_ports {hbm_cattrip}]
# SI5394 (SI5394B-A10605-GM)
# I2C address 0x68
# IN0: 161.1328125 MHz from qsfp_recclk
@ -56,25 +78,35 @@ set_property -dict {LOC J18 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
#set_property -dict {LOC J16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports si5394_sda]
#set_property -dict {LOC L19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports si5394_scl]
#set_false_path -to [get_ports {si5394_rst_b}]
#set_output_delay 0 [get_ports {si5394_rst_b}]
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_false_path -to [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_output_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_false_path -from [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_input_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
# QSFP28 Interfaces
set_property -dict {LOC J45 } [get_ports qsfp_rx1_p] ;# MGTYRXP0_131 GTYE3_CHANNEL_X0Y28 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC J46 } [get_ports qsfp_rx1_n] ;# MGTYRXN0_131 GTYE3_CHANNEL_X0Y28 / GTYE3_COMMON_X0Y7
set_property -dict {LOC D42 } [get_ports qsfp_tx1_p] ;# MGTYTXP0_131 GTYE3_CHANNEL_X0Y28 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC D43 } [get_ports qsfp_tx1_n] ;# MGTYTXN0_131 GTYE3_CHANNEL_X0Y28 / GTYE3_COMMON_X0Y7
set_property -dict {LOC G45 } [get_ports qsfp_rx2_p] ;# MGTYRXP1_131 GTYE3_CHANNEL_X0Y29 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC G46 } [get_ports qsfp_rx2_n] ;# MGTYRXN1_131 GTYE3_CHANNEL_X0Y29 / GTYE3_COMMON_X0Y7
set_property -dict {LOC C40 } [get_ports qsfp_tx2_p] ;# MGTYTXP1_131 GTYE3_CHANNEL_X0Y29 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC C41 } [get_ports qsfp_tx2_n] ;# MGTYTXN1_131 GTYE3_CHANNEL_X0Y29 / GTYE3_COMMON_X0Y7
set_property -dict {LOC F43 } [get_ports qsfp_rx3_p] ;# MGTYRXP2_131 GTYE3_CHANNEL_X0Y30 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC F44 } [get_ports qsfp_rx3_n] ;# MGTYRXN2_131 GTYE3_CHANNEL_X0Y30 / GTYE3_COMMON_X0Y7
set_property -dict {LOC B42 } [get_ports qsfp_tx3_p] ;# MGTYTXP2_131 GTYE3_CHANNEL_X0Y30 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC B43 } [get_ports qsfp_tx3_n] ;# MGTYTXN2_131 GTYE3_CHANNEL_X0Y30 / GTYE3_COMMON_X0Y7
set_property -dict {LOC E45 } [get_ports qsfp_rx4_p] ;# MGTYRXP3_131 GTYE3_CHANNEL_X0Y31 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC E46 } [get_ports qsfp_rx4_n] ;# MGTYRXN3_131 GTYE3_CHANNEL_X0Y31 / GTYE3_COMMON_X0Y7
set_property -dict {LOC A40 } [get_ports qsfp_tx4_p] ;# MGTYTXP3_131 GTYE3_CHANNEL_X0Y31 / GTYE3_COMMON_X0Y7
#set_property -dict {LOC A41 } [get_ports qsfp_tx4_n] ;# MGTYTXN3_131 GTYE3_CHANNEL_X0Y31 / GTYE3_COMMON_X0Y7
set_property -dict {LOC J45 } [get_ports qsfp_rx1_p] ;# MGTYRXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J46 } [get_ports qsfp_rx1_n] ;# MGTYRXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC D42 } [get_ports qsfp_tx1_p] ;# MGTYTXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC D43 } [get_ports qsfp_tx1_n] ;# MGTYTXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G45 } [get_ports qsfp_rx2_p] ;# MGTYRXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G46 } [get_ports qsfp_rx2_n] ;# MGTYRXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC C40 } [get_ports qsfp_tx2_p] ;# MGTYTXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC C41 } [get_ports qsfp_tx2_n] ;# MGTYTXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F43 } [get_ports qsfp_rx3_p] ;# MGTYRXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F44 } [get_ports qsfp_rx3_n] ;# MGTYRXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC B42 } [get_ports qsfp_tx3_p] ;# MGTYTXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC B43 } [get_ports qsfp_tx3_n] ;# MGTYTXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E45 } [get_ports qsfp_rx4_p] ;# MGTYRXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E46 } [get_ports qsfp_rx4_n] ;# MGTYRXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC A40 } [get_ports qsfp_tx4_p] ;# MGTYTXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC A41 } [get_ports qsfp_tx4_n] ;# MGTYTXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC N36 } [get_ports qsfp_mgt_refclk_0_p] ;# MGTREFCLK0P_131 from SI5394 OUT0
#set_property -dict {LOC N37 } [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_131 from SI5394 OUT0
set_property -dict {LOC N37 } [get_ports qsfp_mgt_refclk_0_n] ;# MGTREFCLK0N_131 from SI5394 OUT0
#set_property -dict {LOC M38 } [get_ports qsfp_mgt_refclk_1_p] ;# MGTREFCLK1P_131 from SI5394 OUT2
#set_property -dict {LOC M39 } [get_ports qsfp_mgt_refclk_1_n] ;# MGTREFCLK1N_131 from SI5394 OUT2
#set_property -dict {LOC F19 IOSTANDARD LVDS} [get_ports qsfp_recclk_p] ;# to SI5394 IN0
@ -167,4 +199,5 @@ create_clock -period 6.206 -name qsfp_mgt_refclk_0 [get_ports qsfp_mgt_refclk_0_
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports pcie_refclk_3_p]
#set_false_path -from [get_ports {pcie_reset_n}]
#set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@ -70,7 +70,7 @@ program: $(FPGA_TOP).bit
vivado -nojournal -nolog -mode batch -source program.tcl
%.mcs %.prm: %.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
@ -78,7 +78,7 @@ program: $(FPGA_TOP).bit
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,95 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../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/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx_64.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,243 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import XgmiiFrame, XgmiiSource, XgmiiSink
class TB:
def __init__(self, dut):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 6.4, units="ns").start())
# 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)
async def init(self):
self.dut.rst.setimmediatevalue(0)
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)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst.setimmediatevalue(1)
self.dut.qsfp_rx_rst_1 <= 1
self.dut.qsfp_tx_rst_1 <= 1
self.dut.qsfp_rx_rst_2 <= 1
self.dut.qsfp_tx_rst_2 <= 1
self.dut.qsfp_rx_rst_3 <= 1
self.dut.qsfp_tx_rst_3 <= 1
self.dut.qsfp_rx_rst_4 <= 1
self.dut.qsfp_tx_rst_4 <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
self.dut.qsfp_rx_rst_1 <= 0
self.dut.qsfp_tx_rst_1 <= 0
self.dut.qsfp_rx_rst_2 <= 0
self.dut.qsfp_tx_rst_2 <= 0
self.dut.qsfp_rx_rst_3 <= 0
self.dut.qsfp_tx_rst_3 <= 0
self.dut.qsfp_rx_rst_4 <= 0
self.dut.qsfp_tx_rst_4 <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = XgmiiFrame.from_payload(test_pkt.build())
await tb.qsfp_1_source.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.qsfp_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = XgmiiFrame.from_payload(resp_pkt.build())
await tb.qsfp_1_source.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.qsfp_1_sink.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(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, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete_64.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen_64.v"),
os.path.join(eth_rtl_dir, "udp_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx_64.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_complete_64.v"),
os.path.join(eth_rtl_dir, "ip_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx_64.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx_64.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1,343 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import xgmii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
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/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete_64.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen_64.v")
srcs.append("../lib/eth/rtl/udp_64.v")
srcs.append("../lib/eth/rtl/udp_ip_rx_64.v")
srcs.append("../lib/eth/rtl/udp_ip_tx_64.v")
srcs.append("../lib/eth/rtl/ip_complete_64.v")
srcs.append("../lib/eth/rtl/ip_64.v")
srcs.append("../lib/eth/rtl/ip_eth_rx_64.v")
srcs.append("../lib/eth/rtl/ip_eth_tx_64.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_register.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
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:])
# Outputs
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:])
# 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')
# 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,
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
)
@always(delay(4))
def clkgen():
clk.next = not clk
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
@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
yield clk.posedge
print("test 1: test UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
qsfp_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while qsfp_1_sink.empty():
yield clk.posedge
rx_frame = qsfp_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
qsfp_1_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while qsfp_1_sink.empty():
yield clk.posedge
rx_frame = qsfp_1_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert qsfp_1_source.empty()
assert qsfp_1_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()

View File

@ -1,161 +0,0 @@
/*
Copyright (c) 2016-2018 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 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;
// Outputs
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;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
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
);
$to_myhdl(
qsfp_txd_1,
qsfp_txc_1,
qsfp_txd_2,
qsfp_txc_2,
qsfp_txd_3,
qsfp_txc_3,
qsfp_txd_4,
qsfp_txc_4
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core
UUT (
.clk(clk),
.rst(rst),
.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)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/xgmii_ep.py

View File

@ -30,21 +30,33 @@ set_property -dict {LOC J5 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports
set_property -dict {LOC T9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led6]
set_property -dict {LOC T10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports led7]
set_false_path -to [get_ports {led0_r led0_g led0_b led1_r led1_g led1_b led2_r led2_g led2_b led3_r led3_g led3_b led4 led5 led6 led7}]
set_output_delay 0 [get_ports {led0_r led0_g led0_b led1_r led1_g led1_b led2_r led2_g led2_b led3_r led3_g led3_b led4 led5 led6 led7}]
# Reset button
set_property -dict {LOC C2 IOSTANDARD LVCMOS33} [get_ports reset_n]
set_false_path -from [get_ports {reset_n}]
set_input_delay 0 [get_ports {reset_n}]
# Push buttons
set_property -dict {LOC D9 IOSTANDARD LVCMOS33} [get_ports {btn[0]}]
set_property -dict {LOC C9 IOSTANDARD LVCMOS33} [get_ports {btn[1]}]
set_property -dict {LOC B9 IOSTANDARD LVCMOS33} [get_ports {btn[2]}]
set_property -dict {LOC B8 IOSTANDARD LVCMOS33} [get_ports {btn[3]}]
set_false_path -from [get_ports {btn[*]}]
set_input_delay 0 [get_ports {btn[*]}]
# Toggle switches
set_property -dict {LOC A8 IOSTANDARD LVCMOS33} [get_ports {sw[0]}]
set_property -dict {LOC C11 IOSTANDARD LVCMOS33} [get_ports {sw[1]}]
set_property -dict {LOC C10 IOSTANDARD LVCMOS33} [get_ports {sw[2]}]
set_property -dict {LOC A10 IOSTANDARD LVCMOS33} [get_ports {sw[3]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# GPIO
# PMOD JA
#set_property -dict {LOC G13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {gpio_ja1}] ;# PMOD JA pin 1
@ -87,6 +99,11 @@ set_property -dict {LOC A10 IOSTANDARD LVCMOS33} [get_ports {sw[3]}]
set_property -dict {LOC D10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports uart_txd]
set_property -dict {LOC A9 IOSTANDARD LVCMOS33} [get_ports uart_rxd]
set_false_path -to [get_ports {uart_txd}]
set_output_delay 0 [get_ports {uart_txd}]
set_false_path -from [get_ports {uart_rxd}]
set_input_delay 0 [get_ports {uart_rxd}]
# Ethernet MII PHY
set_property -dict {LOC F15 IOSTANDARD LVCMOS33} [get_ports phy_rx_clk]
set_property -dict {LOC D18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[0]}]
@ -111,3 +128,10 @@ set_property -dict {LOC C16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports
create_clock -period 40.000 -name phy_rx_clk [get_ports phy_rx_clk]
create_clock -period 40.000 -name phy_tx_clk [get_ports phy_tx_clk]
set_false_path -to [get_ports {phy_ref_clk phy_reset_n}]
set_output_delay 0 [get_ports {phy_ref_clk phy_reset_n}]
#set_false_path -to [get_ports {phy_mdio phy_mdc}]
#set_output_delay 0 [get_ports {phy_mdio phy_mdc}]
#set_false_path -from [get_ports {phy_mdio}]
#set_input_delay 0 [get_ports {phy_mdio}]

View File

@ -214,7 +214,9 @@ sync_signal_inst (
assign phy_ref_clk = clk_25mhz_int;
fpga_core
fpga_core #(
.TARGET("XILINX")
)
core_inst (
/*
* Clock: 125MHz

View File

@ -31,7 +31,7 @@ THE SOFTWARE.
*/
module fpga_core #
(
parameter TARGET = "XILINX"
parameter TARGET = "GENERIC"
)
(
/*

View File

@ -1 +0,0 @@
../lib/eth/tb/arp_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/axis_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/eth_ep.py

View File

@ -0,0 +1,98 @@
# Copyright (c) 2020 Alex Forencich
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
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 += ../../lib/eth/rtl/eth_mac_mii_fifo.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_mii.v
VERILOG_SOURCES += ../../lib/eth/rtl/ssio_sdr_in.v
VERILOG_SOURCES += ../../lib/eth/rtl/mii_phy_if.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_mac_1g.v
VERILOG_SOURCES += ../../lib/eth/rtl/axis_gmii_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/axis_gmii_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/lfsr.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_axis_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_complete.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_checksum_gen.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/udp_ip_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_complete.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/ip_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_cache.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_rx.v
VERILOG_SOURCES += ../../lib/eth/rtl/arp_eth_tx.v
VERILOG_SOURCES += ../../lib/eth/rtl/eth_arb_mux.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/arbiter.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/priority_encoder.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo.v
VERILOG_SOURCES += ../../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v
# module parameters
#export PARAM_A ?= value
ifeq ($(SIM), icarus)
PLUSARGS += -fst
# COMPILE_ARGS += -P $(TOPLEVEL).A=$(PARAM_A)
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 += -GA=$(PARAM_A)
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim
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 iverilog_dump.v
@rm -rf dump.fst $(TOPLEVEL).fst

View File

@ -0,0 +1,211 @@
"""
Copyright (c) 2020 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
import logging
import os
from scapy.layers.l2 import Ether, ARP
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
from cocotbext.eth import GmiiFrame, MiiPhy
class TB:
def __init__(self, dut, speed=100e6):
self.dut = dut
self.log = SimLog("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.fork(Clock(dut.clk, 8, units="ns").start())
self.mii_phy = MiiPhy(dut.phy_txd, None, dut.phy_tx_en, dut.phy_tx_clk,
dut.phy_rxd, dut.phy_rx_er, dut.phy_rx_dv, dut.phy_rx_clk, speed=speed)
dut.phy_crs.setimmediatevalue(0)
dut.phy_col.setimmediatevalue(0)
dut.btn.setimmediatevalue(0)
dut.sw.setimmediatevalue(0)
dut.uart_rxd.setimmediatevalue(0)
async def init(self):
self.dut.rst.setimmediatevalue(0)
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 1
for k in range(10):
await RisingEdge(self.dut.clk)
self.dut.rst <= 0
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("test UDP RX packet")
payload = bytes([x % 256 for x in range(256)])
eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
ip = IP(src='192.168.1.100', dst='192.168.1.128')
udp = UDP(sport=5678, dport=1234)
test_pkt = eth / ip / udp / payload
test_frame = GmiiFrame.from_payload(test_pkt.build())
await tb.mii_phy.rx.send(test_frame)
tb.log.info("receive ARP request")
rx_frame = await tb.mii_phy.tx.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[ARP].hwtype == 1
assert rx_pkt[ARP].ptype == 0x0800
assert rx_pkt[ARP].hwlen == 6
assert rx_pkt[ARP].plen == 4
assert rx_pkt[ARP].op == 1
assert rx_pkt[ARP].hwsrc == test_pkt.dst
assert rx_pkt[ARP].psrc == test_pkt[IP].dst
assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
assert rx_pkt[ARP].pdst == test_pkt[IP].src
tb.log.info("send ARP response")
eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
arp = ARP(hwtype=1, ptype=0x0800, hwlen=6, plen=4, op=2,
hwsrc=test_pkt.src, psrc=test_pkt[IP].src,
hwdst=test_pkt.dst, pdst=test_pkt[IP].dst)
resp_pkt = eth / arp
resp_frame = GmiiFrame.from_payload(resp_pkt.build())
await tb.mii_phy.rx.send(resp_frame)
tb.log.info("receive UDP packet")
rx_frame = await tb.mii_phy.tx.recv()
rx_pkt = Ether(bytes(rx_frame.get_payload()))
tb.log.info("RX packet: %s", repr(rx_pkt))
assert rx_pkt.dst == test_pkt.src
assert rx_pkt.src == test_pkt.dst
assert rx_pkt[IP].dst == test_pkt[IP].src
assert rx_pkt[IP].src == test_pkt[IP].dst
assert rx_pkt[UDP].dport == test_pkt[UDP].sport
assert rx_pkt[UDP].sport == test_pkt[UDP].dport
assert rx_pkt[UDP].payload == test_pkt[UDP].payload
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
# cocotb-test
tests_dir = os.path.abspath(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'))
axis_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', 'lib', 'axis', 'rtl'))
eth_rtl_dir = os.path.abspath(os.path.join(lib_dir, 'eth', '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(eth_rtl_dir, "eth_mac_mii_fifo.v"),
os.path.join(eth_rtl_dir, "eth_mac_mii.v"),
os.path.join(eth_rtl_dir, "ssio_sdr_in.v"),
os.path.join(eth_rtl_dir, "mii_phy_if.v"),
os.path.join(eth_rtl_dir, "eth_mac_1g.v"),
os.path.join(eth_rtl_dir, "axis_gmii_rx.v"),
os.path.join(eth_rtl_dir, "axis_gmii_tx.v"),
os.path.join(eth_rtl_dir, "lfsr.v"),
os.path.join(eth_rtl_dir, "eth_axis_rx.v"),
os.path.join(eth_rtl_dir, "eth_axis_tx.v"),
os.path.join(eth_rtl_dir, "udp_complete.v"),
os.path.join(eth_rtl_dir, "udp_checksum_gen.v"),
os.path.join(eth_rtl_dir, "udp.v"),
os.path.join(eth_rtl_dir, "udp_ip_rx.v"),
os.path.join(eth_rtl_dir, "udp_ip_tx.v"),
os.path.join(eth_rtl_dir, "ip_complete.v"),
os.path.join(eth_rtl_dir, "ip.v"),
os.path.join(eth_rtl_dir, "ip_eth_rx.v"),
os.path.join(eth_rtl_dir, "ip_eth_tx.v"),
os.path.join(eth_rtl_dir, "ip_arb_mux.v"),
os.path.join(eth_rtl_dir, "arp.v"),
os.path.join(eth_rtl_dir, "arp_cache.v"),
os.path.join(eth_rtl_dir, "arp_eth_rx.v"),
os.path.join(eth_rtl_dir, "arp_eth_tx.v"),
os.path.join(eth_rtl_dir, "eth_arb_mux.v"),
os.path.join(axis_rtl_dir, "arbiter.v"),
os.path.join(axis_rtl_dir, "priority_encoder.v"),
os.path.join(axis_rtl_dir, "axis_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo.v"),
os.path.join(axis_rtl_dir, "axis_async_fifo_adapter.v"),
]
parameters = {}
# parameters['A'] = val
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,
)

View File

@ -1 +0,0 @@
../lib/eth/tb/ip_ep.py

View File

@ -1 +0,0 @@
../lib/eth/tb/mii_ep.py

View File

@ -1,326 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2019 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from myhdl import *
import os
import eth_ep
import arp_ep
import udp_ep
import mii_ep
module = 'fpga_core'
testbench = 'test_%s' % module
srcs = []
srcs.append("../rtl/%s.v" % module)
srcs.append("../lib/eth/rtl/ssio_sdr_in.v")
srcs.append("../lib/eth/rtl/mii_phy_if.v")
srcs.append("../lib/eth/rtl/eth_mac_mii_fifo.v")
srcs.append("../lib/eth/rtl/eth_mac_mii.v")
srcs.append("../lib/eth/rtl/eth_mac_1g.v")
srcs.append("../lib/eth/rtl/axis_gmii_rx.v")
srcs.append("../lib/eth/rtl/axis_gmii_tx.v")
srcs.append("../lib/eth/rtl/lfsr.v")
srcs.append("../lib/eth/rtl/eth_axis_rx.v")
srcs.append("../lib/eth/rtl/eth_axis_tx.v")
srcs.append("../lib/eth/rtl/udp_complete.v")
srcs.append("../lib/eth/rtl/udp_checksum_gen.v")
srcs.append("../lib/eth/rtl/udp.v")
srcs.append("../lib/eth/rtl/udp_ip_rx.v")
srcs.append("../lib/eth/rtl/udp_ip_tx.v")
srcs.append("../lib/eth/rtl/ip_complete.v")
srcs.append("../lib/eth/rtl/ip.v")
srcs.append("../lib/eth/rtl/ip_eth_rx.v")
srcs.append("../lib/eth/rtl/ip_eth_tx.v")
srcs.append("../lib/eth/rtl/ip_arb_mux.v")
srcs.append("../lib/eth/rtl/arp.v")
srcs.append("../lib/eth/rtl/arp_cache.v")
srcs.append("../lib/eth/rtl/arp_eth_rx.v")
srcs.append("../lib/eth/rtl/arp_eth_tx.v")
srcs.append("../lib/eth/rtl/eth_arb_mux.v")
srcs.append("../lib/eth/lib/axis/rtl/arbiter.v")
srcs.append("../lib/eth/lib/axis/rtl/priority_encoder.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo.v")
srcs.append("../lib/eth/lib/axis/rtl/axis_async_fifo_adapter.v")
srcs.append("%s.v" % testbench)
src = ' '.join(srcs)
build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench():
# Parameters
TARGET = "SIM"
# Inputs
clk = Signal(bool(0))
rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:])
btn = Signal(intbv(0)[4:])
sw = Signal(intbv(0)[4:])
phy_rx_clk = Signal(bool(0))
phy_rxd = Signal(intbv(0)[4:])
phy_rx_dv = Signal(bool(0))
phy_rx_er = Signal(bool(0))
phy_col = Signal(bool(0))
phy_crs = Signal(bool(0))
uart_rxd = Signal(bool(0))
# Outputs
led0_r = Signal(bool(0))
led0_g = Signal(bool(0))
led0_b = Signal(bool(0))
led1_r = Signal(bool(0))
led1_g = Signal(bool(0))
led1_b = Signal(bool(0))
led2_r = Signal(bool(0))
led2_g = Signal(bool(0))
led2_b = Signal(bool(0))
led3_r = Signal(bool(0))
led3_g = Signal(bool(0))
led3_b = Signal(bool(0))
led4 = Signal(bool(0))
led5 = Signal(bool(0))
led6 = Signal(bool(0))
led7 = Signal(bool(0))
phy_tx_clk = Signal(bool(0))
phy_txd = Signal(intbv(0)[4:])
phy_tx_en = Signal(bool(0))
phy_reset_n = Signal(bool(0))
uart_txd = Signal(bool(0))
# sources and sinks
mii_source = mii_ep.MIISource()
mii_source_logic = mii_source.create_logic(
phy_rx_clk,
rst,
txd=phy_rxd,
tx_en=phy_rx_dv,
tx_er=phy_rx_er,
name='mii_source'
)
mii_sink = mii_ep.MIISink()
mii_sink_logic = mii_sink.create_logic(
phy_tx_clk,
rst,
rxd=phy_txd,
rx_dv=phy_tx_en,
rx_er=False,
name='mii_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,
btn=btn,
sw=sw,
led0_r=led0_r,
led0_g=led0_g,
led0_b=led0_b,
led1_r=led1_r,
led1_g=led1_g,
led1_b=led1_b,
led2_r=led2_r,
led2_g=led2_g,
led2_b=led2_b,
led3_r=led3_r,
led3_g=led3_g,
led3_b=led3_b,
led4=led4,
led5=led5,
led6=led6,
led7=led7,
phy_rx_clk=phy_rx_clk,
phy_rxd=phy_rxd,
phy_rx_dv=phy_rx_dv,
phy_rx_er=phy_rx_er,
phy_tx_clk=phy_tx_clk,
phy_txd=phy_txd,
phy_tx_en=phy_tx_en,
phy_col=phy_col,
phy_crs=phy_crs,
phy_reset_n=phy_reset_n,
uart_rxd=uart_rxd,
uart_txd=uart_txd
)
@always(delay(4))
def clkgen():
clk.next = not clk
phy_clk_hp = Signal(int(20))
@instance
def phy_clk_gen():
while True:
yield delay(int(phy_clk_hp))
phy_rx_clk.next = not phy_rx_clk
phy_tx_clk.next = not phy_tx_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 UDP RX packet")
current_test.next = 1
test_frame = udp_ep.UDPFrame()
test_frame.eth_dest_mac = 0x020000000000
test_frame.eth_src_mac = 0xDAD1D2D3D4D5
test_frame.eth_type = 0x0800
test_frame.ip_version = 4
test_frame.ip_ihl = 5
test_frame.ip_dscp = 0
test_frame.ip_ecn = 0
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 = 0xc0a80181
test_frame.ip_dest_ip = 0xc0a80180
test_frame.udp_source_port = 5678
test_frame.udp_dest_port = 1234
test_frame.payload = bytearray(range(32))
test_frame.build()
mii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+test_frame.build_eth().build_axis_fcs().data)
# wait for ARP request packet
while mii_sink.empty():
yield clk.posedge
rx_frame = mii_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = arp_ep.ARPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xFFFFFFFFFFFF
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0806
assert check_frame.arp_htype == 0x0001
assert check_frame.arp_ptype == 0x0800
assert check_frame.arp_hlen == 6
assert check_frame.arp_plen == 4
assert check_frame.arp_oper == 1
assert check_frame.arp_sha == 0x020000000000
assert check_frame.arp_spa == 0xc0a80180
assert check_frame.arp_tha == 0x000000000000
assert check_frame.arp_tpa == 0xc0a80181
# generate response
arp_frame = arp_ep.ARPFrame()
arp_frame.eth_dest_mac = 0x020000000000
arp_frame.eth_src_mac = 0xDAD1D2D3D4D5
arp_frame.eth_type = 0x0806
arp_frame.arp_htype = 0x0001
arp_frame.arp_ptype = 0x0800
arp_frame.arp_hlen = 6
arp_frame.arp_plen = 4
arp_frame.arp_oper = 2
arp_frame.arp_sha = 0xDAD1D2D3D4D5
arp_frame.arp_spa = 0xc0a80181
arp_frame.arp_tha = 0x020000000000
arp_frame.arp_tpa = 0xc0a80180
mii_source.send(b'\x55\x55\x55\x55\x55\x55\x55\xD5'+arp_frame.build_eth().build_axis_fcs().data)
while mii_sink.empty():
yield clk.posedge
rx_frame = mii_sink.recv()
check_eth_frame = eth_ep.EthFrame()
check_eth_frame.parse_axis_fcs(rx_frame.data[8:])
check_frame = udp_ep.UDPFrame()
check_frame.parse_eth(check_eth_frame)
print(check_frame)
assert check_frame.eth_dest_mac == 0xDAD1D2D3D4D5
assert check_frame.eth_src_mac == 0x020000000000
assert check_frame.eth_type == 0x0800
assert check_frame.ip_version == 4
assert check_frame.ip_ihl == 5
assert check_frame.ip_dscp == 0
assert check_frame.ip_ecn == 0
assert check_frame.ip_identification == 0
assert check_frame.ip_flags == 2
assert check_frame.ip_fragment_offset == 0
assert check_frame.ip_ttl == 64
assert check_frame.ip_protocol == 0x11
assert check_frame.ip_source_ip == 0xc0a80180
assert check_frame.ip_dest_ip == 0xc0a80181
assert check_frame.udp_source_port == 1234
assert check_frame.udp_dest_port == 5678
assert check_frame.payload.data == bytearray(range(32))
assert mii_source.empty()
assert mii_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()

View File

@ -1,158 +0,0 @@
/*
Copyright (c) 2019 Alex Forencich
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// Language: Verilog 2001
`timescale 1ns / 1ps
/*
* Testbench for fpga_core
*/
module test_fpga_core;
// Parameters
parameter TARGET = "SIM";
// Inputs
reg clk = 0;
reg rst = 0;
reg [7:0] current_test = 0;
reg [3:0] btn = 0;
reg [3:0] sw = 0;
reg phy_rx_clk = 0;
reg [3:0] phy_rxd = 0;
reg phy_rx_dv = 0;
reg phy_rx_er = 0;
reg phy_col = 0;
reg phy_crs = 0;
reg phy_tx_clk = 0;
reg uart_rxd = 0;
// Outputs
wire led0_r;
wire led0_g;
wire led0_b;
wire led1_r;
wire led1_g;
wire led1_b;
wire led2_r;
wire led2_g;
wire led2_b;
wire led3_r;
wire led3_g;
wire led3_b;
wire led4;
wire led5;
wire led6;
wire led7;
wire [3:0] phy_txd;
wire phy_tx_en;
wire phy_reset_n;
wire uart_txd;
initial begin
// myhdl integration
$from_myhdl(
clk,
rst,
current_test,
btn,
sw,
phy_rx_clk,
phy_rxd,
phy_rx_dv,
phy_rx_er,
phy_tx_clk,
phy_col,
phy_crs,
uart_rxd
);
$to_myhdl(
led0_r,
led0_g,
led0_b,
led1_r,
led1_g,
led1_b,
led2_r,
led2_g,
led2_b,
led3_r,
led3_g,
led3_b,
led4,
led5,
led6,
led7,
phy_txd,
phy_tx_en,
phy_reset_n,
uart_txd
);
// dump file
$dumpfile("test_fpga_core.lxt");
$dumpvars(0, test_fpga_core);
end
fpga_core #(
.TARGET(TARGET)
)
UUT (
.clk(clk),
.rst(rst),
.btn(btn),
.sw(sw),
.led0_r(led0_r),
.led0_g(led0_g),
.led0_b(led0_b),
.led1_r(led1_r),
.led1_g(led1_g),
.led1_b(led1_b),
.led2_r(led2_r),
.led2_g(led2_g),
.led2_b(led2_b),
.led3_r(led3_r),
.led3_g(led3_g),
.led3_b(led3_b),
.led4(led4),
.led5(led5),
.led6(led6),
.led7(led7),
.phy_rx_clk(phy_rx_clk),
.phy_rxd(phy_rxd),
.phy_rx_dv(phy_rx_dv),
.phy_rx_er(phy_rx_er),
.phy_tx_clk(phy_tx_clk),
.phy_txd(phy_txd),
.phy_tx_en(phy_tx_en),
.phy_col(phy_col),
.phy_crs(phy_crs),
.phy_reset_n(phy_reset_n),
.uart_rxd(uart_rxd),
.uart_txd(uart_txd)
);
endmodule

View File

@ -1 +0,0 @@
../lib/eth/tb/udp_ep.py

Some files were not shown because too many files have changed in this diff Show More